diff options
288 files changed, 2663 insertions, 2203 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a13d69b2217d..8ae5fac08dfa 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1444,7 +1444,8 @@ and is between 256 and 4096 characters. It is defined in the file Param: "schedule" - profile schedule points. Param: <number> - step/bucket size as a power of 2 for statistical time based profiling. - Param: "sleep" - profile D-state sleeping (millisecs) + Param: "sleep" - profile D-state sleeping (millisecs). + Requires CONFIG_SCHEDSTATS Param: "kvm" - profile VM exits. processor.max_cstate= [HW,ACPI] diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 5bdc37f81842..f2668390e8f7 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -34,25 +34,24 @@ #include <zlib.h> #include <assert.h> #include <sched.h> -/*L:110 We can ignore the 30 include files we need for this program, but I do - * want to draw attention to the use of kernel-style types. - * - * As Linus said, "C is a Spartan language, and so should your naming be." I - * like these abbreviations and the header we need uses them, so we define them - * here. - */ -typedef unsigned long long u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; #include "linux/lguest_launcher.h" -#include "linux/pci_ids.h" #include "linux/virtio_config.h" #include "linux/virtio_net.h" #include "linux/virtio_blk.h" #include "linux/virtio_console.h" #include "linux/virtio_ring.h" #include "asm-x86/bootparam.h" +/*L:110 We can ignore the 38 include files we need for this program, but I do + * want to draw attention to the use of kernel-style types. + * + * As Linus said, "C is a Spartan language, and so should your naming be." I + * like these abbreviations, so we define them here. Note that u64 is always + * unsigned long long, which works on all Linux systems: this means that we can + * use %llu in printf for any u64. */ +typedef unsigned long long u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; /*:*/ #define PAGE_PRESENT 0x7 /* Present, RW, Execute */ @@ -361,8 +360,8 @@ static unsigned long load_bzimage(int fd) } /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels - * come wrapped up in the self-decompressing "bzImage" format. With some funky - * coding, we can load those, too. */ + * come wrapped up in the self-decompressing "bzImage" format. With a little + * work, we can load those, too. */ static unsigned long load_kernel(int fd) { Elf32_Ehdr hdr; @@ -465,6 +464,7 @@ static unsigned long setup_pagetables(unsigned long mem, * to know where it is. */ return to_guest_phys(pgdir); } +/*:*/ /* Simple routine to roll all the commandline arguments together with spaces * between them. */ @@ -481,9 +481,9 @@ static void concat(char *dst, char *args[]) dst[len] = '\0'; } -/* This is where we actually tell the kernel to initialize the Guest. We saw - * the arguments it expects when we looked at initialize() in lguest_user.c: - * the base of guest "physical" memory, the top physical page to allow, the +/*L:185 This is where we actually tell the kernel to initialize the Guest. We + * saw the arguments it expects when we looked at initialize() in lguest_user.c: + * the base of Guest "physical" memory, the top physical page to allow, the * top level pagetable and the entry point for the Guest. */ static int tell_kernel(unsigned long pgdir, unsigned long start) { @@ -513,13 +513,14 @@ static void add_device_fd(int fd) /*L:200 * The Waker. * - * With a console and network devices, we can have lots of input which we need - * to process. We could try to tell the kernel what file descriptors to watch, - * but handing a file descriptor mask through to the kernel is fairly icky. + * With console, block and network devices, we can have lots of input which we + * need to process. We could try to tell the kernel what file descriptors to + * watch, but handing a file descriptor mask through to the kernel is fairly + * icky. * * Instead, we fork off a process which watches the file descriptors and writes - * the LHREQ_BREAK command to the /dev/lguest filedescriptor to tell the Host - * loop to stop running the Guest. This causes it to return from the + * the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host + * stop running the Guest. This causes the Launcher to return from the * /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset * the LHREQ_BREAK and wake us up again. * @@ -545,7 +546,9 @@ static void wake_parent(int pipefd, int lguest_fd) if (read(pipefd, &fd, sizeof(fd)) == 0) exit(0); /* Otherwise it's telling us to change what file - * descriptors we're to listen to. */ + * descriptors we're to listen to. Positive means + * listen to a new one, negative means stop + * listening. */ if (fd >= 0) FD_SET(fd, &devices.infds); else @@ -560,7 +563,7 @@ static int setup_waker(int lguest_fd) { int pipefd[2], child; - /* We create a pipe to talk to the waker, and also so it knows when the + /* We create a pipe to talk to the Waker, and also so it knows when the * Launcher dies (and closes pipe). */ pipe(pipefd); child = fork(); @@ -568,7 +571,8 @@ static int setup_waker(int lguest_fd) err(1, "forking"); if (child == 0) { - /* Close the "writing" end of our copy of the pipe */ + /* We are the Waker: close the "writing" end of our copy of the + * pipe and start waiting for input. */ close(pipefd[1]); wake_parent(pipefd[0], lguest_fd); } @@ -579,12 +583,12 @@ static int setup_waker(int lguest_fd) return pipefd[1]; } -/*L:210 +/* * Device Handling. * - * When the Guest sends DMA to us, it sends us an array of addresses and sizes. + * When the Guest gives us a buffer, it sends an array of addresses and sizes. * We need to make sure it's not trying to reach into the Launcher itself, so - * we have a convenient routine which check it and exits with an error message + * we have a convenient routine which checks it and exits with an error message * if something funny is going on: */ static void *_check_pointer(unsigned long addr, unsigned int size, @@ -601,7 +605,9 @@ static void *_check_pointer(unsigned long addr, unsigned int size, /* A macro which transparently hands the line number to the real function. */ #define check_pointer(addr,size) _check_pointer(addr, size, __LINE__) -/* This function returns the next descriptor in the chain, or vq->vring.num. */ +/* Each buffer in the virtqueues is actually a chain of descriptors. This + * function returns the next descriptor in the chain, or vq->vring.num if we're + * at the end. */ static unsigned next_desc(struct virtqueue *vq, unsigned int i) { unsigned int next; @@ -680,13 +686,14 @@ static unsigned get_vq_desc(struct virtqueue *vq, return head; } -/* Once we've used one of their buffers, we tell them about it. We'll then +/* After we've used one of their buffers, we tell them about it. We'll then * want to send them an interrupt, using trigger_irq(). */ static void add_used(struct virtqueue *vq, unsigned int head, int len) { struct vring_used_elem *used; - /* Get a pointer to the next entry in the used ring. */ + /* The virtqueue contains a ring of used buffers. Get a pointer to the + * next entry in that used ring. */ used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num]; used->id = head; used->len = len; @@ -700,6 +707,7 @@ static void trigger_irq(int fd, struct virtqueue *vq) { unsigned long buf[] = { LHREQ_IRQ, vq->config.irq }; + /* If they don't want an interrupt, don't send one. */ if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) return; @@ -716,8 +724,11 @@ static void add_used_and_trigger(int fd, struct virtqueue *vq, trigger_irq(fd, vq); } -/* Here is the input terminal setting we save, and the routine to restore them - * on exit so the user can see what they type next. */ +/* + * The Console + * + * Here is the input terminal setting we save, and the routine to restore them + * on exit so the user gets their terminal back. */ static struct termios orig_term; static void restore_term(void) { @@ -818,7 +829,10 @@ static void handle_console_output(int fd, struct virtqueue *vq) } } -/* Handling output for network is also simple: we get all the output buffers +/* + * The Network + * + * Handling output for network is also simple: we get all the output buffers * and write them (ignoring the first element) to this device's file descriptor * (stdout). */ static void handle_net_output(int fd, struct virtqueue *vq) @@ -831,8 +845,9 @@ static void handle_net_output(int fd, struct virtqueue *vq) while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) { if (in) errx(1, "Input buffers in output queue?"); - /* Check header, but otherwise ignore it (we said we supported - * no features). */ + /* Check header, but otherwise ignore it (we told the Guest we + * supported no features, so it shouldn't have anything + * interesting). */ (void)convert(&iov[0], struct virtio_net_hdr); len = writev(vq->dev->fd, iov+1, out-1); add_used_and_trigger(fd, vq, head, len); @@ -883,7 +898,8 @@ static bool handle_tun_input(int fd, struct device *dev) return true; } -/* This callback ensures we try again, in case we stopped console or net +/*L:215 This is the callback attached to the network and console input + * virtqueues: it ensures we try again, in case we stopped console or net * delivery because Guest didn't have any buffers. */ static void enable_fd(int fd, struct virtqueue *vq) { @@ -919,7 +935,7 @@ static void handle_output(int fd, unsigned long addr) strnlen(from_guest_phys(addr), guest_limit - addr)); } -/* This is called when the waker wakes us up: check for incoming file +/* This is called when the Waker wakes us up: check for incoming file * descriptors. */ static void handle_input(int fd) { @@ -986,8 +1002,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type) } /* Each device descriptor is followed by some configuration information. - * The first byte is a "status" byte for the Guest to report what's happening. - * After that are fields: u8 type, u8 len, [... len bytes...]. + * 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. */ @@ -1044,14 +1059,17 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, /* Link virtqueue back to device. */ vq->dev = dev; - /* Set up handler. */ + /* Set the routine to call when the Guest does something to this + * virtqueue. */ vq->handle_output = handle_output; + + /* Set the "Don't Notify Me" flag if we don't have a handler */ if (!handle_output) vq->vring.used->flags = VRING_USED_F_NO_NOTIFY; } /* This routine does all the creation and setup of a new device, including - * caling new_dev_desc() to allocate the descriptor and device memory. */ + * calling new_dev_desc() to allocate the descriptor and device memory. */ static struct device *new_device(const char *name, u16 type, int fd, bool (*handle_input)(int, struct device *)) { @@ -1060,7 +1078,7 @@ static struct device *new_device(const char *name, u16 type, int fd, /* 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/lgba, etc. */ + * is eth0, the first block device /dev/vda, etc. */ *devices.lastdev = dev; dev->next = NULL; devices.lastdev = &dev->next; @@ -1104,7 +1122,7 @@ static void setup_console(void) /* The console needs two virtqueues: the input then the output. When * they put something the input queue, we make sure we're listening to * stdin. When they put something in the output queue, we write it to - * stdout. */ + * stdout. */ add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd); add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output); @@ -1252,21 +1270,17 @@ static void setup_tun_net(const char *arg) verbose("attached to bridge: %s\n", br_name); } - -/* - * Block device. +/* Our block (disk) device should be really simple: the Guest asks for a block + * number and we read or write that position in the file. Unfortunately, that + * was amazingly slow: the Guest waits until the read is finished before + * running anything else, even if it could have been doing useful work. * - * Serving a block device is really easy: the Guest asks for a block number and - * we read or write that position in the file. - * - * Unfortunately, this is amazingly slow: the Guest waits until the read is - * finished before running anything else, even if it could be doing useful - * work. We could use async I/O, except it's reputed to suck so hard that - * characters actually go missing from your code when you try to use it. + * We could use async I/O, except it's reputed to suck so hard that characters + * actually go missing from your code when you try to use it. * * So we farm the I/O out to thread, and communicate with it via a pipe. */ -/* This hangs off device->priv, with the data. */ +/* This hangs off device->priv. */ struct vblk_info { /* The size of the file. */ @@ -1282,8 +1296,14 @@ struct vblk_info * Launcher triggers interrupt to Guest. */ int done_fd; }; +/*:*/ -/* This is the core of the I/O thread. It returns true if it did something. */ +/*L:210 + * The Disk + * + * Remember that the block device is handled by a separate I/O thread. We head + * straight into the core of that thread here: + */ static bool service_io(struct device *dev) { struct vblk_info *vblk = dev->priv; @@ -1294,10 +1314,14 @@ static bool service_io(struct device *dev) struct iovec iov[dev->vq->vring.num]; off64_t off; + /* See if there's a request waiting. If not, nothing to do. */ head = get_vq_desc(dev->vq, iov, &out_num, &in_num); if (head == dev->vq->vring.num) return false; + /* Every block request should contain at least one output buffer + * (detailing the location on disk and the type of request) and one + * input buffer (to hold the result). */ if (out_num == 0 || in_num == 0) errx(1, "Bad virtblk cmd %u out=%u in=%u", head, out_num, in_num); @@ -1306,10 +1330,15 @@ static bool service_io(struct device *dev) in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr); off = out->sector * 512; - /* This is how we implement barriers. Pretty poor, no? */ + /* The block device implements "barriers", where the Guest indicates + * that it wants all previous writes to occur before this write. We + * don't have a way of asking our kernel to do a barrier, so we just + * synchronize all the data in the file. Pretty poor, no? */ if (out->type & VIRTIO_BLK_T_BARRIER) fdatasync(vblk->fd); + /* In general the virtio block driver is allowed to try SCSI commands. + * It'd be nice if we supported eject, for example, but we don't. */ if (out->type & VIRTIO_BLK_T_SCSI_CMD) { fprintf(stderr, "Scsi commands unsupported\n"); in->status = VIRTIO_BLK_S_UNSUPP; @@ -1375,7 +1404,7 @@ static int io_thread(void *_dev) /* When this read fails, it means Launcher died, so we follow. */ while (read(vblk->workpipe[0], &c, 1) == 1) { - /* We acknowledge each request immediately, to reduce latency, + /* We acknowledge each request immediately to reduce latency, * rather than waiting until we've done them all. I haven't * measured to see if it makes any difference. */ while (service_io(dev)) @@ -1384,12 +1413,14 @@ static int io_thread(void *_dev) return 0; } -/* When the thread says some I/O is done, we interrupt the Guest. */ +/* Now we've seen the I/O thread, we return to the Launcher to see what happens + * when the thread tells us it's completed some I/O. */ static bool handle_io_finish(int fd, struct device *dev) { char c; - /* If child died, presumably it printed message. */ + /* If the I/O thread died, presumably it printed the error, so we + * simply exit. */ if (read(dev->fd, &c, 1) != 1) exit(1); @@ -1398,7 +1429,7 @@ static bool handle_io_finish(int fd, struct device *dev) return true; } -/* When the Guest submits some I/O, we wake the I/O thread. */ +/* When the Guest submits some I/O, we just need to wake the I/O thread. */ static void handle_virtblk_output(int fd, struct virtqueue *vq) { struct vblk_info *vblk = vq->dev->priv; @@ -1410,7 +1441,7 @@ static void handle_virtblk_output(int fd, struct virtqueue *vq) exit(1); } -/* This creates a virtual block device. */ +/*L:198 This actually sets up a virtual block device. */ static void setup_block_file(const char *filename) { int p[2]; @@ -1426,7 +1457,7 @@ static void setup_block_file(const char *filename) /* The device responds to return from I/O thread. */ dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish); - /* The device has a virtqueue. */ + /* The device has one virtqueue, where the Guest places requests. */ add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output); /* Allocate the room for our own bookkeeping */ @@ -1448,7 +1479,8 @@ static void setup_block_file(const char *filename) /* The I/O thread writes to this end of the pipe when done. */ vblk->done_fd = p[1]; - /* This is how we tell the I/O thread about more work. */ + /* This is the second pipe, which is how we tell the I/O thread about + * more work. */ pipe(vblk->workpipe); /* Create stack for thread and run it */ @@ -1487,24 +1519,25 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd) char reason[1024] = { 0 }; read(lguest_fd, reason, sizeof(reason)-1); errx(1, "%s", reason); - /* EAGAIN means the waker wanted us to look at some input. + /* 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"); - /* Service input, then unset the BREAK which releases - * the Waker. */ + /* Service input, then unset the BREAK to release the Waker. */ handle_input(lguest_fd); if (write(lguest_fd, args, sizeof(args)) < 0) err(1, "Resetting break"); } } /* - * This is the end of the Launcher. + * This is the end of the Launcher. The good news: we are over halfway + * through! The bad news: the most fiendish part of the code still lies ahead + * of us. * - * But wait! We've seen I/O from the Launcher, and we've seen I/O from the - * Drivers. If we were to see the Host kernel I/O code, our understanding - * would be complete... :*/ + * Are you ready? Take a deep breath and join me in the core of the Host, in + * "make Host". + :*/ static struct option opts[] = { { "verbose", 0, NULL, 'v' }, @@ -1527,7 +1560,7 @@ int main(int argc, char *argv[]) /* Memory, top-level pagetable, code startpoint and size of the * (optional) initrd. */ unsigned long mem = 0, pgdir, start, initrd_size = 0; - /* A temporary and the /dev/lguest file descriptor. */ + /* Two temporaries and the /dev/lguest file descriptor. */ int i, c, lguest_fd; /* The boot information for the Guest. */ struct boot_params *boot; @@ -1622,6 +1655,7 @@ int main(int argc, char *argv[]) /* The boot header contains a command line pointer: we put the command * line after the boot header. */ boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1); + /* We use a simple helper to copy the arguments separated by spaces. */ concat((char *)(boot + 1), argv+optind+2); /* Boot protocol version: 2.07 supports the fields for lguest. */ diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 747a5d15d529..6f7872ba1def 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -184,14 +184,14 @@ tcp_frto - INTEGER F-RTO is an enhanced recovery algorithm for TCP retransmission timeouts. It is particularly beneficial in wireless environments where packet loss is typically due to random radio interference - rather than intermediate router congestion. FRTO is sender-side + rather than intermediate router congestion. F-RTO is sender-side only modification. Therefore it does not require any support from the peer, but in a typical case, however, where wireless link is the local access link and most of the data flows downlink, the - faraway servers should have FRTO enabled to take advantage of it. + faraway servers should have F-RTO enabled to take advantage of it. If set to 1, basic version is enabled. 2 enables SACK enhanced F-RTO if flow uses SACK. The basic version can be used also when - SACK is in use though scenario(s) with it exists where FRTO + SACK is in use though scenario(s) with it exists where F-RTO interacts badly with the packet counting of the SACK enabled TCP flow. diff --git a/Documentation/networking/tc-actions-env-rules.txt b/Documentation/networking/tc-actions-env-rules.txt new file mode 100644 index 000000000000..01e716d185f4 --- /dev/null +++ b/Documentation/networking/tc-actions-env-rules.txt @@ -0,0 +1,29 @@ + +The "enviromental" rules for authors of any new tc actions are: + +1) If you stealeth or borroweth any packet thou shalt be branching +from the righteous path and thou shalt cloneth. + +For example if your action queues a packet to be processed later +or intentionaly branches by redirecting a packet then you need to +clone the packet. +There are certain fields in the skb tc_verd that need to be reset so we +avoid loops etc. A few are generic enough so much so that skb_act_clone() +resets them for you. So invoke skb_act_clone() rather than skb_clone() + +2) If you munge any packet thou shalt call pskb_expand_head in the case +someone else is referencing the skb. After that you "own" the skb. +You must also tell us if it is ok to munge the packet (TC_OK2MUNGE), +this way any action downstream can stomp on the packet. + +3) dropping packets you dont own is a nono. You simply return +TC_ACT_SHOT to the caller and they will drop it. + +The "enviromental" rules for callers of actions (qdiscs etc) are: + +*) thou art responsible for freeing anything returned as being +TC_ACT_SHOT/STOLEN/QUEUED. If none of TC_ACT_SHOT/STOLEN/QUEUED is +returned then all is great and you dont need to do anything. + +Post on netdev if something is unclear. + diff --git a/MAINTAINERS b/MAINTAINERS index 76b857157866..231bda28c428 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2129,8 +2129,8 @@ S: Maintained JOURNALLING FLASH FILE SYSTEM V2 (JFFS2) P: David Woodhouse M: dwmw2@infradead.org -L: jffs-dev@axis.com -W: http://sources.redhat.com/jffs2/ +L: linux-mtd@lists.infradead.org +W: http://www.linux-mtd.infradead.org/doc/jffs2.html S: Maintained JFS FILESYSTEM @@ -2259,6 +2259,13 @@ L: legousb-devel@lists.sourceforge.net W: http://legousb.sourceforge.net/ S: Maintained +LGUEST +P: Rusty Russell +M: rusty@rustcorp.com.au +L: lguest@ozlabs.org +W: http://lguest.ozlabs.org/ +S: Maintained + LINUX FOR IBM pSERIES (RS/6000) P: Paul Mackerras M: paulus@au.ibm.com @@ -2442,13 +2449,15 @@ W: http://www.tazenda.demon.co.uk/phil/linux-hp S: Maintained MAC80211 -P: Jiri Benc -M: jbenc@suse.cz P: Michael Wu M: flamingice@sourmilk.net +P: Johannes Berg +M: johannes@sipsolutions.net +P: Jiri Benc +M: jbenc@suse.cz L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/jbenc/mac80211.git +T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git S: Maintained MACVLAN DRIVER @@ -4141,6 +4150,12 @@ W: http://linuxtv.org T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git S: Maintained +VLAN (802.1Q) +P: Patrick McHardy +M: kaber@trash.net +L: netdev@vger.kernel.org +S: Maintained + VT1211 HARDWARE MONITOR DRIVER P: Juerg Haefliger M: juergh@gmail.com @@ -196,6 +196,9 @@ CROSS_COMPILE ?= UTS_MACHINE := $(ARCH) SRCARCH := $(ARCH) +# for i386 and x86_64 we use SRCARCH equal to x86 +SRCARCH := $(if $(filter x86_64 i386,$(SRCARCH)),x86,$(SRCARCH)) + KCONFIG_CONFIG ?= .config # SHELL used by kbuild @@ -418,7 +421,7 @@ ifeq ($(config-targets),1) # Read arch specific Makefile to set KBUILD_DEFCONFIG as needed. # KBUILD_DEFCONFIG may point out an alternative default configuration # used for 'make defconfig' -include $(srctree)/arch/$(ARCH)/Makefile +include $(srctree)/arch/$(SRCARCH)/Makefile export KBUILD_DEFCONFIG config %config: scripts_basic outputmakefile FORCE @@ -497,7 +500,7 @@ else KBUILD_CFLAGS += -O2 endif -include $(srctree)/arch/$(ARCH)/Makefile +include $(srctree)/arch/$(SRCARCH)/Makefile ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c index a16cb03c5291..d6b61d56b656 100644 --- a/arch/blackfin/kernel/dma-mapping.c +++ b/arch/blackfin/kernel/dma-mapping.c @@ -35,6 +35,7 @@ #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/io.h> +#include <linux/scatterlist.h> #include <asm/cacheflush.h> #include <asm/bfin-global.h> diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c index 671ce1e8434f..662f7b12d005 100644 --- a/arch/frv/mb93090-mb00/pci-dma.c +++ b/arch/frv/mb93090-mb00/pci-dma.c @@ -15,6 +15,7 @@ #include <linux/list.h> #include <linux/pci.h> #include <linux/highmem.h> +#include <linux/scatterlist.h> #include <asm/io.h> void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) @@ -86,7 +87,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, dampr2 = __get_DAMPR(2); for (i = 0; i < nents; i++) { - vaddr = kmap_atomic(sg[i].page, __KM_CACHE); + vaddr = kmap_atomic(sg_page(&sg[i]), __KM_CACHE); frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE); diff --git a/arch/i386/.gitignore b/arch/i386/.gitignore deleted file mode 100644 index 36ef4c374d25..000000000000 --- a/arch/i386/.gitignore +++ /dev/null @@ -1 +0,0 @@ -boot diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c index ef490e1ce600..6f8c080dd9f9 100644 --- a/arch/m68k/kernel/dma.c +++ b/arch/m68k/kernel/dma.c @@ -9,10 +9,10 @@ #include <linux/dma-mapping.h> #include <linux/device.h> #include <linux/kernel.h> +#include <linux/scatterlist.h> #include <linux/vmalloc.h> #include <asm/pgalloc.h> -#include <asm/scatterlist.h> void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t flag) diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index f2eae457fc9a..f2d432edc92d 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -753,7 +753,7 @@ void __init pci_time_init(void) local_irq_enable(); } -static __inline__ unsigned long do_gettimeoffset(void) +static inline unsigned long do_gettimeoffset(void) { /* * We divide all by 100 diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 33f7a3ddb104..77460e316a03 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -1,7 +1,6 @@ -/* $Id: process.c,v 1.161 2002/01/23 11:27:32 davem Exp $ - * linux/arch/sparc/kernel/process.c +/* linux/arch/sparc/kernel/process.c * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) */ @@ -397,7 +396,7 @@ void flush_thread(void) } } -static __inline__ struct sparc_stackf __user * +static inline struct sparc_stackf __user * clone_stackframe(struct sparc_stackf __user *dst, struct sparc_stackf __user *src) { diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 4bf78a5e8e0f..45cb7c5286d7 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,7 +1,6 @@ -/* $Id: time.c,v 1.60 2002/01/23 14:33:55 davem Exp $ - * linux/arch/sparc/kernel/time.c +/* linux/arch/sparc/kernel/time.c * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) * * Chris Davis (cdavis@cois.on.ca) 03/27/1998 @@ -210,7 +209,7 @@ static void __devinit kick_start_clock(void) } /* Return nonzero if the clock chip battery is low. */ -static __inline__ int has_low_battery(void) +static inline int has_low_battery(void) { struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; unsigned char data1, data2; @@ -252,7 +251,7 @@ static void __devinit mostek_set_system_time(void) } /* Probe for the real time clock chip on Sun4 */ -static __inline__ void sun4_clock_probe(void) +static inline void sun4_clock_probe(void) { #ifdef CONFIG_SUN4 int temp; diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c index ec4231c2855a..a312d127d47a 100644 --- a/arch/sparc/mm/btfixup.c +++ b/arch/sparc/mm/btfixup.c @@ -1,5 +1,4 @@ -/* $Id: btfixup.c,v 1.10 2000/05/09 17:40:13 davem Exp $ - * btfixup.c: Boot time code fixup and relocator, so that +/* btfixup.c: Boot time code fixup and relocator, so that * we can get rid of most indirect calls to achieve single * image sun4c and srmmu kernel. * @@ -69,7 +68,7 @@ static void __init set_addr(unsigned int *addr, unsigned int q1, int fmangled, u } } #else -static __inline__ void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value) +static inline void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value) { *addr = value; } diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 1666087c5b80..b86dfce8eee4 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus spin_lock_irqsave(&iounit->lock, flags); while (sz != 0) { --sz; - sg->dvma_address = iounit_get_area(iounit, sg_virt(sg), sg->length); + sg->dvma_address = iounit_get_area(iounit, (unsigned long) sg_virt(sg), sg->length); sg->dvma_length = sg->length; sg = sg_next(sg); } diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index a2cc141291c7..0729305f2f59 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,7 +1,6 @@ -/* $Id: sun4c.c,v 1.212 2001/12/21 04:56:15 davem Exp $ - * sun4c.c: Doing in software what should be done in hardware. +/* sun4c.c: Doing in software what should be done in hardware. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1996 Andrew Tridgell (Andrew.Tridgell@anu.edu.au) * Copyright (C) 1997-2000 Anton Blanchard (anton@samba.org) @@ -719,7 +718,7 @@ static void add_ring(struct sun4c_mmu_ring *ring, ring->num_entries++; } -static __inline__ void add_lru(struct sun4c_mmu_entry *entry) +static inline void add_lru(struct sun4c_mmu_entry *entry) { struct sun4c_mmu_ring *ring = &sun4c_ulru_ring; struct sun4c_mmu_entry *head = &ring->ringhd; @@ -746,7 +745,7 @@ static void add_ring_ordered(struct sun4c_mmu_ring *ring, add_lru(entry); } -static __inline__ void remove_ring(struct sun4c_mmu_ring *ring, +static inline void remove_ring(struct sun4c_mmu_ring *ring, struct sun4c_mmu_entry *entry) { struct sun4c_mmu_entry *next = entry->next; @@ -1836,7 +1835,7 @@ static unsigned long sun4c_pte_to_pgoff(pte_t pte) } -static __inline__ unsigned long sun4c_pmd_page_v(pmd_t pmd) +static inline unsigned long sun4c_pmd_page_v(pmd_t pmd) { return (pmd_val(pmd) & PAGE_MASK); } @@ -1922,7 +1921,7 @@ static void sun4c_free_pgd_fast(pgd_t *pgd) } -static __inline__ pte_t * +static inline pte_t * sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) { unsigned long *ret; @@ -1956,7 +1955,7 @@ static struct page *sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long addr return virt_to_page(pte); } -static __inline__ void sun4c_free_pte_fast(pte_t *pte) +static inline void sun4c_free_pte_fast(pte_t *pte) { *(unsigned long *)pte = (unsigned long) pte_quicklist; pte_quicklist = (unsigned long *) pte; diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c index 9ad84ff10a17..1587a29a4b0e 100644 --- a/arch/sparc64/kernel/binfmt_elf32.c +++ b/arch/sparc64/kernel/binfmt_elf32.c @@ -1,7 +1,7 @@ /* * binfmt_elf32.c: Support 32-bit Sparc ELF binaries on Ultra. * - * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@davemloft.net) * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) */ @@ -133,7 +133,7 @@ struct elf_prpsinfo32 #undef cputime_to_timeval #define cputime_to_timeval cputime_to_compat_timeval -static __inline__ void +static inline void cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) { unsigned long jiffies = cputime_to_jiffies(cputime); diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c index 8230099f0d8a..b61b8dfb09cf 100644 --- a/arch/sparc64/kernel/central.c +++ b/arch/sparc64/kernel/central.c @@ -1,7 +1,6 @@ -/* $Id: central.c,v 1.15 2001/12/19 00:29:51 davem Exp $ - * central.c: Central FHC driver for Sunfire/Starfire/Wildfire. +/* central.c: Central FHC driver for Sunfire/Starfire/Wildfire. * - * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1997, 1999 David S. Miller (davem@davemloft.net) */ #include <linux/kernel.h> @@ -385,7 +384,7 @@ void __init central_probe(void) init_all_fhc_hw(); } -static __inline__ void fhc_ledblink(struct linux_fhc *fhc, int on) +static inline void fhc_ledblink(struct linux_fhc *fhc, int on) { u32 tmp; @@ -402,7 +401,7 @@ static __inline__ void fhc_ledblink(struct linux_fhc *fhc, int on) upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL); } -static __inline__ void central_ledblink(struct linux_central *central, int on) +static inline void central_ledblink(struct linux_central *central, int on) { u8 tmp; diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c index b70324e0d83d..efd5dff85f60 100644 --- a/arch/sparc64/kernel/iommu_common.c +++ b/arch/sparc64/kernel/iommu_common.c @@ -234,7 +234,7 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents) dma_sg->dma_length = dent_len; if (dma_sg != sg) { - dma_sg = next_sg(dma_sg); + dma_sg = sg_next(dma_sg); dma_sg->dma_length = 0; } diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c index c8313cb60f0a..217478a94128 100644 --- a/arch/sparc64/kernel/ldc.c +++ b/arch/sparc64/kernel/ldc.c @@ -2121,7 +2121,7 @@ int ldc_map_sg(struct ldc_channel *lp, state.nc = 0; for (i = 0; i < num_sg; i++) - fill_cookies(&state, page_to_pfn(sg[i].page) << PAGE_SHIFT, + fill_cookies(&state, page_to_pfn(sg_page(&sg[i])) << PAGE_SHIFT, sg[i].offset, sg[i].length); return state.nc; diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index a809e63f03ef..9974a6899551 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -1,5 +1,4 @@ -/* $Id: semaphore.c,v 1.9 2001/11/18 00:12:56 davem Exp $ - * semaphore.c: Sparc64 semaphore implementation. +/* semaphore.c: Sparc64 semaphore implementation. * * This is basically the PPC semaphore scheme ported to use * the sparc64 atomic instructions, so see the PPC code for @@ -19,7 +18,7 @@ * sem->count = tmp; * return old_count; */ -static __inline__ int __sem_update_count(struct semaphore *sem, int incr) +static inline int __sem_update_count(struct semaphore *sem, int incr) { int old_count, tmp; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 407d74a8a542..7cd8d94df0dc 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -459,7 +459,7 @@ again: } } -static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) +static inline void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) { u64 pstate; int i; @@ -906,7 +906,7 @@ extern atomic_t dcpage_flushes; extern atomic_t dcpage_flushes_xcall; #endif -static __inline__ void __local_flush_dcache_page(struct page *page) +static inline void __local_flush_dcache_page(struct page *page) { #ifdef DCACHE_ALIASING_POSSIBLE __flush_dcache_page(page_address(page), diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 560cb1edb1d0..c56573a10eee 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -318,7 +318,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u if (flags & MAP_FIXED) { /* Ok, don't mess with it. */ - return get_unmapped_area(NULL, addr, len, pgoff, flags); + return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); } flags &= ~MAP_SHARED; diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index e9c7e4f07abf..04998388259f 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,7 +1,6 @@ -/* $Id: traps.c,v 1.85 2002/02/09 19:49:31 davem Exp $ - * arch/sparc64/kernel/traps.c +/* arch/sparc64/kernel/traps.c * - * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995,1997 David S. Miller (davem@davemloft.net) * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) */ @@ -765,7 +764,7 @@ static unsigned long cheetah_afsr_errors; */ struct cheetah_err_info *cheetah_error_log; -static __inline__ struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr) +static inline struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr) { struct cheetah_err_info *p; int cpu = smp_processor_id(); @@ -1085,7 +1084,7 @@ static unsigned char cheetah_mtag_syntab[] = { }; /* Return the highest priority error conditon mentioned. */ -static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr) +static inline unsigned long cheetah_get_hipri(unsigned long afsr) { unsigned long tmp = 0; int i; diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 100c4456ed1e..e18ccf85224f 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -201,7 +201,7 @@ inline void flush_dcache_page_impl(struct page *page) #define dcache_dirty_cpu(page) \ (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask) -static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) +static inline void set_dcache_dirty(struct page *page, int this_cpu) { unsigned long mask = this_cpu; unsigned long non_cpu_bits; @@ -223,7 +223,7 @@ static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) : "g1", "g7"); } -static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long cpu) +static inline void clear_dcache_dirty_cpu(struct page *page, unsigned long cpu) { unsigned long mask = (1UL << PG_dcache_dirty); diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c index 3fafa9a8b50b..e1c3fc87484d 100644 --- a/arch/sparc64/prom/console.c +++ b/arch/sparc64/prom/console.c @@ -1,8 +1,7 @@ -/* $Id: console.c,v 1.9 1997/10/29 07:41:43 ecd Exp $ - * console.c: Routines that deal with sending and receiving IO +/* console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) */ @@ -19,7 +18,7 @@ extern int prom_stdin, prom_stdout; /* Non blocking get character from console input device, returns -1 * if no input was taken. This can be used for polling. */ -__inline__ int +inline int prom_nbgetchar(void) { char inc; @@ -35,7 +34,7 @@ prom_nbgetchar(void) /* Non blocking put character to console device, returns -1 if * unsuccessful. */ -__inline__ int +inline int prom_nbputchar(char c) { char outc; diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index b2c5b12c9818..a99ccd7fb1b0 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c @@ -18,14 +18,12 @@ /* Return the child of node 'node' or zero if no this node has no * direct descendent. */ -__inline__ int -__prom_getchild(int node) +inline int __prom_getchild(int node) { return p1275_cmd ("child", P1275_INOUT(1, 1), node); } -__inline__ int -prom_getchild(int node) +inline int prom_getchild(int node) { int cnode; @@ -35,8 +33,7 @@ prom_getchild(int node) return (int)cnode; } -__inline__ int -prom_getparent(int node) +inline int prom_getparent(int node) { int cnode; @@ -49,14 +46,12 @@ prom_getparent(int node) /* Return the next sibling of node 'node' or zero if no more siblings * at this level of depth in the tree. */ -__inline__ int -__prom_getsibling(int node) +inline int __prom_getsibling(int node) { return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node); } -__inline__ int -prom_getsibling(int node) +inline int prom_getsibling(int node) { int sibnode; @@ -72,8 +67,7 @@ prom_getsibling(int node) /* Return the length in bytes of property 'prop' at node 'node'. * Return -1 on error. */ -__inline__ int -prom_getproplen(int node, const char *prop) +inline int prom_getproplen(int node, const char *prop) { if((!node) || (!prop)) return -1; return p1275_cmd ("getproplen", @@ -86,8 +80,8 @@ prom_getproplen(int node, const char *prop) * 'buffer' which has a size of 'bufsize'. If the acquisition * was successful the length will be returned, else -1 is returned. */ -__inline__ int -prom_getproperty(int node, const char *prop, char *buffer, int bufsize) +inline int prom_getproperty(int node, const char *prop, + char *buffer, int bufsize) { int plen; @@ -107,8 +101,7 @@ prom_getproperty(int node, const char *prop, char *buffer, int bufsize) /* Acquire an integer property and return its value. Returns -1 * on failure. */ -__inline__ int -prom_getint(int node, const char *prop) +inline int prom_getint(int node, const char *prop) { int intprop; @@ -122,8 +115,7 @@ prom_getint(int node, const char *prop) * integer. */ -int -prom_getintdefault(int node, const char *property, int deflt) +int prom_getintdefault(int node, const char *property, int deflt) { int retval; @@ -134,8 +126,7 @@ prom_getintdefault(int node, const char *property, int deflt) } /* Acquire a boolean property, 1=TRUE 0=FALSE. */ -int -prom_getbool(int node, const char *prop) +int prom_getbool(int node, const char *prop) { int retval; @@ -148,8 +139,7 @@ prom_getbool(int node, const char *prop) * string on error. The char pointer is the user supplied string * buffer. */ -void -prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) +void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) { int len; @@ -163,8 +153,7 @@ prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) /* Does the device at node 'node' have name 'name'? * YES = 1 NO = 0 */ -int -prom_nodematch(int node, const char *name) +int prom_nodematch(int node, const char *name) { char namebuf[128]; prom_getproperty(node, "name", namebuf, sizeof(namebuf)); @@ -175,8 +164,7 @@ prom_nodematch(int node, const char *name) /* Search siblings at 'node_start' for a node with name * 'nodename'. Return node if successful, zero if not. */ -int -prom_searchsiblings(int node_start, const char *nodename) +int prom_searchsiblings(int node_start, const char *nodename) { int thisnode, error; @@ -197,8 +185,7 @@ prom_searchsiblings(int node_start, const char *nodename) /* Return the first property type for node 'node'. * buffer should be at least 32B in length */ -__inline__ char * -prom_firstprop(int node, char *buffer) +inline char *prom_firstprop(int node, char *buffer) { *buffer = 0; if(node == -1) return buffer; @@ -212,8 +199,7 @@ prom_firstprop(int node, char *buffer) * at node 'node' . Returns NULL string if no more * property types for this node. */ -__inline__ char * -prom_nextprop(int node, const char *oprop, char *buffer) +inline char *prom_nextprop(int node, const char *oprop, char *buffer) { char buf[32]; @@ -279,8 +265,7 @@ prom_setprop(int node, const char *pname, char *value, int size) node, pname, value, P1275_SIZE(size)); } -__inline__ int -prom_inst2pkg(int inst) +inline int prom_inst2pkg(int inst) { int node; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 3a8cd3dfb51c..e184b44b1011 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -35,6 +35,7 @@ #include "linux/genhd.h" #include "linux/spinlock.h" #include "linux/platform_device.h" +#include "linux/scatterlist.h" #include "asm/segment.h" #include "asm/uaccess.h" #include "asm/irq.h" @@ -704,6 +705,7 @@ static int ubd_add(int n, char **error_out) ubd_dev->size = ROUND_BLOCK(ubd_dev->size); INIT_LIST_HEAD(&ubd_dev->restart); + sg_init_table(&ubd_dev->sg, MAX_SG); err = -ENOMEM; ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock); diff --git a/arch/i386/Kconfig.cpu b/arch/x86/Kconfig.cpu index 0e2adadf5905..0e2adadf5905 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu diff --git a/arch/i386/Kconfig.debug b/arch/x86/Kconfig.debug index f03531eacdfb..970b2defe7df 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -1,14 +1,14 @@ menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT - bool - default y + def_bool y source "lib/Kconfig.debug" config EARLY_PRINTK bool "Early printk" if EMBEDDED && DEBUG_KERNEL default y + depends on X86_32 help Write kernel log output directly into the VGA buffer or to a serial port. @@ -37,10 +37,12 @@ config DEBUG_STACK_USAGE comment "Page alloc debug is incompatible with Software Suspend on i386" depends on DEBUG_KERNEL && HIBERNATION + depends on X86_32 config DEBUG_PAGEALLOC bool "Debug page memory allocations" depends on DEBUG_KERNEL && !HIBERNATION && !HUGETLBFS + depends on X86_32 help Unmap pages from the kernel linear mapping after free_pages(). This results in a large slowdown, but helps to find certain types @@ -59,6 +61,7 @@ config DEBUG_RODATA config 4KSTACKS bool "Use 4Kb for kernel stacks instead of 8Kb" depends on DEBUG_KERNEL + depends on X86_32 help If you say Y here the kernel will use a 4Kb stacksize for the kernel stack attached to each process/thread. This facilitates @@ -67,22 +70,50 @@ config 4KSTACKS will also use IRQ stacks to compensate for the reduced stackspace. config X86_FIND_SMP_CONFIG - bool + def_bool y depends on X86_LOCAL_APIC || X86_VOYAGER - default y + depends on X86_32 config X86_MPPARSE - bool + def_bool y depends on X86_LOCAL_APIC && !X86_VISWS - default y + depends on X86_32 config DOUBLEFAULT default y bool "Enable doublefault exception handler" if EMBEDDED + depends on X86_32 + help + This option allows trapping of rare doublefault exceptions that + would otherwise cause a system to silently reboot. Disabling this + option saves about 4k and might cause you much additional grey + hair. + +config IOMMU_DEBUG + bool "Enable IOMMU debugging" + depends on IOMMU && DEBUG_KERNEL + depends on X86_64 help - This option allows trapping of rare doublefault exceptions that - would otherwise cause a system to silently reboot. Disabling this - option saves about 4k and might cause you much additional grey - hair. + Force the IOMMU to on even when you have less than 4GB of + memory and add debugging code. On overflow always panic. And + allow to enable IOMMU leak tracing. Can be disabled at boot + time with iommu=noforce. This will also enable scatter gather + list merging. Currently not recommended for production + code. When you use it make sure you have a big enough + IOMMU/AGP aperture. Most of the options enabled by this can + be set more finegrained using the iommu= command line + options. See Documentation/x86_64/boot-options.txt for more + details. + +config IOMMU_LEAK + bool "IOMMU leak tracing" + depends on DEBUG_KERNEL + depends on IOMMU_DEBUG + help + Add a simple leak tracer to the IOMMU code. This is useful when you + are debugging a buggy device driver that leaks IOMMU mappings. + +#config X86_REMOTE_DEBUG +# bool "kgdb debugging stub" endmenu diff --git a/arch/i386/Kconfig b/arch/x86/Kconfig.i386 index b4437ce0f973..7331efe891a7 100644 --- a/arch/i386/Kconfig +++ b/arch/x86/Kconfig.i386 @@ -287,7 +287,7 @@ config ES7000_CLUSTERED_APIC default y depends on SMP && X86_ES7000 && MPENTIUMIII -source "arch/i386/Kconfig.cpu" +source "arch/x86/Kconfig.cpu" config HPET_TIMER bool "HPET Timer Support" @@ -1272,7 +1272,7 @@ source "fs/Kconfig" source "kernel/Kconfig.instrumentation" -source "arch/i386/Kconfig.debug" +source "arch/x86/Kconfig.debug" source "security/Kconfig" diff --git a/arch/x86_64/Kconfig b/arch/x86/Kconfig.x86_64 index 308970aa5382..e2542e5b536c 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86/Kconfig.x86_64 @@ -835,7 +835,7 @@ source fs/Kconfig source "kernel/Kconfig.instrumentation" -source "arch/x86_64/Kconfig.debug" +source "arch/x86/Kconfig.debug" source "security/Kconfig" diff --git a/arch/x86/Makefile b/arch/x86/Makefile new file mode 100644 index 000000000000..309597386a77 --- /dev/null +++ b/arch/x86/Makefile @@ -0,0 +1,16 @@ +# Unified Makefile for i386 and x86_64 + +# select defconfig based on actual architecture +KBUILD_DEFCONFIG := $(ARCH)_defconfig + +# # No need to remake these files +$(srctree)/arch/x86/Makefile%: ; + +ifeq ($(ARCH),i386) + include $(srctree)/arch/x86/Makefile_32 +else + include $(srctree)/arch/x86/Makefile_64 +endif + + + diff --git a/arch/i386/Makefile b/arch/x86/Makefile_32 index f5b9a37def8b..346ac0766875 100644 --- a/arch/i386/Makefile +++ b/arch/x86/Makefile_32 @@ -1,5 +1,5 @@ # -# i386/Makefile +# i386 Makefile # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -17,9 +17,6 @@ # 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net> # Added support for GEODE CPU -# Fill in SRCARCH -SRCARCH := x86 - # BITS is used as extension for files which are available in a 32 bit # and a 64 bit version to simplify shared Makefiles. # e.g.: obj-y += foo_$(BITS).o @@ -46,7 +43,7 @@ KBUILD_CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) # CPU-specific tuning. Anything which can be shared with UML should go here. -include $(srctree)/arch/i386/Makefile.cpu +include $(srctree)/arch/x86/Makefile_32.cpu # temporary until string.h is fixed cflags-y += -ffreestanding diff --git a/arch/i386/Makefile.cpu b/arch/x86/Makefile_32.cpu index e372b584e919..e372b584e919 100644 --- a/arch/i386/Makefile.cpu +++ b/arch/x86/Makefile_32.cpu diff --git a/arch/x86_64/Makefile b/arch/x86/Makefile_64 index 20eb69bd5a6d..57e714a47af7 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86/Makefile_64 @@ -1,5 +1,5 @@ # -# x86_64/Makefile +# x86_64 Makefile # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -21,9 +21,6 @@ # # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $ -# Fill in SRCARCH -SRCARCH := x86 - # BITS is used as extension for files which are available in a 32 bit # and a 64 bit version to simplify shared Makefiles. # e.g.: obj-y += foo_$(BITS).o diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 5f9a2e72a731..d2b5adf46512 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -17,6 +17,8 @@ #ifndef BOOT_BOOT_H #define BOOT_BOOT_H +#define STACK_SIZE 512 /* Minimum number of bytes for stack */ + #ifndef __ASSEMBLY__ #include <stdarg.h> @@ -198,8 +200,6 @@ static inline int isdigit(int ch) } /* Heap -- available for dynamic lists. */ -#define STACK_SIZE 512 /* Minimum number of bytes for stack */ - extern char _end[]; extern char *HEAP; extern char *heap_end; @@ -216,9 +216,9 @@ static inline char *__get_heap(size_t s, size_t a, size_t n) #define GET_HEAP(type, n) \ ((type *)__get_heap(sizeof(type),__alignof__(type),(n))) -static inline int heap_free(void) +static inline bool heap_free(size_t n) { - return heap_end-HEAP; + return (int)(heap_end-HEAP) >= (int)n; } /* copy.S */ diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index a0ae2e7f6cec..036e635f18a3 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -33,24 +33,20 @@ .globl startup_32 startup_32: - /* check to see if KEEP_SEGMENTS flag is meaningful */ - cmpw $0x207, BP_version(%esi) - jb 1f - + cld /* test KEEP_SEGMENTS flag to see if the bootloader is asking * us to not reload segments */ testb $(1<<6), BP_loadflags(%esi) - jnz 2f + jnz 1f -1: cli + cli movl $(__BOOT_DS),%eax movl %eax,%ds movl %eax,%es movl %eax,%fs movl %eax,%gs movl %eax,%ss - -2: cld +1: /* Calculate the delta between where we were compiled to run * at and where we were actually loaded at. This can only be done diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 49467640751f..1ccb38a7f0d2 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -29,6 +29,7 @@ #include <asm/pgtable.h> #include <asm/page.h> #include <asm/msr.h> +#include <asm/asm-offsets.h> .section ".text.head" .code32 @@ -36,11 +37,17 @@ startup_32: cld + /* test KEEP_SEGMENTS flag to see if the bootloader is asking + * us to not reload segments */ + testb $(1<<6), BP_loadflags(%esi) + jnz 1f + cli movl $(__KERNEL_DS), %eax movl %eax, %ds movl %eax, %es movl %eax, %ss +1: /* Calculate the delta between where we were compiled to run * at and where we were actually loaded at. This can only be done diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 8353c81c41c0..6ef5a060fa11 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -173,7 +173,8 @@ ramdisk_size: .long 0 # its size in bytes bootsect_kludge: .long 0 # obsolete -heap_end_ptr: .word _end+1024 # (Header version 0x0201 or later) +heap_end_ptr: .word _end+STACK_SIZE-512 + # (Header version 0x0201 or later) # space from here (exclusive) down to # end of setup code can be used by setup # for local heap purposes. @@ -230,28 +231,53 @@ start_of_setup: int $0x13 #endif -# We will have entered with %cs = %ds+0x20, normalize %cs so -# it is on par with the other segments. - pushw %ds - pushw $setup2 - lretw - -setup2: # Force %es = %ds movw %ds, %ax movw %ax, %es cld -# Stack paranoia: align the stack and make sure it is good -# for both 16- and 32-bit references. In particular, if we -# were meant to have been using the full 16-bit segment, the -# caller might have set %sp to zero, which breaks %esp-based -# references. - andw $~3, %sp # dword align (might as well...) - jnz 1f - movw $0xfffc, %sp # Make sure we're not zero -1: movzwl %sp, %esp # Clear upper half of %esp - sti +# Apparently some ancient versions of LILO invoked the kernel +# with %ss != %ds, which happened to work by accident for the +# old code. If the CAN_USE_HEAP flag is set in loadflags, or +# %ss != %ds, then adjust the stack pointer. + + # Smallest possible stack we can tolerate + movw $(_end+STACK_SIZE), %cx + + movw heap_end_ptr, %dx + addw $512, %dx + jnc 1f + xorw %dx, %dx # Wraparound - whole segment available +1: testb $CAN_USE_HEAP, loadflags + jnz 2f + + # No CAN_USE_HEAP + movw %ss, %dx + cmpw %ax, %dx # %ds == %ss? + movw %sp, %dx + # If so, assume %sp is reasonably set, otherwise use + # the smallest possible stack. + jne 4f # -> Smallest possible stack... + + # Make sure the stack is at least minimum size. Take a value + # of zero to mean "full segment." +2: + andw $~3, %dx # dword align (might as well...) + jnz 3f + movw $0xfffc, %dx # Make sure we're not zero +3: cmpw %cx, %dx + jnb 5f +4: movw %cx, %dx # Minimum value we can possibly use +5: movw %ax, %ss + movzwl %dx, %esp # Clear upper half of %esp + sti # Now we should have a working stack + +# We will have entered with %cs = %ds+0x20, normalize %cs so +# it is on par with the other segments. + pushw %ds + pushw $6f + lretw +6: # Check signature at end of setup cmpl $0x5a5aaa55, setup_sig diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c index 68e65d95cdfd..ed0672a81870 100644 --- a/arch/x86/boot/video-bios.c +++ b/arch/x86/boot/video-bios.c @@ -79,7 +79,7 @@ static int bios_probe(void) video_bios.modes = GET_HEAP(struct mode_info, 0); for (mode = 0x14; mode <= 0x7f; mode++) { - if (heap_free() < sizeof(struct mode_info)) + if (!heap_free(sizeof(struct mode_info))) break; if (mode_defined(VIDEO_FIRST_BIOS+mode)) diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 192190710710..4716b9a96357 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c @@ -57,7 +57,7 @@ static int vesa_probe(void) while ((mode = rdfs16(mode_ptr)) != 0xffff) { mode_ptr += 2; - if (heap_free() < sizeof(struct mode_info)) + if (!heap_free(sizeof(struct mode_info))) break; /* Heap full, can't save mode info */ if (mode & ~0x1ff) diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c index e4ba897bf9a3..ad9712f01739 100644 --- a/arch/x86/boot/video.c +++ b/arch/x86/boot/video.c @@ -371,7 +371,7 @@ static void save_screen(void) saved.curx = boot_params.screen_info.orig_x; saved.cury = boot_params.screen_info.orig_y; - if (heap_free() < saved.x*saved.y*sizeof(u16)+512) + if (!heap_free(saved.x*saved.y*sizeof(u16)+512)) return; /* Not enough heap to save the screen */ saved.data = GET_HEAP(u16, saved.x*saved.y); diff --git a/arch/i386/defconfig b/arch/x86/configs/i386_defconfig index 54ee1764fdae..54ee1764fdae 100644 --- a/arch/i386/defconfig +++ b/arch/x86/configs/i386_defconfig diff --git a/arch/x86_64/defconfig b/arch/x86/configs/x86_64_defconfig index b091c5e35558..b091c5e35558 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86/configs/x86_64_defconfig diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index 2ed0a4ce62f0..f63e5ff0aca1 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c @@ -62,8 +62,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) /* Initialize _PDC data based on the CPU vendor */ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) { - unsigned int cpu = pr->id; - struct cpuinfo_x86 *c = &cpu_data(cpu); + struct cpuinfo_x86 *c = &cpu_data(pr->id); pr->pdc = NULL; if (c->x86_vendor == X86_VENDOR_INTEL) diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 7e50bda565b4..d1b6ed98774e 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -15,12 +15,16 @@ #include <asm/segment.h> #include <asm/thread_info.h> #include <asm/ia32.h> +#include <asm/bootparam.h> #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) #define BLANK() asm volatile("\n->" : : ) +#define OFFSET(sym, str, mem) \ + DEFINE(sym, offsetof(struct str, mem)) + #define __NO_STUBS 1 #undef __SYSCALL #undef _ASM_X86_64_UNISTD_H_ @@ -109,5 +113,11 @@ int main(void) DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); BLANK(); DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); + + BLANK(); + OFFSET(BP_scratch, boot_params, scratch); + OFFSET(BP_loadflags, boot_params, hdr.loadflags); + OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch); + OFFSET(BP_version, boot_params, hdr.version); return 0; } diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index af0253f94a9a..8bb482ff091b 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -25,7 +25,7 @@ #include <linux/kdebug.h> #include <asm/smp.h> -#ifdef X86_32 +#ifdef CONFIG_X86_32 #include <mach_ipi.h> #else #include <asm/mach_apic.h> @@ -41,7 +41,7 @@ static int crash_nmi_callback(struct notifier_block *self, unsigned long val, void *data) { struct pt_regs *regs; -#ifdef X86_32 +#ifdef CONFIG_X86_32 struct pt_regs fixed_regs; #endif int cpu; @@ -60,7 +60,7 @@ static int crash_nmi_callback(struct notifier_block *self, return NOTIFY_STOP; local_irq_disable(); -#ifdef X86_32 +#ifdef CONFIG_X86_32 if (!user_mode_vm(regs)) { crash_fixup_ss_esp(&fixed_regs, regs); regs = &fixed_regs; diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index dc34acbd54aa..639e6320518e 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -35,12 +35,14 @@ static void __init via_bugs(void) } #ifdef CONFIG_ACPI +#ifdef CONFIG_X86_IO_APIC static int __init nvidia_hpet_check(struct acpi_table_header *header) { return 0; } -#endif +#endif /* CONFIG_X86_IO_APIC */ +#endif /* CONFIG_ACPI */ static void __init nvidia_bugs(void) { diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 0d8577f05422..aa3d2c8f7737 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -233,6 +233,8 @@ NORET_TYPE void machine_kexec(struct kimage *image) void arch_crash_save_vmcoreinfo(void) { + VMCOREINFO_SYMBOL(init_level4_pgt); + #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE VMCOREINFO_SYMBOL(node_data); VMCOREINFO_LENGTH(node_data, MAX_NUMNODES); diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index c56e9ee64964..ae7e0161ce46 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -338,7 +338,6 @@ static int __dma_map_cont(struct scatterlist *start, int nelems, BUG_ON(s != start && s->offset); if (s == start) { - *sout = *s; sout->dma_address = iommu_bus_base; sout->dma_address += iommu_page*PAGE_SIZE + s->offset; sout->dma_length = s->length; @@ -365,7 +364,7 @@ static inline int dma_map_cont(struct scatterlist *start, int nelems, { if (!need) { BUG_ON(nelems != 1); - *sout = *start; + sout->dma_address = start->dma_address; sout->dma_length = start->length; return 0; } diff --git a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c index f32115308399..fcaa026eb807 100644 --- a/arch/x86/kernel/smp_32.c +++ b/arch/x86/kernel/smp_32.c @@ -708,10 +708,4 @@ struct smp_ops smp_ops = { .smp_send_reschedule = native_smp_send_reschedule, .smp_call_function_mask = native_smp_call_function_mask, }; - -int smp_call_function_mask(cpumask_t mask, void (*func) (void *info), - void *info, int wait) -{ - return smp_ops.smp_call_function_mask(mask, func, info, wait); -} -EXPORT_SYMBOL(smp_call_function_mask); +EXPORT_SYMBOL_GPL(smp_ops); diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index d2235db4085f..a55b0902f9d3 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -56,6 +56,7 @@ #include <linux/lguest.h> #include <linux/lguest_launcher.h> #include <linux/virtio_console.h> +#include <linux/pm.h> #include <asm/paravirt.h> #include <asm/param.h> #include <asm/page.h> @@ -98,7 +99,7 @@ static cycle_t clock_base; * When lazy_mode is set, it means we're allowed to defer all hypercalls and do * them as a batch when lazy_mode is eventually turned off. Because hypercalls * are reasonably expensive, batching them up makes sense. For example, a - * large mmap might update dozens of page table entries: that code calls + * large munmap might update dozens of page table entries: that code calls * paravirt_enter_lazy_mmu(), does the dozen updates, then calls * lguest_leave_lazy_mode(). * @@ -163,8 +164,8 @@ void async_hcall(unsigned long call, /*:*/ /*G:033 - * Here are our first native-instruction replacements: four functions for - * interrupt control. + * After that diversion we return to our first native-instruction + * replacements: four functions for interrupt control. * * The simplest way of implementing these would be to have "turn interrupts * off" and "turn interrupts on" hypercalls. Unfortunately, this is too slow: @@ -183,7 +184,7 @@ static unsigned long save_fl(void) return lguest_data.irq_enabled; } -/* "restore_flags" just sets the flags back to the value given. */ +/* restore_flags() just sets the flags back to the value given. */ static void restore_fl(unsigned long flags) { lguest_data.irq_enabled = flags; @@ -356,7 +357,7 @@ static void lguest_cpuid(unsigned int *eax, unsigned int *ebx, * it. The Host needs to know when the Guest wants to change them, so we have * a whole series of functions like read_cr0() and write_cr0(). * - * We start with CR0. CR0 allows you to turn on and off all kinds of basic + * We start with cr0. cr0 allows you to turn on and off all kinds of basic * features, but Linux only really cares about one: the horrifically-named Task * Switched (TS) bit at bit 3 (ie. 8) * @@ -371,8 +372,7 @@ static void lguest_cpuid(unsigned int *eax, unsigned int *ebx, static unsigned long current_cr0, current_cr3; static void lguest_write_cr0(unsigned long val) { - /* 8 == TS bit. */ - lazy_hcall(LHCALL_TS, val & 8, 0, 0); + lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0); current_cr0 = val; } @@ -387,10 +387,10 @@ static unsigned long lguest_read_cr0(void) static void lguest_clts(void) { lazy_hcall(LHCALL_TS, 0, 0, 0); - current_cr0 &= ~8U; + current_cr0 &= ~X86_CR0_TS; } -/* CR2 is the virtual address of the last page fault, which the Guest only ever +/* cr2 is the virtual address of the last page fault, which the Guest only ever * reads. The Host kindly writes this into our "struct lguest_data", so we * just read it out of there. */ static unsigned long lguest_read_cr2(void) @@ -398,7 +398,7 @@ static unsigned long lguest_read_cr2(void) return lguest_data.cr2; } -/* CR3 is the current toplevel pagetable page: the principle is the same as +/* cr3 is the current toplevel pagetable page: the principle is the same as * cr0. Keep a local copy, and tell the Host when it changes. */ static void lguest_write_cr3(unsigned long cr3) { @@ -411,7 +411,7 @@ static unsigned long lguest_read_cr3(void) return current_cr3; } -/* CR4 is used to enable and disable PGE, but we don't care. */ +/* cr4 is used to enable and disable PGE, but we don't care. */ static unsigned long lguest_read_cr4(void) { return 0; @@ -432,7 +432,7 @@ static void lguest_write_cr4(unsigned long val) * maps virtual addresses to physical addresses using "page tables". We could * use one huge index of 1 million entries: each address is 4 bytes, so that's * 1024 pages just to hold the page tables. But since most virtual addresses - * are unused, we use a two level index which saves space. The CR3 register + * are unused, we use a two level index which saves space. The cr3 register * contains the physical address of the top level "page directory" page, which * contains physical addresses of up to 1024 second-level pages. Each of these * second level pages contains up to 1024 physical addresses of actual pages, @@ -440,7 +440,7 @@ static void lguest_write_cr4(unsigned long val) * * Here's a diagram, where arrows indicate physical addresses: * - * CR3 ---> +---------+ + * cr3 ---> +---------+ * | --------->+---------+ * | | | PADDR1 | * Top-level | | PADDR2 | @@ -498,8 +498,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) * * ... except in early boot when the kernel sets up the initial pagetables, * which makes booting astonishingly slow. So we don't even tell the Host - * anything changed until we've done the first page table switch. - */ + * anything changed until we've done the first page table switch. */ static void lguest_set_pte(pte_t *ptep, pte_t pteval) { *ptep = pteval; @@ -720,10 +719,10 @@ static void lguest_time_init(void) /* Set up the timer interrupt (0) to go to our simple timer routine */ set_irq_handler(0, lguest_time_irq); - /* Our clock structure look like arch/i386/kernel/tsc.c if we can use - * the TSC, otherwise it's a dumb nanosecond-resolution clock. Either - * way, the "rating" is initialized so high that it's always chosen - * over any other clocksource. */ + /* Our clock structure looks like arch/x86/kernel/tsc_32.c if we can + * use the TSC, otherwise it's a dumb nanosecond-resolution clock. + * Either way, the "rating" is set so high that it's always chosen over + * any other clocksource. */ if (lguest_data.tsc_khz) lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz, lguest_clock.shift); @@ -749,7 +748,7 @@ static void lguest_time_init(void) * to work. They're pretty simple. */ -/* The Guest needs to tell the host what stack it expects traps to use. For +/* The Guest needs to tell the Host what stack it expects traps to use. For * native hardware, this is part of the Task State Segment mentioned above in * lguest_load_tr_desc(), but to help hypervisors there's this special call. * @@ -850,13 +849,16 @@ static __init char *lguest_memory_setup(void) return "LGUEST"; } -/* Before virtqueues are set up, we use LHCALL_NOTIFY on normal memory to - * produce console output. */ +/* We will eventually use the virtio console device to produce console output, + * but before that is set up we use LHCALL_NOTIFY on normal memory to produce + * console output. */ static __init int early_put_chars(u32 vtermno, const char *buf, int count) { char scratch[17]; unsigned int len = count; + /* We use a nul-terminated string, so we have to make a copy. Icky, + * huh? */ if (len > sizeof(scratch) - 1) len = sizeof(scratch) - 1; scratch[len] = '\0'; @@ -883,7 +885,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) * Our current solution is to allow the paravirt back end to optionally patch * over the indirect calls to replace them with something more efficient. We * patch the four most commonly called functions: disable interrupts, enable - * interrupts, restore interrupts and save interrupts. We usually have 10 + * interrupts, restore interrupts and save interrupts. We usually have 6 or 10 * bytes to patch into: the Guest versions of these operations are small enough * that we can fit comfortably. * @@ -1015,7 +1017,7 @@ __init void lguest_init(void) asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); /* The Host uses the top of the Guest's virtual address space for the - * Host<->Guest Switcher, and it tells us how much it needs in + * Host<->Guest Switcher, and it tells us how big that is in * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */ reserve_top_address(lguest_data.reserve_mem); @@ -1065,6 +1067,6 @@ __init void lguest_init(void) /* * This marks the end of stage II of our journey, The Guest. * - * It is now time for us to explore the nooks and crannies of the three Guest - * devices and complete our understanding of the Guest in "make Drivers". + * It is now time for us to explore the layer of virtual drivers and complete + * our understanding of the Guest in "make Drivers". */ diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index ebc6ac733899..95b6fbcded63 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S @@ -6,7 +6,7 @@ #include <asm/processor-flags.h> /*G:020 This is where we begin: head.S notes that the boot header's platform - * type field is "1" (lguest), so calls us here. The boot header is in %esi. + * type field is "1" (lguest), so calls us here. * * WARNING: be very careful here! We're running at addresses equal to physical * addesses (around 0), not above PAGE_OFFSET as most code expectes @@ -17,13 +17,15 @@ * boot. */ .section .init.text, "ax", @progbits ENTRY(lguest_entry) - /* Make initial hypercall now, so we can set up the pagetables. */ + /* We make the "initialization" hypercall now to tell the Host about + * us, and also find out where it put our page tables. */ movl $LHCALL_LGUEST_INIT, %eax movl $lguest_data - __PAGE_OFFSET, %edx int $LGUEST_TRAP_ENTRY /* The Host put the toplevel pagetable in lguest_data.pgdir. The movsl - * instruction uses %esi implicitly. */ + * instruction uses %esi implicitly as the source for the copy we' + * about to do. */ movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi /* Copy first 32 entries of page directory to __PAGE_OFFSET entries. diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 361ac5107b33..69371434b0cf 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c @@ -29,14 +29,14 @@ #include <asm/arch_hooks.h> /* TLB state -- visible externally, indexed physically */ -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; +DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 }; /* CPU IRQ affinity -- set to all ones initially */ static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = ~0UL }; /* per CPU data structure (for /proc/cpuinfo et al), visible externally * indexed physically */ -DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned; +DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); EXPORT_PER_CPU_SYMBOL(cpu_info); /* physical ID of the CPU used to boot the system */ diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index 503dfc05111b..33563ee8eb0f 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c @@ -550,7 +550,7 @@ no_context: page &= PAGE_MASK; page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)]; - printk(KERN_ALERT "*pde = %016Lx ", page); + printk(KERN_CONT "*pde = %016Lx ", page); page &= ~_PAGE_NX; } #else diff --git a/arch/x86_64/.gitignore b/arch/x86_64/.gitignore deleted file mode 100644 index 36ef4c374d25..000000000000 --- a/arch/x86_64/.gitignore +++ /dev/null @@ -1 +0,0 @@ -boot diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug deleted file mode 100644 index 775d211a5cf9..000000000000 --- a/arch/x86_64/Kconfig.debug +++ /dev/null @@ -1,61 +0,0 @@ -menu "Kernel hacking" - -config TRACE_IRQFLAGS_SUPPORT - bool - default y - -source "lib/Kconfig.debug" - -config DEBUG_RODATA - bool "Write protect kernel read-only data structures" - depends on DEBUG_KERNEL - help - Mark the kernel read-only data as write-protected in the pagetables, - in order to catch accidental (and incorrect) writes to such const data. - This option may have a slight performance impact because a portion - of the kernel code won't be covered by a 2MB TLB anymore. - If in doubt, say "N". - -config IOMMU_DEBUG - depends on IOMMU && DEBUG_KERNEL - bool "Enable IOMMU debugging" - help - Force the IOMMU to on even when you have less than 4GB of - memory and add debugging code. On overflow always panic. And - allow to enable IOMMU leak tracing. Can be disabled at boot - time with iommu=noforce. This will also enable scatter gather - list merging. Currently not recommended for production - code. When you use it make sure you have a big enough - IOMMU/AGP aperture. Most of the options enabled by this can - be set more finegrained using the iommu= command line - options. See Documentation/x86_64/boot-options.txt for more - details. - -config IOMMU_LEAK - bool "IOMMU leak tracing" - depends on DEBUG_KERNEL - depends on IOMMU_DEBUG - help - Add a simple leak tracer to the IOMMU code. This is useful when you - are debugging a buggy device driver that leaks IOMMU mappings. - -config DEBUG_STACKOVERFLOW - bool "Check for stack overflows" - depends on DEBUG_KERNEL - help - This option will cause messages to be printed if free stack space - drops below a certain limit. - -config DEBUG_STACK_USAGE - bool "Stack utilization instrumentation" - depends on DEBUG_KERNEL - help - Enables the display of the minimum amount of free stack which each - task has ever had available in the sysrq-T and sysrq-P debug output. - - This option will slow down process creation somewhat. - -#config X86_REMOTE_DEBUG -# bool "kgdb debugging stub" - -endmenu diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index de5ba479c224..b01dee3ae7f3 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -1366,9 +1366,7 @@ new_segment: sg = sg_next(sg); } - sg_set_page(sg, bvec->bv_page); - sg->length = nbytes; - sg->offset = bvec->bv_offset; + sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset); nsegs++; } bvprv = bvec; diff --git a/crypto/hmac.c b/crypto/hmac.c index e4eb6ac53b5c..0f05be769c34 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -61,7 +61,7 @@ static int hmac_setkey(struct crypto_hash *parent, desc.tfm = tfm; desc.flags = crypto_hash_get_flags(parent); desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP; - sg_set_buf(&tmp, inkey, keylen); + sg_init_one(&tmp, inkey, keylen); err = crypto_hash_digest(&desc, &tmp, keylen, digest); if (err) @@ -96,7 +96,7 @@ static int hmac_init(struct hash_desc *pdesc) desc.tfm = ctx->child; desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; - sg_set_buf(&tmp, ipad, bs); + sg_init_one(&tmp, ipad, bs); err = crypto_hash_init(&desc); if (unlikely(err)) @@ -131,7 +131,7 @@ static int hmac_final(struct hash_desc *pdesc, u8 *out) desc.tfm = ctx->child; desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; - sg_set_buf(&tmp, opad, bs + ds); + sg_init_one(&tmp, opad, bs + ds); err = crypto_hash_final(&desc, digest); if (unlikely(err)) @@ -158,10 +158,11 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, desc.tfm = ctx->child; desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; + sg_init_table(sg1, 2); sg_set_buf(sg1, ipad, bs); + sg_set_page(&sg1[1], (void *) sg, 0, 0); - sg_set_page(&sg[1], (void *) sg); - sg1[1].length = 0; + sg_init_table(sg2, 1); sg_set_buf(sg2, opad, bs + ds); err = crypto_hash_digest(&desc, sg1, nbytes + bs, digest); diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index d741c63af42c..24141fb6f5cb 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -139,7 +139,7 @@ static void test_hash(char *algo, struct hash_testvec *template, printk("test %u:\n", i + 1); memset(result, 0, 64); - sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize); + sg_init_one(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize); if (hash_tv[i].ksize) { ret = crypto_hash_setkey(tfm, hash_tv[i].key, @@ -176,6 +176,7 @@ static void test_hash(char *algo, struct hash_testvec *template, memset(result, 0, 64); temp = 0; + sg_init_table(sg, hash_tv[i].np); for (k = 0; k < hash_tv[i].np; k++) { memcpy(&xbuf[IDX[k]], hash_tv[i].plaintext + temp, @@ -289,8 +290,8 @@ static void test_cipher(char *algo, int enc, goto out; } - sg_set_buf(&sg[0], cipher_tv[i].input, - cipher_tv[i].ilen); + sg_init_one(&sg[0], cipher_tv[i].input, + cipher_tv[i].ilen); ablkcipher_request_set_crypt(req, sg, sg, cipher_tv[i].ilen, @@ -353,6 +354,7 @@ static void test_cipher(char *algo, int enc, } temp = 0; + sg_init_table(sg, cipher_tv[i].np); for (k = 0; k < cipher_tv[i].np; k++) { memcpy(&xbuf[IDX[k]], cipher_tv[i].input + temp, @@ -414,7 +416,7 @@ static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, int bcount; int ret; - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { @@ -440,7 +442,7 @@ static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, char *p, int ret = 0; int i; - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); local_bh_disable(); local_irq_disable(); @@ -570,6 +572,8 @@ static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen, int bcount; int ret; + sg_init_table(sg, 1); + for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { sg_set_buf(sg, p, blen); @@ -595,6 +599,8 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen, if (plen == blen) return test_hash_jiffies_digest(desc, p, blen, out, sec); + sg_init_table(sg, 1); + for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { ret = crypto_hash_init(desc); @@ -626,6 +632,8 @@ static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen, int i; int ret; + sg_init_table(sg, 1); + local_bh_disable(); local_irq_disable(); @@ -677,6 +685,8 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen, if (plen == blen) return test_hash_cycles_digest(desc, p, blen, out); + sg_init_table(sg, 1); + local_bh_disable(); local_irq_disable(); diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 3839efd5eaea..1538355c266b 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c @@ -194,6 +194,23 @@ static int get_date_field(char **p, u32 * value) return result; } +/* Read a possibly BCD register, always return binary */ +static u32 cmos_bcd_read(int offset, int rtc_control) +{ + u32 val = CMOS_READ(offset); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(val); + return val; +} + +/* Write binary value into possibly BCD register */ +static void cmos_bcd_write(u32 val, int offset, int rtc_control) +{ + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BIN_TO_BCD(val); + CMOS_WRITE(val, offset); +} + static ssize_t acpi_system_write_alarm(struct file *file, const char __user * buffer, size_t count, loff_t * ppos) @@ -258,35 +275,18 @@ acpi_system_write_alarm(struct file *file, spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } if (adjust) { - yr += CMOS_READ(RTC_YEAR); - mo += CMOS_READ(RTC_MONTH); - day += CMOS_READ(RTC_DAY_OF_MONTH); - hr += CMOS_READ(RTC_HOURS); - min += CMOS_READ(RTC_MINUTES); - sec += CMOS_READ(RTC_SECONDS); + yr += cmos_bcd_read(RTC_YEAR, rtc_control); + mo += cmos_bcd_read(RTC_MONTH, rtc_control); + day += cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); + hr += cmos_bcd_read(RTC_HOURS, rtc_control); + min += cmos_bcd_read(RTC_MINUTES, rtc_control); + sec += cmos_bcd_read(RTC_SECONDS, rtc_control); } spin_unlock_irq(&rtc_lock); - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(yr); - BCD_TO_BIN(mo); - BCD_TO_BIN(day); - BCD_TO_BIN(hr); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - } - if (sec > 59) { min++; sec -= 60; @@ -307,14 +307,6 @@ acpi_system_write_alarm(struct file *file, yr++; mo -= 12; } - if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(yr); - BIN_TO_BCD(mo); - BIN_TO_BCD(day); - BIN_TO_BCD(hr); - BIN_TO_BCD(min); - BIN_TO_BCD(sec); - } spin_lock_irq(&rtc_lock); /* @@ -326,9 +318,9 @@ acpi_system_write_alarm(struct file *file, CMOS_READ(RTC_INTR_FLAGS); /* write the fields the rtc knows about */ - CMOS_WRITE(hr, RTC_HOURS_ALARM); - CMOS_WRITE(min, RTC_MINUTES_ALARM); - CMOS_WRITE(sec, RTC_SECONDS_ALARM); + cmos_bcd_write(hr, RTC_HOURS_ALARM, rtc_control); + cmos_bcd_write(min, RTC_MINUTES_ALARM, rtc_control); + cmos_bcd_write(sec, RTC_SECONDS_ALARM, rtc_control); /* * If the system supports an enhanced alarm it will have non-zero @@ -336,11 +328,11 @@ acpi_system_write_alarm(struct file *file, * to the RTC area of memory. */ if (acpi_gbl_FADT.day_alarm) - CMOS_WRITE(day, acpi_gbl_FADT.day_alarm); + cmos_bcd_write(day, acpi_gbl_FADT.day_alarm, rtc_control); if (acpi_gbl_FADT.month_alarm) - CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm); + cmos_bcd_write(mo, acpi_gbl_FADT.month_alarm, rtc_control); if (acpi_gbl_FADT.century) - CMOS_WRITE(yr / 100, acpi_gbl_FADT.century); + cmos_bcd_write(yr / 100, acpi_gbl_FADT.century, rtc_control); /* enable the rtc alarm interrupt */ rtc_control |= RTC_AIE; CMOS_WRITE(rtc_control, RTC_CONTROL); diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 95229e77bffe..49cf4cf1a5a2 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -41,6 +41,7 @@ #include <linux/interrupt.h> #include <linux/dma-mapping.h> #include <linux/device.h> +#include <linux/dmi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_cmnd.h> #include <linux/libata.h> @@ -241,6 +242,7 @@ static void ahci_pmp_attach(struct ata_port *ap); static void ahci_pmp_detach(struct ata_port *ap); static void ahci_error_handler(struct ata_port *ap); static void ahci_vt8251_error_handler(struct ata_port *ap); +static void ahci_p5wdh_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); static int ahci_port_resume(struct ata_port *ap); static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl); @@ -339,6 +341,40 @@ static const struct ata_port_operations ahci_vt8251_ops = { .port_stop = ahci_port_stop, }; +static const struct ata_port_operations ahci_p5wdh_ops = { + .check_status = ahci_check_status, + .check_altstatus = ahci_check_status, + .dev_select = ata_noop_dev_select, + + .tf_read = ahci_tf_read, + + .qc_defer = sata_pmp_qc_defer_cmd_switch, + .qc_prep = ahci_qc_prep, + .qc_issue = ahci_qc_issue, + + .irq_clear = ahci_irq_clear, + + .scr_read = ahci_scr_read, + .scr_write = ahci_scr_write, + + .freeze = ahci_freeze, + .thaw = ahci_thaw, + + .error_handler = ahci_p5wdh_error_handler, + .post_internal_cmd = ahci_post_internal_cmd, + + .pmp_attach = ahci_pmp_attach, + .pmp_detach = ahci_pmp_detach, + +#ifdef CONFIG_PM + .port_suspend = ahci_port_suspend, + .port_resume = ahci_port_resume, +#endif + + .port_start = ahci_port_start, + .port_stop = ahci_port_stop, +}; + #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) static const struct ata_port_info ahci_port_info[] = { @@ -1213,6 +1249,53 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, return rc ?: -EAGAIN; } +static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; + struct ata_taskfile tf; + int rc; + + ahci_stop_engine(ap); + + /* clear D2H reception area to properly wait for D2H FIS */ + ata_tf_init(link->device, &tf); + tf.command = 0x80; + ata_tf_to_fis(&tf, 0, 0, d2h_fis); + + rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), + deadline); + + ahci_start_engine(ap); + + if (rc || ata_link_offline(link)) + return rc; + + /* spec mandates ">= 2ms" before checking status */ + msleep(150); + + /* The pseudo configuration device on SIMG4726 attached to + * ASUS P5W-DH Deluxe doesn't send signature FIS after + * hardreset if no device is attached to the first downstream + * port && the pseudo device locks up on SRST w/ PMP==0. To + * work around this, wait for !BSY only briefly. If BSY isn't + * cleared, perform CLO and proceed to IDENTIFY (achieved by + * ATA_LFLAG_NO_SRST and ATA_LFLAG_ASSUME_ATA). + * + * Wait for two seconds. Devices attached to downstream port + * which can't process the following IDENTIFY after this will + * have to be reset again. For most cases, this should + * suffice while making probing snappish enough. + */ + rc = ata_wait_ready(ap, jiffies + 2 * HZ); + if (rc) + ahci_kick_engine(ap, 0); + + return 0; +} + static void ahci_postreset(struct ata_link *link, unsigned int *class) { struct ata_port *ap = link->ap; @@ -1670,6 +1753,19 @@ static void ahci_vt8251_error_handler(struct ata_port *ap) ahci_postreset); } +static void ahci_p5wdh_error_handler(struct ata_port *ap) +{ + if (!(ap->pflags & ATA_PFLAG_FROZEN)) { + /* restart engine */ + ahci_stop_engine(ap); + ahci_start_engine(ap); + } + + /* perform recovery */ + ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_p5wdh_hardreset, + ahci_postreset); +} + static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; @@ -1955,6 +2051,51 @@ static void ahci_print_info(struct ata_host *host) ); } +/* On ASUS P5W DH Deluxe, the second port of PCI device 00:1f.2 is + * hardwired to on-board SIMG 4726. The chipset is ICH8 and doesn't + * support PMP and the 4726 either directly exports the device + * attached to the first downstream port or acts as a hardware storage + * controller and emulate a single ATA device (can be RAID 0/1 or some + * other configuration). + * + * When there's no device attached to the first downstream port of the + * 4726, "Config Disk" appears, which is a pseudo ATA device to + * configure the 4726. However, ATA emulation of the device is very + * lame. It doesn't send signature D2H Reg FIS after the initial + * hardreset, pukes on SRST w/ PMP==0 and has bunch of other issues. + * + * The following function works around the problem by always using + * hardreset on the port and not depending on receiving signature FIS + * afterward. If signature FIS isn't received soon, ATA class is + * assumed without follow-up softreset. + */ +static void ahci_p5wdh_workaround(struct ata_host *host) +{ + static struct dmi_system_id sysids[] = { + { + .ident = "P5W DH Deluxe", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "ASUSTEK COMPUTER INC"), + DMI_MATCH(DMI_PRODUCT_NAME, "P5W DH Deluxe"), + }, + }, + { } + }; + struct pci_dev *pdev = to_pci_dev(host->dev); + + if (pdev->bus->number == 0 && pdev->devfn == PCI_DEVFN(0x1f, 2) && + dmi_check_system(sysids)) { + struct ata_port *ap = host->ports[1]; + + dev_printk(KERN_INFO, &pdev->dev, "enabling ASUS P5W DH " + "Deluxe on-board SIMG4726 workaround\n"); + + ap->ops = &ahci_p5wdh_ops; + ap->link.flags |= ATA_LFLAG_NO_SRST | ATA_LFLAG_ASSUME_ATA; + } +} + static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; @@ -2024,6 +2165,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ap->ops = &ata_dummy_port_ops; } + /* apply workaround for ASUS P5W DH Deluxe mainboard */ + ahci_p5wdh_workaround(host); + /* initialize adapter */ rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); if (rc) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2d147b51c978..081e3dfb64d4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -68,7 +68,8 @@ const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 }; static unsigned int ata_dev_init_params(struct ata_device *dev, u16 heads, u16 sectors); static unsigned int ata_dev_set_xfermode(struct ata_device *dev); -static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable); +static unsigned int ata_dev_set_feature(struct ata_device *dev, + u8 enable, u8 feature); static void ata_dev_xfermask(struct ata_device *dev); static unsigned long ata_dev_blacklisted(const struct ata_device *dev); @@ -1799,13 +1800,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, * SET_FEATURES spin-up subcommand before it will accept * anything other than the original IDENTIFY command. */ - ata_tf_init(dev, &tf); - tf.command = ATA_CMD_SET_FEATURES; - tf.feature = SETFEATURES_SPINUP; - tf.protocol = ATA_PROT_NODATA; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - err_mask = ata_exec_internal(dev, &tf, NULL, - DMA_NONE, NULL, 0, 0); + err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0); if (err_mask && id[2] != 0x738c) { rc = -EIO; reason = "SPINUP failed"; @@ -2075,7 +2070,8 @@ int ata_dev_configure(struct ata_device *dev) unsigned int err_mask; /* issue SET feature command to turn this on */ - err_mask = ata_dev_set_AN(dev, SETFEATURES_SATA_ENABLE); + err_mask = ata_dev_set_feature(dev, + SETFEATURES_SATA_ENABLE, SATA_AN); if (err_mask) ata_dev_printk(dev, KERN_ERR, "failed to enable ATAPI AN " @@ -2886,6 +2882,13 @@ static int ata_dev_set_mode(struct ata_device *dev) dev->pio_mode <= XFER_PIO_2) err_mask &= ~AC_ERR_DEV; + /* 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 && + dev->dma_mode == XFER_MW_DMA_0 && + (dev->id[63] >> 8) & 1) + err_mask &= ~AC_ERR_DEV; + if (err_mask) { ata_dev_printk(dev, KERN_ERR, "failed to set xfermode " "(err_mask=0x%x)\n", err_mask); @@ -3947,9 +3950,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, - { "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */ - { "IOMEGA ZIP 250 ATAPI Floppy", - NULL, ATA_HORKAGE_NODMA }, /* Odd clown on sil3726/4726 PMPs */ { "Config Disk", NULL, ATA_HORKAGE_NODMA | ATA_HORKAGE_SKIP_PM }, @@ -4007,7 +4007,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { } }; -int strn_pattern_cmp(const char *patt, const char *name, int wildchar) +static int strn_pattern_cmp(const char *patt, const char *name, int wildchar) { const char *p; int len; @@ -4181,15 +4181,14 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; } - /** - * ata_dev_set_AN - Issue SET FEATURES - SATA FEATURES + * ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES * @dev: Device to which command will be sent * @enable: Whether to enable or disable the feature + * @feature: The sector count represents the feature to set * * Issue SET FEATURES - SATA FEATURES command to device @dev - * on port @ap with sector count set to indicate Asynchronous - * Notification feature + * on port @ap with sector count * * LOCKING: * PCI/etc. bus probe sem. @@ -4197,7 +4196,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) * RETURNS: * 0 on success, AC_ERR_* mask otherwise. */ -static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable) +static unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, + u8 feature) { struct ata_taskfile tf; unsigned int err_mask; @@ -4210,7 +4210,7 @@ static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable) tf.feature = enable; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.protocol = ATA_PROT_NODATA; - tf.nsect = SATA_AN; + tf.nsect = feature; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); @@ -4689,8 +4689,8 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * data in this function or read data in ata_sg_clean. */ offset = lsg->offset + lsg->length - qc->pad_len; - sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT)); - psg->offset = offset_in_page(offset); + sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT), + qc->pad_len, offset_in_page(offset)); if (qc->tf.flags & ATA_TFLAG_WRITE) { void *addr = kmap_atomic(sg_page(psg), KM_IRQ0); @@ -6921,7 +6921,7 @@ int ata_host_activate(struct ata_host *host, int irq, * LOCKING: * Kernel thread context (may sleep). */ -void ata_port_detach(struct ata_port *ap) +static void ata_port_detach(struct ata_port *ap) { unsigned long flags; struct ata_link *link; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 93e2b545b439..8cb35bb87605 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2071,7 +2071,7 @@ int ata_eh_reset(struct ata_link *link, int classify, int try = 0; struct ata_device *dev; unsigned long deadline; - unsigned int action; + unsigned int tmp_action; ata_reset_fn_t reset; unsigned long flags; int rc; @@ -2086,14 +2086,14 @@ int ata_eh_reset(struct ata_link *link, int classify, /* Determine which reset to use and record in ehc->i.action. * prereset() may examine and modify it. */ - action = ehc->i.action; - ehc->i.action &= ~ATA_EH_RESET_MASK; if (softreset && (!hardreset || (!(link->flags & ATA_LFLAG_NO_SRST) && !sata_set_spd_needed(link) && - !(action & ATA_EH_HARDRESET)))) - ehc->i.action |= ATA_EH_SOFTRESET; + !(ehc->i.action & ATA_EH_HARDRESET)))) + tmp_action = ATA_EH_SOFTRESET; else - ehc->i.action |= ATA_EH_HARDRESET; + tmp_action = ATA_EH_HARDRESET; + + ehc->i.action = (ehc->i.action & ~ATA_EH_RESET_MASK) | tmp_action; if (prereset) { rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT); diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index be30923566c5..842fe08a3c13 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -332,12 +332,13 @@ static void ata_dummy_noret(struct ata_port *port) { } -static void pata_icside_postreset(struct ata_port *ap, unsigned int *classes) +static void pata_icside_postreset(struct ata_link *link, unsigned int *classes) { + struct ata_port *ap = link->ap; struct pata_icside_state *state = ap->host->private_data; if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE) - return ata_std_postreset(ap, classes); + return ata_std_postreset(link, classes); state->port[ap->port_no].disabled = 1; @@ -395,29 +396,30 @@ static struct ata_port_operations pata_icside_port_ops = { static void __devinit pata_icside_setup_ioaddr(struct ata_port *ap, void __iomem *base, - const struct portinfo *info) + struct pata_icside_info *info, + const struct portinfo *port) { struct ata_ioports *ioaddr = &ap->ioaddr; - void __iomem *cmd = base + info->dataoffset; + void __iomem *cmd = base + port->dataoffset; ioaddr->cmd_addr = cmd; - ioaddr->data_addr = cmd + (ATA_REG_DATA << info->stepping); - ioaddr->error_addr = cmd + (ATA_REG_ERR << info->stepping); - ioaddr->feature_addr = cmd + (ATA_REG_FEATURE << info->stepping); - ioaddr->nsect_addr = cmd + (ATA_REG_NSECT << info->stepping); - ioaddr->lbal_addr = cmd + (ATA_REG_LBAL << info->stepping); - ioaddr->lbam_addr = cmd + (ATA_REG_LBAM << info->stepping); - ioaddr->lbah_addr = cmd + (ATA_REG_LBAH << info->stepping); - ioaddr->device_addr = cmd + (ATA_REG_DEVICE << info->stepping); - ioaddr->status_addr = cmd + (ATA_REG_STATUS << info->stepping); - ioaddr->command_addr = cmd + (ATA_REG_CMD << info->stepping); - - ioaddr->ctl_addr = base + info->ctrloffset; + ioaddr->data_addr = cmd + (ATA_REG_DATA << port->stepping); + ioaddr->error_addr = cmd + (ATA_REG_ERR << port->stepping); + ioaddr->feature_addr = cmd + (ATA_REG_FEATURE << port->stepping); + ioaddr->nsect_addr = cmd + (ATA_REG_NSECT << port->stepping); + ioaddr->lbal_addr = cmd + (ATA_REG_LBAL << port->stepping); + ioaddr->lbam_addr = cmd + (ATA_REG_LBAM << port->stepping); + ioaddr->lbah_addr = cmd + (ATA_REG_LBAH << port->stepping); + ioaddr->device_addr = cmd + (ATA_REG_DEVICE << port->stepping); + ioaddr->status_addr = cmd + (ATA_REG_STATUS << port->stepping); + ioaddr->command_addr = cmd + (ATA_REG_CMD << port->stepping); + + ioaddr->ctl_addr = base + port->ctrloffset; ioaddr->altstatus_addr = ioaddr->ctl_addr; ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", - info->raw_base + info->dataoffset, - info->raw_base + info->ctrloffset); + info->raw_base + port->dataoffset, + info->raw_base + port->ctrloffset); if (info->raw_ioc_base) ata_port_desc(ap, "iocbase 0x%lx", info->raw_ioc_base); @@ -441,7 +443,7 @@ static int __devinit pata_icside_register_v5(struct pata_icside_info *info) info->nr_ports = 1; info->port[0] = &pata_icside_portinfo_v5; - info->raw_base = ecard_resource_start(ec, ECARD_RES_MEMC); + info->raw_base = ecard_resource_start(info->ec, ECARD_RES_MEMC); return 0; } @@ -522,7 +524,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info) ap->flags |= ATA_FLAG_SLAVE_POSS; ap->ops = &pata_icside_port_ops; - pata_icside_setup_ioaddr(ap, info->base, info->port[i]); + pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]); } return ata_host_activate(host, ec->irq, ata_interrupt, 0, diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 2e0279fdd7aa..f1b422f7c749 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -365,9 +365,9 @@ static const struct pci_device_id nv_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), SWNCQ }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), SWNCQ }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), SWNCQ }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, { } /* terminate list */ }; diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c index 1b58b010797f..241167878edf 100644 --- a/drivers/block/cryptoloop.c +++ b/drivers/block/cryptoloop.c @@ -150,13 +150,8 @@ cryptoloop_transfer(struct loop_device *lo, int cmd, u32 iv[4] = { 0, }; iv[0] = cpu_to_le32(IV & 0xffffffff); - sg_set_page(&sg_in, in_page); - sg_in.offset = in_offs; - sg_in.length = sz; - - sg_set_page(&sg_out, out_page); - sg_out.offset = out_offs; - sg_out.length = sz; + sg_set_page(&sg_in, in_page, sz, in_offs); + sg_set_page(&sg_out, out_page, sz, out_offs); desc.info = iv; err = encdecfunc(&desc, &sg_out, &sg_in, sz); diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 7276f7d207c2..fac4c6cd04f7 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -15,6 +15,7 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/list.h> +#include <linux/scatterlist.h> #include <asm/vio.h> #include <asm/ldc.h> diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 14143f2c484d..08e909dc7944 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -1428,9 +1428,9 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) scmd->state = UB_CMDST_INIT; scmd->nsg = 1; sg = &scmd->sgv[0]; - sg_set_page(sg, virt_to_page(sc->top_sense)); - sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1); - sg->length = UB_SENSE_SIZE; + sg_init_table(sg, UB_MAX_REQ_SG); + sg_set_page(sg, virt_to_page(sc->top_sense), UB_SENSE_SIZE, + (unsigned long)sc->top_sense & (PAGE_SIZE-1)); scmd->len = UB_SENSE_SIZE; scmd->lun = cmd->lun; scmd->done = ub_top_sense_done; @@ -1864,9 +1864,8 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, cmd->state = UB_CMDST_INIT; cmd->nsg = 1; sg = &cmd->sgv[0]; - sg_set_page(sg, virt_to_page(p)); - sg->offset = (unsigned long)p & (PAGE_SIZE-1); - sg->length = 8; + sg_init_table(sg, UB_MAX_REQ_SG); + sg_set_page(sg, virt_to_page(p), 8, (unsigned long)p & (PAGE_SIZE-1)); cmd->len = 8; cmd->lun = lun; cmd->done = ub_probe_done; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index a901eee64ba5..3cf7129d83e6 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -4,7 +4,9 @@ #include <linux/hdreg.h> #include <linux/virtio.h> #include <linux/virtio_blk.h> -#include <linux/virtio_blk.h> +#include <linux/scatterlist.h> + +#define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) static unsigned char virtblk_index = 'a'; struct virtio_blk @@ -23,7 +25,7 @@ struct virtio_blk mempool_t *pool; /* Scatterlist: can be too big for stack. */ - struct scatterlist sg[3+MAX_PHYS_SEGMENTS]; + struct scatterlist sg[VIRTIO_MAX_SG]; }; struct virtblk_req @@ -94,8 +96,8 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, if (blk_barrier_rq(vbr->req)) vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; - /* We have to zero this, otherwise blk_rq_map_sg gets upset. */ - memset(vblk->sg, 0, sizeof(vblk->sg)); + /* This init could be done at vblk creation time */ + sg_init_table(vblk->sg, VIRTIO_MAX_SG); sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr)); num = blk_rq_map_sg(q, vbr->req, vblk->sg+1); sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr)); diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 880b5dce3a62..d8bb44b98a6a 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -41,9 +41,9 @@ #include <linux/completion.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/scatterlist.h> #include <asm/vio.h> -#include <asm/scatterlist.h> #include <asm/iseries/hv_types.h> #include <asm/iseries/hv_lp_event.h> #include <asm/iseries/vio.h> @@ -258,6 +258,7 @@ static int send_request(struct request *req) cmd = viomajorsubtype_cdio | viocdwrite; } + sg_init_table(&sg, 1); if (blk_rq_map_sg(req->q, req, &sg) == 0) { printk(VIOCD_KERN_WARNING "error setting up scatter/gather list\n"); diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index 4e8de162fc12..c666b4e0933e 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -55,7 +55,7 @@ static void padlock_sha_bypass(struct crypto_tfm *tfm) if (ctx(tfm)->data && ctx(tfm)->used) { struct scatterlist sg; - sg_set_buf(&sg, ctx(tfm)->data, ctx(tfm)->used); + sg_init_one(&sg, ctx(tfm)->data, ctx(tfm)->used); crypto_hash_update(&ctx(tfm)->fallback, &sg, sg.length); } @@ -79,7 +79,7 @@ static void padlock_sha_update(struct crypto_tfm *tfm, if (unlikely(ctx(tfm)->bypass)) { struct scatterlist sg; - sg_set_buf(&sg, (uint8_t *)data, length); + sg_init_one(&sg, (uint8_t *)data, length); crypto_hash_update(&ctx(tfm)->fallback, &sg, length); return; } diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 410a0d13e35e..93f71fcfc04d 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -316,13 +316,13 @@ static int icside_dma_end(ide_drive_t *drive) drive->waiting_for_dma = 0; - disable_dma(state->dev->dma); + disable_dma(ECARD_DEV(state->dev)->dma); /* Teardown mappings after DMA has completed. */ dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents, hwif->sg_dma_direction); - return get_dma_residue(state->dev->dma) != 0; + return get_dma_residue(ECARD_DEV(state->dev)->dma) != 0; } static void icside_dma_start(ide_drive_t *drive) @@ -331,8 +331,8 @@ static void icside_dma_start(ide_drive_t *drive) struct icside_state *state = hwif->hwif_data; /* We can not enable DMA on both channels simultaneously. */ - BUG_ON(dma_channel_active(state->dev->dma)); - enable_dma(state->dev->dma); + BUG_ON(dma_channel_active(ECARD_DEV(state->dev)->dma)); + enable_dma(ECARD_DEV(state->dev)->dma); } static int icside_dma_setup(ide_drive_t *drive) @@ -350,7 +350,7 @@ static int icside_dma_setup(ide_drive_t *drive) /* * We can not enable DMA on both channels. */ - BUG_ON(dma_channel_active(state->dev->dma)); + BUG_ON(dma_channel_active(ECARD_DEV(state->dev)->dma)); icside_build_sglist(drive, rq); @@ -367,14 +367,14 @@ static int icside_dma_setup(ide_drive_t *drive) /* * Select the correct timing for this drive. */ - set_dma_speed(state->dev->dma, drive->drive_data); + set_dma_speed(ECARD_DEV(state->dev)->dma, drive->drive_data); /* * Tell the DMA engine about the SG table and * data direction. */ - set_dma_sg(state->dev->dma, hwif->sg_table, hwif->sg_nents); - set_dma_mode(state->dev->dma, dma_mode); + set_dma_sg(ECARD_DEV(state->dev)->dma, hwif->sg_table, hwif->sg_nents); + set_dma_mode(ECARD_DEV(state->dev)->dma, dma_mode); drive->waiting_for_dma = 1; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 95168833d069..dcda0f109df5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -582,9 +582,12 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); /* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. * We list them here and depend on the device side cable detection for them. + * + * Some optical devices with the buggy firmwares have the same problem. */ static const struct drive_list_entry ivb_list[] = { { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, + { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, { NULL , NULL } }; diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 3ef4fc10fe2c..1cd4e9cb0521 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cy82c693.c Version 0.41 Aug 27, 2007 + * linux/drivers/ide/pci/cy82c693.c Version 0.42 Oct 23, 2007 * * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator @@ -436,10 +436,10 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) hwif->ide_dma_on = &cy82c693_ide_dma_on; } -static __devinitdata ide_hwif_t *primary; - static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) { + static ide_hwif_t *primary; + if (PCI_FUNC(hwif->pci_dev->devfn) == 1) primary = hwif; else { diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index f44d70852c3c..06885697ed7b 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -49,7 +49,7 @@ static int __init ide_generic_all_on(char *unused) printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); return 1; } -__setup("all-generic-ide", ide_generic_all_on); +const __setup("all-generic-ide", ide_generic_all_on); #endif module_param_named(all_generic_ide, ide_generic_all, bool, 0444); MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 612b795241bf..5682895d36d9 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.20 Oct 1, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.21 Oct 23, 2007 * * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -433,7 +433,7 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = { sixty_six_base_hpt37x }; -static struct hpt_info hpt36x __devinitdata = { +static const struct hpt_info hpt36x __devinitdata = { .chip_name = "HPT36x", .chip_type = HPT36x, .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, @@ -441,7 +441,7 @@ static struct hpt_info hpt36x __devinitdata = { .settings = hpt36x_settings }; -static struct hpt_info hpt370 __devinitdata = { +static const struct hpt_info hpt370 __devinitdata = { .chip_name = "HPT370", .chip_type = HPT370, .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, @@ -449,7 +449,7 @@ static struct hpt_info hpt370 __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt370a __devinitdata = { +static const struct hpt_info hpt370a __devinitdata = { .chip_name = "HPT370A", .chip_type = HPT370A, .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, @@ -457,7 +457,7 @@ static struct hpt_info hpt370a __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt374 __devinitdata = { +static const struct hpt_info hpt374 __devinitdata = { .chip_name = "HPT374", .chip_type = HPT374, .udma_mask = ATA_UDMA5, @@ -465,7 +465,7 @@ static struct hpt_info hpt374 __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt372 __devinitdata = { +static const struct hpt_info hpt372 __devinitdata = { .chip_name = "HPT372", .chip_type = HPT372, .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -473,7 +473,7 @@ static struct hpt_info hpt372 __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt372a __devinitdata = { +static const struct hpt_info hpt372a __devinitdata = { .chip_name = "HPT372A", .chip_type = HPT372A, .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -481,7 +481,7 @@ static struct hpt_info hpt372a __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt302 __devinitdata = { +static const struct hpt_info hpt302 __devinitdata = { .chip_name = "HPT302", .chip_type = HPT302, .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -489,7 +489,7 @@ static struct hpt_info hpt302 __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt371 __devinitdata = { +static const struct hpt_info hpt371 __devinitdata = { .chip_name = "HPT371", .chip_type = HPT371, .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -497,7 +497,7 @@ static struct hpt_info hpt371 __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt372n __devinitdata = { +static const struct hpt_info hpt372n __devinitdata = { .chip_name = "HPT372N", .chip_type = HPT372N, .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -505,7 +505,7 @@ static struct hpt_info hpt372n __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt302n __devinitdata = { +static const struct hpt_info hpt302n __devinitdata = { .chip_name = "HPT302N", .chip_type = HPT302N, .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -513,7 +513,7 @@ static struct hpt_info hpt302n __devinitdata = { .settings = hpt37x_settings }; -static struct hpt_info hpt371n __devinitdata = { +static const struct hpt_info hpt371n __devinitdata = { .chip_name = "HPT371N", .chip_type = HPT371N, .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, @@ -1508,7 +1508,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { */ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - struct hpt_info *info = NULL; + const struct hpt_info *info = NULL; struct pci_dev *dev2 = NULL; struct ide_port_info d; u8 idx = id->driver_data; @@ -1522,7 +1522,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic if (rev < 3) info = &hpt36x; else { - static struct hpt_info *hpt37x_info[] = + static const struct hpt_info *hpt37x_info[] = { &hpt370, &hpt370a, &hpt372, &hpt372n }; info = hpt37x_info[min_t(u8, rev, 6) - 3]; @@ -1552,7 +1552,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic d.name = info->chip_name; d.udma_mask = info->udma_mask; - pci_set_drvdata(dev, info); + pci_set_drvdata(dev, (void *)info); if (info == &hpt36x || info == &hpt374) dev2 = pci_get_slot(dev->bus, dev->devfn + 1); @@ -1560,7 +1560,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic if (dev2) { int ret; - pci_set_drvdata(dev2, info); + pci_set_drvdata(dev2, (void *)info); if (info == &hpt374) hpt374_init(dev, dev2); diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index d2c8b5524f28..0a7b3202066d 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -324,17 +324,18 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) pci_disable_device(dev); pci_set_power_state(dev, pci_choose_state(dev, state)); - dev->current_state = state.event; return 0; } static int sc1200_resume (struct pci_dev *dev) { ide_hwif_t *hwif = NULL; + int i; + + i = pci_enable_device(dev); + if (i) + return i; - pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state - dev->current_state = PM_EVENT_ON; - pci_enable_device(dev); // // loop over all interfaces that are part of this pci device: // diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c index 3051e312fdc8..f5f4983dfbf3 100644 --- a/drivers/ieee1394/dma.c +++ b/drivers/ieee1394/dma.c @@ -111,8 +111,8 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, unsigned long va = (unsigned long)dma->kvirt + (i << PAGE_SHIFT); - sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va)); - dma->sglist[i].length = PAGE_SIZE; + sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va), + PAGE_SIZE, 0); } /* map sglist to the IOMMU */ diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 14159ff29408..4e3128ff73c1 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -171,9 +171,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, if (vma_list && !is_vm_hugetlb_page(vma_list[i + off])) umem->hugetlb = 0; - sg_set_page(&chunk->page_list[i], page_list[i + off]); - chunk->page_list[i].offset = 0; - chunk->page_list[i].length = PAGE_SIZE; + sg_set_page(&chunk->page_list[i], page_list[i + off], PAGE_SIZE, 0); } chunk->nmap = ib_dma_map_sg(context->device, diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 007b38157fc4..1f4d27d7c16d 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -113,9 +113,7 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m if (!page) return -ENOMEM; - sg_set_page(mem, page); - mem->length = PAGE_SIZE << order; - mem->offset = 0; + sg_set_page(mem, page, PAGE_SIZE << order, 0); return 0; } @@ -481,9 +479,8 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, if (ret < 0) goto out; - sg_set_page(&db_tab->page[i].mem, pages[0]); - db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE; - db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK; + sg_set_page(&db_tab->page[i].mem, pages[0], MTHCA_ICM_PAGE_SIZE, + uaddr & ~PAGE_MASK); ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE); if (ret < 0) { diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c index 034d41a61ae1..e0331e0094f1 100644 --- a/drivers/isdn/sc/shmem.c +++ b/drivers/isdn/sc/shmem.c @@ -28,15 +28,15 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n) { unsigned long flags; unsigned char ch; + unsigned long dest_rem = ((unsigned long) dest) % 0x4000; - if(!IS_VALID_CARD(card)) { + if (!IS_VALID_CARD(card)) { pr_debug("Invalid param: %d is not a valid card id\n", card); return; } - if(n > SRAM_PAGESIZE) { + if (n > SRAM_PAGESIZE) return; - } /* * determine the page to load from the address @@ -50,8 +50,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n) outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80, sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]); - memcpy_toio(sc_adapter[card]->rambase + - ((unsigned long) dest % 0x4000), src, n); + memcpy_toio(sc_adapter[card]->rambase + dest_rem, src, n); spin_unlock_irqrestore(&sc_adapter[card]->lock, flags); pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename, ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80); diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 35d19ae58de7..cb4c67025d52 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -128,9 +128,12 @@ static void unmap_switcher(void) __free_pages(switcher_page[i], 0); } -/*L:305 +/*H:032 * Dealing With Guest Memory. * + * Before we go too much further into the Host, we need to grok the routines + * we use to deal with Guest memory. + * * When the Guest gives us (what it thinks is) a physical address, we can use * the normal copy_from_user() & copy_to_user() on the corresponding place in * the memory region allocated by the Launcher. diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c index 9d5184c7c14a..b478affe8f91 100644 --- a/drivers/lguest/hypercalls.c +++ b/drivers/lguest/hypercalls.c @@ -90,6 +90,7 @@ static void do_hcall(struct lguest *lg, struct hcall_args *args) lg->pending_notify = args->arg1; break; default: + /* It should be an architecture-specific hypercall. */ if (lguest_arch_do_hcall(lg, args)) kill_guest(lg, "Bad hypercall %li\n", args->arg0); } @@ -157,7 +158,6 @@ static void do_async_hcalls(struct lguest *lg) * Guest makes a hypercall, we end up here to set things up: */ static void initialize(struct lguest *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) { @@ -174,7 +174,8 @@ static void initialize(struct lguest *lg) || get_user(lg->noirq_end, &lg->lguest_data->noirq_end)) kill_guest(lg, "bad guest page %p", lg->lguest_data); - /* We write the current time into the Guest's data page once now. */ + /* We write the current time into the Guest's data page once so it can + * set its clock. */ write_timestamp(lg); /* page_tables.c will also do some setup. */ @@ -182,8 +183,8 @@ static void initialize(struct lguest *lg) /* This is the one case where the above accesses might have been the * first write to a Guest page. This may have caused a copy-on-write - * fault, but the Guest might be referring to the old (read-only) - * page. */ + * fault, but the old page might be (read-only) in the Guest + * pagetable. */ guest_pagetable_clear_all(lg); } @@ -220,7 +221,7 @@ void do_hypercalls(struct lguest *lg) * Normally it doesn't matter: the Guest will run again and * update the trap number before we come back here. * - * However, if we are signalled or the Guest sends DMA to the + * However, if we are signalled or the Guest sends I/O to the * Launcher, the run_guest() loop will exit without running the * Guest. When it comes back it would try to re-run the * hypercall. */ diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index 82966982cb38..2b66f79c208b 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c @@ -92,8 +92,8 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err) /* 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: the Guest copies - * it back in "lguest_iret". */ + * Guest's "irq_enabled" field into the eflags word: we saw the Guest + * copy it back in "lguest_iret". */ eflags = lg->regs->eflags; if (get_user(irq_enable, &lg->lguest_data->irq_enabled) == 0 && !(irq_enable & X86_EFLAGS_IF)) @@ -124,7 +124,7 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err) kill_guest(lg, "Disabling interrupts"); } -/*H:200 +/*H:205 * Virtual Interrupts. * * maybe_do_interrupt() gets called before every entry to the Guest, to see if @@ -256,19 +256,21 @@ int deliver_trap(struct lguest *lg, unsigned int num) * 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)) return 0; - set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, has_err(num)); + set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, + has_err(num)); return 1; } /*H:250 Here's the hard part: returning to the Host every time a trap happens * and then calling deliver_trap() and re-entering the Guest is slow. - * Particularly because Guest userspace system calls are traps (trap 128). + * Particularly because Guest userspace system calls are traps (usually trap + * 128). * * So we'd like to set up the IDT to tell the CPU to deliver traps directly * into the Guest. This is possible, but the complexities cause the size of * this file to double! However, 150 lines of code is worth writing for taking * system calls down from 1750ns to 270ns. Plus, if lguest didn't do it, all - * the other hypervisors would tease it. + * the other hypervisors would beat it up at lunchtime. * * This routine indicates if a particular trap number could be delivered * directly. */ @@ -331,7 +333,7 @@ void pin_stack_pages(struct lguest *lg) * change stacks on each context switch. */ void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages) { - /* You are not allowd have a stack segment with privilege level 0: bad + /* 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); @@ -350,7 +352,7 @@ void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages) * part of the Host: page table handling. */ /*H:235 This is the routine which actually checks the Guest's IDT entry and - * transfers it into our entry in "struct lguest": */ + * transfers it into the entry in "struct lguest": */ static void set_trap(struct lguest *lg, struct desc_struct *trap, unsigned int num, u32 lo, u32 hi) { @@ -456,6 +458,18 @@ void copy_traps(const struct lguest *lg, struct desc_struct *idt, } } +/*H:200 + * The Guest Clock. + * + * There are two sources of virtual interrupts. We saw one in lguest_user.c: + * the Launcher sending interrupts for virtual devices. The other is the Guest + * timer interrupt. + * + * The Guest uses the LHCALL_SET_CLOCKEVENT hypercall to tell us how long to + * the next timer interrupt (in nanoseconds). We use the high-resolution timer + * infrastructure to set a callback at that time. + * + * 0 means "turn off the clock". */ void guest_set_clockevent(struct lguest *lg, unsigned long delta) { ktime_t expires; @@ -466,20 +480,27 @@ void guest_set_clockevent(struct lguest *lg, unsigned long delta) return; } + /* We use wallclock time here, so the Guest might not be running for + * 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); } +/* 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); + /* Remember the first interrupt is the timer interrupt. */ set_bit(0, lg->irqs_pending); + /* If the Guest is actually stopped, we need to wake it up. */ if (lg->halted) wake_up_process(lg->tsk); return HRTIMER_NORESTART; } +/* This sets up the timer for this Guest. */ void init_clockdev(struct lguest *lg) { hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS); diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index d9144beca82c..86924891b5eb 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h @@ -74,9 +74,6 @@ struct lguest u32 pgdidx; struct pgdir pgdirs[4]; - /* Cached wakeup: we hold a reference to this task. */ - struct task_struct *wake; - unsigned long noirq_start, noirq_end; unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */ @@ -103,7 +100,7 @@ int lguest_address_ok(const struct lguest *lg, void __lgread(struct lguest *, void *, unsigned long, unsigned); void __lgwrite(struct lguest *, unsigned long, const void *, unsigned); -/*L:306 Using memory-copy operations like that is usually inconvient, so we +/*H:035 Using memory-copy operations like that is usually inconvient, so we * have the following helper macros which read and write a specific type (often * an unsigned long). * @@ -191,7 +188,7 @@ void write_timestamp(struct lguest *lg); * Let's step aside for the moment, to study one important routine that's used * widely in the Host code. * - * There are many cases where the Guest does something invalid, like pass crap + * There are many cases where the Guest can do something invalid, like pass crap * to a hypercall. Since only the Guest kernel can make hypercalls, it's quite * acceptable to simply terminate the Guest and give the Launcher a nicely * formatted reason. It's also simpler for the Guest itself, which doesn't diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 71c64837b437..8904f72f97c6 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c @@ -53,7 +53,8 @@ struct lguest_device { * Device configurations * * The configuration information for a device consists of a series of fields. - * The device will look for these fields during setup. + * 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. @@ -122,8 +123,8 @@ static void lg_set_status(struct virtio_device *vdev, u8 status) * The other piece of infrastructure virtio needs is a "virtqueue": a way of * the Guest device registering buffers for the other side to read from or * write into (ie. send and receive buffers). Each device can have multiple - * virtqueues: for example the console has one queue for sending and one for - * receiving. + * virtqueues: for example the console driver uses one queue for sending and + * another for receiving. * * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue * already exists in virtio_ring.c. We just need to connect it up. @@ -158,7 +159,7 @@ static void lg_notify(struct virtqueue *vq) * * This is kind of an ugly duckling. It'd be nicer to have a standard * representation of a virtqueue in the configuration space, but it seems that - * everyone wants to do it differently. The KVM guys want the Guest to + * everyone wants to do it differently. The KVM coders want the Guest to * allocate its own pages and tell the Host where they are, but for lguest it's * simpler for the Host to simply tell us where the pages are. * @@ -284,6 +285,8 @@ static void add_lguest_device(struct lguest_device_desc *d) { struct lguest_device *ldev; + /* Start with zeroed memory; Linux's device layer seems to count on + * it. */ ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); if (!ldev) { printk(KERN_EMERG "Cannot allocate lguest dev %u\n", diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index ee405b38383d..9d716fa42cad 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c @@ -8,20 +8,22 @@ #include <linux/fs.h> #include "lg.h" -/*L:315 To force the Guest to stop running and return to the Launcher, the - * Waker sets writes LHREQ_BREAK and the value "1" to /dev/lguest. The - * Launcher then writes LHREQ_BREAK and "0" to release the Waker. */ +/*L:055 When something happens, the Waker process needs a way to stop the + * kernel running the Guest and return to the Launcher. So the Waker writes + * 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) { unsigned long on; - /* Fetch whether they're turning break on or off.. */ + /* Fetch whether they're turning break on or off. */ if (get_user(on, input) != 0) return -EFAULT; if (on) { lg->break_out = 1; - /* Pop it out (may be running on different CPU) */ + /* Pop it out of the Guest (may be running on different CPU) */ wake_up_process(lg->tsk); /* Wait for them to reset it */ return wait_event_interruptible(lg->break_wq, !lg->break_out); @@ -58,7 +60,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) if (!lg) return -EINVAL; - /* If you're not the task which owns the guest, go away. */ + /* If you're not the task which owns the Guest, go away. */ if (current != lg->tsk) return -EPERM; @@ -92,8 +94,8 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) * base: The start of the Guest-physical memory inside the Launcher memory. * * pfnlimit: The highest (Guest-physical) page number the Guest should be - * allowed to access. The Launcher has to live in Guest memory, so it sets - * this to ensure the Guest can't reach it. + * allowed to access. The Guest memory lives inside the Launcher, so it sets + * this to ensure the Guest can only reach its own memory. * * pgdir: The (Guest-physical) address of the top of the initial Guest * pagetables (which are set up by the Launcher). @@ -189,7 +191,7 @@ unlock: } /*L:010 The first operation the Launcher does must be a write. All writes - * start with a 32 bit number: for the first write this must be + * start with an unsigned long number: for the first write this must be * LHREQ_INITIALIZE to set up the Guest. After that the Launcher can use * writes of other values to send interrupts. */ static ssize_t write(struct file *file, const char __user *in, @@ -275,8 +277,7 @@ static int close(struct inode *inode, struct file *file) * The Launcher is the Host userspace program which sets up, runs and services * the Guest. In fact, many comments in the Drivers which refer to "the Host" * doing things are inaccurate: the Launcher does all the device handling for - * the Guest. The Guest can't tell what's done by the the Launcher and what by - * the Host. + * the Guest, but the Guest can't know that. * * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we * shall see more of that later. diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 2a45f0691c9b..fffabb327157 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c @@ -26,7 +26,8 @@ * * We use two-level page tables for the Guest. If you're not entirely * comfortable with virtual addresses, physical addresses and page tables then - * I recommend you review lguest.c's "Page Table Handling" (with diagrams!). + * I recommend you review arch/x86/lguest/boot.c's "Page Table Handling" (with + * diagrams!). * * The Guest keeps page tables, but we maintain the actual ones here: these are * called "shadow" page tables. Which is a very Guest-centric name: these are @@ -36,11 +37,11 @@ * * Anyway, this is the most complicated part of the Host code. There are seven * parts to this: - * (i) Setting up a page table entry for the Guest when it faults, - * (ii) Setting up the page table entry for the Guest stack, - * (iii) Setting up a page table entry when the Guest tells us it has changed, + * (i) Looking up a page table entry when the Guest faults, + * (ii) Making sure the Guest stack is mapped, + * (iii) Setting up a page table entry when the Guest tells us one has changed, * (iv) Switching page tables, - * (v) Flushing (thowing away) page tables, + * (v) Flushing (throwing away) page tables, * (vi) Mapping the Switcher when the Guest is about to run, * (vii) Setting up the page tables initially. :*/ @@ -57,16 +58,15 @@ static DEFINE_PER_CPU(pte_t *, switcher_pte_pages); #define switcher_pte_page(cpu) per_cpu(switcher_pte_pages, cpu) -/*H:320 With our shadow and Guest types established, we need to deal with - * them: the page table code is curly enough to need helper functions to keep - * it clear and clean. +/*H:320 The page table code is curly enough to need helper functions to keep it + * clear and clean. * * There are two functions which return pointers to the shadow (aka "real") * page tables. * * spgd_addr() takes the virtual address and returns a pointer to the top-level - * page directory entry for that address. Since we keep track of several page - * tables, the "i" argument tells us which one we're interested in (it's + * page directory entry (PGD) for that address. Since we keep track of several + * page tables, the "i" argument tells us which one we're interested in (it's * usually the current one). */ static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr) { @@ -81,9 +81,9 @@ static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr) return &lg->pgdirs[i].pgdir[index]; } -/* This routine then takes the PGD entry given above, which contains the - * address of the PTE page. It then returns a pointer to the PTE entry for the - * given address. */ +/* This routine then takes the page directory entry returned above, which + * contains the address of the page table entry (PTE) page. It then returns a + * pointer to the PTE entry for the given address. */ static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr) { pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT); @@ -191,7 +191,7 @@ static void check_gpgd(struct lguest *lg, pgd_t gpgd) } /*H:330 - * (i) Setting up a page table entry for the Guest when it faults + * (i) Looking up a page table entry when the Guest faults. * * We saw this call in run_guest(): when we see a page fault in the Guest, we * come here. That's because we only set up the shadow page tables lazily as @@ -199,7 +199,7 @@ static void check_gpgd(struct lguest *lg, pgd_t gpgd) * and return to the Guest without it knowing. * * If we fixed up the fault (ie. we mapped the address), this routine returns - * true. */ + * 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) { pgd_t gpgd; @@ -246,16 +246,16 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode) if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW)) return 0; - /* User access to a kernel page? (bit 3 == user access) */ + /* User access to a kernel-only page? (bit 3 == user access) */ if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER)) return 0; /* Check that the Guest PTE flags are OK, and the page number is below * the pfn_limit (ie. not mapping the Launcher binary). */ check_gpte(lg, gpte); + /* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */ gpte = pte_mkyoung(gpte); - if (errcode & 2) gpte = pte_mkdirty(gpte); @@ -272,23 +272,28 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode) else /* If this is a read, don't set the "writable" bit in the page * table entry, even if the Guest says it's writable. That way - * we come back here when a write does actually ocur, so we can - * update the Guest's _PAGE_DIRTY flag. */ + * we will come back here when a write does actually occur, so + * we can update the Guest's _PAGE_DIRTY flag. */ *spte = gpte_to_spte(lg, pte_wrprotect(gpte), 0); /* Finally, we write the Guest PTE entry back: we've set the * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */ lgwrite(lg, gpte_ptr, pte_t, gpte); - /* We succeeded in mapping the page! */ + /* The fault is fixed, the page table is populated, the mapping + * manipulated, the result returned and the code complete. A small + * delay and a trace of alliteration are the only indications the Guest + * has that a page fault occurred at all. */ return 1; } -/*H:360 (ii) Setting up the page table entry for the Guest stack. +/*H:360 + * (ii) Making sure the Guest stack is mapped. * - * Remember pin_stack_pages() which makes sure the stack is mapped? It could - * simply call demand_page(), but as we've seen that logic is quite long, and - * usually the stack pages are already mapped anyway, so it's not required. + * Remember that direct traps into the Guest need a mapped Guest kernel stack. + * pin_stack_pages() calls us here: we could simply call demand_page(), but as + * we've seen that logic is quite long, and usually the stack pages are already + * mapped, so it's overkill. * * This is a quick version which answers the question: is this virtual address * mapped by the shadow page tables, and is it writable? */ @@ -297,7 +302,7 @@ static int page_writable(struct lguest *lg, unsigned long vaddr) pgd_t *spgd; unsigned long flags; - /* Look at the top level entry: is it present? */ + /* Look at the current top level entry: is it present? */ spgd = spgd_addr(lg, lg->pgdidx, vaddr); if (!(pgd_flags(*spgd) & _PAGE_PRESENT)) return 0; @@ -333,15 +338,14 @@ static void release_pgd(struct lguest *lg, pgd_t *spgd) release_pte(ptepage[i]); /* Now we can free the page of PTEs */ free_page((long)ptepage); - /* And zero out the PGD entry we we never release it twice. */ + /* And zero out the PGD entry so we never release it twice. */ *spgd = __pgd(0); } } -/*H:440 (v) Flushing (thowing away) page tables, - * - * We saw flush_user_mappings() called when we re-used a top-level pgdir page. - * It simply releases every PTE page from 0 up to the kernel address. */ +/*H:445 We saw flush_user_mappings() twice: once from the flush_user_mappings() + * hypercall and once in new_pgdir() when we re-used a top-level pgdir page. + * It simply releases every PTE page from 0 up to the Guest's kernel address. */ static void flush_user_mappings(struct lguest *lg, int idx) { unsigned int i; @@ -350,8 +354,10 @@ static void flush_user_mappings(struct lguest *lg, int idx) release_pgd(lg, lg->pgdirs[idx].pgdir + i); } -/* The Guest also has a hypercall to do this manually: it's used when a large - * number of mappings have been changed. */ +/*H:440 (v) Flushing (throwing away) page tables, + * + * 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) { /* Drop the userspace part of the current page table. */ @@ -423,8 +429,9 @@ static unsigned int new_pgdir(struct lguest *lg, /*H:430 (iv) Switching page tables * - * This is what happens when the Guest changes page tables (ie. changes the - * top-level pgdir). This happens on almost every context switch. */ + * 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) { int newpgdir, repin = 0; @@ -443,7 +450,8 @@ void guest_new_pagetable(struct lguest *lg, unsigned long pgtable) } /*H:470 Finally, a routine which throws away everything: all PGD entries in all - * the shadow page tables. This is used when we destroy the Guest. */ + * the shadow page tables, including the Guest's kernel mappings. This is used + * when we destroy the Guest. */ static void release_all_pagetables(struct lguest *lg) { unsigned int i, j; @@ -458,13 +466,22 @@ static void release_all_pagetables(struct lguest *lg) /* We also throw away everything when a Guest tells us it's changed a kernel * mapping. Since kernel mappings are in every page table, it's easiest to - * throw them all away. This is amazingly slow, but thankfully rare. */ + * 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) { release_all_pagetables(lg); /* We need the Guest kernel stack mapped again. */ pin_stack_pages(lg); } +/*:*/ +/*M:009 Since we throw away all mappings when a kernel mapping changes, our + * performance sucks for guests using highmem. In fact, a guest with + * PAGE_OFFSET 0xc0000000 (the default) and more than about 700MB of RAM is + * usually slower than a Guest with less memory. + * + * This, of course, cannot be fixed. It would take some kind of... well, I + * don't know, but the term "puissant code-fu" comes to mind. :*/ /*H:420 This is the routine which actually sets the page table entry for then * "idx"'th shadow page table. @@ -483,7 +500,7 @@ void guest_pagetable_clear_all(struct lguest *lg) static void do_set_pte(struct lguest *lg, int idx, unsigned long vaddr, pte_t gpte) { - /* Look up the matching shadow page directot entry. */ + /* Look up the matching shadow page directory entry. */ pgd_t *spgd = spgd_addr(lg, idx, vaddr); /* If the top level isn't present, there's no entry to update. */ @@ -500,7 +517,8 @@ static void do_set_pte(struct lguest *lg, int idx, *spte = gpte_to_spte(lg, gpte, pte_flags(gpte) & _PAGE_DIRTY); } else - /* Otherwise we can demand_page() it in later. */ + /* Otherwise kill it and we can demand_page() it in + * later. */ *spte = __pte(0); } } @@ -535,7 +553,7 @@ void guest_set_pte(struct lguest *lg, } /*H:400 - * (iii) Setting up a page table entry when the Guest tells us it has changed. + * (iii) Setting up a page table entry when the Guest tells us one has changed. * * Just like we did in interrupts_and_traps.c, it makes sense for us to deal * with the other side of page tables while we're here: what happens when the @@ -612,9 +630,10 @@ void free_guest_pagetable(struct lguest *lg) /*H:480 (vi) Mapping the Switcher when the Guest is about to run. * - * The Switcher and the two pages for this CPU need to be available to the + * The Switcher and the two pages for this CPU need to be visible in the * 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. */ + * 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) { pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); @@ -677,6 +696,18 @@ static __init void populate_switcher_pte_page(unsigned int cpu, __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED)); } +/* We've made it through the page table code. Perhaps our tired brains are + * still processing the details, or perhaps we're simply glad it's over. + * + * If nothing else, note that all this complexity in juggling shadow page + * tables in sync with the Guest's page tables is for one reason: for most + * Guests this page table dance determines how bad performance will be. This + * is why Xen uses exotic direct Guest pagetable manipulation, and why both + * Intel and AMD have implemented shadow page table support directly into + * hardware. + * + * There is just one file remaining in the Host. */ + /*H:510 At boot or module load time, init_pagetables() allocates and populates * the Switcher PTE page for each CPU. */ __init int init_pagetables(struct page **switcher_page, unsigned int pages) diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c index c2434ec99f7b..9e189cbec7dd 100644 --- a/drivers/lguest/segments.c +++ b/drivers/lguest/segments.c @@ -12,8 +12,6 @@ #include "lg.h" /*H:600 - * We've almost completed the Host; there's just one file to go! - * * Segments & The Global Descriptor Table * * (That title sounds like a bad Nerdcore group. Not to suggest that there are @@ -55,7 +53,7 @@ static int ignored_gdt(unsigned int num) || num == GDT_ENTRY_DOUBLEFAULT_TSS); } -/*H:610 Once the GDT has been changed, we fix the new entries up a little. We +/*H:630 Once the Guest gave us new GDT entries, we fix them up a little. We * don't care if they're invalid: the worst that can happen is a General * 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 @@ -84,25 +82,33 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end) } } -/* This routine is called at boot or modprobe time for each CPU to set up the - * "constant" GDT entries for Guests running on that CPU. */ +/*H:610 Like the IDT, we never simply use the GDT the Guest gives us. We keep + * a GDT for each CPU, and copy across the Guest's entries each time we want to + * run the Guest on that CPU. + * + * This routine is called at boot or modprobe time for each CPU to set up the + * constant GDT entries: the ones which are the same no matter what Guest we're + * running. */ void setup_default_gdt_entries(struct lguest_ro_state *state) { struct desc_struct *gdt = state->guest_gdt; unsigned long tss = (unsigned long)&state->guest_tss; - /* The hypervisor segments are full 0-4G segments, privilege level 0 */ + /* The Switcher segments are full 0-4G segments, privilege level 0 */ gdt[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT; gdt[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT; - /* The TSS segment refers to the TSS entry for this CPU, so we cannot - * copy it from the Guest. Forgive the magic flags */ + /* The TSS segment refers to the TSS entry for this particular CPU. + * Forgive the magic flags: the 0x8900 means the entry is Present, it's + * privilege level 0 Available 386 TSS system segment, and the 0x67 + * means Saturn is eclipsed by Mercury in the twelfth house. */ gdt[GDT_ENTRY_TSS].a = 0x00000067 | (tss << 16); gdt[GDT_ENTRY_TSS].b = 0x00008900 | (tss & 0xFF000000) | ((tss >> 16) & 0x000000FF); } -/* This routine is called before the Guest is run for the first time. */ +/* This routine sets up the initial Guest GDT for booting. All entries start + * as 0 (unusable). */ void setup_guest_gdt(struct lguest *lg) { /* Start with full 0-4G segments... */ @@ -114,13 +120,8 @@ void setup_guest_gdt(struct lguest *lg) lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13); } -/* Like the IDT, we never simply use the GDT the Guest gives us. We set up the - * GDTs for each CPU, then we copy across the entries each time we want to run - * a different Guest on that CPU. */ - -/* A partial GDT load, for the three "thead-local storage" entries. Otherwise - * it's just like load_guest_gdt(). So much, in fact, it would probably be - * neater to have a single hypercall to cover both. */ +/*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) { unsigned int i; @@ -129,7 +130,9 @@ void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt) gdt[i] = lg->arch.gdt[i]; } -/* This is the full version */ +/*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) { unsigned int i; @@ -141,7 +144,8 @@ void copy_gdt(const struct lguest *lg, struct desc_struct *gdt) gdt[i] = lg->arch.gdt[i]; } -/* This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). */ +/*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) { /* We assume the Guest has the same number of GDT entries as the @@ -157,16 +161,22 @@ void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num) lg->changed |= CHANGED_GDT; } +/* This is the fast-track version for just changing the three TLS entries. + * 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) { struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN]; __lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES); fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1); + /* Note that just the TLS entries have changed. */ lg->changed |= CHANGED_GDT_TLS; } +/*:*/ -/* +/*H:660 * With this, we have finished the Host. * * Five of the seven parts of our task are complete. You have made it through diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 9eed12d5a395..482aec2a9631 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -63,7 +63,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu) static DEFINE_PER_CPU(struct lguest *, last_guest); /*S:010 - * We are getting close to the Switcher. + * We approach the Switcher. * * Remember that each CPU has two pages which are visible to the Guest when it * runs on that CPU. This has to contain the state for that Guest: we copy the @@ -134,7 +134,7 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) * * The lcall also pushes the old code segment (KERNEL_CS) onto the * stack, then the address of this call. This stack layout happens to - * exactly match the stack of an interrupt... */ + * exactly match the stack layout created by an interrupt... */ asm volatile("pushf; lcall *lguest_entry" /* This is how we tell GCC that %eax ("a") and %ebx ("b") * are changed by this routine. The "=" means output. */ @@ -151,40 +151,46 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages) } /*:*/ +/*M:002 There are hooks in the scheduler which we can register to tell when we + * get kicked off the CPU (preempt_notifier_register()). This would allow us + * to lazily disable SYSENTER which would regain some performance, and should + * also simplify copy_in_guest_info(). Note that we'd still need to restore + * things when we exit to Launcher userspace, but that's fairly easy. + * + * The hooks were designed for KVM, but we can also put them to good use. :*/ + /*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) { - /* 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. */ + /* 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) lguest_set_ts(); - /* SYSENTER is an optimized way of doing system calls. We - * can't allow it because it always jumps to privilege level 0. - * A normal Guest won't try it because we don't advertise it in - * CPUID, but a malicious Guest (or malicious Guest userspace - * program) could, so we tell the CPU to disable it before - * running the Guest. */ + /* SYSENTER is an optimized way of doing system calls. We can't allow + * it because it always jumps to privilege level 0. A normal Guest + * won't try it because we don't advertise it in CPUID, but a malicious + * Guest (or malicious Guest userspace program) could, so we tell the + * CPU to disable it before running the Guest. */ if (boot_cpu_has(X86_FEATURE_SEP)) wrmsr(MSR_IA32_SYSENTER_CS, 0, 0); - /* Now we actually run the Guest. It will pop back out when - * something interesting happens, and we can examine its - * registers to see what it was doing. */ + /* 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())); - /* The "regs" pointer contains two extra entries which are not - * really registers: a trap number which says what interrupt or - * trap made the switcher code come back, and an error code - * which some traps set. */ + /* Note that the "regs" pointer contains two extra entries which are + * not really registers: a trap number which says what interrupt or + * trap made the switcher code come back, and an error code which some + * traps set. */ - /* If the Guest page faulted, then the cr2 register will tell - * us the 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 the Guest page faulted, then the cr2 register will tell us the + * 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(); /* Similarly, if we took a trap because the Guest used the FPU, @@ -197,14 +203,15 @@ void lguest_arch_run_guest(struct lguest *lg) wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); } -/*H:130 Our Guest is usually so well behaved; it never tries to do things it - * isn't allowed to. Unfortunately, Linux's paravirtual infrastructure isn't - * quite complete, because it doesn't contain replacements for the Intel I/O - * instructions. As a result, the Guest sometimes fumbles across one during - * the boot process as it probes for various things which are usually attached - * to a PC. +/*H:130 Now we've examined the hypercall code; our Guest can make requests. + * Our Guest is usually so well behaved; it never tries to do things it isn't + * allowed to, and uses hypercalls instead. Unfortunately, Linux's paravirtual + * infrastructure isn't quite complete, because it doesn't contain replacements + * for the Intel I/O instructions. As a result, the Guest sometimes fumbles + * across one during the boot process as it probes for various things which are + * usually attached to a PC. * - * When the Guest uses one of these instructions, we get trap #13 (General + * 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) @@ -275,43 +282,43 @@ static int emulate_insn(struct lguest *lg) void lguest_arch_handle_trap(struct lguest *lg) { switch (lg->regs->trapnum) { - case 13: /* We've intercepted a GPF. */ - /* 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. */ + 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)) return; } break; - case 14: /* We've intercepted a page fault. */ - /* The Guest accessed a virtual address that wasn't - * mapped. This happens a lot: we don't actually set - * up most of the page tables for the Guest at all when - * we start: as it runs it asks for more and more, and - * we set them up as required. In this case, we don't - * even tell the Guest that the fault happened. - * - * The errcode tells whether this was a read or a - * write, and whether kernel or userspace code. */ + case 14: /* We've intercepted a Page Fault. */ + /* The Guest accessed a virtual address that wasn't mapped. + * This happens a lot: we don't actually set up most of the + * page tables for the Guest at all when we start: as it runs + * it asks for more and more, and we set them up as + * required. In this case, we don't even tell the Guest that + * the fault happened. + * + * 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)) return; - /* OK, it's really not there (or not OK): the Guest - * needs to know. We write out the cr2 value so it - * knows where the fault occurred. - * - * Note that if the Guest were really messed up, this - * could happen before it's done the INITIALIZE - * hypercall, so lg->lguest_data will be NULL */ + /* OK, it's really not there (or not OK): the Guest needs to + * know. We write out the cr2 value so it knows where the + * fault occurred. + * + * Note that if the Guest were really messed up, this could + * 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)) 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 the Guest doesn't want to know, we already restored the + * Floating Point Unit, so we just continue without telling + * it. */ if (!lg->ts) return; break; @@ -536,9 +543,6 @@ int lguest_arch_init_hypercalls(struct lguest *lg) return 0; } -/* Now we've examined the hypercall code; our Guest can make requests. There - * is one other way we can do things for the Guest, as we see in - * emulate_insn(). :*/ /*L:030 lguest_arch_setup_regs() * @@ -562,7 +566,7 @@ void lguest_arch_setup_regs(struct lguest *lg, unsigned long start) * is supposed to always be "1". Bit 9 (0x200) controls whether * interrupts are enabled. We always leave interrupts enabled while * running the Guest. */ - regs->eflags = 0x202; + regs->eflags = X86_EFLAGS_IF | 0x2; /* The "Extended Instruction Pointer" register says where the Guest is * running. */ @@ -570,8 +574,8 @@ void lguest_arch_setup_regs(struct lguest *lg, unsigned long start) /* %esi points to our boot information, at physical address 0, so don't * touch it. */ + /* There are a couple of GDT entries the Guest expects when first * booting. */ - setup_guest_gdt(lg); } diff --git a/drivers/lguest/x86/switcher_32.S b/drivers/lguest/x86/switcher_32.S index 1010b90b11fc..0af8baaa0d4a 100644 --- a/drivers/lguest/x86/switcher_32.S +++ b/drivers/lguest/x86/switcher_32.S @@ -6,6 +6,37 @@ * are feeling invigorated and refreshed then the next, more challenging stage * can be found in "make Guest". :*/ +/*M:012 Lguest is meant to be simple: my rule of thumb is that 1% more LOC must + * gain at least 1% more performance. Since neither LOC nor performance can be + * measured beforehand, it generally means implementing a feature then deciding + * if it's worth it. And once it's implemented, who can say no? + * + * This is why I haven't implemented this idea myself. I want to, but I + * haven't. You could, though. + * + * The main place where lguest performance sucks is Guest page faulting. When + * a Guest userspace process hits an unmapped page we switch back to the Host, + * walk the page tables, find it's not mapped, switch back to the Guest page + * fault handler, which calls a hypercall to set the page table entry, then + * finally returns to userspace. That's two round-trips. + * + * If we had a small walker in the Switcher, we could quickly check the Guest + * page table and if the page isn't mapped, immediately reflect the fault back + * into the Guest. This means the Switcher would have to know the top of the + * Guest page table and the page fault handler address. + * + * For simplicity, the Guest should only handle the case where the privilege + * level of the fault is 3 and probably only not present or write faults. It + * should also detect recursive faults, and hand the original fault to the + * Host (which is actually really easy). + * + * Two questions remain. Would the performance gain outweigh the complexity? + * And who would write the verse documenting it? :*/ + +/*M:011 Lguest64 handles NMI. This gave me NMI envy (until I looked at their + * code). It's worth doing though, since it would let us use oprofile in the + * Host when a Guest is running. :*/ + /*S:100 * Welcome to the Switcher itself! * @@ -88,7 +119,7 @@ ENTRY(switch_to_guest) // All saved and there's now five steps before us: // Stack, GDT, IDT, TSS - // And last of all the page tables are flipped. + // Then last of all the page tables are flipped. // Yet beware that our stack pointer must be // Always valid lest an NMI hits @@ -103,25 +134,25 @@ ENTRY(switch_to_guest) lgdt LGUEST_PAGES_guest_gdt_desc(%eax) // The Guest's IDT we did partially - // Move to the "struct lguest_pages" as well. + // Copy to "struct lguest_pages" as well. lidt LGUEST_PAGES_guest_idt_desc(%eax) // The TSS entry which controls traps // Must be loaded up with "ltr" now: + // The GDT entry that TSS uses + // Changes type when we load it: damn Intel! // For after we switch over our page tables - // It (as the rest) will be writable no more. - // (The GDT entry TSS needs - // Changes type when we load it: damn Intel!) + // That entry will be read-only: we'd crash. movl $(GDT_ENTRY_TSS*8), %edx ltr %dx // Look back now, before we take this last step! // The Host's TSS entry was also marked used; - // Let's clear it again, ere we return. + // Let's clear it again for our return. // The GDT descriptor of the Host // Points to the table after two "size" bytes movl (LGUEST_PAGES_host_gdt_desc+2)(%eax), %edx - // Clear the type field of "used" (byte 5, bit 2) + // Clear "used" from type field (byte 5, bit 2) andb $0xFD, (GDT_ENTRY_TSS*8 + 5)(%edx) // Once our page table's switched, the Guest is live! @@ -131,7 +162,7 @@ ENTRY(switch_to_guest) // The page table change did one tricky thing: // The Guest's register page has been mapped - // Writable onto our %esp (stack) -- + // Writable under our %esp (stack) -- // We can simply pop off all Guest regs. popl %eax popl %ebx @@ -152,16 +183,15 @@ ENTRY(switch_to_guest) addl $8, %esp // The last five stack slots hold return address - // And everything needed to change privilege - // Into the Guest privilege level of 1, + // And everything needed to switch privilege + // From Switcher's level 0 to Guest's 1, // And the stack where the Guest had last left it. // Interrupts are turned back on: we are Guest. iret -// There are two paths where we switch to the Host +// We treat two paths to switch back to the Host +// Yet both must save Guest state and restore Host // So we put the routine in a macro. -// We are on our way home, back to the Host -// Interrupted out of the Guest, we come here. #define SWITCH_TO_HOST \ /* We save the Guest state: all registers first \ * Laid out just as "struct lguest_regs" defines */ \ @@ -194,7 +224,7 @@ ENTRY(switch_to_guest) movl %esp, %eax; \ andl $(~(1 << PAGE_SHIFT - 1)), %eax; \ /* Save our trap number: the switch will obscure it \ - * (The Guest regs are not mapped here in the Host) \ + * (In the Host the Guest regs are not mapped here) \ * %ebx holds it safe for deliver_to_host */ \ movl LGUEST_PAGES_regs_trapnum(%eax), %ebx; \ /* The Host GDT, IDT and stack! \ @@ -210,9 +240,9 @@ ENTRY(switch_to_guest) /* Switch to Host's GDT, IDT. */ \ lgdt LGUEST_PAGES_host_gdt_desc(%eax); \ lidt LGUEST_PAGES_host_idt_desc(%eax); \ - /* Restore the Host's stack where it's saved regs lie */ \ + /* Restore the Host's stack where its saved regs lie */ \ movl LGUEST_PAGES_host_sp(%eax), %esp; \ - /* Last the TSS: our Host is complete */ \ + /* Last the TSS: our Host is returned */ \ movl $(GDT_ENTRY_TSS*8), %edx; \ ltr %dx; \ /* Restore now the regs saved right at the first. */ \ @@ -222,14 +252,15 @@ ENTRY(switch_to_guest) popl %ds; \ popl %es -// Here's where we come when the Guest has just trapped: -// (Which trap we'll see has been pushed on the stack). +// The first path is trod when the Guest has trapped: +// (Which trap it was has been pushed on the stack). // We need only switch back, and the Host will decode // Why we came home, and what needs to be done. return_to_host: SWITCH_TO_HOST iret +// We are lead to the second path like so: // An interrupt, with some cause external // Has ajerked us rudely from the Guest's code // Again we must return home to the Host @@ -238,7 +269,7 @@ deliver_to_host: // But now we must go home via that place // Where that interrupt was supposed to go // Had we not been ensconced, running the Guest. - // Here we see the cleverness of our stack: + // Here we see the trickness of run_guest_once(): // The Host stack is formed like an interrupt // With EIP, CS and EFLAGS layered. // Interrupt handlers end with "iret" @@ -263,7 +294,7 @@ deliver_to_host: xorw %ax, %ax orl %eax, %edx // Now the address of the handler's in %edx - // We call it now: its "iret" takes us home. + // We call it now: its "iret" drops us home. jmp *%edx // Every interrupt can come to us here diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index ac54f697c508..28c6ae095c56 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -168,7 +168,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, return -ENOMEM; } - sg_set_buf(&sg, cc->key, cc->key_size); + sg_init_one(&sg, cc->key, cc->key_size); desc.tfm = hash_tfm; desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; err = crypto_hash_digest(&desc, &sg, cc->key_size, salt); @@ -351,14 +351,10 @@ static int crypt_convert(struct crypt_config *cc, struct scatterlist sg_in, sg_out; sg_init_table(&sg_in, 1); - sg_set_page(&sg_in, bv_in->bv_page); - sg_in.offset = bv_in->bv_offset + ctx->offset_in; - sg_in.length = 1 << SECTOR_SHIFT; + sg_set_page(&sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, bv_in->bv_offset + ctx->offset_in); sg_init_table(&sg_out, 1); - sg_set_page(&sg_out, bv_out->bv_page); - sg_out.offset = bv_out->bv_offset + ctx->offset_out; - sg_out.length = 1 << SECTOR_SHIFT; + sg_set_page(&sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT, bv_out->bv_offset + ctx->offset_out); ctx->offset_in += sg_in.length; if (ctx->offset_in >= bv_in->bv_len) { diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index 2b1f8b4be00a..cb034ead95ab 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c @@ -118,8 +118,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) if (NULL == pg) goto err; BUG_ON(PageHighMem(pg)); - sg_set_page(&sglist[i], pg); - sglist[i].length = PAGE_SIZE; + sg_set_page(&sglist[i], pg, PAGE_SIZE, 0); } return sglist; diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c index 912b424e5204..460db03b0ba0 100644 --- a/drivers/media/video/ivtv/ivtv-udma.c +++ b/drivers/media/video/ivtv/ivtv-udma.c @@ -49,8 +49,6 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info unsigned int len = (i == dma_page->page_count - 1) ? dma_page->tail : PAGE_SIZE - offset; - dma->SGlist[map_offset].length = len; - dma->SGlist[map_offset].offset = offset; if (PageHighMem(dma->map[map_offset])) { void *src; @@ -63,10 +61,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len); kunmap_atomic(src, KM_BOUNCE_READ); local_irq_restore(flags); - sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]); + sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset); } else { - sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]); + sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset); } offset = 0; map_offset++; diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 9ab94a749d81..44ee408e145f 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -67,8 +67,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages) if (NULL == pg) goto err; BUG_ON(PageHighMem(pg)); - sg_set_page(&sglist[i], pg); - sglist[i].length = PAGE_SIZE; + sg_set_page(&sglist[i], pg, PAGE_SIZE, 0); } return sglist; @@ -95,16 +94,13 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) if (PageHighMem(pages[0])) /* DMA to highmem pages might not work */ goto highmem; - sg_set_page(&sglist[0], pages[0]); - sglist[0].offset = offset; - sglist[0].length = PAGE_SIZE - offset; + sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); for (i = 1; i < nr_pages; i++) { if (NULL == pages[i]) goto nopage; if (PageHighMem(pages[i])) goto highmem; - sg_set_page(&sglist[i], pages[i]); - sglist[i].length = PAGE_SIZE; + sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0); } return sglist; diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index d602ba6d5417..682406168de9 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -284,6 +284,7 @@ static inline struct i2o_block_request *i2o_block_request_alloc(void) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&ireq->queue); + sg_init_table(ireq->sg_table, I2O_MAX_PHYS_SEGMENTS); return ireq; }; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index bf4bc6adcfef..7471d49909b2 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -267,15 +267,26 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, int mmc_send_csd(struct mmc_card *card, u32 *csd) { + int ret, i; + if (!mmc_host_is_spi(card->host)) return mmc_send_cxd_native(card->host, card->rca << 16, csd, MMC_SEND_CSD); - return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); + ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16); + if (ret) + return ret; + + for (i = 0;i < 4;i++) + csd[i] = be32_to_cpu(csd[i]); + + return 0; } int mmc_send_cid(struct mmc_host *host, u32 *cid) { + int ret, i; + if (!mmc_host_is_spi(host)) { if (!host->card) return -EINVAL; @@ -283,7 +294,14 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid) cid, MMC_SEND_CID); } - return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); + ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16); + if (ret) + return ret; + + for (i = 0;i < 4;i++) + cid[i] = be32_to_cpu(cid[i]); + + return 0; } int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index ee4029a24efd..a6dafe62b992 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -294,8 +294,8 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr) if (data.error) return data.error; - scr[0] = ntohl(scr[0]); - scr[1] = ntohl(scr[1]); + scr[0] = be32_to_cpu(scr[0]); + scr[1] = be32_to_cpu(scr[1]); return 0; } diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index bcbb6d247bf7..c3926eb3bf43 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -40,13 +40,13 @@ #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> +#include <linux/scatterlist.h> #include <linux/mmc/host.h> #include <asm/io.h> #include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-au1x00/au1100_mmc.h> -#include <asm/scatterlist.h> #include <au1xxx.h> #include "au1xmmc.h" @@ -212,12 +212,12 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, } if (data) { - if (flags & MMC_DATA_READ) { + if (data->flags & MMC_DATA_READ) { if (data->blocks > 1) mmccmd |= SD_CMD_CT_4; else mmccmd |= SD_CMD_CT_2; - } else if (flags & MMC_DATA_WRITE) { + } else if (data->flags & MMC_DATA_WRITE) { if (data->blocks > 1) mmccmd |= SD_CMD_CT_3; else diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 12c2d807c145..a6469218f194 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc) return IRQ_HANDLED; } +struct count_children { + unsigned n; + struct bus_type *bus; +}; + +static int maybe_count_child(struct device *dev, void *c) +{ + struct count_children *ccp = c; + + if (dev->bus == ccp->bus) { + if (ccp->n) + return -EBUSY; + ccp->n++; + } + return 0; +} + static int mmc_spi_probe(struct spi_device *spi) { void *ones; @@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_device *spi) return status; } - /* We can use the bus safely iff nobody else will interfere with - * us. That is, either we have the experimental exclusive access - * primitives ... or else there's nobody to share it with. + /* We can use the bus safely iff nobody else will interfere with us. + * Most commands consist of one SPI message to issue a command, then + * several more to collect its response, then possibly more for data + * transfer. Clocking access to other devices during that period will + * corrupt the command execution. + * + * Until we have software primitives which guarantee non-interference, + * we'll aim for a hardware-level guarantee. + * + * REVISIT we can't guarantee another device won't be added later... */ if (spi->master->num_chipselect > 1) { - struct device *parent = spi->dev.parent; + struct count_children cc; - /* If there are multiple devices on this bus, we - * can't proceed. - */ - spin_lock(&parent->klist_children.k_lock); - if (parent->klist_children.k_list.next - != parent->klist_children.k_list.prev) - status = -EMLINK; - else - status = 0; - spin_unlock(&parent->klist_children.k_lock); + cc.n = 0; + cc.bus = spi->dev.bus; + status = device_for_each_child(spi->dev.parent, &cc, + maybe_count_child); if (status < 0) { dev_err(&spi->dev, "can't share SPI bus\n"); return status; } - /* REVISIT we can't guarantee another device won't - * be added later. It's uncommon though ... for now, - * work as if this is safe. - */ - dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n"); + dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n"); } /* We need a supply of ones to transmit. This is the only time diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index d0eb0a2abf4d..95244a7e7353 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -20,11 +20,11 @@ #include <linux/mmc/host.h> #include <linux/amba/bus.h> #include <linux/clk.h> +#include <linux/scatterlist.h> #include <asm/cacheflush.h> #include <asm/div64.h> #include <asm/io.h> -#include <asm/scatterlist.h> #include <asm/sizes.h> #include <asm/mach/mmc.h> @@ -167,7 +167,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, * partially written to a page is properly coherent. */ if (host->sg_len && data->flags & MMC_DATA_READ) - flush_dcache_page(host->sg_ptr->page); + flush_dcache_page(sg_page(host->sg_ptr)); } if (status & MCI_DATAEND) { mmci_stop_data(host); @@ -319,7 +319,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) * page, ensure that the data cache is coherent. */ if (status & MCI_RXACTIVE) - flush_dcache_page(host->sg_ptr->page); + flush_dcache_page(sg_page(host->sg_ptr)); if (!mmci_next_sg(host)) break; diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 0601e01aa2c2..a25ee71998a9 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -29,7 +29,6 @@ #include <asm/dma.h> #include <asm/io.h> -#include <asm/scatterlist.h> #include <asm/sizes.h> #include <asm/arch/pxa-regs.h> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d7c5b94d8c58..6b80bf77a4ef 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -17,8 +17,6 @@ #include <linux/mmc/host.h> -#include <asm/scatterlist.h> - #include "sdhci.h" #define DRIVER_NAME "sdhci" diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index fa4c8c53cc7a..4d5f37421874 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -33,10 +33,10 @@ #include <linux/pnp.h> #include <linux/highmem.h> #include <linux/mmc/host.h> +#include <linux/scatterlist.h> #include <asm/io.h> #include <asm/dma.h> -#include <asm/scatterlist.h> #include "wbsd.h" diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index d2499bb07c13..473f78de4be0 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -122,7 +122,8 @@ struct e1000_buffer { u16 next_to_watch; }; /* RX */ - struct page *page; + /* arrays of page information for packet split */ + struct e1000_ps_page *ps_pages; }; }; @@ -142,8 +143,6 @@ struct e1000_ring { /* array of buffer information structs */ struct e1000_buffer *buffer_info; - /* arrays of page information for packet split */ - struct e1000_ps_page *ps_pages; struct sk_buff *rx_skb_top; struct e1000_queue_stats stats; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 033e124d1c1f..4fd2e23720b6 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -245,37 +245,36 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, rx_desc = E1000_RX_DESC_PS(*rx_ring, i); for (j = 0; j < PS_PAGE_BUFFERS; j++) { - ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) - + j]; - if (j < adapter->rx_ps_pages) { + ps_page = &buffer_info->ps_pages[j]; + if (j >= adapter->rx_ps_pages) { + /* all unused desc entries get hw null ptr */ + rx_desc->read.buffer_addr[j+1] = ~0; + continue; + } + if (!ps_page->page) { + ps_page->page = alloc_page(GFP_ATOMIC); if (!ps_page->page) { - ps_page->page = alloc_page(GFP_ATOMIC); - if (!ps_page->page) { - adapter->alloc_rx_buff_failed++; - goto no_buffers; - } - ps_page->dma = pci_map_page(pdev, - ps_page->page, - 0, PAGE_SIZE, - PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error( - ps_page->dma)) { - dev_err(&adapter->pdev->dev, - "RX DMA page map failed\n"); - adapter->rx_dma_failed++; - goto no_buffers; - } + adapter->alloc_rx_buff_failed++; + goto no_buffers; + } + ps_page->dma = pci_map_page(pdev, + ps_page->page, + 0, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(ps_page->dma)) { + dev_err(&adapter->pdev->dev, + "RX DMA page map failed\n"); + adapter->rx_dma_failed++; + goto no_buffers; } - /* - * Refresh the desc even if buffer_addrs - * didn't change because each write-back - * erases this info. - */ - rx_desc->read.buffer_addr[j+1] = - cpu_to_le64(ps_page->dma); - } else { - rx_desc->read.buffer_addr[j+1] = ~0; } + /* + * Refresh the desc even if buffer_addrs + * didn't change because each write-back + * erases this info. + */ + rx_desc->read.buffer_addr[j+1] = + cpu_to_le64(ps_page->dma); } skb = netdev_alloc_skb(netdev, @@ -334,94 +333,6 @@ no_buffers: } /** - * e1000_alloc_rx_buffers_jumbo - Replace used jumbo receive buffers - * - * @adapter: address of board private structure - * @cleaned_count: number of buffers to allocate this pass - **/ -static void e1000_alloc_rx_buffers_jumbo(struct e1000_adapter *adapter, - int cleaned_count) -{ - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; - struct e1000_rx_desc *rx_desc; - struct e1000_buffer *buffer_info; - struct sk_buff *skb; - unsigned int i; - unsigned int bufsz = 256 - - 16 /*for skb_reserve */ - - NET_IP_ALIGN; - - i = rx_ring->next_to_use; - buffer_info = &rx_ring->buffer_info[i]; - - while (cleaned_count--) { - skb = buffer_info->skb; - if (skb) { - skb_trim(skb, 0); - goto check_page; - } - - skb = netdev_alloc_skb(netdev, bufsz); - if (!skb) { - /* Better luck next round */ - adapter->alloc_rx_buff_failed++; - break; - } - - /* Make buffer alignment 2 beyond a 16 byte boundary - * this will result in a 16 byte aligned IP header after - * the 14 byte MAC header is removed - */ - skb_reserve(skb, NET_IP_ALIGN); - - buffer_info->skb = skb; -check_page: - /* allocate a new page if necessary */ - if (!buffer_info->page) { - buffer_info->page = alloc_page(GFP_ATOMIC); - if (!buffer_info->page) { - adapter->alloc_rx_buff_failed++; - break; - } - } - - if (!buffer_info->dma) - buffer_info->dma = pci_map_page(pdev, - buffer_info->page, 0, - PAGE_SIZE, - PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { - dev_err(&adapter->pdev->dev, "RX DMA page map failed\n"); - adapter->rx_dma_failed++; - break; - } - - rx_desc = E1000_RX_DESC(*rx_ring, i); - rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); - - i++; - if (i == rx_ring->count) - i = 0; - buffer_info = &rx_ring->buffer_info[i]; - } - - if (rx_ring->next_to_use != i) { - rx_ring->next_to_use = i; - if (i-- == 0) - i = (rx_ring->count - 1); - - /* Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). */ - wmb(); - writel(i, adapter->hw.hw_addr + rx_ring->tail); - } -} - -/** * e1000_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure * @@ -495,10 +406,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, goto next_desc; } - /* adjust length to remove Ethernet CRC */ - length -= 4; - - /* probably a little skewed due to removing CRC */ total_rx_bytes += length; total_rx_packets++; @@ -554,15 +461,6 @@ next_desc: return cleaned; } -static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, - u16 length) -{ - bi->page = NULL; - skb->len += length; - skb->data_len += length; - skb->truesize += length; -} - static void e1000_put_txbuf(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info) { @@ -699,174 +597,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } /** - * e1000_clean_rx_irq_jumbo - Send received data up the network stack; legacy - * @adapter: board private structure - * - * the return value indicates whether actual cleaning was done, there - * is no guarantee that everything was cleaned - **/ -static bool e1000_clean_rx_irq_jumbo(struct e1000_adapter *adapter, - int *work_done, int work_to_do) -{ - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; - struct e1000_rx_desc *rx_desc, *next_rxd; - struct e1000_buffer *buffer_info, *next_buffer; - u32 length; - unsigned int i; - int cleaned_count = 0; - bool cleaned = 0; - unsigned int total_rx_bytes = 0, total_rx_packets = 0; - - i = rx_ring->next_to_clean; - rx_desc = E1000_RX_DESC(*rx_ring, i); - buffer_info = &rx_ring->buffer_info[i]; - - while (rx_desc->status & E1000_RXD_STAT_DD) { - struct sk_buff *skb; - u8 status; - - if (*work_done >= work_to_do) - break; - (*work_done)++; - - status = rx_desc->status; - skb = buffer_info->skb; - buffer_info->skb = NULL; - - i++; - if (i == rx_ring->count) - i = 0; - next_rxd = E1000_RX_DESC(*rx_ring, i); - prefetch(next_rxd); - - next_buffer = &rx_ring->buffer_info[i]; - - cleaned = 1; - cleaned_count++; - pci_unmap_page(pdev, - buffer_info->dma, - PAGE_SIZE, - PCI_DMA_FROMDEVICE); - buffer_info->dma = 0; - - length = le16_to_cpu(rx_desc->length); - - /* errors is only valid for DD + EOP descriptors */ - if ((status & E1000_RXD_STAT_EOP) && - (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { - /* recycle both page and skb */ - buffer_info->skb = skb; - /* an error means any chain goes out the window too */ - if (rx_ring->rx_skb_top) - dev_kfree_skb(rx_ring->rx_skb_top); - rx_ring->rx_skb_top = NULL; - goto next_desc; - } - -#define rxtop rx_ring->rx_skb_top - if (!(status & E1000_RXD_STAT_EOP)) { - /* this descriptor is only the beginning (or middle) */ - if (!rxtop) { - /* this is the beginning of a chain */ - rxtop = skb; - skb_fill_page_desc(rxtop, 0, buffer_info->page, - 0, length); - } else { - /* this is the middle of a chain */ - skb_fill_page_desc(rxtop, - skb_shinfo(rxtop)->nr_frags, - buffer_info->page, 0, - length); - /* re-use the skb, only consumed the page */ - buffer_info->skb = skb; - } - e1000_consume_page(buffer_info, rxtop, length); - goto next_desc; - } else { - if (rxtop) { - /* end of the chain */ - skb_fill_page_desc(rxtop, - skb_shinfo(rxtop)->nr_frags, - buffer_info->page, 0, length); - /* re-use the current skb, we only consumed the - * page */ - buffer_info->skb = skb; - skb = rxtop; - rxtop = NULL; - e1000_consume_page(buffer_info, skb, length); - } else { - /* no chain, got EOP, this buf is the packet - * copybreak to save the put_page/alloc_page */ - if (length <= copybreak && - skb_tailroom(skb) >= length) { - u8 *vaddr; - vaddr = kmap_atomic(buffer_info->page, - KM_SKB_DATA_SOFTIRQ); - memcpy(skb_tail_pointer(skb), - vaddr, length); - kunmap_atomic(vaddr, - KM_SKB_DATA_SOFTIRQ); - /* re-use the page, so don't erase - * buffer_info->page */ - skb_put(skb, length); - } else { - skb_fill_page_desc(skb, 0, - buffer_info->page, 0, - length); - e1000_consume_page(buffer_info, skb, - length); - } - } - } - - /* Receive Checksum Offload XXX recompute due to CRC strip? */ - e1000_rx_checksum(adapter, - (u32)(status) | - ((u32)(rx_desc->errors) << 24), - le16_to_cpu(rx_desc->csum), skb); - - pskb_trim(skb, skb->len - 4); - - /* probably a little skewed due to removing CRC */ - total_rx_bytes += skb->len; - total_rx_packets++; - - /* eth type trans needs skb->data to point to something */ - if (!pskb_may_pull(skb, ETH_HLEN)) { - ndev_err(netdev, "__pskb_pull_tail failed.\n"); - dev_kfree_skb(skb); - goto next_desc; - } - - e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special); - -next_desc: - rx_desc->status = 0; - - /* return some buffers to hardware, one at a time is too slow */ - if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count); - cleaned_count = 0; - } - - /* use prefetched values */ - rx_desc = next_rxd; - buffer_info = next_buffer; - } - rx_ring->next_to_clean = i; - - cleaned_count = e1000_desc_unused(rx_ring); - if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count); - - adapter->total_rx_packets += total_rx_packets; - adapter->total_rx_bytes += total_rx_bytes; - return cleaned; -} - -/** * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split * @adapter: board private structure * @@ -953,7 +683,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, ((length + l1) <= adapter->rx_ps_bsize0)) { u8 *vaddr; - ps_page = &rx_ring->ps_pages[i * PS_PAGE_BUFFERS]; + ps_page = &buffer_info->ps_pages[0]; /* there is no documentation about how to call * kmap_atomic, so we can't hold the mapping @@ -965,8 +695,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); pci_dma_sync_single_for_device(pdev, ps_page->dma, PAGE_SIZE, PCI_DMA_FROMDEVICE); - /* remove the CRC */ - l1 -= 4; + skb_put(skb, l1); goto copydone; } /* if */ @@ -977,7 +706,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, if (!length) break; - ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) + j]; + ps_page = &buffer_info->ps_pages[j]; pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, PCI_DMA_FROMDEVICE); ps_page->dma = 0; @@ -988,10 +717,6 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, skb->truesize += length; } - /* strip the ethernet crc, problem is we're using pages now so - * this whole operation can get a little cpu intensive */ - pskb_trim(skb, skb->len - 4); - copydone: total_rx_bytes += skb->len; total_rx_packets++; @@ -1043,7 +768,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) struct e1000_buffer *buffer_info; struct e1000_ps_page *ps_page; struct pci_dev *pdev = adapter->pdev; - unsigned long size; unsigned int i, j; /* Free all the Rx ring sk_buffs */ @@ -1054,9 +778,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) pci_unmap_single(pdev, buffer_info->dma, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - else if (adapter->clean_rx == e1000_clean_rx_irq_jumbo) - pci_unmap_page(pdev, buffer_info->dma, - PAGE_SIZE, PCI_DMA_FROMDEVICE); else if (adapter->clean_rx == e1000_clean_rx_irq_ps) pci_unmap_single(pdev, buffer_info->dma, adapter->rx_ps_bsize0, @@ -1064,19 +785,13 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) buffer_info->dma = 0; } - if (buffer_info->page) { - put_page(buffer_info->page); - buffer_info->page = NULL; - } - if (buffer_info->skb) { dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; } for (j = 0; j < PS_PAGE_BUFFERS; j++) { - ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) - + j]; + ps_page = &buffer_info->ps_pages[j]; if (!ps_page->page) break; pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, @@ -1093,12 +808,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) rx_ring->rx_skb_top = NULL; } - size = sizeof(struct e1000_buffer) * rx_ring->count; - memset(rx_ring->buffer_info, 0, size); - size = sizeof(struct e1000_ps_page) - * (rx_ring->count * PS_PAGE_BUFFERS); - memset(rx_ring->ps_pages, 0, size); - /* Zero out the descriptor ring */ memset(rx_ring->desc, 0, rx_ring->size); @@ -1421,7 +1130,8 @@ err: int e1000e_setup_rx_resources(struct e1000_adapter *adapter) { struct e1000_ring *rx_ring = adapter->rx_ring; - int size, desc_len, err = -ENOMEM; + struct e1000_buffer *buffer_info; + int i, size, desc_len, err = -ENOMEM; size = sizeof(struct e1000_buffer) * rx_ring->count; rx_ring->buffer_info = vmalloc(size); @@ -1429,11 +1139,14 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter) goto err; memset(rx_ring->buffer_info, 0, size); - rx_ring->ps_pages = kcalloc(rx_ring->count * PS_PAGE_BUFFERS, - sizeof(struct e1000_ps_page), - GFP_KERNEL); - if (!rx_ring->ps_pages) - goto err; + for (i = 0; i < rx_ring->count; i++) { + buffer_info = &rx_ring->buffer_info[i]; + buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS, + sizeof(struct e1000_ps_page), + GFP_KERNEL); + if (!buffer_info->ps_pages) + goto err_pages; + } desc_len = sizeof(union e1000_rx_desc_packet_split); @@ -1443,16 +1156,21 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter) err = e1000_alloc_ring_dma(adapter, rx_ring); if (err) - goto err; + goto err_pages; rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; rx_ring->rx_skb_top = NULL; return 0; + +err_pages: + for (i = 0; i < rx_ring->count; i++) { + buffer_info = &rx_ring->buffer_info[i]; + kfree(buffer_info->ps_pages); + } err: vfree(rx_ring->buffer_info); - kfree(rx_ring->ps_pages); ndev_err(adapter->netdev, "Unable to allocate memory for the transmit descriptor ring\n"); return err; @@ -1518,15 +1236,17 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; struct e1000_ring *rx_ring = adapter->rx_ring; + int i; e1000_clean_rx_ring(adapter); + for (i = 0; i < rx_ring->count; i++) { + kfree(rx_ring->buffer_info[i].ps_pages); + } + vfree(rx_ring->buffer_info); rx_ring->buffer_info = NULL; - kfree(rx_ring->ps_pages); - rx_ring->ps_pages = NULL; - dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, rx_ring->dma); rx_ring->desc = NULL; @@ -2032,9 +1752,11 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) ew32(RFCTL, rfctl); - /* disable the stripping of CRC because it breaks - * BMC firmware connected over SMBUS */ - rctl |= E1000_RCTL_DTYP_PS /* | E1000_RCTL_SECRC */; + /* 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; @@ -2077,11 +1799,6 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) sizeof(union e1000_rx_desc_packet_split); adapter->clean_rx = e1000_clean_rx_irq_ps; adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; - } else if (adapter->netdev->mtu > ETH_FRAME_LEN + VLAN_HLEN + 4) { - rdlen = rx_ring->count * - sizeof(struct e1000_rx_desc); - adapter->clean_rx = e1000_clean_rx_irq_jumbo; - adapter->alloc_rx_buf = e1000_alloc_rx_buffers_jumbo; } else { rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); @@ -2326,8 +2043,11 @@ void e1000e_reset(struct e1000_adapter *adapter) struct e1000_mac_info *mac = &adapter->hw.mac; struct e1000_hw *hw = &adapter->hw; u32 tx_space, min_tx_space, min_rx_space; + u32 pba; u16 hwm; + ew32(PBA, adapter->pba); + if (mac->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN ) { /* To maintain wire speed transmits, the Tx FIFO should be * large enough to accommodate two full transmit packets, @@ -2335,11 +2055,11 @@ void e1000e_reset(struct e1000_adapter *adapter) * the Rx FIFO should be large enough to accommodate at least * one full receive packet and is similarly rounded up and * expressed in KB. */ - adapter->pba = er32(PBA); + pba = er32(PBA); /* upper 16 bits has Tx packet buffer allocation size in KB */ - tx_space = adapter->pba >> 16; + tx_space = pba >> 16; /* lower 16 bits has Rx packet buffer allocation size in KB */ - adapter->pba &= 0xffff; + pba &= 0xffff; /* the tx fifo also stores 16 bytes of information about the tx * but don't include ethernet FCS because hardware appends it */ min_tx_space = (mac->max_frame_size + @@ -2355,20 +2075,21 @@ void e1000e_reset(struct e1000_adapter *adapter) /* If current Tx allocation is less than the min Tx FIFO size, * and the min Tx FIFO size is less than the current Rx FIFO * allocation, take space away from current Rx allocation */ - if (tx_space < min_tx_space && - ((min_tx_space - tx_space) < adapter->pba)) { - adapter->pba -= - (min_tx_space - tx_space); + if ((tx_space < min_tx_space) && + ((min_tx_space - tx_space) < pba)) { + pba -= min_tx_space - tx_space; /* if short on rx space, rx wins and must trump tx * adjustment or use Early Receive if available */ - if ((adapter->pba < min_rx_space) && + if ((pba < min_rx_space) && (!(adapter->flags & FLAG_HAS_ERT))) /* ERT enabled in e1000_configure_rx */ - adapter->pba = min_rx_space; + pba = min_rx_space; } + + ew32(PBA, pba); } - ew32(PBA, adapter->pba); /* flow control settings */ /* The high water mark must be low enough to fit one full frame @@ -3624,9 +3345,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN * means we reserve 2 more, this pushes us to allocate from the next * larger slab size. - * i.e. RXBUFFER_2048 --> size-4096 slab - * however with the new *_jumbo* routines, jumbo receives will use - * fragmented skbs */ + * i.e. RXBUFFER_2048 --> size-4096 slab */ if (max_frame <= 256) adapter->rx_buffer_len = 256; diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 4b4b74e47a67..f78e5bf7cb33 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0079" +#define DRV_VERSION "EHEA_0080" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 0a7e78925540..f0319f1e8e05 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -33,6 +33,9 @@ #include <linux/if.h> #include <linux/list.h> #include <linux/if_ether.h> +#include <linux/notifier.h> +#include <linux/reboot.h> + #include <net/ip.h> #include "ehea.h" @@ -3295,6 +3298,20 @@ static int __devexit ehea_remove(struct of_device *dev) return 0; } +static int ehea_reboot_notifier(struct notifier_block *nb, + unsigned long action, void *unused) +{ + if (action == SYS_RESTART) { + ehea_info("Reboot: freeing all eHEA resources"); + ibmebus_unregister_driver(&ehea_driver); + } + return NOTIFY_DONE; +} + +static struct notifier_block ehea_reboot_nb = { + .notifier_call = ehea_reboot_notifier, +}; + static int check_module_parm(void) { int ret = 0; @@ -3351,6 +3368,8 @@ int __init ehea_module_init(void) if (ret) goto out; + register_reboot_notifier(&ehea_reboot_nb); + ret = ibmebus_register_driver(&ehea_driver); if (ret) { ehea_error("failed registering eHEA device driver on ebus"); @@ -3362,6 +3381,7 @@ int __init ehea_module_init(void) if (ret) { ehea_error("failed to register capabilities attribute, ret=%d", ret); + unregister_reboot_notifier(&ehea_reboot_nb); ibmebus_unregister_driver(&ehea_driver); goto out; } @@ -3375,6 +3395,7 @@ static void __exit ehea_module_exit(void) flush_scheduled_work(); driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); + unregister_reboot_notifier(&ehea_reboot_nb); ehea_destroy_busmap(); } diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 4dbdfaaf37bf..a1e4508717c8 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -627,19 +627,16 @@ static int au1k_irda_rx(struct net_device *dev) } -void au1k_irda_interrupt(int irq, void *dev_id) +static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; - - if (dev == NULL) { - printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); - return; - } + struct net_device *dev = dev_id; writel(0, IR_INT_CLEAR); /* ack irda interrupts */ au1k_irda_rx(dev); au1k_tx_ack(dev); + + return IRQ_HANDLED; } diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 662b8d16803c..45f30a2974b8 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -284,7 +284,7 @@ static __net_exit void loopback_net_exit(struct net *net) unregister_netdev(dev); } -static struct pernet_operations __net_initdata loopback_net_ops = { +static struct pernet_operations loopback_net_ops = { .init = loopback_net_init, .exit = loopback_net_exit, }; diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index 887633b207d9..2a5bef6388fe 100644 --- a/drivers/net/mlx4/icm.c +++ b/drivers/net/mlx4/icm.c @@ -101,9 +101,7 @@ static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_ma if (!page) return -ENOMEM; - sg_set_page(mem, page); - mem->length = PAGE_SIZE << order; - mem->offset = 0; + sg_set_page(mem, page, PAGE_SIZE << order, 0); return 0; } diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c index bcb0885011c8..b35d79449500 100644 --- a/drivers/net/ppp_mppe.c +++ b/drivers/net/ppp_mppe.c @@ -68,7 +68,7 @@ MODULE_VERSION("1.0.2"); static unsigned int setup_sg(struct scatterlist *sg, const void *address, unsigned int length) { - sg_init_one(sg, address, length); + sg_set_buf(sg, address, length); return length; } @@ -140,6 +140,8 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state) struct scatterlist sg[4]; unsigned int nbytes; + sg_init_table(sg, 4); + nbytes = setup_sg(&sg[0], state->master_key, state->keylen); nbytes += setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1)); @@ -166,6 +168,8 @@ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key) if (!initial_key) { crypto_blkcipher_setkey(state->arc4, state->sha1_digest, state->keylen); + sg_init_table(sg_in, 1); + sg_init_table(sg_out, 1); setup_sg(sg_in, state->sha1_digest, state->keylen); setup_sg(sg_out, state->session_key, state->keylen); if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in, @@ -421,6 +425,8 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf, isize -= 2; /* Encrypt packet */ + sg_init_table(sg_in, 1); + sg_init_table(sg_out, 1); setup_sg(sg_in, ibuf, isize); setup_sg(sg_out, obuf, osize); if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in, isize) != 0) { @@ -608,6 +614,8 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf, * Decrypt the first byte in order to check if it is * a compressed or uncompressed protocol field. */ + sg_init_table(sg_in, 1); + sg_init_table(sg_out, 1); setup_sg(sg_in, ibuf, 1); setup_sg(sg_out, obuf, 1); if (crypto_blkcipher_decrypt(&desc, sg_out, sg_in, 1) != 0) { diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 19152f54ef2b..b822859c8de3 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -79,12 +79,10 @@ static char version[] __devinitdata = "rrunner.c: v0.50 11/11/2002 Jes Sorensen */ /* - * These are checked at init time to see if they are at least 256KB - * and increased to 256KB if they are not. This is done to avoid ending - * up with socket buffers smaller than the MTU size, + * sysctl_[wr]mem_max are checked at init time to see if they are at + * least 256KB and increased to 256KB if they are not. This is done to + * avoid ending up with socket buffers smaller than the MTU size, */ -extern __u32 sysctl_wmem_max; -extern __u32 sysctl_rmem_max; static int __devinit rr_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9d9ff76a9bc6..5058e60e5703 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2391,7 +2391,7 @@ out_requeue: if (b43_debug(dev, B43_DBG_PWORK_FAST)) delay = msecs_to_jiffies(50); else - delay = round_jiffies(HZ * 15); + delay = round_jiffies_relative(HZ * 15); queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); out: mutex_unlock(&wl->mutex); diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index d09479e816cd..f0e56dfc9ecf 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2260,7 +2260,7 @@ out_requeue: if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST)) delay = msecs_to_jiffies(50); else - delay = round_jiffies(HZ); + delay = round_jiffies_relative(HZ); queue_delayed_work(dev->wl->hw->workqueue, &dev->periodic_work, delay); out: diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index a6c7904de282..8d53d08b9691 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -1769,7 +1769,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) if (priv->stop_rf_kill) { priv->stop_rf_kill = 0; queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies(HZ)); + round_jiffies_relative(HZ)); } deferred = 1; @@ -2086,7 +2086,8 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) /* Make sure the RF Kill check timer is running */ priv->stop_rf_kill = 0; cancel_delayed_work(&priv->rf_kill); - queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ)); + queue_delayed_work(priv->workqueue, &priv->rf_kill, + round_jiffies_relative(HZ)); } static void send_scan_event(void *data) @@ -2123,7 +2124,7 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) if (!delayed_work_pending(&priv->scan_event_later)) queue_delayed_work(priv->workqueue, &priv->scan_event_later, - round_jiffies(msecs_to_jiffies(4000))); + round_jiffies_relative(msecs_to_jiffies(4000))); } else { priv->user_requested_scan = 0; cancel_delayed_work(&priv->scan_event_later); @@ -4242,7 +4243,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) priv->stop_rf_kill = 0; cancel_delayed_work(&priv->rf_kill); queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies(HZ)); + round_jiffies_relative(HZ)); } else schedule_reset(priv); } @@ -5981,7 +5982,7 @@ static void ipw2100_rf_kill(struct work_struct *work) IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); if (!priv->stop_rf_kill) queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies(HZ)); + round_jiffies_relative(HZ)); goto exit_unlock; } diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index e3c828401b9a..54f44e5473c0 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -1753,7 +1753,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) /* Make sure the RF_KILL check timer is running */ cancel_delayed_work(&priv->rf_kill); queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies(2 * HZ)); + round_jiffies_relative(2 * HZ)); } else queue_work(priv->workqueue, &priv->up); } @@ -4364,7 +4364,7 @@ static void handle_scan_event(struct ipw_priv *priv) if (!priv->user_requested_scan) { if (!delayed_work_pending(&priv->scan_event)) queue_delayed_work(priv->workqueue, &priv->scan_event, - round_jiffies(msecs_to_jiffies(4000))); + round_jiffies_relative(msecs_to_jiffies(4000))); } else { union iwreq_data wrqu; @@ -4728,7 +4728,7 @@ static void ipw_rx_notification(struct ipw_priv *priv, && priv->status & STATUS_ASSOCIATED) queue_delayed_work(priv->workqueue, &priv->request_scan, - round_jiffies(HZ)); + round_jiffies_relative(HZ)); /* Send an empty event to user space. * We don't send the received data on the event because diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 557deebca1b9..891f90d2f019 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3232,9 +3232,7 @@ int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd, tx->rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[rate_index].plcp, rate_flags); - if (ieee80211_is_probe_request(fc)) - tx->tx_flags |= TX_CMD_FLG_TSF_MSK; - else if (ieee80211_is_back_request(fc)) + if (ieee80211_is_back_request(fc)) tx->tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; #ifdef CONFIG_IWLWIFI_HT @@ -3872,7 +3870,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, */ case IEEE80211_STYPE_ASSOC_RESP: case IEEE80211_STYPE_REASSOC_RESP: - if (network_packet && iwl_is_associated(priv)) { + if (network_packet) { #ifdef CONFIG_IWLWIFI_HT u8 *pos = NULL; struct ieee802_11_elems elems; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 83019d1d7ccc..4f22a7174caf 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6478,8 +6478,9 @@ static void iwl_bg_scan_check(struct work_struct *data) IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "Scan completion watchdog resetting adapter (%dms)\n", jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - queue_work(priv->workqueue, &priv->restart); + iwl_send_scan_abort(priv); } mutex_unlock(&priv->mutex); } @@ -6575,7 +6576,7 @@ static void iwl_bg_request_scan(struct work_struct *data) spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; - scan->max_out_time = cpu_to_le32(600 * 1024); + scan->max_out_time = cpu_to_le32(200 * 1024); if (!interval) interval = suspend_time; /* @@ -6605,7 +6606,7 @@ static void iwl_bg_request_scan(struct work_struct *data) memcpy(scan->direct_scan[0].ssid, priv->direct_ssid, priv->direct_ssid_len); direct_mask = 1; - } else if (!iwl_is_associated(priv)) { + } else if (!iwl_is_associated(priv) && priv->essid_len) { scan->direct_scan[0].id = WLAN_EID_SSID; scan->direct_scan[0].len = priv->essid_len; memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); @@ -6744,6 +6745,12 @@ static void iwl_bg_post_associate(struct work_struct *data) mutex_lock(&priv->mutex); + if (!priv->interface_id || !priv->is_open) { + mutex_unlock(&priv->mutex); + return; + } + iwl_scan_cancel_timeout(priv, 200); + conf = ieee80211_get_hw_conf(priv->hw); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; @@ -6882,9 +6889,19 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) struct iwl_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); + + + mutex_lock(&priv->mutex); + /* stop mac, cancel any scan request and clear + * RXON_FILTER_ASSOC_MSK BIT + */ priv->is_open = 0; - /*netif_stop_queue(dev); */ - flush_workqueue(priv->workqueue); + iwl_scan_cancel_timeout(priv, 100); + cancel_delayed_work(&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_commit_rxon(priv); + mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211("leave\n"); } @@ -7169,8 +7186,6 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, if (priv->iw_mode == IEEE80211_IF_TYPE_AP) iwl_config_ap(priv); else { - priv->staging_rxon.filter_flags |= - RXON_FILTER_ASSOC_MSK; rc = iwl_commit_rxon(priv); if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) iwl_add_station(priv, @@ -7178,6 +7193,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, } } else { + iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwl_commit_rxon(priv); } @@ -7217,6 +7233,12 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211("enter\n"); mutex_lock(&priv->mutex); + + iwl_scan_cancel_timeout(priv, 100); + cancel_delayed_work(&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_commit_rxon(priv); + if (priv->interface_id == conf->if_id) { priv->interface_id = 0; memset(priv->bssid, 0, ETH_ALEN); @@ -7238,6 +7260,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) IWL_DEBUG_MAC80211("enter\n"); + mutex_lock(&priv->mutex); spin_lock_irqsave(&priv->lock, flags); if (!iwl_is_ready_rf(priv)) { @@ -7268,7 +7291,8 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) priv->direct_ssid_len = (u8) min((u8) len, (u8) IW_ESSID_MAX_SIZE); memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len); - } + } else + priv->one_direct_scan = 0; rc = iwl_scan_initiate(priv); @@ -7276,6 +7300,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) out_unlock: spin_unlock_irqrestore(&priv->lock, flags); + mutex_unlock(&priv->mutex); return rc; } @@ -7310,6 +7335,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&priv->mutex); + iwl_scan_cancel_timeout(priv, 100); + switch (cmd) { case SET_KEY: rc = iwl_update_sta_key_info(priv, key, sta_id); @@ -7479,8 +7506,18 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_unlock_irqrestore(&priv->lock, flags); + /* we are restarting association process + * clear RXON_FILTER_ASSOC_MSK bit + */ + if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { + iwl_scan_cancel_timeout(priv, 100); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_commit_rxon(priv); + } + /* Per mac80211.h: This is only used in IBSS mode... */ if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { + IWL_DEBUG_MAC80211("leave - not in IBSS\n"); mutex_unlock(&priv->mutex); return; @@ -8558,6 +8595,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) iwl_rate_control_unregister(priv->hw); } + /*netif_stop_queue(dev); */ + flush_workqueue(priv->workqueue); + /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes * priv->workqueue... so we can't take down the workqueue * until now... */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 5e1279263b22..d60adcb9bd4a 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -6845,8 +6845,9 @@ static void iwl_bg_scan_check(struct work_struct *data) IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "Scan completion watchdog resetting adapter (%dms)\n", jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - queue_work(priv->workqueue, &priv->restart); + iwl_send_scan_abort(priv); } mutex_unlock(&priv->mutex); } @@ -6942,7 +6943,7 @@ static void iwl_bg_request_scan(struct work_struct *data) spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; - scan->max_out_time = cpu_to_le32(600 * 1024); + scan->max_out_time = cpu_to_le32(200 * 1024); if (!interval) interval = suspend_time; @@ -6965,7 +6966,7 @@ static void iwl_bg_request_scan(struct work_struct *data) memcpy(scan->direct_scan[0].ssid, priv->direct_ssid, priv->direct_ssid_len); direct_mask = 1; - } else if (!iwl_is_associated(priv)) { + } else if (!iwl_is_associated(priv) && priv->essid_len) { scan->direct_scan[0].id = WLAN_EID_SSID; scan->direct_scan[0].len = priv->essid_len; memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); @@ -7118,6 +7119,12 @@ static void iwl_bg_post_associate(struct work_struct *data) mutex_lock(&priv->mutex); + if (!priv->interface_id || !priv->is_open) { + mutex_unlock(&priv->mutex); + return; + } + iwl_scan_cancel_timeout(priv, 200); + conf = ieee80211_get_hw_conf(priv->hw); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; @@ -7271,9 +7278,19 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) struct iwl_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); + + + mutex_lock(&priv->mutex); + /* stop mac, cancel any scan request and clear + * RXON_FILTER_ASSOC_MSK BIT + */ priv->is_open = 0; - /*netif_stop_queue(dev); */ - flush_workqueue(priv->workqueue); + iwl_scan_cancel_timeout(priv, 100); + cancel_delayed_work(&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_commit_rxon(priv); + mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211("leave\n"); } @@ -7573,8 +7590,6 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, if (priv->iw_mode == IEEE80211_IF_TYPE_AP) iwl_config_ap(priv); else { - priv->staging_rxon.filter_flags |= - RXON_FILTER_ASSOC_MSK; rc = iwl_commit_rxon(priv); if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) iwl_rxon_add_station( @@ -7582,6 +7597,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, } } else { + iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwl_commit_rxon(priv); } @@ -7621,6 +7637,12 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211("enter\n"); mutex_lock(&priv->mutex); + + iwl_scan_cancel_timeout(priv, 100); + cancel_delayed_work(&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_commit_rxon(priv); + if (priv->interface_id == conf->if_id) { priv->interface_id = 0; memset(priv->bssid, 0, ETH_ALEN); @@ -7642,6 +7664,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) IWL_DEBUG_MAC80211("enter\n"); + mutex_lock(&priv->mutex); spin_lock_irqsave(&priv->lock, flags); if (!iwl_is_ready_rf(priv)) { @@ -7672,7 +7695,8 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) priv->direct_ssid_len = (u8) min((u8) len, (u8) IW_ESSID_MAX_SIZE); memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len); - } + } else + priv->one_direct_scan = 0; rc = iwl_scan_initiate(priv); @@ -7680,6 +7704,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) out_unlock: spin_unlock_irqrestore(&priv->lock, flags); + mutex_unlock(&priv->mutex); return rc; } @@ -7713,6 +7738,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&priv->mutex); + iwl_scan_cancel_timeout(priv, 100); + switch (cmd) { case SET_KEY: rc = iwl_update_sta_key_info(priv, key, sta_id); @@ -7903,8 +7930,18 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_unlock_irqrestore(&priv->lock, flags); + /* we are restarting association process + * clear RXON_FILTER_ASSOC_MSK bit + */ + if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { + iwl_scan_cancel_timeout(priv, 100); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_commit_rxon(priv); + } + /* Per mac80211.h: This is only used in IBSS mode... */ if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { + IWL_DEBUG_MAC80211("leave - not in IBSS\n"); mutex_unlock(&priv->mutex); return; @@ -9152,6 +9189,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) iwl_rate_control_unregister(priv->hw); } + /*netif_stop_queue(dev); */ + flush_workqueue(priv->workqueue); + /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes * priv->workqueue... so we can't take down the workqueue * until now... */ diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 298faa9d3f61..06d9bc0015c0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -30,7 +30,7 @@ * Interval defines * Both the link tuner as the rfkill will be called once per second. */ -#define LINK_TUNE_INTERVAL ( round_jiffies(HZ) ) +#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) ) #define RFKILL_POLL_INTERVAL ( 1000 ) /* diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index de61c8fe6492..e454ae83e97a 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -433,6 +433,9 @@ static int rtl8187_start(struct ieee80211_hw *dev) rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); + rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); + rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); + rtl8187_init_urbs(dev); reg = RTL818X_RX_CONF_ONLYERLPKT | @@ -582,32 +585,31 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id, static void rtl8187_configure_filter(struct ieee80211_hw *dev, unsigned int changed_flags, unsigned int *total_flags, - int mc_count, struct dev_addr_list *mc_list) + int mc_count, struct dev_addr_list *mclist) { struct rtl8187_priv *priv = dev->priv; - *total_flags = 0; - - if (changed_flags & FIF_ALLMULTI) - priv->rx_conf ^= RTL818X_RX_CONF_MULTICAST; if (changed_flags & FIF_FCSFAIL) priv->rx_conf ^= RTL818X_RX_CONF_FCS; if (changed_flags & FIF_CONTROL) priv->rx_conf ^= RTL818X_RX_CONF_CTRL; if (changed_flags & FIF_OTHER_BSS) priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; - - if (mc_count > 0) + if (*total_flags & FIF_ALLMULTI || mc_count > 0) priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; + else + priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; + + *total_flags = 0; - if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) - *total_flags |= FIF_ALLMULTI; if (priv->rx_conf & RTL818X_RX_CONF_FCS) *total_flags |= FIF_FCSFAIL; if (priv->rx_conf & RTL818X_RX_CONF_CTRL) *total_flags |= FIF_CONTROL; if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) *total_flags |= FIF_OTHER_BSS; + if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) + *total_flags |= FIF_ALLMULTI; rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf); } diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index fd5d0c1570df..00118499018b 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -562,8 +562,6 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) sg_init_table(sg_list->sg, sg_list->count); for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) { - sg->length = min(size, PAGE_SIZE); - sg->offset = 0; address = (void *) get_zeroed_page(GFP_KERNEL); if (address == NULL) { sg_list->count = i; @@ -571,7 +569,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size) retval = -ENOMEM; goto out; } - zfcp_address_to_sg(address, sg); + zfcp_address_to_sg(address, sg, min(size, PAGE_SIZE)); size -= sg->length; } @@ -1518,13 +1516,13 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool) return -ENOMEM; memset(data, 0, sizeof(*data)); + sg_init_table(&data->req , 1); + sg_init_table(&data->resp , 1); data->ct.req = &data->req; data->ct.resp = &data->resp; data->ct.req_count = data->ct.resp_count = 1; - zfcp_address_to_sg(&data->ct_iu_req, &data->req); - zfcp_address_to_sg(&data->ct_iu_resp, &data->resp); - data->req.length = sizeof(struct ct_iu_gid_pn_req); - data->resp.length = sizeof(struct ct_iu_gid_pn_resp); + zfcp_address_to_sg(&data->ct_iu_req, &data->req, sizeof(struct ct_iu_gid_pn_req)); + zfcp_address_to_sg(&data->ct_iu_resp, &data->resp, sizeof(struct ct_iu_gid_pn_resp)); *gid_pn = data; return 0; diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 326e7ee232cb..0754542978b6 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -74,8 +74,7 @@ zfcp_sg_to_address(struct scatterlist *list) static inline void zfcp_address_to_sg(void *address, struct scatterlist *list) { - sg_set_page(list, virt_to_page(address)); - list->offset = ((unsigned long) address) & (PAGE_SIZE - 1); + sg_set_buf(list, address, 0); } #define REQUEST_LIST_SIZE 128 diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 9438d0b28799..5552b755c08a 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -322,9 +322,9 @@ zfcp_erp_adisc(struct zfcp_port *port) if (address == NULL) goto nomem; - zfcp_address_to_sg(address, send_els->req); + zfcp_address_to_sg(address, send_els->req, sizeof(struct zfcp_ls_adisc)); address += PAGE_SIZE >> 1; - zfcp_address_to_sg(address, send_els->resp); + zfcp_address_to_sg(address, send_els->resp, sizeof(struct zfcp_ls_adisc_acc)); send_els->req_count = send_els->resp_count = 1; send_els->adapter = adapter; @@ -336,9 +336,6 @@ zfcp_erp_adisc(struct zfcp_port *port) adisc = zfcp_sg_to_address(send_els->req); send_els->ls_code = adisc->code = ZFCP_LS_ADISC; - send_els->req->length = sizeof(struct zfcp_ls_adisc); - send_els->resp->length = sizeof(struct zfcp_ls_adisc_acc); - /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports without FC-AL-2 capability, so we don't set it */ adisc->wwpn = fc_host_port_name(adapter->scsi_host); diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index d1780980fb20..a9680b5e8ac6 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -477,10 +477,9 @@ static void merge_contiguous_buffers(Scsi_Cmnd *cmd) for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; cmd->SCp.buffers_residual && - virt_to_phys(page_address(cmd->SCp.buffer[1].page) + - cmd->SCp.buffer[1].offset) == endaddr;) { + virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) { MER_PRINTK("VTOP(%p) == %08lx -> merging\n", - page_address(cmd->SCp.buffer[1].page), endaddr); + page_address(sg_page(&cmd->SCp.buffer[1])), endaddr); #if (NDEBUG & NDEBUG_MERGING) ++cnt; #endif diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 439b97a6a269..0841df01bc19 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -2890,7 +2890,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) return NULL; } - sg_set_page(&scatterlist[i], page); + sg_set_page(&scatterlist[i], page, 0, 0); } return sglist; diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 6ce4109efdf3..4bcf916c21a7 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -79,9 +79,7 @@ static inline void iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg) { sg_init_table(&ibuf->sg, 1); - sg_set_page(&ibuf->sg, sg_page(sg)); - ibuf->sg.offset = sg->offset; - ibuf->sg.length = sg->length; + sg_set_page(&ibuf->sg, sg_page(sg), sg->length, sg->offset); /* * Fastpath: sg element fits into single page */ @@ -676,9 +674,8 @@ partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg, { struct scatterlist temp; - memcpy(&temp, sg, sizeof(struct scatterlist)); - temp.offset = offset; - temp.length = length; + sg_init_table(&temp, 1); + sg_set_page(&temp, sg_page(sg), length, offset); crypto_hash_update(desc, &temp, length); } diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 1c5c4b68f20f..4652ad22516b 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5256,8 +5256,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) STbuffer->sg[0].offset = 0; if (page != NULL) { - sg_set_page(&STbuffer->sg[0], page); - STbuffer->sg[0].length = b_size; + sg_set_page(&STbuffer->sg[0], page, b_size, 0); STbuffer->b_data = page_address(page); break; } @@ -5285,8 +5284,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) normalize_buffer(STbuffer); return 0; } - sg_set_page(&STbuffer->sg[segs], page); - STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size; + sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0); got += STbuffer->sg[segs].length; STbuffer->buffer_size = got; STbuffer->sg_segs = ++segs; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index cc1971002846..b5fa4f091387 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1717,16 +1717,12 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, goto out_unlock; */ } - sg_set_page(sgl, pages[0]); - sgl[0].offset = uaddr & ~PAGE_MASK; + sg_set_page(sgl, pages[0], 0, uaddr & ~PAGE_MASK); if (nr_pages > 1) { sgl[0].length = PAGE_SIZE - sgl[0].offset; count -= sgl[0].length; - for (i=1; i < nr_pages ; i++) { - sg_set_page(&sgl[i], pages[i]); - sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE; - count -= PAGE_SIZE; - } + for (i=1; i < nr_pages ; i++) + sg_set_page(&sgl[i], pages[i], count < PAGE_SIZE ? count : PAGE_SIZE, 0); } else { sgl[0].length = count; @@ -1854,8 +1850,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) scatter_elem_sz_prev = ret_sz; } } - sg_set_page(sg, p); - sg->length = (ret_sz > num) ? num : ret_sz; + sg_set_page(sg, p, (ret_sz > num) ? num : ret_sz, 0); SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, " "ret_sz=%d\n", k, num, ret_sz)); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index ce69b9efc102..98dfd6ea209c 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3797,13 +3797,11 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length) sg = &(STbp->sg[0]); frp = STbp->frp; for (i=count=0; count < length; i++) { - sg_set_page(&sg[i], frp[i].page); if (length - count > frp[i].length) - sg[i].length = frp[i].length; + sg_set_page(&sg[i], frp[i].page, frp[i].length, 0); else - sg[i].length = length - count; + sg_set_page(&sg[i], frp[i].page, length - count, 0); count += sg[i].length; - sg[i].offset = 0; } STbp->sg_segs = i; STbp->frp_sg_current = length; @@ -4446,15 +4444,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa } /* Populate the scatter/gather list */ - sg_set_page(&sgl[0], pages[0]); - sgl[0].offset = uaddr & ~PAGE_MASK; + sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK); if (nr_pages > 1) { sgl[0].length = PAGE_SIZE - sgl[0].offset; count -= sgl[0].length; for (i=1; i < nr_pages ; i++) { - sg_set_page(&sgl[i], pages[i]);; - sgl[i].offset = 0; - sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE; + sg_set_page(&sgl[i], pages[i], + count < PAGE_SIZE ? count : PAGE_SIZE, 0);; count -= PAGE_SIZE; } } diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 80fb3f88af2e..1bc41907a038 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -332,8 +332,8 @@ static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) struct scatterlist *sg = sp->SCp.buffer; while (sz >= 0) { - sg[sz].dma_address = dvma_map((unsigned long)page_address(sg[sz].page) + - sg[sz].offset, sg[sz].length); + sg[sz].dma_address = dvma_map((unsigned long)sg_virt(&sg[sz]), + sg[sz].length); sz--; } sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dma_address); diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 103189095c80..3bb5d241dd40 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1875,6 +1875,7 @@ uart_set_options(struct uart_port *port, struct console *co, int baud, int parity, int bits, int flow) { struct ktermios termios; + static struct ktermios dummy; int i; /* @@ -1920,7 +1921,7 @@ uart_set_options(struct uart_port *port, struct console *co, */ port->mctrl |= TIOCM_DTR; - port->ops->set_termios(port, &termios, NULL); + port->ops->set_termios(port, &termios, &dummy); co->cflag = termios.c_cflag; return 0; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 8bdaa157ffe7..eb4ac47612a5 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1641,7 +1641,13 @@ free_interfaces: intf->dev.bus_id, ret); continue; } - usb_create_sysfs_intf_files (intf); + + /* The driver's probe method can call usb_set_interface(), + * which would mean the interface's sysfs files are already + * created. Just in case, we'll remove them first. + */ + usb_remove_sysfs_intf_files(intf); + usb_create_sysfs_intf_files(intf); } usb_autosuspend_device(dev); diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index c20c03aaf012..d05ead20081c 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -372,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* enforce simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | - URB_NO_INTERRUPT | URB_DIR_MASK); + URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER); switch (xfertype) { case USB_ENDPOINT_XFER_BULK: if (is_out) diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 1c8040602525..c72e9620bf8d 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -3289,7 +3289,7 @@ static int udc_pci_probe( dev->chiprev = pdev->revision; pci_set_master(pdev); - pci_set_mwi(pdev); + pci_try_set_mwi(pdev); /* init dma pools */ if (use_dma) { diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index c978d622fa8a..177e78ed241b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI config USB_OHCI_HCD_SSB bool "OHCI support for Broadcom SSB OHCI core" - depends on USB_OHCI_HCD && SSB && EXPERIMENTAL + depends on USB_OHCI_HCD && (SSB = y || SSB = CONFIG_USB_OHCI_HCD) && EXPERIMENTAL default n ---help--- Support for the Sonics Silicon Backplane (SSB) attached diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 240c7f507541..704f33fdd2f1 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -80,7 +80,10 @@ static const char hcd_name [] = "ohci_hcd"; static void ohci_dump (struct ohci_hcd *ohci, int verbose); static int ohci_init (struct ohci_hcd *ohci); static void ohci_stop (struct usb_hcd *hcd); + +#if defined(CONFIG_PM) || defined(CONFIG_PCI) static int ohci_restart (struct ohci_hcd *ohci); +#endif #include "ohci-hub.c" #include "ohci-dbg.c" @@ -396,7 +399,7 @@ static int check_ed(struct ohci_hcd *ohci, struct ed *ed) */ static void unlink_watchdog_func(unsigned long _ohci) { - long flags; + unsigned long flags; unsigned max; unsigned seen_count = 0; unsigned i; @@ -893,6 +896,8 @@ static void ohci_stop (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ +#if defined(CONFIG_PM) || defined(CONFIG_PCI) + /* must not be called from interrupt context */ static int ohci_restart (struct ohci_hcd *ohci) { @@ -954,6 +959,8 @@ static int ohci_restart (struct ohci_hcd *ohci) return 0; } +#endif + /*-------------------------------------------------------------------------*/ #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index e5d60d5b105a..60379b17bbc1 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, } else if (qh->period != urb->interval) { return -EINVAL; /* Can't change the period */ - } else { /* Pick up where the last URB leaves off */ + } else { + /* Find the next unused frame */ if (list_empty(&qh->queue)) { frame = qh->iso_frame; } else { @@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, lurb->number_of_packets * lurb->interval; } - if (urb->transfer_flags & URB_ISO_ASAP) - urb->start_frame = frame; - else if (urb->start_frame != frame) - return -EINVAL; + if (urb->transfer_flags & URB_ISO_ASAP) { + /* Skip some frames if necessary to insure + * the start frame is in the future. + */ + uhci_get_current_frame_number(uhci); + if (uhci_frame_before_eq(frame, uhci->frame_number)) { + frame = uhci->frame_number + 1; + frame += ((qh->phase - frame) & + (qh->period - 1)); + } + } /* Otherwise pick up where the last URB leaves off */ + urb->start_frame = frame; } /* Make sure we won't have to go too far into the future */ diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 2677fea147d9..1cd9e7eba93b 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -399,7 +399,6 @@ static void cytherm_disconnect(struct usb_interface *interface) struct usb_cytherm *dev; dev = usb_get_intfdata (interface); - usb_set_intfdata (interface, NULL); device_remove_file(&interface->dev, &dev_attr_brightness); device_remove_file(&interface->dev, &dev_attr_temp); @@ -407,6 +406,9 @@ static void cytherm_disconnect(struct usb_interface *interface) device_remove_file(&interface->dev, &dev_attr_port0); device_remove_file(&interface->dev, &dev_attr_port1); + /* first remove the files, then NULL the pointer */ + usb_set_intfdata (interface, NULL); + usb_put_dev(dev->udev); kfree(dev); diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index cd137577bb2d..4a09b87bdd28 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c @@ -114,6 +114,10 @@ static int emi26_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); + if (err < 0) { + err("%s - error loading firmware: error = %d", __FUNCTION__, err); + goto wraperr; + } msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 4758cc5ccebc..d1362415922c 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c @@ -123,6 +123,10 @@ static int emi62_load_firmware (struct usb_device *dev) /* De-assert reset (let the CPU run) */ err = emi62_set_reset(dev,0); + if (err < 0) { + err("%s - error loading firmware: error = %d", __FUNCTION__, err); + goto wraperr; + } msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index d3d8cd6ff103..148b7fe639b2 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -147,7 +147,7 @@ struct u132_target { /* Structure to hold all of our device specific stuff*/ struct usb_ftdi { struct list_head ftdi_list; - struct semaphore u132_lock; + struct mutex u132_lock; int command_next; int command_head; struct u132_command command[COMMAND_SIZE]; @@ -330,39 +330,39 @@ static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi) static void ftdi_elan_abandon_completions(struct usb_ftdi *ftdi) { - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); while (ftdi->respond_next > ftdi->respond_head) { struct u132_respond *respond = &ftdi->respond[RESPOND_MASK & ftdi->respond_head++]; *respond->result = -ESHUTDOWN; *respond->value = 0; complete(&respond->wait_completion); - } up(&ftdi->u132_lock); + } mutex_unlock(&ftdi->u132_lock); } static void ftdi_elan_abandon_targets(struct usb_ftdi *ftdi) { int ed_number = 4; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); while (ed_number-- > 0) { struct u132_target *target = &ftdi->target[ed_number]; if (target->active == 1) { target->condition_code = TD_DEVNOTRESP; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); ftdi_elan_do_callback(ftdi, target, NULL, 0); - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); } } ftdi->recieved = 0; ftdi->expected = 4; ftdi->ed_found = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); } static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi) { int ed_number = 4; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); while (ed_number-- > 0) { struct u132_target *target = &ftdi->target[ed_number]; target->abandoning = 1; @@ -382,9 +382,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi) ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); goto wait_1; } } @@ -404,9 +404,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi) ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); goto wait_2; } } @@ -414,13 +414,13 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi) ftdi->recieved = 0; ftdi->expected = 4; ftdi->ed_found = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); } static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi) { int ed_number = 4; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); while (ed_number-- > 0) { struct u132_target *target = &ftdi->target[ed_number]; target->abandoning = 1; @@ -440,9 +440,9 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi) ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); goto wait; } } @@ -450,7 +450,7 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi) ftdi->recieved = 0; ftdi->expected = 4; ftdi->ed_found = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); } static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi) @@ -886,14 +886,14 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, char *b) { int payload = (ed_length >> 0) & 0x07FF; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); target->actual = 0; target->non_null = (ed_length >> 15) & 0x0001; target->repeat_number = (ed_length >> 11) & 0x000F; if (ed_type == 0x02) { if (payload == 0 || target->abandoning > 0) { target->abandoning = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, payload); ftdi->recieved = 0; @@ -903,13 +903,13 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, } else { ftdi->expected = 4 + payload; ftdi->ed_found = 1; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return b; } } else if (ed_type == 0x03) { if (payload == 0 || target->abandoning > 0) { target->abandoning = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, payload); ftdi->recieved = 0; @@ -919,12 +919,12 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, } else { ftdi->expected = 4 + payload; ftdi->ed_found = 1; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return b; } } else if (ed_type == 0x01) { target->abandoning = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, payload); ftdi->recieved = 0; @@ -933,7 +933,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, return ftdi->response; } else { target->abandoning = 0; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, payload); ftdi->recieved = 0; @@ -947,12 +947,12 @@ static char *have_ed_get_response(struct usb_ftdi *ftdi, struct u132_target *target, u16 ed_length, int ed_number, int ed_type, char *b) { - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); target->condition_code = TD_DEVNOTRESP; target->actual = (ed_length >> 0) & 0x01FF; target->non_null = (ed_length >> 15) & 0x0001; target->repeat_number = (ed_length >> 11) & 0x000F; - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); if (target->active) ftdi_elan_do_callback(ftdi, target, NULL, 0); target->abandoning = 0; @@ -1278,7 +1278,7 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data) return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { struct u132_command *command = &ftdi->command[ @@ -1292,10 +1292,10 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data) command->buffer = &command->value; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1310,7 +1310,7 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { struct u132_command *command = &ftdi->command[ @@ -1324,10 +1324,10 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset, command->buffer = &command->value; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1342,7 +1342,7 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { struct u132_command *command = &ftdi->command[ @@ -1356,10 +1356,10 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset, command->buffer = &command->value; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1382,7 +1382,7 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data) } else { int command_size; int respond_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; respond_size = ftdi->respond_next - ftdi->respond_head; if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE) @@ -1405,11 +1405,11 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data) ftdi->command_next += 1; ftdi->respond_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); wait_for_completion(&respond->wait_completion); return result; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1425,7 +1425,7 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset, } else { int command_size; int respond_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; respond_size = ftdi->respond_next - ftdi->respond_head; if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE) @@ -1449,11 +1449,11 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset, ftdi->command_next += 1; ftdi->respond_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); wait_for_completion(&respond->wait_completion); return result; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1469,7 +1469,7 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset, } else { int command_size; int respond_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; respond_size = ftdi->respond_next - ftdi->respond_head; if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE) @@ -1493,11 +1493,11 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset, ftdi->command_next += 1; ftdi->respond_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); wait_for_completion(&respond->wait_completion); return result; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1529,7 +1529,7 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { struct u132_target *target = &ftdi->target[ed]; @@ -1550,10 +1550,10 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number, target->active = 1; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1586,7 +1586,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { struct u132_target *target = &ftdi->target[ed]; @@ -1615,10 +1615,10 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number, target->active = 1; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1651,7 +1651,7 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { struct u132_target *target = &ftdi->target[ed]; @@ -1672,10 +1672,10 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number, target->active = 1; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1708,7 +1708,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { u8 *b; @@ -1751,10 +1751,10 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number, target->active = 1; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1787,7 +1787,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number, return -ENODEV; } else { int command_size; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); command_size = ftdi->command_next - ftdi->command_head; if (command_size < COMMAND_SIZE) { int remaining_length = urb->transfer_buffer_length - @@ -1816,10 +1816,10 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number, target->active = 1; ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); goto wait; } @@ -1849,9 +1849,9 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number, return -ENODEV; } else { struct u132_target *target = &ftdi->target[ed]; - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); if (target->abandoning > 0) { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } else { target->abandoning = 1; @@ -1873,13 +1873,13 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number, ftdi->command_next += 1; ftdi_elan_kick_command_queue(ftdi); } else { - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); msleep(100); - down(&ftdi->u132_lock); + mutex_lock(&ftdi->u132_lock); goto wait_1; } } - up(&ftdi->u132_lock); + mutex_unlock(&ftdi->u132_lock); return 0; } } @@ -2793,7 +2793,7 @@ static int ftdi_elan_probe(struct usb_interface *interface, init_MUTEX(&ftdi->sw_lock); ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); ftdi->interface = interface; - init_MUTEX(&ftdi->u132_lock); + mutex_init(&ftdi->u132_lock); ftdi->expected = 4; iface_desc = interface->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index e6fd024024f5..4bcf7fb4e5da 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -66,6 +66,7 @@ static struct usb_device_id idmouse_table[] = { USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000) MODULE_DEVICE_TABLE(usb, idmouse_table); +static DEFINE_MUTEX(open_disc_mutex); /* structure to hold all of our device specific stuff */ struct usb_idmouse { @@ -80,7 +81,7 @@ struct usb_idmouse { int open; /* if the port is open or not */ int present; /* if the device is not disconnected */ - struct semaphore sem; /* locks this structure */ + struct mutex lock; /* locks this structure */ }; @@ -213,13 +214,17 @@ static int idmouse_open(struct inode *inode, struct file *file) if (!interface) return -ENODEV; + mutex_lock(&open_disc_mutex); /* get the device information block from the interface */ dev = usb_get_intfdata(interface); - if (!dev) + if (!dev) { + mutex_unlock(&open_disc_mutex); return -ENODEV; + } /* lock this device */ - down(&dev->sem); + mutex_lock(&dev->lock); + mutex_unlock(&open_disc_mutex); /* check if already open */ if (dev->open) { @@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file) error: /* unlock this device */ - up(&dev->sem); + mutex_unlock(&dev->lock); return result; } @@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file) if (dev == NULL) return -ENODEV; + mutex_lock(&open_disc_mutex); /* lock our device */ - down(&dev->sem); + mutex_lock(&dev->lock); /* are we really open? */ if (dev->open <= 0) { - up(&dev->sem); + mutex_unlock(&dev->lock); + mutex_unlock(&open_disc_mutex); return -ENODEV; } @@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file) if (!dev->present) { /* the device was unplugged before the file was released */ - up(&dev->sem); + mutex_unlock(&dev->lock); + mutex_unlock(&open_disc_mutex); idmouse_delete(dev); } else { - up(&dev->sem); + mutex_unlock(&dev->lock); + mutex_unlock(&open_disc_mutex); } return 0; } @@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count int result; /* lock this object */ - down(&dev->sem); + mutex_lock(&dev->lock); /* verify that the device wasn't unplugged */ if (!dev->present) { - up(&dev->sem); + mutex_unlock(&dev->lock); return -ENODEV; } result = simple_read_from_buffer(buffer, count, ppos, dev->bulk_in_buffer, IMGSIZE); /* unlock the device */ - up(&dev->sem); + mutex_unlock(&dev->lock); return result; } @@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface, if (dev == NULL) return -ENOMEM; - init_MUTEX(&dev->sem); + mutex_init(&dev->lock); dev->udev = udev; dev->interface = interface; @@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface) /* get device structure */ dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); /* give back our minor */ usb_deregister_dev(interface, &idmouse_class); - /* lock it */ - down(&dev->sem); + mutex_lock(&open_disc_mutex); + usb_set_intfdata(interface, NULL); + /* lock the device */ + mutex_lock(&dev->lock); + mutex_unlock(&open_disc_mutex); /* prevent device read, write and ioctl */ dev->present = 0; /* if the device is opened, idmouse_release will clean this up */ if (!dev->open) { - up(&dev->sem); + mutex_unlock(&dev->lock); idmouse_delete(dev); } else { /* unlock */ - up(&dev->sem); + mutex_unlock(&dev->lock); } info("%s disconnected", DRIVER_DESC); diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index d372fbc4effb..764696ff1e8e 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -66,6 +66,7 @@ module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "debug=1 enables debugging messages"); static struct usb_driver iowarrior_driver; +static DEFINE_MUTEX(iowarrior_open_disc_lock); /*--------------*/ /* data */ @@ -351,7 +352,7 @@ static ssize_t iowarrior_write(struct file *file, mutex_lock(&dev->mutex); /* verify that the device wasn't unplugged */ - if (dev == NULL || !dev->present) { + if (!dev->present) { retval = -ENODEV; goto exit; } @@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file) return -ENODEV; } + mutex_lock(&iowarrior_open_disc_lock); dev = usb_get_intfdata(interface); - if (!dev) + if (!dev) { + mutex_unlock(&iowarrior_open_disc_lock); return -ENODEV; + } mutex_lock(&dev->mutex); + mutex_unlock(&iowarrior_open_disc_lock); /* Only one process can open each device, no sharing. */ if (dev->opened) { @@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) int minor; dev = usb_get_intfdata(interface); + mutex_lock(&iowarrior_open_disc_lock); usb_set_intfdata(interface, NULL); minor = dev->minor; @@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface) dev->present = 0; mutex_unlock(&dev->mutex); + mutex_unlock(&iowarrior_open_disc_lock); if (dev->opened) { /* There is a process that holds a filedescriptor to the device , diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 561970b889a5..aab320085ebf 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -198,6 +198,7 @@ static struct usb_device_id tower_table [] = { }; MODULE_DEVICE_TABLE (usb, tower_table); +static DEFINE_MUTEX(open_disc_mutex); #define LEGO_USB_TOWER_MINOR_BASE 160 @@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file) goto exit; } + mutex_lock(&open_disc_mutex); dev = usb_get_intfdata(interface); if (!dev) { + mutex_unlock(&open_disc_mutex); retval = -ENODEV; goto exit; } /* lock this device */ if (down_interruptible (&dev->sem)) { + mutex_unlock(&open_disc_mutex); retval = -ERESTARTSYS; goto exit; } + /* allow opening only once */ if (dev->open_count) { + mutex_unlock(&open_disc_mutex); retval = -EBUSY; goto unlock_exit; } dev->open_count = 1; + mutex_unlock(&open_disc_mutex); /* reset the tower */ result = usb_control_msg (dev->udev, @@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file) if (dev == NULL) { dbg(1, "%s: object is NULL", __FUNCTION__); retval = -ENODEV; - goto exit; + goto exit_nolock; } + mutex_lock(&open_disc_mutex); if (down_interruptible (&dev->sem)) { retval = -ERESTARTSYS; goto exit; @@ -468,6 +476,8 @@ unlock_exit: up (&dev->sem); exit: + mutex_unlock(&open_disc_mutex); +exit_nolock: dbg(2, "%s: leave, return value %d", __FUNCTION__, retval); return retval; } @@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface) dbg(2, "%s: enter", __FUNCTION__); dev = usb_get_intfdata (interface); + mutex_lock(&open_disc_mutex); usb_set_intfdata (interface, NULL); minor = dev->minor; @@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface) usb_deregister_dev (interface, &tower_class); down (&dev->sem); + mutex_unlock(&open_disc_mutex); /* if the device is not opened, then we clean up right now */ if (!dev->open_count) { diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 88f6abe73624..330c18e390b8 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -118,10 +118,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, mutex_lock(&(rio->lock)); /* Sanity check to make sure rio is connected, powered, etc */ - if ( rio == NULL || - rio->present == 0 || - rio->rio_dev == NULL ) - { + if (rio->present == 0 || rio->rio_dev == NULL) { retval = -ENODEV; goto err_out; } @@ -280,10 +277,7 @@ write_rio(struct file *file, const char __user *buffer, if (intr) return -EINTR; /* Sanity check to make sure rio is connected, powered, etc */ - if ( rio == NULL || - rio->present == 0 || - rio->rio_dev == NULL ) - { + if (rio->present == 0 || rio->rio_dev == NULL) { mutex_unlock(&(rio->lock)); return -ENODEV; } @@ -369,10 +363,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) if (intr) return -EINTR; /* Sanity check to make sure rio is connected, powered, etc */ - if ( rio == NULL || - rio->present == 0 || - rio->rio_dev == NULL ) - { + if (rio->present == 0 || rio->rio_dev == NULL) { mutex_unlock(&(rio->lock)); return -ENODEV; } diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 719842032712..20777d01db62 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/errno.h> +#include <linux/mutex.h> #include <asm/uaccess.h> #include <linux/usb.h> @@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = { }; MODULE_DEVICE_TABLE (usb, id_table); +static DEFINE_MUTEX(open_disc_mutex); + struct usb_lcd { struct usb_device * udev; /* init: probe_lcd */ @@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file) return -ENODEV; } + mutex_lock(&open_disc_mutex); dev = usb_get_intfdata(interface); - if (!dev) + if (!dev) { + mutex_unlock(&open_disc_mutex); return -ENODEV; + } /* increment our usage count for the device */ kref_get(&dev->kref); + mutex_unlock(&open_disc_mutex); /* grab a power reference */ r = usb_autopm_get_interface(interface); @@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface) struct usb_lcd *dev; int minor = interface->minor; + mutex_lock(&open_disc_mutex); dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); + mutex_unlock(&open_disc_mutex); /* give back our minor */ usb_deregister_dev(interface, &lcd_class); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 2a8e537cb046..ddfee918000d 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -161,7 +161,8 @@ static void ark3116_set_termios(struct usb_serial_port *port, { struct usb_serial *serial = port->serial; struct ark3116_private *priv = usb_get_serial_port_data(port); - unsigned int cflag = port->tty->termios->c_cflag; + struct ktermios *termios = port->tty->termios; + unsigned int cflag = termios->c_cflag; unsigned long flags; int baud; int ark3116_baud; @@ -177,11 +178,14 @@ static void ark3116_set_termios(struct usb_serial_port *port, *(port->tty->termios) = tty_std_termios; port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + termios->c_ispeed = 9600; + termios->c_ospeed = 9600; priv->termios_initialized = 1; } spin_unlock_irqrestore(&priv->lock, flags); - cflag = port->tty->termios->c_cflag; + cflag = termios->c_cflag; + termios->c_cflag &= ~(CMSPAR|CRTSCTS); buf = kmalloc(1, GFP_KERNEL); if (!buf) { @@ -254,9 +258,13 @@ static void ark3116_set_termios(struct usb_serial_port *port, case 115200: case 230400: case 460800: + /* Report the resulting rate back to the caller */ + tty_encode_baud_rate(port->tty, baud, baud); break; /* set 9600 as default (if given baudrate is invalid for example) */ default: + tty_encode_baud_rate(port->tty, 9600, 9600); + case 0: baud = 9600; } @@ -302,6 +310,7 @@ static void ark3116_set_termios(struct usb_serial_port *port, /* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */ kfree(buf); + return; } diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 6b252ceb39a8..42582d49b69c 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -272,9 +272,6 @@ static void ch341_set_termios(struct usb_serial_port *port, dbg("ch341_set_termios()"); - if (!tty || !tty->termios) - return; - baud_rate = tty_get_baud_rate(tty); switch (baud_rate) { @@ -299,6 +296,11 @@ static void ch341_set_termios(struct usb_serial_port *port, * (cflag & PARENB) : parity {NONE, EVEN, ODD} * (cflag & CSTOPB) : stop bits [1, 2] */ + + /* Copy back the old hardware settings */ + tty_termios_copy_hw(tty->termios, old_termios); + /* And re-encode with the new baud */ + tty_encode_baud_rate(tty, baud_rate, baud_rate); } static struct usb_driver ch341_driver = { diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 9386e216d681..0362654d3b52 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -164,6 +164,7 @@ static int usb_console_setup(struct console *co, char *options) } if (serial->type->set_termios) { + struct ktermios dummy; /* build up a fake tty structure so that the open call has something * to look at to get the cflag value */ tty = kzalloc(sizeof(*tty), GFP_KERNEL); @@ -177,12 +178,13 @@ static int usb_console_setup(struct console *co, char *options) kfree (tty); return -ENOMEM; } + memset(&dummy, 0, sizeof(struct ktermios)); termios->c_cflag = cflag; tty->termios = termios; port->tty = tty; /* set up the initial termios settings */ - serial->type->set_termios(port, NULL); + serial->type->set_termios(port, &dummy); port->tty = NULL; kfree (termios); kfree (tty); diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index eb7df1835c11..3a83cb4c4bc2 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -361,7 +361,6 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - no tty structures", __FUNCTION__); return; } - cflag = port->tty->termios->c_cflag; cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); /* Convert to baudrate */ @@ -369,40 +368,9 @@ static void cp2101_get_termios (struct usb_serial_port *port) baud = BAUD_RATE_GEN_FREQ / baud; dbg("%s - baud rate = %d", __FUNCTION__, baud); - cflag &= ~CBAUD; - switch (baud) { - /* - * The baud rates which are commented out below - * appear to be supported by the device - * but are non-standard - */ - case 600: cflag |= B600; break; - case 1200: cflag |= B1200; break; - case 1800: cflag |= B1800; break; - case 2400: cflag |= B2400; break; - case 4800: cflag |= B4800; break; - /*case 7200: cflag |= B7200; break;*/ - case 9600: cflag |= B9600; break; - /*case 14400: cflag |= B14400; break;*/ - case 19200: cflag |= B19200; break; - /*case 28800: cflag |= B28800; break;*/ - case 38400: cflag |= B38400; break; - /*case 55854: cflag |= B55054; break;*/ - case 57600: cflag |= B57600; break; - case 115200: cflag |= B115200; break; - /*case 127117: cflag |= B127117; break;*/ - case 230400: cflag |= B230400; break; - case 460800: cflag |= B460800; break; - case 921600: cflag |= B921600; break; - /*case 3686400: cflag |= B3686400; break;*/ - default: - dbg("%s - Baud rate is not supported, " - "using 9600 baud", __FUNCTION__); - cflag |= B9600; - cp2101_set_config_single(port, CP2101_BAUDRATE, - (BAUD_RATE_GEN_FREQ/9600)); - break; - } + + tty_encode_baud_rate(port->tty, baud, baud); + cflag = port->tty->termios->c_cflag; cp2101_get_config(port, CP2101_BITS, &bits, 2); cflag &= ~CSIZE; @@ -516,7 +484,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) static void cp2101_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) { - unsigned int cflag, old_cflag=0; + unsigned int cflag, old_cflag; int baud=0, bits; unsigned int modem_ctl[4]; @@ -526,6 +494,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - no tty structures", __FUNCTION__); return; } + port->tty->termios->c_cflag &= ~CMSPAR; + cflag = port->tty->termios->c_cflag; old_cflag = old_termios->c_cflag; baud = tty_get_baud_rate(port->tty); @@ -563,11 +533,15 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - Setting baud rate to %d baud", __FUNCTION__, baud); if (cp2101_set_config_single(port, CP2101_BAUDRATE, - (BAUD_RATE_GEN_FREQ / baud))) + (BAUD_RATE_GEN_FREQ / baud))) { dev_err(&port->dev, "Baud rate requested not " "supported by device\n"); + baud = tty_termios_baud_rate(old_termios); + } } } + /* Report back the resulting baud rate */ + tty_encode_baud_rate(port->tty, baud, baud); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index dab2e66d111d..ae410c4678ea 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -973,6 +973,8 @@ static void digi_set_termios(struct usb_serial_port *port, } } /* set parity */ + tty->termios->c_cflag &= ~CMSPAR; + if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { if (cflag&PARENB) { if (cflag&PARODD) @@ -1054,15 +1056,15 @@ static void digi_set_termios(struct usb_serial_port *port, } /* set output flow control */ - if ((iflag&IXON) != (old_iflag&IXON) - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { + if ((iflag & IXON) != (old_iflag & IXON) + || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { arg = 0; - if (iflag&IXON) + if (iflag & IXON) arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; else arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; - if (cflag&CRTSCTS) { + if (cflag & CRTSCTS) { arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; } else { arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; @@ -1076,8 +1078,8 @@ static void digi_set_termios(struct usb_serial_port *port, } /* set receive enable/disable */ - if ((cflag&CREAD) != (old_cflag&CREAD)) { - if (cflag&CREAD) + if ((cflag & CREAD) != (old_cflag & CREAD)) { + if (cflag & CREAD) arg = DIGI_ENABLE; else arg = DIGI_DISABLE; @@ -1089,7 +1091,7 @@ static void digi_set_termios(struct usb_serial_port *port, } if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0) dbg("digi_set_termios: write oob failed, ret=%d", ret); - + tty_encode_baud_rate(tty, baud, baud); } diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 050fcc996f56..a5c8e1e17ea5 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -449,14 +449,9 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) { - + struct ktermios *termios = port->tty->termios; dbg("%s - port %d", __FUNCTION__, port->number); - if ((!port->tty) || (!port->tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - /* * The empeg-car player wants these particular tty settings. * You could, for example, change the baud rate, however the @@ -466,7 +461,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol * * The default requirements for this device are: */ - port->tty->termios->c_iflag + termios->c_iflag &= ~(IGNBRK /* disable ignore break */ | BRKINT /* disable break causes interrupt */ | PARMRK /* disable mark parity errors */ @@ -476,24 +471,23 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol | ICRNL /* disable translate CR to NL */ | IXON); /* disable enable XON/XOFF flow control */ - port->tty->termios->c_oflag + termios->c_oflag &= ~OPOST; /* disable postprocess output characters */ - port->tty->termios->c_lflag + termios->c_lflag &= ~(ECHO /* disable echo input characters */ | ECHONL /* disable echo new line */ | ICANON /* disable erase, kill, werase, and rprnt special characters */ | ISIG /* disable interrupt, quit, and suspend special characters */ | IEXTEN); /* disable non-POSIX special characters */ - port->tty->termios->c_cflag + termios->c_cflag &= ~(CSIZE /* no size */ | PARENB /* disable parity bit */ | CBAUD); /* clear current baud rate */ - port->tty->termios->c_cflag - |= (CS8 /* character size 8 bits */ - | B115200); /* baud rate 115200 */ + termios->c_cflag + |= CS8; /* character size 8 bits */ /* * Force low_latency on; otherwise the pushes are scheduled; @@ -501,8 +495,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol * on the floor. We don't want to drop bytes on the floor. :) */ port->tty->low_latency = 1; - - return; + tty_encode_baud_rate(port->tty, 115200, 115200); } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8a8a6b9fb05b..c40e77dccf8e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -294,7 +294,7 @@ struct ftdi_private { __u16 interface; /* FT2232C port interface (0 for FT232/245) */ - int force_baud; /* if non-zero, force the baud rate to this value */ + speed_t force_baud; /* if non-zero, force the baud rate to this value */ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */ spinlock_t tx_lock; /* spinlock for transmit state */ @@ -878,6 +878,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) if (div_value == 0) { dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__, baud); div_value = ftdi_sio_b9600; + baud = 9600; div_okay = 0; } break; @@ -886,6 +887,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) div_value = ftdi_232am_baud_to_divisor(baud); } else { dbg("%s - Baud rate too high!", __FUNCTION__); + baud = 9600; div_value = ftdi_232am_baud_to_divisor(9600); div_okay = 0; } @@ -899,6 +901,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) dbg("%s - Baud rate too high!", __FUNCTION__); div_value = ftdi_232bm_baud_to_divisor(9600); div_okay = 0; + baud = 9600; } break; } /* priv->chip_type */ @@ -909,6 +912,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) ftdi_chip_name[priv->chip_type]); } + tty_encode_baud_rate(port->tty, baud, baud); return(div_value); } @@ -1263,7 +1267,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv) priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 77; - priv->force_baud = B38400; + priv->force_baud = 38400; } /* ftdi_USB_UIRT_setup */ /* Setup for the HE-TIRA1 device, which requires hardwired @@ -1274,7 +1278,7 @@ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv) priv->flags |= ASYNC_SPD_CUST; priv->custom_divisor = 240; - priv->force_baud = B38400; + priv->force_baud = 38400; priv->force_rtscts = 1; } /* ftdi_HE_TIRA1_setup */ @@ -1363,7 +1367,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) /* ftdi_set_termios will send usb control messages */ if (port->tty) - ftdi_set_termios(port, NULL); + ftdi_set_termios(port, port->tty->termios); /* FIXME: Flow control might be enabled, so it should be checked - we have no control of defaults! */ @@ -1933,32 +1937,33 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) { /* ftdi_termios */ struct usb_device *dev = port->serial->dev; - unsigned int cflag = port->tty->termios->c_cflag; struct ftdi_private *priv = usb_get_serial_port_data(port); + struct ktermios *termios = port->tty->termios; + unsigned int cflag = termios->c_cflag; __u16 urb_value; /* will hold the new flags */ char buf[1]; /* Perhaps I should dynamically alloc this? */ // Added for xon/xoff support - unsigned int iflag = port->tty->termios->c_iflag; + unsigned int iflag = termios->c_iflag; unsigned char vstop; unsigned char vstart; dbg("%s", __FUNCTION__); /* Force baud rate if this device requires it, unless it is set to B0. */ - if (priv->force_baud && ((port->tty->termios->c_cflag & CBAUD) != B0)) { + if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) { dbg("%s: forcing baud rate for this device", __FUNCTION__); - port->tty->termios->c_cflag &= ~CBAUD; - port->tty->termios->c_cflag |= priv->force_baud; + tty_encode_baud_rate(port->tty, priv->force_baud, + priv->force_baud); } /* Force RTS-CTS if this device requires it. */ if (priv->force_rtscts) { dbg("%s: forcing rtscts for this device", __FUNCTION__); - port->tty->termios->c_cflag |= CRTSCTS; + termios->c_cflag |= CRTSCTS; } - cflag = port->tty->termios->c_cflag; + cflag = termios->c_cflag; /* FIXME -For this cut I don't care if the line is really changing or not - so just do the change regardless - should be able to @@ -1969,6 +1974,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old /* Set number of data bits, parity, stop bits */ + termios->c_cflag &= ~CMSPAR; + urb_value = 0; urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : FTDI_SIO_SET_DATA_STOP_BITS_1); @@ -2048,8 +2055,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old // Set the vstart and vstop -- could have been done up above where // a lot of other dereferencing is done but that would be very // inefficient as vstart and vstop are not always needed - vstart=port->tty->termios->c_cc[VSTART]; - vstop=port->tty->termios->c_cc[VSTOP]; + vstart = termios->c_cc[VSTART]; + vstop = termios->c_cc[VSTOP]; urb_value=(vstop << 8) | (vstart); if (usb_control_msg(dev, diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 88a2c7dce335..9eb4a65ee4d9 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -208,14 +208,15 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * /* only do something if we have a bulk out endpoint */ if (serial->num_bulk_out) { - spin_lock_bh(&port->lock); + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); if (port->write_urb_busy) { - spin_unlock_bh(&port->lock); + spin_unlock_irqrestore(&port->lock, flags); dbg("%s - already writing", __FUNCTION__); return 0; } port->write_urb_busy = 1; - spin_unlock_bh(&port->lock); + spin_unlock_irqrestore(&port->lock, flags); count = (count > port->bulk_out_size) ? port->bulk_out_size : count; diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 8dd3abc99d63..a5d2e115e167 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1503,22 +1503,16 @@ static void edge_unthrottle (struct usb_serial_port *port) *****************************************************************************/ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) { + /* FIXME: This function appears unused ?? */ struct edgeport_port *edge_port = usb_get_serial_port_data(port); struct tty_struct *tty = port->tty; unsigned int cflag; - if (!port->tty || !port->tty->termios) { - dbg ("%s - no tty or termios", __FUNCTION__); - return; - } - cflag = tty->termios->c_cflag; dbg("%s - clfag %08x iflag %08x", __FUNCTION__, tty->termios->c_cflag, tty->termios->c_iflag); - if (old_termios) { - dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, - old_termios->c_cflag, old_termios->c_iflag); - } + dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, + old_termios->c_cflag, old_termios->c_iflag); dbg("%s - port %d", __FUNCTION__, port->number); @@ -2653,7 +2647,11 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi dbg("%s - baud rate = %d", __FUNCTION__, baud); status = send_cmd_write_baud_rate (edge_port, baud); - + if (status == -1) { + /* Speed change was not possible - put back the old speed */ + baud = tty_termios_baud_rate(old_termios); + tty_encode_baud_rate(tty, baud, baud); + } return; } diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 5ab6a0c5ac52..6b803ab98543 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -504,11 +504,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t dbg("%s - port %d", __FUNCTION__, port->number); - if ((!port->tty) || (!port->tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - baud = tty_get_baud_rate(port->tty); /* @@ -531,8 +526,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t default: ir_baud = SPEED_9600; baud = 9600; - /* And once the new tty stuff is all done we need to - call back to correct the baud bits */ } if (xbof == -1) @@ -562,6 +555,10 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t result = usb_submit_urb (port->write_urb, GFP_KERNEL); if (result) dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result); + + /* Only speed changes are supported */ + tty_termios_copy_hw(port->tty->termios, old_termios); + tty_encode_baud_rate(port->tty, baud, baud); } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index f2a6fce5de1e..6bfdba6a213f 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -278,29 +278,35 @@ static void keyspan_set_termios (struct usb_serial_port *port, struct keyspan_port_private *p_priv; const struct keyspan_device_details *d_details; unsigned int cflag; + struct tty_struct *tty = port->tty; dbg("%s", __FUNCTION__); p_priv = usb_get_serial_port_data(port); d_details = p_priv->device_details; - cflag = port->tty->termios->c_cflag; + cflag = tty->termios->c_cflag; device_port = port->number - port->serial->minor; /* Baud rate calculation takes baud rate as an integer so other rates can be generated if desired. */ - baud_rate = tty_get_baud_rate(port->tty); + baud_rate = tty_get_baud_rate(tty); /* If no match or invalid, don't change */ - if (baud_rate >= 0 - && d_details->calculate_baud_rate(baud_rate, d_details->baudclk, + if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk, NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) { /* FIXME - more to do here to ensure rate changes cleanly */ + /* FIXME - calcuate exact rate from divisor ? */ p_priv->baud = baud_rate; - } + } else + baud_rate = tty_termios_baud_rate(old_termios); + tty_encode_baud_rate(tty, baud_rate, baud_rate); /* set CTS/RTS handshake etc. */ p_priv->cflag = cflag; p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none; + /* Mark/Space not supported */ + tty->termios->c_cflag &= ~CMSPAR; + keyspan_send_setup(port, 0); } diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 6f224195bd25..aee450246bfd 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -616,8 +616,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old case 1200: urb_val = SUSBCR_SBR_1200; break; - case 9600: default: + speed = 9600; + case 9600: urb_val = SUSBCR_SBR_9600; break; } @@ -641,6 +642,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old urb_val |= SUSBCR_SPASB_NoParity; strcat(settings, "No Parity"); } + port->tty->termios->c_cflag &= ~CMSPAR; + tty_encode_baud_rate(port->tty, speed, speed); result = usb_control_msg( port->serial->dev, usb_rcvctrlpipe(port->serial->dev, 0 ), diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index f76480f1455d..a5ced7e08cbf 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1977,11 +1977,6 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, tty = mos7840_port->port->tty; - if ((!tty) || (!tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - dbg("%s", "Entering .......... \n"); lData = LCR_BITS_8; @@ -2151,11 +2146,6 @@ static void mos7840_set_termios(struct usb_serial_port *port, tty = port->tty; - if (!port->tty || !port->tty->termios) { - dbg("%s - no tty or termios", __FUNCTION__); - return; - } - if (!mos7840_port->open) { dbg("%s - port not opened", __FUNCTION__); return; @@ -2165,19 +2155,10 @@ static void mos7840_set_termios(struct usb_serial_port *port, cflag = tty->termios->c_cflag; - if (!cflag) { - dbg("%s %s\n", __FUNCTION__, "cflag is NULL"); - return; - } - dbg("%s - clfag %08x iflag %08x", __FUNCTION__, tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); - - if (old_termios) { - dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, - old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); - } - + dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, + old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); dbg("%s - port %d", __FUNCTION__, port->number); /* change the port settings to the new ones specified */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a18659e0700c..4590124cf888 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -172,6 +172,8 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */ { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ @@ -311,7 +313,8 @@ static void option_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { dbg("%s", __FUNCTION__); - + /* Doesn't support option setting */ + tty_termios_copy_hw(port->tty->termios, old_termios); option_send_setup(port); } diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 1da57fd9ea23..2cd3f1d4b687 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, + { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, @@ -470,16 +471,13 @@ static void pl2303_set_termios(struct usb_serial_port *port, dbg("%s - port %d", __FUNCTION__, port->number); - if ((!port->tty) || (!port->tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - return; - } - spin_lock_irqsave(&priv->lock, flags); if (!priv->termios_initialized) { *(port->tty->termios) = tty_std_termios; port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + port->tty->termios->c_ispeed = 9600; + port->tty->termios->c_ospeed = 9600; priv->termios_initialized = 1; } spin_unlock_irqrestore(&priv->lock, flags); @@ -596,6 +594,10 @@ static void pl2303_set_termios(struct usb_serial_port *port, dbg ("0x40:0x1:0x0:0x0 %d", i); } + /* FIXME: Need to read back resulting baud rate */ + if (baud) + tty_encode_baud_rate(port->tty, baud, baud); + kfree(buf); } diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index c39bace5cbcc..ed603e3decd6 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -20,6 +20,7 @@ #define IODATA_VENDOR_ID 0x04bb #define IODATA_PRODUCT_ID 0x0a03 +#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e #define ELCOM_VENDOR_ID 0x056e #define ELCOM_PRODUCT_ID 0x5003 diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 959b3e4e9077..833f6e1e3721 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -224,7 +224,7 @@ static void sierra_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { dbg("%s", __FUNCTION__); - + tty_termios_copy_hw(port->tty->termios, old_termios); sierra_send_setup(port); } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4b1bd7def4a5..497e29a700ca 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -429,6 +429,8 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios * old) /* pass on to the driver specific version of this function if it is available */ if (port->serial->type->set_termios) port->serial->type->set_termios(port, old); + else + tty_termios_copy_hw(tty->termios, old); } static void serial_break (struct tty_struct *tty, int break_state) @@ -1121,7 +1123,9 @@ int usb_serial_resume(struct usb_interface *intf) { struct usb_serial *serial = usb_get_intfdata(intf); - return serial->type->resume(serial); + if (serial->type->resume) + return serial->type->resume(serial); + return 0; } EXPORT_SYMBOL(usb_serial_resume); diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index cc8b44c08712..ee5dd8b5a713 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -885,16 +885,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios) { dbg("%s -port %d", __FUNCTION__, port->number); - - if ((!port->tty) || (!port->tty->termios)) { - dbg("%s - no tty structures", __FUNCTION__); - goto exit; - } - firm_setup_port(port); - -exit: - return; } @@ -1244,6 +1235,8 @@ static int firm_setup_port(struct usb_serial_port *port) { port_settings.baud = tty_get_baud_rate(port->tty); dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud); + /* fixme: should set validated settings */ + tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud); /* handle any settings that aren't specified in the tty structure */ port_settings.lloop = 0; diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index fe2c4cd53f5a..7e53333be013 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -48,7 +48,6 @@ config USB_STORAGE_FREECOM config USB_STORAGE_ISD200 bool "ISD-200 USB/ATA Bridge support" depends on USB_STORAGE - depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE ---help--- Say Y here if you want to use USB Mass Store devices based on the In-Systems Design ISD-200 USB/ATA bridge. diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 93a7724e167a..49ba6c0ff1e8 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -977,6 +977,109 @@ static int isd200_manual_enum(struct us_data *us) return(retStatus); } +/* + * We are the last non IDE user of the legacy IDE ident structures + * and we thus want to keep a private copy of this function so the + * driver can be used without the obsolete drivers/ide layer + */ + +static void isd200_fix_driveid (struct hd_driveid *id) +{ +#ifndef __LITTLE_ENDIAN +# ifdef __BIG_ENDIAN + int i; + u16 *stringcast; + + id->config = __le16_to_cpu(id->config); + id->cyls = __le16_to_cpu(id->cyls); + id->reserved2 = __le16_to_cpu(id->reserved2); + id->heads = __le16_to_cpu(id->heads); + id->track_bytes = __le16_to_cpu(id->track_bytes); + id->sector_bytes = __le16_to_cpu(id->sector_bytes); + id->sectors = __le16_to_cpu(id->sectors); + id->vendor0 = __le16_to_cpu(id->vendor0); + id->vendor1 = __le16_to_cpu(id->vendor1); + id->vendor2 = __le16_to_cpu(id->vendor2); + stringcast = (u16 *)&id->serial_no[0]; + for (i = 0; i < (20/2); i++) + stringcast[i] = __le16_to_cpu(stringcast[i]); + id->buf_type = __le16_to_cpu(id->buf_type); + id->buf_size = __le16_to_cpu(id->buf_size); + id->ecc_bytes = __le16_to_cpu(id->ecc_bytes); + stringcast = (u16 *)&id->fw_rev[0]; + for (i = 0; i < (8/2); i++) + stringcast[i] = __le16_to_cpu(stringcast[i]); + stringcast = (u16 *)&id->model[0]; + for (i = 0; i < (40/2); i++) + stringcast[i] = __le16_to_cpu(stringcast[i]); + id->dword_io = __le16_to_cpu(id->dword_io); + id->reserved50 = __le16_to_cpu(id->reserved50); + id->field_valid = __le16_to_cpu(id->field_valid); + id->cur_cyls = __le16_to_cpu(id->cur_cyls); + id->cur_heads = __le16_to_cpu(id->cur_heads); + id->cur_sectors = __le16_to_cpu(id->cur_sectors); + id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0); + id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1); + id->lba_capacity = __le32_to_cpu(id->lba_capacity); + id->dma_1word = __le16_to_cpu(id->dma_1word); + id->dma_mword = __le16_to_cpu(id->dma_mword); + id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes); + id->eide_dma_min = __le16_to_cpu(id->eide_dma_min); + id->eide_dma_time = __le16_to_cpu(id->eide_dma_time); + id->eide_pio = __le16_to_cpu(id->eide_pio); + id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy); + for (i = 0; i < 2; ++i) + id->words69_70[i] = __le16_to_cpu(id->words69_70[i]); + for (i = 0; i < 4; ++i) + id->words71_74[i] = __le16_to_cpu(id->words71_74[i]); + id->queue_depth = __le16_to_cpu(id->queue_depth); + for (i = 0; i < 4; ++i) + id->words76_79[i] = __le16_to_cpu(id->words76_79[i]); + id->major_rev_num = __le16_to_cpu(id->major_rev_num); + id->minor_rev_num = __le16_to_cpu(id->minor_rev_num); + id->command_set_1 = __le16_to_cpu(id->command_set_1); + id->command_set_2 = __le16_to_cpu(id->command_set_2); + id->cfsse = __le16_to_cpu(id->cfsse); + id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1); + id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2); + id->csf_default = __le16_to_cpu(id->csf_default); + id->dma_ultra = __le16_to_cpu(id->dma_ultra); + id->trseuc = __le16_to_cpu(id->trseuc); + id->trsEuc = __le16_to_cpu(id->trsEuc); + id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues); + id->mprc = __le16_to_cpu(id->mprc); + id->hw_config = __le16_to_cpu(id->hw_config); + id->acoustic = __le16_to_cpu(id->acoustic); + id->msrqs = __le16_to_cpu(id->msrqs); + id->sxfert = __le16_to_cpu(id->sxfert); + id->sal = __le16_to_cpu(id->sal); + id->spg = __le32_to_cpu(id->spg); + id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2); + for (i = 0; i < 22; i++) + id->words104_125[i] = __le16_to_cpu(id->words104_125[i]); + id->last_lun = __le16_to_cpu(id->last_lun); + id->word127 = __le16_to_cpu(id->word127); + id->dlf = __le16_to_cpu(id->dlf); + id->csfo = __le16_to_cpu(id->csfo); + for (i = 0; i < 26; i++) + id->words130_155[i] = __le16_to_cpu(id->words130_155[i]); + id->word156 = __le16_to_cpu(id->word156); + for (i = 0; i < 3; i++) + id->words157_159[i] = __le16_to_cpu(id->words157_159[i]); + id->cfa_power = __le16_to_cpu(id->cfa_power); + for (i = 0; i < 14; i++) + id->words161_175[i] = __le16_to_cpu(id->words161_175[i]); + for (i = 0; i < 31; i++) + id->words176_205[i] = __le16_to_cpu(id->words176_205[i]); + for (i = 0; i < 48; i++) + id->words206_254[i] = __le16_to_cpu(id->words206_254[i]); + id->integrity_word = __le16_to_cpu(id->integrity_word); +# else +# error "Please fix <asm/byteorder.h>" +# endif +#endif +} + /************************************************************************** * isd200_get_inquiry_data @@ -1018,7 +1121,7 @@ static int isd200_get_inquiry_data( struct us_data *us ) int i; __be16 *src; __u16 *dest; - ide_fix_driveid(id); + isd200_fix_driveid(id); US_DEBUGP(" Identify Data Structure:\n"); US_DEBUGP(" config = 0x%x\n", id->config); diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index f99cb77e7b42..f7e2d5add831 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -2509,8 +2509,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, cinfo = info->par; cinfo->btype = btype; - assert(z > 0); - assert(z2 >= 0); + assert(z); assert(btype != BT_NONE); cinfo->zdev = z; diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 0a9882edf562..9d70289f7df3 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -279,13 +279,13 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, int offset; int remainder_of_page; + sg_init_table(sg, sg_size); + while (size > 0 && i < sg_size) { pg = virt_to_page(addr); offset = offset_in_page(addr); - if (sg) { - sg_set_page(&sg[i], pg); - sg[i].offset = offset; - } + if (sg) + sg_set_page(&sg[i], pg, 0, offset); remainder_of_page = PAGE_CACHE_SIZE - offset; if (size >= remainder_of_page) { if (sg) @@ -716,12 +716,8 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, sg_init_table(&src_sg, 1); sg_init_table(&dst_sg, 1); - sg_set_page(&src_sg, src_page); - src_sg.offset = src_offset; - src_sg.length = size; - sg_set_page(&dst_sg, dst_page); - dst_sg.offset = dst_offset; - dst_sg.length = size; + sg_set_page(&src_sg, src_page, size, src_offset); + sg_set_page(&dst_sg, dst_page, size, dst_offset); return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv); } @@ -746,14 +742,11 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, struct scatterlist src_sg, dst_sg; sg_init_table(&src_sg, 1); + sg_set_page(&src_sg, src_page, size, src_offset); + sg_init_table(&dst_sg, 1); + sg_set_page(&dst_sg, dst_page, size, dst_offset); - sg_set_page(&src_sg, src_page); - src_sg.offset = src_offset; - src_sg.length = size; - sg_set_page(&dst_sg, dst_page); - dst_sg.offset = dst_offset; - dst_sg.length = size; return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 9728614b8958..77fc5838609c 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -372,7 +372,7 @@ int jffs2_init_acl_post(struct inode *inode) return rc; } - return rc; + return 0; } void jffs2_clear_acl(struct jffs2_inode_info *f) diff --git a/fs/mbcache.c b/fs/mbcache.c index 1046cbefbfbf..eb31b73e7d69 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -403,9 +403,9 @@ mb_cache_entry_alloc(struct mb_cache *cache) { struct mb_cache_entry *ce; - atomic_inc(&cache->c_entry_count); ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL); if (ce) { + atomic_inc(&cache->c_entry_count); INIT_LIST_HEAD(&ce->e_lru_list); INIT_LIST_HEAD(&ce->e_block_list); ce->e_cache = cache; diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 2e91fb756e9a..749def054a34 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -185,7 +185,7 @@ static __net_exit void proc_net_ns_exit(struct net *net) kfree(net->proc_net_root); } -struct pernet_operations __net_initdata proc_net_ns_ops = { +static struct pernet_operations proc_net_ns_ops = { .init = proc_net_ns_init, .exit = proc_net_ns_exit, }; diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 680c429bfa22..4e57fcf85982 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -171,7 +171,8 @@ static ssize_t proc_sys_read(struct file *filp, char __user *buf, struct dentry *dentry = filp->f_dentry; struct ctl_table_header *head; struct ctl_table *table; - ssize_t error, res; + ssize_t error; + size_t res; table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); /* Has the sysctl entry disappeared on us? */ @@ -209,7 +210,8 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf, struct dentry *dentry = filp->f_dentry; struct ctl_table_header *head; struct ctl_table *table; - ssize_t error, res; + ssize_t error; + size_t res; table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); /* Has the sysctl entry disappeared on us? */ diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index a7131630c057..57dc672bab8e 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -3,7 +3,7 @@ #include <linux/mm.h> #include <linux/device.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include <asm/processor.h> #include <asm/cacheflush.h> #include <asm/io.h> diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h index 99ba76edc42a..2e7143b5a7ad 100644 --- a/include/asm-frv/scatterlist.h +++ b/include/asm-frv/scatterlist.h @@ -16,8 +16,7 @@ * * can be rewritten as * - * sg_set_page(virt_to_page(some_ptr)); - * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK; + * sg_set_buf(sg, some_ptr, length); * * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens */ diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h index bdca5416d8b0..3328950dbfe6 100644 --- a/include/asm-sparc/atomic.h +++ b/include/asm-sparc/atomic.h @@ -1,6 +1,6 @@ /* atomic.h: These still suck, but the I-cache hit rate is higher. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au) * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org) * @@ -33,7 +33,7 @@ extern void __cmpxchg_called_with_bad_pointer(void); extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_); /* don't worry...optimizer will get rid of most of this */ -static __inline__ unsigned long +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) { switch(size) { diff --git a/include/asm-sparc/dma.h b/include/asm-sparc/dma.h index 407b3614468a..959d6c8a71ae 100644 --- a/include/asm-sparc/dma.h +++ b/include/asm-sparc/dma.h @@ -1,7 +1,6 @@ -/* $Id: dma.h,v 1.35 1999/12/27 06:37:09 anton Exp $ - * include/asm-sparc/dma.h +/* include/asm-sparc/dma.h * - * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu) + * Copyright 1995 (C) David S. Miller (davem@davemloft.net) */ #ifndef _ASM_SPARC_DMA_H @@ -21,14 +20,14 @@ struct page; extern spinlock_t dma_spin_lock; -static __inline__ unsigned long claim_dma_lock(void) +static inline unsigned long claim_dma_lock(void) { unsigned long flags; spin_lock_irqsave(&dma_spin_lock, flags); return flags; } -static __inline__ void release_dma_lock(unsigned long flags) +static inline void release_dma_lock(unsigned long flags) { spin_unlock_irqrestore(&dma_spin_lock, flags); } diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h index 5da1eef0f706..dbe7a586be5b 100644 --- a/include/asm-sparc/floppy.h +++ b/include/asm-sparc/floppy.h @@ -1,6 +1,6 @@ /* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver. * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@davemloft.net) */ #ifndef __ASM_SPARC_FLOPPY_H @@ -232,12 +232,12 @@ extern char *pdma_base; extern unsigned long pdma_areasize; /* Common routines to all controller types on the Sparc. */ -static __inline__ void virtual_dma_init(void) +static inline void virtual_dma_init(void) { /* nothing... */ } -static __inline__ void sun_fd_disable_dma(void) +static inline void sun_fd_disable_dma(void) { doing_pdma = 0; if (pdma_base) { @@ -246,7 +246,7 @@ static __inline__ void sun_fd_disable_dma(void) } } -static __inline__ void sun_fd_set_dma_mode(int mode) +static inline void sun_fd_set_dma_mode(int mode) { switch(mode) { case DMA_MODE_READ: @@ -261,17 +261,17 @@ static __inline__ void sun_fd_set_dma_mode(int mode) } } -static __inline__ void sun_fd_set_dma_addr(char *buffer) +static inline void sun_fd_set_dma_addr(char *buffer) { pdma_vaddr = buffer; } -static __inline__ void sun_fd_set_dma_count(int length) +static inline void sun_fd_set_dma_count(int length) { pdma_size = length; } -static __inline__ void sun_fd_enable_dma(void) +static inline void sun_fd_enable_dma(void) { pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size); pdma_base = pdma_vaddr; diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h index 404022765fc7..4076cb5d1581 100644 --- a/include/asm-sparc/ide.h +++ b/include/asm-sparc/ide.h @@ -1,7 +1,6 @@ -/* $Id: ide.h,v 1.7 2002/01/16 20:58:40 davem Exp $ - * ide.h: SPARC PCI specific IDE glue. +/* ide.h: SPARC PCI specific IDE glue. * - * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1997 David S. Miller (davem@davemloft.net) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Adaptation from sparc64 version to sparc by Pete Zaitcev. */ @@ -31,7 +30,7 @@ #define __ide_mm_outsw __ide_outsw #define __ide_mm_outsl __ide_outsl -static __inline__ void __ide_insw(unsigned long port, +static inline void __ide_insw(unsigned long port, void *dst, unsigned long count) { @@ -62,7 +61,7 @@ static __inline__ void __ide_insw(unsigned long port, /* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */ } -static __inline__ void __ide_outsw(unsigned long port, +static inline void __ide_outsw(unsigned long port, const void *src, unsigned long count) { diff --git a/include/asm-sparc/posix_types.h b/include/asm-sparc/posix_types.h index 9ef1b3db4cbf..62c8fa7b36d4 100644 --- a/include/asm-sparc/posix_types.h +++ b/include/asm-sparc/posix_types.h @@ -49,7 +49,7 @@ typedef struct { #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) #undef __FD_SET -static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) { unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; @@ -57,7 +57,7 @@ static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) } #undef __FD_CLR -static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) { unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; @@ -65,7 +65,7 @@ static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) } #undef __FD_ISSET -static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) +static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) { unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; @@ -77,7 +77,7 @@ static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) * for 256 and 1024-bit fd_sets respectively) */ #undef __FD_ZERO -static __inline__ void __FD_ZERO(__kernel_fd_set *p) +static inline void __FD_ZERO(__kernel_fd_set *p) { unsigned long *tmp = p->fds_bits; int i; diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h index 8c259de02614..2655d142b22d 100644 --- a/include/asm-sparc/system.h +++ b/include/asm-sparc/system.h @@ -1,5 +1,3 @@ -/* $Id: system.h,v 1.86 2001/10/30 04:57:10 davem Exp $ */ - #ifndef __SPARC_SYSTEM_H #define __SPARC_SYSTEM_H @@ -56,7 +54,7 @@ extern void sun_do_break(void); extern int serial_console; extern int stop_a_enabled; -static __inline__ int con_is_present(void) +static inline int con_is_present(void) { return serial_console ? 0 : 1; } @@ -217,7 +215,7 @@ static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned lon extern void __xchg_called_with_bad_pointer(void); -static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) +static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) { switch (size) { case 4: diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h index 3fb4e1f7f186..2c71ec4a3b18 100644 --- a/include/asm-sparc64/atomic.h +++ b/include/asm-sparc64/atomic.h @@ -1,5 +1,4 @@ -/* $Id: atomic.h,v 1.22 2001/07/11 23:56:07 davem Exp $ - * atomic.h: Thankfully the V9 is at least reasonable for this +/* atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) @@ -74,7 +73,7 @@ extern int atomic64_sub_ret(int, atomic64_t *); #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) +static inline int atomic_add_unless(atomic_t *v, int a, int u) { int c, old; c = atomic_read(v); @@ -95,7 +94,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n))) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) +static inline int atomic64_add_unless(atomic64_t *v, long a, long u) { long c, old; c = atomic64_read(v); diff --git a/include/asm-sparc64/backoff.h b/include/asm-sparc64/backoff.h index 0e32f8b62fd2..dadd6c385c6c 100644 --- a/include/asm-sparc64/backoff.h +++ b/include/asm-sparc64/backoff.h @@ -21,7 +21,9 @@ #else #define BACKOFF_SETUP(reg) -#define BACKOFF_SPIN(reg, tmp, label) +#define BACKOFF_SPIN(reg, tmp, label) \ + ba,pt %xcc, label; \ + nop; #endif diff --git a/include/asm-sparc64/byteorder.h b/include/asm-sparc64/byteorder.h index c69b08af5fe0..3943022906fd 100644 --- a/include/asm-sparc64/byteorder.h +++ b/include/asm-sparc64/byteorder.h @@ -1,4 +1,3 @@ -/* $Id: byteorder.h,v 1.8 1997/12/18 02:44:14 ecd Exp $ */ #ifndef _SPARC64_BYTEORDER_H #define _SPARC64_BYTEORDER_H @@ -7,7 +6,7 @@ #ifdef __GNUC__ -static __inline__ __u16 ___arch__swab16p(const __u16 *addr) +static inline __u16 ___arch__swab16p(const __u16 *addr) { __u16 ret; @@ -17,7 +16,7 @@ static __inline__ __u16 ___arch__swab16p(const __u16 *addr) return ret; } -static __inline__ __u32 ___arch__swab32p(const __u32 *addr) +static inline __u32 ___arch__swab32p(const __u32 *addr) { __u32 ret; @@ -27,7 +26,7 @@ static __inline__ __u32 ___arch__swab32p(const __u32 *addr) return ret; } -static __inline__ __u64 ___arch__swab64p(const __u64 *addr) +static inline __u64 ___arch__swab64p(const __u64 *addr) { __u64 ret; diff --git a/include/asm-sparc64/fpumacro.h b/include/asm-sparc64/fpumacro.h index d583e5efd75d..cc463fec806f 100644 --- a/include/asm-sparc64/fpumacro.h +++ b/include/asm-sparc64/fpumacro.h @@ -16,7 +16,7 @@ struct fpustate { #define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs) -static __inline__ unsigned long fprs_read(void) +static inline unsigned long fprs_read(void) { unsigned long retval; @@ -25,7 +25,7 @@ static __inline__ unsigned long fprs_read(void) return retval; } -static __inline__ void fprs_write(unsigned long val) +static inline void fprs_write(unsigned long val) { __asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val)); } diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h index cd7ef3097ac2..c299b853b5ba 100644 --- a/include/asm-sparc64/io.h +++ b/include/asm-sparc64/io.h @@ -1,4 +1,3 @@ -/* $Id: io.h,v 1.47 2001/12/13 10:36:02 davem Exp $ */ #ifndef __SPARC64_IO_H #define __SPARC64_IO_H @@ -19,7 +18,7 @@ extern unsigned long kern_base, kern_size; #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #define BIO_VMERGE_BOUNDARY 8192 -static __inline__ u8 _inb(unsigned long addr) +static inline u8 _inb(unsigned long addr) { u8 ret; @@ -30,7 +29,7 @@ static __inline__ u8 _inb(unsigned long addr) return ret; } -static __inline__ u16 _inw(unsigned long addr) +static inline u16 _inw(unsigned long addr) { u16 ret; @@ -41,7 +40,7 @@ static __inline__ u16 _inw(unsigned long addr) return ret; } -static __inline__ u32 _inl(unsigned long addr) +static inline u32 _inl(unsigned long addr) { u32 ret; @@ -52,21 +51,21 @@ static __inline__ u32 _inl(unsigned long addr) return ret; } -static __inline__ void _outb(u8 b, unsigned long addr) +static inline void _outb(u8 b, unsigned long addr) { __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */" : /* no outputs */ : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } -static __inline__ void _outw(u16 w, unsigned long addr) +static inline void _outw(u16 w, unsigned long addr) { __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */" : /* no outputs */ : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } -static __inline__ void _outl(u32 l, unsigned long addr) +static inline void _outl(u32 l, unsigned long addr) { __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */" : /* no outputs */ @@ -205,7 +204,7 @@ static inline void _writeq(u64 q, volatile void __iomem *addr) #define writeq(__q, __addr) _writeq(__q, __addr) /* Now versions without byte-swapping. */ -static __inline__ u8 _raw_readb(unsigned long addr) +static inline u8 _raw_readb(unsigned long addr) { u8 ret; @@ -216,7 +215,7 @@ static __inline__ u8 _raw_readb(unsigned long addr) return ret; } -static __inline__ u16 _raw_readw(unsigned long addr) +static inline u16 _raw_readw(unsigned long addr) { u16 ret; @@ -227,7 +226,7 @@ static __inline__ u16 _raw_readw(unsigned long addr) return ret; } -static __inline__ u32 _raw_readl(unsigned long addr) +static inline u32 _raw_readl(unsigned long addr) { u32 ret; @@ -238,7 +237,7 @@ static __inline__ u32 _raw_readl(unsigned long addr) return ret; } -static __inline__ u64 _raw_readq(unsigned long addr) +static inline u64 _raw_readq(unsigned long addr) { u64 ret; @@ -249,28 +248,28 @@ static __inline__ u64 _raw_readq(unsigned long addr) return ret; } -static __inline__ void _raw_writeb(u8 b, unsigned long addr) +static inline void _raw_writeb(u8 b, unsigned long addr) { __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" : /* no outputs */ : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static __inline__ void _raw_writew(u16 w, unsigned long addr) +static inline void _raw_writew(u16 w, unsigned long addr) { __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" : /* no outputs */ : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static __inline__ void _raw_writel(u32 l, unsigned long addr) +static inline void _raw_writel(u32 l, unsigned long addr) { __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" : /* no outputs */ : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static __inline__ void _raw_writeq(u64 q, unsigned long addr) +static inline void _raw_writeq(u64 q, unsigned long addr) { __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */" : /* no outputs */ diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 182dba05c702..30cb76b47be1 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -1,7 +1,6 @@ -/* $Id: irq.h,v 1.21 2002/01/23 11:27:36 davem Exp $ - * irq.h: IRQ registers on the 64-bit Sparc. +/* irq.h: IRQ registers on the 64-bit Sparc. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) */ @@ -67,21 +66,21 @@ extern void virt_irq_free(unsigned int virt_irq); extern void fixup_irqs(void); -static __inline__ void set_softint(unsigned long bits) +static inline void set_softint(unsigned long bits) { __asm__ __volatile__("wr %0, 0x0, %%set_softint" : /* No outputs */ : "r" (bits)); } -static __inline__ void clear_softint(unsigned long bits) +static inline void clear_softint(unsigned long bits) { __asm__ __volatile__("wr %0, 0x0, %%clear_softint" : /* No outputs */ : "r" (bits)); } -static __inline__ unsigned long get_softint(void) +static inline unsigned long get_softint(void) { unsigned long retval; diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h index d14dd8988161..c5652de2ace2 100644 --- a/include/asm-sparc64/mostek.h +++ b/include/asm-sparc64/mostek.h @@ -1,7 +1,6 @@ -/* $Id: mostek.h,v 1.4 2001/01/11 15:07:09 davem Exp $ - * mostek.h: Describes the various Mostek time of day clock registers. +/* mostek.h: Describes the various Mostek time of day clock registers. * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1995 David S. Miller (davem@davemloft.net) * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) */ @@ -38,7 +37,7 @@ * * We now deal with physical addresses for I/O to the chip. -DaveM */ -static __inline__ u8 mostek_read(void __iomem *addr) +static inline u8 mostek_read(void __iomem *addr) { u8 ret; @@ -48,7 +47,7 @@ static __inline__ u8 mostek_read(void __iomem *addr) return ret; } -static __inline__ void mostek_write(void __iomem *addr, u8 val) +static inline void mostek_write(void __iomem *addr, u8 val) { __asm__ __volatile__("stba %0, [%1] %2" : /* no outputs */ diff --git a/include/asm-sparc64/ns87303.h b/include/asm-sparc64/ns87303.h index 6d58fdf349b5..686defe6aaa0 100644 --- a/include/asm-sparc64/ns87303.h +++ b/include/asm-sparc64/ns87303.h @@ -1,5 +1,4 @@ -/* $Id: ns87303.h,v 1.3 2000/01/09 15:16:34 ecd Exp $ - * ns87303.h: Configuration Register Description for the +/* ns87303.h: Configuration Register Description for the * National Semiconductor PC87303 (SuperIO). * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -85,7 +84,7 @@ extern spinlock_t ns87303_lock; -static __inline__ int ns87303_modify(unsigned long port, unsigned int index, +static inline int ns87303_modify(unsigned long port, unsigned int index, unsigned char clr, unsigned char set) { static unsigned char reserved[] = { diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h index 8116e8f6062c..e9555b246c8d 100644 --- a/include/asm-sparc64/parport.h +++ b/include/asm-sparc64/parport.h @@ -1,5 +1,4 @@ -/* $Id: parport.h,v 1.11 2001/05/11 07:54:24 davem Exp $ - * parport.h: sparc64 specific parport initialization and dma. +/* parport.h: sparc64 specific parport initialization and dma. * * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) */ @@ -42,7 +41,7 @@ static struct sparc_ebus_info { static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS); -static __inline__ int request_dma(unsigned int dmanr, const char *device_id) +static inline int request_dma(unsigned int dmanr, const char *device_id) { if (dmanr >= PARPORT_PC_MAX_PORTS) return -EINVAL; @@ -51,7 +50,7 @@ static __inline__ int request_dma(unsigned int dmanr, const char *device_id) return 0; } -static __inline__ void free_dma(unsigned int dmanr) +static inline void free_dma(unsigned int dmanr) { if (dmanr >= PARPORT_PC_MAX_PORTS) { printk(KERN_WARNING "Trying to free DMA%d\n", dmanr); @@ -63,7 +62,7 @@ static __inline__ void free_dma(unsigned int dmanr) } } -static __inline__ void enable_dma(unsigned int dmanr) +static inline void enable_dma(unsigned int dmanr) { ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); @@ -73,32 +72,32 @@ static __inline__ void enable_dma(unsigned int dmanr) BUG(); } -static __inline__ void disable_dma(unsigned int dmanr) +static inline void disable_dma(unsigned int dmanr) { ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0); } -static __inline__ void clear_dma_ff(unsigned int dmanr) +static inline void clear_dma_ff(unsigned int dmanr) { /* nothing */ } -static __inline__ void set_dma_mode(unsigned int dmanr, char mode) +static inline void set_dma_mode(unsigned int dmanr, char mode) { ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE)); } -static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int addr) +static inline void set_dma_addr(unsigned int dmanr, unsigned int addr) { sparc_ebus_dmas[dmanr].addr = addr; } -static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) +static inline void set_dma_count(unsigned int dmanr, unsigned int count) { sparc_ebus_dmas[dmanr].count = count; } -static __inline__ unsigned int get_dma_residue(unsigned int dmanr) +static inline unsigned int get_dma_residue(unsigned int dmanr) { return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); } diff --git a/include/asm-sparc64/posix_types.h b/include/asm-sparc64/posix_types.h index c86b9452c683..3426a65ecd35 100644 --- a/include/asm-sparc64/posix_types.h +++ b/include/asm-sparc64/posix_types.h @@ -53,7 +53,7 @@ typedef struct { #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) #undef __FD_SET -static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) +static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) { unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; @@ -61,7 +61,7 @@ static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) } #undef __FD_CLR -static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) +static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) { unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; @@ -69,7 +69,7 @@ static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) } #undef __FD_ISSET -static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) +static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) { unsigned long _tmp = fd / __NFDBITS; unsigned long _rem = fd % __NFDBITS; @@ -81,7 +81,7 @@ static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p) * for 256 and 1024-bit fd_sets respectively) */ #undef __FD_ZERO -static __inline__ void __FD_ZERO(__kernel_fd_set *p) +static inline void __FD_ZERO(__kernel_fd_set *p) { unsigned long *tmp = p->fds_bits; int i; diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h index 0151cad486f3..24a04a55cf85 100644 --- a/include/asm-sparc64/sbus.h +++ b/include/asm-sparc64/sbus.h @@ -29,12 +29,12 @@ * numbers + offsets, and vice versa. */ -static __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset) +static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset) { return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset)); } -static __inline__ int sbus_dev_slot(unsigned long dev_addr) +static inline int sbus_dev_slot(unsigned long dev_addr) { return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28); } diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h index cf7807813e85..63b7040e8134 100644 --- a/include/asm-sparc64/spitfire.h +++ b/include/asm-sparc64/spitfire.h @@ -1,7 +1,6 @@ -/* $Id: spitfire.h,v 1.18 2001/11/29 16:42:10 kanoj Exp $ - * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. +/* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. * - * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) */ #ifndef _SPARC64_SPITFIRE_H @@ -67,7 +66,7 @@ extern void cheetah_enable_pcache(void); /* The data cache is write through, so this just invalidates the * specified line. */ -static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag) +static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -81,7 +80,7 @@ static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long * a flush instruction (to any address) is sufficient to handle * this issue after the line is invalidated. */ -static __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag) +static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -89,7 +88,7 @@ static __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long : "r" (tag), "r" (addr), "i" (ASI_IC_TAG)); } -static __inline__ unsigned long spitfire_get_dtlb_data(int entry) +static inline unsigned long spitfire_get_dtlb_data(int entry) { unsigned long data; @@ -103,7 +102,7 @@ static __inline__ unsigned long spitfire_get_dtlb_data(int entry) return data; } -static __inline__ unsigned long spitfire_get_dtlb_tag(int entry) +static inline unsigned long spitfire_get_dtlb_tag(int entry) { unsigned long tag; @@ -113,7 +112,7 @@ static __inline__ unsigned long spitfire_get_dtlb_tag(int entry) return tag; } -static __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data) +static inline void spitfire_put_dtlb_data(int entry, unsigned long data) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -122,7 +121,7 @@ static __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data) "i" (ASI_DTLB_DATA_ACCESS)); } -static __inline__ unsigned long spitfire_get_itlb_data(int entry) +static inline unsigned long spitfire_get_itlb_data(int entry) { unsigned long data; @@ -136,7 +135,7 @@ static __inline__ unsigned long spitfire_get_itlb_data(int entry) return data; } -static __inline__ unsigned long spitfire_get_itlb_tag(int entry) +static inline unsigned long spitfire_get_itlb_tag(int entry) { unsigned long tag; @@ -146,7 +145,7 @@ static __inline__ unsigned long spitfire_get_itlb_tag(int entry) return tag; } -static __inline__ void spitfire_put_itlb_data(int entry, unsigned long data) +static inline void spitfire_put_itlb_data(int entry, unsigned long data) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -155,7 +154,7 @@ static __inline__ void spitfire_put_itlb_data(int entry, unsigned long data) "i" (ASI_ITLB_DATA_ACCESS)); } -static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page) +static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page) { __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" "membar #Sync" @@ -163,7 +162,7 @@ static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page) : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP)); } -static __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page) +static inline void spitfire_flush_itlb_nucleus_page(unsigned long page) { __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" "membar #Sync" @@ -172,7 +171,7 @@ static __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page) } /* Cheetah has "all non-locked" tlb flushes. */ -static __inline__ void cheetah_flush_dtlb_all(void) +static inline void cheetah_flush_dtlb_all(void) { __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" "membar #Sync" @@ -180,7 +179,7 @@ static __inline__ void cheetah_flush_dtlb_all(void) : "r" (0x80), "i" (ASI_DMMU_DEMAP)); } -static __inline__ void cheetah_flush_itlb_all(void) +static inline void cheetah_flush_itlb_all(void) { __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" "membar #Sync" @@ -202,7 +201,7 @@ static __inline__ void cheetah_flush_itlb_all(void) * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes * the problem for me. -DaveM */ -static __inline__ unsigned long cheetah_get_ldtlb_data(int entry) +static inline unsigned long cheetah_get_ldtlb_data(int entry) { unsigned long data; @@ -215,7 +214,7 @@ static __inline__ unsigned long cheetah_get_ldtlb_data(int entry) return data; } -static __inline__ unsigned long cheetah_get_litlb_data(int entry) +static inline unsigned long cheetah_get_litlb_data(int entry) { unsigned long data; @@ -228,7 +227,7 @@ static __inline__ unsigned long cheetah_get_litlb_data(int entry) return data; } -static __inline__ unsigned long cheetah_get_ldtlb_tag(int entry) +static inline unsigned long cheetah_get_ldtlb_tag(int entry) { unsigned long tag; @@ -240,7 +239,7 @@ static __inline__ unsigned long cheetah_get_ldtlb_tag(int entry) return tag; } -static __inline__ unsigned long cheetah_get_litlb_tag(int entry) +static inline unsigned long cheetah_get_litlb_tag(int entry) { unsigned long tag; @@ -252,7 +251,7 @@ static __inline__ unsigned long cheetah_get_litlb_tag(int entry) return tag; } -static __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data) +static inline void cheetah_put_ldtlb_data(int entry, unsigned long data) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -262,7 +261,7 @@ static __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data) "i" (ASI_DTLB_DATA_ACCESS)); } -static __inline__ void cheetah_put_litlb_data(int entry, unsigned long data) +static inline void cheetah_put_litlb_data(int entry, unsigned long data) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -272,7 +271,7 @@ static __inline__ void cheetah_put_litlb_data(int entry, unsigned long data) "i" (ASI_ITLB_DATA_ACCESS)); } -static __inline__ unsigned long cheetah_get_dtlb_data(int entry, int tlb) +static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb) { unsigned long data; @@ -284,7 +283,7 @@ static __inline__ unsigned long cheetah_get_dtlb_data(int entry, int tlb) return data; } -static __inline__ unsigned long cheetah_get_dtlb_tag(int entry, int tlb) +static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb) { unsigned long tag; @@ -294,7 +293,7 @@ static __inline__ unsigned long cheetah_get_dtlb_tag(int entry, int tlb) return tag; } -static __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb) +static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" @@ -304,7 +303,7 @@ static __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data, int "i" (ASI_DTLB_DATA_ACCESS)); } -static __inline__ unsigned long cheetah_get_itlb_data(int entry) +static inline unsigned long cheetah_get_itlb_data(int entry) { unsigned long data; @@ -317,7 +316,7 @@ static __inline__ unsigned long cheetah_get_itlb_data(int entry) return data; } -static __inline__ unsigned long cheetah_get_itlb_tag(int entry) +static inline unsigned long cheetah_get_itlb_tag(int entry) { unsigned long tag; @@ -327,7 +326,7 @@ static __inline__ unsigned long cheetah_get_itlb_tag(int entry) return tag; } -static __inline__ void cheetah_put_itlb_data(int entry, unsigned long data) +static inline void cheetah_put_itlb_data(int entry, unsigned long data) { __asm__ __volatile__("stxa %0, [%1] %2\n\t" "membar #Sync" diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index 3f175fa7e6d2..159e62b51d70 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -1,4 +1,3 @@ -/* $Id: system.h,v 1.69 2002/02/09 19:49:31 davem Exp $ */ #ifndef __SPARC64_SYSTEM_H #define __SPARC64_SYSTEM_H @@ -240,7 +239,7 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long extern void __xchg_called_with_bad_pointer(void); -static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, +static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size) { switch (size) { @@ -263,7 +262,7 @@ extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noret #define __HAVE_ARCH_CMPXCHG 1 -static __inline__ unsigned long +static inline unsigned long __cmpxchg_u32(volatile int *m, int old, int new) { __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" @@ -276,7 +275,7 @@ __cmpxchg_u32(volatile int *m, int old, int new) return new; } -static __inline__ unsigned long +static inline unsigned long __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) { __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n" @@ -293,7 +292,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) if something tries to do an invalid cmpxchg(). */ extern void __cmpxchg_called_with_bad_pointer(void); -static __inline__ unsigned long +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { switch (size) { diff --git a/include/asm-sparc64/upa.h b/include/asm-sparc64/upa.h index 7ae09a22e408..5b1633223f92 100644 --- a/include/asm-sparc64/upa.h +++ b/include/asm-sparc64/upa.h @@ -1,4 +1,3 @@ -/* $Id: upa.h,v 1.3 1999/09/21 14:39:47 davem Exp $ */ #ifndef _SPARC64_UPA_H #define _SPARC64_UPA_H @@ -25,7 +24,7 @@ /* UPA I/O space accessors */ #if defined(__KERNEL__) && !defined(__ASSEMBLY__) -static __inline__ unsigned char _upa_readb(unsigned long addr) +static inline unsigned char _upa_readb(unsigned long addr) { unsigned char ret; @@ -36,7 +35,7 @@ static __inline__ unsigned char _upa_readb(unsigned long addr) return ret; } -static __inline__ unsigned short _upa_readw(unsigned long addr) +static inline unsigned short _upa_readw(unsigned long addr) { unsigned short ret; @@ -47,7 +46,7 @@ static __inline__ unsigned short _upa_readw(unsigned long addr) return ret; } -static __inline__ unsigned int _upa_readl(unsigned long addr) +static inline unsigned int _upa_readl(unsigned long addr) { unsigned int ret; @@ -58,7 +57,7 @@ static __inline__ unsigned int _upa_readl(unsigned long addr) return ret; } -static __inline__ unsigned long _upa_readq(unsigned long addr) +static inline unsigned long _upa_readq(unsigned long addr) { unsigned long ret; @@ -69,28 +68,28 @@ static __inline__ unsigned long _upa_readq(unsigned long addr) return ret; } -static __inline__ void _upa_writeb(unsigned char b, unsigned long addr) +static inline void _upa_writeb(unsigned char b, unsigned long addr) { __asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */" : /* no outputs */ : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static __inline__ void _upa_writew(unsigned short w, unsigned long addr) +static inline void _upa_writew(unsigned short w, unsigned long addr) { __asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */" : /* no outputs */ : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static __inline__ void _upa_writel(unsigned int l, unsigned long addr) +static inline void _upa_writel(unsigned int l, unsigned long addr) { __asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */" : /* no outputs */ : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static __inline__ void _upa_writeq(unsigned long q, unsigned long addr) +static inline void _upa_writeq(unsigned long q, unsigned long addr) { __asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */" : /* no outputs */ diff --git a/include/asm-sparc64/visasm.h b/include/asm-sparc64/visasm.h index a74078551e0f..34f2ec64933b 100644 --- a/include/asm-sparc64/visasm.h +++ b/include/asm-sparc64/visasm.h @@ -1,4 +1,3 @@ -/* $Id: visasm.h,v 1.5 2001/04/24 01:09:12 davem Exp $ */ #ifndef _SPARC64_VISASM_H #define _SPARC64_VISASM_H @@ -44,7 +43,7 @@ wr %o5, 0, %fprs; #ifndef __ASSEMBLY__ -static __inline__ void save_and_clear_fpu(void) { +static inline void save_and_clear_fpu(void) { __asm__ __volatile__ ( " rd %%fprs, %%o5\n" " andcc %%o5, %0, %%g0\n" diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h index 36ebb5b02b4f..0b40f6d20bea 100644 --- a/include/asm-x86/bitops_32.h +++ b/include/asm-x86/bitops_32.h @@ -183,9 +183,12 @@ static inline int test_and_set_bit(int nr, volatile unsigned long * addr) * @nr: Bit to set * @addr: Address to count from * - * This is the same as test_and_set_bit on x86 + * This is the same as test_and_set_bit on x86. */ -#define test_and_set_bit_lock test_and_set_bit +static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) +{ + return test_and_set_bit(nr, addr); +} /** * __test_and_set_bit - Set a bit and return its old value diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h index b4d47940b959..766bcc0470a6 100644 --- a/include/asm-x86/bitops_64.h +++ b/include/asm-x86/bitops_64.h @@ -29,7 +29,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static __inline__ void set_bit(int nr, volatile void * addr) +static inline void set_bit(int nr, volatile void *addr) { __asm__ __volatile__( LOCK_PREFIX "btsl %1,%0" @@ -46,7 +46,7 @@ static __inline__ void set_bit(int nr, volatile void * addr) * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static __inline__ void __set_bit(int nr, volatile void * addr) +static inline void __set_bit(int nr, volatile void *addr) { __asm__ volatile( "btsl %1,%0" @@ -64,7 +64,7 @@ static __inline__ void __set_bit(int nr, volatile void * addr) * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -static __inline__ void clear_bit(int nr, volatile void * addr) +static inline void clear_bit(int nr, volatile void *addr) { __asm__ __volatile__( LOCK_PREFIX "btrl %1,%0" @@ -86,7 +86,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad clear_bit(nr, addr); } -static __inline__ void __clear_bit(int nr, volatile void * addr) +static inline void __clear_bit(int nr, volatile void *addr) { __asm__ __volatile__( "btrl %1,%0" @@ -124,7 +124,7 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long * * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -static __inline__ void __change_bit(int nr, volatile void * addr) +static inline void __change_bit(int nr, volatile void *addr) { __asm__ __volatile__( "btcl %1,%0" @@ -141,7 +141,7 @@ static __inline__ void __change_bit(int nr, volatile void * addr) * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -static __inline__ void change_bit(int nr, volatile void * addr) +static inline void change_bit(int nr, volatile void *addr) { __asm__ __volatile__( LOCK_PREFIX "btcl %1,%0" @@ -157,7 +157,7 @@ static __inline__ void change_bit(int nr, volatile void * addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static __inline__ int test_and_set_bit(int nr, volatile void * addr) +static inline int test_and_set_bit(int nr, volatile void *addr) { int oldbit; @@ -173,9 +173,12 @@ static __inline__ int test_and_set_bit(int nr, volatile void * addr) * @nr: Bit to set * @addr: Address to count from * - * This is the same as test_and_set_bit on x86 + * This is the same as test_and_set_bit on x86. */ -#define test_and_set_bit_lock test_and_set_bit +static inline int test_and_set_bit_lock(int nr, volatile void *addr) +{ + return test_and_set_bit(nr, addr); +} /** * __test_and_set_bit - Set a bit and return its old value @@ -186,7 +189,7 @@ static __inline__ int test_and_set_bit(int nr, volatile void * addr) * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -static __inline__ int __test_and_set_bit(int nr, volatile void * addr) +static inline int __test_and_set_bit(int nr, volatile void *addr) { int oldbit; @@ -205,7 +208,7 @@ static __inline__ int __test_and_set_bit(int nr, volatile void * addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +static inline int test_and_clear_bit(int nr, volatile void *addr) { int oldbit; @@ -225,7 +228,7 @@ static __inline__ int test_and_clear_bit(int nr, volatile void * addr) * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +static inline int __test_and_clear_bit(int nr, volatile void *addr) { int oldbit; @@ -237,7 +240,7 @@ static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) } /* WARNING: non atomic and it can be reordered! */ -static __inline__ int __test_and_change_bit(int nr, volatile void * addr) +static inline int __test_and_change_bit(int nr, volatile void *addr) { int oldbit; @@ -256,7 +259,7 @@ static __inline__ int __test_and_change_bit(int nr, volatile void * addr) * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -static __inline__ int test_and_change_bit(int nr, volatile void * addr) +static inline int test_and_change_bit(int nr, volatile void *addr) { int oldbit; @@ -273,15 +276,15 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr) * @nr: bit number to test * @addr: Address to start counting from */ -static int test_bit(int nr, const volatile void * addr); +static int test_bit(int nr, const volatile void *addr); #endif -static __inline__ int constant_test_bit(int nr, const volatile void * addr) +static inline int constant_test_bit(int nr, const volatile void *addr) { return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; } -static __inline__ int variable_test_bit(int nr, volatile const void * addr) +static inline int variable_test_bit(int nr, volatile const void *addr) { int oldbit; @@ -299,10 +302,10 @@ static __inline__ int variable_test_bit(int nr, volatile const void * addr) #undef ADDR -extern long find_first_zero_bit(const unsigned long * addr, unsigned long size); -extern long find_next_zero_bit (const unsigned long * addr, long size, long offset); -extern long find_first_bit(const unsigned long * addr, unsigned long size); -extern long find_next_bit(const unsigned long * addr, long size, long offset); +extern long find_first_zero_bit(const unsigned long *addr, unsigned long size); +extern long find_next_zero_bit(const unsigned long *addr, long size, long offset); +extern long find_first_bit(const unsigned long *addr, unsigned long size); +extern long find_next_bit(const unsigned long *addr, long size, long offset); /* return index of first bet set in val or max when no bit is set */ static inline long __scanbit(unsigned long val, unsigned long max) @@ -363,7 +366,7 @@ static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i, * * Undefined if no zero exists, so code should check against ~0UL first. */ -static __inline__ unsigned long ffz(unsigned long word) +static inline unsigned long ffz(unsigned long word) { __asm__("bsfq %1,%0" :"=r" (word) @@ -377,7 +380,7 @@ static __inline__ unsigned long ffz(unsigned long word) * * Undefined if no bit exists, so code should check against 0 first. */ -static __inline__ unsigned long __ffs(unsigned long word) +static inline unsigned long __ffs(unsigned long word) { __asm__("bsfq %1,%0" :"=r" (word) @@ -391,7 +394,7 @@ static __inline__ unsigned long __ffs(unsigned long word) * * Undefined if no zero exists, so code should check against ~0UL first. */ -static __inline__ unsigned long __fls(unsigned long word) +static inline unsigned long __fls(unsigned long word) { __asm__("bsrq %1,%0" :"=r" (word) @@ -411,7 +414,7 @@ static __inline__ unsigned long __fls(unsigned long word) * the libc and compiler builtin ffs routines, therefore * differs in spirit from the above ffz (man ffs). */ -static __inline__ int ffs(int x) +static inline int ffs(int x) { int r; @@ -427,7 +430,7 @@ static __inline__ int ffs(int x) * * This is defined the same way as fls. */ -static __inline__ int fls64(__u64 x) +static inline int fls64(__u64 x) { if (x == 0) return 0; @@ -440,7 +443,7 @@ static __inline__ int fls64(__u64 x) * * This is defined the same way as ffs. */ -static __inline__ int fls(int x) +static inline int fls(int x) { int r; diff --git a/include/asm-x86/lguest_hcall.h b/include/asm-x86/lguest_hcall.h index f948491eb56a..9c5092b6aa9f 100644 --- a/include/asm-x86/lguest_hcall.h +++ b/include/asm-x86/lguest_hcall.h @@ -18,12 +18,17 @@ #define LHCALL_LOAD_TLS 16 #define LHCALL_NOTIFY 17 +#define LGUEST_TRAP_ENTRY 0x1F + +#ifndef __ASSEMBLY__ +#include <asm/hw_irq.h> + /*G:031 First, how does our Guest contact the Host to ask for privileged * operations? There are two ways: the direct way is to make a "hypercall", * to make requests of the Host Itself. * * Our hypercall mechanism uses the highest unused trap code (traps 32 and - * above are used by real hardware interrupts). Seventeen hypercalls are + * above are used by real hardware interrupts). Fifteen hypercalls are * available: the hypercall number is put in the %eax register, and the * arguments (when required) are placed in %edx, %ebx and %ecx. If a return * value makes sense, it's returned in %eax. @@ -31,20 +36,15 @@ * Grossly invalid calls result in Sudden Death at the hands of the vengeful * Host, rather than returning failure. This reflects Winston Churchill's * definition of a gentleman: "someone who is only rude intentionally". */ -#define LGUEST_TRAP_ENTRY 0x1F - -#ifndef __ASSEMBLY__ -#include <asm/hw_irq.h> - static inline unsigned long hcall(unsigned long call, unsigned long arg1, unsigned long arg2, unsigned long arg3) { /* "int" is the Intel instruction to trigger a trap. */ asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) - /* The call is in %eax (aka "a"), and can be replaced */ + /* The call in %eax (aka "a") might be overwritten */ : "=a"(call) - /* The other arguments are in %eax, %edx, %ebx & %ecx */ + /* The arguments are in %eax, %edx, %ebx & %ecx */ : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3) /* "memory" means this might write somewhere in memory. * This isn't true for all calls, but it's safe to tell diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h index 7056d8684522..e10b7affdfe5 100644 --- a/include/asm-x86/smp_32.h +++ b/include/asm-x86/smp_32.h @@ -94,9 +94,12 @@ static inline void smp_send_reschedule(int cpu) { smp_ops.smp_send_reschedule(cpu); } -extern int smp_call_function_mask(cpumask_t mask, - void (*func) (void *info), void *info, - int wait); +static inline int smp_call_function_mask(cpumask_t mask, + void (*func) (void *info), void *info, + int wait) +{ + return smp_ops.smp_call_function_mask(mask, func, info, wait); +} void native_smp_prepare_boot_cpu(void); void native_smp_prepare_cpus(unsigned int max_cpus); diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h index 8bd9d2c02a24..3c7d537dd15d 100644 --- a/include/asm-xtensa/dma-mapping.h +++ b/include/asm-xtensa/dma-mapping.h @@ -11,10 +11,10 @@ #ifndef _XTENSA_DMA_MAPPING_H #define _XTENSA_DMA_MAPPING_H -#include <asm/scatterlist.h> #include <asm/cache.h> #include <asm/io.h> #include <linux/mm.h> +#include <linux/scatterlist.h> /* * DMA-consistent mapping functions. diff --git a/include/linux/compiler.h b/include/linux/compiler.h index c811c8b979ac..c68b67b86ef1 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -101,6 +101,12 @@ extern void __chk_io_ptr(const volatile void __iomem *); #undef __must_check #define __must_check #endif +#ifndef CONFIG_ENABLE_WARN_DEPRECATED +#undef __deprecated +#undef __deprecated_for_modules +#define __deprecated +#define __deprecated_for_modules +#endif /* * Allow us to avoid 'defined but not used' warnings on functions and data, diff --git a/include/linux/completion.h b/include/linux/completion.h index 268c5a4a2bd4..33d6aaf94447 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h @@ -42,15 +42,15 @@ static inline void init_completion(struct completion *x) init_waitqueue_head(&x->wait); } -extern void FASTCALL(wait_for_completion(struct completion *)); -extern int FASTCALL(wait_for_completion_interruptible(struct completion *x)); -extern unsigned long FASTCALL(wait_for_completion_timeout(struct completion *x, - unsigned long timeout)); -extern unsigned long FASTCALL(wait_for_completion_interruptible_timeout( - struct completion *x, unsigned long timeout)); - -extern void FASTCALL(complete(struct completion *)); -extern void FASTCALL(complete_all(struct completion *)); +extern void wait_for_completion(struct completion *); +extern int wait_for_completion_interruptible(struct completion *x); +extern unsigned long wait_for_completion_timeout(struct completion *x, + unsigned long timeout); +extern unsigned long wait_for_completion_interruptible_timeout( + struct completion *x, unsigned long timeout); + +extern void complete(struct completion *); +extern void complete_all(struct completion *); #define INIT_COMPLETION(x) ((x).done = 0) diff --git a/include/linux/dccp.h b/include/linux/dccp.h index f3fc4392e93d..333c3ea82a5d 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -144,6 +144,8 @@ enum dccp_reset_codes { DCCP_RESET_CODE_TOO_BUSY, DCCP_RESET_CODE_BAD_INIT_COOKIE, DCCP_RESET_CODE_AGGRESSION_PENALTY, + + DCCP_MAX_RESET_CODES /* Leave at the end! */ }; /* DCCP options */ @@ -270,10 +272,9 @@ static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen) return memset(skb_transport_header(skb), 0, headlen); } -static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb) +static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh) { - return (struct dccp_hdr_ext *)(skb_transport_header(skb) + - sizeof(struct dccp_hdr)); + return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh)); } static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) @@ -287,13 +288,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb) return __dccp_basic_hdr_len(dh); } -static inline __u64 dccp_hdr_seq(const struct sk_buff *skb) +static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh) { - const struct dccp_hdr *dh = dccp_hdr(skb); __u64 seq_nr = ntohs(dh->dccph_seq); if (dh->dccph_x != 0) - seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low); + seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low); else seq_nr += (u32)dh->dccph_seq2 << 16; diff --git a/include/linux/lguest.h b/include/linux/lguest.h index 8beb29134626..175e63f4a8c0 100644 --- a/include/linux/lguest.h +++ b/include/linux/lguest.h @@ -12,8 +12,8 @@ #define LG_CLOCK_MAX_DELTA ULONG_MAX /*G:032 The second method of communicating with the Host is to via "struct - * lguest_data". The Guest's very first hypercall is to tell the Host where - * this is, and then the Guest and Host both publish information in it. :*/ + * lguest_data". Once the Guest's initialization hypercall tells the Host where + * this is, the Guest and Host both publish information in it. :*/ struct lguest_data { /* 512 == enabled (same as eflags in normal hardware). The Guest diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index 61e1e3e6b1cc..697104da91f1 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -1,17 +1,7 @@ -#ifndef _ASM_LGUEST_USER -#define _ASM_LGUEST_USER +#ifndef _LINUX_LGUEST_LAUNCHER +#define _LINUX_LGUEST_LAUNCHER /* Everything the "lguest" userspace program needs to know. */ #include <linux/types.h> -/* They can register up to 32 arrays of lguest_dma. */ -#define LGUEST_MAX_DMA 32 -/* At most we can dma 16 lguest_dma in one op. */ -#define LGUEST_MAX_DMA_SECTIONS 16 - -/* How many devices? Assume each one wants up to two dma arrays per device. */ -#define LGUEST_MAX_DEVICES (LGUEST_MAX_DMA/2) - -/* Where the Host expects the Guest to SEND_DMA console output to. */ -#define LGUEST_CONSOLE_DMA_KEY 0 /*D:010 * Drivers @@ -20,7 +10,11 @@ * real devices (think of the damage it could do!) we provide virtual devices. * We could emulate a PCI bus with various devices on it, but that is a fairly * complex burden for the Host and suboptimal for the Guest, so we have our own - * "lguest" bus and simple drivers. + * simple lguest bus and we use "virtio" drivers. These drivers need a set of + * routines from us which will actually do the virtual I/O, but they handle all + * the net/block/console stuff themselves. This means that if we want to add + * a new device, we simply need to write a new virtio driver and create support + * for it in the Launcher: this code won't need to change. * * Devices are described by a simplified ID, a status byte, and some "config" * bytes which describe this device's configuration. This is placed by the @@ -51,9 +45,9 @@ struct lguest_vqconfig { /* Write command first word is a request. */ enum lguest_req { - LHREQ_INITIALIZE, /* + pfnlimit, pgdir, start, pageoffset */ + LHREQ_INITIALIZE, /* + base, pfnlimit, pgdir, start */ LHREQ_GETDMA, /* No longer used */ LHREQ_IRQ, /* + irq */ LHREQ_BREAK, /* + on/off flag (on blocks until someone does off) */ }; -#endif /* _ASM_LGUEST_USER */ +#endif /* _LINUX_LGUEST_LAUNCHER */ diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 3f272396642b..8df230a279a0 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -8,6 +8,9 @@ #define MV643XX_ETH_NAME "mv643xx_eth" #define MV643XX_ETH_SHARED_REGS 0x2000 #define MV643XX_ETH_SHARED_REGS_SIZE 0x2000 +#define MV643XX_ETH_BAR_4 0x220 +#define MV643XX_ETH_SIZE_REG_4 0x224 +#define MV643XX_ETH_BASE_ADDR_ENABLE_REG 0x0290 struct mv643xx_eth_platform_data { int port_number; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c4de536cefa3..9b0c8f12373e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -390,7 +390,7 @@ static inline void napi_complete(struct napi_struct *n) static inline void napi_disable(struct napi_struct *n) { while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) - msleep_interruptible(1); + msleep(1); } /** @@ -669,6 +669,8 @@ struct net_device #define HAVE_SET_MAC_ADDR int (*set_mac_address)(struct net_device *dev, void *addr); +#define HAVE_VALIDATE_ADDR + int (*validate_addr)(struct net_device *dev); #define HAVE_PRIVATE_IOCTL int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index df7ddcee7c4b..457123171389 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -1,6 +1,7 @@ #ifndef _LINUX_SCATTERLIST_H #define _LINUX_SCATTERLIST_H +#include <asm/types.h> #include <asm/scatterlist.h> #include <linux/mm.h> #include <linux/string.h> @@ -26,18 +27,16 @@ #define SG_MAGIC 0x87654321 /** - * sg_set_page - Set sg entry to point at given page - * @sg: SG entry - * @page: The page + * sg_assign_page - Assign a given page to an SG entry + * @sg: SG entry + * @page: The page * * Description: - * Use this function to set an sg entry pointing at a page, never assign - * the page directly. We encode sg table information in the lower bits - * of the page pointer. See sg_page() for looking up the page belonging - * to an sg entry. + * Assign page to sg entry. Also see sg_set_page(), the most commonly used + * variant. * **/ -static inline void sg_set_page(struct scatterlist *sg, struct page *page) +static inline void sg_assign_page(struct scatterlist *sg, struct page *page) { unsigned long page_link = sg->page_link & 0x3; @@ -52,6 +51,28 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page) sg->page_link = page_link | (unsigned long) page; } +/** + * sg_set_page - Set sg entry to point at given page + * @sg: SG entry + * @page: The page + * @len: Length of data + * @offset: Offset into page + * + * Description: + * Use this function to set an sg entry pointing at a page, never assign + * the page directly. We encode sg table information in the lower bits + * of the page pointer. See sg_page() for looking up the page belonging + * to an sg entry. + * + **/ +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg_assign_page(sg, page); + sg->offset = offset; + sg->length = len; +} + #define sg_page(sg) ((struct page *) ((sg)->page_link & ~0x3)) /** @@ -64,9 +85,7 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page) static inline void sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen) { - sg_set_page(sg, virt_to_page(buf)); - sg->offset = offset_in_page(buf); - sg->length = buflen; + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); } /* @@ -237,7 +256,7 @@ static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) * on the sg page. * **/ -static inline unsigned long sg_phys(struct scatterlist *sg) +static inline dma_addr_t sg_phys(struct scatterlist *sg) { return page_to_phys(sg_page(sg)) + sg->offset; } diff --git a/include/linux/sched.h b/include/linux/sched.h index 13df99fb2769..3c07d595979f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -828,12 +828,17 @@ struct sched_class { struct task_struct * (*pick_next_task) (struct rq *rq); void (*put_prev_task) (struct rq *rq, struct task_struct *p); +#ifdef CONFIG_SMP unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, - struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, + 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 (*move_one_task) (struct rq *this_rq, int this_cpu, + struct rq *busiest, struct sched_domain *sd, + enum cpu_idle_type idle); +#endif + 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); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fd4e12f24270..94e49915a8c0 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -994,7 +994,7 @@ static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len) * * Return the number of bytes of free space at the head of an &sk_buff. */ -static inline int skb_headroom(const struct sk_buff *skb) +static inline unsigned int skb_headroom(const struct sk_buff *skb) { return skb->data - skb->head; } @@ -1347,7 +1347,7 @@ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev, * Returns true if modifying the header part of the cloned buffer * does not requires the data to be copied. */ -static inline int skb_clone_writable(struct sk_buff *skb, int len) +static inline int skb_clone_writable(struct sk_buff *skb, unsigned int len) { return !skb_header_cloned(skb) && skb_headroom(skb) + len <= skb->hdr_len; diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 8228b57eb18f..4427dcd1e53a 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -26,7 +26,6 @@ #include <net/inet_connection_sock.h> #include <net/inet_sock.h> -#include <net/route.h> #include <net/sock.h> #include <net/tcp_states.h> @@ -266,11 +265,6 @@ out: wake_up(&hashinfo->lhash_wait); } -static inline int inet_iif(const struct sk_buff *skb) -{ - return ((struct rtable *)skb->dst)->rt_iif; -} - extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo, const __be32 daddr, const unsigned short hnum, diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 62daf214931f..70013c5f4e59 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -24,6 +24,7 @@ #include <net/flow.h> #include <net/sock.h> #include <net/request_sock.h> +#include <net/route.h> /** struct ip_options - IP Options * @@ -190,4 +191,10 @@ static inline int inet_sk_ehashfn(const struct sock *sk) return inet_ehashfn(laddr, lport, faddr, fport); } + +static inline int inet_iif(const struct sk_buff *skb) +{ + return ((struct rtable *)skb->dst)->rt_iif; +} + #endif /* _INET_SOCK_H */ diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 8dabdd603fe1..eea2e6152389 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -127,7 +127,6 @@ extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); extern void ircomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios); -extern hashbin_t *ircomm_tty; #endif diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 93aa87d32804..5279466606d2 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -102,11 +102,9 @@ static inline void release_net(struct net *net) #ifdef CONFIG_NET_NS #define __net_init #define __net_exit -#define __net_initdata #else #define __net_init __init #define __net_exit __exit_refok -#define __net_initdata __initdata #endif struct pernet_operations { diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index a02ec9e5fea5..c9265518a378 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -316,4 +316,19 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) return rtab->data[slot]; } +#ifdef CONFIG_NET_CLS_ACT +static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) +{ + struct sk_buff *n = skb_clone(skb, gfp_mask); + + if (n) { + n->tc_verd = SET_TC_VERD(n->tc_verd, 0); + n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); + n->tc_verd = CLR_TC_MUNGED(n->tc_verd); + n->iif = skb->iif; + } + return n; +} +#endif + #endif diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h index 4945954a16af..9e8f13b7da5a 100644 --- a/include/net/sctp/auth.h +++ b/include/net/sctp/auth.h @@ -88,7 +88,6 @@ static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key) void sctp_auth_key_put(struct sctp_auth_bytes *key); struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp); -void sctp_auth_shkey_free(struct sctp_shared_key *sh_key); void sctp_auth_destroy_keys(struct list_head *keys); int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp); struct sctp_shared_key *sctp_auth_get_shkey( diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 119f5a1ed499..93eb708609e7 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -156,7 +156,6 @@ int sctp_primitive_ASCONF(struct sctp_association *, void *arg); __u32 sctp_start_cksum(__u8 *ptr, __u16 count); __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum); __u32 sctp_end_cksum(__u32 cksum); -__u32 sctp_update_copy_cksum(__u8 *, __u8 *, __u16 count, __u32 cksum); /* * sctp/input.c diff --git a/include/net/tcp.h b/include/net/tcp.h index 92049e681258..d695cea7730d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -803,7 +803,7 @@ static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) return left <= tcp_max_burst(tp); } -static inline void tcp_minshall_update(struct tcp_sock *tp, int mss, +static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss, const struct sk_buff *skb) { if (skb->len < mss) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 688f6f5d3285..58dfa82889aa 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -37,6 +37,8 @@ extern struct sock *xfrm_nl; extern u32 sysctl_xfrm_aevent_etime; extern u32 sysctl_xfrm_aevent_rseqth; +extern int sysctl_xfrm_larval_drop; +extern u32 sysctl_xfrm_acq_expires; extern struct mutex xfrm_cfg_mutex; diff --git a/init/Kconfig b/init/Kconfig index b7dffa837926..8b88d0bedcbd 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -322,7 +322,6 @@ config CPUSETS config FAIR_GROUP_SCHED bool "Fair group CPU scheduler" default y - depends on EXPERIMENTAL help This feature lets CPU scheduler recognize task groups and control CPU bandwidth allocation to such task groups. diff --git a/kernel/profile.c b/kernel/profile.c index 631b75c25d7e..5e95330e5120 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -60,6 +60,7 @@ static int __init profile_setup(char * str) int par; if (!strncmp(str, sleepstr, strlen(sleepstr))) { +#ifdef CONFIG_SCHEDSTATS prof_on = SLEEP_PROFILING; if (str[strlen(sleepstr)] == ',') str += strlen(sleepstr) + 1; @@ -68,6 +69,10 @@ static int __init profile_setup(char * str) printk(KERN_INFO "kernel sleep profiling enabled (shift: %ld)\n", prof_shift); +#else + printk(KERN_WARNING + "kernel sleep profiling requires CONFIG_SCHEDSTATS\n"); +#endif /* CONFIG_SCHEDSTATS */ } else if (!strncmp(str, schedstr, strlen(schedstr))) { prof_on = SCHED_PROFILING; if (str[strlen(schedstr)] == ',') diff --git a/kernel/sched.c b/kernel/sched.c index 2810e562a991..b4fbbc440453 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -66,6 +66,7 @@ #include <linux/pagemap.h> #include <asm/tlb.h> +#include <asm/irq_regs.h> /* * Scheduler clock - returns current time in nanosec units. @@ -837,11 +838,18 @@ struct rq_iterator { struct task_struct *(*next)(void *); }; -static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, - struct sched_domain *sd, enum cpu_idle_type idle, - int *all_pinned, unsigned long *load_moved, - int *this_best_prio, struct rq_iterator *iterator); +#ifdef CONFIG_SMP +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, + int *this_best_prio, struct rq_iterator *iterator); + +static int +iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, + struct sched_domain *sd, enum cpu_idle_type idle, + struct rq_iterator *iterator); +#endif #include "sched_stats.h" #include "sched_idletask.c" @@ -2223,17 +2231,17 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, return 1; } -static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, - struct sched_domain *sd, enum cpu_idle_type idle, - int *all_pinned, unsigned long *load_moved, - int *this_best_prio, struct rq_iterator *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, + int *this_best_prio, struct rq_iterator *iterator) { int pulled = 0, pinned = 0, skip_for_load; struct task_struct *p; long rem_load_move = max_load_move; - if (max_nr_move == 0 || max_load_move == 0) + if (max_load_move == 0) goto out; pinned = 1; @@ -2266,7 +2274,7 @@ next: * We only want to steal up to the prescribed number of tasks * and the prescribed amount of weighted load. */ - if (pulled < max_nr_move && rem_load_move > 0) { + if (rem_load_move > 0) { if (p->prio < *this_best_prio) *this_best_prio = p->prio; p = iterator->next(iterator->arg); @@ -2274,7 +2282,7 @@ next: } out: /* - * Right now, this is the only place pull_task() is called, + * Right now, this is one of only two places pull_task() is called, * so we can safely collect pull_task() stats here rather than * inside pull_task(). */ @@ -2282,8 +2290,8 @@ out: if (all_pinned) *all_pinned = pinned; - *load_moved = max_load_move - rem_load_move; - return pulled; + + return max_load_move - rem_load_move; } /* @@ -2305,7 +2313,7 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, do { total_load_moved += class->load_balance(this_rq, this_cpu, busiest, - ULONG_MAX, max_load_move - total_load_moved, + max_load_move - total_load_moved, sd, idle, all_pinned, &this_best_prio); class = class->next; } while (class && max_load_move > total_load_moved); @@ -2313,6 +2321,32 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, return total_load_moved > 0; } +static int +iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, + struct sched_domain *sd, enum cpu_idle_type idle, + struct rq_iterator *iterator) +{ + struct task_struct *p = iterator->start(iterator->arg); + int pinned = 0; + + while (p) { + if (can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) { + pull_task(busiest, p, this_rq, this_cpu); + /* + * Right now, this is only the second place pull_task() + * is called, so we can safely collect pull_task() + * stats here rather than inside pull_task(). + */ + schedstat_inc(sd, lb_gained[idle]); + + return 1; + } + p = iterator->next(iterator->arg); + } + + return 0; +} + /* * move_one_task tries to move exactly one task from busiest to this_rq, as * part of active balancing operations within "domain". @@ -2324,12 +2358,9 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, struct sched_domain *sd, enum cpu_idle_type idle) { const struct sched_class *class; - int this_best_prio = MAX_PRIO; for (class = sched_class_highest; class; class = class->next) - if (class->load_balance(this_rq, this_cpu, busiest, - 1, ULONG_MAX, sd, idle, NULL, - &this_best_prio)) + if (class->move_one_task(this_rq, this_cpu, busiest, sd, idle)) return 1; return 0; @@ -3266,18 +3297,6 @@ static inline void idle_balance(int cpu, struct rq *rq) { } -/* Avoid "used but not defined" warning on UP */ -static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, - struct sched_domain *sd, enum cpu_idle_type idle, - int *all_pinned, unsigned long *load_moved, - int *this_best_prio, struct rq_iterator *iterator) -{ - *load_moved = 0; - - return 0; -} - #endif DEFINE_PER_CPU(struct kernel_stat, kstat); @@ -3507,12 +3526,19 @@ EXPORT_SYMBOL(sub_preempt_count); */ static noinline void __schedule_bug(struct task_struct *prev) { - printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n", - prev->comm, preempt_count(), task_pid_nr(prev)); + 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()); + debug_show_held_locks(prev); if (irqs_disabled()) print_irqtrace_events(prev); - dump_stack(); + + if (regs) + show_regs(regs); + else + dump_stack(); } /* @@ -3820,7 +3846,7 @@ __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) } EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ -void fastcall complete(struct completion *x) +void complete(struct completion *x) { unsigned long flags; @@ -3832,7 +3858,7 @@ void fastcall complete(struct completion *x) } EXPORT_SYMBOL(complete); -void fastcall complete_all(struct completion *x) +void complete_all(struct completion *x) { unsigned long flags; @@ -3884,13 +3910,13 @@ wait_for_common(struct completion *x, long timeout, int state) return timeout; } -void fastcall __sched wait_for_completion(struct completion *x) +void __sched wait_for_completion(struct completion *x) { wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE); } EXPORT_SYMBOL(wait_for_completion); -unsigned long fastcall __sched +unsigned long __sched wait_for_completion_timeout(struct completion *x, unsigned long timeout) { return wait_for_common(x, timeout, TASK_UNINTERRUPTIBLE); @@ -3906,7 +3932,7 @@ int __sched wait_for_completion_interruptible(struct completion *x) } EXPORT_SYMBOL(wait_for_completion_interruptible); -unsigned long fastcall __sched +unsigned long __sched wait_for_completion_interruptible_timeout(struct completion *x, unsigned long timeout) { @@ -5461,11 +5487,12 @@ static void register_sched_domain_sysctl(void) struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); char buf[32]; + WARN_ON(sd_ctl_dir[0].child); + sd_ctl_dir[0].child = entry; + if (entry == NULL) return; - sd_ctl_dir[0].child = entry; - for_each_online_cpu(i) { snprintf(buf, 32, "cpu%d", i); entry->procname = kstrdup(buf, GFP_KERNEL); @@ -5473,14 +5500,19 @@ static void register_sched_domain_sysctl(void) entry->child = sd_alloc_ctl_cpu_table(i); entry++; } + + WARN_ON(sd_sysctl_header); sd_sysctl_header = register_sysctl_table(sd_ctl_root); } +/* may be called multiple times per register */ static void unregister_sched_domain_sysctl(void) { - unregister_sysctl_table(sd_sysctl_header); + if (sd_sysctl_header) + unregister_sysctl_table(sd_sysctl_header); sd_sysctl_header = NULL; - sd_free_ctl_entry(&sd_ctl_dir[0].child); + if (sd_ctl_dir[0].child) + sd_free_ctl_entry(&sd_ctl_dir[0].child); } #else static void register_sched_domain_sysctl(void) @@ -5611,101 +5643,101 @@ int nr_cpu_ids __read_mostly = NR_CPUS; EXPORT_SYMBOL(nr_cpu_ids); #ifdef CONFIG_SCHED_DEBUG -static void sched_domain_debug(struct sched_domain *sd, int cpu) + +static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level) { - int level = 0; + struct sched_group *group = sd->groups; + cpumask_t groupmask; + char str[NR_CPUS]; - if (!sd) { - printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu); - return; + cpumask_scnprintf(str, NR_CPUS, sd->span); + cpus_clear(groupmask); + + printk(KERN_DEBUG "%*s domain %d: ", level, "", level); + + if (!(sd->flags & SD_LOAD_BALANCE)) { + printk("does not load-balance\n"); + if (sd->parent) + printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain" + " has parent"); + return -1; } - printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu); + printk(KERN_CONT "span %s\n", str); + + if (!cpu_isset(cpu, sd->span)) { + printk(KERN_ERR "ERROR: domain->span does not contain " + "CPU%d\n", cpu); + } + if (!cpu_isset(cpu, group->cpumask)) { + printk(KERN_ERR "ERROR: domain->groups does not contain" + " CPU%d\n", cpu); + } + printk(KERN_DEBUG "%*s groups:", level + 1, ""); do { - int i; - char str[NR_CPUS]; - struct sched_group *group = sd->groups; - cpumask_t groupmask; - - cpumask_scnprintf(str, NR_CPUS, sd->span); - cpus_clear(groupmask); - - printk(KERN_DEBUG); - for (i = 0; i < level + 1; i++) - printk(" "); - printk("domain %d: ", level); - - if (!(sd->flags & SD_LOAD_BALANCE)) { - printk("does not load-balance\n"); - if (sd->parent) - printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain" - " has parent"); + if (!group) { + printk("\n"); + printk(KERN_ERR "ERROR: group is NULL\n"); break; } - printk("span %s\n", str); + if (!group->__cpu_power) { + printk(KERN_CONT "\n"); + printk(KERN_ERR "ERROR: domain->cpu_power not " + "set\n"); + break; + } - if (!cpu_isset(cpu, sd->span)) - printk(KERN_ERR "ERROR: domain->span does not contain " - "CPU%d\n", cpu); - if (!cpu_isset(cpu, group->cpumask)) - printk(KERN_ERR "ERROR: domain->groups does not contain" - " CPU%d\n", cpu); + if (!cpus_weight(group->cpumask)) { + printk(KERN_CONT "\n"); + printk(KERN_ERR "ERROR: empty group\n"); + break; + } - printk(KERN_DEBUG); - for (i = 0; i < level + 2; i++) - printk(" "); - printk("groups:"); - do { - if (!group) { - printk("\n"); - printk(KERN_ERR "ERROR: group is NULL\n"); - break; - } + if (cpus_intersects(groupmask, group->cpumask)) { + printk(KERN_CONT "\n"); + printk(KERN_ERR "ERROR: repeated CPUs\n"); + break; + } - if (!group->__cpu_power) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: domain->cpu_power not " - "set\n"); - break; - } + cpus_or(groupmask, groupmask, group->cpumask); - if (!cpus_weight(group->cpumask)) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: empty group\n"); - break; - } + cpumask_scnprintf(str, NR_CPUS, group->cpumask); + printk(KERN_CONT " %s", str); - if (cpus_intersects(groupmask, group->cpumask)) { - printk(KERN_CONT "\n"); - printk(KERN_ERR "ERROR: repeated CPUs\n"); - break; - } + group = group->next; + } while (group != sd->groups); + printk(KERN_CONT "\n"); - cpus_or(groupmask, groupmask, group->cpumask); + if (!cpus_equal(sd->span, groupmask)) + printk(KERN_ERR "ERROR: groups don't span domain->span\n"); - cpumask_scnprintf(str, NR_CPUS, group->cpumask); - printk(KERN_CONT " %s", str); + if (sd->parent && !cpus_subset(groupmask, sd->parent->span)) + printk(KERN_ERR "ERROR: parent span is not a superset " + "of domain->span\n"); + return 0; +} - group = group->next; - } while (group != sd->groups); - printk(KERN_CONT "\n"); +static void sched_domain_debug(struct sched_domain *sd, int cpu) +{ + int level = 0; - if (!cpus_equal(sd->span, groupmask)) - printk(KERN_ERR "ERROR: groups don't span " - "domain->span\n"); + if (!sd) { + printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu); + return; + } + + printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu); + for (;;) { + if (sched_domain_debug_one(sd, cpu, level)) + break; level++; sd = sd->parent; if (!sd) - continue; - - if (!cpus_subset(groupmask, sd->span)) - printk(KERN_ERR "ERROR: parent span is not a superset " - "of domain->span\n"); - - } while (sd); + break; + } } #else # define sched_domain_debug(sd, cpu) do { } while (0) @@ -6424,13 +6456,17 @@ static cpumask_t fallback_doms; */ static int arch_init_sched_domains(const cpumask_t *cpu_map) { + int err; + ndoms_cur = 1; doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL); if (!doms_cur) doms_cur = &fallback_doms; cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map); + err = build_sched_domains(doms_cur); register_sched_domain_sysctl(); - return build_sched_domains(doms_cur); + + return err; } static void arch_destroy_sched_domains(const cpumask_t *cpu_map) @@ -6479,6 +6515,9 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new) { int i, j; + /* always unregister in case we don't destroy any domains */ + unregister_sched_domain_sysctl(); + if (doms_new == NULL) { ndoms_new = 1; doms_new = &fallback_doms; @@ -6514,6 +6553,8 @@ match2: kfree(doms_cur); doms_cur = doms_new; ndoms_cur = ndoms_new; + + register_sched_domain_sysctl(); } #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) @@ -7101,25 +7142,25 @@ unsigned long sched_group_shares(struct task_group *tg) #ifdef CONFIG_FAIR_CGROUP_SCHED /* return corresponding task_group object of a cgroup */ -static inline struct task_group *cgroup_tg(struct cgroup *cont) +static inline struct task_group *cgroup_tg(struct cgroup *cgrp) { - return container_of(cgroup_subsys_state(cont, cpu_cgroup_subsys_id), - struct task_group, css); + return container_of(cgroup_subsys_state(cgrp, cpu_cgroup_subsys_id), + struct task_group, css); } static struct cgroup_subsys_state * -cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) +cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp) { struct task_group *tg; - if (!cont->parent) { + if (!cgrp->parent) { /* This is early initialization for the top cgroup */ - init_task_group.css.cgroup = cont; + init_task_group.css.cgroup = cgrp; return &init_task_group.css; } /* we support only 1-level deep hierarchical scheduler atm */ - if (cont->parent->parent) + if (cgrp->parent->parent) return ERR_PTR(-EINVAL); tg = sched_create_group(); @@ -7127,21 +7168,21 @@ cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) return ERR_PTR(-ENOMEM); /* Bind the cgroup to task_group object we just created */ - tg->css.cgroup = cont; + tg->css.cgroup = cgrp; return &tg->css; } static void cpu_cgroup_destroy(struct cgroup_subsys *ss, - struct cgroup *cont) + struct cgroup *cgrp) { - struct task_group *tg = cgroup_tg(cont); + struct task_group *tg = cgroup_tg(cgrp); sched_destroy_group(tg); } static int cpu_cgroup_can_attach(struct cgroup_subsys *ss, - struct cgroup *cont, struct task_struct *tsk) + struct cgroup *cgrp, struct task_struct *tsk) { /* We don't support RT-tasks being in separate groups */ if (tsk->sched_class != &fair_sched_class) @@ -7151,38 +7192,21 @@ static int cpu_cgroup_can_attach(struct cgroup_subsys *ss, } static void -cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cont, +cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, struct cgroup *old_cont, struct task_struct *tsk) { sched_move_task(tsk); } -static ssize_t cpu_shares_write(struct cgroup *cont, struct cftype *cftype, - struct file *file, const char __user *userbuf, - size_t nbytes, loff_t *ppos) +static int cpu_shares_write_uint(struct cgroup *cgrp, struct cftype *cftype, + u64 shareval) { - unsigned long shareval; - struct task_group *tg = cgroup_tg(cont); - char buffer[2*sizeof(unsigned long) + 1]; - int rc; - - if (nbytes > 2*sizeof(unsigned long)) /* safety check */ - return -E2BIG; - - if (copy_from_user(buffer, userbuf, nbytes)) - return -EFAULT; - - buffer[nbytes] = 0; /* nul-terminate */ - shareval = simple_strtoul(buffer, NULL, 10); - - rc = sched_group_set_shares(tg, shareval); - - return (rc < 0 ? rc : nbytes); + return sched_group_set_shares(cgroup_tg(cgrp), shareval); } -static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft) +static u64 cpu_shares_read_uint(struct cgroup *cgrp, struct cftype *cft) { - struct task_group *tg = cgroup_tg(cont); + struct task_group *tg = cgroup_tg(cgrp); return (u64) tg->shares; } @@ -7190,7 +7214,7 @@ static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft) static struct cftype cpu_shares = { .name = "shares", .read_uint = cpu_shares_read_uint, - .write = cpu_shares_write, + .write_uint = cpu_shares_write_uint, }; static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont) diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 166ed6db600b..9971831b560e 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -876,6 +876,7 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev) } } +#ifdef CONFIG_SMP /************************************************** * Fair scheduling class load-balancing methods: */ @@ -936,12 +937,11 @@ static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) static unsigned long load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, + unsigned long max_load_move, struct sched_domain *sd, enum cpu_idle_type idle, int *all_pinned, int *this_best_prio) { struct cfs_rq *busy_cfs_rq; - unsigned long load_moved, total_nr_moved = 0, nr_moved; long rem_load_move = max_load_move; struct rq_iterator cfs_rq_iterator; @@ -969,25 +969,48 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, #else # define maxload rem_load_move #endif - /* pass busy_cfs_rq argument into + /* + * pass busy_cfs_rq argument into * load_balance_[start|next]_fair iterators */ cfs_rq_iterator.arg = busy_cfs_rq; - nr_moved = balance_tasks(this_rq, this_cpu, busiest, - max_nr_move, maxload, sd, idle, all_pinned, - &load_moved, this_best_prio, &cfs_rq_iterator); - - total_nr_moved += nr_moved; - max_nr_move -= nr_moved; - rem_load_move -= load_moved; + rem_load_move -= balance_tasks(this_rq, this_cpu, busiest, + maxload, sd, idle, all_pinned, + this_best_prio, + &cfs_rq_iterator); - if (max_nr_move <= 0 || rem_load_move <= 0) + if (rem_load_move <= 0) break; } return max_load_move - rem_load_move; } +static int +move_one_task_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, + struct sched_domain *sd, enum cpu_idle_type idle) +{ + struct cfs_rq *busy_cfs_rq; + struct rq_iterator cfs_rq_iterator; + + cfs_rq_iterator.start = load_balance_start_fair; + cfs_rq_iterator.next = load_balance_next_fair; + + for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { + /* + * pass busy_cfs_rq argument into + * load_balance_[start|next]_fair iterators + */ + cfs_rq_iterator.arg = busy_cfs_rq; + if (iter_move_one_task(this_rq, this_cpu, busiest, sd, idle, + &cfs_rq_iterator)) + return 1; + } + + return 0; +} +#endif + /* * scheduler tick hitting a task of our scheduling class: */ @@ -1063,7 +1086,10 @@ static const struct sched_class fair_sched_class = { .pick_next_task = pick_next_task_fair, .put_prev_task = put_prev_task_fair, +#ifdef CONFIG_SMP .load_balance = load_balance_fair, + .move_one_task = move_one_task_fair, +#endif .set_curr_task = set_curr_task_fair, .task_tick = task_tick_fair, diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index 6e2ead41516e..bf9c25c15b8b 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -37,15 +37,24 @@ static void put_prev_task_idle(struct rq *rq, struct task_struct *prev) { } +#ifdef CONFIG_SMP static unsigned long load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, - struct sched_domain *sd, enum cpu_idle_type idle, - int *all_pinned, int *this_best_prio) + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, int *this_best_prio) { return 0; } +static int +move_one_task_idle(struct rq *this_rq, int this_cpu, struct rq *busiest, + struct sched_domain *sd, enum cpu_idle_type idle) +{ + return 0; +} +#endif + static void task_tick_idle(struct rq *rq, struct task_struct *curr) { } @@ -69,7 +78,10 @@ const struct sched_class idle_sched_class = { .pick_next_task = pick_next_task_idle, .put_prev_task = put_prev_task_idle, +#ifdef CONFIG_SMP .load_balance = load_balance_idle, + .move_one_task = move_one_task_idle, +#endif .set_curr_task = set_curr_task_idle, .task_tick = task_tick_idle, diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index d0097a0634e5..8abd752a0ebd 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -98,6 +98,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p) p->se.exec_start = 0; } +#ifdef CONFIG_SMP /* * Load-balancing iterator. Note: while the runqueue stays locked * during the whole iteration, the current task might be @@ -172,13 +173,11 @@ static struct task_struct *load_balance_next_rt(void *arg) static unsigned long load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, - unsigned long max_nr_move, unsigned long max_load_move, - struct sched_domain *sd, enum cpu_idle_type idle, - int *all_pinned, int *this_best_prio) + unsigned long max_load_move, + struct sched_domain *sd, enum cpu_idle_type idle, + int *all_pinned, int *this_best_prio) { - int nr_moved; struct rq_iterator rt_rq_iterator; - unsigned long load_moved; rt_rq_iterator.start = load_balance_start_rt; rt_rq_iterator.next = load_balance_next_rt; @@ -187,12 +186,24 @@ load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, */ rt_rq_iterator.arg = busiest; - nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move, - max_load_move, sd, idle, all_pinned, &load_moved, - this_best_prio, &rt_rq_iterator); + return balance_tasks(this_rq, this_cpu, busiest, max_load_move, sd, + idle, all_pinned, this_best_prio, &rt_rq_iterator); +} + +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 load_moved; + return iter_move_one_task(this_rq, this_cpu, busiest, sd, idle, + &rt_rq_iterator); } +#endif static void task_tick_rt(struct rq *rq, struct task_struct *p) { @@ -236,7 +247,10 @@ const struct sched_class rt_sched_class = { .pick_next_task = pick_next_task_rt, .put_prev_task = put_prev_task_rt, +#ifdef CONFIG_SMP .load_balance = load_balance_rt, + .move_one_task = move_one_task_rt, +#endif .set_curr_task = set_curr_task_rt, .task_tick = task_tick_rt, diff --git a/kernel/user.c b/kernel/user.c index e91331c457e2..0f3aa0234107 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -129,7 +129,7 @@ static inline void uids_mutex_unlock(void) } /* return cpu shares held by the user */ -ssize_t cpu_shares_show(struct kset *kset, char *buffer) +static ssize_t cpu_shares_show(struct kset *kset, char *buffer) { struct user_struct *up = container_of(kset, struct user_struct, kset); @@ -137,7 +137,8 @@ ssize_t cpu_shares_show(struct kset *kset, char *buffer) } /* modify cpu shares held by the user */ -ssize_t cpu_shares_store(struct kset *kset, const char *buffer, size_t size) +static ssize_t cpu_shares_store(struct kset *kset, const char *buffer, + size_t size) { struct user_struct *up = container_of(kset, struct user_struct, kset); unsigned long shares; diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1faa5087dc86..1e5f207b9074 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -9,6 +9,14 @@ config PRINTK_TIME operations. This is useful for identifying long delays in kernel startup. +config ENABLE_WARN_DEPRECATED + bool "Enable __deprecated logic" + default y + help + Enable the __deprecated logic in the kernel build. + Disable this to suppress the "warning: 'foo' is deprecated + (declared at kernel/power/somefile.c:1234)" messages. + config ENABLE_MUST_CHECK bool "Enable __must_check logic" default y diff --git a/net/9p/mux.c b/net/9p/mux.c index f14014793bed..c9f0805048e4 100644 --- a/net/9p/mux.c +++ b/net/9p/mux.c @@ -222,8 +222,10 @@ static int p9_mux_poll_start(struct p9_conn *m) } if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) { - if (vptlast == NULL) + if (vptlast == NULL) { + mutex_unlock(&p9_mux_task_lock); return -ENOMEM; + } P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); list_add(&m->mux_list, &vptlast->mux_list); diff --git a/net/core/dev.c b/net/core/dev.c index 872658927e47..853c8b575f1d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -120,6 +120,8 @@ #include <linux/ctype.h> #include <linux/if_arp.h> +#include "net-sysfs.h" + /* * The list of packet types we will receive (as opposed to discard) * and the routines to invoke. @@ -249,10 +251,6 @@ static RAW_NOTIFIER_HEAD(netdev_chain); DEFINE_PER_CPU(struct softnet_data, softnet_data); -extern int netdev_kobject_init(void); -extern int netdev_register_kobject(struct net_device *); -extern void netdev_unregister_kobject(struct net_device *); - #ifdef CONFIG_DEBUG_LOCK_ALLOC /* * register_netdevice() inits dev->_xmit_lock and sets lockdep class @@ -885,6 +883,9 @@ int dev_change_name(struct net_device *dev, char *newname) if (!dev_valid_name(newname)) return -EINVAL; + if (strncmp(newname, dev->name, IFNAMSIZ) == 0) + return 0; + memcpy(oldname, dev->name, IFNAMSIZ); if (strchr(newname, '%')) { @@ -1007,17 +1008,20 @@ int dev_open(struct net_device *dev) * Call device private open method */ set_bit(__LINK_STATE_START, &dev->state); - if (dev->open) { + + if (dev->validate_addr) + ret = dev->validate_addr(dev); + + if (!ret && dev->open) ret = dev->open(dev); - if (ret) - clear_bit(__LINK_STATE_START, &dev->state); - } /* * If it went open OK then: */ - if (!ret) { + if (ret) + clear_bit(__LINK_STATE_START, &dev->state); + else { /* * Set the flags. */ @@ -1038,6 +1042,7 @@ int dev_open(struct net_device *dev) */ call_netdevice_notifiers(NETDEV_UP, dev); } + return ret; } @@ -2663,7 +2668,7 @@ static void __net_exit dev_proc_net_exit(struct net *net) proc_net_remove(net, "dev"); } -static struct pernet_operations __net_initdata dev_proc_ops = { +static struct pernet_operations dev_proc_ops = { .init = dev_proc_net_init, .exit = dev_proc_net_exit, }; @@ -4323,7 +4328,7 @@ static void __net_exit netdev_exit(struct net *net) kfree(net->dev_index_head); } -static struct pernet_operations __net_initdata netdev_net_ops = { +static struct pernet_operations netdev_net_ops = { .init = netdev_init, .exit = netdev_exit, }; @@ -4354,7 +4359,7 @@ static void __net_exit default_device_exit(struct net *net) rtnl_unlock(); } -static struct pernet_operations __net_initdata default_device_ops = { +static struct pernet_operations default_device_ops = { .exit = default_device_exit, }; diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 15241cf48af8..ae354057d84c 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -285,7 +285,7 @@ static void __net_exit dev_mc_net_exit(struct net *net) proc_net_remove(net, "dev_mcast"); } -static struct pernet_operations __net_initdata dev_mc_net_ops = { +static struct pernet_operations dev_mc_net_ops = { .init = dev_mc_net_init, .exit = dev_mc_net_exit, }; diff --git a/net/core/flow.c b/net/core/flow.c index 0ab5234b17d8..3ed2b4b1d6d4 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -142,8 +142,6 @@ typedef u64 flow_compare_t; typedef u32 flow_compare_t; #endif -extern void flowi_is_missized(void); - /* I hear what you're saying, use memcmp. But memcmp cannot make * important assumptions that we can here, such as alignment and * constant size. @@ -153,8 +151,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2) flow_compare_t *k1, *k1_lim, *k2; const int n_elem = sizeof(struct flowi) / sizeof(flow_compare_t); - if (sizeof(struct flowi) % sizeof(flow_compare_t)) - flowi_is_missized(); + BUILD_BUG_ON(sizeof(struct flowi) % sizeof(flow_compare_t)); k1 = (flow_compare_t *) key1; k1_lim = k1 + n_elem; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 6628e457ddc0..61ead1d11132 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -18,6 +18,8 @@ #include <linux/wireless.h> #include <net/iw_handler.h> +#include "net-sysfs.h" + #ifdef CONFIG_SYSFS static const char fmt_hex[] = "%#x\n"; static const char fmt_long_hex[] = "%#lx\n"; diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h new file mode 100644 index 000000000000..f5f108db3924 --- /dev/null +++ b/net/core/net-sysfs.h @@ -0,0 +1,8 @@ +#ifndef __NET_SYSFS_H__ +#define __NET_SYSFS_H__ + +int netdev_kobject_init(void); +int netdev_register_kobject(struct net_device *); +void netdev_unregister_kobject(struct net_device *); + +#endif diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4a2640d38261..e1ba26fb4bf2 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -742,7 +742,7 @@ static struct net *get_net_ns_by_pid(pid_t pid) /* Lookup the network namespace */ net = ERR_PTR(-ESRCH); rcu_read_lock(); - tsk = find_task_by_pid(pid); + tsk = find_task_by_vpid(pid); if (tsk) { struct nsproxy *nsproxy; nsproxy = task_nsproxy(tsk); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4e2c84fcf276..573e17240197 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -415,13 +415,6 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; n->nohdr = 0; n->destructor = NULL; -#ifdef CONFIG_NET_CLS_ACT - /* FIXME What is this and why don't we do it in copy_skb_header? */ - n->tc_verd = SET_TC_VERD(n->tc_verd,0); - n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); - n->tc_verd = CLR_TC_MUNGED(n->tc_verd); - C(iif); -#endif C(truesize); atomic_set(&n->users, 1); C(head); @@ -2045,9 +2038,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) if (copy > 0) { if (copy > len) copy = len; - sg_set_page(&sg[elt], virt_to_page(skb->data + offset)); - sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; - sg[elt].length = copy; + sg_set_buf(sg, skb->data + offset, copy); elt++; if ((len -= copy) == 0) return elt; @@ -2065,9 +2056,8 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) if (copy > len) copy = len; - sg_set_page(&sg[elt], frag->page); - sg[elt].offset = frag->page_offset+offset-start; - sg[elt].length = copy; + sg_set_page(&sg[elt], frag->page, copy, + frag->page_offset+offset-start); elt++; if (!(len -= copy)) return elt; diff --git a/net/core/sock.c b/net/core/sock.c index febbcbcf8022..bba9949681ff 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1649,7 +1649,6 @@ void sock_enable_timestamp(struct sock *sk) net_enable_timestamp(); } } -EXPORT_SYMBOL(sock_enable_timestamp); /* * Get a socket option on an socket. diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 6d5ea9762040..113cc728dc31 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -9,25 +9,12 @@ #include <linux/sysctl.h> #include <linux/module.h> #include <linux/socket.h> +#include <linux/netdevice.h> #include <net/sock.h> +#include <net/xfrm.h> #ifdef CONFIG_SYSCTL -extern int netdev_max_backlog; -extern int weight_p; - -extern __u32 sysctl_wmem_max; -extern __u32 sysctl_rmem_max; - -extern int sysctl_core_destroy_delay; - -#ifdef CONFIG_XFRM -extern u32 sysctl_xfrm_aevent_etime; -extern u32 sysctl_xfrm_aevent_rseqth; -extern int sysctl_xfrm_larval_drop; -extern u32 sysctl_xfrm_acq_expires; -#endif - ctl_table core_table[] = { #ifdef CONFIG_NET { diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 426008e3b7e3..d694656b8800 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -750,20 +750,16 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) */ hctx->ccid2hctx_ssthresh = ~0; hctx->ccid2hctx_numdupack = 3; - hctx->ccid2hctx_seqbufc = 0; /* XXX init ~ to window size... */ if (ccid2_hc_tx_alloc_seq(hctx)) return -ENOMEM; - hctx->ccid2hctx_sent = 0; hctx->ccid2hctx_rto = 3 * HZ; ccid2_change_srtt(hctx, -1); hctx->ccid2hctx_rttvar = -1; - hctx->ccid2hctx_lastrtt = 0; hctx->ccid2hctx_rpdupack = -1; hctx->ccid2hctx_last_cong = jiffies; - hctx->ccid2hctx_high_ack = 0; hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire; hctx->ccid2hctx_rtotimer.data = (unsigned long)sk; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 25772c326172..19b33586333d 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -40,6 +40,8 @@ #include "lib/tfrc.h" #include "ccid3.h" +#include <asm/unaligned.h> + #ifdef CONFIG_IP_DCCP_CCID3_DEBUG static int ccid3_debug; #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) @@ -544,6 +546,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, const struct dccp_sock *dp = dccp_sk(sk); struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); struct ccid3_options_received *opt_recv; + __be32 opt_val; opt_recv = &hctx->ccid3hctx_options_received; @@ -563,8 +566,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, dccp_role(sk), sk, len); rc = -EINVAL; } else { - opt_recv->ccid3or_loss_event_rate = - ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->ccid3or_loss_event_rate = ntohl(opt_val); ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", dccp_role(sk), sk, opt_recv->ccid3or_loss_event_rate); @@ -585,8 +588,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, dccp_role(sk), sk, len); rc = -EINVAL; } else { - opt_recv->ccid3or_receive_rate = - ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->ccid3or_receive_rate = ntohl(opt_val); ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", dccp_role(sk), sk, opt_recv->ccid3or_receive_rate); @@ -601,8 +604,6 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) { struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); - hctx->ccid3hctx_s = 0; - hctx->ccid3hctx_rtt = 0; hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; INIT_LIST_HEAD(&hctx->ccid3hctx_hist); @@ -963,8 +964,6 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real(); - hcrx->ccid3hcrx_s = 0; - hcrx->ccid3hcrx_rtt = 0; return 0; } diff --git a/net/dccp/input.c b/net/dccp/input.c index 3560a2a875a0..1ce101062824 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -58,6 +58,42 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) dccp_send_close(sk, 0); } +static u8 dccp_reset_code_convert(const u8 code) +{ + const u8 error_code[] = { + [DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */ + [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */ + [DCCP_RESET_CODE_ABORTED] = ECONNRESET, + + [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED, + [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED, + [DCCP_RESET_CODE_TOO_BUSY] = EUSERS, + [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT, + + [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG, + [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR, + [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC, + [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ, + [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP, + }; + + return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code]; +} + +static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) +{ + u8 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code); + + sk->sk_err = err; + + /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */ + dccp_fin(sk, skb); + + if (err && !sock_flag(sk, SOCK_DEAD)) + sk_wake_async(sk, 0, POLL_ERR); + dccp_time_wait(sk, DCCP_TIME_WAIT, 0); +} + static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); @@ -191,9 +227,8 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, * S.state := TIMEWAIT * Set TIMEWAIT timer * Drop packet and return - */ - dccp_fin(sk, skb); - dccp_time_wait(sk, DCCP_TIME_WAIT, 0); + */ + dccp_rcv_reset(sk, skb); return 0; case DCCP_PKT_CLOSEREQ: dccp_rcv_closereq(sk, skb); @@ -521,12 +556,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * Drop packet and return */ if (dh->dccph_type == DCCP_PKT_RESET) { - /* - * Queue the equivalent of TCP fin so that dccp_recvmsg - * exits the loop - */ - dccp_fin(sk, skb); - dccp_time_wait(sk, DCCP_TIME_WAIT, 0); + dccp_rcv_reset(sk, skb); return 0; /* * Step 7: Check for unexpected packet types diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 222549ab274a..01a6a808bdb7 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -241,8 +241,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) goto out; dp = dccp_sk(sk); - seq = dccp_hdr_seq(skb); - if (sk->sk_state != DCCP_LISTEN && + seq = dccp_hdr_seq(dh); + if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) && !between48(seq, dp->dccps_swl, dp->dccps_swh)) { NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); goto out; @@ -795,7 +795,7 @@ static int dccp_v4_rcv(struct sk_buff *skb) dh = dccp_hdr(skb); - DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); + DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; dccp_pr_debug("%8.8s " diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index bbadd6681b83..62428ff137dd 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -173,7 +173,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, icmpv6_err_convert(type, code, &err); - seq = DCCP_SKB_CB(skb)->dccpd_seq; + seq = dccp_hdr_seq(dh); /* Might be for an request_sock */ switch (sk->sk_state) { struct request_sock *req, **prev; @@ -787,7 +787,7 @@ static int dccp_v6_rcv(struct sk_buff *skb) dh = dccp_hdr(skb); - DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); + DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; if (dccp_packet_without_ack(skb)) diff --git a/net/dccp/options.c b/net/dccp/options.c index d361b5533309..d286cffe2c49 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -14,6 +14,7 @@ #include <linux/dccp.h> #include <linux/module.h> #include <linux/types.h> +#include <asm/unaligned.h> #include <linux/kernel.h> #include <linux/skbuff.h> @@ -59,6 +60,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) unsigned char opt, len; unsigned char *value; u32 elapsed_time; + __be32 opt_val; int rc; int mandatory = 0; @@ -145,7 +147,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) if (len != 4) goto out_invalid_option; - opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->dccpor_timestamp = ntohl(opt_val); dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; dp->dccps_timestamp_time = ktime_get_real(); @@ -159,7 +162,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) if (len != 4 && len != 6 && len != 8) goto out_invalid_option; - opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->dccpor_timestamp_echo = ntohl(opt_val); dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, " "ackno=%llu", dccp_role(sk), @@ -168,16 +172,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) (unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq); + value += 4; - if (len == 4) { + if (len == 4) { /* no elapsed time included */ dccp_pr_debug_cat("\n"); break; } - if (len == 6) - elapsed_time = ntohs(*(__be16 *)(value + 4)); - else - elapsed_time = ntohl(*(__be32 *)(value + 4)); + if (len == 6) { /* 2-byte elapsed time */ + __be16 opt_val2 = get_unaligned((__be16 *)value); + elapsed_time = ntohs(opt_val2); + } else { /* 4-byte elapsed time */ + opt_val = get_unaligned((__be32 *)value); + elapsed_time = ntohl(opt_val); + } dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time); @@ -192,10 +200,13 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) if (pkt_type == DCCP_PKT_DATA) continue; - if (len == 2) - elapsed_time = ntohs(*(__be16 *)value); - else - elapsed_time = ntohl(*(__be32 *)value); + if (len == 2) { + __be16 opt_val2 = get_unaligned((__be16 *)value); + elapsed_time = ntohs(opt_val2); + } else { + opt_val = get_unaligned((__be32 *)value); + elapsed_time = ntohl(opt_val); + } if (elapsed_time > opt_recv->dccpor_elapsed_time) opt_recv->dccpor_elapsed_time = elapsed_time; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index cc9bf1cb2646..d84973928033 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -26,6 +26,7 @@ #include <net/sock.h> #include <net/xfrm.h> +#include <asm/ioctls.h> #include <asm/semaphore.h> #include <linux/spinlock.h> #include <linux/timer.h> @@ -378,8 +379,36 @@ EXPORT_SYMBOL_GPL(dccp_poll); int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) { - dccp_pr_debug("entry\n"); - return -ENOIOCTLCMD; + int rc = -ENOTCONN; + + lock_sock(sk); + + if (sk->sk_state == DCCP_LISTEN) + goto out; + + switch (cmd) { + case SIOCINQ: { + struct sk_buff *skb; + unsigned long amount = 0; + + skb = skb_peek(&sk->sk_receive_queue); + if (skb != NULL) { + /* + * We will only return the amount of this packet since + * that is all that will be read. + */ + amount = skb->len; + } + rc = put_user(amount, (int __user *)arg); + } + break; + default: + rc = -ENOIOCTLCMD; + break; + } +out: + release_sock(sk); + return rc; } EXPORT_SYMBOL_GPL(dccp_ioctl); diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index ed8a3d49487d..6b2e454ae313 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -298,6 +298,14 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu) return 0; } +static int eth_validate_addr(struct net_device *dev) +{ + if (!is_valid_ether_addr(dev->dev_addr)) + return -EINVAL; + + return 0; +} + const struct header_ops eth_header_ops ____cacheline_aligned = { .create = eth_header, .parse = eth_header_parse, @@ -317,6 +325,7 @@ void ether_setup(struct net_device *dev) dev->change_mtu = eth_change_mtu; dev->set_mac_address = eth_mac_addr; + dev->validate_addr = eth_validate_addr; dev->type = ARPHRD_ETHER; dev->hard_header_len = ETH_HLEN; diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 811777682e2b..4cce3534e408 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -25,7 +25,7 @@ #include <net/ieee80211.h> #include <linux/crypto.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include <linux/crc32.h> MODULE_AUTHOR("Jouni Malinen"); @@ -537,13 +537,8 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr, return -1; } sg_init_table(sg, 2); - sg_set_page(&sg[0], virt_to_page(hdr)); - sg[0].offset = offset_in_page(hdr); - sg[0].length = 16; - - sg_set_page(&sg[1], virt_to_page(data)); - sg[1].offset = offset_in_page(data); - sg[1].length = data_len; + sg_set_buf(&sg[0], hdr, 16); + sg_set_buf(&sg[1], data, data_len); if (crypto_hash_setkey(tfm_michael, key, 8)) return -1; diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c index 9693429489ed..866fc04c44f9 100644 --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c @@ -22,7 +22,7 @@ #include <net/ieee80211.h> #include <linux/crypto.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include <linux/crc32.h> MODULE_AUTHOR("Jouni Malinen"); diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 805a78e6ed55..f18e88bc86ec 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -504,22 +504,16 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) INIT_RCU_HEAD(&doi_def->rcu); INIT_LIST_HEAD(&doi_def->dom_list); - rcu_read_lock(); - if (cipso_v4_doi_search(doi_def->doi) != NULL) - goto doi_add_failure_rlock; spin_lock(&cipso_v4_doi_list_lock); if (cipso_v4_doi_search(doi_def->doi) != NULL) - goto doi_add_failure_slock; + goto doi_add_failure; list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); return 0; -doi_add_failure_slock: +doi_add_failure: spin_unlock(&cipso_v4_doi_list_lock); -doi_add_failure_rlock: - rcu_read_unlock(); return -EEXIST; } @@ -543,29 +537,23 @@ int cipso_v4_doi_remove(u32 doi, struct cipso_v4_doi *doi_def; struct cipso_v4_domhsh_entry *dom_iter; - rcu_read_lock(); - if (cipso_v4_doi_search(doi) != NULL) { - spin_lock(&cipso_v4_doi_list_lock); - doi_def = cipso_v4_doi_search(doi); - if (doi_def == NULL) { - spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); - return -ENOENT; - } + spin_lock(&cipso_v4_doi_list_lock); + doi_def = cipso_v4_doi_search(doi); + if (doi_def != NULL) { doi_def->valid = 0; list_del_rcu(&doi_def->list); spin_unlock(&cipso_v4_doi_list_lock); + rcu_read_lock(); list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) if (dom_iter->valid) netlbl_domhsh_remove(dom_iter->domain, audit_info); - cipso_v4_cache_invalidate(); rcu_read_unlock(); - + cipso_v4_cache_invalidate(); call_rcu(&doi_def->rcu, callback); return 0; } - rcu_read_unlock(); + spin_unlock(&cipso_v4_doi_list_lock); return -ENOENT; } @@ -653,22 +641,19 @@ int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain) new_dom->valid = 1; INIT_RCU_HEAD(&new_dom->rcu); - rcu_read_lock(); spin_lock(&cipso_v4_doi_list_lock); - list_for_each_entry_rcu(iter, &doi_def->dom_list, list) + list_for_each_entry(iter, &doi_def->dom_list, list) if (iter->valid && ((domain != NULL && iter->domain != NULL && strcmp(iter->domain, domain) == 0) || (domain == NULL && iter->domain == NULL))) { spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); kfree(new_dom->domain); kfree(new_dom); return -EEXIST; } list_add_tail_rcu(&new_dom->list, &doi_def->dom_list); spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); return 0; } @@ -689,9 +674,8 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def, { struct cipso_v4_domhsh_entry *iter; - rcu_read_lock(); spin_lock(&cipso_v4_doi_list_lock); - list_for_each_entry_rcu(iter, &doi_def->dom_list, list) + list_for_each_entry(iter, &doi_def->dom_list, list) if (iter->valid && ((domain != NULL && iter->domain != NULL && strcmp(iter->domain, domain) == 0) || @@ -699,13 +683,10 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def, iter->valid = 0; list_del_rcu(&iter->list); spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free); - return 0; } spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); return -ENOENT; } diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 6b1a31a74cf2..cad4278025ad 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -3,7 +3,7 @@ #include <net/ip.h> #include <net/xfrm.h> #include <net/esp.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include <linux/crypto.h> #include <linux/kernel.h> #include <linux/pfkeyv2.h> @@ -110,7 +110,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto unlock; } - skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); + sg_init_table(sg, nfrags); + sg_mark_end(sg, skb_to_sgvec(skb, sg, esph->enc_data + + esp->conf.ivlen - + skb->data, clen)); err = crypto_blkcipher_encrypt(&desc, sg, sg, clen); if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); @@ -201,7 +204,9 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto out; } - skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen); + sg_init_table(sg, nfrags); + sg_mark_end(sg, skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, + elen)); err = crypto_blkcipher_decrypt(&desc, sg, sg, elen); if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 78b514ba1414..60123905dbbf 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -128,13 +128,14 @@ struct net_device * ip_dev_find(__be32 addr) struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; struct net_device *dev = NULL; + struct fib_table *local_table; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif - if (!ip_fib_local_table || - ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res)) + local_table = fib_get_table(RT_TABLE_LOCAL); + if (!local_table || local_table->tb_lookup(local_table, &fl, &res)) return NULL; if (res.type != RTN_LOCAL) goto out; @@ -152,6 +153,7 @@ unsigned inet_addr_type(__be32 addr) struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; unsigned ret = RTN_BROADCAST; + struct fib_table *local_table; if (ZERONET(addr) || BADCLASS(addr)) return RTN_BROADCAST; @@ -162,10 +164,10 @@ unsigned inet_addr_type(__be32 addr) res.r = NULL; #endif - if (ip_fib_local_table) { + local_table = fib_get_table(RT_TABLE_LOCAL); + if (local_table) { ret = RTN_UNICAST; - if (!ip_fib_local_table->tb_lookup(ip_fib_local_table, - &fl, &res)) { + if (!local_table->tb_lookup(local_table, &fl, &res)) { ret = res.type; fib_res_put(&res); } diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 272c69e106e9..233de0634298 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -1104,5 +1104,4 @@ void __init icmp_init(struct net_proto_family *ops) EXPORT_SYMBOL(icmp_err_convert); EXPORT_SYMBOL(icmp_send); EXPORT_SYMBOL(icmp_statistics); -EXPORT_SYMBOL(icmpmsg_statistics); EXPORT_SYMBOL(xrlim_allow); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f151900efaf9..02b02a8d681c 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -674,7 +674,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) struct rtable *rt; /* Route to the other host */ struct net_device *tdev; /* Device to other host */ struct iphdr *iph; /* Our new IP header */ - int max_headroom; /* The extra header space needed */ + unsigned int max_headroom; /* The extra header space needed */ int gre_hlen; __be32 dst; int mtu; @@ -1033,7 +1033,6 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) return 0; } -#ifdef CONFIG_NET_IPGRE_BROADCAST /* Nice toy. Unfortunately, useless in real life :-) It allows to construct virtual multiprotocol broadcast "LAN" over the Internet, provided multicast routing is tuned. @@ -1092,10 +1091,19 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, return -t->hlen; } +static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{ + struct iphdr *iph = (struct iphdr*) skb_mac_header(skb); + memcpy(haddr, &iph->saddr, 4); + return 4; +} + static const struct header_ops ipgre_header_ops = { .create = ipgre_header, + .parse = ipgre_header_parse, }; +#ifdef CONFIG_NET_IPGRE_BROADCAST static int ipgre_open(struct net_device *dev) { struct ip_tunnel *t = netdev_priv(dev); @@ -1197,6 +1205,8 @@ static int ipgre_tunnel_init(struct net_device *dev) dev->stop = ipgre_close; } #endif + } else { + dev->header_ops = &ipgre_header_ops; } if (!tdev && tunnel->parms.link) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f508835ba713..e5f7dc2de303 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -161,7 +161,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) struct dst_entry *dst = skb->dst; struct rtable *rt = (struct rtable *)dst; struct net_device *dev = dst->dev; - int hh_len = LL_RESERVED_SPACE(dev); + unsigned int hh_len = LL_RESERVED_SPACE(dev); if (rt->rt_type == RTN_MULTICAST) IP_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 5cd5bbe1379a..8c2b2b0741da 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -515,7 +515,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) struct net_device *tdev; /* Device to other host */ struct iphdr *old_iph = ip_hdr(skb); struct iphdr *iph; /* Our new IP header */ - int max_headroom; /* The extra header space needed */ + unsigned int max_headroom; /* The extra header space needed */ __be32 dst = tiph->daddr; int mtu; diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index d0a92dec1050..7c074e386c17 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c @@ -325,7 +325,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, __be16 df = old_iph->frag_off; sk_buff_data_t old_transport_header = skb->transport_header; struct iphdr *iph; /* Our new IP header */ - int max_headroom; /* The extra header space needed */ + unsigned int max_headroom; /* The extra header space needed */ int mtu; EnterFunction(10); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index fd16cb8f8abe..9be0daa9c0ec 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -121,14 +121,6 @@ static const struct snmp_mib snmp4_ipextstats_list[] = { SNMP_MIB_SENTINEL }; -static const struct snmp_mib snmp4_icmp_list[] = { - SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), - SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), - SNMP_MIB_ITEM("OutMsgs", ICMP_MIB_OUTMSGS), - SNMP_MIB_ITEM("OutErrors", ICMP_MIB_OUTERRORS), - SNMP_MIB_SENTINEL -}; - static struct { char *name; int index; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9288220b73a8..69d8c38ccd39 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -103,7 +103,7 @@ int sysctl_tcp_abc __read_mostly; #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ -#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained DSACK info */ +#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) @@ -866,7 +866,7 @@ static void tcp_disable_fack(struct tcp_sock *tp) tp->rx_opt.sack_ok &= ~2; } -/* Take a notice that peer is sending DSACKs */ +/* Take a notice that peer is sending D-SACKs */ static void tcp_dsack_seen(struct tcp_sock *tp) { tp->rx_opt.sack_ok |= 4; @@ -1058,7 +1058,7 @@ static void tcp_update_reordering(struct sock *sk, const int metric, * * With D-SACK the lower bound is extended to cover sequence space below * SND.UNA down to undo_marker, which is the last point of interest. Yet - * again, DSACK block must not to go across snd_una (for the same reason as + * again, D-SACK block must not to go across snd_una (for the same reason as * for the normal SACK blocks, explained above). But there all simplicity * ends, TCP might receive valid D-SACKs below that. As long as they reside * fully below undo_marker they do not affect behavior in anyway and can @@ -1080,7 +1080,7 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, if (!before(start_seq, tp->snd_nxt)) return 0; - /* In outstanding window? ...This is valid exit for DSACKs too. + /* In outstanding window? ...This is valid exit for D-SACKs too. * start_seq == snd_una is non-sensical (see comments above) */ if (after(start_seq, tp->snd_una)) @@ -1204,8 +1204,8 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, * which may fail and creates some hassle (caller must handle error case * returns). */ -int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, - u32 start_seq, u32 end_seq) +static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, + u32 start_seq, u32 end_seq) { int in_sack, err; unsigned int pkt_len; @@ -1248,6 +1248,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ int cached_fack_count; int i; int first_sack_index; + int force_one_sack; if (!tp->sacked_out) { if (WARN_ON(tp->fackets_out)) @@ -1272,18 +1273,18 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ * if the only SACK change is the increase of the end_seq of * the first block then only apply that SACK block * and use retrans queue hinting otherwise slowpath */ - flag = 1; + force_one_sack = 1; for (i = 0; i < num_sacks; i++) { __be32 start_seq = sp[i].start_seq; __be32 end_seq = sp[i].end_seq; if (i == 0) { if (tp->recv_sack_cache[i].start_seq != start_seq) - flag = 0; + force_one_sack = 0; } else { if ((tp->recv_sack_cache[i].start_seq != start_seq) || (tp->recv_sack_cache[i].end_seq != end_seq)) - flag = 0; + force_one_sack = 0; } tp->recv_sack_cache[i].start_seq = start_seq; tp->recv_sack_cache[i].end_seq = end_seq; @@ -1295,7 +1296,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } first_sack_index = 0; - if (flag) + if (force_one_sack) num_sacks = 1; else { int j; @@ -1321,9 +1322,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } } - /* clear flag as used for different purpose in following code */ - flag = 0; - /* Use SACK fastpath hint if valid */ cached_skb = tp->fastpath_skb_hint; cached_fack_count = tp->fastpath_cnt_hint; @@ -1615,7 +1613,7 @@ void tcp_enter_frto(struct sock *sk) !icsk->icsk_retransmits)) { tp->prior_ssthresh = tcp_current_ssthresh(sk); /* Our state is too optimistic in ssthresh() call because cwnd - * is not reduced until tcp_enter_frto_loss() when previous FRTO + * is not reduced until tcp_enter_frto_loss() when previous F-RTO * recovery has not yet completed. Pattern would be this: RTO, * Cumulative ACK, RTO (2xRTO for the same segment does not end * up here twice). @@ -1801,7 +1799,7 @@ void tcp_enter_loss(struct sock *sk, int how) tcp_set_ca_state(sk, TCP_CA_Loss); tp->high_seq = tp->snd_nxt; TCP_ECN_queue_cwr(tp); - /* Abort FRTO algorithm if one is in progress */ + /* Abort F-RTO algorithm if one is in progress */ tp->frto_counter = 0; } @@ -1946,7 +1944,7 @@ static int tcp_time_to_recover(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); __u32 packets_out; - /* Do not perform any recovery during FRTO algorithm */ + /* Do not perform any recovery during F-RTO algorithm */ if (tp->frto_counter) return 0; @@ -2962,7 +2960,7 @@ static int tcp_process_frto(struct sock *sk, int flag) } if (tp->frto_counter == 1) { - /* Sending of the next skb must be allowed or no FRTO */ + /* Sending of the next skb must be allowed or no F-RTO */ if (!tcp_send_head(sk) || after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, tp->snd_una + tp->snd_wnd)) { @@ -3909,7 +3907,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, while (before(start, end)) { struct sk_buff *nskb; - int header = skb_headroom(skb); + unsigned int header = skb_headroom(skb); int copy = SKB_MAX_ORDER(header, 0); /* Too big header? This can happen with IPv6. */ diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 38cf73a56731..ad759f1c3777 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1055,6 +1055,9 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, bp->pad = 0; bp->protocol = protocol; bp->len = htons(tcplen); + + sg_init_table(sg, 4); + sg_set_buf(&sg[block++], bp, sizeof(*bp)); nbytes += sizeof(*bp); @@ -1080,6 +1083,8 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, sg_set_buf(&sg[block++], key->key, key->keylen); nbytes += key->keylen; + sg_mark_end(sg, block); + /* Now store the Hash into the packet */ err = crypto_hash_init(desc); if (err) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 35d2b0e9e10b..4bc25b46f33f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1152,7 +1152,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, - skb->dev->ifindex, udptable ); + inet_iif(skb), udptable); if (sk != NULL) { int ret = udp_queue_rcv_skb(sk, skb); diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 72a659806cad..ab17b5e62355 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -29,7 +29,7 @@ #include <net/ip.h> #include <net/xfrm.h> #include <net/esp.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include <linux/crypto.h> #include <linux/kernel.h> #include <linux/pfkeyv2.h> @@ -109,7 +109,10 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto unlock; } - skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); + sg_init_table(sg, nfrags); + sg_mark_end(sg, skb_to_sgvec(skb, sg, esph->enc_data + + esp->conf.ivlen - + skb->data, clen)); err = crypto_blkcipher_encrypt(&desc, sg, sg, clen); if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); @@ -205,7 +208,10 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) goto out; } } - skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen); + sg_init_table(sg, nfrags); + sg_mark_end(sg, skb_to_sgvec(skb, sg, + sizeof(*esph) + esp->conf.ivlen, + elen)); ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen); if (unlikely(sg != &esp->sgbuf[0])) kfree(sg); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 13565dfb1b45..653fc0a8235b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -171,7 +171,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, u32 mtu; if (opt) { - int head_room; + unsigned int head_room; /* First: exthdrs may take lots of space (~8K for now) MAX_HEADER is not enough. diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2320cc27ff9e..5383b33db8ca 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -838,7 +838,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, struct dst_entry *dst; struct net_device *tdev; int mtu; - int max_headroom = sizeof(struct ipv6hdr); + unsigned int max_headroom = sizeof(struct ipv6hdr); u8 proto; int err = -1; int pkt_len; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 466657a9a8bd..71433d29d884 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -430,7 +430,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) struct rtable *rt; /* Route to the other host */ struct net_device *tdev; /* Device to other host */ struct iphdr *iph; /* Our new IP header */ - int max_headroom; /* The extra header space needed */ + unsigned int max_headroom; /* The extra header space needed */ __be32 dst = tiph->daddr; int mtu; struct in6_addr *addr6; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 737b755342bd..85208026278b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -59,6 +59,7 @@ #include <net/snmp.h> #include <net/dsfield.h> #include <net/timewait_sock.h> +#include <net/netdma.h> #include <asm/uaccess.h> @@ -757,6 +758,8 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, bp->len = htonl(tcplen); bp->protocol = htonl(protocol); + sg_init_table(sg, 4); + sg_set_buf(&sg[block++], bp, sizeof(*bp)); nbytes += sizeof(*bp); @@ -778,6 +781,8 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, sg_set_buf(&sg[block++], key->key, key->keylen); nbytes += key->keylen; + sg_mark_end(sg, block); + /* Now store the hash into the packet */ err = crypto_hash_init(desc); if (err) { @@ -1728,6 +1733,8 @@ process: if (!sock_owned_by_user(sk)) { #ifdef CONFIG_NET_DMA struct tcp_sock *tp = tcp_sk(sk); + if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) + tp->ucopy.dma_chan = get_softnet_dma(); if (tp->ucopy.dma_chan) ret = tcp_v6_do_rcv(sk, skb); else diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 3d241e415a2a..1120b150e211 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -77,7 +77,7 @@ static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len, #endif /* CONFIG_PROC_FS */ static struct tty_driver *driver; -hashbin_t *ircomm_tty = NULL; +static hashbin_t *ircomm_tty = NULL; static const struct tty_operations ops = { .open = ircomm_tty_open, diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index f7ffeec3913f..fda0e06453e8 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -1184,7 +1184,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " "status=%d aid=%d)\n", dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), - capab_info, status_code, aid & ~(BIT(15) | BIT(14))); + capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); if (status_code != WLAN_STATUS_SUCCESS) { printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", @@ -2096,7 +2096,8 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, { int tmp, hidden_ssid; - if (!memcmp(ifsta->ssid, ssid, ssid_len)) + if (ssid_len == ifsta->ssid_len && + !memcmp(ifsta->ssid, ssid, ssid_len)) return 1; if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index b6c844b7e1c1..b3675bd7db33 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -178,11 +178,9 @@ int netlbl_domhsh_init(u32 size) for (iter = 0; iter < hsh_tbl->size; iter++) INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); - rcu_read_lock(); spin_lock(&netlbl_domhsh_lock); rcu_assign_pointer(netlbl_domhsh, hsh_tbl); spin_unlock(&netlbl_domhsh_lock); - rcu_read_unlock(); return 0; } @@ -222,7 +220,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, entry->valid = 1; INIT_RCU_HEAD(&entry->rcu); - ret_val = 0; rcu_read_lock(); if (entry->domain != NULL) { bkt = netlbl_domhsh_hash(entry->domain); @@ -233,7 +230,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, else ret_val = -EEXIST; spin_unlock(&netlbl_domhsh_lock); - } else if (entry->domain == NULL) { + } else { INIT_LIST_HEAD(&entry->list); spin_lock(&netlbl_domhsh_def_lock); if (rcu_dereference(netlbl_domhsh_def) == NULL) @@ -241,9 +238,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, else ret_val = -EEXIST; spin_unlock(&netlbl_domhsh_def_lock); - } else - ret_val = -EINVAL; - + } audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); if (audit_buf != NULL) { audit_log_format(audit_buf, @@ -262,7 +257,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); } - rcu_read_unlock(); if (ret_val != 0) { @@ -313,38 +307,30 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) struct audit_buffer *audit_buf; rcu_read_lock(); - if (domain != NULL) - entry = netlbl_domhsh_search(domain, 0); - else - entry = netlbl_domhsh_search(domain, 1); + entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1)); if (entry == NULL) goto remove_return; switch (entry->type) { - case NETLBL_NLTYPE_UNLABELED: - break; case NETLBL_NLTYPE_CIPSOV4: - ret_val = cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, - entry->domain); - if (ret_val != 0) - goto remove_return; + cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, + entry->domain); break; } - ret_val = 0; if (entry != rcu_dereference(netlbl_domhsh_def)) { spin_lock(&netlbl_domhsh_lock); if (entry->valid) { entry->valid = 0; list_del_rcu(&entry->list); - } else - ret_val = -ENOENT; + ret_val = 0; + } spin_unlock(&netlbl_domhsh_lock); } else { spin_lock(&netlbl_domhsh_def_lock); if (entry->valid) { entry->valid = 0; rcu_assign_pointer(netlbl_domhsh_def, NULL); - } else - ret_val = -ENOENT; + ret_val = 0; + } spin_unlock(&netlbl_domhsh_def_lock); } @@ -357,11 +343,10 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) audit_log_end(audit_buf); } - if (ret_val == 0) - call_rcu(&entry->rcu, netlbl_domhsh_free_entry); - remove_return: rcu_read_unlock(); + if (ret_val == 0) + call_rcu(&entry->rcu, netlbl_domhsh_free_entry); return ret_val; } diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 5315dacc5222..56483377997a 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -85,11 +85,9 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { */ void netlbl_mgmt_protocount_inc(void) { - rcu_read_lock(); spin_lock(&netlabel_mgmt_protocount_lock); netlabel_mgmt_protocount++; spin_unlock(&netlabel_mgmt_protocount_lock); - rcu_read_unlock(); } /** @@ -103,12 +101,10 @@ void netlbl_mgmt_protocount_inc(void) */ void netlbl_mgmt_protocount_dec(void) { - rcu_read_lock(); spin_lock(&netlabel_mgmt_protocount_lock); if (netlabel_mgmt_protocount > 0) netlabel_mgmt_protocount--; spin_unlock(&netlabel_mgmt_protocount_lock); - rcu_read_unlock(); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 5c303c68af1d..348292450deb 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -84,12 +84,10 @@ static void netlbl_unlabel_acceptflg_set(u8 value, struct audit_buffer *audit_buf; u8 old_val; - rcu_read_lock(); - old_val = netlabel_unlabel_acceptflg; spin_lock(&netlabel_unlabel_acceptflg_lock); + old_val = netlabel_unlabel_acceptflg; netlabel_unlabel_acceptflg = value; spin_unlock(&netlabel_unlabel_acceptflg_lock); - rcu_read_unlock(); audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, audit_info); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 98e313e5e594..4f994c0fb3f8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1565,7 +1565,11 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, netlink_dump(sk); sock_put(sk); - return 0; + + /* We successfully started a dump, by returning -EINTR we + * signal not to send ACK even if it was requested. + */ + return -EINTR; } void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) @@ -1619,17 +1623,21 @@ int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, /* Only requests are handled by the kernel */ if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) - goto skip; + goto ack; /* Skip control messages */ if (nlh->nlmsg_type < NLMSG_MIN_TYPE) - goto skip; + goto ack; err = cb(skb, nlh); -skip: + if (err == -EINTR) + goto skip; + +ack: if (nlh->nlmsg_flags & NLM_F_ACK || err) netlink_ack(skb, nlh, err); +skip: msglen = NLMSG_ALIGN(nlh->nlmsg_len); if (msglen > skb->len) msglen = skb->len; @@ -1880,7 +1888,7 @@ static void __net_exit netlink_net_exit(struct net *net) #endif } -static struct pernet_operations __net_initdata netlink_net_ops = { +static struct pernet_operations netlink_net_ops = { .init = netlink_net_init, .exit = netlink_net_exit, }; diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index ac3cabdca78c..eebefb6ef139 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -135,9 +135,8 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn) tmpbuf.x[2] = 0; tmpbuf.x[3] = htonl(conn->security_ix); - memset(sg, 0, sizeof(sg)); - sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf)); - sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); memcpy(&conn->csum_iv, &tmpbuf.x[2], sizeof(conn->csum_iv)); @@ -180,9 +179,8 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call, desc.info = iv.x; desc.flags = 0; - memset(sg, 0, sizeof(sg)); - sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf)); - sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); memcpy(sechdr, &tmpbuf, sizeof(tmpbuf)); @@ -227,9 +225,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, desc.info = iv.x; desc.flags = 0; - memset(sg, 0, sizeof(sg[0]) * 2); - sg_set_buf(&sg[0], sechdr, sizeof(rxkhdr)); - sg_set_buf(&sg[1], &rxkhdr, sizeof(rxkhdr)); + sg_init_one(&sg[0], sechdr, sizeof(rxkhdr)); + sg_init_one(&sg[1], &rxkhdr, sizeof(rxkhdr)); crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(rxkhdr)); /* we want to encrypt the skbuff in-place */ @@ -240,7 +237,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, len = data_size + call->conn->size_align - 1; len &= ~(call->conn->size_align - 1); - skb_to_sgvec(skb, sg, 0, len); + sg_init_table(sg, skb_to_sgvec(skb, sg, 0, len)); crypto_blkcipher_encrypt_iv(&desc, sg, sg, len); _leave(" = 0"); @@ -290,9 +287,8 @@ static int rxkad_secure_packet(const struct rxrpc_call *call, tmpbuf.x[0] = sp->hdr.callNumber; tmpbuf.x[1] = x; - memset(&sg, 0, sizeof(sg)); - sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf)); - sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); x = ntohl(tmpbuf.x[1]); @@ -332,20 +328,23 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call, struct rxrpc_skb_priv *sp; struct blkcipher_desc desc; struct rxrpc_crypt iv; - struct scatterlist sg[2]; + struct scatterlist sg[16]; struct sk_buff *trailer; u32 data_size, buf; u16 check; + int nsg; _enter(""); sp = rxrpc_skb(skb); /* we want to decrypt the skbuff in-place */ - if (skb_cow_data(skb, 0, &trailer) < 0) + nsg = skb_cow_data(skb, 0, &trailer); + if (nsg < 0 || nsg > 16) goto nomem; - skb_to_sgvec(skb, sg, 0, 8); + sg_init_table(sg, nsg); + sg_mark_end(sg, skb_to_sgvec(skb, sg, 0, 8)); /* start the decryption afresh */ memset(&iv, 0, sizeof(iv)); @@ -426,7 +425,8 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call, goto nomem; } - skb_to_sgvec(skb, sg, 0, skb->len); + sg_init_table(sg, nsg); + sg_mark_end(sg, skb_to_sgvec(skb, sg, 0, skb->len)); /* decrypt from the session key */ payload = call->conn->key->payload.data; @@ -521,9 +521,8 @@ static int rxkad_verify_packet(const struct rxrpc_call *call, tmpbuf.x[0] = call->call_id; tmpbuf.x[1] = x; - memset(&sg, 0, sizeof(sg)); - sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf)); - sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf)); + sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf)); crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf)); x = ntohl(tmpbuf.x[1]); @@ -690,16 +689,20 @@ static void rxkad_calc_response_checksum(struct rxkad_response *response) static void rxkad_sg_set_buf2(struct scatterlist sg[2], void *buf, size_t buflen) { + int nsg = 1; - memset(sg, 0, sizeof(sg)); + sg_init_table(sg, 2); sg_set_buf(&sg[0], buf, buflen); if (sg[0].offset + buflen > PAGE_SIZE) { /* the buffer was split over two pages */ sg[0].length = PAGE_SIZE - sg[0].offset; sg_set_buf(&sg[1], buf + sg[0].length, buflen - sg[0].length); + nsg++; } + sg_mark_end(sg, nsg); + ASSERTCMP(sg[0].length + sg[1].length, ==, buflen); } @@ -712,7 +715,7 @@ static void rxkad_encrypt_response(struct rxrpc_connection *conn, { struct blkcipher_desc desc; struct rxrpc_crypt iv; - struct scatterlist ssg[2], dsg[2]; + struct scatterlist sg[2]; /* continue encrypting from where we left off */ memcpy(&iv, s2->session_key, sizeof(iv)); @@ -720,9 +723,8 @@ static void rxkad_encrypt_response(struct rxrpc_connection *conn, desc.info = iv.x; desc.flags = 0; - rxkad_sg_set_buf2(ssg, &resp->encrypted, sizeof(resp->encrypted)); - memcpy(dsg, ssg, sizeof(dsg)); - crypto_blkcipher_encrypt_iv(&desc, dsg, ssg, sizeof(resp->encrypted)); + rxkad_sg_set_buf2(sg, &resp->encrypted, sizeof(resp->encrypted)); + crypto_blkcipher_encrypt_iv(&desc, sg, sg, sizeof(resp->encrypted)); } /* @@ -817,7 +819,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, { struct blkcipher_desc desc; struct rxrpc_crypt iv, key; - struct scatterlist ssg[1], dsg[1]; + struct scatterlist sg[1]; struct in_addr addr; unsigned life; time_t issue, now; @@ -850,9 +852,8 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn, desc.info = iv.x; desc.flags = 0; - sg_init_one(&ssg[0], ticket, ticket_len); - memcpy(dsg, ssg, sizeof(dsg)); - crypto_blkcipher_decrypt_iv(&desc, dsg, ssg, ticket_len); + sg_init_one(&sg[0], ticket, ticket_len); + crypto_blkcipher_decrypt_iv(&desc, sg, sg, ticket_len); p = ticket; end = p + ticket_len; @@ -961,7 +962,7 @@ static void rxkad_decrypt_response(struct rxrpc_connection *conn, const struct rxrpc_crypt *session_key) { struct blkcipher_desc desc; - struct scatterlist ssg[2], dsg[2]; + struct scatterlist sg[2]; struct rxrpc_crypt iv; _enter(",,%08x%08x", @@ -979,9 +980,8 @@ static void rxkad_decrypt_response(struct rxrpc_connection *conn, desc.info = iv.x; desc.flags = 0; - rxkad_sg_set_buf2(ssg, &resp->encrypted, sizeof(resp->encrypted)); - memcpy(dsg, ssg, sizeof(dsg)); - crypto_blkcipher_decrypt_iv(&desc, dsg, ssg, sizeof(resp->encrypted)); + rxkad_sg_set_buf2(sg, &resp->encrypted, sizeof(resp->encrypted)); + crypto_blkcipher_decrypt_iv(&desc, sg, sg, sizeof(resp->encrypted)); mutex_unlock(&rxkad_ci_mutex); _leave(""); diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index fd7bca4d5c20..c3fde9180f9d 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -166,7 +166,7 @@ bad_mirred: return TC_ACT_SHOT; } - skb2 = skb_clone(skb, GFP_ATOMIC); + skb2 = skb_act_clone(skb, GFP_ATOMIC); if (skb2 == NULL) goto bad_mirred; if (m->tcfm_eaction != TCA_EGRESS_MIRROR && diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index abd82fc3ec60..de894096e442 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -136,7 +136,7 @@ prio_dequeue(struct Qdisc* sch) * pulling an skb. This way we avoid excessive requeues * for slower queues. */ - if (!netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) { + if (!__netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) { qdisc = q->queues[prio]; skb = qdisc->dequeue(qdisc); if (skb) { @@ -165,7 +165,7 @@ static struct sk_buff *rr_dequeue(struct Qdisc* sch) * for slower queues. If the queue is stopped, try the * next queue. */ - if (!netif_subqueue_stopped(sch->dev, + if (!__netif_subqueue_stopped(sch->dev, (q->mq ? q->curband : 0))) { qdisc = q->queues[q->curband]; skb = qdisc->dequeue(qdisc); diff --git a/net/sctp/auth.c b/net/sctp/auth.c index cbd64b216cce..8af1004abefe 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -107,7 +107,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp) } /* Free the shared key stucture */ -void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) +static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) { BUG_ON(!list_empty(&sh_key->key_list)); sctp_auth_key_put(sh_key->key); @@ -220,7 +220,7 @@ static struct sctp_auth_bytes *sctp_auth_make_key_vector( /* Make a key vector based on our local parameters */ -struct sctp_auth_bytes *sctp_auth_make_local_vector( +static struct sctp_auth_bytes *sctp_auth_make_local_vector( const struct sctp_association *asoc, gfp_t gfp) { @@ -232,7 +232,7 @@ struct sctp_auth_bytes *sctp_auth_make_local_vector( } /* Make a key vector based on peer's parameters */ -struct sctp_auth_bytes *sctp_auth_make_peer_vector( +static struct sctp_auth_bytes *sctp_auth_make_peer_vector( const struct sctp_association *asoc, gfp_t gfp) { @@ -726,10 +726,7 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc, /* set up scatter list */ end = skb_tail_pointer(skb); - sg_init_table(&sg, 1); - sg_set_page(&sg, virt_to_page(auth)); - sg.offset = (unsigned long)(auth) % PAGE_SIZE; - sg.length = end - (unsigned char *)auth; + sg_init_one(&sg, auth, end - (unsigned char *)auth); desc.tfm = asoc->ep->auth_hmacs[hmac_id]; desc.flags = 0; diff --git a/net/sctp/crc32c.c b/net/sctp/crc32c.c index 59cf7b06d216..181edabdb8ca 100644 --- a/net/sctp/crc32c.c +++ b/net/sctp/crc32c.c @@ -170,6 +170,7 @@ __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32) return crc32; } +#if 0 __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32) { __u32 i; @@ -186,6 +187,7 @@ __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32) return crc32; } +#endif /* 0 */ __u32 sctp_end_cksum(__u32 crc32) { diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 658476c4d587..c377e4e8f653 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -1513,10 +1513,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, struct hash_desc desc; /* Sign the message. */ - sg_init_table(&sg, 1); - sg_set_page(&sg, virt_to_page(&cookie->c)); - sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE; - sg.length = bodysize; + sg_init_one(&sg, &cookie->c, bodysize); keylen = SCTP_SECRET_SIZE; key = (char *)ep->secret_key[ep->current_key]; desc.tfm = sctp_sk(ep->base.sk)->hmac; @@ -1586,10 +1583,7 @@ struct sctp_association *sctp_unpack_cookie( /* Check the signature. */ keylen = SCTP_SECRET_SIZE; - sg_init_table(&sg, 1); - sg_set_page(&sg, virt_to_page(bear_cookie)); - sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE; - sg.length = bodysize; + sg_init_one(&sg, bear_cookie, bodysize); key = (char *)ep->secret_key[ep->current_key]; desc.tfm = sctp_sk(ep->base.sk)->hmac; desc.flags = 0; diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index b9370956b187..4be92d0a2cab 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -908,8 +908,8 @@ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn) return; } -/* Renege 'needed' bytes from the ordering queue. */ -static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed) +static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq, + struct sk_buff_head *list, __u16 needed) { __u16 freed = 0; __u32 tsn; @@ -919,7 +919,7 @@ static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed) tsnmap = &ulpq->asoc->peer.tsn_map; - while ((skb = __skb_dequeue_tail(&ulpq->lobby)) != NULL) { + while ((skb = __skb_dequeue_tail(list)) != NULL) { freed += skb_headlen(skb); event = sctp_skb2event(skb); tsn = event->tsn; @@ -933,30 +933,16 @@ static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed) return freed; } +/* Renege 'needed' bytes from the ordering queue. */ +static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed) +{ + return sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed); +} + /* Renege 'needed' bytes from the reassembly queue. */ static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed) { - __u16 freed = 0; - __u32 tsn; - struct sk_buff *skb; - struct sctp_ulpevent *event; - struct sctp_tsnmap *tsnmap; - - tsnmap = &ulpq->asoc->peer.tsn_map; - - /* Walk backwards through the list, reneges the newest tsns. */ - while ((skb = __skb_dequeue_tail(&ulpq->reasm)) != NULL) { - freed += skb_headlen(skb); - event = sctp_skb2event(skb); - tsn = event->tsn; - - sctp_ulpevent_free(event); - sctp_tsnmap_renege(tsnmap, tsn); - if (freed >= needed) - return freed; - } - - return freed; + return sctp_ulpq_renege_list(ulpq, &ulpq->reasm, needed); } /* Partial deliver the first message as there is pressure on rwnd. */ diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 32be431affcf..91cd8f0d1e10 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -75,7 +75,7 @@ krb5_encrypt( memcpy(local_iv, iv, crypto_blkcipher_ivsize(tfm)); memcpy(out, in, length); - sg_set_buf(sg, out, length); + sg_init_one(sg, out, length); ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, length); out: @@ -110,7 +110,7 @@ krb5_decrypt( memcpy(local_iv,iv, crypto_blkcipher_ivsize(tfm)); memcpy(out, in, length); - sg_set_buf(sg, out, length); + sg_init_one(sg, out, length); ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, length); out: @@ -146,7 +146,7 @@ make_checksum(char *cksumname, char *header, int hdrlen, struct xdr_buf *body, err = crypto_hash_init(&desc); if (err) goto out; - sg_set_buf(sg, header, hdrlen); + sg_init_one(sg, header, hdrlen); err = crypto_hash_update(&desc, sg, hdrlen); if (err) goto out; @@ -188,8 +188,6 @@ encryptor(struct scatterlist *sg, void *data) /* Worst case is 4 fragments: head, end of page 1, start * of page 2, tail. Anything more is a bug. */ BUG_ON(desc->fragno > 3); - desc->infrags[desc->fragno] = *sg; - desc->outfrags[desc->fragno] = *sg; page_pos = desc->pos - outbuf->head[0].iov_len; if (page_pos >= 0 && page_pos < outbuf->page_len) { @@ -199,7 +197,10 @@ encryptor(struct scatterlist *sg, void *data) } else { in_page = sg_page(sg); } - sg_set_page(&desc->infrags[desc->fragno], in_page); + sg_set_page(&desc->infrags[desc->fragno], in_page, sg->length, + sg->offset); + sg_set_page(&desc->outfrags[desc->fragno], sg_page(sg), sg->length, + sg->offset); desc->fragno++; desc->fraglen += sg->length; desc->pos += sg->length; @@ -210,16 +211,22 @@ encryptor(struct scatterlist *sg, void *data) if (thislen == 0) return 0; + sg_mark_end(desc->infrags, desc->fragno); + sg_mark_end(desc->outfrags, desc->fragno); + ret = crypto_blkcipher_encrypt_iv(&desc->desc, desc->outfrags, desc->infrags, thislen); if (ret) return ret; + + sg_init_table(desc->infrags, 4); + sg_init_table(desc->outfrags, 4); + if (fraglen) { - sg_set_page(&desc->outfrags[0], sg_page(sg)); - desc->outfrags[0].offset = sg->offset + sg->length - fraglen; - desc->outfrags[0].length = fraglen; + sg_set_page(&desc->outfrags[0], sg_page(sg), fraglen, + sg->offset + sg->length - fraglen); desc->infrags[0] = desc->outfrags[0]; - sg_set_page(&desc->infrags[0], in_page); + sg_assign_page(&desc->infrags[0], in_page); desc->fragno = 1; desc->fraglen = fraglen; } else { @@ -248,6 +255,9 @@ gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf, desc.fragno = 0; desc.fraglen = 0; + sg_init_table(desc.infrags, 4); + sg_init_table(desc.outfrags, 4); + ret = xdr_process_buf(buf, offset, buf->len - offset, encryptor, &desc); return ret; } @@ -272,7 +282,8 @@ decryptor(struct scatterlist *sg, void *data) /* Worst case is 4 fragments: head, end of page 1, start * of page 2, tail. Anything more is a bug. */ BUG_ON(desc->fragno > 3); - desc->frags[desc->fragno] = *sg; + sg_set_page(&desc->frags[desc->fragno], sg_page(sg), sg->length, + sg->offset); desc->fragno++; desc->fraglen += sg->length; @@ -282,14 +293,18 @@ decryptor(struct scatterlist *sg, void *data) if (thislen == 0) return 0; + sg_mark_end(desc->frags, desc->fragno); + ret = crypto_blkcipher_decrypt_iv(&desc->desc, desc->frags, desc->frags, thislen); if (ret) return ret; + + sg_init_table(desc->frags, 4); + if (fraglen) { - sg_set_page(&desc->frags[0], sg_page(sg)); - desc->frags[0].offset = sg->offset + sg->length - fraglen; - desc->frags[0].length = fraglen; + sg_set_page(&desc->frags[0], sg_page(sg), fraglen, + sg->offset + sg->length - fraglen); desc->fragno = 1; desc->fraglen = fraglen; } else { @@ -314,6 +329,9 @@ gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf, desc.desc.flags = 0; desc.fragno = 0; desc.fraglen = 0; + + sg_init_table(desc.frags, 4); + return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc); } diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c index d158635de6c0..abf17ce2e3b1 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_seal.c +++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c @@ -173,7 +173,7 @@ make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header, if (err) goto out; - sg_set_buf(sg, header, hdrlen); + sg_init_one(sg, header, hdrlen); crypto_hash_update(&desc, sg, sg->length); xdr_process_buf(body, body_offset, body->len - body_offset, diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 3d1f7cdf9dd0..fdc5e6d7562b 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -1030,6 +1030,8 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, unsigned page_len, thislen, page_offset; struct scatterlist sg[1]; + sg_init_table(sg, 1); + if (offset >= buf->head[0].iov_len) { offset -= buf->head[0].iov_len; } else { @@ -1059,9 +1061,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, do { if (thislen > page_len) thislen = page_len; - sg_set_page(sg, buf->pages[i]); - sg->offset = page_offset; - sg->length = thislen; + sg_set_page(sg, buf->pages[i], thislen, page_offset); ret = actor(sg, data); if (ret) goto out; diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 313d4bed3aa9..0426388d351d 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c @@ -553,9 +553,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, if (copy > len) copy = len; - sg_set_page(&sg, virt_to_page(skb->data + offset)); - sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; - sg.length = copy; + sg_init_one(&sg, skb->data + offset, copy); err = icv_update(desc, &sg, copy); if (unlikely(err)) @@ -578,9 +576,9 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, if (copy > len) copy = len; - sg_set_page(&sg, frag->page); - sg.offset = frag->page_offset + offset-start; - sg.length = copy; + sg_init_table(&sg, 1); + sg_set_page(&sg, frag->page, copy, + frag->page_offset + offset-start); err = icv_update(desc, &sg, copy); if (unlikely(err)) diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 83c5e76414ce..59594126e8b6 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -4,23 +4,30 @@ PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config +# If a arch/$(SRCARCH)/Kconfig.$(ARCH) file exist use it +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/Kconfig.$(ARCH)),) + Kconfig := arch/$(SRCARCH)/Kconfig.$(ARCH) +else + Kconfig := arch/$(SRCARCH)/Kconfig +endif + xconfig: $(obj)/qconf - $< arch/$(ARCH)/Kconfig + $< $(Kconfig) gconfig: $(obj)/gconf - $< arch/$(ARCH)/Kconfig + $< $(Kconfig) menuconfig: $(obj)/mconf - $< arch/$(ARCH)/Kconfig + $< $(Kconfig) config: $(obj)/conf - $< arch/$(ARCH)/Kconfig + $< $(Kconfig) oldconfig: $(obj)/conf - $< -o arch/$(ARCH)/Kconfig + $< -o $(Kconfig) silentoldconfig: $(obj)/conf - $< -s arch/$(ARCH)/Kconfig + $< -s $(Kconfig) # Create new linux.po file # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files @@ -45,27 +52,27 @@ update-po-config: $(obj)/kxgettext PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig randconfig: $(obj)/conf - $< -r arch/$(ARCH)/Kconfig + $< -r $(Kconfig) allyesconfig: $(obj)/conf - $< -y arch/$(ARCH)/Kconfig + $< -y $(Kconfig) allnoconfig: $(obj)/conf - $< -n arch/$(ARCH)/Kconfig + $< -n $(Kconfig) allmodconfig: $(obj)/conf - $< -m arch/$(ARCH)/Kconfig + $< -m $(Kconfig) defconfig: $(obj)/conf ifeq ($(KBUILD_DEFCONFIG),) - $< -d arch/$(ARCH)/Kconfig + $< -d $(Kconfig) else - @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)' - $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig + @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'" + $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) endif %_defconfig: $(obj)/conf - $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig + $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig) # Help text used by make help help: diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d9f78c809ee9..1c502789cc1e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9299,7 +9299,6 @@ static struct alc_config_preset alc268_presets[] = { .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, .input_mux = &alc268_capture_source, - .input_mux = &alc268_capture_source, .unsol_event = alc268_toshiba_unsol_event, .init_hook = alc268_toshiba_automute, }, |