From e1812935fdf517f638896ba570e4f28a29f90619 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 22 Apr 2008 19:46:10 -0400 Subject: [PATCH] --- yaml --- r: 95809 b: refs/heads/master c: 74d92abc6143b124db03f0d341f02bde72fba6f5 h: refs/heads/master i: 95807: aecad7cfd20b4d290b6b1269b7c8c4019b2a4841 v: v3 --- [refs] | 2 +- trunk/Documentation/hwmon/w83l785ts | 3 +- trunk/Documentation/kdump/kdump.txt | 5 +- trunk/Documentation/lguest/lguest.c | 62 +- trunk/MAINTAINERS | 18 +- trunk/Makefile | 6 +- trunk/arch/frv/mm/Makefile | 2 +- trunk/arch/ia64/ia32/ia32_signal.c | 2 +- trunk/arch/ia64/kernel/acpi.c | 2 +- trunk/arch/ia64/kernel/irq.c | 4 +- trunk/arch/ia64/kernel/palinfo.c | 2 +- trunk/arch/ia64/kernel/signal.c | 15 +- trunk/arch/ia64/kernel/smp.c | 68 +- trunk/arch/ia64/kernel/time.c | 5 + trunk/arch/ia64/kernel/topology.c | 16 +- trunk/arch/ia64/kvm/kvm-ia64.c | 3 +- trunk/arch/m32r/Makefile | 2 - trunk/arch/m32r/defconfig | 863 ++++++ trunk/arch/m32r/kernel/vmlinux.lds.S | 3 + trunk/arch/m68knommu/kernel/asm-offsets.c | 1 - trunk/arch/m68knommu/kernel/entry.S | 9 - trunk/arch/m68knommu/kernel/setup.c | 2 +- trunk/arch/m68knommu/kernel/signal.c | 21 +- trunk/arch/m68knommu/kernel/traps.c | 88 +- trunk/arch/m68knommu/kernel/vmlinux.lds.S | 3 - trunk/arch/m68knommu/platform/5206e/config.c | 2 +- trunk/arch/m68knommu/platform/5272/config.c | 4 + trunk/arch/m68knommu/platform/528x/config.c | 266 +- trunk/arch/m68knommu/platform/5307/config.c | 3 +- .../arch/m68knommu/platform/coldfire/entry.S | 18 - trunk/arch/mips/kernel/binfmt_elfn32.c | 5 +- trunk/arch/mips/kernel/binfmt_elfo32.c | 5 +- trunk/arch/powerpc/kernel/time.c | 4 +- trunk/arch/x86/kvm/i8254.c | 6 +- trunk/arch/x86/kvm/lapic.c | 6 +- trunk/block/blk-barrier.c | 3 +- trunk/block/blk-core.c | 5 +- trunk/block/blk-settings.c | 20 +- trunk/block/blk-tag.c | 8 +- trunk/block/bsg.c | 2 +- trunk/block/elevator.c | 5 +- trunk/crypto/authenc.c | 5 +- trunk/crypto/cryptd.c | 4 +- trunk/crypto/eseqiv.c | 3 +- trunk/drivers/base/cpu.c | 10 +- trunk/drivers/block/cciss.c | 8 +- trunk/drivers/block/ub.c | 63 +- trunk/drivers/block/virtio_blk.c | 44 +- trunk/drivers/char/i8k.c | 6 +- trunk/drivers/char/mmtimer.c | 24 +- trunk/drivers/char/synclink.c | 16 +- trunk/drivers/firewire/fw-sbp2.c | 2 +- trunk/drivers/gpio/pca953x.c | 4 +- trunk/drivers/hwmon/adt7473.c | 45 +- trunk/drivers/hwmon/asb100.c | 4 + trunk/drivers/hwmon/lm75.c | 5 +- trunk/drivers/hwmon/smsc47b397.c | 17 +- trunk/drivers/hwmon/w83793.c | 26 +- trunk/drivers/hwmon/w83l785ts.c | 4 +- trunk/drivers/ide/ide-probe.c | 3 +- trunk/drivers/ieee1394/nodemgr.c | 5 +- trunk/drivers/isdn/hysdn/hysdn_procconf.c | 3 +- trunk/drivers/lguest/lguest_device.c | 68 +- trunk/drivers/lguest/lguest_user.c | 4 +- trunk/drivers/mtd/chips/cfi_cmdset_0001.c | 14 +- trunk/drivers/mtd/devices/mtdram.c | 11 +- trunk/drivers/mtd/devices/phram.c | 13 +- trunk/drivers/mtd/devices/pmc551.c | 27 +- trunk/drivers/mtd/devices/slram.c | 15 +- trunk/drivers/mtd/maps/uclinux.c | 6 +- trunk/drivers/mtd/mtdpart.c | 8 +- trunk/drivers/mtd/nand/at91_nand.c | 42 +- trunk/drivers/net/fec.c | 125 +- trunk/drivers/net/fec.h | 4 +- trunk/drivers/net/virtio_net.c | 96 +- trunk/drivers/pcmcia/au1000_db1x00.c | 6 +- trunk/drivers/pcmcia/au1000_generic.c | 11 +- trunk/drivers/pcmcia/au1000_pb1x00.c | 14 +- trunk/drivers/pcmcia/au1000_xxs1500.c | 2 +- trunk/drivers/pcmcia/cardbus.c | 2 +- trunk/drivers/pcmcia/ds.c | 2 +- trunk/drivers/pcmcia/i82092.c | 6 +- trunk/drivers/pcmcia/omap_cf.c | 2 +- trunk/drivers/pcmcia/pd6729.c | 6 +- trunk/drivers/pcmcia/pxa2xx_lubbock.c | 8 +- trunk/drivers/pcmcia/pxa2xx_mainstone.c | 4 +- trunk/drivers/pcmcia/rsrc_nonstatic.c | 2 +- trunk/drivers/pcmcia/sa1100_assabet.c | 4 +- trunk/drivers/pcmcia/sa1100_badge4.c | 8 +- trunk/drivers/pcmcia/sa1100_cerf.c | 2 +- trunk/drivers/pcmcia/sa1100_jornada720.c | 4 +- trunk/drivers/pcmcia/sa1100_neponset.c | 4 +- trunk/drivers/pcmcia/sa1100_shannon.c | 8 +- trunk/drivers/pcmcia/sa1100_simpad.c | 2 +- trunk/drivers/pcmcia/soc_common.c | 17 +- trunk/drivers/pcmcia/soc_common.h | 1 + trunk/drivers/pnp/pnpbios/rsparser.c | 6 +- trunk/drivers/scsi/mvsas.c | 4 +- trunk/drivers/scsi/ncr53c8xx.c | 2 +- trunk/drivers/serial/8250.c | 3 +- trunk/drivers/serial/8250_early.c | 2 +- trunk/drivers/serial/8250_pci.c | 14 +- trunk/drivers/serial/jsm/jsm.h | 1 - trunk/drivers/serial/jsm/jsm_driver.c | 6 +- trunk/drivers/spi/spi_bfin5xx.c | 7 +- trunk/drivers/spi/spi_s3c24xx.c | 6 +- trunk/drivers/usb/Makefile | 2 - trunk/drivers/usb/atm/Kconfig | 4 + trunk/drivers/usb/c67x00/Makefile | 9 - trunk/drivers/usb/c67x00/c67x00-drv.c | 243 -- trunk/drivers/usb/c67x00/c67x00-hcd.c | 412 --- trunk/drivers/usb/c67x00/c67x00-hcd.h | 133 - trunk/drivers/usb/c67x00/c67x00-ll-hpi.c | 480 ---- trunk/drivers/usb/c67x00/c67x00-sched.c | 1170 -------- trunk/drivers/usb/c67x00/c67x00.h | 294 -- trunk/drivers/usb/core/message.c | 4 +- trunk/drivers/usb/gadget/Kconfig | 20 - trunk/drivers/usb/gadget/Makefile | 1 - trunk/drivers/usb/gadget/ether.c | 8 +- trunk/drivers/usb/gadget/file_storage.c | 25 +- trunk/drivers/usb/gadget/pxa27x_udc.c | 2404 ----------------- trunk/drivers/usb/gadget/pxa27x_udc.h | 487 ---- trunk/drivers/usb/gadget/serial.c | 90 +- trunk/drivers/usb/gadget/zero.c | 370 +-- trunk/drivers/usb/host/Kconfig | 39 - trunk/drivers/usb/host/Makefile | 4 +- trunk/drivers/usb/host/isp1760-hcd.c | 2231 --------------- trunk/drivers/usb/host/isp1760-hcd.h | 206 -- trunk/drivers/usb/host/isp1760-if.c | 298 -- trunk/drivers/usb/host/ohci-hub.c | 2 +- trunk/drivers/usb/host/uhci-hcd.c | 74 +- trunk/drivers/usb/host/uhci-hcd.h | 5 +- trunk/drivers/usb/misc/ldusb.c | 28 +- trunk/drivers/usb/misc/usbtest.c | 276 +- trunk/drivers/usb/serial/aircable.c | 98 +- trunk/drivers/usb/serial/airprime.c | 63 +- trunk/drivers/usb/serial/ark3116.c | 54 +- trunk/drivers/usb/serial/ch341.c | 2 +- trunk/drivers/usb/serial/ftdi_sio.c | 8 - trunk/drivers/usb/serial/ftdi_sio.h | 11 - trunk/drivers/usb/serial/mos7840.c | 5 +- trunk/drivers/usb/storage/Kconfig | 3 +- trunk/drivers/usb/storage/libusual.c | 2 +- trunk/drivers/usb/storage/onetouch.c | 4 +- trunk/drivers/usb/storage/unusual_devs.h | 28 +- trunk/drivers/usb/storage/usb.c | 3 +- trunk/drivers/virtio/virtio.c | 38 +- trunk/drivers/virtio/virtio_balloon.c | 12 +- trunk/drivers/virtio/virtio_pci.c | 34 +- trunk/drivers/virtio/virtio_ring.c | 5 - trunk/fs/autofs4/expire.c | 26 +- trunk/fs/autofs4/root.c | 38 +- trunk/fs/autofs4/waitq.c | 2 +- trunk/fs/fuse/file.c | 2 +- trunk/fs/jffs2/build.c | 31 +- trunk/fs/jffs2/dir.c | 42 +- trunk/fs/jffs2/erase.c | 9 +- trunk/fs/jffs2/fs.c | 14 +- trunk/fs/jffs2/gc.c | 8 +- trunk/fs/jffs2/nodelist.h | 5 +- trunk/fs/jffs2/nodemgmt.c | 2 +- trunk/fs/jffs2/os-linux.h | 2 +- trunk/fs/jffs2/readinode.c | 16 +- trunk/fs/jffs2/scan.c | 9 +- trunk/fs/jffs2/super.c | 15 +- trunk/fs/jffs2/wbuf.c | 2 +- trunk/fs/jffs2/write.c | 17 +- trunk/fs/jffs2/xattr.c | 4 +- trunk/fs/utimes.c | 17 +- trunk/include/asm-arm/div64.h | 2 + trunk/include/asm-frv/unaligned.h | 6 +- trunk/include/asm-generic/div64.h | 7 + trunk/include/asm-ia64/cpu.h | 2 +- trunk/include/asm-ia64/dmi.h | 5 - trunk/include/asm-ia64/io.h | 5 + trunk/include/asm-ia64/thread_info.h | 13 +- trunk/include/asm-m68k/div64.h | 1 + trunk/include/asm-m68knommu/dma.h | 3 +- trunk/include/asm-m68knommu/param.h | 7 +- trunk/include/asm-mips/div64.h | 6 + trunk/include/asm-mn10300/div64.h | 3 + trunk/include/asm-um/div64.h | 1 + trunk/include/asm-x86/div64.h | 34 +- trunk/include/asm-x86/dmi.h | 1 - trunk/include/asm-x86/io_32.h | 5 + trunk/include/crypto/scatterwalk.h | 4 - trunk/include/linux/Kbuild | 5 - trunk/include/linux/calc64.h | 49 + trunk/include/linux/clocksource.h | 2 - trunk/include/linux/compat.h | 3 +- trunk/include/linux/device.h | 8 +- trunk/include/linux/irq.h | 1 - trunk/include/linux/jiffies.h | 2 +- trunk/include/linux/math64.h | 84 - trunk/include/linux/module.h | 19 +- trunk/include/linux/mtd/jedec.h | 66 + trunk/include/linux/mtd/mtd.h | 6 +- trunk/include/linux/mtd/pmc551.h | 5 +- trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/quota.h | 3 - trunk/include/linux/string.h | 2 - trunk/include/linux/sysfs.h | 6 - trunk/include/linux/timex.h | 46 +- trunk/include/linux/usb/c67x00.h | 48 - trunk/include/linux/usb/ch9.h | 12 +- trunk/include/linux/usb/gadget.h | 21 - trunk/include/linux/virtio.h | 7 - trunk/include/linux/virtio_blk.h | 14 +- trunk/include/linux/virtio_config.h | 81 +- trunk/include/linux/virtio_net.h | 13 +- trunk/kernel/compat.c | 3 +- trunk/kernel/irq/manage.c | 49 +- trunk/kernel/irq/spurious.c | 4 +- trunk/kernel/kexec.c | 2 +- trunk/kernel/module.c | 319 +-- trunk/kernel/posix-cpu-timers.c | 11 +- trunk/kernel/ptrace.c | 2 + trunk/kernel/sched.c | 6 +- trunk/kernel/sched_debug.c | 4 +- trunk/kernel/softirq.c | 20 +- trunk/kernel/time.c | 54 +- trunk/kernel/time/ntp.c | 398 ++- trunk/kernel/time/timekeeping.c | 17 +- trunk/kernel/workqueue.c | 6 +- trunk/lib/div64.c | 35 +- trunk/lib/idr.c | 2 +- trunk/lib/string.c | 27 - trunk/mm/memcontrol.c | 11 - trunk/mm/slub.c | 9 +- trunk/mm/vmalloc.c | 1 - trunk/net/ipv4/tcp_cubic.c | 4 +- trunk/net/netfilter/xt_connbytes.c | 5 +- .../kconfig/lxdialog/check-lxdialog.sh | 6 +- 233 files changed, 2760 insertions(+), 11263 deletions(-) create mode 100644 trunk/arch/m32r/defconfig delete mode 100644 trunk/drivers/usb/c67x00/Makefile delete mode 100644 trunk/drivers/usb/c67x00/c67x00-drv.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00-hcd.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00-hcd.h delete mode 100644 trunk/drivers/usb/c67x00/c67x00-ll-hpi.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00-sched.c delete mode 100644 trunk/drivers/usb/c67x00/c67x00.h delete mode 100644 trunk/drivers/usb/gadget/pxa27x_udc.c delete mode 100644 trunk/drivers/usb/gadget/pxa27x_udc.h delete mode 100644 trunk/drivers/usb/host/isp1760-hcd.c delete mode 100644 trunk/drivers/usb/host/isp1760-hcd.h delete mode 100644 trunk/drivers/usb/host/isp1760-if.c create mode 100644 trunk/include/linux/calc64.h delete mode 100644 trunk/include/linux/math64.h create mode 100644 trunk/include/linux/mtd/jedec.h delete mode 100644 trunk/include/linux/usb/c67x00.h diff --git a/[refs] b/[refs] index 43754a94fe87..ae321031c56e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1be1d6b7f3f6e3a87f872dd5e7a867d03d8a6851 +refs/heads/master: 74d92abc6143b124db03f0d341f02bde72fba6f5 diff --git a/trunk/Documentation/hwmon/w83l785ts b/trunk/Documentation/hwmon/w83l785ts index bd1fa9d4468d..1841cedc25b2 100644 --- a/trunk/Documentation/hwmon/w83l785ts +++ b/trunk/Documentation/hwmon/w83l785ts @@ -33,8 +33,7 @@ Known Issues ------------ On some systems (Asus), the BIOS is known to interfere with the driver -and cause read errors. Or maybe the W83L785TS-S chip is simply unreliable, -we don't really know. The driver will retry a given number of times +and cause read errors. The driver will retry a given number of times (5 by default) and then give up, returning the old value (or 0 if there is no old value). It seems to work well enough so that you should not notice anything. Thanks to James Bolt for helping test this feature. diff --git a/trunk/Documentation/kdump/kdump.txt b/trunk/Documentation/kdump/kdump.txt index b8e52c0355d3..d0ac72cc19ff 100644 --- a/trunk/Documentation/kdump/kdump.txt +++ b/trunk/Documentation/kdump/kdump.txt @@ -245,8 +245,6 @@ The syntax is: crashkernel=:[,:,...][@offset] range=start-[end] - 'start' is inclusive and 'end' is exclusive. - For example: crashkernel=512M-2G:64M,2G-:128M @@ -255,11 +253,10 @@ This would mean: 1) if the RAM is smaller than 512M, then don't reserve anything (this is the "rescue" case) - 2) if the RAM size is between 512M and 2G (exclusive), then reserve 64M + 2) if the RAM size is between 512M and 2G, then reserve 64M 3) if the RAM size is larger than 2G, then reserve 128M - Boot into System Kernel ======================= diff --git a/trunk/Documentation/lguest/lguest.c b/trunk/Documentation/lguest/lguest.c index 3be8ab2a886a..4c1fc65a8b3d 100644 --- a/trunk/Documentation/lguest/lguest.c +++ b/trunk/Documentation/lguest/lguest.c @@ -131,9 +131,6 @@ struct device /* Any queues attached to this device */ struct virtqueue *vq; - /* Handle status being finalized (ie. feature bits stable). */ - void (*ready)(struct device *me); - /* Device-specific data. */ void *priv; }; @@ -928,40 +925,24 @@ static void enable_fd(int fd, struct virtqueue *vq) write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); } -/* When the Guest tells us they updated the status field, we handle it. */ -static void update_device_status(struct device *dev) +/* When the Guest asks us to reset a device, it's is fairly easy. */ +static void reset_device(struct device *dev) { struct virtqueue *vq; - /* This is a reset. */ - if (dev->desc->status == 0) { - verbose("Resetting device %s\n", dev->name); + verbose("Resetting device %s\n", dev->name); + /* Clear the status. */ + dev->desc->status = 0; - /* Clear any features they've acked. */ - memset(get_feature_bits(dev) + dev->desc->feature_len, 0, - dev->desc->feature_len); + /* Clear any features they've acked. */ + memset(get_feature_bits(dev) + dev->desc->feature_len, 0, + dev->desc->feature_len); - /* Zero out the virtqueues. */ - for (vq = dev->vq; vq; vq = vq->next) { - memset(vq->vring.desc, 0, - vring_size(vq->config.num, getpagesize())); - vq->last_avail_idx = 0; - } - } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { - warnx("Device %s configuration FAILED", dev->name); - } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { - unsigned int i; - - verbose("Device %s OK: offered", dev->name); - for (i = 0; i < dev->desc->feature_len; i++) - verbose(" %08x", get_feature_bits(dev)[i]); - verbose(", accepted"); - for (i = 0; i < dev->desc->feature_len; i++) - verbose(" %08x", get_feature_bits(dev) - [dev->desc->feature_len+i]); - - if (dev->ready) - dev->ready(dev); + /* Zero out the virtqueues. */ + for (vq = dev->vq; vq; vq = vq->next) { + memset(vq->vring.desc, 0, + vring_size(vq->config.num, getpagesize())); + vq->last_avail_idx = 0; } } @@ -973,9 +954,9 @@ static void handle_output(int fd, unsigned long addr) /* Check each device and virtqueue. */ for (i = devices.dev; i; i = i->next) { - /* Notifications to device descriptors update device status. */ + /* Notifications to device descriptors reset the device. */ if (from_guest_phys(addr) == i->desc) { - update_device_status(i); + reset_device(i); return; } @@ -1189,7 +1170,6 @@ static struct device *new_device(const char *name, u16 type, int fd, dev->handle_input = handle_input; dev->name = name; dev->vq = NULL; - dev->ready = NULL; /* Append to device list. Prepending to a single-linked list is * easier, but the user expects the devices to be arranged on the bus @@ -1418,7 +1398,7 @@ static bool service_io(struct device *dev) struct vblk_info *vblk = dev->priv; unsigned int head, out_num, in_num, wlen; int ret; - u8 *in; + struct virtio_blk_inhdr *in; struct virtio_blk_outhdr *out; struct iovec iov[dev->vq->vring.num]; off64_t off; @@ -1436,7 +1416,7 @@ static bool service_io(struct device *dev) head, out_num, in_num); out = convert(&iov[0], struct virtio_blk_outhdr); - in = convert(&iov[out_num+in_num-1], u8); + in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr); off = out->sector * 512; /* The block device implements "barriers", where the Guest indicates @@ -1450,7 +1430,7 @@ static bool service_io(struct device *dev) * 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 = VIRTIO_BLK_S_UNSUPP; + in->status = VIRTIO_BLK_S_UNSUPP; wlen = sizeof(*in); } else if (out->type & VIRTIO_BLK_T_OUT) { /* Write */ @@ -1473,7 +1453,7 @@ static bool service_io(struct device *dev) errx(1, "Write past end %llu+%u", off, ret); } wlen = sizeof(*in); - *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); + in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); } else { /* Read */ @@ -1486,10 +1466,10 @@ static bool service_io(struct device *dev) verbose("READ from sector %llu: %i\n", out->sector, ret); if (ret >= 0) { wlen = sizeof(*in) + ret; - *in = VIRTIO_BLK_S_OK; + in->status = VIRTIO_BLK_S_OK; } else { wlen = sizeof(*in); - *in = VIRTIO_BLK_S_IOERR; + in->status = VIRTIO_BLK_S_IOERR; } } diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 93547d3d04b9..c3a533d5d382 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1196,9 +1196,9 @@ S: Maintained CPUSETS P: Paul Jackson -P: Paul Menage +P: Simon Derr M: pj@sgi.com -M: menage@google.com +M: simon.derr@bull.net L: linux-kernel@vger.kernel.org W: http://www.bullopensource.org/cpuset/ S: Supported @@ -1557,14 +1557,6 @@ M: raisch@de.ibm.com L: general@lists.openfabrics.org S: Supported -EMBEDDED LINUX -P: Paul Gortmaker -M: paul.gortmaker@windriver.com -P David Woodhouse -M: dwmw2@infradead.org -L: linux-embedded@vger.kernel.org -S: Maintained - EMULEX LPFC FC SCSI DRIVER P: James Smart M: james.smart@emulex.com @@ -4051,12 +4043,6 @@ L: linux-usb@vger.kernel.org S: Maintained W: http://www.kroah.com/linux-usb/ -USB CYPRESS C67X00 DRIVER -P: Peter Korsgaard -M: jacmet@sunsite.dk -L: linux-usb@vger.kernel.org -S: Maintained - USB DAVICOM DM9601 DRIVER P: Peter Korsgaard M: jacmet@sunsite.dk diff --git a/trunk/Makefile b/trunk/Makefile index 5cf825819533..d3634cd6fe35 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -794,7 +794,7 @@ endif # ifdef CONFIG_KALLSYMS quiet_cmd_vmlinux-modpost = LD $@ cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@ \ $(vmlinux-init) --start-group $(vmlinux-main) --end-group \ - $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^) + $(filter-out $(vmlinux-init) $(vmlinux-main) $(vmlinux-lds) FORCE ,$^) define rule_vmlinux-modpost : +$(call cmd,vmlinux-modpost) @@ -818,9 +818,7 @@ endif ifdef CONFIG_KALLSYMS .tmp_vmlinux1: vmlinux.o endif - -modpost-init := $(filter-out init/built-in.o, $(vmlinux-init)) -vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE +vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE $(call if_changed_rule,vmlinux-modpost) # The actual objects are generated when descending, diff --git a/trunk/arch/frv/mm/Makefile b/trunk/arch/frv/mm/Makefile index 1bca5ab8a6ab..fb8b1d860f46 100644 --- a/trunk/arch/frv/mm/Makefile +++ b/trunk/arch/frv/mm/Makefile @@ -6,4 +6,4 @@ obj-y := init.o kmap.o obj-$(CONFIG_MMU) += \ pgalloc.o highmem.o fault.o extable.o cache-page.o tlb-flush.o tlb-miss.o \ - mmu-context.o dma-alloc.o elf-fdpic.o + mmu-context.o dma-alloc.o unaligned.o elf-fdpic.o diff --git a/trunk/arch/ia64/ia32/ia32_signal.c b/trunk/arch/ia64/ia32/ia32_signal.c index b763ca19ef17..256a7faeda07 100644 --- a/trunk/arch/ia64/ia32/ia32_signal.c +++ b/trunk/arch/ia64/ia32/ia32_signal.c @@ -463,7 +463,7 @@ sys32_sigsuspend (int history0, int history1, old_sigset_t mask) current->state = TASK_INTERRUPTIBLE; schedule(); - set_restore_sigmask(); + set_thread_flag(TIF_RESTORE_SIGMASK); return -ERESTARTNOHAND; } diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 19709a079635..c7467f863c7a 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -966,7 +966,7 @@ acpi_map_iosapics (void) fs_initcall(acpi_map_iosapics); #endif /* CONFIG_ACPI_NUMA */ -int __ref acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) { int err; diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 7fd18f54c056..6dee579f205f 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -183,10 +183,10 @@ void fixup_irqs(void) { unsigned int irq; extern void ia64_process_pending_intr(void); + extern void ia64_disable_timer(void); extern volatile int time_keeper_id; - /* Mask ITV to disable timer */ - ia64_set_itv(1 << 16); + ia64_disable_timer(); /* * Find a new timesync master diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 4547a2092af9..396004e8cd14 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -1053,7 +1053,7 @@ static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __refdata palinfo_cpu_notifier = +static struct notifier_block palinfo_cpu_notifier __cpuinitdata = { .notifier_call = palinfo_cpu_callback, .priority = 0, diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c index 19c5a78636fc..5740296c35af 100644 --- a/trunk/arch/ia64/kernel/signal.c +++ b/trunk/arch/ia64/kernel/signal.c @@ -464,7 +464,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) if (!user_mode(&scr->pt)) return; - if (current_thread_info()->status & TS_RESTORE_SIGMASK) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; @@ -530,13 +530,12 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) * continue to iterate in this loop so we can deliver the SIGSEGV... */ if (handle_signal(signr, &ka, &info, oldset, scr)) { - /* - * A signal was successfully delivered; the saved + /* a signal was successfully delivered; the saved * sigmask will have been stored in the signal frame, * and will be restored by sigreturn, so we can simply - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + * clear the TIF_RESTORE_SIGMASK flag */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); return; } } @@ -567,8 +566,8 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (current_thread_info()->status & TS_RESTORE_SIGMASK) { - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c index 983296f1c813..9a9d4c489330 100644 --- a/trunk/arch/ia64/kernel/smp.c +++ b/trunk/arch/ia64/kernel/smp.c @@ -98,33 +98,8 @@ unlock_ipi_calllock(void) spin_unlock_irq(&call_lock); } -static inline void -handle_call_data(void) -{ - struct call_data_struct *data; - void (*func)(void *info); - void *info; - int wait; - - /* release the 'pointer lock' */ - data = (struct call_data_struct *)call_data; - func = data->func; - info = data->info; - wait = data->wait; - - mb(); - atomic_inc(&data->started); - /* At this point the structure may be gone unless wait is true. */ - (*func)(info); - - /* Notify the sending CPU that the task is done. */ - mb(); - if (wait) - atomic_inc(&data->finished); -} - static void -stop_this_cpu(void) +stop_this_cpu (void) { /* * Remove this CPU: @@ -163,21 +138,44 @@ handle_IPI (int irq, void *dev_id) ops &= ~(1 << which); switch (which) { - case IPI_CALL_FUNC: - handle_call_data(); - break; - - case IPI_CPU_STOP: + case IPI_CALL_FUNC: + { + struct call_data_struct *data; + void (*func)(void *info); + void *info; + int wait; + + /* release the 'pointer lock' */ + data = (struct call_data_struct *) call_data; + func = data->func; + info = data->info; + wait = data->wait; + + mb(); + atomic_inc(&data->started); + /* + * At this point the structure may be gone unless + * wait is true. + */ + (*func)(info); + + /* Notify the sending CPU that the task is done. */ + mb(); + if (wait) + atomic_inc(&data->finished); + } + break; + + case IPI_CPU_STOP: stop_this_cpu(); break; #ifdef CONFIG_KEXEC - case IPI_KDUMP_CPU_STOP: + case IPI_KDUMP_CPU_STOP: unw_init_running(kdump_cpu_freeze, NULL); break; #endif - default: - printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", - this_cpu, which); + default: + printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); break; } } while (ops); diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 8c73643f2d66..48e15a51782f 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -379,6 +379,11 @@ static struct irqaction timer_irqaction = { .name = "timer" }; +void __devinit ia64_disable_timer(void) +{ + ia64_set_itv(1 << 16); +} + void __init time_init (void) { diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 26228e2d01ae..abb17a613b17 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -36,11 +36,9 @@ void arch_fix_phys_package_id(int num, u32 slot) } EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); - -#ifdef CONFIG_HOTPLUG_CPU -int __ref arch_register_cpu(int num) +int arch_register_cpu(int num) { -#ifdef CONFIG_ACPI +#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* * If CPEI can be re-targetted or if this is not * CPEI target, then it is hotpluggable @@ -49,21 +47,19 @@ int __ref arch_register_cpu(int num) sysfs_cpus[num].cpu.hotpluggable = 1; map_cpu_to_node(num, node_cpuid[num].nid); #endif + return register_cpu(&sysfs_cpus[num].cpu, num); } -EXPORT_SYMBOL(arch_register_cpu); + +#ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { unregister_cpu(&sysfs_cpus[num].cpu); unmap_cpu_from_node(num, cpu_to_node(num)); } +EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); -#else -static int __init arch_register_cpu(int num) -{ - return register_cpu(&sysfs_cpus[num].cpu, num); -} #endif /*CONFIG_HOTPLUG_CPU*/ diff --git a/trunk/arch/ia64/kvm/kvm-ia64.c b/trunk/arch/ia64/kvm/kvm-ia64.c index 318b81100623..6df073240135 100644 --- a/trunk/arch/ia64/kvm/kvm-ia64.c +++ b/trunk/arch/ia64/kvm/kvm-ia64.c @@ -1,3 +1,4 @@ + /* * kvm_ia64.c: Basic KVM suppport On Itanium series processors * @@ -430,7 +431,7 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) if (itc_diff < 0) itc_diff = -itc_diff; - expires = div64_u64(itc_diff, cyc_per_usec); + expires = div64_64(itc_diff, cyc_per_usec); kt = ktime_set(0, 1000 * expires); vcpu->arch.ht_active = 1; hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); diff --git a/trunk/arch/m32r/Makefile b/trunk/arch/m32r/Makefile index 469766b24e22..4072a07ebf8e 100644 --- a/trunk/arch/m32r/Makefile +++ b/trunk/arch/m32r/Makefile @@ -5,8 +5,6 @@ # architecture-specific flags and dependencies. # -KBUILD_DEFCONFIG := m32700ut.smp_defconfig - LDFLAGS := OBJCOPYFLAGS := -O binary -R .note -R .comment -S LDFLAGS_vmlinux := diff --git a/trunk/arch/m32r/defconfig b/trunk/arch/m32r/defconfig new file mode 100644 index 000000000000..af3b98179113 --- /dev/null +++ b/trunk/arch/m32r/defconfig @@ -0,0 +1,863 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc1 +# Wed Aug 1 17:22:35 2007 +# +CONFIG_M32R=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_NO_IOPORT=y +CONFIG_NO_DMA=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_CPUSETS is not set +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y +# CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# +# Processor type and features +# +# CONFIG_PLAT_MAPPI is not set +# CONFIG_PLAT_USRV is not set +CONFIG_PLAT_M32700UT=y +# CONFIG_PLAT_OPSPUT is not set +# CONFIG_PLAT_OAKS32R is not set +# CONFIG_PLAT_MAPPI2 is not set +# CONFIG_PLAT_MAPPI3 is not set +# CONFIG_PLAT_M32104UT is not set +CONFIG_CHIP_M32700=y +# CONFIG_CHIP_M32102 is not set +# CONFIG_CHIP_M32104 is not set +# CONFIG_CHIP_VDEC2 is not set +# CONFIG_CHIP_OPSP is not set +CONFIG_MMU=y +CONFIG_TLB_ENTRIES=32 +CONFIG_ISA_M32R2=y +CONFIG_ISA_DSP_LEVEL2=y +CONFIG_ISA_DUAL_ISSUE=y +CONFIG_BUS_CLOCK=50000000 +CONFIG_TIMER_DIVIDE=128 +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_MEMORY_START=0x08000000 +CONFIG_MEMORY_SIZE=0x01000000 +CONFIG_NOHIGHMEM=y +CONFIG_ARCH_DISCONTIGMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +CONFIG_DISCONTIGMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_DISCONTIGMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_NEED_MULTIPLE_NODES=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_IRAM_START=0x00f00000 +CONFIG_IRAM_SIZE=0x00080000 +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_PREEMPT=y +CONFIG_SMP=y +# CONFIG_CHIP_M32700_TS1 is not set +CONFIG_NR_CPUS=2 +CONFIG_NODES_SHIFT=1 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_ISA is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_NOSWAP is not set +CONFIG_MTD_CFI_BE_BYTE_SWAP=y +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=m +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +# CONFIG_IDE_ARM is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_NE2000 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_M32R_SIO=y +CONFIG_SERIAL_M32R_SIO_CONSOLE=y +CONFIG_SERIAL_M32R_PLDSIO=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_RTC is not set +CONFIG_DS1302=y +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +# CONFIG_VIDEO_CPIA is not set +CONFIG_VIDEO_M32R_AR=m +CONFIG_VIDEO_M32R_AR_M64278=m +CONFIG_RADIO_ADAPTERS=y +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB_DDC is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_S1D13XXX=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_LOGO_M32R_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_USB_SUPPORT=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set +CONFIG_MMC=y +CONFIG_MMC_DEBUG=y +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_NEW_LEDS is not set + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +CONFIG_JBD_DEBUG=y +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y diff --git a/trunk/arch/m32r/kernel/vmlinux.lds.S b/trunk/arch/m32r/kernel/vmlinux.lds.S index 15a6f36c06db..41b07854fcc6 100644 --- a/trunk/arch/m32r/kernel/vmlinux.lds.S +++ b/trunk/arch/m32r/kernel/vmlinux.lds.S @@ -60,6 +60,9 @@ SECTIONS . = ALIGN(4096); __nosave_end = .; + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff --git a/trunk/arch/m68knommu/kernel/asm-offsets.c b/trunk/arch/m68knommu/kernel/asm-offsets.c index c785d07c02cc..fd0c685a7f11 100644 --- a/trunk/arch/m68knommu/kernel/asm-offsets.c +++ b/trunk/arch/m68knommu/kernel/asm-offsets.c @@ -87,7 +87,6 @@ int main(void) DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); return 0; diff --git a/trunk/arch/m68knommu/kernel/entry.S b/trunk/arch/m68knommu/kernel/entry.S index f4782d2dce8f..1e7ea6a3e1a1 100644 --- a/trunk/arch/m68knommu/kernel/entry.S +++ b/trunk/arch/m68knommu/kernel/entry.S @@ -32,7 +32,6 @@ #include #include #include -#include .text @@ -141,11 +140,3 @@ ENTRY(sys_rt_sigreturn) RESTORE_SWITCH_STACK rts -ENTRY(ret_from_user_signal) - moveq #__NR_sigreturn,%d0 - trap #0 - -ENTRY(ret_from_user_rt_signal) - move #__NR_rt_sigreturn,%d0 - trap #0 - diff --git a/trunk/arch/m68knommu/kernel/setup.c b/trunk/arch/m68knommu/kernel/setup.c index 03f4fe6a2fc0..d6f0200316fe 100644 --- a/trunk/arch/m68knommu/kernel/setup.c +++ b/trunk/arch/m68knommu/kernel/setup.c @@ -162,7 +162,7 @@ void __init setup_arch(char **cmdline_p) printk(KERN_INFO "DragonEngine II board support by Georges Menie\n"); #endif #ifdef CONFIG_M5235EVB - printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n"); + printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)"); #endif #ifdef DEBUG diff --git a/trunk/arch/m68knommu/kernel/signal.c b/trunk/arch/m68knommu/kernel/signal.c index bbfcae9e52b4..70371378db86 100644 --- a/trunk/arch/m68knommu/kernel/signal.c +++ b/trunk/arch/m68knommu/kernel/signal.c @@ -51,8 +51,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -void ret_from_user_signal(void); -void ret_from_user_rt_signal(void); asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); /* @@ -541,6 +539,10 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) return err; } +static inline void push_cache (unsigned long vaddr) +{ +} + static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) { @@ -584,11 +586,16 @@ static void setup_frame (int sig, struct k_sigaction *ka, err |= copy_to_user (&frame->sc, &context, sizeof(context)); /* Set up to return from userspace. */ - err |= __put_user((void *) ret_from_user_signal, &frame->pretcode); + err |= __put_user(frame->retcode, &frame->pretcode); + /* moveq #,d0; trap #0 */ + err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), + (long *)(frame->retcode)); if (err) goto give_sigsegv; + push_cache ((unsigned long) &frame->retcode); + /* Set up registers for signal handler */ wrusp ((unsigned long) frame); regs->pc = (unsigned long) ka->sa.sa_handler; @@ -648,11 +655,17 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); /* Set up to return from userspace. */ - err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode); + err |= __put_user(frame->retcode, &frame->pretcode); + /* moveq #,d0; notb d0; trap #0 */ + err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), + (long *)(frame->retcode + 0)); + err |= __put_user(0x4e40, (short *)(frame->retcode + 4)); if (err) goto give_sigsegv; + push_cache ((unsigned long) &frame->retcode); + /* Set up registers for signal handler */ wrusp ((unsigned long) frame); regs->pc = (unsigned long) ka->sa.sa_handler; diff --git a/trunk/arch/m68knommu/kernel/traps.c b/trunk/arch/m68knommu/kernel/traps.c index ec9aea652e79..437a061d8b94 100644 --- a/trunk/arch/m68knommu/kernel/traps.c +++ b/trunk/arch/m68knommu/kernel/traps.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -103,47 +102,56 @@ asmlinkage void buserr_c(struct frame *fp) force_sig(SIGSEGV, current); } + int kstack_depth_to_print = 48; -static void __show_stack(struct task_struct *task, unsigned long *stack) +void show_stack(struct task_struct *task, unsigned long *stack) { unsigned long *endstack, addr; - unsigned long *last_stack; + extern char _start, _etext; int i; - if (!stack) - stack = (unsigned long *)task->thread.ksp; + if (!stack) { + if (task) + stack = (unsigned long *)task->thread.ksp; + else + stack = (unsigned long *)&stack; + } addr = (unsigned long) stack; endstack = (unsigned long *) PAGE_ALIGN(addr); printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack); for (i = 0; i < kstack_depth_to_print; i++) { - if (stack + 1 + i > endstack) + if (stack + 1 > endstack) break; if (i % 8 == 0) printk("\n" KERN_EMERG " "); - printk(" %08lx", *(stack + i)); + printk(" %08lx", *stack++); } printk("\n"); -#ifdef CONFIG_FRAME_POINTER - printk(KERN_EMERG "Call Trace:\n"); - - last_stack = stack - 1; - while (stack <= endstack && stack > last_stack) { - - addr = *(stack + 1); - printk(KERN_EMERG " [%08lx] ", addr); - print_symbol(KERN_CONT "%s\n", addr); - - last_stack = stack; - stack = (unsigned long *)*stack; + printk(KERN_EMERG "Call Trace:"); + i = 0; + while (stack + 1 <= endstack) { + addr = *stack++; + /* + * If the address is either in the text segment of the + * kernel, or in the region which contains vmalloc'ed + * memory, it *may* be the address of a calling + * routine; if so, print it so that someone tracing + * down the cause of the crash will be able to figure + * out the call path that was taken. + */ + if (((addr >= (unsigned long) &_start) && + (addr <= (unsigned long) &_etext))) { + if (i % 4 == 0) + printk("\n" KERN_EMERG " "); + printk(" [<%08lx>]", addr); + i++; + } } printk("\n"); -#else - printk(KERN_EMERG "CONFIG_FRAME_POINTER disabled, no symbolic call trace\n"); -#endif } void bad_super_trap(struct frame *fp) @@ -290,46 +298,18 @@ asmlinkage void set_esp0(unsigned long ssp) current->thread.esp0 = ssp; } + /* * The architecture-independent backtrace generator */ void dump_stack(void) { - /* - * We need frame pointers for this little trick, which works as follows: - * - * +------------+ 0x00 - * | Next SP | -> 0x0c - * +------------+ 0x04 - * | Caller | - * +------------+ 0x08 - * | Local vars | -> our stack var - * +------------+ 0x0c - * | Next SP | -> 0x18, that is what we pass to show_stack() - * +------------+ 0x10 - * | Caller | - * +------------+ 0x14 - * | Local vars | - * +------------+ 0x18 - * | ... | - * +------------+ - */ + unsigned long stack; - unsigned long *stack; - - stack = (unsigned long *)&stack; - stack++; - __show_stack(current, stack); + show_stack(current, &stack); } -EXPORT_SYMBOL(dump_stack); -void show_stack(struct task_struct *task, unsigned long *stack) -{ - if (!stack && !task) - dump_stack(); - else - __show_stack(task, stack); -} +EXPORT_SYMBOL(dump_stack); #ifdef CONFIG_M68KFPU_EMU asmlinkage void fpemu_signal(int signal, int code, void *addr) diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 5592e0bf951f..b44edb08e212 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -64,7 +64,6 @@ SECTIONS { _stext = . ; TEXT_TEXT SCHED_TEXT - LOCK_TEXT *(.text.lock) . = ALIGN(16); /* Exception table */ @@ -74,7 +73,6 @@ SECTIONS { *(.rodata) *(.rodata.*) *(__vermagic) /* Kernel version magic */ - *(__markers_strings) *(.rodata1) *(.rodata.str1.1) @@ -184,7 +182,6 @@ SECTIONS { *(COMMON) . = ALIGN(4) ; _ebss = . ; - _end = . ; } > BSS } diff --git a/trunk/arch/m68knommu/platform/5206e/config.c b/trunk/arch/m68knommu/platform/5206e/config.c index d01a5d2b7557..a6692e958f6b 100644 --- a/trunk/arch/m68knommu/platform/5206e/config.c +++ b/trunk/arch/m68knommu/platform/5206e/config.c @@ -48,7 +48,7 @@ static struct platform_device *m5206e_devices[] __initdata = { /***************************************************************************/ -static void __init m5206e_uart_init_line(int line, int irq) +static void __init m5206_uart_init_line(int line, int irq) { if (line == 0) { writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); diff --git a/trunk/arch/m68knommu/platform/5272/config.c b/trunk/arch/m68knommu/platform/5272/config.c index 230bae691a7f..2aca599a1ca7 100644 --- a/trunk/arch/m68knommu/platform/5272/config.c +++ b/trunk/arch/m68knommu/platform/5272/config.c @@ -139,6 +139,10 @@ void __init config_BSP(char *commandp, int size) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); commandp[size-1] = 0; +#elif defined(CONFIG_MTD_KeyTechnology) + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xffe06000, size); + commandp[size-1] = 0; #elif defined(CONFIG_CANCam) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0010000, size); diff --git a/trunk/arch/m68knommu/platform/528x/config.c b/trunk/arch/m68knommu/platform/528x/config.c index dfdb5c2ed8e6..036e1b73d944 100644 --- a/trunk/arch/m68knommu/platform/528x/config.c +++ b/trunk/arch/m68knommu/platform/528x/config.c @@ -26,240 +26,9 @@ #include #include -#ifdef CONFIG_MTD_PARTITIONS -#include -#endif - /***************************************************************************/ void coldfire_reset(void); -static void coldfire_qspi_cs_control(u8 cs, u8 command); - -/***************************************************************************/ - -#if defined(CONFIG_SPI) - -#if defined(CONFIG_WILDFIRE) -#define SPI_NUM_CHIPSELECTS 0x02 -#define SPI_PAR_VAL 0x07 /* Enable DIN, DOUT, CLK */ -#define SPI_CS_MASK 0x18 - -#define FLASH_BLOCKSIZE (1024*64) -#define FLASH_NUMBLOCKS 16 -#define FLASH_TYPE "m25p80" - -#define M25P80_CS 0 -#define MMC_CS 1 - -#ifdef CONFIG_MTD_PARTITIONS -static struct mtd_partition stm25p_partitions[] = { - /* sflash */ - [0] = { - .name = "stm25p80", - .offset = 0x00000000, - .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS, - .mask_flags = 0 - } -}; - -#endif - -#elif defined(CONFIG_WILDFIREMOD) - -#define SPI_NUM_CHIPSELECTS 0x08 -#define SPI_PAR_VAL 0x07 /* Enable DIN, DOUT, CLK */ -#define SPI_CS_MASK 0x78 - -#define FLASH_BLOCKSIZE (1024*64) -#define FLASH_NUMBLOCKS 64 -#define FLASH_TYPE "m25p32" -/* Reserve 1M for the kernel parition */ -#define FLASH_KERNEL_SIZE (1024 * 1024) - -#define M25P80_CS 5 -#define MMC_CS 6 - -#ifdef CONFIG_MTD_PARTITIONS -static struct mtd_partition stm25p_partitions[] = { - /* sflash */ - [0] = { - .name = "kernel", - .offset = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE, - .size = FLASH_KERNEL_SIZE, - .mask_flags = 0 - }, - [1] = { - .name = "image", - .offset = 0x00000000, - .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS - FLASH_KERNEL_SIZE, - .mask_flags = 0 - }, - [2] = { - .name = "all", - .offset = 0x00000000, - .size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS, - .mask_flags = 0 - } -}; -#endif - -#else -#define SPI_NUM_CHIPSELECTS 0x04 -#define SPI_PAR_VAL 0x7F /* Enable DIN, DOUT, CLK, CS0 - CS4 */ -#endif - -#ifdef MMC_CS -static struct coldfire_spi_chip flash_chip_info = { - .mode = SPI_MODE_0, - .bits_per_word = 16, - .del_cs_to_clk = 17, - .del_after_trans = 1, - .void_write_data = 0 -}; - -static struct coldfire_spi_chip mmc_chip_info = { - .mode = SPI_MODE_0, - .bits_per_word = 16, - .del_cs_to_clk = 17, - .del_after_trans = 1, - .void_write_data = 0xFFFF -}; -#endif - -#ifdef M25P80_CS -static struct flash_platform_data stm25p80_platform_data = { - .name = "ST M25P80 SPI Flash chip", -#ifdef CONFIG_MTD_PARTITIONS - .parts = stm25p_partitions, - .nr_parts = sizeof(stm25p_partitions) / sizeof(*stm25p_partitions), -#endif - .type = FLASH_TYPE -}; -#endif - -static struct spi_board_info spi_board_info[] __initdata = { -#ifdef M25P80_CS - { - .modalias = "m25p80", - .max_speed_hz = 16000000, - .bus_num = 1, - .chip_select = M25P80_CS, - .platform_data = &stm25p80_platform_data, - .controller_data = &flash_chip_info - }, -#endif -#ifdef MMC_CS - { - .modalias = "mmc_spi", - .max_speed_hz = 16000000, - .bus_num = 1, - .chip_select = MMC_CS, - .controller_data = &mmc_chip_info - } -#endif -}; - -static struct coldfire_spi_master coldfire_master_info = { - .bus_num = 1, - .num_chipselect = SPI_NUM_CHIPSELECTS, - .irq_source = MCF5282_QSPI_IRQ_SOURCE, - .irq_vector = MCF5282_QSPI_IRQ_VECTOR, - .irq_mask = ((0x01 << MCF5282_QSPI_IRQ_SOURCE) | 0x01), - .irq_lp = 0x2B, /* Level 5 and Priority 3 */ - .par_val = SPI_PAR_VAL, - .cs_control = coldfire_qspi_cs_control, -}; - -static struct resource coldfire_spi_resources[] = { - [0] = { - .name = "qspi-par", - .start = MCF5282_QSPI_PAR, - .end = MCF5282_QSPI_PAR, - .flags = IORESOURCE_MEM - }, - - [1] = { - .name = "qspi-module", - .start = MCF5282_QSPI_QMR, - .end = MCF5282_QSPI_QMR + 0x18, - .flags = IORESOURCE_MEM - }, - - [2] = { - .name = "qspi-int-level", - .start = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE, - .end = MCF5282_INTC0 + MCFINTC_ICR0 + MCF5282_QSPI_IRQ_SOURCE, - .flags = IORESOURCE_MEM - }, - - [3] = { - .name = "qspi-int-mask", - .start = MCF5282_INTC0 + MCFINTC_IMRL, - .end = MCF5282_INTC0 + MCFINTC_IMRL, - .flags = IORESOURCE_MEM - } -}; - -static struct platform_device coldfire_spi = { - .name = "spi_coldfire", - .id = -1, - .resource = coldfire_spi_resources, - .num_resources = ARRAY_SIZE(coldfire_spi_resources), - .dev = { - .platform_data = &coldfire_master_info, - } -}; - -static void coldfire_qspi_cs_control(u8 cs, u8 command) -{ - u8 cs_bit = ((0x01 << cs) << 3) & SPI_CS_MASK; - -#if defined(CONFIG_WILDFIRE) - u8 cs_mask = ~(((0x01 << cs) << 3) & SPI_CS_MASK); -#endif -#if defined(CONFIG_WILDFIREMOD) - u8 cs_mask = (cs << 3) & SPI_CS_MASK; -#endif - - /* - * Don't do anything if the chip select is not - * one of the port qs pins. - */ - if (command & QSPI_CS_INIT) { -#if defined(CONFIG_WILDFIRE) - MCF5282_GPIO_DDRQS |= cs_bit; - MCF5282_GPIO_PQSPAR &= ~cs_bit; -#endif - -#if defined(CONFIG_WILDFIREMOD) - MCF5282_GPIO_DDRQS |= SPI_CS_MASK; - MCF5282_GPIO_PQSPAR &= ~SPI_CS_MASK; -#endif - } - - if (command & QSPI_CS_ASSERT) { - MCF5282_GPIO_PORTQS &= ~SPI_CS_MASK; - MCF5282_GPIO_PORTQS |= cs_mask; - } else if (command & QSPI_CS_DROP) { - MCF5282_GPIO_PORTQS |= SPI_CS_MASK; - } -} - -static int __init spi_dev_init(void) -{ - int retval; - - retval = platform_device_register(&coldfire_spi); - if (retval < 0) - return retval; - - if (ARRAY_SIZE(spi_board_info)) - retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); - - return retval; -} - -#endif /* CONFIG_SPI */ /***************************************************************************/ @@ -342,43 +111,10 @@ void mcf_autovector(unsigned int vec) /***************************************************************************/ -#ifdef CONFIG_WILDFIRE -void wildfire_halt(void) -{ - writeb(0, 0x30000007); - writeb(0x2, 0x30000007); -} -#endif - -#ifdef CONFIG_WILDFIREMOD -void wildfiremod_halt(void) -{ - printk(KERN_INFO "WildFireMod hibernating...\n"); - - /* Set portE.5 to Digital IO */ - MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2)); - - /* Make portE.5 an output */ - MCF5282_GPIO_DDRE |= (1 << 5); - - /* Now toggle portE.5 from low to high */ - MCF5282_GPIO_PORTE &= ~(1 << 5); - MCF5282_GPIO_PORTE |= (1 << 5); - - printk(KERN_EMERG "Failed to hibernate. Halting!\n"); -} -#endif - void __init config_BSP(char *commandp, int size) { mcf_disableall(); - -#ifdef CONFIG_WILDFIRE - mach_halt = wildfire_halt; -#endif -#ifdef CONFIG_WILDFIREMOD - mach_halt = wildfiremod_halt; -#endif + mach_reset = coldfire_reset; } /***************************************************************************/ diff --git a/trunk/arch/m68knommu/platform/5307/config.c b/trunk/arch/m68knommu/platform/5307/config.c index 11cff6625dcc..92dc862fa826 100644 --- a/trunk/arch/m68knommu/platform/5307/config.c +++ b/trunk/arch/m68knommu/platform/5307/config.c @@ -124,7 +124,8 @@ void __init config_BSP(char *commandp, int size) mcf_setimr(MCFSIM_IMR_MASKALL); #if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ - defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) + defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ + defined(CONFIG_CLEOPATRA) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0xf0004000, size); commandp[size-1] = 0; diff --git a/trunk/arch/m68knommu/platform/coldfire/entry.S b/trunk/arch/m68knommu/platform/coldfire/entry.S index 1e3c0dcbd7ac..111b66dc737b 100644 --- a/trunk/arch/m68knommu/platform/coldfire/entry.S +++ b/trunk/arch/m68knommu/platform/coldfire/entry.S @@ -103,26 +103,9 @@ ret_from_signal: addql #4,%sp ret_from_exception: - move #0x2700,%sr /* disable intrs */ btst #5,%sp@(PT_SR) /* check if returning to kernel */ jeq Luser_return /* if so, skip resched, signals */ -#ifdef CONFIG_PREEMPT - movel %sp,%d1 /* get thread_info pointer */ - andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ - movel %d1,%a0 - movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ - andl #_TIF_NEED_RESCHED,%d1 - jeq Lkernel_return - - movel %a0@(TI_PREEMPTCOUNT),%d1 - cmpl #0,%d1 - jne Lkernel_return - - pea Lkernel_return - jmp preempt_schedule_irq /* preempt the kernel */ -#endif - Lkernel_return: moveml %sp@,%d1-%d5/%a0-%a2 lea %sp@(32),%sp /* space for 8 regs */ @@ -157,7 +140,6 @@ Lreturn: Lwork_to_do: movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ - move #0x2000,%sr /* enable intrs again */ btst #TIF_NEED_RESCHED,%d1 jne reschedule diff --git a/trunk/arch/mips/kernel/binfmt_elfn32.c b/trunk/arch/mips/kernel/binfmt_elfn32.c index 9fdd8bcdd21e..77db3473deab 100644 --- a/trunk/arch/mips/kernel/binfmt_elfn32.c +++ b/trunk/arch/mips/kernel/binfmt_elfn32.c @@ -54,7 +54,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #include #include #include -#include #define elf_prstatus elf_prstatus32 struct elf_prstatus32 @@ -103,8 +102,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) * one divide. */ u64 nsec = (u64)jiffies * TICK_NSEC; - u32 rem; - value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem); + long rem; + value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem); value->tv_usec = rem / NSEC_PER_USEC; } diff --git a/trunk/arch/mips/kernel/binfmt_elfo32.c b/trunk/arch/mips/kernel/binfmt_elfo32.c index e1333d7319e2..08f4cd781ee3 100644 --- a/trunk/arch/mips/kernel/binfmt_elfo32.c +++ b/trunk/arch/mips/kernel/binfmt_elfo32.c @@ -56,7 +56,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #include #include #include -#include #define elf_prstatus elf_prstatus32 struct elf_prstatus32 @@ -105,8 +104,8 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) * one divide. */ u64 nsec = (u64)jiffies * TICK_NSEC; - u32 rem; - value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem); + long rem; + value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &rem); value->tv_usec = rem / NSEC_PER_USEC; } diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 73401e83739a..3b26fbd6bec9 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -149,7 +149,7 @@ EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */ u64 tb_to_xs; unsigned tb_to_us; -#define TICKLEN_SCALE NTP_SCALE_SHIFT +#define TICKLEN_SCALE TICK_LENGTH_SHIFT u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */ u64 ticklen_to_xs; /* 0.64 fraction */ @@ -1007,6 +1007,8 @@ void __init time_init(void) vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; vdso_data->tb_to_xs = tb_to_xs; + time_freq = 0; + write_sequnlock_irqrestore(&xtime_lock, flags); /* Register the clocksource, if we're not running on iSeries */ diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index 4c943eabacc3..361e31611276 100644 --- a/trunk/arch/x86/kvm/i8254.c +++ b/trunk/arch/x86/kvm/i8254.c @@ -35,7 +35,7 @@ #include "i8254.h" #ifndef CONFIG_X86_64 -#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) +#define mod_64(x, y) ((x) - (y) * div64_64(x, y)) #else #define mod_64(x, y) ((x) % (y)) #endif @@ -60,8 +60,8 @@ static u64 muldiv64(u64 a, u32 b, u32 c) rl = (u64)u.l.low * (u64)b; rh = (u64)u.l.high * (u64)b; rh += (rl >> 32); - res.l.high = div64_u64(rh, c); - res.l.low = div64_u64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c); + res.l.high = div64_64(rh, c); + res.l.low = div64_64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c); return res.ll; } diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index 36809d79788b..57ac4e4c556a 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -25,13 +25,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include "irq.h" #define PRId64 "d" @@ -526,8 +526,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic) } else passed = ktime_sub(now, apic->timer.last_update); - counter_passed = div64_u64(ktime_to_ns(passed), - (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); + counter_passed = div64_64(ktime_to_ns(passed), + (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); if (counter_passed > tmcct) { if (unlikely(!apic_lvtt_period(apic))) { diff --git a/trunk/block/blk-barrier.c b/trunk/block/blk-barrier.c index a09ead19f9c5..66e55288178c 100644 --- a/trunk/block/blk-barrier.c +++ b/trunk/block/blk-barrier.c @@ -26,7 +26,8 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered, { if (ordered & (QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH) && prepare_flush_fn == NULL) { - printk(KERN_ERR "%s: prepare_flush_fn required\n", __func__); + printk(KERN_ERR "%s: prepare_flush_fn required\n", + __FUNCTION__); return -EINVAL; } diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index b754a4a2f9bd..5d09f8c56024 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -136,7 +136,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio, if (unlikely(nbytes > bio->bi_size)) { printk(KERN_ERR "%s: want %u bytes done, %u left\n", - __func__, nbytes, bio->bi_size); + __FUNCTION__, nbytes, bio->bi_size); nbytes = bio->bi_size; } @@ -1566,7 +1566,8 @@ static int __end_that_request_first(struct request *req, int error, if (unlikely(bio->bi_idx >= bio->bi_vcnt)) { blk_dump_rq_flags(req, "__end_that"); printk(KERN_ERR "%s: bio idx %d >= vcnt %d\n", - __func__, bio->bi_idx, bio->bi_vcnt); + __FUNCTION__, bio->bi_idx, + bio->bi_vcnt); break; } diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index bb93d4c32775..6089384ab064 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -168,8 +168,8 @@ void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors) { if ((max_sectors << 9) < PAGE_CACHE_SIZE) { max_sectors = 1 << (PAGE_CACHE_SHIFT - 9); - printk(KERN_INFO "%s: set to minimum %d\n", - __func__, max_sectors); + printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__, + max_sectors); } if (BLK_DEF_MAX_SECTORS > max_sectors) @@ -196,8 +196,8 @@ void blk_queue_max_phys_segments(struct request_queue *q, { if (!max_segments) { max_segments = 1; - printk(KERN_INFO "%s: set to minimum %d\n", - __func__, max_segments); + printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__, + max_segments); } q->max_phys_segments = max_segments; @@ -220,8 +220,8 @@ void blk_queue_max_hw_segments(struct request_queue *q, { if (!max_segments) { max_segments = 1; - printk(KERN_INFO "%s: set to minimum %d\n", - __func__, max_segments); + printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__, + max_segments); } q->max_hw_segments = max_segments; @@ -241,8 +241,8 @@ void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size) { if (max_size < PAGE_CACHE_SIZE) { max_size = PAGE_CACHE_SIZE; - printk(KERN_INFO "%s: set to minimum %d\n", - __func__, max_size); + printk(KERN_INFO "%s: set to minimum %d\n", __FUNCTION__, + max_size); } q->max_segment_size = max_size; @@ -357,8 +357,8 @@ void blk_queue_segment_boundary(struct request_queue *q, unsigned long mask) { if (mask < PAGE_CACHE_SIZE - 1) { mask = PAGE_CACHE_SIZE - 1; - printk(KERN_INFO "%s: set to minimum %lx\n", - __func__, mask); + printk(KERN_INFO "%s: set to minimum %lx\n", __FUNCTION__, + mask); } q->seg_boundary_mask = mask; diff --git a/trunk/block/blk-tag.c b/trunk/block/blk-tag.c index de64e0429977..e176ddbe599e 100644 --- a/trunk/block/blk-tag.c +++ b/trunk/block/blk-tag.c @@ -112,7 +112,7 @@ init_tag_map(struct request_queue *q, struct blk_queue_tag *tags, int depth) if (q && depth > q->nr_requests * 2) { depth = q->nr_requests * 2; printk(KERN_ERR "%s: adjusted depth to %d\n", - __func__, depth); + __FUNCTION__, depth); } tag_index = kzalloc(depth * sizeof(struct request *), GFP_ATOMIC); @@ -296,13 +296,13 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq) if (unlikely(bqt->tag_index[tag] == NULL)) printk(KERN_ERR "%s: tag %d is missing\n", - __func__, tag); + __FUNCTION__, tag); bqt->tag_index[tag] = NULL; if (unlikely(!test_bit(tag, bqt->tag_map))) { printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n", - __func__, tag); + __FUNCTION__, tag); return; } /* @@ -340,7 +340,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq) if (unlikely((rq->cmd_flags & REQ_QUEUED))) { printk(KERN_ERR "%s: request %p for device [%s] already tagged %d", - __func__, rq, + __FUNCTION__, rq, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag); BUG(); } diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index fa796b605f55..23ea4fd1a66d 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -57,7 +57,7 @@ enum { #undef BSG_DEBUG #ifdef BSG_DEBUG -#define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ##args) +#define dprintk(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ##args) #else #define dprintk(fmt, args...) #endif diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 980f8ae147b4..ac5310ef8270 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -650,7 +650,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) default: printk(KERN_ERR "%s: bad insertion point %d\n", - __func__, where); + __FUNCTION__, where); BUG(); } @@ -808,7 +808,8 @@ struct request *elv_next_request(struct request_queue *q) rq->cmd_flags |= REQ_QUIET; end_queued_request(rq, 0); } else { - printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); + printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__, + ret); break; } } diff --git a/trunk/crypto/authenc.c b/trunk/crypto/authenc.c index 4b226768752a..ed8ac5a6fa5f 100644 --- a/trunk/crypto/authenc.c +++ b/trunk/crypto/authenc.c @@ -217,10 +217,9 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, int err) { if (!err) { - struct aead_request *areq = req->data; - struct skcipher_givcrypt_request *greq = aead_request_ctx(areq); + struct aead_givcrypt_request *greq = req->data; - err = crypto_authenc_genicv(areq, greq->giv, 0); + err = crypto_authenc_genicv(&greq->areq, greq->giv, 0); } aead_request_complete(req->data, err); diff --git a/trunk/crypto/cryptd.c b/trunk/crypto/cryptd.c index b150de562057..250425263e00 100644 --- a/trunk/crypto/cryptd.c +++ b/trunk/crypto/cryptd.c @@ -190,10 +190,8 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg, int err; inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); - if (!inst) { - inst = ERR_PTR(-ENOMEM); + if (IS_ERR(inst)) goto out; - } err = -ENAMETOOLONG; if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, diff --git a/trunk/crypto/eseqiv.c b/trunk/crypto/eseqiv.c index 881d30910434..b14f14e314b6 100644 --- a/trunk/crypto/eseqiv.c +++ b/trunk/crypto/eseqiv.c @@ -136,8 +136,7 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) } ablkcipher_request_set_crypt(subreq, reqctx->src, dst, - req->creq.nbytes + ivsize, - req->creq.info); + req->creq.nbytes, req->creq.info); memcpy(req->creq.info, ctx->salt, ivsize); diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index e38dfed41d80..6fe417429977 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -18,7 +18,7 @@ struct sysdev_class cpu_sysdev_class = { }; EXPORT_SYMBOL(cpu_sysdev_class); -static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices); +static struct sys_device *cpu_sys_devices[NR_CPUS]; #ifdef CONFIG_HOTPLUG_CPU static ssize_t show_online(struct sys_device *dev, char *buf) @@ -68,7 +68,7 @@ void unregister_cpu(struct cpu *cpu) sysdev_remove_file(&cpu->sysdev, &attr_online); sysdev_unregister(&cpu->sysdev); - per_cpu(cpu_sys_devices, logical_cpu) = NULL; + cpu_sys_devices[logical_cpu] = NULL; return; } #else /* ... !CONFIG_HOTPLUG_CPU */ @@ -167,7 +167,7 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) if (!error && cpu->hotpluggable) register_cpu_control(cpu); if (!error) - per_cpu(cpu_sys_devices, num) = &cpu->sysdev; + cpu_sys_devices[num] = &cpu->sysdev; if (!error) register_cpu_under_node(num, cpu_to_node(num)); @@ -180,8 +180,8 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) struct sys_device *get_cpu_sysdev(unsigned cpu) { - if (cpu < nr_cpu_ids && cpu_possible(cpu)) - return per_cpu(cpu_sys_devices, cpu); + if (cpu < NR_CPUS) + return cpu_sys_devices[cpu]; else return NULL; } diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index e336b05fe4a7..e539be5750dc 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -428,9 +428,13 @@ static void __devinit cciss_procinit(int i) proc_cciss = proc_mkdir("driver/cciss", NULL); if (!proc_cciss) return; - pde = proc_create_data(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP | + pde = proc_create(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, proc_cciss, - &cciss_proc_fops, hba[i]); + &cciss_proc_fops); + if (!pde) + return; + + pde->data = hba[i]; } #endif /* CONFIG_PROC_FS */ diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 3a281ef11ffa..e322cce8c12d 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -205,7 +205,6 @@ struct ub_scsi_cmd { unsigned char key, asc, ascq; /* May be valid if error==-EIO */ int stat_count; /* Retries getting status. */ - unsigned int timeo; /* jiffies until rq->timeout changes */ unsigned int len; /* Requested length */ unsigned int current_sg; @@ -319,7 +318,6 @@ struct ub_dev { int openc; /* protected by ub_lock! */ /* kref is too implicit for our taste */ int reset; /* Reset is running */ - int bad_resid; unsigned int tagcnt; char name[12]; struct usb_device *dev; @@ -766,12 +764,6 @@ static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, cmd->cdb_len = rq->cmd_len; cmd->len = rq->data_len; - - /* - * To reapply this to every URB is not as incorrect as it looks. - * In return, we avoid any complicated tracking calculations. - */ - cmd->timeo = rq->timeout; } static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) @@ -793,6 +785,10 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) scsi_status = 0; } else { if (cmd->act_len != cmd->len) { + if ((cmd->key == MEDIUM_ERROR || + cmd->key == UNIT_ATTENTION) && + ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) + return; scsi_status = SAM_STAT_CHECK_CONDITION; } else { scsi_status = 0; @@ -808,10 +804,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) else scsi_status = DID_ERROR << 16; } else { - if (cmd->error == -EIO && - (cmd->key == 0 || - cmd->key == MEDIUM_ERROR || - cmd->key == UNIT_ATTENTION)) { + if (cmd->error == -EIO) { if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) return; } @@ -1266,19 +1259,14 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) return; } - if (!sc->bad_resid) { - len = le32_to_cpu(bcs->Residue); - if (len != cmd->len - cmd->act_len) { - /* - * Only start ignoring if this cmd ended well. - */ - if (cmd->len == cmd->act_len) { - printk(KERN_NOTICE "%s: " - "bad residual %d of %d, ignoring\n", - sc->name, len, cmd->len); - sc->bad_resid = 1; - } - } + len = le32_to_cpu(bcs->Residue); + if (len != cmd->len - cmd->act_len) { + /* + * It is all right to transfer less, the caller has + * to check. But it's not all right if the device + * counts disagree with our counts. + */ + goto Bad_End; } switch (bcs->Status) { @@ -1309,7 +1297,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) ub_state_done(sc, cmd, -EIO); } else { - printk(KERN_WARNING "%s: wrong command state %d\n", + printk(KERN_WARNING "%s: " + "wrong command state %d\n", sc->name, cmd->state); ub_state_done(sc, cmd, -EINVAL); return; @@ -1347,10 +1336,7 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) return; } - if (cmd->timeo) - sc->work_timer.expires = jiffies + cmd->timeo; - else - sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT; + sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT; add_timer(&sc->work_timer); cmd->state = UB_CMDST_DATA; @@ -1390,10 +1376,7 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) return -1; } - if (cmd->timeo) - sc->work_timer.expires = jiffies + cmd->timeo; - else - sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT; + sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT; add_timer(&sc->work_timer); return 0; } @@ -1532,7 +1515,8 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) return; } if (cmd->state != UB_CMDST_SENSE) { - printk(KERN_WARNING "%s: sense done with bad cmd state %d\n", + printk(KERN_WARNING "%s: " + "sense done with bad cmd state %d\n", sc->name, cmd->state); return; } @@ -1736,7 +1720,7 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, } /* - * This is called by check_disk_change if we reported a media change. + * This is called once a new disk was seen by the block layer or by ub_probe(). * The main onjective here is to discover the features of the media such as * the capacity, read-only status, etc. USB storage generally does not * need to be spun up, but if we needed it, this would be the place. @@ -2152,7 +2136,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, } if (ep_in == NULL || ep_out == NULL) { - printk(KERN_NOTICE "%s: failed endpoint check\n", sc->name); + printk(KERN_NOTICE "%s: failed endpoint check\n", + sc->name); return -ENODEV; } @@ -2369,7 +2354,7 @@ static void ub_disconnect(struct usb_interface *intf) spin_unlock_irqrestore(&ub_lock, flags); /* - * Fence stall clearings, operations triggered by unlinkings and so on. + * Fence stall clearnings, operations triggered by unlinkings and so on. * We do not attempt to unlink any URBs, because we do not trust the * unlink paths in HC drivers. Also, we get -84 upon disconnect anyway. */ @@ -2432,7 +2417,7 @@ static void ub_disconnect(struct usb_interface *intf) spin_unlock_irqrestore(sc->lock, flags); /* - * There is virtually no chance that other CPU runs a timeout so long + * There is virtually no chance that other CPU runs times so long * after ub_urb_complete should have called del_timer, but only if HCD * didn't forget to deliver a callback on unlink. */ diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 84e064ffee52..0cfbe8c594a5 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -35,7 +35,7 @@ struct virtblk_req struct list_head list; struct request *req; struct virtio_blk_outhdr out_hdr; - u8 status; + struct virtio_blk_inhdr in_hdr; }; static void blk_done(struct virtqueue *vq) @@ -48,7 +48,7 @@ static void blk_done(struct virtqueue *vq) spin_lock_irqsave(&vblk->lock, flags); while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { int uptodate; - switch (vbr->status) { + switch (vbr->in_hdr.status) { case VIRTIO_BLK_S_OK: uptodate = 1; break; @@ -101,7 +101,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, 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->status, sizeof(vbr->status)); + sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr)); if (rq_data_dir(vbr->req) == WRITE) { vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; @@ -157,25 +157,10 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp, /* We provide getgeo only to please some old bootloader/partitioning tools */ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) { - struct virtio_blk *vblk = bd->bd_disk->private_data; - struct virtio_blk_geometry vgeo; - int err; - - /* see if the host passed in geometry config */ - err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, - offsetof(struct virtio_blk_config, geometry), - &vgeo); - - if (!err) { - geo->heads = vgeo.heads; - geo->sectors = vgeo.sectors; - geo->cylinders = vgeo.cylinders; - } else { - /* some standard values, similar to sd */ - geo->heads = 1 << 6; - geo->sectors = 1 << 5; - geo->cylinders = get_capacity(bd->bd_disk) >> 11; - } + /* some standard values, similar to sd */ + geo->heads = 1 << 6; + geo->sectors = 1 << 5; + geo->cylinders = get_capacity(bd->bd_disk) >> 11; return 0; } @@ -257,12 +242,12 @@ static int virtblk_probe(struct virtio_device *vdev) index++; /* If barriers are supported, tell block layer that queue is ordered */ - if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) + if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); /* Host must always specify the capacity. */ - vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), - &cap, sizeof(cap)); + __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), + &cap); /* If capacity is too big, truncate with warning. */ if ((sector_t)cap != cap) { @@ -304,6 +289,7 @@ static int virtblk_probe(struct virtio_device *vdev) static void virtblk_remove(struct virtio_device *vdev) { struct virtio_blk *vblk = vdev->priv; + int major = vblk->disk->major; /* Nothing should be pending. */ BUG_ON(!list_empty(&vblk->reqs)); @@ -313,6 +299,7 @@ static void virtblk_remove(struct virtio_device *vdev) blk_cleanup_queue(vblk->disk->queue); put_disk(vblk->disk); + unregister_blkdev(major, "virtblk"); mempool_destroy(vblk->pool); vdev->config->del_vq(vblk->vq); kfree(vblk); @@ -323,14 +310,7 @@ static struct virtio_device_id id_table[] = { { 0 }, }; -static unsigned int features[] = { - VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, - VIRTIO_BLK_F_GEOMETRY, -}; - static struct virtio_driver virtio_blk = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/trunk/drivers/char/i8k.c b/trunk/drivers/char/i8k.c index b60d425ce8d1..f49037b744f9 100644 --- a/trunk/drivers/char/i8k.c +++ b/trunk/drivers/char/i8k.c @@ -77,10 +77,6 @@ static int power_status; module_param(power_status, bool, 0600); MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); -static int fan_mult = I8K_FAN_MULT; -module_param(fan_mult, int, 0); -MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with"); - static int i8k_open_fs(struct inode *inode, struct file *file); static int i8k_ioctl(struct inode *, struct file *, unsigned int, unsigned long); @@ -243,7 +239,7 @@ static int i8k_get_fan_speed(int fan) struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; regs.ebx = fan & 0xff; - return i8k_smm(®s) ? : (regs.eax & 0xffff) * fan_mult; + return i8k_smm(®s) ? : (regs.eax & 0xffff) * I8K_FAN_MULT; } /* diff --git a/trunk/drivers/char/mmtimer.c b/trunk/drivers/char/mmtimer.c index 192961fd7173..d83db5d880e0 100644 --- a/trunk/drivers/char/mmtimer.c +++ b/trunk/drivers/char/mmtimer.c @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include @@ -474,8 +472,8 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp) nsec = rtc_time() * sgi_clock_period + sgi_clock_offset.tv_nsec; - *tp = ns_to_timespec(nsec); - tp->tv_sec += sgi_clock_offset.tv_sec; + tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec) + + sgi_clock_offset.tv_sec; return 0; }; @@ -483,11 +481,11 @@ static int sgi_clock_set(clockid_t clockid, struct timespec *tp) { u64 nsec; - u32 rem; + u64 rem; nsec = rtc_time() * sgi_clock_period; - sgi_clock_offset.tv_sec = tp->tv_sec - div_u64_rem(nsec, NSEC_PER_SEC, &rem); + sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem); if (rem <= tp->tv_nsec) sgi_clock_offset.tv_nsec = tp->tv_sec - rem; @@ -646,6 +644,9 @@ static int sgi_timer_del(struct k_itimer *timr) return 0; } +#define timespec_to_ns(x) ((x).tv_nsec + (x).tv_sec * NSEC_PER_SEC) +#define ns_to_timespec(ts, nsec) (ts).tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &(ts).tv_nsec) + /* Assumption: it_lock is already held with irq's disabled */ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) { @@ -658,8 +659,9 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) return; } - cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period); - cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period); + ns_to_timespec(cur_setting->it_interval, timr->it.mmtimer.incr * sgi_clock_period); + ns_to_timespec(cur_setting->it_value, (timr->it.mmtimer.expires - rtc_time())* sgi_clock_period); + return; } @@ -677,8 +679,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, sgi_timer_get(timr, old_setting); sgi_timer_del(timr); - when = timespec_to_ns(&new_setting->it_value); - period = timespec_to_ns(&new_setting->it_interval); + when = timespec_to_ns(new_setting->it_value); + period = timespec_to_ns(new_setting->it_interval); if (when == 0) /* Clear timer */ @@ -693,7 +695,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, unsigned long now; getnstimeofday(&n); - now = timespec_to_ns(&n); + now = timespec_to_ns(n); if (when > now) when -= now; else diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index ac5080df2565..513b7c2f3e26 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -2028,13 +2028,13 @@ static void mgsl_change_params(struct mgsl_struct *info) */ static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) { - struct mgsl_struct *info = tty->driver_data; + struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data; unsigned long flags; - int ret = 0; + int ret; - if (debug_level >= DEBUG_LEVEL_INFO) { - printk(KERN_DEBUG "%s(%d):mgsl_put_char(%d) on %s\n", - __FILE__, __LINE__, ch, info->device_name); + if ( debug_level >= DEBUG_LEVEL_INFO ) { + printk( "%s(%d):mgsl_put_char(%d) on %s\n", + __FILE__,__LINE__,ch,info->device_name); } if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) @@ -2043,9 +2043,9 @@ static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) if (!tty || !info->xmit_buf) return 0; - spin_lock_irqsave(&info->irq_spinlock, flags); + spin_lock_irqsave(&info->irq_spinlock,flags); - if ((info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active) { + if ( (info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active ) { if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) { info->xmit_buf[info->xmit_head++] = ch; info->xmit_head &= SERIAL_XMIT_SIZE-1; @@ -2053,7 +2053,7 @@ static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) ret = 1; } } - spin_unlock_irqrestore(&info->irq_spinlock, flags); + spin_unlock_irqrestore(&info->irq_spinlock,flags); return ret; } /* end of mgsl_put_char() */ diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index 62e3c9190983..2a999373863e 100644 --- a/trunk/drivers/firewire/fw-sbp2.c +++ b/trunk/drivers/firewire/fw-sbp2.c @@ -784,7 +784,7 @@ static void sbp2_release_target(struct kref *kref) kfree(lu); } scsi_remove_host(shost); - fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no); + fw_notify("released %s\n", tgt->bus_id); fw_unit_put(tgt->unit); scsi_host_put(shost); diff --git a/trunk/drivers/gpio/pca953x.c b/trunk/drivers/gpio/pca953x.c index 93f916720b13..5a99e81d2784 100644 --- a/trunk/drivers/gpio/pca953x.c +++ b/trunk/drivers/gpio/pca953x.c @@ -30,8 +30,6 @@ static const struct i2c_device_id pca953x_id[] = { { "pca9537", 4, }, { "pca9538", 8, }, { "pca9539", 16, }, - { "pca9555", 16, }, - { "pca9557", 8, }, /* REVISIT several pca955x parts should work here too */ { } }; @@ -195,7 +193,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, { struct pca953x_platform_data *pdata; struct pca953x_chip *chip; - int ret; + int ret, i; pdata = client->dev.platform_data; if (pdata == NULL) diff --git a/trunk/drivers/hwmon/adt7473.c b/trunk/drivers/hwmon/adt7473.c index c1009d6f9796..9587869bdba0 100644 --- a/trunk/drivers/hwmon/adt7473.c +++ b/trunk/drivers/hwmon/adt7473.c @@ -422,14 +422,18 @@ static ssize_t show_volt(struct device *dev, struct device_attribute *devattr, * number in the range -128 to 127, or as an unsigned number that must * be offset by 64. */ -static int decode_temp(u8 twos_complement, u8 raw) +static int decode_temp(struct adt7473_data *data, u8 raw) { - return twos_complement ? (s8)raw : raw - 64; + if (data->temp_twos_complement) + return (s8)raw; + return raw - 64; } -static u8 encode_temp(u8 twos_complement, int cooked) +static u8 encode_temp(struct adt7473_data *data, int cooked) { - return twos_complement ? cooked & 0xFF : cooked + 64; + if (data->temp_twos_complement) + return (cooked & 0xFF); + return cooked + 64; } static ssize_t show_temp_min(struct device *dev, @@ -438,9 +442,8 @@ static ssize_t show_temp_min(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adt7473_data *data = adt7473_update_device(dev); - return sprintf(buf, "%d\n", 1000 * decode_temp( - data->temp_twos_complement, - data->temp_min[attr->index])); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_min[attr->index])); } static ssize_t set_temp_min(struct device *dev, @@ -452,7 +455,7 @@ static ssize_t set_temp_min(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct adt7473_data *data = i2c_get_clientdata(client); int temp = simple_strtol(buf, NULL, 10) / 1000; - temp = encode_temp(data->temp_twos_complement, temp); + temp = encode_temp(data, temp); mutex_lock(&data->lock); data->temp_min[attr->index] = temp; @@ -469,9 +472,8 @@ static ssize_t show_temp_max(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adt7473_data *data = adt7473_update_device(dev); - return sprintf(buf, "%d\n", 1000 * decode_temp( - data->temp_twos_complement, - data->temp_max[attr->index])); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_max[attr->index])); } static ssize_t set_temp_max(struct device *dev, @@ -483,7 +485,7 @@ static ssize_t set_temp_max(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct adt7473_data *data = i2c_get_clientdata(client); int temp = simple_strtol(buf, NULL, 10) / 1000; - temp = encode_temp(data->temp_twos_complement, temp); + temp = encode_temp(data, temp); mutex_lock(&data->lock); data->temp_max[attr->index] = temp; @@ -499,9 +501,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adt7473_data *data = adt7473_update_device(dev); - return sprintf(buf, "%d\n", 1000 * decode_temp( - data->temp_twos_complement, - data->temp[attr->index])); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp[attr->index])); } static ssize_t show_fan_min(struct device *dev, @@ -670,9 +671,8 @@ static ssize_t show_temp_tmax(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adt7473_data *data = adt7473_update_device(dev); - return sprintf(buf, "%d\n", 1000 * decode_temp( - data->temp_twos_complement, - data->temp_tmax[attr->index])); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_tmax[attr->index])); } static ssize_t set_temp_tmax(struct device *dev, @@ -684,7 +684,7 @@ static ssize_t set_temp_tmax(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct adt7473_data *data = i2c_get_clientdata(client); int temp = simple_strtol(buf, NULL, 10) / 1000; - temp = encode_temp(data->temp_twos_complement, temp); + temp = encode_temp(data, temp); mutex_lock(&data->lock); data->temp_tmax[attr->index] = temp; @@ -701,9 +701,8 @@ static ssize_t show_temp_tmin(struct device *dev, { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct adt7473_data *data = adt7473_update_device(dev); - return sprintf(buf, "%d\n", 1000 * decode_temp( - data->temp_twos_complement, - data->temp_tmin[attr->index])); + return sprintf(buf, "%d\n", + 1000 * decode_temp(data, data->temp_tmin[attr->index])); } static ssize_t set_temp_tmin(struct device *dev, @@ -715,7 +714,7 @@ static ssize_t set_temp_tmin(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct adt7473_data *data = i2c_get_clientdata(client); int temp = simple_strtol(buf, NULL, 10) / 1000; - temp = encode_temp(data->temp_twos_complement, temp); + temp = encode_temp(data, temp); mutex_lock(&data->lock); data->temp_tmin[attr->index] = temp; diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index fe2eea4d799b..84712a22acea 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -953,8 +953,12 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value) static void asb100_init_client(struct i2c_client *client) { struct asb100_data *data = i2c_get_clientdata(client); + int vid = 0; + vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f; + vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4; data->vrm = vid_which_vrm(); + vid = vid_from_reg(vid, data->vrm); /* Start monitoring */ asb100_write_value(client, ASB100_REG_CONFIG, diff --git a/trunk/drivers/hwmon/lm75.c b/trunk/drivers/hwmon/lm75.c index fa7696905154..115f4090b98e 100644 --- a/trunk/drivers/hwmon/lm75.c +++ b/trunk/drivers/hwmon/lm75.c @@ -248,7 +248,7 @@ static int lm75_detach_client(struct i2c_client *client) /* All registers are word-sized, except for the configuration register. LM75 uses a high-byte first convention, which is exactly opposite to - the SMBus standard. */ + the usual practice. */ static int lm75_read_value(struct i2c_client *client, u8 reg) { if (reg == LM75_REG_CONF) @@ -257,6 +257,9 @@ static int lm75_read_value(struct i2c_client *client, u8 reg) return swab16(i2c_smbus_read_word_data(client, reg)); } +/* All registers are word-sized, except for the configuration register. + LM75 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) { if (reg == LM75_REG_CONF) diff --git a/trunk/drivers/hwmon/smsc47b397.c b/trunk/drivers/hwmon/smsc47b397.c index eb03544c731c..f61d8f4185b2 100644 --- a/trunk/drivers/hwmon/smsc47b397.c +++ b/trunk/drivers/hwmon/smsc47b397.c @@ -335,23 +335,11 @@ static int __init smsc47b397_device_add(unsigned short address) static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; - char *name; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); - switch(id) { - case 0x81: - name = "SCH5307-NS"; - break; - case 0x6f: - name = "LPC47B397-NC"; - break; - case 0x85: - case 0x8c: - name = "SCH5317"; - break; - default: + if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) { superio_exit(); return -ENODEV; } @@ -364,7 +352,8 @@ static int __init smsc47b397_find(unsigned short *addr) printk(KERN_INFO DRVNAME ": found SMSC %s " "(base address 0x%04x, revision %u)\n", - name, *addr, rev); + id == 0x81 ? "SCH5307-NS" : id == 0x85 ? "SCH5317" : + "LPC47B397-NC", *addr, rev); superio_exit(); return 0; diff --git a/trunk/drivers/hwmon/w83793.c b/trunk/drivers/hwmon/w83793.c index ed3c019b78c7..ee35af93b574 100644 --- a/trunk/drivers/hwmon/w83793.c +++ b/trunk/drivers/hwmon/w83793.c @@ -1024,9 +1024,10 @@ static struct sensor_device_attribute_2 w83793_vid[] = { SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0), SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1), }; -static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm); static struct sensor_device_attribute_2 sda_single_files[] = { + SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm, + NOT_USED, NOT_USED), SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, store_chassis_clear, ALARM_STATUS, 30), SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable, @@ -1079,7 +1080,6 @@ static int w83793_detach_client(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) device_remove_file(dev, &w83793_vid[i].dev_attr); - device_remove_file(dev, &dev_attr_vrm); for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); @@ -1282,6 +1282,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) /* Initialize the chip */ w83793_init_client(client); + data->vrm = vid_which_vrm(); /* Only fan 1-5 has their own input pins, Pwm 1-3 has their own pins @@ -1292,9 +1293,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) val = w83793_read_value(client, W83793_REG_FANIN_CTRL); /* check the function of pins 49-56 */ - if (tmp & 0x80) { - data->has_vid |= 0x2; /* has VIDB */ - } else { + if (!(tmp & 0x80)) { data->has_pwm |= 0x18; /* pwm 4,5 */ if (val & 0x01) { /* fan 6 */ data->has_fan |= 0x20; @@ -1310,15 +1309,13 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) } } - /* check the function of pins 37-40 */ - if (!(tmp & 0x29)) - data->has_vid |= 0x1; /* has VIDA */ if (0x08 == (tmp & 0x0c)) { if (val & 0x08) /* fan 9 */ data->has_fan |= 0x100; if (val & 0x10) /* fan 10 */ data->has_fan |= 0x200; } + if (0x20 == (tmp & 0x30)) { if (val & 0x20) /* fan 11 */ data->has_fan |= 0x400; @@ -1362,6 +1359,13 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) if (tmp & 0x02) data->has_temp |= 0x20; + /* Detect the VID usage and ignore unused input */ + tmp = w83793_read_value(client, W83793_REG_MFC); + if (!(tmp & 0x29)) + data->has_vid |= 0x1; /* has VIDA */ + if (tmp & 0x80) + data->has_vid |= 0x2; /* has VIDB */ + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { err = device_create_file(dev, @@ -1377,12 +1381,6 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) if (err) goto exit_remove; } - if (data->has_vid) { - data->vrm = vid_which_vrm(); - err = device_create_file(dev, &dev_attr_vrm); - if (err) - goto exit_remove; - } for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { err = device_create_file(dev, &sda_single_files[i].dev_attr); diff --git a/trunk/drivers/hwmon/w83l785ts.c b/trunk/drivers/hwmon/w83l785ts.c index 52e268e25dab..77f2d482888b 100644 --- a/trunk/drivers/hwmon/w83l785ts.c +++ b/trunk/drivers/hwmon/w83l785ts.c @@ -301,8 +301,8 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval) msleep(i); } - dev_err(&client->dev, "Couldn't read value from register 0x%02x.\n", - reg); + dev_err(&client->dev, "Couldn't read value from register 0x%02x. " + "Please report.\n", reg); return defval; } diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 591deda3f86a..099a0fe1745b 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1347,8 +1347,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) hwif->irq = port ? 15 : 14; - /* ->host_flags may be set by ->init_iops (or even earlier...) */ - hwif->host_flags |= d->host_flags; + hwif->host_flags = d->host_flags; hwif->pio_mask = d->pio_mask; /* ->set_pio_mode for DTC2278 is currently limited to port 0 */ diff --git a/trunk/drivers/ieee1394/nodemgr.c b/trunk/drivers/ieee1394/nodemgr.c index 05710c7c1220..29d833e71cbf 100644 --- a/trunk/drivers/ieee1394/nodemgr.c +++ b/trunk/drivers/ieee1394/nodemgr.c @@ -520,11 +520,8 @@ static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf) char *scratch = buf; driver = container_of(drv, struct hpsb_protocol_driver, driver); - id = driver->id_table; - if (!id) - return 0; - for (; id->match_flags != 0; id++) { + for (id = driver->id_table; id->match_flags != 0; id++) { int need_coma = 0; if (id->match_flags & IEEE1394_MATCH_VENDOR_ID) { diff --git a/trunk/drivers/isdn/hysdn/hysdn_procconf.c b/trunk/drivers/isdn/hysdn/hysdn_procconf.c index 15906d005b05..877be9922c3d 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_procconf.c +++ b/trunk/drivers/isdn/hysdn/hysdn_procconf.c @@ -405,8 +405,7 @@ hysdn_procconf_init(void) sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid); if ((card->procconf = (void *) proc_create(conf_name, S_IFREG | S_IRUGO | S_IWUSR, - hysdn_proc_entry, - &conf_fops)) != NULL) { + hysdn_proc_entry)) != NULL) { hysdn_proclog_init(card); /* init the log file entry */ } card = card->next; /* next entry */ diff --git a/trunk/drivers/lguest/lguest_device.c b/trunk/drivers/lguest/lguest_device.c index 8080249957af..2bc9bf7e88e5 100644 --- a/trunk/drivers/lguest/lguest_device.c +++ b/trunk/drivers/lguest/lguest_device.c @@ -85,34 +85,27 @@ static unsigned desc_size(const struct lguest_device_desc *desc) + desc->config_len; } -/* This gets the device's feature bits. */ -static u32 lg_get_features(struct virtio_device *vdev) +/* This tests (and acknowleges) a feature bit. */ +static bool lg_feature(struct virtio_device *vdev, unsigned fbit) { - unsigned int i; - u32 features = 0; struct lguest_device_desc *desc = to_lgdev(vdev)->desc; - u8 *in_features = lg_features(desc); - - /* We do this the slow but generic way. */ - for (i = 0; i < min(desc->feature_len * 8, 32); i++) - if (in_features[i / 8] & (1 << (i % 8))) - features |= (1 << i); - - return features; -} - -static void lg_set_features(struct virtio_device *vdev, u32 features) -{ - unsigned int i; - struct lguest_device_desc *desc = to_lgdev(vdev)->desc; - /* Second half of bitmap is features we accept. */ - u8 *out_features = lg_features(desc) + desc->feature_len; - - memset(out_features, 0, desc->feature_len); - for (i = 0; i < min(desc->feature_len * 8, 32); i++) { - if (features & (1 << i)) - out_features[i / 8] |= (1 << (i % 8)); - } + u8 *features; + + /* Obviously if they ask for a feature off the end of our feature + * bitmap, it's not set. */ + if (fbit / 8 > desc->feature_len) + return false; + + /* The feature bitmap comes after the virtqueues. */ + features = lg_features(desc); + if (!(features[fbit / 8] & (1 << (fbit % 8)))) + return false; + + /* We set the matching bit in the other half of the bitmap to tell the + * Host we want to use this feature. We don't use this yet, but we + * could in future. */ + features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); + return true; } /* Once they've found a field, getting a copy of it is easy. */ @@ -144,26 +137,20 @@ static u8 lg_get_status(struct virtio_device *vdev) return to_lgdev(vdev)->desc->status; } -/* To notify on status updates, we (ab)use the NOTIFY hypercall, with the - * descriptor address of the device. A zero status means "reset". */ -static void set_status(struct virtio_device *vdev, u8 status) -{ - unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; - - /* We set the status. */ - to_lgdev(vdev)->desc->status = status; - hcall(LHCALL_NOTIFY, (max_pfn<desc->status = status; } +/* To reset the device, we (ab)use the NOTIFY hypercall, with the descriptor + * address of the device. The Host will zero the status and all the + * features. */ static void lg_reset(struct virtio_device *vdev) { - set_status(vdev, 0); + unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; + + hcall(LHCALL_NOTIFY, (max_pfn<= ARRAY_SIZE(cpu->lg->cpus)) + if (id >= NR_CPUS) return -EINVAL; /* Set up this CPU's id, and pointer back to the lguest struct. */ @@ -251,6 +251,8 @@ static ssize_t write(struct file *file, const char __user *in, if (!lg || (cpu_id >= lg->nr_cpus)) return -EINVAL; cpu = &lg->cpus[cpu_id]; + if (!cpu) + return -EINVAL; /* Once the Guest is dead, you can only read() why it died. */ if (lg->dead) diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index fcd1aeccdf93..e812df607a5c 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -82,8 +82,9 @@ static struct mtd_info *cfi_intelext_setup (struct mtd_info *); static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **); static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); -static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); + size_t *retlen, u_char **mtdbuf); +static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, + size_t len); static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); @@ -1239,8 +1240,7 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a return ret; } -static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) +static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -1257,10 +1257,8 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); - *virt = map->virt + cfi->chips[chipnum].start + ofs; + *mtdbuf = (void *)map->virt + cfi->chips[chipnum].start + ofs; *retlen = 0; - if (phys) - *phys = map->phys + cfi->chips[chipnum].start + ofs; while (len) { unsigned long thislen; @@ -1293,7 +1291,7 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; diff --git a/trunk/drivers/mtd/devices/mtdram.c b/trunk/drivers/mtd/devices/mtdram.c index 0399be178620..bf485ff49457 100644 --- a/trunk/drivers/mtd/devices/mtdram.c +++ b/trunk/drivers/mtd/devices/mtdram.c @@ -48,21 +48,18 @@ static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) } static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) + size_t *retlen, u_char **mtdbuf) { if (from + len > mtd->size) return -EINVAL; - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; - - *virt = mtd->priv + from; + *mtdbuf = mtd->priv + from; *retlen = len; return 0; } -static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from, + size_t len) { } diff --git a/trunk/drivers/mtd/devices/phram.c b/trunk/drivers/mtd/devices/phram.c index c7987b1c5e01..5f960182da95 100644 --- a/trunk/drivers/mtd/devices/phram.c +++ b/trunk/drivers/mtd/devices/phram.c @@ -57,21 +57,20 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) } static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) + size_t *retlen, u_char **mtdbuf) { - if (from + len > mtd->size) - return -EINVAL; + u_char *start = mtd->priv; - /* can we return a physical address with this driver? */ - if (phys) + if (from + len > mtd->size) return -EINVAL; - *virt = mtd->priv + from; + *mtdbuf = start + from; *retlen = len; return 0; } -static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, + size_t len) { } diff --git a/trunk/drivers/mtd/devices/pmc551.c b/trunk/drivers/mtd/devices/pmc551.c index bc9981749064..7060a0895ce2 100644 --- a/trunk/drivers/mtd/devices/pmc551.c +++ b/trunk/drivers/mtd/devices/pmc551.c @@ -134,8 +134,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) eoff_lo = end & (priv->asize - 1); soff_lo = instr->addr & (priv->asize - 1); - pmc551_point(mtd, instr->addr, instr->len, &retlen, - (void **)&ptr, NULL); + pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr); if (soff_hi == eoff_hi || mtd->size == priv->asize) { /* The whole thing fits within one access, so just one shot @@ -155,8 +154,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) } soff_hi += priv->asize; pmc551_point(mtd, (priv->base_map0 | soff_hi), - priv->asize, &retlen, - (void **)&ptr, NULL); + priv->asize, &retlen, &ptr); } memset(ptr, 0xff, eoff_lo); } @@ -172,7 +170,7 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) } static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) + size_t * retlen, u_char ** mtdbuf) { struct mypriv *priv = mtd->priv; u32 soff_hi; @@ -190,10 +188,6 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, return -EINVAL; } - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; - soff_hi = from & ~(priv->asize - 1); soff_lo = from & (priv->asize - 1); @@ -204,12 +198,13 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, priv->curr_map0 = soff_hi; } - *virt = priv->start + soff_lo; + *mtdbuf = priv->start + soff_lo; *retlen = len; return 0; } -static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from, + size_t len) { #ifdef CONFIG_MTD_PMC551_DEBUG printk(KERN_DEBUG "pmc551_unpoint()\n"); @@ -247,7 +242,7 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, soff_lo = from & (priv->asize - 1); eoff_lo = end & (priv->asize - 1); - pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL); + pmc551_point(mtd, from, len, retlen, &ptr); if (soff_hi == eoff_hi) { /* The whole thing fits within one access, so just one shot @@ -268,8 +263,7 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, goto out; } soff_hi += priv->asize; - pmc551_point(mtd, soff_hi, priv->asize, retlen, - (void **)&ptr, NULL); + pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr); } memcpy(copyto, ptr, eoff_lo); copyto += eoff_lo; @@ -314,7 +308,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, soff_lo = to & (priv->asize - 1); eoff_lo = end & (priv->asize - 1); - pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL); + pmc551_point(mtd, to, len, retlen, &ptr); if (soff_hi == eoff_hi) { /* The whole thing fits within one access, so just one shot @@ -335,8 +329,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, goto out; } soff_hi += priv->asize; - pmc551_point(mtd, soff_hi, priv->asize, retlen, - (void **)&ptr, NULL); + pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr); } memcpy(ptr, copyfrom, eoff_lo); copyfrom += eoff_lo; diff --git a/trunk/drivers/mtd/devices/slram.c b/trunk/drivers/mtd/devices/slram.c index cb86db746f28..d293add1857c 100644 --- a/trunk/drivers/mtd/devices/slram.c +++ b/trunk/drivers/mtd/devices/slram.c @@ -76,9 +76,8 @@ static char *map; static slram_mtd_list_t *slram_mtdlist = NULL; static int slram_erase(struct mtd_info *, struct erase_info *); -static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **, - resource_size_t *); -static void slram_unpoint(struct mtd_info *, loff_t, size_t); +static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, u_char **); +static void slram_unpoint(struct mtd_info *, u_char *, loff_t, size_t); static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -105,23 +104,19 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr) } static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) + size_t *retlen, u_char **mtdbuf) { slram_priv_t *priv = mtd->priv; - /* can we return a physical address with this driver? */ - if (phys) - return -EINVAL; - if (from + len > mtd->size) return -EINVAL; - *virt = priv->start + from; + *mtdbuf = priv->start + from; *retlen = len; return(0); } -static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void slram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) { } diff --git a/trunk/drivers/mtd/maps/uclinux.c b/trunk/drivers/mtd/maps/uclinux.c index c42f4b83f686..14ffb1a9302a 100644 --- a/trunk/drivers/mtd/maps/uclinux.c +++ b/trunk/drivers/mtd/maps/uclinux.c @@ -40,12 +40,10 @@ struct mtd_partition uclinux_romfs[] = { /****************************************************************************/ int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) + size_t *retlen, u_char **mtdbuf) { struct map_info *map = mtd->priv; - *virt = map->virt + from; - if (phys) - *phys = map->phys + from; + *mtdbuf = (u_char *) (map->virt + ((int) from)); *retlen = len; return(0); } diff --git a/trunk/drivers/mtd/mtdpart.c b/trunk/drivers/mtd/mtdpart.c index 07c701169344..c66902df3171 100644 --- a/trunk/drivers/mtd/mtdpart.c +++ b/trunk/drivers/mtd/mtdpart.c @@ -68,7 +68,7 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len, } static int part_point (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) + size_t *retlen, u_char **buf) { struct mtd_part *part = PART(mtd); if (from >= mtd->size) @@ -76,14 +76,14 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len, else if (from + len > mtd->size) len = mtd->size - from; return part->master->point (part->master, from + part->offset, - len, retlen, virt, phys); + len, retlen, buf); } -static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) { struct mtd_part *part = PART(mtd); - part->master->unpoint(part->master, from + part->offset, len); + part->master->unpoint (part->master, addr, from + part->offset, len); } static int part_read_oob(struct mtd_info *mtd, loff_t from, diff --git a/trunk/drivers/mtd/nand/at91_nand.c b/trunk/drivers/mtd/nand/at91_nand.c index 0adb287027a2..414ceaecdb3a 100644 --- a/trunk/drivers/mtd/nand/at91_nand.c +++ b/trunk/drivers/mtd/nand/at91_nand.c @@ -93,24 +93,6 @@ struct at91_nand_host { void __iomem *ecc; }; -/* - * Enable NAND. - */ -static void at91_nand_enable(struct at91_nand_host *host) -{ - if (host->board->enable_pin) - at91_set_gpio_value(host->board->enable_pin, 0); -} - -/* - * Disable NAND. - */ -static void at91_nand_disable(struct at91_nand_host *host) -{ - if (host->board->enable_pin) - at91_set_gpio_value(host->board->enable_pin, 1); -} - /* * Hardware specific access to control-lines */ @@ -119,11 +101,11 @@ static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *nand_chip = mtd->priv; struct at91_nand_host *host = nand_chip->priv; - if (ctrl & NAND_CTRL_CHANGE) { + if (host->board->enable_pin && (ctrl & NAND_CTRL_CHANGE)) { if (ctrl & NAND_NCE) - at91_nand_enable(host); + at91_set_gpio_value(host->board->enable_pin, 0); else - at91_nand_disable(host); + at91_set_gpio_value(host->board->enable_pin, 1); } if (cmd == NAND_CMD_NONE) return; @@ -145,6 +127,24 @@ static int at91_nand_device_ready(struct mtd_info *mtd) return at91_get_gpio_value(host->board->rdy_pin); } +/* + * Enable NAND. + */ +static void at91_nand_enable(struct at91_nand_host *host) +{ + if (host->board->enable_pin) + at91_set_gpio_value(host->board->enable_pin, 0); +} + +/* + * Disable NAND. + */ +static void at91_nand_disable(struct at91_nand_host *host) +{ + if (host->board->enable_pin) + at91_set_gpio_value(host->board->enable_pin, 1); +} + /* * write oob for small pages */ diff --git a/trunk/drivers/net/fec.c b/trunk/drivers/net/fec.c index 32a4f17d35fc..d7a3ea88eddb 100644 --- a/trunk/drivers/net/fec.c +++ b/trunk/drivers/net/fec.c @@ -67,10 +67,6 @@ #define FEC_MAX_PORTS 1 #endif -#if defined(CONFIG_FADS) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_M5272) -#define HAVE_mii_link_interrupt -#endif - /* * Define the fixed address of the FEC hardware. */ @@ -209,10 +205,7 @@ struct fec_enet_private { cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ uint tx_full; - /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ - spinlock_t hw_lock; - /* hold while accessing the mii_list_t() elements */ - spinlock_t mii_lock; + spinlock_t lock; uint phy_id; uint phy_id_done; @@ -316,7 +309,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) volatile fec_t *fecp; volatile cbd_t *bdp; unsigned short status; - unsigned long flags; fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -326,7 +318,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) return 1; } - spin_lock_irqsave(&fep->hw_lock, flags); /* Fill in a Tx ring entry */ bdp = fep->cur_tx; @@ -337,7 +328,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) * This should not happen, since dev->tbusy should be set. */ printk("%s: tx queue full!.\n", dev->name); - spin_unlock_irqrestore(&fep->hw_lock, flags); return 1; } #endif @@ -376,6 +366,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) flush_dcache_range((unsigned long)skb->data, (unsigned long)skb->data + skb->len); + spin_lock_irq(&fep->lock); + /* Send it on its way. Tell FEC it's ready, interrupt when done, * it's the last BD of the frame, and to put the CRC on the end. */ @@ -404,7 +396,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) fep->cur_tx = (cbd_t *)bdp; - spin_unlock_irqrestore(&fep->hw_lock, flags); + spin_unlock_irq(&fep->lock); return 0; } @@ -462,20 +454,19 @@ fec_enet_interrupt(int irq, void * dev_id) struct net_device *dev = dev_id; volatile fec_t *fecp; uint int_events; - irqreturn_t ret = IRQ_NONE; + int handled = 0; fecp = (volatile fec_t*)dev->base_addr; /* Get the interrupt events that caused us to be here. */ - do { - int_events = fecp->fec_ievent; + while ((int_events = fecp->fec_ievent) != 0) { fecp->fec_ievent = int_events; /* Handle receive event in its own function. */ if (int_events & FEC_ENET_RXF) { - ret = IRQ_HANDLED; + handled = 1; fec_enet_rx(dev); } @@ -484,18 +475,17 @@ fec_enet_interrupt(int irq, void * dev_id) them as part of the transmit process. */ if (int_events & FEC_ENET_TXF) { - ret = IRQ_HANDLED; + handled = 1; fec_enet_tx(dev); } if (int_events & FEC_ENET_MII) { - ret = IRQ_HANDLED; + handled = 1; fec_enet_mii(dev); } - } while (int_events); - - return ret; + } + return IRQ_RETVAL(handled); } @@ -508,7 +498,7 @@ fec_enet_tx(struct net_device *dev) struct sk_buff *skb; fep = netdev_priv(dev); - spin_lock_irq(&fep->hw_lock); + spin_lock(&fep->lock); bdp = fep->dirty_tx; while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { @@ -567,7 +557,7 @@ fec_enet_tx(struct net_device *dev) } } fep->dirty_tx = (cbd_t *)bdp; - spin_unlock_irq(&fep->hw_lock); + spin_unlock(&fep->lock); } @@ -594,8 +584,6 @@ fec_enet_rx(struct net_device *dev) fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; - spin_lock_irq(&fep->hw_lock); - /* First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. */ @@ -701,8 +689,6 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { */ fecp->fec_r_des_active = 0; #endif - - spin_unlock_irq(&fep->hw_lock); } @@ -716,11 +702,11 @@ fec_enet_mii(struct net_device *dev) uint mii_reg; fep = netdev_priv(dev); - spin_lock_irq(&fep->mii_lock); - ep = fep->hwp; mii_reg = ep->fec_mii_data; + spin_lock(&fep->lock); + if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); goto unlock; @@ -737,7 +723,7 @@ fec_enet_mii(struct net_device *dev) ep->fec_mii_data = mip->mii_regval; unlock: - spin_unlock_irq(&fep->mii_lock); + spin_unlock(&fep->lock); } static int @@ -751,11 +737,12 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi /* Add PHY address to register command. */ fep = netdev_priv(dev); - spin_lock_irqsave(&fep->mii_lock, flags); - regval |= fep->phy_addr << 23; + retval = 0; + spin_lock_irqsave(&fep->lock,flags); + if ((mip = mii_free) != NULL) { mii_free = mip->mii_next; mip->mii_regval = regval; @@ -772,8 +759,9 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 1; } - spin_unlock_irqrestore(&fep->mii_lock, flags); - return retval; + spin_unlock_irqrestore(&fep->lock,flags); + + return(retval); } static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) @@ -1234,7 +1222,7 @@ static phy_info_t const * const phy_info[] = { }; /* ------------------------------------------------------------------------- */ -#ifdef HAVE_mii_link_interrupt +#if !defined(CONFIG_M532x) #ifdef CONFIG_RPXCLASSIC static void mii_link_interrupt(void *dev_id); @@ -1374,8 +1362,18 @@ static void __inline__ fec_request_intrs(struct net_device *dev) unsigned short irq; } *idp, id[] = { { "fec(TXF)", 23 }, + { "fec(TXB)", 24 }, + { "fec(TXFIFO)", 25 }, + { "fec(TXCR)", 26 }, { "fec(RXF)", 27 }, + { "fec(RXB)", 28 }, { "fec(MII)", 29 }, + { "fec(LC)", 30 }, + { "fec(HBERR)", 31 }, + { "fec(GRA)", 32 }, + { "fec(EBERR)", 33 }, + { "fec(BABT)", 34 }, + { "fec(BABR)", 35 }, { NULL }, }; @@ -1535,8 +1533,18 @@ static void __inline__ fec_request_intrs(struct net_device *dev) unsigned short irq; } *idp, id[] = { { "fec(TXF)", 23 }, + { "fec(TXB)", 24 }, + { "fec(TXFIFO)", 25 }, + { "fec(TXCR)", 26 }, { "fec(RXF)", 27 }, + { "fec(RXB)", 28 }, { "fec(MII)", 29 }, + { "fec(LC)", 30 }, + { "fec(HBERR)", 31 }, + { "fec(GRA)", 32 }, + { "fec(EBERR)", 33 }, + { "fec(BABT)", 34 }, + { "fec(BABR)", 35 }, { NULL }, }; @@ -1652,8 +1660,18 @@ static void __inline__ fec_request_intrs(struct net_device *dev) unsigned short irq; } *idp, id[] = { { "fec(TXF)", 36 }, + { "fec(TXB)", 37 }, + { "fec(TXFIFO)", 38 }, + { "fec(TXCR)", 39 }, { "fec(RXF)", 40 }, + { "fec(RXB)", 41 }, { "fec(MII)", 42 }, + { "fec(LC)", 43 }, + { "fec(HBERR)", 44 }, + { "fec(GRA)", 45 }, + { "fec(EBERR)", 46 }, + { "fec(BABT)", 47 }, + { "fec(BABR)", 48 }, { NULL }, }; @@ -2108,7 +2126,6 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) /* This interrupt occurs when the PHY detects a link change. */ -#ifdef HAVE_mii_link_interrupt #ifdef CONFIG_RPXCLASSIC static void mii_link_interrupt(void *dev_id) @@ -2131,7 +2148,6 @@ mii_link_interrupt(int irq, void * dev_id) return IRQ_HANDLED; } -#endif static int fec_enet_open(struct net_device *dev) @@ -2227,13 +2243,13 @@ static void set_multicast_list(struct net_device *dev) /* Catch all multicast addresses, so set the * filter to all 1's. */ - ep->fec_grp_hash_table_high = 0xffffffff; - ep->fec_grp_hash_table_low = 0xffffffff; + ep->fec_hash_table_high = 0xffffffff; + ep->fec_hash_table_low = 0xffffffff; } else { /* Clear filter and add the addresses in hash register. */ - ep->fec_grp_hash_table_high = 0; - ep->fec_grp_hash_table_low = 0; + ep->fec_hash_table_high = 0; + ep->fec_hash_table_low = 0; dmi = dev->mc_list; @@ -2264,9 +2280,9 @@ static void set_multicast_list(struct net_device *dev) hash = (crc >> (32 - HASH_BITS)) & 0x3f; if (hash > 31) - ep->fec_grp_hash_table_high |= 1 << (hash - 32); + ep->fec_hash_table_high |= 1 << (hash - 32); else - ep->fec_grp_hash_table_low |= 1 << hash; + ep->fec_hash_table_low |= 1 << hash; } } } @@ -2316,9 +2332,6 @@ int __init fec_enet_init(struct net_device *dev) return -ENOMEM; } - spin_lock_init(&fep->hw_lock); - spin_lock_init(&fep->mii_lock); - /* Create an Ethernet device instance. */ fecp = (volatile fec_t *) fec_hw[index]; @@ -2417,15 +2430,11 @@ int __init fec_enet_init(struct net_device *dev) */ fec_request_intrs(dev); - fecp->fec_grp_hash_table_high = 0; - fecp->fec_grp_hash_table_low = 0; + fecp->fec_hash_table_high = 0; + fecp->fec_hash_table_low = 0; fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; fecp->fec_ecntrl = 2; fecp->fec_r_des_active = 0; -#ifndef CONFIG_M5272 - fecp->fec_hash_table_high = 0; - fecp->fec_hash_table_low = 0; -#endif dev->base_addr = (unsigned long)fecp; @@ -2446,7 +2455,8 @@ int __init fec_enet_init(struct net_device *dev) /* Clear and enable interrupts */ fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); /* Queue up command to detect the PHY and initialize the * remainder of the interface. @@ -2490,8 +2500,8 @@ fec_restart(struct net_device *dev, int duplex) /* Reset all multicast. */ - fecp->fec_grp_hash_table_high = 0; - fecp->fec_grp_hash_table_low = 0; + fecp->fec_hash_table_high = 0; + fecp->fec_hash_table_low = 0; /* Set maximum receive buffer size. */ @@ -2573,7 +2583,8 @@ fec_restart(struct net_device *dev, int duplex) /* Enable interrupts we wish to service. */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); } static void @@ -2613,7 +2624,7 @@ fec_stop(struct net_device *dev) static int __init fec_enet_module_init(void) { struct net_device *dev; - int i, err; + int i, j, err; DECLARE_MAC_BUF(mac); printk("FEC ENET Version 0.2\n"); diff --git a/trunk/drivers/net/fec.h b/trunk/drivers/net/fec.h index 292719daceff..1d421606984f 100644 --- a/trunk/drivers/net/fec.h +++ b/trunk/drivers/net/fec.h @@ -88,8 +88,8 @@ typedef struct fec { unsigned long fec_reserved7[158]; unsigned long fec_addr_low; /* Low 32bits MAC address */ unsigned long fec_addr_high; /* High 16bits MAC address */ - unsigned long fec_grp_hash_table_high;/* High 32bits hash table */ - unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */ + unsigned long fec_hash_table_high; /* High 32bits hash table */ + unsigned long fec_hash_table_low; /* Low 32bits hash table */ unsigned long fec_r_des_start; /* Receive descriptor ring */ unsigned long fec_x_des_start; /* Transmit descriptor ring */ unsigned long fec_r_buff_size; /* Maximum receive buff size */ diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index f926b5ab3d09..555b70c8b863 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -41,9 +41,6 @@ struct virtnet_info struct net_device *dev; struct napi_struct napi; - /* The skb we couldn't send because buffers were full. */ - struct sk_buff *last_xmit_skb; - /* Number of input buffers, and max we've ever had. */ unsigned int num, max; @@ -145,10 +142,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, static void try_fill_recv(struct virtnet_info *vi) { struct sk_buff *skb; - struct scatterlist sg[2+MAX_SKB_FRAGS]; + struct scatterlist sg[1+MAX_SKB_FRAGS]; int num, err; - sg_init_table(sg, 2+MAX_SKB_FRAGS); + sg_init_table(sg, 1+MAX_SKB_FRAGS); for (;;) { skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); if (unlikely(!skb)) @@ -224,22 +221,23 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { pr_debug("Sent skb %p\n", skb); __skb_unlink(skb, &vi->send); - vi->dev->stats.tx_bytes += skb->len; + vi->dev->stats.tx_bytes += len; vi->dev->stats.tx_packets++; kfree_skb(skb); } } -static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) +static int start_xmit(struct sk_buff *skb, struct net_device *dev) { - int num; - struct scatterlist sg[2+MAX_SKB_FRAGS]; + struct virtnet_info *vi = netdev_priv(dev); + int num, err; + struct scatterlist sg[1+MAX_SKB_FRAGS]; struct virtio_net_hdr *hdr; const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; - sg_init_table(sg, 2+MAX_SKB_FRAGS); + sg_init_table(sg, 1+MAX_SKB_FRAGS); - pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb, + pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]); @@ -274,51 +272,30 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) vnet_hdr_to_sg(sg, skb); num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; - - return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); -} - -static int start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct virtnet_info *vi = netdev_priv(dev); + __skb_queue_head(&vi->send, skb); again: /* Free up any pending old buffers before queueing new ones. */ free_old_xmit_skbs(vi); - - /* If we has a buffer left over from last time, send it now. */ - if (vi->last_xmit_skb) { - if (xmit_skb(vi, vi->last_xmit_skb) != 0) { - /* Drop this skb: we only queue one. */ - vi->dev->stats.tx_dropped++; - kfree_skb(skb); - goto stop_queue; + err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); + if (err) { + pr_debug("%s: virtio not prepared to send\n", dev->name); + netif_stop_queue(dev); + + /* Activate callback for using skbs: if this returns false it + * means some were used in the meantime. */ + if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { + vi->svq->vq_ops->disable_cb(vi->svq); + netif_start_queue(dev); + goto again; } - vi->last_xmit_skb = NULL; - } + __skb_unlink(skb, &vi->send); - /* Put new one in send queue and do transmit */ - __skb_queue_head(&vi->send, skb); - if (xmit_skb(vi, skb) != 0) { - vi->last_xmit_skb = skb; - goto stop_queue; + return NETDEV_TX_BUSY; } -done: vi->svq->vq_ops->kick(vi->svq); - return NETDEV_TX_OK; - -stop_queue: - pr_debug("%s: virtio not prepared to send\n", dev->name); - netif_stop_queue(dev); - - /* Activate callback for using skbs: if this returns false it - * means some were used in the meantime. */ - if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { - vi->svq->vq_ops->disable_cb(vi->svq); - netif_start_queue(dev); - goto again; - } - goto done; + + return 0; } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -378,26 +355,17 @@ static int virtnet_probe(struct virtio_device *vdev) SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ - if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { + if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { /* This opens up the world of extra features. */ dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { + if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { dev->features |= NETIF_F_TSO | NETIF_F_UFO | NETIF_F_TSO_ECN | NETIF_F_TSO6; } - /* Individual feature bits: what can host handle? */ - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) - dev->features |= NETIF_F_TSO; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) - dev->features |= NETIF_F_TSO6; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) - dev->features |= NETIF_F_TSO_ECN; - if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) - dev->features |= NETIF_F_UFO; } /* Configuration may specify what MAC to use. Otherwise random. */ - if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { + if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { vdev->config->get(vdev, offsetof(struct virtio_net_config, mac), dev->dev_addr, dev->addr_len); @@ -486,15 +454,7 @@ static struct virtio_device_id id_table[] = { { 0 }, }; -static unsigned int features[] = { - VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, - VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, - VIRTIO_NET_F_HOST_ECN, -}; - static struct virtio_driver virtio_net = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/trunk/drivers/pcmcia/au1000_db1x00.c b/trunk/drivers/pcmcia/au1000_db1x00.c index c78d77fd7e3b..74e051535d6c 100644 --- a/trunk/drivers/pcmcia/au1000_db1x00.c +++ b/trunk/drivers/pcmcia/au1000_db1x00.c @@ -194,7 +194,7 @@ db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_s default: pwr |= SET_VCC_VPP(0,0,sock); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, state->Vcc, state->Vpp); break; @@ -215,7 +215,7 @@ db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_s default: pwr |= SET_VCC_VPP(0,0,sock); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, state->Vcc, state->Vpp); break; @@ -224,7 +224,7 @@ db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_s default: /* what's this ? */ pwr |= SET_VCC_VPP(0,0,sock); printk(KERN_ERR "%s: bad Vcc %d\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); break; } diff --git a/trunk/drivers/pcmcia/au1000_generic.c b/trunk/drivers/pcmcia/au1000_generic.c index 75e8f8505e47..b693367d38cd 100644 --- a/trunk/drivers/pcmcia/au1000_generic.c +++ b/trunk/drivers/pcmcia/au1000_generic.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -72,7 +71,7 @@ extern struct au1000_pcmcia_socket au1000_pcmcia_socket[]; u32 *pcmcia_base_vaddrs[2]; extern const unsigned long mips_io_port_base; -static DEFINE_MUTEX(pcmcia_sockets_lock); +DECLARE_MUTEX(pcmcia_sockets_lock); static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = { au1x_board_init, @@ -473,7 +472,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev) struct skt_dev_info *sinfo = dev_get_drvdata(dev); int i; - mutex_lock(&pcmcia_sockets_lock); + down(&pcmcia_sockets_lock); dev_set_drvdata(dev, NULL); for (i = 0; i < sinfo->nskt; i++) { @@ -489,7 +488,7 @@ int au1x00_drv_pcmcia_remove(struct device *dev) } kfree(sinfo); - mutex_unlock(&pcmcia_sockets_lock); + up(&pcmcia_sockets_lock); return 0; } @@ -502,13 +501,13 @@ static int au1x00_drv_pcmcia_probe(struct device *dev) { int i, ret = -ENODEV; - mutex_lock(&pcmcia_sockets_lock); + down(&pcmcia_sockets_lock); for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) { ret = au1x00_pcmcia_hw_init[i](dev); if (ret == 0) break; } - mutex_unlock(&pcmcia_sockets_lock); + up(&pcmcia_sockets_lock); return ret; } diff --git a/trunk/drivers/pcmcia/au1000_pb1x00.c b/trunk/drivers/pcmcia/au1000_pb1x00.c index 157e41423a0a..86c0808d6a05 100644 --- a/trunk/drivers/pcmcia/au1000_pb1x00.c +++ b/trunk/drivers/pcmcia/au1000_pb1x00.c @@ -244,7 +244,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, configure->sock); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, configure->vcc, configure->vpp); break; @@ -272,7 +272,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, configure->sock); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, configure->vcc, configure->vpp); break; @@ -300,7 +300,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, configure->sock); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, configure->vcc, configure->vpp); break; @@ -309,7 +309,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) default: /* what's this ? */ pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock); printk(KERN_ERR "%s: bad Vcc %d\n", - __func__, configure->vcc); + __FUNCTION__, configure->vcc); break; } @@ -353,7 +353,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) default: pcr |= SET_VCC_VPP(0,0); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, configure->vcc, configure->vpp); break; @@ -374,7 +374,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) default: pcr |= SET_VCC_VPP(0,0); printk("%s: bad Vcc/Vpp (%d:%d)\n", - __func__, + __FUNCTION__, configure->vcc, configure->vpp); break; @@ -383,7 +383,7 @@ pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) default: /* what's this ? */ pcr |= SET_VCC_VPP(0,0); printk(KERN_ERR "%s: bad Vcc %d\n", - __func__, configure->vcc); + __FUNCTION__, configure->vcc); break; } diff --git a/trunk/drivers/pcmcia/au1000_xxs1500.c b/trunk/drivers/pcmcia/au1000_xxs1500.c index c78ed5347510..ce9d5c44a7b5 100644 --- a/trunk/drivers/pcmcia/au1000_xxs1500.c +++ b/trunk/drivers/pcmcia/au1000_xxs1500.c @@ -56,7 +56,7 @@ #define PCMCIA_IRQ AU1000_GPIO_4 #if 0 -#define DEBUG(x, args...) printk(__func__ ": " x, ##args) +#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) #else #define DEBUG(x,args...) #endif diff --git a/trunk/drivers/pcmcia/cardbus.c b/trunk/drivers/pcmcia/cardbus.c index fb2f38dc92c5..714baaeb6da1 100644 --- a/trunk/drivers/pcmcia/cardbus.c +++ b/trunk/drivers/pcmcia/cardbus.c @@ -209,7 +209,7 @@ static void cardbus_assign_irqs(struct pci_bus *bus, int irq) } } -int __ref cb_alloc(struct pcmcia_socket * s) +int cb_alloc(struct pcmcia_socket * s) { struct pci_bus *bus = s->cb_dev->subordinate; struct pci_dev *dev; diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index e40775443d04..5a85871f5ee9 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -1520,7 +1520,7 @@ static void pcmcia_bus_remove_socket(struct device *dev, /* the pcmcia_bus_interface is used to handle pcmcia socket devices */ -static struct class_interface pcmcia_bus_interface __refdata = { +static struct class_interface pcmcia_bus_interface = { .class = &pcmcia_socket_class, .add_dev = &pcmcia_bus_add_socket, .remove_dev = &pcmcia_bus_remove_socket, diff --git a/trunk/drivers/pcmcia/i82092.c b/trunk/drivers/pcmcia/i82092.c index e13618656ff7..e54ecc580d9e 100644 --- a/trunk/drivers/pcmcia/i82092.c +++ b/trunk/drivers/pcmcia/i82092.c @@ -53,7 +53,7 @@ static int i82092aa_socket_resume (struct pci_dev *dev) } #endif -static struct pci_driver i82092aa_pci_driver = { +static struct pci_driver i82092aa_pci_drv = { .name = "i82092aa", .id_table = i82092aa_pci_ids, .probe = i82092aa_pci_probe, @@ -714,13 +714,13 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_ static int i82092aa_module_init(void) { - return pci_register_driver(&i82092aa_pci_driver); + return pci_register_driver(&i82092aa_pci_drv); } static void i82092aa_module_exit(void) { enter("i82092aa_module_exit"); - pci_unregister_driver(&i82092aa_pci_driver); + pci_unregister_driver(&i82092aa_pci_drv); if (sockets[0].io_base>0) release_region(sockets[0].io_base, 2); leave("i82092aa_module_exit"); diff --git a/trunk/drivers/pcmcia/omap_cf.c b/trunk/drivers/pcmcia/omap_cf.c index 46314b420765..bb6db3a582b2 100644 --- a/trunk/drivers/pcmcia/omap_cf.c +++ b/trunk/drivers/pcmcia/omap_cf.c @@ -153,7 +153,7 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) static int omap_cf_ss_suspend(struct pcmcia_socket *s) { - pr_debug("%s: %s\n", driver_name, __func__); + pr_debug("%s: %s\n", driver_name, __FUNCTION__); return omap_cf_set_socket(s, &dead_socket); } diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index 8bed1dab9039..abc10fe49bd8 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -778,7 +778,7 @@ static struct pci_device_id pd6729_pci_ids[] = { }; MODULE_DEVICE_TABLE(pci, pd6729_pci_ids); -static struct pci_driver pd6729_pci_driver = { +static struct pci_driver pd6729_pci_drv = { .name = "pd6729", .id_table = pd6729_pci_ids, .probe = pd6729_pci_probe, @@ -791,12 +791,12 @@ static struct pci_driver pd6729_pci_driver = { static int pd6729_module_init(void) { - return pci_register_driver(&pd6729_pci_driver); + return pci_register_driver(&pd6729_pci_drv); } static void pd6729_module_exit(void) { - pci_unregister_driver(&pd6729_pci_driver); + pci_unregister_driver(&pd6729_pci_drv); } module_init(pd6729_module_init); diff --git a/trunk/drivers/pcmcia/pxa2xx_lubbock.c b/trunk/drivers/pcmcia/pxa2xx_lubbock.c index 881ec8a8e389..4a05802213c8 100644 --- a/trunk/drivers/pcmcia/pxa2xx_lubbock.c +++ b/trunk/drivers/pcmcia/pxa2xx_lubbock.c @@ -87,7 +87,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, default: printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); ret = -1; } @@ -104,7 +104,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, pa_dwr_set |= GPIO_A0; else { printk(KERN_ERR "%s(): unrecognized Vpp %u\n", - __func__, state->Vpp); + __FUNCTION__, state->Vpp); ret = -1; break; } @@ -128,14 +128,14 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, default: printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); ret = -1; break; } if (state->Vpp != state->Vcc && state->Vpp != 0) { printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", - __func__, state->Vpp); + __FUNCTION__, state->Vpp); ret = -1; break; } diff --git a/trunk/drivers/pcmcia/pxa2xx_mainstone.c b/trunk/drivers/pcmcia/pxa2xx_mainstone.c index 145b85e0f02c..6fa5eaaab8af 100644 --- a/trunk/drivers/pcmcia/pxa2xx_mainstone.c +++ b/trunk/drivers/pcmcia/pxa2xx_mainstone.c @@ -99,7 +99,7 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, case 50: power |= MST_PCMCIA_PWR_VCC_50; break; default: printk(KERN_ERR "%s(): bad Vcc %u\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); ret = -1; } @@ -111,7 +111,7 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, power |= MST_PCMCIA_PWR_VPP_VCC; } else { printk(KERN_ERR "%s(): bad Vpp %u\n", - __func__, state->Vpp); + __FUNCTION__, state->Vpp); ret = -1; } } diff --git a/trunk/drivers/pcmcia/rsrc_nonstatic.c b/trunk/drivers/pcmcia/rsrc_nonstatic.c index 0fcf763b9175..a8d100707721 100644 --- a/trunk/drivers/pcmcia/rsrc_nonstatic.c +++ b/trunk/drivers/pcmcia/rsrc_nonstatic.c @@ -1045,7 +1045,7 @@ static void __devexit pccard_sysfs_remove_rsrc(struct device *dev, device_remove_file(dev, *attr); } -static struct class_interface pccard_rsrc_interface __refdata = { +static struct class_interface pccard_rsrc_interface = { .class = &pcmcia_socket_class, .add_dev = &pccard_sysfs_add_rsrc, .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc), diff --git a/trunk/drivers/pcmcia/sa1100_assabet.c b/trunk/drivers/pcmcia/sa1100_assabet.c index ce133ce81c10..7c57fdd3c8d7 100644 --- a/trunk/drivers/pcmcia/sa1100_assabet.c +++ b/trunk/drivers/pcmcia/sa1100_assabet.c @@ -66,14 +66,14 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat case 50: printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n", - __func__); + __FUNCTION__); case 33: /* Can only apply 3.3V to the CF slot. */ mask = ASSABET_BCR_CF_PWR; break; default: - printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__, + printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, state->Vcc); return -1; } diff --git a/trunk/drivers/pcmcia/sa1100_badge4.c b/trunk/drivers/pcmcia/sa1100_badge4.c index 607c3f326eca..62bfc7566ec2 100644 --- a/trunk/drivers/pcmcia/sa1100_badge4.c +++ b/trunk/drivers/pcmcia/sa1100_badge4.c @@ -82,14 +82,14 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state case 0: if ((state->Vcc != 0) && (state->Vcc != badge4_pcmvcc)) { - complain_about_jumpering(__func__, "pcmvcc", + complain_about_jumpering(__FUNCTION__, "pcmvcc", badge4_pcmvcc, state->Vcc); // Apply power regardless of the jumpering. // return -1; } if ((state->Vpp != 0) && (state->Vpp != badge4_pcmvpp)) { - complain_about_jumpering(__func__, "pcmvpp", + complain_about_jumpering(__FUNCTION__, "pcmvpp", badge4_pcmvpp, state->Vpp); return -1; } @@ -98,7 +98,7 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state case 1: if ((state->Vcc != 0) && (state->Vcc != badge4_cfvcc)) { - complain_about_jumpering(__func__, "cfvcc", + complain_about_jumpering(__FUNCTION__, "cfvcc", badge4_cfvcc, state->Vcc); return -1; } @@ -143,7 +143,7 @@ int pcmcia_badge4_init(struct device *dev) if (machine_is_badge4()) { printk(KERN_INFO "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", - __func__, + __FUNCTION__, badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2); diff --git a/trunk/drivers/pcmcia/sa1100_cerf.c b/trunk/drivers/pcmcia/sa1100_cerf.c index 7c3951a2675d..549a1529fe35 100644 --- a/trunk/drivers/pcmcia/sa1100_cerf.c +++ b/trunk/drivers/pcmcia/sa1100_cerf.c @@ -63,7 +63,7 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, default: printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); return -1; } diff --git a/trunk/drivers/pcmcia/sa1100_jornada720.c b/trunk/drivers/pcmcia/sa1100_jornada720.c index 2167e6714d2d..6284c35dabc6 100644 --- a/trunk/drivers/pcmcia/sa1100_jornada720.c +++ b/trunk/drivers/pcmcia/sa1100_jornada720.c @@ -42,7 +42,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s unsigned int pa_dwr_mask, pa_dwr_set; int ret; -printk("%s(): config socket %d vcc %d vpp %d\n", __func__, +printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__, skt->nr, state->Vcc, state->Vpp); switch (skt->nr) { @@ -74,7 +74,7 @@ printk("%s(): config socket %d vcc %d vpp %d\n", __func__, if (state->Vpp != state->Vcc && state->Vpp != 0) { printk(KERN_ERR "%s(): slot cannot support VPP %u\n", - __func__, state->Vpp); + __FUNCTION__, state->Vpp); return -1; } diff --git a/trunk/drivers/pcmcia/sa1100_neponset.c b/trunk/drivers/pcmcia/sa1100_neponset.c index 687492fcd5b4..5bc9e9532b9d 100644 --- a/trunk/drivers/pcmcia/sa1100_neponset.c +++ b/trunk/drivers/pcmcia/sa1100_neponset.c @@ -59,7 +59,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta ncr_set = NCR_A0VPP; else { printk(KERN_ERR "%s(): unrecognized VPP %u\n", - __func__, state->Vpp); + __FUNCTION__, state->Vpp); return -1; } break; @@ -71,7 +71,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta if (state->Vpp != state->Vcc && state->Vpp != 0) { printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n", - __func__, state->Vpp); + __FUNCTION__, state->Vpp); return -1; } break; diff --git a/trunk/drivers/pcmcia/sa1100_shannon.c b/trunk/drivers/pcmcia/sa1100_shannon.c index 494912fccc0d..9456f5478d09 100644 --- a/trunk/drivers/pcmcia/sa1100_shannon.c +++ b/trunk/drivers/pcmcia/sa1100_shannon.c @@ -73,19 +73,19 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, { switch (state->Vcc) { case 0: /* power off */ - printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __func__); + printk(KERN_WARNING "%s(): CS asked for 0V, still applying 3.3V..\n", __FUNCTION__); break; case 50: - printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __func__); + printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __FUNCTION__); case 33: break; default: printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); return -1; } - printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __func__); + printk(KERN_WARNING "%s(): Warning, Can't perform reset\n", __FUNCTION__); /* Silently ignore Vpp, output enable, speaker enable. */ diff --git a/trunk/drivers/pcmcia/sa1100_simpad.c b/trunk/drivers/pcmcia/sa1100_simpad.c index 42567de894b9..04d6f7f75f78 100644 --- a/trunk/drivers/pcmcia/sa1100_simpad.c +++ b/trunk/drivers/pcmcia/sa1100_simpad.c @@ -90,7 +90,7 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, default: printk(KERN_ERR "%s(): unrecognized Vcc %u\n", - __func__, state->Vcc); + __FUNCTION__, state->Vcc); clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); local_irq_restore(flags); return -1; diff --git a/trunk/drivers/pcmcia/soc_common.c b/trunk/drivers/pcmcia/soc_common.c index 420a77540f41..aa7779d89752 100644 --- a/trunk/drivers/pcmcia/soc_common.c +++ b/trunk/drivers/pcmcia/soc_common.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -354,7 +353,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m (map->flags&MAP_PREFETCH)?"PREFETCH ":""); if (map->map >= MAX_IO_WIN) { - printk(KERN_ERR "%s(): map (%d) out of range\n", __func__, + printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__, map->map); return -1; } @@ -579,7 +578,7 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs); LIST_HEAD(soc_pcmcia_sockets); -static DEFINE_MUTEX(soc_pcmcia_sockets_lock); +DECLARE_MUTEX(soc_pcmcia_sockets_lock); static const char *skt_names[] = { "PCMCIA socket 0", @@ -602,11 +601,11 @@ soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data) struct cpufreq_freqs *freqs = data; int ret = 0; - mutex_lock(&soc_pcmcia_sockets_lock); + down(&soc_pcmcia_sockets_lock); list_for_each_entry(skt, &soc_pcmcia_sockets, node) if ( skt->ops->frequency_change ) ret += skt->ops->frequency_change(skt, val, freqs); - mutex_unlock(&soc_pcmcia_sockets_lock); + up(&soc_pcmcia_sockets_lock); return ret; } @@ -643,7 +642,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops struct soc_pcmcia_socket *skt; int ret, i; - mutex_lock(&soc_pcmcia_sockets_lock); + down(&soc_pcmcia_sockets_lock); sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); if (!sinfo) { @@ -783,7 +782,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops kfree(sinfo); out: - mutex_unlock(&soc_pcmcia_sockets_lock); + up(&soc_pcmcia_sockets_lock); return ret; } @@ -794,7 +793,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev) dev_set_drvdata(dev, NULL); - mutex_lock(&soc_pcmcia_sockets_lock); + down(&soc_pcmcia_sockets_lock); for (i = 0; i < sinfo->nskt; i++) { struct soc_pcmcia_socket *skt = &sinfo->skt[i]; @@ -819,7 +818,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev) if (list_empty(&soc_pcmcia_sockets)) soc_pcmcia_cpufreq_unregister(); - mutex_unlock(&soc_pcmcia_sockets_lock); + up(&soc_pcmcia_sockets_lock); kfree(sinfo); diff --git a/trunk/drivers/pcmcia/soc_common.h b/trunk/drivers/pcmcia/soc_common.h index 1edc1da9d353..6f14126889b3 100644 --- a/trunk/drivers/pcmcia/soc_common.h +++ b/trunk/drivers/pcmcia/soc_common.h @@ -133,6 +133,7 @@ extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_ extern struct list_head soc_pcmcia_sockets; +extern struct semaphore soc_pcmcia_sockets_lock; extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr); extern int soc_common_drv_pcmcia_remove(struct device *dev); diff --git a/trunk/drivers/pnp/pnpbios/rsparser.c b/trunk/drivers/pnp/pnpbios/rsparser.c index 5ff9a4c0447e..2e2c457a0fea 100644 --- a/trunk/drivers/pnp/pnpbios/rsparser.c +++ b/trunk/drivers/pnp/pnpbios/rsparser.c @@ -591,8 +591,7 @@ static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, p[1] = map & 0xff; p[2] = (map >> 8) & 0xff; - dev_dbg(&dev->dev, " encode irq %llu\n", - (unsigned long long)res->start); + dev_dbg(&dev->dev, " encode irq %d\n", res->start); } static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, @@ -603,8 +602,7 @@ static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, map = 1 << res->start; p[1] = map & 0xff; - dev_dbg(&dev->dev, " encode dma %llu\n", - (unsigned long long)res->start); + dev_dbg(&dev->dev, " encode dma %d\n", res->start); } static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, diff --git a/trunk/drivers/scsi/mvsas.c b/trunk/drivers/scsi/mvsas.c index 1dd70d7a4947..e55b9037adb2 100644 --- a/trunk/drivers/scsi/mvsas.c +++ b/trunk/drivers/scsi/mvsas.c @@ -2822,9 +2822,7 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, dev_printk(KERN_DEBUG, &pdev->dev, "phy[%d] Get Attached Address 0x%llX ," " SAS Address 0x%llX\n", - i, - (unsigned long long)phy->att_dev_sas_addr, - (unsigned long long)phy->dev_sas_addr); + i, phy->att_dev_sas_addr, phy->dev_sas_addr); dev_printk(KERN_DEBUG, &pdev->dev, "Rate = %x , type = %d\n", sas_phy->linkrate, phy->phy_type); diff --git a/trunk/drivers/scsi/ncr53c8xx.c b/trunk/drivers/scsi/ncr53c8xx.c index c57c94c0ffd2..ceab4f73caf1 100644 --- a/trunk/drivers/scsi/ncr53c8xx.c +++ b/trunk/drivers/scsi/ncr53c8xx.c @@ -8222,7 +8222,7 @@ static void process_waiting_list(struct ncb *np, int sts) #ifdef DEBUG_WAITING_LIST if (waiting_list) printk("%s: waiting_list=%lx processing sts=%d\n", ncr_name(np), (u_long) waiting_list, sts); #endif - while ((wcmd = waiting_list) != NULL) { + while (wcmd = waiting_list) { waiting_list = (struct scsi_cmnd *) wcmd->next_wcmd; wcmd->next_wcmd = NULL; if (sts == DID_OK) { diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index a1ca9b7bf2d5..ea41f2626458 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -2271,8 +2271,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) } if (up->port.flags & UPF_IOREMAP) { - up->port.membase = ioremap_nocache(up->port.mapbase, - size); + up->port.membase = ioremap(up->port.mapbase, size); if (!up->port.membase) { release_mem_region(up->port.mapbase, size); ret = -ENOMEM; diff --git a/trunk/drivers/serial/8250_early.c b/trunk/drivers/serial/8250_early.c index f279745e9fef..cd898704ba4f 100644 --- a/trunk/drivers/serial/8250_early.c +++ b/trunk/drivers/serial/8250_early.c @@ -153,7 +153,7 @@ static int __init parse_options(struct early_serial8250_device *device, (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); port->membase += port->mapbase & ~PAGE_MASK; #else - port->membase = ioremap_nocache(port->mapbase, 64); + port->membase = ioremap(port->mapbase, 64); if (!port->membase) { printk(KERN_ERR "%s: Couldn't ioremap 0x%llx\n", __func__, diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 53fa19cf2f06..6e57382b9137 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -86,7 +86,7 @@ setup_port(struct serial_private *priv, struct uart_port *port, len = pci_resource_len(dev, bar); if (!priv->remapped_bar[bar]) - priv->remapped_bar[bar] = ioremap_nocache(base, len); + priv->remapped_bar[bar] = ioremap(base, len); if (!priv->remapped_bar[bar]) return -ENOMEM; @@ -270,7 +270,7 @@ static int pci_plx9050_init(struct pci_dev *dev) /* * enable/disable interrupts */ - p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); + p = ioremap(pci_resource_start(dev, 0), 0x80); if (p == NULL) return -ENOMEM; writel(irq_config, p + 0x4c); @@ -294,7 +294,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev) /* * disable interrupts */ - p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); + p = ioremap(pci_resource_start(dev, 0), 0x80); if (p != NULL) { writel(0, p + 0x4c); @@ -341,8 +341,7 @@ static int sbs_init(struct pci_dev *dev) { u8 __iomem *p; - p = ioremap_nocache(pci_resource_start(dev, 0), - pci_resource_len(dev, 0)); + p = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); if (p == NULL) return -ENOMEM; @@ -366,8 +365,7 @@ static void __devexit sbs_exit(struct pci_dev *dev) { u8 __iomem *p; - p = ioremap_nocache(pci_resource_start(dev, 0), - pci_resource_len(dev, 0)); + p = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0)); /* FIXME: What if resource_len < OCT_REG_CR_OFF */ if (p != NULL) writeb(0, p + OCT_REG_CR_OFF); @@ -421,7 +419,7 @@ static int pci_siig10x_init(struct pci_dev *dev) break; } - p = ioremap_nocache(pci_resource_start(dev, 0), 0x80); + p = ioremap(pci_resource_start(dev, 0), 0x80); if (p == NULL) return -ENOMEM; diff --git a/trunk/drivers/serial/jsm/jsm.h b/trunk/drivers/serial/jsm/jsm.h index 8871aaa3dba6..12c934a1f274 100644 --- a/trunk/drivers/serial/jsm/jsm.h +++ b/trunk/drivers/serial/jsm/jsm.h @@ -373,7 +373,6 @@ struct neo_uart_struct { #define PCI_DEVICE_NEO_2DB9PRI_PCI_NAME "Neo 2 - DB9 Universal PCI - Powered Ring Indicator" #define PCI_DEVICE_NEO_2RJ45_PCI_NAME "Neo 2 - RJ45 Universal PCI" #define PCI_DEVICE_NEO_2RJ45PRI_PCI_NAME "Neo 2 - RJ45 Universal PCI - Powered Ring Indicator" -#define PCIE_DEVICE_NEO_IBM_PCI_NAME "Neo 4 - PCI Express - IBM" /* * Our Global Variables. diff --git a/trunk/drivers/serial/jsm/jsm_driver.c b/trunk/drivers/serial/jsm/jsm_driver.c index 338cf8a08b43..6767ee381cd1 100644 --- a/trunk/drivers/serial/jsm/jsm_driver.c +++ b/trunk/drivers/serial/jsm/jsm_driver.c @@ -82,10 +82,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* store the info for the board we've found */ brd->boardnum = adapter_count++; brd->pci_dev = pdev; - if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM) - brd->maxports = 4; - else - brd->maxports = 2; + brd->maxports = 2; spin_lock_init(&brd->bd_lock); spin_lock_init(&brd->bd_intr_lock); @@ -211,7 +208,6 @@ static struct pci_device_id jsm_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9PRI), 0, 0, 1 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, - { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, { 0, } }; MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); diff --git a/trunk/drivers/spi/spi_bfin5xx.c b/trunk/drivers/spi/spi_bfin5xx.c index 7fea3cf4588a..a9ac1fdb3094 100644 --- a/trunk/drivers/spi/spi_bfin5xx.c +++ b/trunk/drivers/spi/spi_bfin5xx.c @@ -608,7 +608,6 @@ static void pump_transfers(unsigned long data) u8 width; u16 cr, dma_width, dma_config; u32 tranf_success = 1; - u8 full_duplex = 0; /* Get current state information */ message = drv_data->cur_msg; @@ -659,7 +658,6 @@ static void pump_transfers(unsigned long data) } if (transfer->rx_buf != NULL) { - full_duplex = transfer->tx_buf != NULL; drv_data->rx = transfer->rx_buf; drv_data->rx_end = drv_data->rx + transfer->len; dev_dbg(&drv_data->pdev->dev, "rx_buf is %p, rx_end is %p\n", @@ -742,8 +740,7 @@ static void pump_transfers(unsigned long data) * successful use different way to r/w according to * drv_data->cur_chip->enable_dma */ - if (!full_duplex && drv_data->cur_chip->enable_dma - && drv_data->len > 6) { + if (drv_data->cur_chip->enable_dma && drv_data->len > 6) { disable_dma(drv_data->dma_channel); clear_dma_irqstat(drv_data->dma_channel); @@ -831,7 +828,7 @@ static void pump_transfers(unsigned long data) /* IO mode write then read */ dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n"); - if (full_duplex) { + if (drv_data->tx != NULL && drv_data->rx != NULL) { /* full duplex mode */ BUG_ON((drv_data->tx_end - drv_data->tx) != (drv_data->rx_end - drv_data->rx)); diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index 0885cc357a37..34bfb7dd7764 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -125,10 +125,10 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi, /* is clk = pclk / (2 * (pre+1)), or is it * clk = (pclk * 2) / ( pre + 1) */ - div /= 2; + div = (div / 2) - 1; - if (div > 0) - div -= 1; + if (div < 0) + div = 1; if (div > 255) div = 255; diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index a419c42e880e..516a6400db43 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -17,8 +17,6 @@ obj-$(CONFIG_USB_SL811_HCD) += host/ obj-$(CONFIG_USB_U132_HCD) += host/ obj-$(CONFIG_USB_R8A66597_HCD) += host/ -obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ - obj-$(CONFIG_USB_ACM) += class/ obj-$(CONFIG_USB_PRINTER) += class/ diff --git a/trunk/drivers/usb/atm/Kconfig b/trunk/drivers/usb/atm/Kconfig index be0b8daac9c7..86e64035edb0 100644 --- a/trunk/drivers/usb/atm/Kconfig +++ b/trunk/drivers/usb/atm/Kconfig @@ -19,6 +19,7 @@ if USB_ATM config USB_SPEEDTOUCH tristate "Speedtouch USB support" + depends on USB_ATM select FW_LOADER help Say Y here if you have an SpeedTouch USB or SpeedTouch 330 @@ -31,6 +32,7 @@ config USB_SPEEDTOUCH config USB_CXACRU tristate "Conexant AccessRunner USB support" + depends on USB_ATM select FW_LOADER help Say Y here if you have an ADSL USB modem based on the Conexant @@ -43,6 +45,7 @@ config USB_CXACRU config USB_UEAGLEATM tristate "ADI 930 and eagle USB DSL modem" + depends on USB_ATM select FW_LOADER help Say Y here if you have an ADSL USB modem based on the ADI 930 @@ -55,6 +58,7 @@ config USB_UEAGLEATM config USB_XUSBATM tristate "Other USB DSL modem support" + depends on USB_ATM help Say Y here if you have a DSL USB modem not explicitly supported by another USB DSL drivers. In order to use your modem you will need to diff --git a/trunk/drivers/usb/c67x00/Makefile b/trunk/drivers/usb/c67x00/Makefile deleted file mode 100644 index 868bc41b5980..000000000000 --- a/trunk/drivers/usb/c67x00/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for Cypress C67X00 USB Controller -# - -ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG - -obj-$(CONFIG_USB_C67X00_HCD) += c67x00.o - -c67x00-objs := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o diff --git a/trunk/drivers/usb/c67x00/c67x00-drv.c b/trunk/drivers/usb/c67x00/c67x00-drv.c deleted file mode 100644 index 5633bc5c8bf2..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-drv.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * c67x00-drv.c: Cypress C67X00 USB Common infrastructure - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -/* - * This file implements the common infrastructure for using the c67x00. - * It is both the link between the platform configuration and subdrivers and - * the link between the common hardware parts and the subdrivers (e.g. - * interrupt handling). - * - * The c67x00 has 2 SIE's (serial interface engine) wich can be configured - * to be host, device or OTG (with some limitations, E.G. only SIE1 can be OTG). - * - * Depending on the platform configuration, the SIE's are created and - * the corresponding subdriver is initialized (c67x00_probe_sie). - */ - -#include -#include -#include -#include -#include - -#include "c67x00.h" -#include "c67x00-hcd.h" - -static void c67x00_probe_sie(struct c67x00_sie *sie, - struct c67x00_device *dev, int sie_num) -{ - spin_lock_init(&sie->lock); - sie->dev = dev; - sie->sie_num = sie_num; - sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num); - - switch (sie->mode) { - case C67X00_SIE_HOST: - c67x00_hcd_probe(sie); - break; - - case C67X00_SIE_UNUSED: - dev_info(sie_dev(sie), - "Not using SIE %d as requested\n", sie->sie_num); - break; - - default: - dev_err(sie_dev(sie), - "Unsupported configuration: 0x%x for SIE %d\n", - sie->mode, sie->sie_num); - break; - } -} - -static void c67x00_remove_sie(struct c67x00_sie *sie) -{ - switch (sie->mode) { - case C67X00_SIE_HOST: - c67x00_hcd_remove(sie); - break; - - default: - break; - } -} - -static irqreturn_t c67x00_irq(int irq, void *__dev) -{ - struct c67x00_device *c67x00 = __dev; - struct c67x00_sie *sie; - u16 msg, int_status; - int i, count = 8; - - int_status = c67x00_ll_hpi_status(c67x00); - if (!int_status) - return IRQ_NONE; - - while (int_status != 0 && (count-- >= 0)) { - c67x00_ll_irq(c67x00, int_status); - for (i = 0; i < C67X00_SIES; i++) { - sie = &c67x00->sie[i]; - msg = 0; - if (int_status & SIEMSG_FLG(i)) - msg = c67x00_ll_fetch_siemsg(c67x00, i); - if (sie->irq) - sie->irq(sie, int_status, msg); - } - int_status = c67x00_ll_hpi_status(c67x00); - } - - if (int_status) - dev_warn(&c67x00->pdev->dev, "Not all interrupts handled! " - "status = 0x%04x\n", int_status); - - return IRQ_HANDLED; -} - -/* ------------------------------------------------------------------------- */ - -static int __devinit c67x00_drv_probe(struct platform_device *pdev) -{ - struct c67x00_device *c67x00; - struct c67x00_platform_data *pdata; - struct resource *res, *res2; - int ret, i; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res2) - return -ENODEV; - - pdata = pdev->dev.platform_data; - if (!pdata) - return -ENODEV; - - c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL); - if (!c67x00) - return -ENOMEM; - - if (!request_mem_region(res->start, res->end - res->start + 1, - pdev->name)) { - dev_err(&pdev->dev, "Memory region busy\n"); - ret = -EBUSY; - goto request_mem_failed; - } - c67x00->hpi.base = ioremap(res->start, res->end - res->start + 1); - if (!c67x00->hpi.base) { - dev_err(&pdev->dev, "Unable to map HPI registers\n"); - ret = -EIO; - goto map_failed; - } - - spin_lock_init(&c67x00->hpi.lock); - c67x00->hpi.regstep = pdata->hpi_regstep; - c67x00->pdata = pdev->dev.platform_data; - c67x00->pdev = pdev; - - c67x00_ll_init(c67x00); - c67x00_ll_hpi_reg_init(c67x00); - - ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, c67x00); - if (ret) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto request_irq_failed; - } - - ret = c67x00_ll_reset(c67x00); - if (ret) { - dev_err(&pdev->dev, "Device reset failed\n"); - goto reset_failed; - } - - for (i = 0; i < C67X00_SIES; i++) - c67x00_probe_sie(&c67x00->sie[i], c67x00, i); - - platform_set_drvdata(pdev, c67x00); - - return 0; - - reset_failed: - free_irq(res2->start, c67x00); - request_irq_failed: - iounmap(c67x00->hpi.base); - map_failed: - release_mem_region(res->start, res->end - res->start + 1); - request_mem_failed: - kfree(c67x00); - - return ret; -} - -static int __devexit c67x00_drv_remove(struct platform_device *pdev) -{ - struct c67x00_device *c67x00 = platform_get_drvdata(pdev); - struct resource *res; - int i; - - for (i = 0; i < C67X00_SIES; i++) - c67x00_remove_sie(&c67x00->sie[i]); - - c67x00_ll_release(c67x00); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res) - free_irq(res->start, c67x00); - - iounmap(c67x00->hpi.base); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, res->end - res->start + 1); - - kfree(c67x00); - - return 0; -} - -static struct platform_driver c67x00_driver = { - .probe = c67x00_drv_probe, - .remove = __devexit_p(c67x00_drv_remove), - .driver = { - .owner = THIS_MODULE, - .name = "c67x00", - }, -}; -MODULE_ALIAS("platform:c67x00"); - -static int __init c67x00_init(void) -{ - return platform_driver_register(&c67x00_driver); -} - -static void __exit c67x00_exit(void) -{ - platform_driver_unregister(&c67x00_driver); -} - -module_init(c67x00_init); -module_exit(c67x00_exit); - -MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely"); -MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/c67x00/c67x00-hcd.c b/trunk/drivers/usb/c67x00/c67x00-hcd.c deleted file mode 100644 index a22b887f4e9e..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-hcd.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * c67x00-hcd.c: Cypress C67X00 USB Host Controller Driver - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#include -#include -#include - -#include "c67x00.h" -#include "c67x00-hcd.h" - -/* -------------------------------------------------------------------------- - * Root Hub Support - */ - -static __u8 c67x00_hub_des[] = { - 0x09, /* __u8 bLength; */ - 0x29, /* __u8 bDescriptorType; Hub-descriptor */ - 0x02, /* __u8 bNbrPorts; */ - 0x00, /* __u16 wHubCharacteristics; */ - 0x00, /* (per-port OC, no power switching) */ - 0x32, /* __u8 bPwrOn2pwrGood; 2ms */ - 0x00, /* __u8 bHubContrCurrent; 0 mA */ - 0x00, /* __u8 DeviceRemovable; ** 7 Ports max ** */ - 0xff, /* __u8 PortPwrCtrlMask; ** 7 ports max ** */ -}; - -static void c67x00_hub_reset_host_port(struct c67x00_sie *sie, int port) -{ - struct c67x00_hcd *c67x00 = sie->private_data; - unsigned long flags; - - c67x00_ll_husb_reset(sie, port); - - spin_lock_irqsave(&c67x00->lock, flags); - c67x00_ll_husb_reset_port(sie, port); - spin_unlock_irqrestore(&c67x00->lock, flags); - - c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT); -} - -static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - struct c67x00_sie *sie = c67x00->sie; - u16 status; - int i; - - *buf = 0; - status = c67x00_ll_usb_get_status(sie); - for (i = 0; i < C67X00_PORTS; i++) - if (status & PORT_CONNECT_CHANGE(i)) - *buf |= (1 << i); - - /* bit 0 denotes hub change, b1..n port change */ - *buf <<= 1; - - return !!*buf; -} - -static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, - u16 wIndex, char *buf, u16 wLength) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - struct c67x00_sie *sie = c67x00->sie; - u16 status, usb_status; - int len = 0; - unsigned int port = wIndex-1; - u16 wPortChange, wPortStatus; - - switch (typeReq) { - - case GetHubStatus: - *(__le32 *) buf = cpu_to_le32(0); - len = 4; /* hub power */ - break; - - case GetPortStatus: - if (wIndex > C67X00_PORTS) - return -EPIPE; - - status = c67x00_ll_usb_get_status(sie); - usb_status = c67x00_ll_get_usb_ctl(sie); - - wPortChange = 0; - if (status & PORT_CONNECT_CHANGE(port)) - wPortChange |= USB_PORT_STAT_C_CONNECTION; - - wPortStatus = USB_PORT_STAT_POWER; - if (!(status & PORT_SE0_STATUS(port))) - wPortStatus |= USB_PORT_STAT_CONNECTION; - if (usb_status & LOW_SPEED_PORT(port)) { - wPortStatus |= USB_PORT_STAT_LOW_SPEED; - c67x00->low_speed_ports |= (1 << port); - } else - c67x00->low_speed_ports &= ~(1 << port); - - if (usb_status & SOF_EOP_EN(port)) - wPortStatus |= USB_PORT_STAT_ENABLE; - - *(__le16 *) buf = cpu_to_le16(wPortStatus); - *(__le16 *) (buf + 2) = cpu_to_le16(wPortChange); - len = 4; - break; - - case SetHubFeature: /* We don't implement these */ - case ClearHubFeature: - switch (wValue) { - case C_HUB_OVER_CURRENT: - case C_HUB_LOCAL_POWER: - len = 0; - break; - - default: - return -EPIPE; - } - break; - - case SetPortFeature: - if (wIndex > C67X00_PORTS) - return -EPIPE; - - switch (wValue) { - case USB_PORT_FEAT_SUSPEND: - dev_dbg(c67x00_hcd_dev(c67x00), - "SetPortFeature %d (SUSPEND)\n", port); - len = 0; - break; - - case USB_PORT_FEAT_RESET: - c67x00_hub_reset_host_port(sie, port); - len = 0; - break; - - case USB_PORT_FEAT_POWER: - /* Power always enabled */ - len = 0; - break; - - default: - dev_dbg(c67x00_hcd_dev(c67x00), - "%s: SetPortFeature %d (0x%04x) Error!\n", - __func__, port, wValue); - return -EPIPE; - } - break; - - case ClearPortFeature: - if (wIndex > C67X00_PORTS) - return -EPIPE; - - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - /* Reset the port so that the c67x00 also notices the - * disconnect */ - c67x00_hub_reset_host_port(sie, port); - len = 0; - break; - - case USB_PORT_FEAT_C_ENABLE: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): C_ENABLE\n", port); - len = 0; - break; - - case USB_PORT_FEAT_SUSPEND: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): SUSPEND\n", port); - len = 0; - break; - - case USB_PORT_FEAT_C_SUSPEND: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): C_SUSPEND\n", port); - len = 0; - break; - - case USB_PORT_FEAT_POWER: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): POWER\n", port); - return -EPIPE; - - case USB_PORT_FEAT_C_CONNECTION: - c67x00_ll_usb_clear_status(sie, - PORT_CONNECT_CHANGE(port)); - len = 0; - break; - - case USB_PORT_FEAT_C_OVER_CURRENT: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): OVER_CURRENT\n", port); - len = 0; - break; - - case USB_PORT_FEAT_C_RESET: - dev_dbg(c67x00_hcd_dev(c67x00), - "ClearPortFeature (%d): C_RESET\n", port); - len = 0; - break; - - default: - dev_dbg(c67x00_hcd_dev(c67x00), - "%s: ClearPortFeature %d (0x%04x) Error!\n", - __func__, port, wValue); - return -EPIPE; - } - break; - - case GetHubDescriptor: - len = min_t(unsigned int, sizeof(c67x00_hub_des), wLength); - memcpy(buf, c67x00_hub_des, len); - break; - - default: - dev_dbg(c67x00_hcd_dev(c67x00), "%s: unknown\n", __func__); - return -EPIPE; - } - - return 0; -} - -/* --------------------------------------------------------------------- - * Main part of host controller driver - */ - -/** - * c67x00_hcd_irq - * - * This function is called from the interrupt handler in c67x00-drv.c - */ -static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg) -{ - struct c67x00_hcd *c67x00 = sie->private_data; - struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00); - - /* Handle sie message flags */ - if (msg) { - if (msg & HUSB_TDListDone) - c67x00_sched_kick(c67x00); - else - dev_warn(c67x00_hcd_dev(c67x00), - "Unknown SIE msg flag(s): 0x%04x\n", msg); - } - - if (unlikely(hcd->state == HC_STATE_HALT)) - return; - - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) - return; - - /* Handle Start of frame events */ - if (int_status & SOFEOP_FLG(sie->sie_num)) { - c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG); - c67x00_sched_kick(c67x00); - set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - } -} - -/** - * c67x00_hcd_start: Host controller start hook - */ -static int c67x00_hcd_start(struct usb_hcd *hcd) -{ - hcd->uses_new_polling = 1; - hcd->state = HC_STATE_RUNNING; - hcd->poll_rh = 1; - - return 0; -} - -/** - * c67x00_hcd_stop: Host controller stop hook - */ -static void c67x00_hcd_stop(struct usb_hcd *hcd) -{ - /* Nothing to do */ -} - -static int c67x00_hcd_get_frame(struct usb_hcd *hcd) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - u16 temp_val; - - dev_dbg(c67x00_hcd_dev(c67x00), "%s\n", __func__); - temp_val = c67x00_ll_husb_get_frame(c67x00->sie); - temp_val &= HOST_FRAME_MASK; - return temp_val ? (temp_val - 1) : HOST_FRAME_MASK; -} - -static struct hc_driver c67x00_hc_driver = { - .description = "c67x00-hcd", - .product_desc = "Cypress C67X00 Host Controller", - .hcd_priv_size = sizeof(struct c67x00_hcd), - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = c67x00_hcd_start, - .stop = c67x00_hcd_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = c67x00_urb_enqueue, - .urb_dequeue = c67x00_urb_dequeue, - .endpoint_disable = c67x00_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = c67x00_hcd_get_frame, - - /* - * root hub support - */ - .hub_status_data = c67x00_hub_status_data, - .hub_control = c67x00_hub_control, -}; - -/* --------------------------------------------------------------------- - * Setup/Teardown routines - */ - -int c67x00_hcd_probe(struct c67x00_sie *sie) -{ - struct c67x00_hcd *c67x00; - struct usb_hcd *hcd; - unsigned long flags; - int retval; - - if (usb_disabled()) - return -ENODEV; - - hcd = usb_create_hcd(&c67x00_hc_driver, sie_dev(sie), "c67x00_sie"); - if (!hcd) { - retval = -ENOMEM; - goto err0; - } - c67x00 = hcd_to_c67x00_hcd(hcd); - - spin_lock_init(&c67x00->lock); - c67x00->sie = sie; - - INIT_LIST_HEAD(&c67x00->list[PIPE_ISOCHRONOUS]); - INIT_LIST_HEAD(&c67x00->list[PIPE_INTERRUPT]); - INIT_LIST_HEAD(&c67x00->list[PIPE_CONTROL]); - INIT_LIST_HEAD(&c67x00->list[PIPE_BULK]); - c67x00->urb_count = 0; - INIT_LIST_HEAD(&c67x00->td_list); - c67x00->td_base_addr = CY_HCD_BUF_ADDR + SIE_TD_OFFSET(sie->sie_num); - c67x00->buf_base_addr = CY_HCD_BUF_ADDR + SIE_BUF_OFFSET(sie->sie_num); - c67x00->max_frame_bw = MAX_FRAME_BW_STD; - - c67x00_ll_husb_init_host_port(sie); - - init_completion(&c67x00->endpoint_disable); - retval = c67x00_sched_start_scheduler(c67x00); - if (retval) - goto err1; - - retval = usb_add_hcd(hcd, 0, 0); - if (retval) { - dev_dbg(sie_dev(sie), "%s: usb_add_hcd returned %d\n", - __func__, retval); - goto err2; - } - - spin_lock_irqsave(&sie->lock, flags); - sie->private_data = c67x00; - sie->irq = c67x00_hcd_irq; - spin_unlock_irqrestore(&sie->lock, flags); - - return retval; - - err2: - c67x00_sched_stop_scheduler(c67x00); - err1: - usb_put_hcd(hcd); - err0: - return retval; -} - -/* may be called with controller, bus, and devices active */ -void c67x00_hcd_remove(struct c67x00_sie *sie) -{ - struct c67x00_hcd *c67x00 = sie->private_data; - struct usb_hcd *hcd = c67x00_hcd_to_hcd(c67x00); - - c67x00_sched_stop_scheduler(c67x00); - usb_remove_hcd(hcd); - usb_put_hcd(hcd); -} diff --git a/trunk/drivers/usb/c67x00/c67x00-hcd.h b/trunk/drivers/usb/c67x00/c67x00-hcd.h deleted file mode 100644 index e8c6d94b2514..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-hcd.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * c67x00-hcd.h: Cypress C67X00 USB HCD - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#ifndef _USB_C67X00_HCD_H -#define _USB_C67X00_HCD_H - -#include -#include -#include -#include -#include "../core/hcd.h" -#include "c67x00.h" - -/* - * The following parameters depend on the CPU speed, bus speed, ... - * These can be tuned for specific use cases, e.g. if isochronous transfers - * are very important, bandwith can be sacrificed to guarantee that the - * 1ms deadline will be met. - * If bulk transfers are important, the MAX_FRAME_BW can be increased, - * but some (or many) isochronous deadlines might not be met. - * - * The values are specified in bittime. - */ - -/* - * The current implementation switches between _STD (default) and _ISO (when - * isochronous transfers are scheduled), in order to optimize the throughput - * in normal cicrumstances, but also provide good isochronous behaviour. - * - * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms - * frames; there are 12000 bit times per frame. - */ - -#define TOTAL_FRAME_BW 12000 -#define DEFAULT_EOT 2250 - -#define MAX_FRAME_BW_STD (TOTAL_FRAME_BW - DEFAULT_EOT) -#define MAX_FRAME_BW_ISO 2400 - -/* - * Periodic transfers may only use 90% of the full frame, but as - * we currently don't even use 90% of the full frame, we may - * use the full usable time for periodic transfers. - */ -#define MAX_PERIODIC_BW(full_bw) full_bw - -/* -------------------------------------------------------------------------- */ - -struct c67x00_hcd { - spinlock_t lock; - struct c67x00_sie *sie; - unsigned int low_speed_ports; /* bitmask of low speed ports */ - unsigned int urb_count; - unsigned int urb_iso_count; - - struct list_head list[4]; /* iso, int, ctrl, bulk */ -#if PIPE_BULK != 3 -#error "Sanity check failed, this code presumes PIPE_... to range from 0 to 3" -#endif - - /* USB bandwidth allocated to td_list */ - int bandwidth_allocated; - /* USB bandwidth allocated for isoc/int transfer */ - int periodic_bw_allocated; - struct list_head td_list; - int max_frame_bw; - - u16 td_base_addr; - u16 buf_base_addr; - u16 next_td_addr; - u16 next_buf_addr; - - struct tasklet_struct tasklet; - - struct completion endpoint_disable; - - u16 current_frame; - u16 last_frame; -}; - -static inline struct c67x00_hcd *hcd_to_c67x00_hcd(struct usb_hcd *hcd) -{ - return (struct c67x00_hcd *)(hcd->hcd_priv); -} - -static inline struct usb_hcd *c67x00_hcd_to_hcd(struct c67x00_hcd *c67x00) -{ - return container_of((void *)c67x00, struct usb_hcd, hcd_priv); -} - -/* --------------------------------------------------------------------- - * Functions used by c67x00-drv - */ - -int c67x00_hcd_probe(struct c67x00_sie *sie); -void c67x00_hcd_remove(struct c67x00_sie *sie); - -/* --------------------------------------------------------------------- - * Transfer Descriptor scheduling functions - */ -int c67x00_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags); -int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); -void c67x00_endpoint_disable(struct usb_hcd *hcd, - struct usb_host_endpoint *ep); - -void c67x00_hcd_msg_received(struct c67x00_sie *sie, u16 msg); -void c67x00_sched_kick(struct c67x00_hcd *c67x00); -int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00); -void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00); - -#define c67x00_hcd_dev(x) (c67x00_hcd_to_hcd(x)->self.controller) - -#endif /* _USB_C67X00_HCD_H */ diff --git a/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c b/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c deleted file mode 100644 index f3430b372f09..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * c67x00-ll-hpi.c: Cypress C67X00 USB Low level interface using HPI - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#include -#include -#include -#include "c67x00.h" - -#define COMM_REGS 14 - -struct c67x00_lcp_int_data { - u16 regs[COMM_REGS]; -}; - -/* -------------------------------------------------------------------------- */ -/* Interface definitions */ - -#define COMM_ACK 0x0FED -#define COMM_NAK 0xDEAD - -#define COMM_RESET 0xFA50 -#define COMM_EXEC_INT 0xCE01 -#define COMM_INT_NUM 0x01C2 - -/* Registers 0 to COMM_REGS-1 */ -#define COMM_R(x) (0x01C4 + 2 * (x)) - -#define HUSB_SIE_pCurrentTDPtr(x) ((x) ? 0x01B2 : 0x01B0) -#define HUSB_SIE_pTDListDone_Sem(x) ((x) ? 0x01B8 : 0x01B6) -#define HUSB_pEOT 0x01B4 - -/* Software interrupts */ -/* 114, 115: */ -#define HUSB_SIE_INIT_INT(x) ((x) ? 0x0073 : 0x0072) -#define HUSB_RESET_INT 0x0074 - -#define SUSB_INIT_INT 0x0071 -#define SUSB_INIT_INT_LOC (SUSB_INIT_INT * 2) - -/* ----------------------------------------------------------------------- - * HPI implementation - * - * The c67x00 chip also support control via SPI or HSS serial - * interfaces. However, this driver assumes that register access can - * be performed from IRQ context. While this is a safe assuption with - * the HPI interface, it is not true for the serial interfaces. - */ - -/* HPI registers */ -#define HPI_DATA 0 -#define HPI_MAILBOX 1 -#define HPI_ADDR 2 -#define HPI_STATUS 3 - -static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg) -{ - return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep); -} - -static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value) -{ - __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep); -} - -static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg) -{ - hpi_write_reg(dev, HPI_ADDR, reg); - return hpi_read_reg(dev, HPI_DATA); -} - -static u16 hpi_read_word(struct c67x00_device *dev, u16 reg) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_word_nolock(dev, reg); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -static void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg, u16 value) -{ - hpi_write_reg(dev, HPI_ADDR, reg); - hpi_write_reg(dev, HPI_DATA, value); -} - -static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - hpi_write_word_nolock(dev, reg, value); - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -/* - * Only data is little endian, addr has cpu endianess - */ -static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, - u16 *data, u16 count) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&dev->hpi.lock, flags); - - hpi_write_reg(dev, HPI_ADDR, addr); - for (i = 0; i < count; i++) - hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++)); - - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -/* - * Only data is little endian, addr has cpu endianess - */ -static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, - u16 *data, u16 count) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&dev->hpi.lock, flags); - hpi_write_reg(dev, HPI_ADDR, addr); - for (i = 0; i < count; i++) - *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA)); - - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -static void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_word_nolock(dev, reg); - hpi_write_word_nolock(dev, reg, value | mask); - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -static void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_word_nolock(dev, reg); - hpi_write_word_nolock(dev, reg, value & ~mask); - spin_unlock_irqrestore(&dev->hpi.lock, flags); -} - -static u16 hpi_recv_mbox(struct c67x00_device *dev) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_reg(dev, HPI_MAILBOX); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -static u16 hpi_send_mbox(struct c67x00_device *dev, u16 value) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - hpi_write_reg(dev, HPI_MAILBOX, value); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -u16 c67x00_ll_hpi_status(struct c67x00_device *dev) -{ - u16 value; - unsigned long flags; - - spin_lock_irqsave(&dev->hpi.lock, flags); - value = hpi_read_reg(dev, HPI_STATUS); - spin_unlock_irqrestore(&dev->hpi.lock, flags); - - return value; -} - -void c67x00_ll_hpi_reg_init(struct c67x00_device *dev) -{ - int i; - - hpi_recv_mbox(dev); - c67x00_ll_hpi_status(dev); - hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0); - - for (i = 0; i < C67X00_SIES; i++) { - hpi_write_word(dev, SIEMSG_REG(i), 0); - hpi_read_word(dev, SIEMSG_REG(i)); - } -} - -void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie) -{ - hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, - SOFEOP_TO_HPI_EN(sie->sie_num)); -} - -void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie) -{ - hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG, - SOFEOP_TO_HPI_EN(sie->sie_num)); -} - -/* -------------------------------------------------------------------------- */ -/* Transactions */ - -static inline u16 ll_recv_msg(struct c67x00_device *dev) -{ - u16 res; - - res = wait_for_completion_timeout(&dev->hpi.lcp.msg_received, 5 * HZ); - WARN_ON(!res); - - return (res == 0) ? -EIO : 0; -} - -/* -------------------------------------------------------------------------- */ -/* General functions */ - -u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num) -{ - u16 val; - - val = hpi_read_word(dev, SIEMSG_REG(sie_num)); - /* clear register to allow next message */ - hpi_write_word(dev, SIEMSG_REG(sie_num), 0); - - return val; -} - -u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)); -} - -/** - * c67x00_ll_usb_clear_status - clear the USB status bits - */ -void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits) -{ - hpi_write_word(sie->dev, USB_STAT_REG(sie->sie_num), bits); -} - -u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, USB_STAT_REG(sie->sie_num)); -} - -/* -------------------------------------------------------------------------- */ - -static int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr, - struct c67x00_lcp_int_data *data) -{ - int i, rc; - - mutex_lock(&dev->hpi.lcp.mutex); - hpi_write_word(dev, COMM_INT_NUM, nr); - for (i = 0; i < COMM_REGS; i++) - hpi_write_word(dev, COMM_R(i), data->regs[i]); - hpi_send_mbox(dev, COMM_EXEC_INT); - rc = ll_recv_msg(dev); - mutex_unlock(&dev->hpi.lcp.mutex); - - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* Host specific functions */ - -void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value) -{ - mutex_lock(&dev->hpi.lcp.mutex); - hpi_write_word(dev, HUSB_pEOT, value); - mutex_unlock(&dev->hpi.lcp.mutex); -} - -static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie) -{ - struct c67x00_device *dev = sie->dev; - struct c67x00_lcp_int_data data; - int rc; - - rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data); - BUG_ON(rc); /* No return path for error code; crash spectacularly */ -} - -void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port) -{ - struct c67x00_device *dev = sie->dev; - struct c67x00_lcp_int_data data; - int rc; - - data.regs[0] = 50; /* Reset USB port for 50ms */ - data.regs[1] = port | (sie->sie_num << 1); - rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data); - BUG_ON(rc); /* No return path for error code; crash spectacularly */ -} - -void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr) -{ - hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr); -} - -u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num)); -} - -u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie) -{ - return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num)); -} - -void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie) -{ - /* Set port into host mode */ - hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE); - c67x00_ll_husb_sie_init(sie); - /* Clear interrupts */ - c67x00_ll_usb_clear_status(sie, HOST_STAT_MASK); - /* Check */ - if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE)) - dev_warn(sie_dev(sie), - "SIE %d not set to host mode\n", sie->sie_num); -} - -void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port) -{ - /* Clear connect change */ - c67x00_ll_usb_clear_status(sie, PORT_CONNECT_CHANGE(port)); - - /* Enable interrupts */ - hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG, - SOFEOP_TO_CPU_EN(sie->sie_num)); - hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num), - SOF_EOP_IRQ_EN | DONE_IRQ_EN); - - /* Enable pull down transistors */ - hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port)); -} - -/* -------------------------------------------------------------------------- */ - -void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status) -{ - if ((int_status & MBX_OUT_FLG) == 0) - return; - - dev->hpi.lcp.last_msg = hpi_recv_mbox(dev); - complete(&dev->hpi.lcp.msg_received); -} - -/* -------------------------------------------------------------------------- */ - -int c67x00_ll_reset(struct c67x00_device *dev) -{ - int rc; - - mutex_lock(&dev->hpi.lcp.mutex); - hpi_send_mbox(dev, COMM_RESET); - rc = ll_recv_msg(dev); - mutex_unlock(&dev->hpi.lcp.mutex); - - return rc; -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_ll_write_mem_le16 - write into c67x00 memory - * Only data is little endian, addr has cpu endianess. - */ -void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len) -{ - u8 *buf = data; - - /* Sanity check */ - if (addr + len > 0xffff) { - dev_err(&dev->pdev->dev, - "Trying to write beyond writable region!\n"); - return; - } - - if (addr & 0x01) { - /* unaligned access */ - u16 tmp; - tmp = hpi_read_word(dev, addr - 1); - tmp = (tmp & 0x00ff) | (*buf++ << 8); - hpi_write_word(dev, addr - 1, tmp); - addr++; - len--; - } - - hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2); - buf += len & ~0x01; - addr += len & ~0x01; - len &= 0x01; - - if (len) { - u16 tmp; - tmp = hpi_read_word(dev, addr); - tmp = (tmp & 0xff00) | *buf; - hpi_write_word(dev, addr, tmp); - } -} - -/** - * c67x00_ll_read_mem_le16 - read from c67x00 memory - * Only data is little endian, addr has cpu endianess. - */ -void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len) -{ - u8 *buf = data; - - if (addr & 0x01) { - /* unaligned access */ - u16 tmp; - tmp = hpi_read_word(dev, addr - 1); - *buf++ = (tmp >> 8) & 0x00ff; - addr++; - len--; - } - - hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2); - buf += len & ~0x01; - addr += len & ~0x01; - len &= 0x01; - - if (len) { - u16 tmp; - tmp = hpi_read_word(dev, addr); - *buf = tmp & 0x00ff; - } -} - -/* -------------------------------------------------------------------------- */ - -void c67x00_ll_init(struct c67x00_device *dev) -{ - mutex_init(&dev->hpi.lcp.mutex); - init_completion(&dev->hpi.lcp.msg_received); -} - -void c67x00_ll_release(struct c67x00_device *dev) -{ -} diff --git a/trunk/drivers/usb/c67x00/c67x00-sched.c b/trunk/drivers/usb/c67x00/c67x00-sched.c deleted file mode 100644 index 85dfe2965661..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00-sched.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* - * c67x00-sched.c: Cypress C67X00 USB Host Controller Driver - TD scheduling - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#include - -#include "c67x00.h" -#include "c67x00-hcd.h" - -/* - * These are the stages for a control urb, they are kept - * in both urb->interval and td->privdata. - */ -#define SETUP_STAGE 0 -#define DATA_STAGE 1 -#define STATUS_STAGE 2 - -/* -------------------------------------------------------------------------- */ - -/** - * struct c67x00_ep_data: Host endpoint data structure - */ -struct c67x00_ep_data { - struct list_head queue; - struct list_head node; - struct usb_host_endpoint *hep; - struct usb_device *dev; - u16 next_frame; /* For int/isoc transactions */ -}; - -/** - * struct c67x00_td - * - * Hardware parts are little endiannes, SW in CPU endianess. - */ -struct c67x00_td { - /* HW specific part */ - __le16 ly_base_addr; /* Bytes 0-1 */ - __le16 port_length; /* Bytes 2-3 */ - u8 pid_ep; /* Byte 4 */ - u8 dev_addr; /* Byte 5 */ - u8 ctrl_reg; /* Byte 6 */ - u8 status; /* Byte 7 */ - u8 retry_cnt; /* Byte 8 */ -#define TT_OFFSET 2 -#define TT_CONTROL 0 -#define TT_ISOCHRONOUS 1 -#define TT_BULK 2 -#define TT_INTERRUPT 3 - u8 residue; /* Byte 9 */ - __le16 next_td_addr; /* Bytes 10-11 */ - /* SW part */ - struct list_head td_list; - u16 td_addr; - void *data; - struct urb *urb; - unsigned long privdata; - - /* These are needed for handling the toggle bits: - * an urb can be dequeued while a td is in progress - * after checking the td, the toggle bit might need to - * be fixed */ - struct c67x00_ep_data *ep_data; - unsigned int pipe; -}; - -struct c67x00_urb_priv { - struct list_head hep_node; - struct urb *urb; - int port; - int cnt; /* packet number for isoc */ - int status; - struct c67x00_ep_data *ep_data; -}; - -#define td_udev(td) ((td)->ep_data->dev) - -#define CY_TD_SIZE 12 - -#define TD_PIDEP_OFFSET 0x04 -#define TD_PIDEPMASK_PID 0xF0 -#define TD_PIDEPMASK_EP 0x0F -#define TD_PORTLENMASK_DL 0x02FF -#define TD_PORTLENMASK_PN 0xC000 - -#define TD_STATUS_OFFSET 0x07 -#define TD_STATUSMASK_ACK 0x01 -#define TD_STATUSMASK_ERR 0x02 -#define TD_STATUSMASK_TMOUT 0x04 -#define TD_STATUSMASK_SEQ 0x08 -#define TD_STATUSMASK_SETUP 0x10 -#define TD_STATUSMASK_OVF 0x20 -#define TD_STATUSMASK_NAK 0x40 -#define TD_STATUSMASK_STALL 0x80 - -#define TD_ERROR_MASK (TD_STATUSMASK_ERR | TD_STATUSMASK_TMOUT | \ - TD_STATUSMASK_STALL) - -#define TD_RETRYCNT_OFFSET 0x08 -#define TD_RETRYCNTMASK_ACT_FLG 0x10 -#define TD_RETRYCNTMASK_TX_TYPE 0x0C -#define TD_RETRYCNTMASK_RTY_CNT 0x03 - -#define TD_RESIDUE_OVERFLOW 0x80 - -#define TD_PID_IN 0x90 - -/* Residue: signed 8bits, neg -> OVERFLOW, pos -> UNDERFLOW */ -#define td_residue(td) ((__s8)(td->residue)) -#define td_ly_base_addr(td) (__le16_to_cpu((td)->ly_base_addr)) -#define td_port_length(td) (__le16_to_cpu((td)->port_length)) -#define td_next_td_addr(td) (__le16_to_cpu((td)->next_td_addr)) - -#define td_active(td) ((td)->retry_cnt & TD_RETRYCNTMASK_ACT_FLG) -#define td_length(td) (td_port_length(td) & TD_PORTLENMASK_DL) - -#define td_sequence_ok(td) (!td->status || \ - (!(td->status & TD_STATUSMASK_SEQ) == \ - !(td->ctrl_reg & SEQ_SEL))) - -#define td_acked(td) (!td->status || \ - (td->status & TD_STATUSMASK_ACK)) -#define td_actual_bytes(td) (td_length(td) - td_residue(td)) - -/* -------------------------------------------------------------------------- */ - -#ifdef DEBUG - -/** - * dbg_td - Dump the contents of the TD - */ -static void dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) -{ - struct device *dev = c67x00_hcd_dev(c67x00); - - dev_dbg(dev, "### %s at 0x%04x\n", msg, td->td_addr); - dev_dbg(dev, "urb: 0x%p\n", td->urb); - dev_dbg(dev, "endpoint: %4d\n", usb_pipeendpoint(td->pipe)); - dev_dbg(dev, "pipeout: %4d\n", usb_pipeout(td->pipe)); - dev_dbg(dev, "ly_base_addr: 0x%04x\n", td_ly_base_addr(td)); - dev_dbg(dev, "port_length: 0x%04x\n", td_port_length(td)); - dev_dbg(dev, "pid_ep: 0x%02x\n", td->pid_ep); - dev_dbg(dev, "dev_addr: 0x%02x\n", td->dev_addr); - dev_dbg(dev, "ctrl_reg: 0x%02x\n", td->ctrl_reg); - dev_dbg(dev, "status: 0x%02x\n", td->status); - dev_dbg(dev, "retry_cnt: 0x%02x\n", td->retry_cnt); - dev_dbg(dev, "residue: 0x%02x\n", td->residue); - dev_dbg(dev, "next_td_addr: 0x%04x\n", td_next_td_addr(td)); - dev_dbg(dev, "data:"); - print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1, - td->data, td_length(td), 1); -} -#else /* DEBUG */ - -static inline void -dbg_td(struct c67x00_hcd *c67x00, struct c67x00_td *td, char *msg) { } - -#endif /* DEBUG */ - -/* -------------------------------------------------------------------------- */ -/* Helper functions */ - -static inline u16 c67x00_get_current_frame_number(struct c67x00_hcd *c67x00) -{ - return c67x00_ll_husb_get_frame(c67x00->sie) & HOST_FRAME_MASK; -} - -/** - * frame_add - * Software wraparound for framenumbers. - */ -static inline u16 frame_add(u16 a, u16 b) -{ - return (a + b) & HOST_FRAME_MASK; -} - -/** - * frame_after - is frame a after frame b - */ -static inline int frame_after(u16 a, u16 b) -{ - return ((HOST_FRAME_MASK + a - b) & HOST_FRAME_MASK) < - (HOST_FRAME_MASK / 2); -} - -/** - * frame_after_eq - is frame a after or equal to frame b - */ -static inline int frame_after_eq(u16 a, u16 b) -{ - return ((HOST_FRAME_MASK + 1 + a - b) & HOST_FRAME_MASK) < - (HOST_FRAME_MASK / 2); -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_release_urb - remove link from all tds to this urb - * Disconnects the urb from it's tds, so that it can be given back. - * pre: urb->hcpriv != NULL - */ -static void c67x00_release_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct c67x00_td *td; - struct c67x00_urb_priv *urbp; - - BUG_ON(!urb); - - c67x00->urb_count--; - - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { - c67x00->urb_iso_count--; - if (c67x00->urb_iso_count == 0) - c67x00->max_frame_bw = MAX_FRAME_BW_STD; - } - - /* TODO this might be not so efficient when we've got many urbs! - * Alternatives: - * * only clear when needed - * * keep a list of tds with each urbp - */ - list_for_each_entry(td, &c67x00->td_list, td_list) - if (urb == td->urb) - td->urb = NULL; - - urbp = urb->hcpriv; - urb->hcpriv = NULL; - list_del(&urbp->hep_node); - kfree(urbp); -} - -/* -------------------------------------------------------------------------- */ - -static struct c67x00_ep_data * -c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct usb_host_endpoint *hep = urb->ep; - struct c67x00_ep_data *ep_data; - int type; - - c67x00->current_frame = c67x00_get_current_frame_number(c67x00); - - /* Check if endpoint already has a c67x00_ep_data struct allocated */ - if (hep->hcpriv) { - ep_data = hep->hcpriv; - if (frame_after(c67x00->current_frame, ep_data->next_frame)) - ep_data->next_frame = - frame_add(c67x00->current_frame, 1); - return hep->hcpriv; - } - - /* Allocate and initialize a new c67x00 endpoint data structure */ - ep_data = kzalloc(sizeof(*ep_data), GFP_ATOMIC); - if (!ep_data) - return NULL; - - INIT_LIST_HEAD(&ep_data->queue); - INIT_LIST_HEAD(&ep_data->node); - ep_data->hep = hep; - - /* hold a reference to udev as long as this endpoint lives, - * this is needed to possibly fix the data toggle */ - ep_data->dev = usb_get_dev(urb->dev); - hep->hcpriv = ep_data; - - /* For ISOC and INT endpoints, start ASAP: */ - ep_data->next_frame = frame_add(c67x00->current_frame, 1); - - /* Add the endpoint data to one of the pipe lists; must be added - in order of endpoint address */ - type = usb_pipetype(urb->pipe); - if (list_empty(&ep_data->node)) { - list_add(&ep_data->node, &c67x00->list[type]); - } else { - struct c67x00_ep_data *prev; - - list_for_each_entry(prev, &c67x00->list[type], node) { - if (prev->hep->desc.bEndpointAddress > - hep->desc.bEndpointAddress) { - list_add(&ep_data->node, prev->node.prev); - break; - } - } - } - - return ep_data; -} - -static int c67x00_ep_data_free(struct usb_host_endpoint *hep) -{ - struct c67x00_ep_data *ep_data = hep->hcpriv; - - if (!ep_data) - return 0; - - if (!list_empty(&ep_data->queue)) - return -EBUSY; - - usb_put_dev(ep_data->dev); - list_del(&ep_data->queue); - list_del(&ep_data->node); - - kfree(ep_data); - hep->hcpriv = NULL; - - return 0; -} - -void c67x00_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - unsigned long flags; - - if (!list_empty(&ep->urb_list)) - dev_warn(c67x00_hcd_dev(c67x00), "error: urb list not empty\n"); - - spin_lock_irqsave(&c67x00->lock, flags); - - /* loop waiting for all transfers in the endpoint queue to complete */ - while (c67x00_ep_data_free(ep)) { - /* Drop the lock so we can sleep waiting for the hardware */ - spin_unlock_irqrestore(&c67x00->lock, flags); - - /* it could happen that we reinitialize this completion, while - * somebody was waiting for that completion. The timeout and - * while loop handle such cases, but this might be improved */ - INIT_COMPLETION(c67x00->endpoint_disable); - c67x00_sched_kick(c67x00); - wait_for_completion_timeout(&c67x00->endpoint_disable, 1 * HZ); - - spin_lock_irqsave(&c67x00->lock, flags); - } - - spin_unlock_irqrestore(&c67x00->lock, flags); -} - -/* -------------------------------------------------------------------------- */ - -static inline int get_root_port(struct usb_device *dev) -{ - while (dev->parent->parent) - dev = dev->parent; - return dev->portnum; -} - -int c67x00_urb_enqueue(struct usb_hcd *hcd, - struct urb *urb, gfp_t mem_flags) -{ - int ret; - unsigned long flags; - struct c67x00_urb_priv *urbp; - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - int port = get_root_port(urb->dev)-1; - - spin_lock_irqsave(&c67x00->lock, flags); - - /* Make sure host controller is running */ - if (!HC_IS_RUNNING(hcd->state)) { - ret = -ENODEV; - goto err_not_linked; - } - - ret = usb_hcd_link_urb_to_ep(hcd, urb); - if (ret) - goto err_not_linked; - - /* Allocate and initialize urb private data */ - urbp = kzalloc(sizeof(*urbp), mem_flags); - if (!urbp) { - ret = -ENOMEM; - goto err_urbp; - } - - INIT_LIST_HEAD(&urbp->hep_node); - urbp->urb = urb; - urbp->port = port; - - urbp->ep_data = c67x00_ep_data_alloc(c67x00, urb); - - if (!urbp->ep_data) { - ret = -ENOMEM; - goto err_epdata; - } - - /* TODO claim bandwidth with usb_claim_bandwidth? - * also release it somewhere! */ - - urb->hcpriv = urbp; - - urb->actual_length = 0; /* Nothing received/transmitted yet */ - - switch (usb_pipetype(urb->pipe)) { - case PIPE_CONTROL: - urb->interval = SETUP_STAGE; - break; - case PIPE_INTERRUPT: - break; - case PIPE_BULK: - break; - case PIPE_ISOCHRONOUS: - if (c67x00->urb_iso_count == 0) - c67x00->max_frame_bw = MAX_FRAME_BW_ISO; - c67x00->urb_iso_count++; - /* Assume always URB_ISO_ASAP, FIXME */ - if (list_empty(&urbp->ep_data->queue)) - urb->start_frame = urbp->ep_data->next_frame; - else { - /* Go right after the last one */ - struct urb *last_urb; - - last_urb = list_entry(urbp->ep_data->queue.prev, - struct c67x00_urb_priv, - hep_node)->urb; - urb->start_frame = - frame_add(last_urb->start_frame, - last_urb->number_of_packets * - last_urb->interval); - } - urbp->cnt = 0; - break; - } - - /* Add the URB to the endpoint queue */ - list_add_tail(&urbp->hep_node, &urbp->ep_data->queue); - - /* If this is the only URB, kick start the controller */ - if (!c67x00->urb_count++) - c67x00_ll_hpi_enable_sofeop(c67x00->sie); - - c67x00_sched_kick(c67x00); - spin_unlock_irqrestore(&c67x00->lock, flags); - - return 0; - -err_epdata: - kfree(urbp); -err_urbp: - usb_hcd_unlink_urb_from_ep(hcd, urb); -err_not_linked: - spin_unlock_irqrestore(&c67x00->lock, flags); - - return ret; -} - -int c67x00_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -{ - struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd); - unsigned long flags; - int rc; - - spin_lock_irqsave(&c67x00->lock, flags); - rc = usb_hcd_check_unlink_urb(hcd, urb, status); - if (rc) - goto done; - - c67x00_release_urb(c67x00, urb); - usb_hcd_unlink_urb_from_ep(hcd, urb); - - spin_unlock(&c67x00->lock); - usb_hcd_giveback_urb(hcd, urb, status); - spin_lock(&c67x00->lock); - - spin_unlock_irqrestore(&c67x00->lock, flags); - - return 0; - - done: - spin_unlock_irqrestore(&c67x00->lock, flags); - return rc; -} - -/* -------------------------------------------------------------------------- */ - -/* - * pre: c67x00 locked, urb unlocked - */ -static void -c67x00_giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb, int status) -{ - struct c67x00_urb_priv *urbp; - - if (!urb) - return; - - urbp = urb->hcpriv; - urbp->status = status; - - list_del_init(&urbp->hep_node); - - c67x00_release_urb(c67x00, urb); - usb_hcd_unlink_urb_from_ep(c67x00_hcd_to_hcd(c67x00), urb); - spin_unlock(&c67x00->lock); - usb_hcd_giveback_urb(c67x00_hcd_to_hcd(c67x00), urb, urbp->status); - spin_lock(&c67x00->lock); -} - -/* -------------------------------------------------------------------------- */ - -static int c67x00_claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb, - int len, int periodic) -{ - struct c67x00_urb_priv *urbp = urb->hcpriv; - int bit_time; - - /* According to the C67x00 BIOS user manual, page 3-18,19, the - * following calculations provide the full speed bit times for - * a transaction. - * - * FS(in) = 112.5 + 9.36*BC + HOST_DELAY - * FS(in,iso) = 90.5 + 9.36*BC + HOST_DELAY - * FS(out) = 112.5 + 9.36*BC + HOST_DELAY - * FS(out,iso) = 78.4 + 9.36*BC + HOST_DELAY - * LS(in) = 802.4 + 75.78*BC + HOST_DELAY - * LS(out) = 802.6 + 74.67*BC + HOST_DELAY - * - * HOST_DELAY == 106 for the c67200 and c67300. - */ - - /* make calculations in 1/100 bit times to maintain resolution */ - if (urbp->ep_data->dev->speed == USB_SPEED_LOW) { - /* Low speed pipe */ - if (usb_pipein(urb->pipe)) - bit_time = 80240 + 7578*len; - else - bit_time = 80260 + 7467*len; - } else { - /* FS pipes */ - if (usb_pipeisoc(urb->pipe)) - bit_time = usb_pipein(urb->pipe) ? 9050 : 7840; - else - bit_time = 11250; - bit_time += 936*len; - } - - /* Scale back down to integer bit times. Use a host delay of 106. - * (this is the only place it is used) */ - bit_time = ((bit_time+50) / 100) + 106; - - if (unlikely(bit_time + c67x00->bandwidth_allocated >= - c67x00->max_frame_bw)) - return -EMSGSIZE; - - if (unlikely(c67x00->next_td_addr + CY_TD_SIZE >= - c67x00->td_base_addr + SIE_TD_SIZE)) - return -EMSGSIZE; - - if (unlikely(c67x00->next_buf_addr + len >= - c67x00->buf_base_addr + SIE_TD_BUF_SIZE)) - return -EMSGSIZE; - - if (periodic) { - if (unlikely(bit_time + c67x00->periodic_bw_allocated >= - MAX_PERIODIC_BW(c67x00->max_frame_bw))) - return -EMSGSIZE; - c67x00->periodic_bw_allocated += bit_time; - } - - c67x00->bandwidth_allocated += bit_time; - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/** - * td_addr and buf_addr must be word aligned - */ -static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb, - void *data, int len, int pid, int toggle, - unsigned long privdata) -{ - struct c67x00_td *td; - struct c67x00_urb_priv *urbp = urb->hcpriv; - const __u8 active_flag = 1, retry_cnt = 1; - __u8 cmd = 0; - int tt = 0; - - if (c67x00_claim_frame_bw(c67x00, urb, len, usb_pipeisoc(urb->pipe) - || usb_pipeint(urb->pipe))) - return -EMSGSIZE; /* Not really an error, but expected */ - - td = kzalloc(sizeof(*td), GFP_ATOMIC); - if (!td) - return -ENOMEM; - - td->pipe = urb->pipe; - td->ep_data = urbp->ep_data; - - if ((td_udev(td)->speed == USB_SPEED_LOW) && - !(c67x00->low_speed_ports & (1 << urbp->port))) - cmd |= PREAMBLE_EN; - - switch (usb_pipetype(td->pipe)) { - case PIPE_ISOCHRONOUS: - tt = TT_ISOCHRONOUS; - cmd |= ISO_EN; - break; - case PIPE_CONTROL: - tt = TT_CONTROL; - break; - case PIPE_BULK: - tt = TT_BULK; - break; - case PIPE_INTERRUPT: - tt = TT_INTERRUPT; - break; - } - - if (toggle) - cmd |= SEQ_SEL; - - cmd |= ARM_EN; - - /* SW part */ - td->td_addr = c67x00->next_td_addr; - c67x00->next_td_addr = c67x00->next_td_addr + CY_TD_SIZE; - - /* HW part */ - td->ly_base_addr = __cpu_to_le16(c67x00->next_buf_addr); - td->port_length = __cpu_to_le16((c67x00->sie->sie_num << 15) | - (urbp->port << 14) | (len & 0x3FF)); - td->pid_ep = ((pid & 0xF) << TD_PIDEP_OFFSET) | - (usb_pipeendpoint(td->pipe) & 0xF); - td->dev_addr = usb_pipedevice(td->pipe) & 0x7F; - td->ctrl_reg = cmd; - td->status = 0; - td->retry_cnt = (tt << TT_OFFSET) | (active_flag << 4) | retry_cnt; - td->residue = 0; - td->next_td_addr = __cpu_to_le16(c67x00->next_td_addr); - - /* SW part */ - td->data = data; - td->urb = urb; - td->privdata = privdata; - - c67x00->next_buf_addr += (len + 1) & ~0x01; /* properly align */ - - list_add_tail(&td->td_list, &c67x00->td_list); - return 0; -} - -static inline void c67x00_release_td(struct c67x00_td *td) -{ - list_del_init(&td->td_list); - kfree(td); -} - -/* -------------------------------------------------------------------------- */ - -static int c67x00_add_data_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - int remaining; - int toggle; - int pid; - int ret = 0; - int maxps; - int need_empty; - - toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe)); - remaining = urb->transfer_buffer_length - urb->actual_length; - - maxps = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - - need_empty = (urb->transfer_flags & URB_ZERO_PACKET) && - usb_pipeout(urb->pipe) && !(remaining % maxps); - - while (remaining || need_empty) { - int len; - char *td_buf; - - len = (remaining > maxps) ? maxps : remaining; - if (!len) - need_empty = 0; - - pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; - td_buf = urb->transfer_buffer + urb->transfer_buffer_length - - remaining; - ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, toggle, - DATA_STAGE); - if (ret) - return ret; /* td wasn't created */ - - toggle ^= 1; - remaining -= len; - if (usb_pipecontrol(urb->pipe)) - break; - } - - return 0; -} - -/** - * return 0 in case more bandwidth is available, else errorcode - */ -static int c67x00_add_ctrl_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - int ret; - int pid; - - switch (urb->interval) { - default: - case SETUP_STAGE: - ret = c67x00_create_td(c67x00, urb, urb->setup_packet, - 8, USB_PID_SETUP, 0, SETUP_STAGE); - if (ret) - return ret; - urb->interval = SETUP_STAGE; - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), - usb_pipeout(urb->pipe), 1); - break; - case DATA_STAGE: - if (urb->transfer_buffer_length) { - ret = c67x00_add_data_urb(c67x00, urb); - if (ret) - return ret; - break; - } /* else fallthrough */ - case STATUS_STAGE: - pid = !usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; - ret = c67x00_create_td(c67x00, urb, NULL, 0, pid, 1, - STATUS_STAGE); - if (ret) - return ret; - break; - } - - return 0; -} - -/* - * return 0 in case more bandwidth is available, else errorcode - */ -static int c67x00_add_int_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct c67x00_urb_priv *urbp = urb->hcpriv; - - if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) { - urbp->ep_data->next_frame = - frame_add(urbp->ep_data->next_frame, urb->interval); - return c67x00_add_data_urb(c67x00, urb); - } - return 0; -} - -static int c67x00_add_iso_urb(struct c67x00_hcd *c67x00, struct urb *urb) -{ - struct c67x00_urb_priv *urbp = urb->hcpriv; - - if (frame_after_eq(c67x00->current_frame, urbp->ep_data->next_frame)) { - char *td_buf; - int len, pid, ret; - - BUG_ON(urbp->cnt >= urb->number_of_packets); - - td_buf = urb->transfer_buffer + - urb->iso_frame_desc[urbp->cnt].offset; - len = urb->iso_frame_desc[urbp->cnt].length; - pid = usb_pipeout(urb->pipe) ? USB_PID_OUT : USB_PID_IN; - - ret = c67x00_create_td(c67x00, urb, td_buf, len, pid, 0, - urbp->cnt); - if (ret) { - printk(KERN_DEBUG "create failed: %d\n", ret); - urb->iso_frame_desc[urbp->cnt].actual_length = 0; - urb->iso_frame_desc[urbp->cnt].status = ret; - if (urbp->cnt + 1 == urb->number_of_packets) - c67x00_giveback_urb(c67x00, urb, 0); - } - - urbp->ep_data->next_frame = - frame_add(urbp->ep_data->next_frame, urb->interval); - urbp->cnt++; - } - return 0; -} - -/* -------------------------------------------------------------------------- */ - -static void c67x00_fill_from_list(struct c67x00_hcd *c67x00, int type, - int (*add)(struct c67x00_hcd *, struct urb *)) -{ - struct c67x00_ep_data *ep_data; - struct urb *urb; - - /* traverse every endpoint on the list */ - list_for_each_entry(ep_data, &c67x00->list[type], node) { - if (!list_empty(&ep_data->queue)) { - /* and add the first urb */ - /* isochronous transfer rely on this */ - urb = list_entry(ep_data->queue.next, - struct c67x00_urb_priv, - hep_node)->urb; - add(c67x00, urb); - } - } -} - -static void c67x00_fill_frame(struct c67x00_hcd *c67x00) -{ - struct c67x00_td *td, *ttd; - - /* Check if we can proceed */ - if (!list_empty(&c67x00->td_list)) { - dev_warn(c67x00_hcd_dev(c67x00), - "TD list not empty! This should not happen!\n"); - list_for_each_entry_safe(td, ttd, &c67x00->td_list, td_list) { - dbg_td(c67x00, td, "Unprocessed td"); - c67x00_release_td(td); - } - } - - /* Reinitialize variables */ - c67x00->bandwidth_allocated = 0; - c67x00->periodic_bw_allocated = 0; - - c67x00->next_td_addr = c67x00->td_base_addr; - c67x00->next_buf_addr = c67x00->buf_base_addr; - - /* Fill the list */ - c67x00_fill_from_list(c67x00, PIPE_ISOCHRONOUS, c67x00_add_iso_urb); - c67x00_fill_from_list(c67x00, PIPE_INTERRUPT, c67x00_add_int_urb); - c67x00_fill_from_list(c67x00, PIPE_CONTROL, c67x00_add_ctrl_urb); - c67x00_fill_from_list(c67x00, PIPE_BULK, c67x00_add_data_urb); -} - -/* -------------------------------------------------------------------------- */ - -/** - * Get TD from C67X00 - */ -static inline void -c67x00_parse_td(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - c67x00_ll_read_mem_le16(c67x00->sie->dev, - td->td_addr, td, CY_TD_SIZE); - - if (usb_pipein(td->pipe) && td_actual_bytes(td)) - c67x00_ll_read_mem_le16(c67x00->sie->dev, td_ly_base_addr(td), - td->data, td_actual_bytes(td)); -} - -static int c67x00_td_to_error(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - if (td->status & TD_STATUSMASK_ERR) { - dbg_td(c67x00, td, "ERROR_FLAG"); - return -EILSEQ; - } - if (td->status & TD_STATUSMASK_STALL) { - /* dbg_td(c67x00, td, "STALL"); */ - return -EPIPE; - } - if (td->status & TD_STATUSMASK_TMOUT) { - dbg_td(c67x00, td, "TIMEOUT"); - return -ETIMEDOUT; - } - - return 0; -} - -static inline int c67x00_end_of_data(struct c67x00_td *td) -{ - int maxps, need_empty, remaining; - struct urb *urb = td->urb; - int act_bytes; - - act_bytes = td_actual_bytes(td); - - if (unlikely(!act_bytes)) - return 1; /* This was an empty packet */ - - maxps = usb_maxpacket(td_udev(td), td->pipe, usb_pipeout(td->pipe)); - - if (unlikely(act_bytes < maxps)) - return 1; /* Smaller then full packet */ - - remaining = urb->transfer_buffer_length - urb->actual_length; - need_empty = (urb->transfer_flags & URB_ZERO_PACKET) && - usb_pipeout(urb->pipe) && !(remaining % maxps); - - if (unlikely(!remaining && !need_empty)) - return 1; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/* Remove all td's from the list which come - * after last_td and are meant for the same pipe. - * This is used when a short packet has occured */ -static inline void c67x00_clear_pipe(struct c67x00_hcd *c67x00, - struct c67x00_td *last_td) -{ - struct c67x00_td *td, *tmp; - td = last_td; - tmp = last_td; - while (td->td_list.next != &c67x00->td_list) { - td = list_entry(td->td_list.next, struct c67x00_td, td_list); - if (td->pipe == last_td->pipe) { - c67x00_release_td(td); - td = tmp; - } - tmp = td; - } -} - -/* -------------------------------------------------------------------------- */ - -static void c67x00_handle_successful_td(struct c67x00_hcd *c67x00, - struct c67x00_td *td) -{ - struct urb *urb = td->urb; - - if (!urb) - return; - - urb->actual_length += td_actual_bytes(td); - - switch (usb_pipetype(td->pipe)) { - /* isochronous tds are handled separately */ - case PIPE_CONTROL: - switch (td->privdata) { - case SETUP_STAGE: - urb->interval = - urb->transfer_buffer_length ? - DATA_STAGE : STATUS_STAGE; - /* Don't count setup_packet with normal data: */ - urb->actual_length = 0; - break; - - case DATA_STAGE: - if (c67x00_end_of_data(td)) { - urb->interval = STATUS_STAGE; - c67x00_clear_pipe(c67x00, td); - } - break; - - case STATUS_STAGE: - urb->interval = 0; - c67x00_giveback_urb(c67x00, urb, 0); - break; - } - break; - - case PIPE_INTERRUPT: - case PIPE_BULK: - if (unlikely(c67x00_end_of_data(td))) { - c67x00_clear_pipe(c67x00, td); - c67x00_giveback_urb(c67x00, urb, 0); - } - break; - } -} - -static void c67x00_handle_isoc(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - struct urb *urb = td->urb; - struct c67x00_urb_priv *urbp; - int cnt; - - if (!urb) - return; - - urbp = urb->hcpriv; - cnt = td->privdata; - - if (td->status & TD_ERROR_MASK) - urb->error_count++; - - urb->iso_frame_desc[cnt].actual_length = td_actual_bytes(td); - urb->iso_frame_desc[cnt].status = c67x00_td_to_error(c67x00, td); - if (cnt + 1 == urb->number_of_packets) /* Last packet */ - c67x00_giveback_urb(c67x00, urb, 0); -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_check_td_list - handle tds which have been processed by the c67x00 - * pre: current_td == 0 - */ -static inline void c67x00_check_td_list(struct c67x00_hcd *c67x00) -{ - struct c67x00_td *td, *tmp; - struct urb *urb; - int ack_ok; - int clear_endpoint; - - list_for_each_entry_safe(td, tmp, &c67x00->td_list, td_list) { - /* get the TD */ - c67x00_parse_td(c67x00, td); - urb = td->urb; /* urb can be NULL! */ - ack_ok = 0; - clear_endpoint = 1; - - /* Handle isochronous transfers separately */ - if (usb_pipeisoc(td->pipe)) { - clear_endpoint = 0; - c67x00_handle_isoc(c67x00, td); - goto cont; - } - - /* When an error occurs, all td's for that pipe go into an - * inactive state. This state matches successful transfers so - * we must make sure not to service them. */ - if (td->status & TD_ERROR_MASK) { - c67x00_giveback_urb(c67x00, urb, - c67x00_td_to_error(c67x00, td)); - goto cont; - } - - if ((td->status & TD_STATUSMASK_NAK) || !td_sequence_ok(td) || - !td_acked(td)) - goto cont; - - /* Sequence ok and acked, don't need to fix toggle */ - ack_ok = 1; - - if (unlikely(td->status & TD_STATUSMASK_OVF)) { - if (td_residue(td) & TD_RESIDUE_OVERFLOW) { - /* Overflow */ - c67x00_giveback_urb(c67x00, urb, -EOVERFLOW); - goto cont; - } - } - - clear_endpoint = 0; - c67x00_handle_successful_td(c67x00, td); - -cont: - if (clear_endpoint) - c67x00_clear_pipe(c67x00, td); - if (ack_ok) - usb_settoggle(td_udev(td), usb_pipeendpoint(td->pipe), - usb_pipeout(td->pipe), - !(td->ctrl_reg & SEQ_SEL)); - /* next in list could have been removed, due to clear_pipe! */ - tmp = list_entry(td->td_list.next, typeof(*td), td_list); - c67x00_release_td(td); - } -} - -/* -------------------------------------------------------------------------- */ - -static inline int c67x00_all_tds_processed(struct c67x00_hcd *c67x00) -{ - /* If all tds are processed, we can check the previous frame (if - * there was any) and start our next frame. - */ - return !c67x00_ll_husb_get_current_td(c67x00->sie); -} - -/** - * Send td to C67X00 - */ -static void c67x00_send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td) -{ - int len = td_length(td); - - if (len && ((td->pid_ep & TD_PIDEPMASK_PID) != TD_PID_IN)) - c67x00_ll_write_mem_le16(c67x00->sie->dev, td_ly_base_addr(td), - td->data, len); - - c67x00_ll_write_mem_le16(c67x00->sie->dev, - td->td_addr, td, CY_TD_SIZE); -} - -static void c67x00_send_frame(struct c67x00_hcd *c67x00) -{ - struct c67x00_td *td; - - if (list_empty(&c67x00->td_list)) - dev_warn(c67x00_hcd_dev(c67x00), - "%s: td list should not be empty here!\n", - __func__); - - list_for_each_entry(td, &c67x00->td_list, td_list) { - if (td->td_list.next == &c67x00->td_list) - td->next_td_addr = 0; /* Last td in list */ - - c67x00_send_td(c67x00, td); - } - - c67x00_ll_husb_set_current_td(c67x00->sie, c67x00->td_base_addr); -} - -/* -------------------------------------------------------------------------- */ - -/** - * c67x00_do_work - Schedulers state machine - */ -static void c67x00_do_work(struct c67x00_hcd *c67x00) -{ - spin_lock(&c67x00->lock); - /* Make sure all tds are processed */ - if (!c67x00_all_tds_processed(c67x00)) - goto out; - - c67x00_check_td_list(c67x00); - - /* no td's are being processed (current == 0) - * and all have been "checked" */ - complete(&c67x00->endpoint_disable); - - if (!list_empty(&c67x00->td_list)) - goto out; - - c67x00->current_frame = c67x00_get_current_frame_number(c67x00); - if (c67x00->current_frame == c67x00->last_frame) - goto out; /* Don't send tds in same frame */ - c67x00->last_frame = c67x00->current_frame; - - /* If no urbs are scheduled, our work is done */ - if (!c67x00->urb_count) { - c67x00_ll_hpi_disable_sofeop(c67x00->sie); - goto out; - } - - c67x00_fill_frame(c67x00); - if (!list_empty(&c67x00->td_list)) - /* TD's have been added to the frame */ - c67x00_send_frame(c67x00); - - out: - spin_unlock(&c67x00->lock); -} - -/* -------------------------------------------------------------------------- */ - -static void c67x00_sched_tasklet(unsigned long __c67x00) -{ - struct c67x00_hcd *c67x00 = (struct c67x00_hcd *)__c67x00; - c67x00_do_work(c67x00); -} - -void c67x00_sched_kick(struct c67x00_hcd *c67x00) -{ - tasklet_hi_schedule(&c67x00->tasklet); -} - -int c67x00_sched_start_scheduler(struct c67x00_hcd *c67x00) -{ - tasklet_init(&c67x00->tasklet, c67x00_sched_tasklet, - (unsigned long)c67x00); - return 0; -} - -void c67x00_sched_stop_scheduler(struct c67x00_hcd *c67x00) -{ - tasklet_kill(&c67x00->tasklet); -} diff --git a/trunk/drivers/usb/c67x00/c67x00.h b/trunk/drivers/usb/c67x00/c67x00.h deleted file mode 100644 index a26e9ded0f32..000000000000 --- a/trunk/drivers/usb/c67x00/c67x00.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * c67x00.h: Cypress C67X00 USB register and field definitions - * - * Copyright (C) 2006-2008 Barco N.V. - * Derived from the Cypress cy7c67200/300 ezusb linux driver and - * based on multiple host controller drivers inside the linux kernel. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#ifndef _USB_C67X00_H -#define _USB_C67X00_H - -#include -#include -#include -#include - -/* --------------------------------------------------------------------- - * Cypress C67x00 register definitions - */ - -/* Hardware Revision Register */ -#define HW_REV_REG 0xC004 - -/* General USB registers */ -/* ===================== */ - -/* USB Control Register */ -#define USB_CTL_REG(x) ((x) ? 0xC0AA : 0xC08A) - -#define LOW_SPEED_PORT(x) ((x) ? 0x0800 : 0x0400) -#define HOST_MODE 0x0200 -#define PORT_RES_EN(x) ((x) ? 0x0100 : 0x0080) -#define SOF_EOP_EN(x) ((x) ? 0x0002 : 0x0001) - -/* USB status register - Notice it has different content in hcd/udc mode */ -#define USB_STAT_REG(x) ((x) ? 0xC0B0 : 0xC090) - -#define EP0_IRQ_FLG 0x0001 -#define EP1_IRQ_FLG 0x0002 -#define EP2_IRQ_FLG 0x0004 -#define EP3_IRQ_FLG 0x0008 -#define EP4_IRQ_FLG 0x0010 -#define EP5_IRQ_FLG 0x0020 -#define EP6_IRQ_FLG 0x0040 -#define EP7_IRQ_FLG 0x0080 -#define RESET_IRQ_FLG 0x0100 -#define SOF_EOP_IRQ_FLG 0x0200 -#define ID_IRQ_FLG 0x4000 -#define VBUS_IRQ_FLG 0x8000 - -/* USB Host only registers */ -/* ======================= */ - -/* Host n Control Register */ -#define HOST_CTL_REG(x) ((x) ? 0xC0A0 : 0xC080) - -#define PREAMBLE_EN 0x0080 /* Preamble enable */ -#define SEQ_SEL 0x0040 /* Data Toggle Sequence Bit Select */ -#define ISO_EN 0x0010 /* Isochronous enable */ -#define ARM_EN 0x0001 /* Arm operation */ - -/* Host n Interrupt Enable Register */ -#define HOST_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C) - -#define SOF_EOP_IRQ_EN 0x0200 /* SOF/EOP Interrupt Enable */ -#define SOF_EOP_TMOUT_IRQ_EN 0x0800 /* SOF/EOP Timeout Interrupt Enable */ -#define ID_IRQ_EN 0x4000 /* ID interrupt enable */ -#define VBUS_IRQ_EN 0x8000 /* VBUS interrupt enable */ -#define DONE_IRQ_EN 0x0001 /* Done Interrupt Enable */ - -/* USB status register */ -#define HOST_STAT_MASK 0x02FD -#define PORT_CONNECT_CHANGE(x) ((x) ? 0x0020 : 0x0010) -#define PORT_SE0_STATUS(x) ((x) ? 0x0008 : 0x0004) - -/* Host Frame Register */ -#define HOST_FRAME_REG(x) ((x) ? 0xC0B6 : 0xC096) - -#define HOST_FRAME_MASK 0x07FF - -/* USB Peripheral only registers */ -/* ============================= */ - -/* Device n Port Sel reg */ -#define DEVICE_N_PORT_SEL(x) ((x) ? 0xC0A4 : 0xC084) - -/* Device n Interrupt Enable Register */ -#define DEVICE_N_IRQ_EN_REG(x) ((x) ? 0xC0AC : 0xC08C) - -#define DEVICE_N_ENDPOINT_N_CTL_REG(dev, ep) ((dev) \ - ? (0x0280 + (ep << 4)) \ - : (0x0200 + (ep << 4))) -#define DEVICE_N_ENDPOINT_N_STAT_REG(dev, ep) ((dev) \ - ? (0x0286 + (ep << 4)) \ - : (0x0206 + (ep << 4))) - -#define DEVICE_N_ADDRESS(dev) ((dev) ? (0xC0AE) : (0xC08E)) - -/* HPI registers */ -/* ============= */ - -/* HPI Status register */ -#define SOFEOP_FLG(x) (1 << ((x) ? 12 : 10)) -#define SIEMSG_FLG(x) (1 << (4 + (x))) -#define RESET_FLG(x) ((x) ? 0x0200 : 0x0002) -#define DONE_FLG(x) (1 << (2 + (x))) -#define RESUME_FLG(x) (1 << (6 + (x))) -#define MBX_OUT_FLG 0x0001 /* Message out available */ -#define MBX_IN_FLG 0x0100 -#define ID_FLG 0x4000 -#define VBUS_FLG 0x8000 - -/* Interrupt routing register */ -#define HPI_IRQ_ROUTING_REG 0x0142 - -#define HPI_SWAP_ENABLE(x) ((x) ? 0x0100 : 0x0001) -#define RESET_TO_HPI_ENABLE(x) ((x) ? 0x0200 : 0x0002) -#define DONE_TO_HPI_ENABLE(x) ((x) ? 0x0008 : 0x0004) -#define RESUME_TO_HPI_ENABLE(x) ((x) ? 0x0080 : 0x0040) -#define SOFEOP_TO_HPI_EN(x) ((x) ? 0x2000 : 0x0800) -#define SOFEOP_TO_CPU_EN(x) ((x) ? 0x1000 : 0x0400) -#define ID_TO_HPI_ENABLE 0x4000 -#define VBUS_TO_HPI_ENABLE 0x8000 - -/* SIE msg registers */ -#define SIEMSG_REG(x) ((x) ? 0x0148 : 0x0144) - -#define HUSB_TDListDone 0x1000 - -#define SUSB_EP0_MSG 0x0001 -#define SUSB_EP1_MSG 0x0002 -#define SUSB_EP2_MSG 0x0004 -#define SUSB_EP3_MSG 0x0008 -#define SUSB_EP4_MSG 0x0010 -#define SUSB_EP5_MSG 0x0020 -#define SUSB_EP6_MSG 0x0040 -#define SUSB_EP7_MSG 0x0080 -#define SUSB_RST_MSG 0x0100 -#define SUSB_SOF_MSG 0x0200 -#define SUSB_CFG_MSG 0x0400 -#define SUSB_SUS_MSG 0x0800 -#define SUSB_ID_MSG 0x4000 -#define SUSB_VBUS_MSG 0x8000 - -/* BIOS interrupt routines */ - -#define SUSBx_RECEIVE_INT(x) ((x) ? 97 : 81) -#define SUSBx_SEND_INT(x) ((x) ? 96 : 80) - -#define SUSBx_DEV_DESC_VEC(x) ((x) ? 0x00D4 : 0x00B4) -#define SUSBx_CONF_DESC_VEC(x) ((x) ? 0x00D6 : 0x00B6) -#define SUSBx_STRING_DESC_VEC(x) ((x) ? 0x00D8 : 0x00B8) - -#define CY_HCD_BUF_ADDR 0x500 /* Base address for host */ -#define SIE_TD_SIZE 0x200 /* size of the td list */ -#define SIE_TD_BUF_SIZE 0x400 /* size of the data buffer */ - -#define SIE_TD_OFFSET(host) ((host) ? (SIE_TD_SIZE+SIE_TD_BUF_SIZE) : 0) -#define SIE_BUF_OFFSET(host) (SIE_TD_OFFSET(host) + SIE_TD_SIZE) - -/* Base address of HCD + 2 x TD_SIZE + 2 x TD_BUF_SIZE */ -#define CY_UDC_REQ_HEADER_BASE 0x1100 -/* 8- byte request headers for IN/OUT transfers */ -#define CY_UDC_REQ_HEADER_SIZE 8 - -#define CY_UDC_REQ_HEADER_ADDR(ep_num) (CY_UDC_REQ_HEADER_BASE + \ - ((ep_num) * CY_UDC_REQ_HEADER_SIZE)) -#define CY_UDC_DESC_BASE_ADDRESS (CY_UDC_REQ_HEADER_ADDR(8)) - -#define CY_UDC_BIOS_REPLACE_BASE 0x1800 -#define CY_UDC_REQ_BUFFER_BASE 0x2000 -#define CY_UDC_REQ_BUFFER_SIZE 0x0400 -#define CY_UDC_REQ_BUFFER_ADDR(ep_num) (CY_UDC_REQ_BUFFER_BASE + \ - ((ep_num) * CY_UDC_REQ_BUFFER_SIZE)) - -/* --------------------------------------------------------------------- - * Driver data structures - */ - -struct c67x00_device; - -/** - * struct c67x00_sie - Common data associated with a SIE - * @lock: lock to protect this struct and the associated chip registers - * @private_data: subdriver dependent data - * @irq: subdriver dependent irq handler, set NULL when not used - * @dev: link to common driver structure - * @sie_num: SIE number on chip, starting from 0 - * @mode: SIE mode (host/peripheral/otg/not used) - */ -struct c67x00_sie { - /* Entries to be used by the subdrivers */ - spinlock_t lock; /* protect this structure */ - void *private_data; - void (*irq) (struct c67x00_sie *sie, u16 int_status, u16 msg); - - /* Read only: */ - struct c67x00_device *dev; - int sie_num; - int mode; -}; - -#define sie_dev(s) (&(s)->dev->pdev->dev) - -/** - * struct c67x00_lcp - */ -struct c67x00_lcp { - /* Internal use only */ - struct mutex mutex; - struct completion msg_received; - u16 last_msg; -}; - -/* - * struct c67x00_hpi - */ -struct c67x00_hpi { - void __iomem *base; - int regstep; - spinlock_t lock; - struct c67x00_lcp lcp; -}; - -#define C67X00_SIES 2 -#define C67X00_PORTS 2 - -/** - * struct c67x00_device - Common data associated with a c67x00 instance - * @hpi: hpi addresses - * @sie: array of sie's on this chip - * @pdev: platform device of instance - * @pdata: configuration provided by the platform - */ -struct c67x00_device { - struct c67x00_hpi hpi; - struct c67x00_sie sie[C67X00_SIES]; - struct platform_device *pdev; - struct c67x00_platform_data *pdata; -}; - -/* --------------------------------------------------------------------- - * Low level interface functions - */ - -/* Host Port Interface (HPI) functions */ -u16 c67x00_ll_hpi_status(struct c67x00_device *dev); -void c67x00_ll_hpi_reg_init(struct c67x00_device *dev); -void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie); -void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie); - -/* General functions */ -u16 c67x00_ll_fetch_siemsg(struct c67x00_device *dev, int sie_num); -u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie); -void c67x00_ll_usb_clear_status(struct c67x00_sie *sie, u16 bits); -u16 c67x00_ll_usb_get_status(struct c67x00_sie *sie); -void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len); -void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, - void *data, int len); - -/* Host specific functions */ -void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value); -void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port); -void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr); -u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie); -u16 c67x00_ll_husb_get_frame(struct c67x00_sie *sie); -void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie); -void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port); - -/* Called by c67x00_irq to handle lcp interrupts */ -void c67x00_ll_irq(struct c67x00_device *dev, u16 int_status); - -/* Setup and teardown */ -void c67x00_ll_init(struct c67x00_device *dev); -void c67x00_ll_release(struct c67x00_device *dev); -int c67x00_ll_reset(struct c67x00_device *dev); - -#endif /* _USB_C67X00_H */ diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 3e69266e1f4d..e819e5359d57 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -394,9 +394,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, if (!io->urbs) goto nomem; - urb_flags = URB_NO_INTERRUPT; - if (dma) - urb_flags |= URB_NO_TRANSFER_DMA_MAP; + urb_flags = URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT; if (usb_pipein(pipe)) urb_flags |= URB_SHORT_NOT_OK; diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 6e784d2db423..f7b54651dd42 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -231,26 +231,6 @@ config SUPERH_BUILT_IN_M66592 However, this problem is improved if change a value of NET_IP_ALIGN to 4. -config USB_GADGET_PXA27X - boolean "PXA 27x" - depends on ARCH_PXA && PXA27x - help - Intel's PXA 27x series XScale ARM v5TE processors include - an integrated full speed USB 1.1 device controller. - - It has up to 23 endpoints, as well as endpoint zero (for - control transfers). - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "pxa27x_udc" and force all - gadget drivers to also be dynamically linked. - -config USB_PXA27X - tristate - depends on USB_GADGET_PXA27X - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_GOKU boolean "Toshiba TC86C001 'Goku-S'" depends on PCI diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index 12357255d740..c3aab80b6c76 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2280) += net2280.o obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o -obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 8d61ea67a817..bb93bdd76593 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -235,6 +235,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif +#ifdef CONFIG_USB_GADGET_PXA27X +#define DEV_CONFIG_CDC +#endif + #ifdef CONFIG_USB_GADGET_S3C2410 #define DEV_CONFIG_CDC #endif @@ -266,10 +270,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_SUBSET #endif -#ifdef CONFIG_USB_GADGET_PXA27X -#define DEV_CONFIG_SUBSET -#endif - #ifdef CONFIG_USB_GADGET_SUPERH #define DEV_CONFIG_SUBSET #endif diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 47bb9f09a1aa..bf3f946fd455 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -2307,29 +2307,6 @@ static int halt_bulk_in_endpoint(struct fsg_dev *fsg) return rc; } -static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) -{ - int rc; - - DBG(fsg, "bulk-in set wedge\n"); - rc = usb_ep_set_wedge(fsg->bulk_in); - if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint wedge\n"); - while (rc != 0) { - if (rc != -EAGAIN) { - WARN(fsg, "usb_ep_set_wedge -> %d\n", rc); - rc = 0; - break; - } - - /* Wait for a short time and then try again */ - if (msleep_interruptible(100) != 0) - return -EINTR; - rc = usb_ep_set_wedge(fsg->bulk_in); - } - return rc; -} - static int pad_with_zeros(struct fsg_dev *fsg) { struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; @@ -2980,7 +2957,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) * We aren't required to halt the OUT endpoint; instead * we can simply accept and discard any data received * until the next reset. */ - wedge_bulk_in_endpoint(fsg); + halt_bulk_in_endpoint(fsg); set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); return -EINVAL; } diff --git a/trunk/drivers/usb/gadget/pxa27x_udc.c b/trunk/drivers/usb/gadget/pxa27x_udc.c deleted file mode 100644 index 75eba202f737..000000000000 --- a/trunk/drivers/usb/gadget/pxa27x_udc.c +++ /dev/null @@ -1,2404 +0,0 @@ -/* - * Handles the Intel 27x USB Device Controller (UDC) - * - * Inspired by original driver by Frank Becker, David Brownell, and others. - * Copyright (C) 2008 Robert Jarzmik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include "pxa27x_udc.h" - -/* - * This driver handles the USB Device Controller (UDC) in Intel's PXA 27x - * series processors. - * - * Such controller drivers work with a gadget driver. The gadget driver - * returns descriptors, implements configuration and data protocols used - * by the host to interact with this device, and allocates endpoints to - * the different protocol interfaces. The controller driver virtualizes - * usb hardware so that the gadget drivers will be more portable. - * - * This UDC hardware wants to implement a bit too much USB protocol. The - * biggest issues are: that the endpoints have to be set up before the - * controller can be enabled (minor, and not uncommon); and each endpoint - * can only have one configuration, interface and alternative interface - * number (major, and very unusual). Once set up, these cannot be changed - * without a controller reset. - * - * The workaround is to setup all combinations necessary for the gadgets which - * will work with this driver. This is done in pxa_udc structure, statically. - * See pxa_udc, udc_usb_ep versus pxa_ep, and matching function find_pxa_ep. - * (You could modify this if needed. Some drivers have a "fifo_mode" module - * parameter to facilitate such changes.) - * - * The combinations have been tested with these gadgets : - * - zero gadget - * - file storage gadget - * - ether gadget - * - * The driver doesn't use DMA, only IO access and IRQ callbacks. No use is - * made of UDC's double buffering either. USB "On-The-Go" is not implemented. - * - * All the requests are handled the same way : - * - the drivers tries to handle the request directly to the IO - * - if the IO fifo is not big enough, the remaining is send/received in - * interrupt handling. - */ - -#define DRIVER_VERSION "2008-04-18" -#define DRIVER_DESC "PXA 27x USB Device Controller driver" - -static const char driver_name[] = "pxa27x_udc"; -static struct pxa_udc *the_controller; - -static void handle_ep(struct pxa_ep *ep); - -/* - * Debug filesystem - */ -#ifdef CONFIG_USB_GADGET_DEBUG_FS - -#include -#include -#include - -static int state_dbg_show(struct seq_file *s, void *p) -{ - struct pxa_udc *udc = s->private; - int pos = 0, ret; - u32 tmp; - - ret = -ENODEV; - if (!udc->driver) - goto out; - - /* basic device status */ - pos += seq_printf(s, DRIVER_DESC "\n" - "%s version: %s\nGadget driver: %s\n", - driver_name, DRIVER_VERSION, - udc->driver ? udc->driver->driver.name : "(none)"); - - tmp = udc_readl(udc, UDCCR); - pos += seq_printf(s, - "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), " - "con=%d,inter=%d,altinter=%d\n", tmp, - (tmp & UDCCR_OEN) ? " oen":"", - (tmp & UDCCR_AALTHNP) ? " aalthnp":"", - (tmp & UDCCR_AHNP) ? " rem" : "", - (tmp & UDCCR_BHNP) ? " rstir" : "", - (tmp & UDCCR_DWRE) ? " dwre" : "", - (tmp & UDCCR_SMAC) ? " smac" : "", - (tmp & UDCCR_EMCE) ? " emce" : "", - (tmp & UDCCR_UDR) ? " udr" : "", - (tmp & UDCCR_UDA) ? " uda" : "", - (tmp & UDCCR_UDE) ? " ude" : "", - (tmp & UDCCR_ACN) >> UDCCR_ACN_S, - (tmp & UDCCR_AIN) >> UDCCR_AIN_S, - (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S); - /* registers for device and ep0 */ - pos += seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n", - udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1)); - pos += seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n", - udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1)); - pos += seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR)); - pos += seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, " - "reconfig=%lu\n", - udc->stats.irqs_reset, udc->stats.irqs_suspend, - udc->stats.irqs_resume, udc->stats.irqs_reconfig); - - ret = 0; -out: - return ret; -} - -static int queues_dbg_show(struct seq_file *s, void *p) -{ - struct pxa_udc *udc = s->private; - struct pxa_ep *ep; - struct pxa27x_request *req; - int pos = 0, i, maxpkt, ret; - - ret = -ENODEV; - if (!udc->driver) - goto out; - - /* dump endpoint queues */ - for (i = 0; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - maxpkt = ep->fifo_size; - pos += seq_printf(s, "%-12s max_pkt=%d %s\n", - EPNAME(ep), maxpkt, "pio"); - - if (list_empty(&ep->queue)) { - pos += seq_printf(s, "\t(nothing queued)\n"); - continue; - } - - list_for_each_entry(req, &ep->queue, queue) { - pos += seq_printf(s, "\treq %p len %d/%d buf %p\n", - &req->req, req->req.actual, - req->req.length, req->req.buf); - } - } - - ret = 0; -out: - return ret; -} - -static int eps_dbg_show(struct seq_file *s, void *p) -{ - struct pxa_udc *udc = s->private; - struct pxa_ep *ep; - int pos = 0, i, ret; - u32 tmp; - - ret = -ENODEV; - if (!udc->driver) - goto out; - - ep = &udc->pxa_ep[0]; - tmp = udc_ep_readl(ep, UDCCSR); - pos += seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n", tmp, - (tmp & UDCCSR0_SA) ? " sa" : "", - (tmp & UDCCSR0_RNE) ? " rne" : "", - (tmp & UDCCSR0_FST) ? " fst" : "", - (tmp & UDCCSR0_SST) ? " sst" : "", - (tmp & UDCCSR0_DME) ? " dme" : "", - (tmp & UDCCSR0_IPR) ? " ipr" : "", - (tmp & UDCCSR0_OPC) ? " opc" : ""); - for (i = 0; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - tmp = i? udc_ep_readl(ep, UDCCR) : udc_readl(udc, UDCCR); - pos += seq_printf(s, "%-12s: " - "IN %lu(%lu reqs), OUT %lu(%lu reqs), " - "irqs=%lu, udccr=0x%08x, udccsr=0x%03x, " - "udcbcr=%d\n", - EPNAME(ep), - ep->stats.in_bytes, ep->stats.in_ops, - ep->stats.out_bytes, ep->stats.out_ops, - ep->stats.irqs, - tmp, udc_ep_readl(ep, UDCCSR), - udc_ep_readl(ep, UDCBCR)); - } - - ret = 0; -out: - return ret; -} - -static int eps_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, eps_dbg_show, inode->i_private); -} - -static int queues_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, queues_dbg_show, inode->i_private); -} - -static int state_dbg_open(struct inode *inode, struct file *file) -{ - return single_open(file, state_dbg_show, inode->i_private); -} - -static const struct file_operations state_dbg_fops = { - .owner = THIS_MODULE, - .open = state_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations queues_dbg_fops = { - .owner = THIS_MODULE, - .open = queues_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static const struct file_operations eps_dbg_fops = { - .owner = THIS_MODULE, - .open = eps_dbg_open, - .llseek = seq_lseek, - .read = seq_read, - .release = single_release, -}; - -static void pxa_init_debugfs(struct pxa_udc *udc) -{ - struct dentry *root, *state, *queues, *eps; - - root = debugfs_create_dir(udc->gadget.name, NULL); - if (IS_ERR(root) || !root) - goto err_root; - - state = debugfs_create_file("udcstate", 0400, root, udc, - &state_dbg_fops); - if (!state) - goto err_state; - queues = debugfs_create_file("queues", 0400, root, udc, - &queues_dbg_fops); - if (!queues) - goto err_queues; - eps = debugfs_create_file("epstate", 0400, root, udc, - &eps_dbg_fops); - if (!queues) - goto err_eps; - - udc->debugfs_root = root; - udc->debugfs_state = state; - udc->debugfs_queues = queues; - udc->debugfs_eps = eps; - return; -err_eps: - debugfs_remove(eps); -err_queues: - debugfs_remove(queues); -err_state: - debugfs_remove(root); -err_root: - dev_err(udc->dev, "debugfs is not available\n"); -} - -static void pxa_cleanup_debugfs(struct pxa_udc *udc) -{ - debugfs_remove(udc->debugfs_eps); - debugfs_remove(udc->debugfs_queues); - debugfs_remove(udc->debugfs_state); - debugfs_remove(udc->debugfs_root); - udc->debugfs_eps = NULL; - udc->debugfs_queues = NULL; - udc->debugfs_state = NULL; - udc->debugfs_root = NULL; -} - -#else -static inline void pxa_init_debugfs(struct pxa_udc *udc) -{ -} - -static inline void pxa_cleanup_debugfs(struct pxa_udc *udc) -{ -} -#endif - -/** - * is_match_usb_pxa - check if usb_ep and pxa_ep match - * @udc_usb_ep: usb endpoint - * @ep: pxa endpoint - * @config: configuration required in pxa_ep - * @interface: interface required in pxa_ep - * @altsetting: altsetting required in pxa_ep - * - * Returns 1 if all criteria match between pxa and usb endpoint, 0 otherwise - */ -static int is_match_usb_pxa(struct udc_usb_ep *udc_usb_ep, struct pxa_ep *ep, - int config, int interface, int altsetting) -{ - if (usb_endpoint_num(&udc_usb_ep->desc) != ep->addr) - return 0; - if (usb_endpoint_dir_in(&udc_usb_ep->desc) != ep->dir_in) - return 0; - if (usb_endpoint_type(&udc_usb_ep->desc) != ep->type) - return 0; - if ((ep->config != config) || (ep->interface != interface) - || (ep->alternate != altsetting)) - return 0; - return 1; -} - -/** - * find_pxa_ep - find pxa_ep structure matching udc_usb_ep - * @udc: pxa udc - * @udc_usb_ep: udc_usb_ep structure - * - * Match udc_usb_ep and all pxa_ep available, to see if one matches. - * This is necessary because of the strong pxa hardware restriction requiring - * that once pxa endpoints are initialized, their configuration is freezed, and - * no change can be made to their address, direction, or in which configuration, - * interface or altsetting they are active ... which differs from more usual - * models which have endpoints be roughly just addressable fifos, and leave - * configuration events up to gadget drivers (like all control messages). - * - * Note that there is still a blurred point here : - * - we rely on UDCCR register "active interface" and "active altsetting". - * This is a nonsense in regard of USB spec, where multiple interfaces are - * active at the same time. - * - if we knew for sure that the pxa can handle multiple interface at the - * same time, assuming Intel's Developer Guide is wrong, this function - * should be reviewed, and a cache of couples (iface, altsetting) should - * be kept in the pxa_udc structure. In this case this function would match - * against the cache of couples instead of the "last altsetting" set up. - * - * Returns the matched pxa_ep structure or NULL if none found - */ -static struct pxa_ep *find_pxa_ep(struct pxa_udc *udc, - struct udc_usb_ep *udc_usb_ep) -{ - int i; - struct pxa_ep *ep; - int cfg = udc->config; - int iface = udc->last_interface; - int alt = udc->last_alternate; - - if (udc_usb_ep == &udc->udc_usb_ep[0]) - return &udc->pxa_ep[0]; - - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - if (is_match_usb_pxa(udc_usb_ep, ep, cfg, iface, alt)) - return ep; - } - return NULL; -} - -/** - * update_pxa_ep_matches - update pxa_ep cached values in all udc_usb_ep - * @udc: pxa udc - * - * Context: in_interrupt() - * - * Updates all pxa_ep fields in udc_usb_ep structures, if this field was - * previously set up (and is not NULL). The update is necessary is a - * configuration change or altsetting change was issued by the USB host. - */ -static void update_pxa_ep_matches(struct pxa_udc *udc) -{ - int i; - struct udc_usb_ep *udc_usb_ep; - - for (i = 1; i < NR_USB_ENDPOINTS; i++) { - udc_usb_ep = &udc->udc_usb_ep[i]; - if (udc_usb_ep->pxa_ep) - udc_usb_ep->pxa_ep = find_pxa_ep(udc, udc_usb_ep); - } -} - -/** - * pio_irq_enable - Enables irq generation for one endpoint - * @ep: udc endpoint - */ -static void pio_irq_enable(struct pxa_ep *ep) -{ - struct pxa_udc *udc = ep->dev; - int index = EPIDX(ep); - u32 udcicr0 = udc_readl(udc, UDCICR0); - u32 udcicr1 = udc_readl(udc, UDCICR1); - - if (index < 16) - udc_writel(udc, UDCICR0, udcicr0 | (3 << (index * 2))); - else - udc_writel(udc, UDCICR1, udcicr1 | (3 << ((index - 16) * 2))); -} - -/** - * pio_irq_disable - Disables irq generation for one endpoint - * @ep: udc endpoint - * @index: endpoint number - */ -static void pio_irq_disable(struct pxa_ep *ep) -{ - struct pxa_udc *udc = ep->dev; - int index = EPIDX(ep); - u32 udcicr0 = udc_readl(udc, UDCICR0); - u32 udcicr1 = udc_readl(udc, UDCICR1); - - if (index < 16) - udc_writel(udc, UDCICR0, udcicr0 & ~(3 << (index * 2))); - else - udc_writel(udc, UDCICR1, udcicr1 & ~(3 << ((index - 16) * 2))); -} - -/** - * udc_set_mask_UDCCR - set bits in UDCCR - * @udc: udc device - * @mask: bits to set in UDCCR - * - * Sets bits in UDCCR, leaving DME and FST bits as they were. - */ -static inline void udc_set_mask_UDCCR(struct pxa_udc *udc, int mask) -{ - u32 udccr = udc_readl(udc, UDCCR); - udc_writel(udc, UDCCR, - (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS)); -} - -/** - * udc_clear_mask_UDCCR - clears bits in UDCCR - * @udc: udc device - * @mask: bit to clear in UDCCR - * - * Clears bits in UDCCR, leaving DME and FST bits as they were. - */ -static inline void udc_clear_mask_UDCCR(struct pxa_udc *udc, int mask) -{ - u32 udccr = udc_readl(udc, UDCCR); - udc_writel(udc, UDCCR, - (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS)); -} - -/** - * ep_count_bytes_remain - get how many bytes in udc endpoint - * @ep: udc endpoint - * - * Returns number of bytes in OUT fifos. Broken for IN fifos (-EOPNOTSUPP) - */ -static int ep_count_bytes_remain(struct pxa_ep *ep) -{ - if (ep->dir_in) - return -EOPNOTSUPP; - return udc_ep_readl(ep, UDCBCR) & 0x3ff; -} - -/** - * ep_is_empty - checks if ep has byte ready for reading - * @ep: udc endpoint - * - * If endpoint is the control endpoint, checks if there are bytes in the - * control endpoint fifo. If endpoint is a data endpoint, checks if bytes - * are ready for reading on OUT endpoint. - * - * Returns 0 if ep not empty, 1 if ep empty, -EOPNOTSUPP if IN endpoint - */ -static int ep_is_empty(struct pxa_ep *ep) -{ - int ret; - - if (!is_ep0(ep) && ep->dir_in) - return -EOPNOTSUPP; - if (is_ep0(ep)) - ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR0_RNE); - else - ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNE); - return ret; -} - -/** - * ep_is_full - checks if ep has place to write bytes - * @ep: udc endpoint - * - * If endpoint is not the control endpoint and is an IN endpoint, checks if - * there is place to write bytes into the endpoint. - * - * Returns 0 if ep not full, 1 if ep full, -EOPNOTSUPP if OUT endpoint - */ -static int ep_is_full(struct pxa_ep *ep) -{ - if (is_ep0(ep)) - return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_IPR); - if (!ep->dir_in) - return -EOPNOTSUPP; - return (!(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNF)); -} - -/** - * epout_has_pkt - checks if OUT endpoint fifo has a packet available - * @ep: pxa endpoint - * - * Returns 1 if a complete packet is available, 0 if not, -EOPNOTSUPP for IN ep. - */ -static int epout_has_pkt(struct pxa_ep *ep) -{ - if (!is_ep0(ep) && ep->dir_in) - return -EOPNOTSUPP; - if (is_ep0(ep)) - return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_OPC); - return (udc_ep_readl(ep, UDCCSR) & UDCCSR_PC); -} - -/** - * set_ep0state - Set ep0 automata state - * @dev: udc device - * @state: state - */ -static void set_ep0state(struct pxa_udc *udc, int state) -{ - struct pxa_ep *ep = &udc->pxa_ep[0]; - char *old_stname = EP0_STNAME(udc); - - udc->ep0state = state; - ep_dbg(ep, "state=%s->%s, udccsr0=0x%03x, udcbcr=%d\n", old_stname, - EP0_STNAME(udc), udc_ep_readl(ep, UDCCSR), - udc_ep_readl(ep, UDCBCR)); -} - -/** - * ep0_idle - Put control endpoint into idle state - * @dev: udc device - */ -static void ep0_idle(struct pxa_udc *dev) -{ - set_ep0state(dev, WAIT_FOR_SETUP); -} - -/** - * inc_ep_stats_reqs - Update ep stats counts - * @ep: physical endpoint - * @req: usb request - * @is_in: ep direction (USB_DIR_IN or 0) - * - */ -static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in) -{ - if (is_in) - ep->stats.in_ops++; - else - ep->stats.out_ops++; -} - -/** - * inc_ep_stats_bytes - Update ep stats counts - * @ep: physical endpoint - * @count: bytes transfered on endpoint - * @req: usb request - * @is_in: ep direction (USB_DIR_IN or 0) - */ -static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in) -{ - if (is_in) - ep->stats.in_bytes += count; - else - ep->stats.out_bytes += count; -} - -/** - * pxa_ep_setup - Sets up an usb physical endpoint - * @ep: pxa27x physical endpoint - * - * Find the physical pxa27x ep, and setup its UDCCR - */ -static __init void pxa_ep_setup(struct pxa_ep *ep) -{ - u32 new_udccr; - - new_udccr = ((ep->config << UDCCONR_CN_S) & UDCCONR_CN) - | ((ep->interface << UDCCONR_IN_S) & UDCCONR_IN) - | ((ep->alternate << UDCCONR_AISN_S) & UDCCONR_AISN) - | ((EPADDR(ep) << UDCCONR_EN_S) & UDCCONR_EN) - | ((EPXFERTYPE(ep) << UDCCONR_ET_S) & UDCCONR_ET) - | ((ep->dir_in) ? UDCCONR_ED : 0) - | ((ep->fifo_size << UDCCONR_MPS_S) & UDCCONR_MPS) - | UDCCONR_EE; - - udc_ep_writel(ep, UDCCR, new_udccr); -} - -/** - * pxa_eps_setup - Sets up all usb physical endpoints - * @dev: udc device - * - * Setup all pxa physical endpoints, except ep0 - */ -static __init void pxa_eps_setup(struct pxa_udc *dev) -{ - unsigned int i; - - dev_dbg(dev->dev, "%s: dev=%p\n", __func__, dev); - - for (i = 1; i < NR_PXA_ENDPOINTS; i++) - pxa_ep_setup(&dev->pxa_ep[i]); -} - -/** - * pxa_ep_alloc_request - Allocate usb request - * @_ep: usb endpoint - * @gfp_flags: - * - * For the pxa27x, these can just wrap kmalloc/kfree. gadget drivers - * must still pass correctly initialized endpoints, since other controller - * drivers may care about how it's currently set up (dma issues etc). - */ -static struct usb_request * -pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) -{ - struct pxa27x_request *req; - - req = kzalloc(sizeof *req, gfp_flags); - if (!req || !_ep) - return NULL; - - INIT_LIST_HEAD(&req->queue); - req->in_use = 0; - req->udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - - return &req->req; -} - -/** - * pxa_ep_free_request - Free usb request - * @_ep: usb endpoint - * @_req: usb request - * - * Wrapper around kfree to free _req - */ -static void pxa_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) -{ - struct pxa27x_request *req; - - req = container_of(_req, struct pxa27x_request, req); - WARN_ON(!list_empty(&req->queue)); - kfree(req); -} - -/** - * ep_add_request - add a request to the endpoint's queue - * @ep: usb endpoint - * @req: usb request - * - * Context: ep->lock held - * - * Queues the request in the endpoint's queue, and enables the interrupts - * on the endpoint. - */ -static void ep_add_request(struct pxa_ep *ep, struct pxa27x_request *req) -{ - if (unlikely(!req)) - return; - ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req, - req->req.length, udc_ep_readl(ep, UDCCSR)); - - req->in_use = 1; - list_add_tail(&req->queue, &ep->queue); - pio_irq_enable(ep); -} - -/** - * ep_del_request - removes a request from the endpoint's queue - * @ep: usb endpoint - * @req: usb request - * - * Context: ep->lock held - * - * Unqueue the request from the endpoint's queue. If there are no more requests - * on the endpoint, and if it's not the control endpoint, interrupts are - * disabled on the endpoint. - */ -static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req) -{ - if (unlikely(!req)) - return; - ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req, - req->req.length, udc_ep_readl(ep, UDCCSR)); - - list_del_init(&req->queue); - req->in_use = 0; - if (!is_ep0(ep) && list_empty(&ep->queue)) - pio_irq_disable(ep); -} - -/** - * req_done - Complete an usb request - * @ep: pxa physical endpoint - * @req: pxa request - * @status: usb request status sent to gadget API - * - * Context: ep->lock held - * - * Retire a pxa27x usb request. Endpoint must be locked. - */ -static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) -{ - ep_del_request(ep, req); - if (likely(req->req.status == -EINPROGRESS)) - req->req.status = status; - else - status = req->req.status; - - if (status && status != -ESHUTDOWN) - ep_dbg(ep, "complete req %p stat %d len %u/%u\n", - &req->req, status, - req->req.actual, req->req.length); - - req->req.complete(&req->udc_usb_ep->usb_ep, &req->req); -} - -/** - * ep_end_out_req - Ends control endpoint in request - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends endpoint in request (completes usb request). - */ -static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - inc_ep_stats_reqs(ep, !USB_DIR_IN); - req_done(ep, req, 0); -} - -/** - * ep0_end_out_req - Ends control endpoint in request (ends data stage) - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends control endpoint in request (completes usb request), and puts - * control endpoint into idle state - */ -static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - set_ep0state(ep->dev, OUT_STATUS_STAGE); - ep_end_out_req(ep, req); - ep0_idle(ep->dev); -} - -/** - * ep_end_in_req - Ends endpoint out request - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends endpoint out request (completes usb request). - */ -static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - inc_ep_stats_reqs(ep, USB_DIR_IN); - req_done(ep, req, 0); -} - -/** - * ep0_end_in_req - Ends control endpoint out request (ends data stage) - * @ep: physical endpoint - * @req: pxa request - * - * Context: ep->lock held - * - * Ends control endpoint out request (completes usb request), and puts - * control endpoint into status state - */ -static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) -{ - struct pxa_udc *udc = ep->dev; - - set_ep0state(udc, IN_STATUS_STAGE); - ep_end_in_req(ep, req); -} - -/** - * nuke - Dequeue all requests - * @ep: pxa endpoint - * @status: usb request status - * - * Context: ep->lock held - * - * Dequeues all requests on an endpoint. As a side effect, interrupts will be - * disabled on that endpoint (because no more requests). - */ -static void nuke(struct pxa_ep *ep, int status) -{ - struct pxa27x_request *req; - - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, struct pxa27x_request, queue); - req_done(ep, req, status); - } -} - -/** - * read_packet - transfer 1 packet from an OUT endpoint into request - * @ep: pxa physical endpoint - * @req: usb request - * - * Takes bytes from OUT endpoint and transfers them info the usb request. - * If there is less space in request than bytes received in OUT endpoint, - * bytes are left in the OUT endpoint. - * - * Returns how many bytes were actually transfered - */ -static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req) -{ - u32 *buf; - int bytes_ep, bufferspace, count, i; - - bytes_ep = ep_count_bytes_remain(ep); - bufferspace = req->req.length - req->req.actual; - - buf = (u32 *)(req->req.buf + req->req.actual); - prefetchw(buf); - - if (likely(!ep_is_empty(ep))) - count = min(bytes_ep, bufferspace); - else /* zlp */ - count = 0; - - for (i = count; i > 0; i -= 4) - *buf++ = udc_ep_readl(ep, UDCDR); - req->req.actual += count; - - udc_ep_writel(ep, UDCCSR, UDCCSR_PC); - - return count; -} - -/** - * write_packet - transfer 1 packet from request into an IN endpoint - * @ep: pxa physical endpoint - * @req: usb request - * @max: max bytes that fit into endpoint - * - * Takes bytes from usb request, and transfers them into the physical - * endpoint. If there are no bytes to transfer, doesn't write anything - * to physical endpoint. - * - * Returns how many bytes were actually transfered. - */ -static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req, - unsigned int max) -{ - int length, count, remain, i; - u32 *buf; - u8 *buf_8; - - buf = (u32 *)(req->req.buf + req->req.actual); - prefetch(buf); - - length = min(req->req.length - req->req.actual, max); - req->req.actual += length; - - remain = length & 0x3; - count = length & ~(0x3); - for (i = count; i > 0 ; i -= 4) - udc_ep_writel(ep, UDCDR, *buf++); - - buf_8 = (u8 *)buf; - for (i = remain; i > 0; i--) - udc_ep_writeb(ep, UDCDR, *buf_8++); - - ep_vdbg(ep, "length=%d+%d, udccsr=0x%03x\n", count, remain, - udc_ep_readl(ep, UDCCSR)); - - return length; -} - -/** - * read_fifo - Transfer packets from OUT endpoint into usb request - * @ep: pxa physical endpoint - * @req: usb request - * - * Context: callable when in_interrupt() - * - * Unload as many packets as possible from the fifo we use for usb OUT - * transfers and put them into the request. Caller should have made sure - * there's at least one packet ready. - * Doesn't complete the request, that's the caller's job - * - * Returns 1 if the request completed, 0 otherwise - */ -static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - int count, is_short, completed = 0; - - while (epout_has_pkt(ep)) { - count = read_packet(ep, req); - inc_ep_stats_bytes(ep, count, !USB_DIR_IN); - - is_short = (count < ep->fifo_size); - ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n", - udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "", - &req->req, req->req.actual, req->req.length); - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - completed = 1; - break; - } - /* finished that packet. the next one may be waiting... */ - } - return completed; -} - -/** - * write_fifo - transfer packets from usb request into an IN endpoint - * @ep: pxa physical endpoint - * @req: pxa usb request - * - * Write to an IN endpoint fifo, as many packets as possible. - * irqs will use this to write the rest later. - * caller guarantees at least one packet buffer is ready (or a zlp). - * Doesn't complete the request, that's the caller's job - * - * Returns 1 if request fully transfered, 0 if partial transfer - */ -static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - unsigned max; - int count, is_short, is_last = 0, completed = 0, totcount = 0; - u32 udccsr; - - max = ep->fifo_size; - do { - is_short = 0; - - udccsr = udc_ep_readl(ep, UDCCSR); - if (udccsr & UDCCSR_PC) { - ep_vdbg(ep, "Clearing Transmit Complete, udccsr=%x\n", - udccsr); - udc_ep_writel(ep, UDCCSR, UDCCSR_PC); - } - if (udccsr & UDCCSR_TRN) { - ep_vdbg(ep, "Clearing Underrun on, udccsr=%x\n", - udccsr); - udc_ep_writel(ep, UDCCSR, UDCCSR_TRN); - } - - count = write_packet(ep, req, max); - inc_ep_stats_bytes(ep, count, USB_DIR_IN); - totcount += count; - - /* last packet is usually short (or a zlp) */ - if (unlikely(count < max)) { - is_last = 1; - is_short = 1; - } else { - if (likely(req->req.length > req->req.actual) - || req->req.zero) - is_last = 0; - else - is_last = 1; - /* interrupt/iso maxpacket may not fill the fifo */ - is_short = unlikely(max < ep->fifo_size); - } - - if (is_short) - udc_ep_writel(ep, UDCCSR, UDCCSR_SP); - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - completed = 1; - break; - } - } while (!ep_is_full(ep)); - - ep_dbg(ep, "wrote count:%d bytes%s%s, left:%d req=%p\n", - totcount, is_last ? "/L" : "", is_short ? "/S" : "", - req->req.length - req->req.actual, &req->req); - - return completed; -} - -/** - * read_ep0_fifo - Transfer packets from control endpoint into usb request - * @ep: control endpoint - * @req: pxa usb request - * - * Special ep0 version of the above read_fifo. Reads as many bytes from control - * endpoint as can be read, and stores them into usb request (limited by request - * maximum length). - * - * Returns 0 if usb request only partially filled, 1 if fully filled - */ -static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - int count, is_short, completed = 0; - - while (epout_has_pkt(ep)) { - count = read_packet(ep, req); - udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC); - inc_ep_stats_bytes(ep, count, !USB_DIR_IN); - - is_short = (count < ep->fifo_size); - ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n", - udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "", - &req->req, req->req.actual, req->req.length); - - if (is_short || req->req.actual >= req->req.length) { - completed = 1; - break; - } - } - - return completed; -} - -/** - * write_ep0_fifo - Send a request to control endpoint (ep0 in) - * @ep: control endpoint - * @req: request - * - * Context: callable when in_interrupt() - * - * Sends a request (or a part of the request) to the control endpoint (ep0 in). - * If the request doesn't fit, the remaining part will be sent from irq. - * The request is considered fully written only if either : - * - last write transfered all remaining bytes, but fifo was not fully filled - * - last write was a 0 length write - * - * Returns 1 if request fully written, 0 if request only partially sent - */ -static int write_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req) -{ - unsigned count; - int is_last, is_short; - - count = write_packet(ep, req, EP0_FIFO_SIZE); - inc_ep_stats_bytes(ep, count, USB_DIR_IN); - - is_short = (count < EP0_FIFO_SIZE); - is_last = ((count == 0) || (count < EP0_FIFO_SIZE)); - - /* Sends either a short packet or a 0 length packet */ - if (unlikely(is_short)) - udc_ep_writel(ep, UDCCSR, UDCCSR0_IPR); - - ep_dbg(ep, "in %d bytes%s%s, %d left, req=%p, udccsr0=0x%03x\n", - count, is_short ? "/S" : "", is_last ? "/L" : "", - req->req.length - req->req.actual, - &req->req, udc_ep_readl(ep, UDCCSR)); - - return is_last; -} - -/** - * pxa_ep_queue - Queue a request into an IN endpoint - * @_ep: usb endpoint - * @_req: usb request - * @gfp_flags: flags - * - * Context: normally called when !in_interrupt, but callable when in_interrupt() - * in the special case of ep0 setup : - * (irq->handle_ep0_ctrl_req->gadget_setup->pxa_ep_queue) - * - * Returns 0 if succedeed, error otherwise - */ -static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, - gfp_t gfp_flags) -{ - struct udc_usb_ep *udc_usb_ep; - struct pxa_ep *ep; - struct pxa27x_request *req; - struct pxa_udc *dev; - unsigned long flags; - int rc = 0; - int is_first_req; - unsigned length; - - req = container_of(_req, struct pxa27x_request, req); - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - - if (unlikely(!_req || !_req->complete || !_req->buf)) - return -EINVAL; - - if (unlikely(!_ep)) - return -EINVAL; - - dev = udc_usb_ep->dev; - ep = udc_usb_ep->pxa_ep; - if (unlikely(!ep)) - return -EINVAL; - - dev = ep->dev; - if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - ep_dbg(ep, "bogus device state\n"); - return -ESHUTDOWN; - } - - /* iso is always one packet per request, that's the only way - * we can report per-packet status. that also helps with dma. - */ - if (unlikely(EPXFERTYPE_is_ISO(ep) - && req->req.length > ep->fifo_size)) - return -EMSGSIZE; - - spin_lock_irqsave(&ep->lock, flags); - - is_first_req = list_empty(&ep->queue); - ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n", - _req, is_first_req ? "yes" : "no", - _req->length, _req->buf); - - if (!ep->enabled) { - _req->status = -ESHUTDOWN; - rc = -ESHUTDOWN; - goto out; - } - - if (req->in_use) { - ep_err(ep, "refusing to queue req %p (already queued)\n", req); - goto out; - } - - length = _req->length; - _req->status = -EINPROGRESS; - _req->actual = 0; - - ep_add_request(ep, req); - - if (is_ep0(ep)) { - switch (dev->ep0state) { - case WAIT_ACK_SET_CONF_INTERF: - if (length == 0) { - ep_end_in_req(ep, req); - } else { - ep_err(ep, "got a request of %d bytes while" - "in state WATI_ACK_SET_CONF_INTERF\n", - length); - ep_del_request(ep, req); - rc = -EL2HLT; - } - ep0_idle(ep->dev); - break; - case IN_DATA_STAGE: - if (!ep_is_full(ep)) - if (write_ep0_fifo(ep, req)) - ep0_end_in_req(ep, req); - break; - case OUT_DATA_STAGE: - if ((length == 0) || !epout_has_pkt(ep)) - if (read_ep0_fifo(ep, req)) - ep0_end_out_req(ep, req); - break; - default: - ep_err(ep, "odd state %s to send me a request\n", - EP0_STNAME(ep->dev)); - ep_del_request(ep, req); - rc = -EL2HLT; - break; - } - } else { - handle_ep(ep); - } - -out: - spin_unlock_irqrestore(&ep->lock, flags); - return rc; -} - -/** - * pxa_ep_dequeue - Dequeue one request - * @_ep: usb endpoint - * @_req: usb request - * - * Return 0 if no error, -EINVAL or -ECONNRESET otherwise - */ -static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - struct pxa27x_request *req; - unsigned long flags; - int rc; - - if (!_ep) - return -EINVAL; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return -EINVAL; - - spin_lock_irqsave(&ep->lock, flags); - - /* make sure it's actually queued on this endpoint */ - list_for_each_entry(req, &ep->queue, queue) { - if (&req->req == _req) - break; - } - - rc = -EINVAL; - if (&req->req != _req) - goto out; - - rc = 0; - req_done(ep, req, -ECONNRESET); -out: - spin_unlock_irqrestore(&ep->lock, flags); - return rc; -} - -/** - * pxa_ep_set_halt - Halts operations on one endpoint - * @_ep: usb endpoint - * @value: - * - * Returns 0 if no error, -EINVAL, -EROFS, -EAGAIN otherwise - */ -static int pxa_ep_set_halt(struct usb_ep *_ep, int value) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - unsigned long flags; - int rc; - - - if (!_ep) - return -EINVAL; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return -EINVAL; - - if (value == 0) { - /* - * This path (reset toggle+halt) is needed to implement - * SET_INTERFACE on normal hardware. but it can't be - * done from software on the PXA UDC, and the hardware - * forgets to do it as part of SET_INTERFACE automagic. - */ - ep_dbg(ep, "only host can clear halt\n"); - return -EROFS; - } - - spin_lock_irqsave(&ep->lock, flags); - - rc = -EAGAIN; - if (ep->dir_in && (ep_is_full(ep) || !list_empty(&ep->queue))) - goto out; - - /* FST, FEF bits are the same for control and non control endpoints */ - rc = 0; - udc_ep_writel(ep, UDCCSR, UDCCSR_FST | UDCCSR_FEF); - if (is_ep0(ep)) - set_ep0state(ep->dev, STALL); - -out: - spin_unlock_irqrestore(&ep->lock, flags); - return rc; -} - -/** - * pxa_ep_fifo_status - Get how many bytes in physical endpoint - * @_ep: usb endpoint - * - * Returns number of bytes in OUT fifos. Broken for IN fifos. - */ -static int pxa_ep_fifo_status(struct usb_ep *_ep) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - - if (!_ep) - return -ENODEV; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return -ENODEV; - - if (ep->dir_in) - return -EOPNOTSUPP; - if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN || ep_is_empty(ep)) - return 0; - else - return ep_count_bytes_remain(ep) + 1; -} - -/** - * pxa_ep_fifo_flush - Flushes one endpoint - * @_ep: usb endpoint - * - * Discards all data in one endpoint(IN or OUT), except control endpoint. - */ -static void pxa_ep_fifo_flush(struct usb_ep *_ep) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - unsigned long flags; - - if (!_ep) - return; - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep)) - return; - - spin_lock_irqsave(&ep->lock, flags); - - if (unlikely(!list_empty(&ep->queue))) - ep_dbg(ep, "called while queue list not empty\n"); - ep_dbg(ep, "called\n"); - - /* for OUT, just read and discard the FIFO contents. */ - if (!ep->dir_in) { - while (!ep_is_empty(ep)) - udc_ep_readl(ep, UDCDR); - } else { - /* most IN status is the same, but ISO can't stall */ - udc_ep_writel(ep, UDCCSR, - UDCCSR_PC | UDCCSR_FEF | UDCCSR_TRN - | (EPXFERTYPE_is_ISO(ep) ? 0 : UDCCSR_SST)); - } - - spin_unlock_irqrestore(&ep->lock, flags); - - return; -} - -/** - * pxa_ep_enable - Enables usb endpoint - * @_ep: usb endpoint - * @desc: usb endpoint descriptor - * - * Nothing much to do here, as ep configuration is done once and for all - * before udc is enabled. After udc enable, no physical endpoint configuration - * can be changed. - * Function makes sanity checks and flushes the endpoint. - */ -static int pxa_ep_enable(struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - struct pxa_udc *udc; - - if (!_ep || !desc) - return -EINVAL; - - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - if (udc_usb_ep->pxa_ep) { - ep = udc_usb_ep->pxa_ep; - ep_warn(ep, "usb_ep %s already enabled, doing nothing\n", - _ep->name); - } else { - ep = find_pxa_ep(udc_usb_ep->dev, udc_usb_ep); - } - - if (!ep || is_ep0(ep)) { - dev_err(udc_usb_ep->dev->dev, - "unable to match pxa_ep for ep %s\n", - _ep->name); - return -EINVAL; - } - - if ((desc->bDescriptorType != USB_DT_ENDPOINT) - || (ep->type != usb_endpoint_type(desc))) { - ep_err(ep, "type mismatch\n"); - return -EINVAL; - } - - if (ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) { - ep_err(ep, "bad maxpacket\n"); - return -ERANGE; - } - - udc_usb_ep->pxa_ep = ep; - udc = ep->dev; - - if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) { - ep_err(ep, "bogus device state\n"); - return -ESHUTDOWN; - } - - ep->enabled = 1; - - /* flush fifo (mostly for OUT buffers) */ - pxa_ep_fifo_flush(_ep); - - ep_dbg(ep, "enabled\n"); - return 0; -} - -/** - * pxa_ep_disable - Disable usb endpoint - * @_ep: usb endpoint - * - * Same as for pxa_ep_enable, no physical endpoint configuration can be - * changed. - * Function flushes the endpoint and related requests. - */ -static int pxa_ep_disable(struct usb_ep *_ep) -{ - struct pxa_ep *ep; - struct udc_usb_ep *udc_usb_ep; - unsigned long flags; - - if (!_ep) - return -EINVAL; - - udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); - ep = udc_usb_ep->pxa_ep; - if (!ep || is_ep0(ep) || !list_empty(&ep->queue)) - return -EINVAL; - - spin_lock_irqsave(&ep->lock, flags); - ep->enabled = 0; - nuke(ep, -ESHUTDOWN); - spin_unlock_irqrestore(&ep->lock, flags); - - pxa_ep_fifo_flush(_ep); - udc_usb_ep->pxa_ep = NULL; - - ep_dbg(ep, "disabled\n"); - return 0; -} - -static struct usb_ep_ops pxa_ep_ops = { - .enable = pxa_ep_enable, - .disable = pxa_ep_disable, - - .alloc_request = pxa_ep_alloc_request, - .free_request = pxa_ep_free_request, - - .queue = pxa_ep_queue, - .dequeue = pxa_ep_dequeue, - - .set_halt = pxa_ep_set_halt, - .fifo_status = pxa_ep_fifo_status, - .fifo_flush = pxa_ep_fifo_flush, -}; - - -/** - * pxa_udc_get_frame - Returns usb frame number - * @_gadget: usb gadget - */ -static int pxa_udc_get_frame(struct usb_gadget *_gadget) -{ - struct pxa_udc *udc = to_gadget_udc(_gadget); - - return (udc_readl(udc, UDCFNR) & 0x7ff); -} - -/** - * pxa_udc_wakeup - Force udc device out of suspend - * @_gadget: usb gadget - * - * Returns 0 if succesfull, error code otherwise - */ -static int pxa_udc_wakeup(struct usb_gadget *_gadget) -{ - struct pxa_udc *udc = to_gadget_udc(_gadget); - - /* host may not have enabled remote wakeup */ - if ((udc_readl(udc, UDCCR) & UDCCR_DWRE) == 0) - return -EHOSTUNREACH; - udc_set_mask_UDCCR(udc, UDCCR_UDR); - return 0; -} - -static const struct usb_gadget_ops pxa_udc_ops = { - .get_frame = pxa_udc_get_frame, - .wakeup = pxa_udc_wakeup, - /* current versions must always be self-powered */ -}; - -/** - * udc_disable - disable udc device controller - * @udc: udc device - * - * Disables the udc device : disables clocks, udc interrupts, control endpoint - * interrupts. - */ -static void udc_disable(struct pxa_udc *udc) -{ - udc_writel(udc, UDCICR0, 0); - udc_writel(udc, UDCICR1, 0); - - udc_clear_mask_UDCCR(udc, UDCCR_UDE); - clk_disable(udc->clk); - - ep0_idle(udc); - udc->gadget.speed = USB_SPEED_UNKNOWN; - udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); -} - -/** - * udc_init_data - Initialize udc device data structures - * @dev: udc device - * - * Initializes gadget endpoint list, endpoints locks. No action is taken - * on the hardware. - */ -static __init void udc_init_data(struct pxa_udc *dev) -{ - int i; - struct pxa_ep *ep; - - /* device/ep0 records init */ - INIT_LIST_HEAD(&dev->gadget.ep_list); - INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); - dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0]; - ep0_idle(dev); - strcpy(dev->dev->bus_id, ""); - - /* PXA endpoints init */ - for (i = 0; i < NR_PXA_ENDPOINTS; i++) { - ep = &dev->pxa_ep[i]; - - ep->enabled = is_ep0(ep); - INIT_LIST_HEAD(&ep->queue); - spin_lock_init(&ep->lock); - } - - /* USB endpoints init */ - for (i = 0; i < NR_USB_ENDPOINTS; i++) - if (i != 0) - list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, - &dev->gadget.ep_list); -} - -/** - * udc_enable - Enables the udc device - * @dev: udc device - * - * Enables the udc device : enables clocks, udc interrupts, control endpoint - * interrupts, sets usb as UDC client and setups endpoints. - */ -static void udc_enable(struct pxa_udc *udc) -{ - udc_writel(udc, UDCICR0, 0); - udc_writel(udc, UDCICR1, 0); - udc_writel(udc, UP2OCR, UP2OCR_HXOE); - udc_clear_mask_UDCCR(udc, UDCCR_UDE); - - clk_enable(udc->clk); - - ep0_idle(udc); - udc->gadget.speed = USB_SPEED_FULL; - memset(&udc->stats, 0, sizeof(udc->stats)); - - udc_set_mask_UDCCR(udc, UDCCR_UDE); - udelay(2); - if (udc_readl(udc, UDCCR) & UDCCR_EMCE) - dev_err(udc->dev, "Configuration errors, udc disabled\n"); - - /* - * Caller must be able to sleep in order to cope with startup transients - */ - msleep(100); - - /* enable suspend/resume and reset irqs */ - udc_writel(udc, UDCICR1, - UDCICR1_IECC | UDCICR1_IERU - | UDCICR1_IESU | UDCICR1_IERS); - - /* enable ep0 irqs */ - pio_irq_enable(&udc->pxa_ep[0]); - - dev_info(udc->dev, "UDC connecting\n"); - if (udc->mach->udc_command) - udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); -} - -/** - * usb_gadget_register_driver - Register gadget driver - * @driver: gadget driver - * - * When a driver is successfully registered, it will receive control requests - * including set_configuration(), which enables non-control requests. Then - * usb traffic follows until a disconnect is reported. Then a host may connect - * again, or the driver might get unbound. - * - * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise - */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct pxa_udc *udc = the_controller; - int retval; - - if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind - || !driver->disconnect || !driver->setup) - return -EINVAL; - if (!udc) - return -ENODEV; - if (udc->driver) - return -EBUSY; - - /* first hook up the driver ... */ - udc->driver = driver; - udc->gadget.dev.driver = &driver->driver; - - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(udc->dev, "device_add error %d\n", retval); - goto add_fail; - } - retval = driver->bind(&udc->gadget); - if (retval) { - dev_err(udc->dev, "bind to driver %s --> error %d\n", - driver->driver.name, retval); - goto bind_fail; - } - dev_dbg(udc->dev, "registered gadget driver '%s'\n", - driver->driver.name); - - udc_enable(udc); - return 0; - -bind_fail: - device_del(&udc->gadget.dev); -add_fail: - udc->driver = NULL; - udc->gadget.dev.driver = NULL; - return retval; -} -EXPORT_SYMBOL(usb_gadget_register_driver); - - -/** - * stop_activity - Stops udc endpoints - * @udc: udc device - * @driver: gadget driver - * - * Disables all udc endpoints (even control endpoint), report disconnect to - * the gadget user. - */ -static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) -{ - int i; - - /* don't disconnect drivers more than once */ - if (udc->gadget.speed == USB_SPEED_UNKNOWN) - driver = NULL; - udc->gadget.speed = USB_SPEED_UNKNOWN; - - for (i = 0; i < NR_USB_ENDPOINTS; i++) - pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep); - - if (driver) - driver->disconnect(&udc->gadget); -} - -/** - * usb_gadget_unregister_driver - Unregister the gadget driver - * @driver: gadget driver - * - * Returns 0 if no error, -ENODEV, -EINVAL otherwise - */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct pxa_udc *udc = the_controller; - - if (!udc) - return -ENODEV; - if (!driver || driver != udc->driver || !driver->unbind) - return -EINVAL; - - stop_activity(udc, driver); - udc_disable(udc); - - driver->unbind(&udc->gadget); - udc->driver = NULL; - - device_del(&udc->gadget.dev); - - dev_info(udc->dev, "unregistered gadget driver '%s'\n", - driver->driver.name); - return 0; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); - -/** - * handle_ep0_ctrl_req - handle control endpoint control request - * @udc: udc device - * @req: control request - */ -static void handle_ep0_ctrl_req(struct pxa_udc *udc, - struct pxa27x_request *req) -{ - struct pxa_ep *ep = &udc->pxa_ep[0]; - union { - struct usb_ctrlrequest r; - u32 word[2]; - } u; - int i; - int have_extrabytes = 0; - - nuke(ep, -EPROTO); - - /* read SETUP packet */ - for (i = 0; i < 2; i++) { - if (unlikely(ep_is_empty(ep))) - goto stall; - u.word[i] = udc_ep_readl(ep, UDCDR); - } - - have_extrabytes = !ep_is_empty(ep); - while (!ep_is_empty(ep)) { - i = udc_ep_readl(ep, UDCDR); - ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i); - } - - le16_to_cpus(&u.r.wValue); - le16_to_cpus(&u.r.wIndex); - le16_to_cpus(&u.r.wLength); - - ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n", - u.r.bRequestType, u.r.bRequest, - u.r.wValue, u.r.wIndex, u.r.wLength); - if (unlikely(have_extrabytes)) - goto stall; - - if (u.r.bRequestType & USB_DIR_IN) - set_ep0state(udc, IN_DATA_STAGE); - else - set_ep0state(udc, OUT_DATA_STAGE); - - /* Tell UDC to enter Data Stage */ - udc_ep_writel(ep, UDCCSR, UDCCSR0_SA | UDCCSR0_OPC); - - i = udc->driver->setup(&udc->gadget, &u.r); - if (i < 0) - goto stall; -out: - return; -stall: - ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n", - udc_ep_readl(ep, UDCCSR), i); - udc_ep_writel(ep, UDCCSR, UDCCSR0_FST | UDCCSR0_FTF); - set_ep0state(udc, STALL); - goto out; -} - -/** - * handle_ep0 - Handle control endpoint data transfers - * @udc: udc device - * @fifo_irq: 1 if triggered by fifo service type irq - * @opc_irq: 1 if triggered by output packet complete type irq - * - * Context : when in_interrupt() or with ep->lock held - * - * Tries to transfer all pending request data into the endpoint and/or - * transfer all pending data in the endpoint into usb requests. - * Handles states of ep0 automata. - * - * PXA27x hardware handles several standard usb control requests without - * driver notification. The requests fully handled by hardware are : - * SET_ADDRESS, SET_FEATURE, CLEAR_FEATURE, GET_CONFIGURATION, GET_INTERFACE, - * GET_STATUS - * The requests handled by hardware, but with irq notification are : - * SYNCH_FRAME, SET_CONFIGURATION, SET_INTERFACE - * The remaining standard requests really handled by handle_ep0 are : - * GET_DESCRIPTOR, SET_DESCRIPTOR, specific requests. - * Requests standardized outside of USB 2.0 chapter 9 are handled more - * uniformly, by gadget drivers. - * - * The control endpoint state machine is _not_ USB spec compliant, it's even - * hardly compliant with Intel PXA270 developers guide. - * The key points which inferred this state machine are : - * - on every setup token, bit UDCCSR0_SA is raised and held until cleared by - * software. - * - on every OUT packet received, UDCCSR0_OPC is raised and held until - * cleared by software. - * - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it - * before reading ep0. - * - irq can be called on a "packet complete" event (opc_irq=1), while - * UDCCSR0_OPC is not yet raised (delta can be as big as 100ms - * from experimentation). - * - as UDCCSR0_SA can be activated while in irq handling, and clearing - * UDCCSR0_OPC would flush the setup data, we almost never clear UDCCSR0_OPC - * => we never actually read the "status stage" packet of an IN data stage - * => this is not documented in Intel documentation - * - hardware as no idea of STATUS STAGE, it only handle SETUP STAGE and DATA - * STAGE. The driver add STATUS STAGE to send last zero length packet in - * OUT_STATUS_STAGE. - * - special attention was needed for IN_STATUS_STAGE. If a packet complete - * event is detected, we terminate the status stage without ackowledging the - * packet (not to risk to loose a potential SETUP packet) - */ -static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) -{ - u32 udccsr0; - struct pxa_ep *ep = &udc->pxa_ep[0]; - struct pxa27x_request *req = NULL; - int completed = 0; - - udccsr0 = udc_ep_readl(ep, UDCCSR); - ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", - EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), - (fifo_irq << 1 | opc_irq)); - - if (!list_empty(&ep->queue)) - req = list_entry(ep->queue.next, struct pxa27x_request, queue); - - if (udccsr0 & UDCCSR0_SST) { - ep_dbg(ep, "clearing stall status\n"); - nuke(ep, -EPIPE); - udc_ep_writel(ep, UDCCSR, UDCCSR0_SST); - ep0_idle(udc); - } - - if (udccsr0 & UDCCSR0_SA) { - nuke(ep, 0); - set_ep0state(udc, SETUP_STAGE); - } - - switch (udc->ep0state) { - case WAIT_FOR_SETUP: - /* - * Hardware bug : beware, we cannot clear OPC, since we would - * miss a potential OPC irq for a setup packet. - * So, we only do ... nothing, and hope for a next irq with - * UDCCSR0_SA set. - */ - break; - case SETUP_STAGE: - udccsr0 &= UDCCSR0_CTRL_REQ_MASK; - if (likely(udccsr0 == UDCCSR0_CTRL_REQ_MASK)) - handle_ep0_ctrl_req(udc, req); - break; - case IN_DATA_STAGE: /* GET_DESCRIPTOR */ - if (epout_has_pkt(ep)) - udc_ep_writel(ep, UDCCSR, UDCCSR0_OPC); - if (req && !ep_is_full(ep)) - completed = write_ep0_fifo(ep, req); - if (completed) - ep0_end_in_req(ep, req); - break; - case OUT_DATA_STAGE: /* SET_DESCRIPTOR */ - if (epout_has_pkt(ep) && req) - completed = read_ep0_fifo(ep, req); - if (completed) - ep0_end_out_req(ep, req); - break; - case STALL: - udc_ep_writel(ep, UDCCSR, UDCCSR0_FST); - break; - case IN_STATUS_STAGE: - /* - * Hardware bug : beware, we cannot clear OPC, since we would - * miss a potential PC irq for a setup packet. - * So, we only put the ep0 into WAIT_FOR_SETUP state. - */ - if (opc_irq) - ep0_idle(udc); - break; - case OUT_STATUS_STAGE: - case WAIT_ACK_SET_CONF_INTERF: - ep_warn(ep, "should never get in %s state here!!!\n", - EP0_STNAME(ep->dev)); - ep0_idle(udc); - break; - } -} - -/** - * handle_ep - Handle endpoint data tranfers - * @ep: pxa physical endpoint - * - * Tries to transfer all pending request data into the endpoint and/or - * transfer all pending data in the endpoint into usb requests. - * - * Is always called when in_interrupt() or with ep->lock held. - */ -static void handle_ep(struct pxa_ep *ep) -{ - struct pxa27x_request *req; - int completed; - u32 udccsr; - int is_in = ep->dir_in; - int loop = 0; - - do { - completed = 0; - udccsr = udc_ep_readl(ep, UDCCSR); - if (likely(!list_empty(&ep->queue))) - req = list_entry(ep->queue.next, - struct pxa27x_request, queue); - else - req = NULL; - - ep_dbg(ep, "req:%p, udccsr 0x%03x loop=%d\n", - req, udccsr, loop++); - - if (unlikely(udccsr & (UDCCSR_SST | UDCCSR_TRN))) - udc_ep_writel(ep, UDCCSR, - udccsr & (UDCCSR_SST | UDCCSR_TRN)); - if (!req) - break; - - if (unlikely(is_in)) { - if (likely(!ep_is_full(ep))) - completed = write_fifo(ep, req); - if (completed) - ep_end_in_req(ep, req); - } else { - if (likely(epout_has_pkt(ep))) - completed = read_fifo(ep, req); - if (completed) - ep_end_out_req(ep, req); - } - } while (completed); -} - -/** - * pxa27x_change_configuration - Handle SET_CONF usb request notification - * @udc: udc device - * @config: usb configuration - * - * Post the request to upper level. - * Don't use any pxa specific harware configuration capabilities - */ -static void pxa27x_change_configuration(struct pxa_udc *udc, int config) -{ - struct usb_ctrlrequest req ; - - dev_dbg(udc->dev, "config=%d\n", config); - - udc->config = config; - udc->last_interface = 0; - udc->last_alternate = 0; - - req.bRequestType = 0; - req.bRequest = USB_REQ_SET_CONFIGURATION; - req.wValue = config; - req.wIndex = 0; - req.wLength = 0; - - set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF); - udc->driver->setup(&udc->gadget, &req); -} - -/** - * pxa27x_change_interface - Handle SET_INTERF usb request notification - * @udc: udc device - * @iface: interface number - * @alt: alternate setting number - * - * Post the request to upper level. - * Don't use any pxa specific harware configuration capabilities - */ -static void pxa27x_change_interface(struct pxa_udc *udc, int iface, int alt) -{ - struct usb_ctrlrequest req; - - dev_dbg(udc->dev, "interface=%d, alternate setting=%d\n", iface, alt); - - udc->last_interface = iface; - udc->last_alternate = alt; - - req.bRequestType = USB_RECIP_INTERFACE; - req.bRequest = USB_REQ_SET_INTERFACE; - req.wValue = alt; - req.wIndex = iface; - req.wLength = 0; - - set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF); - udc->driver->setup(&udc->gadget, &req); -} - -/* - * irq_handle_data - Handle data transfer - * @irq: irq IRQ number - * @udc: dev pxa_udc device structure - * - * Called from irq handler, transferts data to or from endpoint to queue - */ -static void irq_handle_data(int irq, struct pxa_udc *udc) -{ - int i; - struct pxa_ep *ep; - u32 udcisr0 = udc_readl(udc, UDCISR0) & UDCCISR0_EP_MASK; - u32 udcisr1 = udc_readl(udc, UDCISR1) & UDCCISR1_EP_MASK; - - if (udcisr0 & UDCISR_INT_MASK) { - udc->pxa_ep[0].stats.irqs++; - udc_writel(udc, UDCISR0, UDCISR_INT(0, UDCISR_INT_MASK)); - handle_ep0(udc, !!(udcisr0 & UDCICR_FIFOERR), - !!(udcisr0 & UDCICR_PKTCOMPL)); - } - - udcisr0 >>= 2; - for (i = 1; udcisr0 != 0 && i < 16; udcisr0 >>= 2, i++) { - if (!(udcisr0 & UDCISR_INT_MASK)) - continue; - - udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK)); - ep = &udc->pxa_ep[i]; - ep->stats.irqs++; - handle_ep(ep); - } - - for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) { - udc_writel(udc, UDCISR1, UDCISR_INT(i - 16, UDCISR_INT_MASK)); - if (!(udcisr1 & UDCISR_INT_MASK)) - continue; - - ep = &udc->pxa_ep[i]; - ep->stats.irqs++; - handle_ep(ep); - } - -} - -/** - * irq_udc_suspend - Handle IRQ "UDC Suspend" - * @udc: udc device - */ -static void irq_udc_suspend(struct pxa_udc *udc) -{ - udc_writel(udc, UDCISR1, UDCISR1_IRSU); - udc->stats.irqs_suspend++; - - if (udc->gadget.speed != USB_SPEED_UNKNOWN - && udc->driver && udc->driver->suspend) - udc->driver->suspend(&udc->gadget); - ep0_idle(udc); -} - -/** - * irq_udc_resume - Handle IRQ "UDC Resume" - * @udc: udc device - */ -static void irq_udc_resume(struct pxa_udc *udc) -{ - udc_writel(udc, UDCISR1, UDCISR1_IRRU); - udc->stats.irqs_resume++; - - if (udc->gadget.speed != USB_SPEED_UNKNOWN - && udc->driver && udc->driver->resume) - udc->driver->resume(&udc->gadget); -} - -/** - * irq_udc_reconfig - Handle IRQ "UDC Change Configuration" - * @udc: udc device - */ -static void irq_udc_reconfig(struct pxa_udc *udc) -{ - unsigned config, interface, alternate, config_change; - u32 udccr = udc_readl(udc, UDCCR); - - udc_writel(udc, UDCISR1, UDCISR1_IRCC); - udc->stats.irqs_reconfig++; - - config = (udccr & UDCCR_ACN) >> UDCCR_ACN_S; - config_change = (config != udc->config); - pxa27x_change_configuration(udc, config); - - interface = (udccr & UDCCR_AIN) >> UDCCR_AIN_S; - alternate = (udccr & UDCCR_AAISN) >> UDCCR_AAISN_S; - pxa27x_change_interface(udc, interface, alternate); - - if (config_change) - update_pxa_ep_matches(udc); - udc_set_mask_UDCCR(udc, UDCCR_SMAC); -} - -/** - * irq_udc_reset - Handle IRQ "UDC Reset" - * @udc: udc device - */ -static void irq_udc_reset(struct pxa_udc *udc) -{ - u32 udccr = udc_readl(udc, UDCCR); - struct pxa_ep *ep = &udc->pxa_ep[0]; - - dev_info(udc->dev, "USB reset\n"); - udc_writel(udc, UDCISR1, UDCISR1_IRRS); - udc->stats.irqs_reset++; - - if ((udccr & UDCCR_UDA) == 0) { - dev_dbg(udc->dev, "USB reset start\n"); - stop_activity(udc, udc->driver); - } - udc->gadget.speed = USB_SPEED_FULL; - memset(&udc->stats, 0, sizeof udc->stats); - - nuke(ep, -EPROTO); - udc_ep_writel(ep, UDCCSR, UDCCSR0_FTF | UDCCSR0_OPC); - ep0_idle(udc); -} - -/** - * pxa_udc_irq - Main irq handler - * @irq: irq number - * @_dev: udc device - * - * Handles all udc interrupts - */ -static irqreturn_t pxa_udc_irq(int irq, void *_dev) -{ - struct pxa_udc *udc = _dev; - u32 udcisr0 = udc_readl(udc, UDCISR0); - u32 udcisr1 = udc_readl(udc, UDCISR1); - u32 udccr = udc_readl(udc, UDCCR); - u32 udcisr1_spec; - - dev_vdbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, " - "UDCCR:0x%08x\n", udcisr0, udcisr1, udccr); - - udcisr1_spec = udcisr1 & 0xf8000000; - if (unlikely(udcisr1_spec & UDCISR1_IRSU)) - irq_udc_suspend(udc); - if (unlikely(udcisr1_spec & UDCISR1_IRRU)) - irq_udc_resume(udc); - if (unlikely(udcisr1_spec & UDCISR1_IRCC)) - irq_udc_reconfig(udc); - if (unlikely(udcisr1_spec & UDCISR1_IRRS)) - irq_udc_reset(udc); - - if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK)) - irq_handle_data(irq, udc); - - return IRQ_HANDLED; -} - -static struct pxa_udc memory = { - .gadget = { - .ops = &pxa_udc_ops, - .ep0 = &memory.udc_usb_ep[0].usb_ep, - .name = driver_name, - .dev = { - .bus_id = "gadget", - }, - }, - - .udc_usb_ep = { - USB_EP_CTRL, - USB_EP_OUT_BULK(1), - USB_EP_IN_BULK(2), - USB_EP_IN_ISO(3), - USB_EP_OUT_ISO(4), - USB_EP_IN_INT(5), - }, - - .pxa_ep = { - PXA_EP_CTRL, - /* Endpoints for gadget zero */ - PXA_EP_OUT_BULK(1, 1, 3, 0, 0), - PXA_EP_IN_BULK(2, 2, 3, 0, 0), - /* Endpoints for ether gadget, file storage gadget */ - PXA_EP_OUT_BULK(3, 1, 1, 0, 0), - PXA_EP_IN_BULK(4, 2, 1, 0, 0), - PXA_EP_IN_ISO(5, 3, 1, 0, 0), - PXA_EP_OUT_ISO(6, 4, 1, 0, 0), - PXA_EP_IN_INT(7, 5, 1, 0, 0), - /* Endpoints for RNDIS, serial */ - PXA_EP_OUT_BULK(8, 1, 2, 0, 0), - PXA_EP_IN_BULK(9, 2, 2, 0, 0), - PXA_EP_IN_INT(10, 5, 2, 0, 0), - /* - * All the following endpoints are only for completion. They - * won't never work, as multiple interfaces are really broken on - * the pxa. - */ - PXA_EP_OUT_BULK(11, 1, 2, 1, 0), - PXA_EP_IN_BULK(12, 2, 2, 1, 0), - /* Endpoint for CDC Ether */ - PXA_EP_OUT_BULK(13, 1, 1, 1, 1), - PXA_EP_IN_BULK(14, 2, 1, 1, 1), - } -}; - -/** - * pxa_udc_probe - probes the udc device - * @_dev: platform device - * - * Perform basic init : allocates udc clock, creates sysfs files, requests - * irq. - */ -static int __init pxa_udc_probe(struct platform_device *pdev) -{ - struct resource *regs; - struct pxa_udc *udc = &memory; - int retval; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENXIO; - udc->irq = platform_get_irq(pdev, 0); - if (udc->irq < 0) - return udc->irq; - - udc->dev = &pdev->dev; - udc->mach = pdev->dev.platform_data; - - udc->clk = clk_get(&pdev->dev, "UDCCLK"); - if (IS_ERR(udc->clk)) { - retval = PTR_ERR(udc->clk); - goto err_clk; - } - - retval = -ENOMEM; - udc->regs = ioremap(regs->start, regs->end - regs->start + 1); - if (!udc->regs) { - dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); - goto err_map; - } - - device_initialize(&udc->gadget.dev); - udc->gadget.dev.parent = &pdev->dev; - udc->gadget.dev.dma_mask = NULL; - - the_controller = udc; - platform_set_drvdata(pdev, udc); - udc_init_data(udc); - pxa_eps_setup(udc); - - /* irq setup after old hardware state is cleaned up */ - retval = request_irq(udc->irq, pxa_udc_irq, - IRQF_SHARED, driver_name, udc); - if (retval != 0) { - dev_err(udc->dev, "%s: can't get irq %i, err %d\n", - driver_name, IRQ_USB, retval); - goto err_irq; - } - - pxa_init_debugfs(udc); - return 0; -err_irq: - iounmap(udc->regs); -err_map: - clk_put(udc->clk); - udc->clk = NULL; -err_clk: - return retval; -} - -/** - * pxa_udc_remove - removes the udc device driver - * @_dev: platform device - */ -static int __exit pxa_udc_remove(struct platform_device *_dev) -{ - struct pxa_udc *udc = platform_get_drvdata(_dev); - - usb_gadget_unregister_driver(udc->driver); - free_irq(udc->irq, udc); - pxa_cleanup_debugfs(udc); - - platform_set_drvdata(_dev, NULL); - the_controller = NULL; - clk_put(udc->clk); - - return 0; -} - -static void pxa_udc_shutdown(struct platform_device *_dev) -{ - struct pxa_udc *udc = platform_get_drvdata(_dev); - - udc_disable(udc); -} - -#ifdef CONFIG_PM -/** - * pxa_udc_suspend - Suspend udc device - * @_dev: platform device - * @state: suspend state - * - * Suspends udc : saves configuration registers (UDCCR*), then disables the udc - * device. - */ -static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) -{ - int i; - struct pxa_udc *udc = platform_get_drvdata(_dev); - struct pxa_ep *ep; - - ep = &udc->pxa_ep[0]; - udc->udccsr0 = udc_ep_readl(ep, UDCCSR); - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - ep->udccsr_value = udc_ep_readl(ep, UDCCSR); - ep->udccr_value = udc_ep_readl(ep, UDCCR); - ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", - ep->udccsr_value, ep->udccr_value); - } - - udc_disable(udc); - - return 0; -} - -/** - * pxa_udc_resume - Resume udc device - * @_dev: platform device - * - * Resumes udc : restores configuration registers (UDCCR*), then enables the udc - * device. - */ -static int pxa_udc_resume(struct platform_device *_dev) -{ - int i; - struct pxa_udc *udc = platform_get_drvdata(_dev); - struct pxa_ep *ep; - - ep = &udc->pxa_ep[0]; - udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); - for (i = 1; i < NR_PXA_ENDPOINTS; i++) { - ep = &udc->pxa_ep[i]; - udc_ep_writel(ep, UDCCSR, ep->udccsr_value); - udc_ep_writel(ep, UDCCR, ep->udccr_value); - ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", - ep->udccsr_value, ep->udccr_value); - } - - udc_enable(udc); - /* - * We do not handle OTG yet. - * - * OTGPH bit is set when sleep mode is entered. - * it indicates that OTG pad is retaining its state. - * Upon exit from sleep mode and before clearing OTGPH, - * Software must configure the USB OTG pad, UDC, and UHC - * to the state they were in before entering sleep mode. - * - * Should be : PSSR |= PSSR_OTGPH; - */ - - return 0; -} -#endif - -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:pxa2xx-udc"); - -static struct platform_driver udc_driver = { - .driver = { - .name = "pxa2xx-udc", - .owner = THIS_MODULE, - }, - .remove = __exit_p(pxa_udc_remove), - .shutdown = pxa_udc_shutdown, -#ifdef CONFIG_PM - .suspend = pxa_udc_suspend, - .resume = pxa_udc_resume -#endif -}; - -static int __init udc_init(void) -{ - printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); - return platform_driver_probe(&udc_driver, pxa_udc_probe); -} -module_init(udc_init); - - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Robert Jarzmik"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/gadget/pxa27x_udc.h b/trunk/drivers/usb/gadget/pxa27x_udc.h deleted file mode 100644 index 1d1b7936ee11..000000000000 --- a/trunk/drivers/usb/gadget/pxa27x_udc.h +++ /dev/null @@ -1,487 +0,0 @@ -/* - * linux/drivers/usb/gadget/pxa27x_udc.h - * Intel PXA27x on-chip full speed USB device controller - * - * Inspired by original driver by Frank Becker, David Brownell, and others. - * Copyright (C) 2008 Robert Jarzmik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __LINUX_USB_GADGET_PXA27X_H -#define __LINUX_USB_GADGET_PXA27X_H - -#include -#include -#include - -/* - * Register definitions - */ -/* Offsets */ -#define UDCCR 0x0000 /* UDC Control Register */ -#define UDCICR0 0x0004 /* UDC Interrupt Control Register0 */ -#define UDCICR1 0x0008 /* UDC Interrupt Control Register1 */ -#define UDCISR0 0x000C /* UDC Interrupt Status Register 0 */ -#define UDCISR1 0x0010 /* UDC Interrupt Status Register 1 */ -#define UDCFNR 0x0014 /* UDC Frame Number Register */ -#define UDCOTGICR 0x0018 /* UDC On-The-Go interrupt control */ -#define UP2OCR 0x0020 /* USB Port 2 Output Control register */ -#define UP3OCR 0x0024 /* USB Port 3 Output Control register */ -#define UDCCSRn(x) (0x0100 + ((x)<<2)) /* UDC Control/Status register */ -#define UDCBCRn(x) (0x0200 + ((x)<<2)) /* UDC Byte Count Register */ -#define UDCDRn(x) (0x0300 + ((x)<<2)) /* UDC Data Register */ -#define UDCCRn(x) (0x0400 + ((x)<<2)) /* UDC Control Register */ - -#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */ -#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation - Protocol Port Support */ -#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol - Support */ -#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol - Enable */ -#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */ -#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */ -#define UDCCR_ACN_S 11 -#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */ -#define UDCCR_AIN_S 8 -#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface - Setting Number */ -#define UDCCR_AAISN_S 5 -#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active - Configuration */ -#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration - Error */ -#define UDCCR_UDR (1 << 2) /* UDC Resume */ -#define UDCCR_UDA (1 << 1) /* UDC Active */ -#define UDCCR_UDE (1 << 0) /* UDC Enable */ - -#define UDCICR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */ -#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */ -#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */ -#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */ -#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */ -#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */ -#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */ -#define UDCICR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL) - -#define UDCISR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2)) -#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */ -#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */ -#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */ -#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */ -#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */ -#define UDCISR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL) - -#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */ -#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt - Rising Edge Interrupt Enable */ -#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt - Falling Edge Interrupt Enable */ -#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge - Interrupt Enable */ -#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising - Edge Interrupt Enable */ -#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling - Edge Interrupt Enable */ -#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge - Interrupt Enable */ -#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge - Interrupt Enable */ - -/* Host Port 2 field bits */ -#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */ -#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */ - /* Transceiver enablers */ -#define UP2OCR_DPPDE (1 << 2) /* D+ Pull Down Enable */ -#define UP2OCR_DMPDE (1 << 3) /* D- Pull Down Enable */ -#define UP2OCR_DPPUE (1 << 4) /* D+ Pull Up Enable */ -#define UP2OCR_DMPUE (1 << 5) /* D- Pull Up Enable */ -#define UP2OCR_DPPUBE (1 << 6) /* D+ Pull Up Bypass Enable */ -#define UP2OCR_DMPUBE (1 << 7) /* D- Pull Up Bypass Enable */ -#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */ -#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */ -#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */ -#define UP2OCR_HXS (1 << 16) /* Transceiver Output Select */ -#define UP2OCR_HXOE (1 << 17) /* Transceiver Output Enable */ -#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ - -#define UDCCSR0_SA (1 << 7) /* Setup Active */ -#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */ -#define UDCCSR0_FST (1 << 5) /* Force Stall */ -#define UDCCSR0_SST (1 << 4) /* Sent Stall */ -#define UDCCSR0_DME (1 << 3) /* DMA Enable */ -#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */ -#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */ -#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */ - -#define UDCCSR_DPE (1 << 9) /* Data Packet Error */ -#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */ -#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */ -#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */ -#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */ -#define UDCCSR_FST (1 << 5) /* Force STALL */ -#define UDCCSR_SST (1 << 4) /* Sent STALL */ -#define UDCCSR_DME (1 << 3) /* DMA Enable */ -#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */ -#define UDCCSR_PC (1 << 1) /* Packet Complete */ -#define UDCCSR_FS (1 << 0) /* FIFO needs service */ - -#define UDCCONR_CN (0x03 << 25) /* Configuration Number */ -#define UDCCONR_CN_S 25 -#define UDCCONR_IN (0x07 << 22) /* Interface Number */ -#define UDCCONR_IN_S 22 -#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */ -#define UDCCONR_AISN_S 19 -#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */ -#define UDCCONR_EN_S 15 -#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */ -#define UDCCONR_ET_S 13 -#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */ -#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */ -#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */ -#define UDCCONR_ET_NU (0x00 << 13) /* Not used */ -#define UDCCONR_ED (1 << 12) /* Endpoint Direction */ -#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */ -#define UDCCONR_MPS_S 2 -#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */ -#define UDCCONR_EE (1 << 0) /* Endpoint Enable */ - -#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_SMAC | UDCCR_UDR | UDCCR_UDE) -#define UDCCSR_WR_MASK (UDCCSR_DME | UDCCSR_FST) -#define UDC_FNR_MASK (0x7ff) -#define UDC_BCR_MASK (0x3ff) - -/* - * UDCCR = UDC Endpoint Configuration Registers - * UDCCSR = UDC Control/Status Register for this EP - * UDCBCR = UDC Byte Count Remaining (contents of OUT fifo) - * UDCDR = UDC Endpoint Data Register (the fifo) - */ -#define ofs_UDCCR(ep) (UDCCRn(ep->idx)) -#define ofs_UDCCSR(ep) (UDCCSRn(ep->idx)) -#define ofs_UDCBCR(ep) (UDCBCRn(ep->idx)) -#define ofs_UDCDR(ep) (UDCDRn(ep->idx)) - -/* Register access macros */ -#define udc_ep_readl(ep, reg) \ - __raw_readl((ep)->dev->regs + ofs_##reg(ep)) -#define udc_ep_writel(ep, reg, value) \ - __raw_writel((value), ep->dev->regs + ofs_##reg(ep)) -#define udc_ep_readb(ep, reg) \ - __raw_readb((ep)->dev->regs + ofs_##reg(ep)) -#define udc_ep_writeb(ep, reg, value) \ - __raw_writeb((value), ep->dev->regs + ofs_##reg(ep)) -#define udc_readl(dev, reg) \ - __raw_readl((dev)->regs + (reg)) -#define udc_writel(udc, reg, value) \ - __raw_writel((value), (udc)->regs + (reg)) - -#define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME) -#define UDCCISR0_EP_MASK ~0 -#define UDCCISR1_EP_MASK 0xffff -#define UDCCSR0_CTRL_REQ_MASK (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE) - -#define EPIDX(ep) (ep->idx) -#define EPADDR(ep) (ep->addr) -#define EPXFERTYPE(ep) (ep->type) -#define EPNAME(ep) (ep->name) -#define is_ep0(ep) (!ep->idx) -#define EPXFERTYPE_is_ISO(ep) (EPXFERTYPE(ep) == USB_ENDPOINT_XFER_ISOC) - -/* - * Endpoint definitions - * - * Once enabled, pxa endpoint configuration is freezed, and cannot change - * unless a reset happens or the udc is disabled. - * Therefore, we must define all pxa potential endpoint definitions needed for - * all gadget and set them up before the udc is enabled. - * - * As the architecture chosen is fully static, meaning the pxa endpoint - * configurations are set up once and for all, we must provide a way to match - * one usb endpoint (usb_ep) to several pxa endpoints. The reason is that gadget - * layer autoconf doesn't choose the usb_ep endpoint on (config, interface, alt) - * criteria, while the pxa architecture requires that. - * - * The solution is to define several pxa endpoints matching one usb_ep. Ex: - * - "ep1-in" matches pxa endpoint EPA (which is an IN ep at addr 1, when - * the udc talks on (config=3, interface=0, alt=0) - * - "ep1-in" matches pxa endpoint EPB (which is an IN ep at addr 1, when - * the udc talks on (config=3, interface=0, alt=1) - * - "ep1-in" matches pxa endpoint EPC (which is an IN ep at addr 1, when - * the udc talks on (config=2, interface=0, alt=0) - * - * We'll define the pxa endpoint by its index (EPA => idx=1, EPB => idx=2, ...) - */ - -/* - * Endpoint definition helpers - */ -#define USB_EP_DEF(addr, bname, dir, type, maxpkt) \ -{ .usb_ep = { .name = bname, .ops = &pxa_ep_ops, .maxpacket = maxpkt, }, \ - .desc = { .bEndpointAddress = addr | (dir ? USB_DIR_IN : 0), \ - .bmAttributes = type, \ - .wMaxPacketSize = maxpkt, }, \ - .dev = &memory \ -} -#define USB_EP_BULK(addr, bname, dir) \ - USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE) -#define USB_EP_ISO(addr, bname, dir) \ - USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE) -#define USB_EP_INT(addr, bname, dir) \ - USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE) -#define USB_EP_IN_BULK(n) USB_EP_BULK(n, "ep" #n "in-bulk", 1) -#define USB_EP_OUT_BULK(n) USB_EP_BULK(n, "ep" #n "out-bulk", 0) -#define USB_EP_IN_ISO(n) USB_EP_ISO(n, "ep" #n "in-iso", 1) -#define USB_EP_OUT_ISO(n) USB_EP_ISO(n, "ep" #n "out-iso", 0) -#define USB_EP_IN_INT(n) USB_EP_INT(n, "ep" #n "in-int", 1) -#define USB_EP_CTRL USB_EP_DEF(0, "ep0", 0, 0, EP0_FIFO_SIZE) - -#define PXA_EP_DEF(_idx, _addr, dir, _type, maxpkt, _config, iface, altset) \ -{ \ - .dev = &memory, \ - .name = "ep" #_idx, \ - .idx = _idx, .enabled = 0, \ - .dir_in = dir, .addr = _addr, \ - .config = _config, .interface = iface, .alternate = altset, \ - .type = _type, .fifo_size = maxpkt, \ -} -#define PXA_EP_BULK(_idx, addr, dir, config, iface, alt) \ - PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE, \ - config, iface, alt) -#define PXA_EP_ISO(_idx, addr, dir, config, iface, alt) \ - PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE, \ - config, iface, alt) -#define PXA_EP_INT(_idx, addr, dir, config, iface, alt) \ - PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE, \ - config, iface, alt) -#define PXA_EP_IN_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 1, c, f, a) -#define PXA_EP_OUT_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 0, c, f, a) -#define PXA_EP_IN_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 1, c, f, a) -#define PXA_EP_OUT_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 0, c, f, a) -#define PXA_EP_IN_INT(i, adr, c, f, a) PXA_EP_INT(i, adr, 1, c, f, a) -#define PXA_EP_CTRL PXA_EP_DEF(0, 0, 0, 0, EP0_FIFO_SIZE, 0, 0, 0) - -struct pxa27x_udc; - -struct stats { - unsigned long in_ops; - unsigned long out_ops; - unsigned long in_bytes; - unsigned long out_bytes; - unsigned long irqs; -}; - -/** - * struct udc_usb_ep - container of each usb_ep structure - * @usb_ep: usb endpoint - * @desc: usb descriptor, especially type and address - * @dev: udc managing this endpoint - * @pxa_ep: matching pxa_ep (cache of find_pxa_ep() call) - */ -struct udc_usb_ep { - struct usb_ep usb_ep; - struct usb_endpoint_descriptor desc; - struct pxa_udc *dev; - struct pxa_ep *pxa_ep; -}; - -/** - * struct pxa_ep - pxa endpoint - * @dev: udc device - * @queue: requests queue - * @lock: lock to pxa_ep data (queues and stats) - * @enabled: true when endpoint enabled (not stopped by gadget layer) - * @idx: endpoint index (1 => epA, 2 => epB, ..., 24 => epX) - * @name: endpoint name (for trace/debug purpose) - * @dir_in: 1 if IN endpoint, 0 if OUT endpoint - * @addr: usb endpoint number - * @config: configuration in which this endpoint is active - * @interface: interface in which this endpoint is active - * @alternate: altsetting in which this endpoitn is active - * @fifo_size: max packet size in the endpoint fifo - * @type: endpoint type (bulk, iso, int, ...) - * @udccsr_value: save register of UDCCSR0 for suspend/resume - * @udccr_value: save register of UDCCR for suspend/resume - * @stats: endpoint statistics - * - * The *PROBLEM* is that pxa's endpoint configuration scheme is both misdesigned - * (cares about config/interface/altsetting, thus placing needless limits on - * device capability) and full of implementation bugs forcing it to be set up - * for use more or less like a pxa255. - * - * As we define the pxa_ep statically, we must guess all needed pxa_ep for all - * gadget which may work with this udc driver. - */ -struct pxa_ep { - struct pxa_udc *dev; - - struct list_head queue; - spinlock_t lock; /* Protects this structure */ - /* (queues, stats) */ - unsigned enabled:1; - - unsigned idx:5; - char *name; - - /* - * Specific pxa endpoint data, needed for hardware initialization - */ - unsigned dir_in:1; - unsigned addr:3; - unsigned config:2; - unsigned interface:3; - unsigned alternate:3; - unsigned fifo_size; - unsigned type; - -#ifdef CONFIG_PM - u32 udccsr_value; - u32 udccr_value; -#endif - struct stats stats; -}; - -/** - * struct pxa27x_request - container of each usb_request structure - * @req: usb request - * @udc_usb_ep: usb endpoint the request was submitted on - * @in_use: sanity check if request already queued on an pxa_ep - * @queue: linked list of requests, linked on pxa_ep->queue - */ -struct pxa27x_request { - struct usb_request req; - struct udc_usb_ep *udc_usb_ep; - unsigned in_use:1; - struct list_head queue; -}; - -enum ep0_state { - WAIT_FOR_SETUP, - SETUP_STAGE, - IN_DATA_STAGE, - OUT_DATA_STAGE, - IN_STATUS_STAGE, - OUT_STATUS_STAGE, - STALL, - WAIT_ACK_SET_CONF_INTERF -}; - -static char *ep0_state_name[] = { - "WAIT_FOR_SETUP", "SETUP_STAGE", "IN_DATA_STAGE", "OUT_DATA_STAGE", - "IN_STATUS_STAGE", "OUT_STATUS_STAGE", "STALL", - "WAIT_ACK_SET_CONF_INTERF" -}; -#define EP0_STNAME(udc) ep0_state_name[(udc)->ep0state] - -#define EP0_FIFO_SIZE 16U -#define BULK_FIFO_SIZE 64U -#define ISO_FIFO_SIZE 256U -#define INT_FIFO_SIZE 16U - -struct udc_stats { - unsigned long irqs_reset; - unsigned long irqs_suspend; - unsigned long irqs_resume; - unsigned long irqs_reconfig; -}; - -#define NR_USB_ENDPOINTS (1 + 5) /* ep0 + ep1in-bulk + .. + ep3in-iso */ -#define NR_PXA_ENDPOINTS (1 + 14) /* ep0 + epA + epB + .. + epX */ - -/** - * struct pxa_udc - udc structure - * @regs: mapped IO space - * @irq: udc irq - * @clk: udc clock - * @usb_gadget: udc gadget structure - * @driver: bound gadget (zero, g_ether, g_file_storage, ...) - * @dev: device - * @mach: machine info, used to activate specific GPIO - * @ep0state: control endpoint state machine state - * @stats: statistics on udc usage - * @udc_usb_ep: array of usb endpoints offered by the gadget - * @pxa_ep: array of pxa available endpoints - * @config: UDC active configuration - * @last_interface: UDC interface of the last SET_INTERFACE host request - * @last_alternate: UDC altsetting of the last SET_INTERFACE host request - * @udccsr0: save of udccsr0 in case of suspend - * @debugfs_root: root entry of debug filesystem - * @debugfs_state: debugfs entry for "udcstate" - * @debugfs_queues: debugfs entry for "queues" - * @debugfs_eps: debugfs entry for "epstate" - */ -struct pxa_udc { - void __iomem *regs; - int irq; - struct clk *clk; - - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - struct device *dev; - struct pxa2xx_udc_mach_info *mach; - - enum ep0_state ep0state; - struct udc_stats stats; - - struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; - struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; - - unsigned config:2; - unsigned last_interface:3; - unsigned last_alternate:3; - -#ifdef CONFIG_PM - unsigned udccsr0; -#endif -#ifdef CONFIG_USB_GADGET_DEBUG_FS - struct dentry *debugfs_root; - struct dentry *debugfs_state; - struct dentry *debugfs_queues; - struct dentry *debugfs_eps; -#endif -}; - -static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget) -{ - return container_of(gadget, struct pxa_udc, gadget); -} - -/* - * Debugging/message support - */ -#define ep_dbg(ep, fmt, arg...) \ - dev_dbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_vdbg(ep, fmt, arg...) \ - dev_vdbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_err(ep, fmt, arg...) \ - dev_err(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_info(ep, fmt, arg...) \ - dev_info(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg) -#define ep_warn(ep, fmt, arg...) \ - dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg) - -#endif /* __LINUX_USB_GADGET_PXA27X_H */ diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 54cdd6f94034..8d158e5640e3 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -135,10 +135,7 @@ struct gs_port { int port_in_use; /* open/close in progress */ wait_queue_head_t port_write_wait;/* waiting to write */ struct gs_buf *port_write_buf; - struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ - u16 port_handshake_bits; -#define RS232_RTS (1 << 1) -#define RS232_DTE (1 << 0) + struct usb_cdc_line_coding port_line_coding; }; /* the device structure holds info for the USB device */ @@ -202,8 +199,6 @@ static int gs_setup_standard(struct usb_gadget *gadget, static int gs_setup_class(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl); static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); -static void gs_setup_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req); static void gs_disconnect(struct usb_gadget *gadget); static int gs_set_config(struct gs_dev *dev, unsigned config); static void gs_reset_config(struct gs_dev *dev); @@ -411,7 +406,7 @@ static struct usb_cdc_acm_descriptor gs_acm_descriptor = { .bLength = sizeof(gs_acm_descriptor), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_ACM_TYPE, - .bmCapabilities = (1 << 1), + .bmCapabilities = 0, }; static const struct usb_cdc_union_desc gs_union_desc = { @@ -1507,8 +1502,6 @@ static int gs_setup(struct usb_gadget *gadget, u16 wValue = le16_to_cpu(ctrl->wValue); u16 wLength = le16_to_cpu(ctrl->wLength); - req->complete = gs_setup_complete; - switch (ctrl->bRequestType & USB_TYPE_MASK) { case USB_TYPE_STANDARD: ret = gs_setup_standard(gadget,ctrl); @@ -1686,14 +1679,18 @@ static int gs_setup_class(struct usb_gadget *gadget, switch (ctrl->bRequest) { case USB_CDC_REQ_SET_LINE_CODING: - if (wLength != sizeof(struct usb_cdc_line_coding)) - break; - ret = wLength; - req->complete = gs_setup_complete_set_line_coding; + /* FIXME Submit req to read the data; have its completion + * handler copy that data to port->port_line_coding (iff + * it's valid) and maybe pass it on. Until then, fail. + */ + pr_warning("gs_setup: set_line_coding " + "unuspported\n"); break; case USB_CDC_REQ_GET_LINE_CODING: - ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding)); + port = dev->dev_port[0]; /* ACM only has one port */ + ret = min(wLength, + (u16)sizeof(struct usb_cdc_line_coding)); if (port) { spin_lock(&port->port_lock); memcpy(req->buf, &port->port_line_coding, ret); @@ -1702,27 +1699,15 @@ static int gs_setup_class(struct usb_gadget *gadget, break; case USB_CDC_REQ_SET_CONTROL_LINE_STATE: - if (wLength != 0) - break; - ret = 0; - if (port) { - /* REVISIT: we currently just remember this data. - * If we change that, update whatever hardware needs - * updating. - */ - spin_lock(&port->port_lock); - port->port_handshake_bits = wValue; - spin_unlock(&port->port_lock); - } + /* FIXME Submit req to read the data; have its completion + * handler use that to set the state (iff it's valid) and + * maybe pass it on. Until then, fail. + */ + pr_warning("gs_setup: set_control_line_state " + "unuspported\n"); break; default: - /* NOTE: strictly speaking, we should accept AT-commands - * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE. - * But our call management descriptor says we don't handle - * call management, so we should be able to get by without - * handling those "required" commands (except by stalling). - */ pr_err("gs_setup: unknown class request, " "type=%02x, request=%02x, value=%04x, " "index=%04x, length=%d\n", @@ -1734,42 +1719,6 @@ static int gs_setup_class(struct usb_gadget *gadget, return ret; } -static void gs_setup_complete_set_line_coding(struct usb_ep *ep, - struct usb_request *req) -{ - struct gs_dev *dev = ep->driver_data; - struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */ - - switch (req->status) { - case 0: - /* normal completion */ - if (req->actual != sizeof(port->port_line_coding)) - usb_ep_set_halt(ep); - else if (port) { - struct usb_cdc_line_coding *value = req->buf; - - /* REVISIT: we currently just remember this data. - * If we change that, (a) validate it first, then - * (b) update whatever hardware needs updating. - */ - spin_lock(&port->port_lock); - port->port_line_coding = *value; - spin_unlock(&port->port_lock); - } - break; - - case -ESHUTDOWN: - /* disconnect */ - gs_free_req(ep, req); - break; - - default: - /* unexpected */ - break; - } - return; -} - /* * gs_setup_complete */ @@ -1957,11 +1906,6 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) } } - /* REVISIT the ACM mode should be able to actually *issue* some - * notifications, for at least serial state change events if - * not also for network connection; say so in bmCapabilities. - */ - pr_info("gs_set_config: %s configured, %s speed %s config\n", GS_LONG_NAME, gadget->speed == USB_SPEED_HIGH ? "high" : "full", diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index fce4924dbbe8..d3d4f4048e6c 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -23,7 +23,9 @@ /* * Gadget Zero only needs two bulk endpoints, and is an example of how you * can write a hardware-agnostic gadget driver running inside a USB device. - * Some hardware details are visible, but don't affect most of the driver. + * + * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't + * affect most of the driver. * * Use it with the Linux host/master side "usbtest" driver to get a basic * functional test of your device-side usb stack, or with "usb-skeleton". @@ -35,7 +37,6 @@ * buflen=N default N=4096, buffer size used * qlen=N default N=32, how many buffers in the loopback queue * loopdefault default false, list loopback config first - * autoresume=N default N=0, seconds before triggering remote wakeup * * Many drivers will only have one configuration, letting them be much * simpler if they also don't support high speed operation (like this @@ -61,13 +62,13 @@ /*-------------------------------------------------------------------------*/ -#define DRIVER_VERSION "Earth Day 2008" +#define DRIVER_VERSION "Lughnasadh, 2007" -static const char shortname[] = "zero"; -static const char longname[] = "Gadget Zero"; +static const char shortname [] = "zero"; +static const char longname [] = "Gadget Zero"; -static const char source_sink[] = "source and sink data"; -static const char loopback[] = "loop input to output"; +static const char source_sink [] = "source and sink data"; +static const char loopback [] = "loop input to output"; /*-------------------------------------------------------------------------*/ @@ -119,16 +120,16 @@ static unsigned buflen = 4096; static unsigned qlen = 32; static unsigned pattern = 0; -module_param(buflen, uint, S_IRUGO); -module_param(qlen, uint, S_IRUGO); -module_param(pattern, uint, S_IRUGO|S_IWUSR); +module_param (buflen, uint, S_IRUGO); +module_param (qlen, uint, S_IRUGO); +module_param (pattern, uint, S_IRUGO|S_IWUSR); /* * if it's nonzero, autoresume says how many seconds to wait * before trying to wake up the host after suspend. */ static unsigned autoresume = 0; -module_param(autoresume, uint, 0); +module_param (autoresume, uint, 0); /* * Normally the "loopback" configuration is second (index 1) so @@ -137,7 +138,8 @@ module_param(autoresume, uint, 0); * Or controllers (like superh) that only support one config. */ static int loopdefault = 0; -module_param(loopdefault, bool, S_IRUGO|S_IWUSR); + +module_param (loopdefault, bool, S_IRUGO|S_IWUSR); /*-------------------------------------------------------------------------*/ @@ -174,22 +176,24 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR); #define CONFIG_SOURCE_SINK 3 #define CONFIG_LOOPBACK 2 -static struct usb_device_descriptor device_desc = { +static struct usb_device_descriptor +device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = __constant_cpu_to_le16(0x0200), + .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, - .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), - .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), + .idVendor = __constant_cpu_to_le16 (DRIVER_VENDOR_NUM), + .idProduct = __constant_cpu_to_le16 (DRIVER_PRODUCT_NUM), .iManufacturer = STRING_MANUFACTURER, .iProduct = STRING_PRODUCT, .iSerialNumber = STRING_SERIAL, .bNumConfigurations = 2, }; -static struct usb_config_descriptor source_sink_config = { +static struct usb_config_descriptor +source_sink_config = { .bLength = sizeof source_sink_config, .bDescriptorType = USB_DT_CONFIG, @@ -201,7 +205,8 @@ static struct usb_config_descriptor source_sink_config = { .bMaxPower = 1, /* self-powered */ }; -static struct usb_config_descriptor loopback_config = { +static struct usb_config_descriptor +loopback_config = { .bLength = sizeof loopback_config, .bDescriptorType = USB_DT_CONFIG, @@ -213,7 +218,8 @@ static struct usb_config_descriptor loopback_config = { .bMaxPower = 1, /* self-powered */ }; -static struct usb_otg_descriptor otg_descriptor = { +static struct usb_otg_descriptor +otg_descriptor = { .bLength = sizeof otg_descriptor, .bDescriptorType = USB_DT_OTG, @@ -222,7 +228,8 @@ static struct usb_otg_descriptor otg_descriptor = { /* one interface in each configuration */ -static const struct usb_interface_descriptor source_sink_intf = { +static const struct usb_interface_descriptor +source_sink_intf = { .bLength = sizeof source_sink_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -231,7 +238,8 @@ static const struct usb_interface_descriptor source_sink_intf = { .iInterface = STRING_SOURCE_SINK, }; -static const struct usb_interface_descriptor loopback_intf = { +static const struct usb_interface_descriptor +loopback_intf = { .bLength = sizeof loopback_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -242,7 +250,8 @@ static const struct usb_interface_descriptor loopback_intf = { /* two full speed bulk endpoints; their use is config-dependent */ -static struct usb_endpoint_descriptor fs_source_desc = { +static struct usb_endpoint_descriptor +fs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -250,7 +259,8 @@ static struct usb_endpoint_descriptor fs_source_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor fs_sink_desc = { +static struct usb_endpoint_descriptor +fs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -258,7 +268,7 @@ static struct usb_endpoint_descriptor fs_sink_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static const struct usb_descriptor_header *fs_source_sink_function[] = { +static const struct usb_descriptor_header *fs_source_sink_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &source_sink_intf, (struct usb_descriptor_header *) &fs_sink_desc, @@ -266,7 +276,7 @@ static const struct usb_descriptor_header *fs_source_sink_function[] = { NULL, }; -static const struct usb_descriptor_header *fs_loopback_function[] = { +static const struct usb_descriptor_header *fs_loopback_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &loopback_intf, (struct usb_descriptor_header *) &fs_sink_desc, @@ -283,33 +293,36 @@ static const struct usb_descriptor_header *fs_loopback_function[] = { * for the config descriptor. */ -static struct usb_endpoint_descriptor hs_source_desc = { +static struct usb_endpoint_descriptor +hs_source_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = __constant_cpu_to_le16 (512), }; -static struct usb_endpoint_descriptor hs_sink_desc = { +static struct usb_endpoint_descriptor +hs_sink_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = __constant_cpu_to_le16(512), + .wMaxPacketSize = __constant_cpu_to_le16 (512), }; -static struct usb_qualifier_descriptor dev_qualifier = { +static struct usb_qualifier_descriptor +dev_qualifier = { .bLength = sizeof dev_qualifier, .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = __constant_cpu_to_le16(0x0200), + .bcdUSB = __constant_cpu_to_le16 (0x0200), .bDeviceClass = USB_CLASS_VENDOR_SPEC, .bNumConfigurations = 2, }; -static const struct usb_descriptor_header *hs_source_sink_function[] = { +static const struct usb_descriptor_header *hs_source_sink_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &source_sink_intf, (struct usb_descriptor_header *) &hs_source_desc, @@ -317,7 +330,7 @@ static const struct usb_descriptor_header *hs_source_sink_function[] = { NULL, }; -static const struct usb_descriptor_header *hs_loopback_function[] = { +static const struct usb_descriptor_header *hs_loopback_function [] = { (struct usb_descriptor_header *) &otg_descriptor, (struct usb_descriptor_header *) &loopback_intf, (struct usb_descriptor_header *) &hs_source_desc, @@ -342,7 +355,7 @@ static char serial[] = "0123456789.0123456789.0123456789"; /* static strings, in UTF-8 */ -static struct usb_string strings[] = { +static struct usb_string strings [] = { { STRING_MANUFACTURER, manufacturer, }, { STRING_PRODUCT, longname, }, { STRING_SERIAL, serial, }, @@ -351,7 +364,7 @@ static struct usb_string strings[] = { { } /* end of list */ }; -static struct usb_gadget_strings stringtab = { +static struct usb_gadget_strings stringtab = { .language = 0x0409, /* en-us */ .strings = strings, }; @@ -374,7 +387,8 @@ static struct usb_gadget_strings stringtab = { * high bandwidth modes at high speed. (Maybe work like Intel's test * device?) */ -static int config_buf(struct usb_gadget *gadget, +static int +config_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index) { int is_source_sink; @@ -405,7 +419,7 @@ static int config_buf(struct usb_gadget *gadget, if (!gadget_is_otg(gadget)) function++; - len = usb_gadget_config_buf(is_source_sink + len = usb_gadget_config_buf (is_source_sink ? &source_sink_config : &loopback_config, buf, USB_BUFSIZ, function); @@ -417,26 +431,27 @@ static int config_buf(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ -static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) +static struct usb_request * +alloc_ep_req (struct usb_ep *ep, unsigned length) { struct usb_request *req; - req = usb_ep_alloc_request(ep, GFP_ATOMIC); + req = usb_ep_alloc_request (ep, GFP_ATOMIC); if (req) { req->length = length; req->buf = kmalloc(length, GFP_ATOMIC); if (!req->buf) { - usb_ep_free_request(ep, req); + usb_ep_free_request (ep, req); req = NULL; } } return req; } -static void free_ep_req(struct usb_ep *ep, struct usb_request *req) +static void free_ep_req (struct usb_ep *ep, struct usb_request *req) { kfree(req->buf); - usb_ep_free_request(ep, req); + usb_ep_free_request (ep, req); } /*-------------------------------------------------------------------------*/ @@ -457,7 +472,7 @@ static void free_ep_req(struct usb_ep *ep, struct usb_request *req) /* optionally require specific source/sink data patterns */ static int -check_read_data( +check_read_data ( struct zero_dev *dev, struct usb_ep *ep, struct usb_request *req @@ -483,8 +498,8 @@ check_read_data( continue; break; } - ERROR(dev, "bad OUT byte, buf[%d] = %d\n", i, *buf); - usb_ep_set_halt(ep); + ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf); + usb_ep_set_halt (ep); return -EINVAL; } return 0; @@ -497,7 +512,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) switch (pattern) { case 0: - memset(req->buf, 0, req->length); + memset (req->buf, 0, req->length); break; case 1: for (i = 0; i < req->length; i++) @@ -510,7 +525,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) * irq delay between end of one request and start of the next. * that prevents using hardware dma queues. */ -static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) +static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) { struct zero_dev *dev = ep->driver_data; int status = req->status; @@ -519,8 +534,8 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) case 0: /* normal completion? */ if (ep == dev->out_ep) { - check_read_data(dev, ep, req); - memset(req->buf, 0x55, req->length); + check_read_data (dev, ep, req); + memset (req->buf, 0x55, req->length); } else reinit_write_data(ep, req); break; @@ -529,11 +544,11 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ - VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, + VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, req->actual, req->length); if (ep == dev->out_ep) - check_read_data(dev, ep, req); - free_ep_req(ep, req); + check_read_data (dev, ep, req); + free_ep_req (ep, req); return; case -EOVERFLOW: /* buffer overrun on read means that @@ -542,18 +557,18 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) */ default: #if 1 - DBG(dev, "%s complete --> %d, %d/%d\n", ep->name, + DBG (dev, "%s complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); #endif case -EREMOTEIO: /* short read */ break; } - status = usb_ep_queue(ep, req, GFP_ATOMIC); + status = usb_ep_queue (ep, req, GFP_ATOMIC); if (status) { - ERROR(dev, "kill %s: resubmit %d bytes --> %d\n", + ERROR (dev, "kill %s: resubmit %d bytes --> %d\n", ep->name, req->length, status); - usb_ep_set_halt(ep); + usb_ep_set_halt (ep); /* FIXME recover later ... somehow */ } } @@ -563,24 +578,24 @@ static struct usb_request *source_sink_start_ep(struct usb_ep *ep) struct usb_request *req; int status; - req = alloc_ep_req(ep, buflen); + req = alloc_ep_req (ep, buflen); if (!req) return NULL; - memset(req->buf, 0, req->length); + memset (req->buf, 0, req->length); req->complete = source_sink_complete; - if (strcmp(ep->name, EP_IN_NAME) == 0) + if (strcmp (ep->name, EP_IN_NAME) == 0) reinit_write_data(ep, req); else - memset(req->buf, 0x55, req->length); + memset (req->buf, 0x55, req->length); status = usb_ep_queue(ep, req, GFP_ATOMIC); if (status) { struct zero_dev *dev = ep->driver_data; - ERROR(dev, "start %s --> %d\n", ep->name, status); - free_ep_req(ep, req); + ERROR (dev, "start %s --> %d\n", ep->name, status); + free_ep_req (ep, req); req = NULL; } @@ -593,34 +608,34 @@ static int set_source_sink_config(struct zero_dev *dev) struct usb_ep *ep; struct usb_gadget *gadget = dev->gadget; - gadget_for_each_ep(ep, gadget) { + gadget_for_each_ep (ep, gadget) { const struct usb_endpoint_descriptor *d; /* one endpoint writes (sources) zeroes in (to the host) */ - if (strcmp(ep->name, EP_IN_NAME) == 0) { - d = ep_desc(gadget, &hs_source_desc, &fs_source_desc); - result = usb_ep_enable(ep, d); + if (strcmp (ep->name, EP_IN_NAME) == 0) { + d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; if (source_sink_start_ep(ep) != NULL) { dev->in_ep = ep; continue; } - usb_ep_disable(ep); + usb_ep_disable (ep); result = -EIO; } /* one endpoint reads (sinks) anything out (from the host) */ - } else if (strcmp(ep->name, EP_OUT_NAME) == 0) { - d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); - result = usb_ep_enable(ep, d); + } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { + d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; if (source_sink_start_ep(ep) != NULL) { dev->out_ep = ep; continue; } - usb_ep_disable(ep); + usb_ep_disable (ep); result = -EIO; } @@ -629,11 +644,11 @@ static int set_source_sink_config(struct zero_dev *dev) continue; /* stop on error */ - ERROR(dev, "can't start %s, result %d\n", ep->name, result); + ERROR (dev, "can't start %s, result %d\n", ep->name, result); break; } if (result == 0) - DBG(dev, "buflen %d\n", buflen); + DBG (dev, "buflen %d\n", buflen); /* caller is responsible for cleanup on error */ return result; @@ -641,7 +656,7 @@ static int set_source_sink_config(struct zero_dev *dev) /*-------------------------------------------------------------------------*/ -static void loopback_complete(struct usb_ep *ep, struct usb_request *req) +static void loopback_complete (struct usb_ep *ep, struct usb_request *req) { struct zero_dev *dev = ep->driver_data; int status = req->status; @@ -653,19 +668,19 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) /* loop this OUT packet back IN to the host */ req->zero = (req->actual < req->length); req->length = req->actual; - status = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + status = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); if (status == 0) return; /* "should never get here" */ - ERROR(dev, "can't loop %s to %s: %d\n", + ERROR (dev, "can't loop %s to %s: %d\n", ep->name, dev->in_ep->name, status); } /* queue the buffer for some later OUT packet */ req->length = buflen; - status = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC); + status = usb_ep_queue (dev->out_ep, req, GFP_ATOMIC); if (status == 0) return; @@ -673,7 +688,7 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) /* FALLTHROUGH */ default: - ERROR(dev, "%s loop complete --> %d, %d/%d\n", ep->name, + ERROR (dev, "%s loop complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); /* FALLTHROUGH */ @@ -685,7 +700,7 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ - free_ep_req(ep, req); + free_ep_req (ep, req); return; } } @@ -696,13 +711,13 @@ static int set_loopback_config(struct zero_dev *dev) struct usb_ep *ep; struct usb_gadget *gadget = dev->gadget; - gadget_for_each_ep(ep, gadget) { + gadget_for_each_ep (ep, gadget) { const struct usb_endpoint_descriptor *d; /* one endpoint writes data back IN to the host */ - if (strcmp(ep->name, EP_IN_NAME) == 0) { - d = ep_desc(gadget, &hs_source_desc, &fs_source_desc); - result = usb_ep_enable(ep, d); + if (strcmp (ep->name, EP_IN_NAME) == 0) { + d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; dev->in_ep = ep; @@ -710,9 +725,9 @@ static int set_loopback_config(struct zero_dev *dev) } /* one endpoint just reads OUT packets */ - } else if (strcmp(ep->name, EP_OUT_NAME) == 0) { - d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); - result = usb_ep_enable(ep, d); + } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { + d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); + result = usb_ep_enable (ep, d); if (result == 0) { ep->driver_data = dev; dev->out_ep = ep; @@ -724,7 +739,7 @@ static int set_loopback_config(struct zero_dev *dev) continue; /* stop on error */ - ERROR(dev, "can't enable %s, result %d\n", ep->name, result); + ERROR (dev, "can't enable %s, result %d\n", ep->name, result); break; } @@ -738,19 +753,19 @@ static int set_loopback_config(struct zero_dev *dev) ep = dev->out_ep; for (i = 0; i < qlen && result == 0; i++) { - req = alloc_ep_req(ep, buflen); + req = alloc_ep_req (ep, buflen); if (req) { req->complete = loopback_complete; - result = usb_ep_queue(ep, req, GFP_ATOMIC); + result = usb_ep_queue (ep, req, GFP_ATOMIC); if (result) - DBG(dev, "%s queue req --> %d\n", + DBG (dev, "%s queue req --> %d\n", ep->name, result); } else result = -ENOMEM; } } if (result == 0) - DBG(dev, "qlen %d, buflen %d\n", qlen, buflen); + DBG (dev, "qlen %d, buflen %d\n", qlen, buflen); /* caller is responsible for cleanup on error */ return result; @@ -758,26 +773,26 @@ static int set_loopback_config(struct zero_dev *dev) /*-------------------------------------------------------------------------*/ -static void zero_reset_config(struct zero_dev *dev) +static void zero_reset_config (struct zero_dev *dev) { if (dev->config == 0) return; - DBG(dev, "reset config\n"); + DBG (dev, "reset config\n"); /* just disable endpoints, forcing completion of pending i/o. * all our completion handlers free their requests in this case. */ if (dev->in_ep) { - usb_ep_disable(dev->in_ep); + usb_ep_disable (dev->in_ep); dev->in_ep = NULL; } if (dev->out_ep) { - usb_ep_disable(dev->out_ep); + usb_ep_disable (dev->out_ep); dev->out_ep = NULL; } dev->config = 0; - del_timer(&dev->resume); + del_timer (&dev->resume); } /* change our operational config. this code must agree with the code @@ -798,12 +813,12 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) if (number == dev->config) return 0; - if (gadget_is_sa1100(gadget) && dev->config) { + if (gadget_is_sa1100 (gadget) && dev->config) { /* tx fifo is full, but we can't clear it...*/ ERROR(dev, "can't change configurations\n"); return -ESPIPE; } - zero_reset_config(dev); + zero_reset_config (dev); switch (number) { case CONFIG_SOURCE_SINK: @@ -822,7 +837,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) if (!result && (!dev->in_ep || !dev->out_ep)) result = -ENODEV; if (result) - zero_reset_config(dev); + zero_reset_config (dev); else { char *speed; @@ -834,7 +849,7 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) } dev->config = number; - INFO(dev, "%s speed config #%d: %s\n", speed, number, + INFO (dev, "%s speed config #%d: %s\n", speed, number, (number == CONFIG_SOURCE_SINK) ? source_sink : loopback); } @@ -843,10 +858,10 @@ static int zero_set_config(struct zero_dev *dev, unsigned number) /*-------------------------------------------------------------------------*/ -static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req) +static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req) { if (req->status || req->actual != req->length) - DBG((struct zero_dev *) ep->driver_data, + DBG ((struct zero_dev *) ep->driver_data, "setup complete --> %d, %d/%d\n", req->status, req->actual, req->length); } @@ -859,9 +874,9 @@ static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req) * the work is in config-specific setup. */ static int -zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); struct usb_request *req = dev->req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); @@ -880,14 +895,14 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) switch (w_value >> 8) { case USB_DT_DEVICE: - value = min(w_length, (u16) sizeof device_desc); - memcpy(req->buf, &device_desc, value); + value = min (w_length, (u16) sizeof device_desc); + memcpy (req->buf, &device_desc, value); break; case USB_DT_DEVICE_QUALIFIER: if (!gadget_is_dualspeed(gadget)) break; - value = min(w_length, (u16) sizeof dev_qualifier); - memcpy(req->buf, &dev_qualifier, value); + value = min (w_length, (u16) sizeof dev_qualifier); + memcpy (req->buf, &dev_qualifier, value); break; case USB_DT_OTHER_SPEED_CONFIG: @@ -895,11 +910,11 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; // FALLTHROUGH case USB_DT_CONFIG: - value = config_buf(gadget, req->buf, + value = config_buf (gadget, req->buf, w_value >> 8, w_value & 0xff); if (value >= 0) - value = min(w_length, (u16) value); + value = min (w_length, (u16) value); break; case USB_DT_STRING: @@ -908,10 +923,10 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) * add string tables for other languages, using * any UTF-8 characters */ - value = usb_gadget_get_string(&stringtab, + value = usb_gadget_get_string (&stringtab, w_value & 0xff, req->buf); if (value >= 0) - value = min(w_length, (u16) value); + value = min (w_length, (u16) value); break; } break; @@ -921,20 +936,20 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (ctrl->bRequestType != 0) goto unknown; if (gadget->a_hnp_support) - DBG(dev, "HNP available\n"); + DBG (dev, "HNP available\n"); else if (gadget->a_alt_hnp_support) - DBG(dev, "HNP needs a different root port\n"); + DBG (dev, "HNP needs a different root port\n"); else - VDBG(dev, "HNP inactive\n"); - spin_lock(&dev->lock); + VDBG (dev, "HNP inactive\n"); + spin_lock (&dev->lock); value = zero_set_config(dev, w_value); - spin_unlock(&dev->lock); + spin_unlock (&dev->lock); break; case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) goto unknown; *(u8 *)req->buf = dev->config; - value = min(w_length, (u16) 1); + value = min (w_length, (u16) 1); break; /* until we add altsetting support, or other interfaces, @@ -944,7 +959,7 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) goto unknown; - spin_lock(&dev->lock); + spin_lock (&dev->lock); if (dev->config && w_index == 0 && w_value == 0) { u8 config = dev->config; @@ -955,11 +970,11 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) * if we had more than one interface we couldn't * use this "reset the config" shortcut. */ - zero_reset_config(dev); + zero_reset_config (dev); zero_set_config(dev, config); value = 0; } - spin_unlock(&dev->lock); + spin_unlock (&dev->lock); break; case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) @@ -971,7 +986,7 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; } *(u8 *)req->buf = 0; - value = min(w_length, (u16) 1); + value = min (w_length, (u16) 1); break; /* @@ -1003,7 +1018,7 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) default: unknown: - VDBG(dev, + VDBG (dev, "unknown control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); @@ -1013,11 +1028,11 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (value >= 0) { req->length = value; req->zero = value < w_length; - value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); + value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { - DBG(dev, "ep_queue --> %d\n", value); + DBG (dev, "ep_queue --> %d\n", value); req->status = 0; - zero_setup_complete(gadget->ep0, req); + zero_setup_complete (gadget->ep0, req); } } @@ -1025,26 +1040,28 @@ zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) return value; } -static void zero_disconnect(struct usb_gadget *gadget) +static void +zero_disconnect (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); unsigned long flags; - spin_lock_irqsave(&dev->lock, flags); - zero_reset_config(dev); + spin_lock_irqsave (&dev->lock, flags); + zero_reset_config (dev); /* a more significant application might have some non-usb * activities to quiesce here, saving resources like power * or pushing the notification up a network stack. */ - spin_unlock_irqrestore(&dev->lock, flags); + spin_unlock_irqrestore (&dev->lock, flags); /* next we may get setup() calls to enumerate new connections; * or an unbind() during shutdown (including removing module). */ } -static void zero_autoresume(unsigned long _dev) +static void +zero_autoresume (unsigned long _dev) { struct zero_dev *dev = (struct zero_dev *) _dev; int status; @@ -1053,30 +1070,32 @@ static void zero_autoresume(unsigned long _dev) * more significant than just a timer firing... */ if (dev->gadget->speed != USB_SPEED_UNKNOWN) { - status = usb_gadget_wakeup(dev->gadget); - DBG(dev, "wakeup --> %d\n", status); + status = usb_gadget_wakeup (dev->gadget); + DBG (dev, "wakeup --> %d\n", status); } } /*-------------------------------------------------------------------------*/ -static void zero_unbind(struct usb_gadget *gadget) +static void /* __init_or_exit */ +zero_unbind (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); - DBG(dev, "unbind\n"); + DBG (dev, "unbind\n"); /* we've already been disconnected ... no i/o is active */ if (dev->req) { dev->req->length = USB_BUFSIZ; - free_ep_req(gadget->ep0, dev->req); + free_ep_req (gadget->ep0, dev->req); } - del_timer_sync(&dev->resume); - kfree(dev); - set_gadget_data(gadget, NULL); + del_timer_sync (&dev->resume); + kfree (dev); + set_gadget_data (gadget, NULL); } -static int __init zero_bind(struct usb_gadget *gadget) +static int __init +zero_bind (struct usb_gadget *gadget) { struct zero_dev *dev; struct usb_ep *ep; @@ -1092,8 +1111,8 @@ static int __init zero_bind(struct usb_gadget *gadget) * autoconfigure on any sane usb controller driver, * but there may also be important quirks to address. */ - usb_ep_autoconfig_reset(gadget); - ep = usb_ep_autoconfig(gadget, &fs_source_desc); + usb_ep_autoconfig_reset (gadget); + ep = usb_ep_autoconfig (gadget, &fs_source_desc); if (!ep) { autoconf_fail: pr_err("%s: can't autoconfigure on %s\n", @@ -1103,15 +1122,15 @@ static int __init zero_bind(struct usb_gadget *gadget) EP_IN_NAME = ep->name; ep->driver_data = ep; /* claim */ - ep = usb_ep_autoconfig(gadget, &fs_sink_desc); + ep = usb_ep_autoconfig (gadget, &fs_sink_desc); if (!ep) goto autoconf_fail; EP_OUT_NAME = ep->name; ep->driver_data = ep; /* claim */ - gcnum = usb_gadget_controller_number(gadget); + gcnum = usb_gadget_controller_number (gadget); if (gcnum >= 0) - device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); + device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum); else { /* gadget zero is so simple (for now, no altsettings) that * it SHOULD NOT have problems with bulk-capable hardware. @@ -1122,7 +1141,7 @@ static int __init zero_bind(struct usb_gadget *gadget) */ pr_warning("%s: controller '%s' not recognized\n", shortname, gadget->name); - device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); + device_desc.bcdDevice = __constant_cpu_to_le16 (0x9999); } @@ -1130,16 +1149,12 @@ static int __init zero_bind(struct usb_gadget *gadget) dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - spin_lock_init(&dev->lock); + spin_lock_init (&dev->lock); dev->gadget = gadget; - set_gadget_data(gadget, dev); - - init_timer(&dev->resume); - dev->resume.function = zero_autoresume; - dev->resume.data = (unsigned long) dev; + set_gadget_data (gadget, dev); /* preallocate control response and buffer */ - dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); + dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); if (!dev->req) goto enomem; dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL); @@ -1167,8 +1182,11 @@ static int __init zero_bind(struct usb_gadget *gadget) loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - usb_gadget_set_selfpowered(gadget); + usb_gadget_set_selfpowered (gadget); + init_timer (&dev->resume); + dev->resume.function = zero_autoresume; + dev->resume.data = (unsigned long) dev; if (autoresume) { source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; @@ -1176,43 +1194,45 @@ static int __init zero_bind(struct usb_gadget *gadget) gadget->ep0->driver_data = dev; - INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname); - INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, + INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname); + INFO (dev, "using %s, OUT %s IN %s\n", gadget->name, EP_OUT_NAME, EP_IN_NAME); - snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", + snprintf (manufacturer, sizeof manufacturer, "%s %s with %s", init_utsname()->sysname, init_utsname()->release, gadget->name); return 0; enomem: - zero_unbind(gadget); + zero_unbind (gadget); return -ENOMEM; } /*-------------------------------------------------------------------------*/ -static void zero_suspend(struct usb_gadget *gadget) +static void +zero_suspend (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); if (gadget->speed == USB_SPEED_UNKNOWN) return; if (autoresume) { - mod_timer(&dev->resume, jiffies + (HZ * autoresume)); - DBG(dev, "suspend, wakeup in %d seconds\n", autoresume); + mod_timer (&dev->resume, jiffies + (HZ * autoresume)); + DBG (dev, "suspend, wakeup in %d seconds\n", autoresume); } else - DBG(dev, "suspend\n"); + DBG (dev, "suspend\n"); } -static void zero_resume(struct usb_gadget *gadget) +static void +zero_resume (struct usb_gadget *gadget) { - struct zero_dev *dev = get_gadget_data(gadget); + struct zero_dev *dev = get_gadget_data (gadget); - DBG(dev, "resume\n"); - del_timer(&dev->resume); + DBG (dev, "resume\n"); + del_timer (&dev->resume); } @@ -1244,15 +1264,15 @@ MODULE_AUTHOR("David Brownell"); MODULE_LICENSE("GPL"); -static int __init init(void) +static int __init init (void) { - return usb_gadget_register_driver(&zero_driver); + return usb_gadget_register_driver (&zero_driver); } -module_init(init); +module_init (init); -static void __exit cleanup(void) +static void __exit cleanup (void) { - usb_gadget_unregister_driver(&zero_driver); + usb_gadget_unregister_driver (&zero_driver); } -module_exit(cleanup); +module_exit (cleanup); diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 33b467a8352d..0b87480dd713 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -4,19 +4,6 @@ comment "USB Host Controller Drivers" depends on USB -config USB_C67X00_HCD - tristate "Cypress C67x00 HCD support" - depends on USB - help - The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role - host/peripheral/OTG USB controllers. - - Enable this option to support this chip in host controller mode. - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called c67x00. - config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support" depends on USB && USB_ARCH_HAS_EHCI @@ -108,32 +95,6 @@ config USB_ISP116X_HCD To compile this driver as a module, choose M here: the module will be called isp116x-hcd. -config USB_ISP1760_HCD - tristate "ISP 1760 HCD support" - depends on USB && EXPERIMENTAL - ---help--- - The ISP1760 chip is a USB 2.0 host controller. - - This driver does not support isochronous transfers or OTG. - - To compile this driver as a module, choose M here: the - module will be called isp1760-hcd. - -config USB_ISP1760_PCI - bool "Support for the PCI bus" - depends on USB_ISP1760_HCD && PCI - ---help--- - Enables support for the device present on the PCI bus. - This should only be required if you happen to have the eval kit from - NXP and you are going to test it. - -config USB_ISP1760_OF - bool "Support for the OF platform bus" - depends on USB_ISP1760_HCD && OF - ---help--- - Enables support for the device present on the PowerPC - OpenFirmware platform bus. - config USB_OHCI_HCD tristate "OHCI HCD support" depends on USB && USB_ARCH_HAS_OHCI diff --git a/trunk/drivers/usb/host/Makefile b/trunk/drivers/usb/host/Makefile index f1edda2dcfde..bb8e9d44f371 100644 --- a/trunk/drivers/usb/host/Makefile +++ b/trunk/drivers/usb/host/Makefile @@ -6,8 +6,6 @@ ifeq ($(CONFIG_USB_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif -isp1760-objs := isp1760-hcd.o isp1760-if.o - obj-$(CONFIG_PCI) += pci-quirks.o obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o @@ -18,4 +16,4 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o -obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o + diff --git a/trunk/drivers/usb/host/isp1760-hcd.c b/trunk/drivers/usb/host/isp1760-hcd.c deleted file mode 100644 index 4ba96c1e060c..000000000000 --- a/trunk/drivers/usb/host/isp1760-hcd.c +++ /dev/null @@ -1,2231 +0,0 @@ -/* - * Driver for the NXP ISP1760 chip - * - * However, the code might contain some bugs. What doesn't work for sure is: - * - ISO - * - OTG - e The interrupt line is configured as active low, level. - * - * (c) 2007 Sebastian Siewior - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../core/hcd.h" -#include "isp1760-hcd.h" - -static struct kmem_cache *qtd_cachep; -static struct kmem_cache *qh_cachep; - -struct isp1760_hcd { - u32 hcs_params; - spinlock_t lock; - struct inter_packet_info atl_ints[32]; - struct inter_packet_info int_ints[32]; - struct memory_chunk memory_pool[BLOCKS]; - - /* periodic schedule support */ -#define DEFAULT_I_TDPS 1024 - unsigned periodic_size; - unsigned i_thresh; - unsigned long reset_done; - unsigned long next_statechange; -}; - -static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) -{ - return (struct isp1760_hcd *) (hcd->hcd_priv); -} -static inline struct usb_hcd *priv_to_hcd(struct isp1760_hcd *priv) -{ - return container_of((void *) priv, struct usb_hcd, hcd_priv); -} - -/* Section 2.2 Host Controller Capability Registers */ -#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ -#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ -#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ -#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */ -#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */ -#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */ -#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */ - -/* Section 2.3 Host Controller Operational Registers */ -#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */ -#define CMD_RESET (1<<1) /* reset HC not bus */ -#define CMD_RUN (1<<0) /* start/stop HC */ -#define STS_PCD (1<<2) /* port change detect */ -#define FLAG_CF (1<<0) /* true: we'll support "high speed" */ - -#define PORT_OWNER (1<<13) /* true: companion hc owns this port */ -#define PORT_POWER (1<<12) /* true: has power (see PPC) */ -#define PORT_USB11(x) (((x) & (3 << 10)) == (1 << 10)) /* USB 1.1 device */ -#define PORT_RESET (1<<8) /* reset port */ -#define PORT_SUSPEND (1<<7) /* suspend port */ -#define PORT_RESUME (1<<6) /* resume it */ -#define PORT_PE (1<<2) /* port enable */ -#define PORT_CSC (1<<1) /* connect status change */ -#define PORT_CONNECT (1<<0) /* device connected */ -#define PORT_RWC_BITS (PORT_CSC) - -struct isp1760_qtd { - struct isp1760_qtd *hw_next; - u8 packet_type; - u8 toggle; - - void *data_buffer; - /* the rest is HCD-private */ - struct list_head qtd_list; - struct urb *urb; - size_t length; - - /* isp special*/ - u32 status; -#define URB_COMPLETE_NOTIFY (1 << 0) -#define URB_ENQUEUED (1 << 1) -#define URB_TYPE_ATL (1 << 2) -#define URB_TYPE_INT (1 << 3) -}; - -struct isp1760_qh { - /* first part defined by EHCI spec */ - struct list_head qtd_list; - struct isp1760_hcd *priv; - - /* periodic schedule info */ - unsigned short period; /* polling interval */ - struct usb_device *dev; - - u32 toggle; - u32 ping; -}; - -#define ehci_port_speed(priv, portsc) (1 << USB_PORT_FEAT_HIGHSPEED) - -static unsigned int isp1760_readl(__u32 __iomem *regs) -{ - return readl(regs); -} - -static void isp1760_writel(const unsigned int val, __u32 __iomem *regs) -{ - writel(val, regs); -} - -/* - * The next two copy via MMIO data to/from the device. memcpy_{to|from}io() - * doesn't quite work because some people have to enforce 32-bit access - */ -static void priv_read_copy(struct isp1760_hcd *priv, u32 *src, - __u32 __iomem *dst, u32 offset, u32 len) -{ - struct usb_hcd *hcd = priv_to_hcd(priv); - u32 val; - u8 *buff8; - - if (!src) { - printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len); - return; - } - isp1760_writel(offset, hcd->regs + HC_MEMORY_REG); - /* XXX - * 90nsec delay, the spec says something how this could be avoided. - */ - mdelay(1); - - while (len >= 4) { - *src = __raw_readl(dst); - len -= 4; - src++; - dst++; - } - - if (!len) - return; - - /* in case we have 3, 2 or 1 by left. The dst buffer may not be fully - * allocated. - */ - val = isp1760_readl(dst); - - buff8 = (u8 *)src; - while (len) { - - *buff8 = val; - val >>= 8; - len--; - buff8++; - } -} - -static void priv_write_copy(const struct isp1760_hcd *priv, const u32 *src, - __u32 __iomem *dst, u32 len) -{ - while (len >= 4) { - __raw_writel(*src, dst); - len -= 4; - src++; - dst++; - } - - if (!len) - return; - /* in case we have 3, 2 or 1 by left. The buffer is allocated and the - * extra bytes should not be read by the HW - */ - - __raw_writel(*src, dst); -} - -/* memory management of the 60kb on the chip from 0x1000 to 0xffff */ -static void init_memory(struct isp1760_hcd *priv) -{ - int i; - u32 payload; - - payload = 0x1000; - for (i = 0; i < BLOCK_1_NUM; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_1_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; - } - - - for (i = BLOCK_1_NUM; i < BLOCK_1_NUM + BLOCK_2_NUM; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_2_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; - } - - - for (i = BLOCK_1_NUM + BLOCK_2_NUM; i < BLOCKS; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_3_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; - } - - BUG_ON(payload - priv->memory_pool[i - 1].size > PAYLOAD_SIZE); -} - -static u32 alloc_mem(struct isp1760_hcd *priv, u32 size) -{ - int i; - - if (!size) - return ISP1760_NULL_POINTER; - - for (i = 0; i < BLOCKS; i++) { - if (priv->memory_pool[i].size >= size && - priv->memory_pool[i].free) { - - priv->memory_pool[i].free = 0; - return priv->memory_pool[i].start; - } - } - - printk(KERN_ERR "ISP1760 MEM: can not allocate %d bytes of memory\n", - size); - printk(KERN_ERR "Current memory map:\n"); - for (i = 0; i < BLOCKS; i++) { - printk(KERN_ERR "Pool %2d size %4d status: %d\n", - i, priv->memory_pool[i].size, - priv->memory_pool[i].free); - } - /* XXX maybe -ENOMEM could be possible */ - BUG(); - return 0; -} - -static void free_mem(struct isp1760_hcd *priv, u32 mem) -{ - int i; - - if (mem == ISP1760_NULL_POINTER) - return; - - for (i = 0; i < BLOCKS; i++) { - if (priv->memory_pool[i].start == mem) { - - BUG_ON(priv->memory_pool[i].free); - - priv->memory_pool[i].free = 1; - return ; - } - } - - printk(KERN_ERR "Trying to free not-here-allocated memory :%08x\n", - mem); - BUG(); -} - -static void isp1760_init_regs(struct usb_hcd *hcd) -{ - isp1760_writel(0, hcd->regs + HC_BUFFER_STATUS_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_ISO_PTD_SKIPMAP_REG); - - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_ATL_PTD_DONEMAP_REG); - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_INT_PTD_DONEMAP_REG); - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_ISO_PTD_DONEMAP_REG); -} - -static int handshake(struct isp1760_hcd *priv, void __iomem *ptr, - u32 mask, u32 done, int usec) -{ - u32 result; - - do { - result = isp1760_readl(ptr); - if (result == ~0) - return -ENODEV; - result &= mask; - if (result == done) - return 0; - udelay(1); - usec--; - } while (usec > 0); - return -ETIMEDOUT; -} - -/* reset a non-running (STS_HALT == 1) controller */ -static int ehci_reset(struct isp1760_hcd *priv) -{ - int retval; - struct usb_hcd *hcd = priv_to_hcd(priv); - u32 command = isp1760_readl(hcd->regs + HC_USBCMD); - - command |= CMD_RESET; - isp1760_writel(command, hcd->regs + HC_USBCMD); - hcd->state = HC_STATE_HALT; - priv->next_statechange = jiffies; - retval = handshake(priv, hcd->regs + HC_USBCMD, - CMD_RESET, 0, 250 * 1000); - return retval; -} - -static void qh_destroy(struct isp1760_qh *qh) -{ - BUG_ON(!list_empty(&qh->qtd_list)); - kmem_cache_free(qh_cachep, qh); -} - -static struct isp1760_qh *isp1760_qh_alloc(struct isp1760_hcd *priv, - gfp_t flags) -{ - struct isp1760_qh *qh; - - qh = kmem_cache_zalloc(qh_cachep, flags); - if (!qh) - return qh; - - INIT_LIST_HEAD(&qh->qtd_list); - qh->priv = priv; - return qh; -} - -/* magic numbers that can affect system performance */ -#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ -#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ -#define EHCI_TUNE_RL_TT 0 -#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ -#define EHCI_TUNE_MULT_TT 1 -#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ - -/* one-time init, only for memory state */ -static int priv_init(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 hcc_params; - - spin_lock_init(&priv->lock); - - /* - * hw default: 1K periodic list heads, one per frame. - * periodic_size can shrink by USBCMD update if hcc_params allows. - */ - priv->periodic_size = DEFAULT_I_TDPS; - - /* controllers may cache some of the periodic schedule ... */ - hcc_params = isp1760_readl(hcd->regs + HC_HCCPARAMS); - /* full frame cache */ - if (HCC_ISOC_CACHE(hcc_params)) - priv->i_thresh = 8; - else /* N microframes cached */ - priv->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); - - return 0; -} - -static int isp1760_hc_setup(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - int result; - u32 scratch; - - isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); - scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); - if (scratch != 0xdeadbabe) { - printk(KERN_ERR "ISP1760: Scratch test failed.\n"); - return -ENODEV; - } - - /* pre reset */ - isp1760_init_regs(hcd); - - /* reset */ - isp1760_writel(SW_RESET_RESET_ALL, hcd->regs + HC_RESET_REG); - mdelay(100); - - isp1760_writel(SW_RESET_RESET_HC, hcd->regs + HC_RESET_REG); - mdelay(100); - - result = ehci_reset(priv); - if (result) - return result; - - /* Step 11 passed */ - - isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); - isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); - - /* ATL reset */ - scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL); - mdelay(10); - isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL); - - isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL); - mdelay(10); - - priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); - - return priv_init(hcd); -} - -static void isp1760_init_maps(struct usb_hcd *hcd) -{ - /*set last maps, for iso its only 1, else 32 tds bitmap*/ - isp1760_writel(0x80000000, hcd->regs + HC_ATL_PTD_LASTPTD_REG); - isp1760_writel(0x80000000, hcd->regs + HC_INT_PTD_LASTPTD_REG); - isp1760_writel(0x00000001, hcd->regs + HC_ISO_PTD_LASTPTD_REG); -} - -static void isp1760_enable_interrupts(struct usb_hcd *hcd) -{ - isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_AND_REG); - isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_AND_REG); - isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_OR_REG); - isp1760_writel(0, hcd->regs + HC_ISO_IRQ_MASK_AND_REG); - isp1760_writel(0xffffffff, hcd->regs + HC_ISO_IRQ_MASK_OR_REG); - /* step 23 passed */ -} - -static int isp1760_run(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - int retval; - u32 temp; - u32 command; - u32 chipid; - - hcd->uses_new_polling = 1; - hcd->poll_rh = 0; - - hcd->state = HC_STATE_RUNNING; - isp1760_enable_interrupts(hcd); - temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - temp |= FINAL_HW_CONFIG; - isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL); - - command = isp1760_readl(hcd->regs + HC_USBCMD); - command &= ~(CMD_LRESET|CMD_RESET); - command |= CMD_RUN; - isp1760_writel(command, hcd->regs + HC_USBCMD); - - retval = handshake(priv, hcd->regs + HC_USBCMD, CMD_RUN, CMD_RUN, - 250 * 1000); - if (retval) - return retval; - - /* - * XXX - * Spec says to write FLAG_CF as last config action, priv code grabs - * the semaphore while doing so. - */ - down_write(&ehci_cf_port_reset_rwsem); - isp1760_writel(FLAG_CF, hcd->regs + HC_CONFIGFLAG); - - retval = handshake(priv, hcd->regs + HC_CONFIGFLAG, FLAG_CF, FLAG_CF, - 250 * 1000); - up_write(&ehci_cf_port_reset_rwsem); - if (retval) - return retval; - - chipid = isp1760_readl(hcd->regs + HC_CHIP_ID_REG); - isp1760_info(priv, "USB ISP %04x HW rev. %d started\n", chipid & 0xffff, - chipid >> 16); - - /* PTD Register Init Part 2, Step 28 */ - /* enable INTs */ - isp1760_init_maps(hcd); - - /* GRR this is run-once init(), being done every time the HC starts. - * So long as they're part of class devices, we can't do it init() - * since the class device isn't created that early. - */ - return 0; -} - -static u32 base_to_chip(u32 base) -{ - return ((base - 0x400) >> 3); -} - -static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) -{ - u32 dw0; - u32 dw1; - u32 dw2; - u32 dw3; - u32 maxpacket; - u32 multi; - u32 pid_code; - u32 rl = RL_COUNTER; - u32 nak = NAK_COUNTER; - - /* according to 3.6.2, max packet len can not be > 0x400 */ - maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - multi = 1 + ((maxpacket >> 11) & 0x3); - maxpacket &= 0x7ff; - - /* DW0 */ - dw0 = PTD_VALID; - dw0 |= PTD_LENGTH(qtd->length); - dw0 |= PTD_MAXPACKET(maxpacket); - dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe)); - dw1 = usb_pipeendpoint(urb->pipe) >> 1; - - /* DW1 */ - dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe)); - - pid_code = qtd->packet_type; - dw1 |= PTD_PID_TOKEN(pid_code); - - if (usb_pipebulk(urb->pipe)) - dw1 |= PTD_TRANS_BULK; - else if (usb_pipeint(urb->pipe)) - dw1 |= PTD_TRANS_INT; - - if (urb->dev->speed != USB_SPEED_HIGH) { - /* split transaction */ - - dw1 |= PTD_TRANS_SPLIT; - if (urb->dev->speed == USB_SPEED_LOW) - dw1 |= PTD_SE_USB_LOSPEED; - - dw1 |= PTD_PORT_NUM(urb->dev->ttport); - dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum); - - /* SE bit for Split INT transfers */ - if (usb_pipeint(urb->pipe) && - (urb->dev->speed == USB_SPEED_LOW)) - dw1 |= 2 << 16; - - dw3 = 0; - rl = 0; - nak = 0; - } else { - dw0 |= PTD_MULTI(multi); - if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) - dw3 = qh->ping; - else - dw3 = 0; - } - /* DW2 */ - dw2 = 0; - dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload)); - dw2 |= PTD_RL_CNT(rl); - dw3 |= PTD_NAC_CNT(nak); - - /* DW3 */ - if (usb_pipecontrol(urb->pipe)) - dw3 |= PTD_DATA_TOGGLE(qtd->toggle); - else - dw3 |= qh->toggle; - - - dw3 |= PTD_ACTIVE; - /* Cerr */ - dw3 |= PTD_CERR(ERR_COUNTER); - - memset(ptd, 0, sizeof(*ptd)); - - ptd->dw0 = cpu_to_le32(dw0); - ptd->dw1 = cpu_to_le32(dw1); - ptd->dw2 = cpu_to_le32(dw2); - ptd->dw3 = cpu_to_le32(dw3); -} - -static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) -{ - u32 maxpacket; - u32 multi; - u32 numberofusofs; - u32 i; - u32 usofmask, usof; - u32 period; - - maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); - multi = 1 + ((maxpacket >> 11) & 0x3); - maxpacket &= 0x7ff; - /* length of the data per uframe */ - maxpacket = multi * maxpacket; - - numberofusofs = urb->transfer_buffer_length / maxpacket; - if (urb->transfer_buffer_length % maxpacket) - numberofusofs += 1; - - usofmask = 1; - usof = 0; - for (i = 0; i < numberofusofs; i++) { - usof |= usofmask; - usofmask <<= 1; - } - - if (urb->dev->speed != USB_SPEED_HIGH) { - /* split */ - ptd->dw5 = __constant_cpu_to_le32(0x1c); - - if (qh->period >= 32) - period = qh->period / 2; - else - period = qh->period; - - } else { - - if (qh->period >= 8) - period = qh->period/8; - else - period = qh->period; - - if (period >= 32) - period = 16; - - if (qh->period >= 8) { - /* millisecond period */ - period = (period << 3); - } else { - /* usof based tranmsfers */ - /* minimum 4 usofs */ - usof = 0x11; - } - } - - ptd->dw2 |= cpu_to_le32(period); - ptd->dw4 = cpu_to_le32(usof); -} - -static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) -{ - transform_into_atl(priv, qh, qtd, urb, payload, ptd); - transform_add_int(priv, qh, qtd, urb, payload, ptd); -} - -static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, - u32 token) -{ - int count; - - qtd->data_buffer = databuffer; - qtd->packet_type = GET_QTD_TOKEN_TYPE(token); - qtd->toggle = GET_DATA_TOGGLE(token); - - if (len > HC_ATL_PL_SIZE) - count = HC_ATL_PL_SIZE; - else - count = len; - - qtd->length = count; - return count; -} - -static int check_error(struct ptd *ptd) -{ - int error = 0; - u32 dw3; - - dw3 = le32_to_cpu(ptd->dw3); - if (dw3 & DW3_HALT_BIT) - error = -EPIPE; - - if (dw3 & DW3_ERROR_BIT) { - printk(KERN_ERR "error bit is set in DW3\n"); - error = -EPIPE; - } - - if (dw3 & DW3_QTD_ACTIVE) { - printk(KERN_ERR "transfer active bit is set DW3\n"); - printk(KERN_ERR "nak counter: %d, rl: %d\n", (dw3 >> 19) & 0xf, - (le32_to_cpu(ptd->dw2) >> 25) & 0xf); - } - - return error; -} - -static void check_int_err_status(u32 dw4) -{ - u32 i; - - dw4 >>= 8; - - for (i = 0; i < 8; i++) { - switch (dw4 & 0x7) { - case INT_UNDERRUN: - printk(KERN_ERR "ERROR: under run , %d\n", i); - break; - - case INT_EXACT: - printk(KERN_ERR "ERROR: transaction error, %d\n", i); - break; - - case INT_BABBLE: - printk(KERN_ERR "ERROR: babble error, %d\n", i); - break; - } - dw4 >>= 3; - } -} - -static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv, - u32 payload) -{ - u32 token; - struct usb_hcd *hcd = priv_to_hcd(priv); - - token = qtd->packet_type; - - if (qtd->length && (qtd->length <= HC_ATL_PL_SIZE)) { - switch (token) { - case IN_PID: - break; - case OUT_PID: - case SETUP_PID: - priv_write_copy(priv, qtd->data_buffer, - hcd->regs + payload, - qtd->length); - } - } -} - -static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload, - struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct urb *urb, u32 slot, struct isp1760_qtd *qtd) -{ - struct ptd ptd; - struct usb_hcd *hcd = priv_to_hcd(priv); - - transform_into_atl(priv, qh, qtd, urb, payload, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + atl_regs, sizeof(ptd)); - enqueue_one_qtd(qtd, priv, payload); - - priv->atl_ints[slot].urb = urb; - priv->atl_ints[slot].qh = qh; - priv->atl_ints[slot].qtd = qtd; - priv->atl_ints[slot].data_buffer = qtd->data_buffer; - priv->atl_ints[slot].payload = payload; - qtd->status |= URB_ENQUEUED | URB_TYPE_ATL; - qtd->status |= slot << 16; -} - -static void enqueue_one_int_qtd(u32 int_regs, u32 payload, - struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct urb *urb, u32 slot, struct isp1760_qtd *qtd) -{ - struct ptd ptd; - struct usb_hcd *hcd = priv_to_hcd(priv); - - transform_into_int(priv, qh, qtd, urb, payload, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + int_regs, sizeof(ptd)); - enqueue_one_qtd(qtd, priv, payload); - - priv->int_ints[slot].urb = urb; - priv->int_ints[slot].qh = qh; - priv->int_ints[slot].qtd = qtd; - priv->int_ints[slot].data_buffer = qtd->data_buffer; - priv->int_ints[slot].payload = payload; - qtd->status |= URB_ENQUEUED | URB_TYPE_INT; - qtd->status |= slot << 16; -} - -void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 skip_map, or_map; - u32 queue_entry; - u32 slot; - u32 atl_regs, payload; - u32 buffstatus; - - skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); - - BUG_ON(!skip_map); - slot = __ffs(skip_map); - queue_entry = 1 << slot; - - atl_regs = ATL_REGS_OFFSET + slot * sizeof(struct ptd); - - payload = alloc_mem(priv, qtd->length); - - enqueue_one_atl_qtd(atl_regs, payload, priv, qh, qtd->urb, slot, qtd); - - or_map = isp1760_readl(hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - or_map |= queue_entry; - isp1760_writel(or_map, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - - skip_map &= ~queue_entry; - isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); - - buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); - buffstatus |= ATL_BUFFER; - isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); -} - -void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 skip_map, or_map; - u32 queue_entry; - u32 slot; - u32 int_regs, payload; - u32 buffstatus; - - skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); - - BUG_ON(!skip_map); - slot = __ffs(skip_map); - queue_entry = 1 << slot; - - int_regs = INT_REGS_OFFSET + slot * sizeof(struct ptd); - - payload = alloc_mem(priv, qtd->length); - - enqueue_one_int_qtd(int_regs, payload, priv, qh, qtd->urb, slot, qtd); - - or_map = isp1760_readl(hcd->regs + HC_INT_IRQ_MASK_OR_REG); - or_map |= queue_entry; - isp1760_writel(or_map, hcd->regs + HC_INT_IRQ_MASK_OR_REG); - - skip_map &= ~queue_entry; - isp1760_writel(skip_map, hcd->regs + HC_INT_PTD_SKIPMAP_REG); - - buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); - buffstatus |= INT_BUFFER; - isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); -} - -static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, int status) -__releases(priv->lock) -__acquires(priv->lock) -{ - if (!urb->unlinked) { - if (status == -EINPROGRESS) - status = 0; - } - - /* complete() can reenter this HCD */ - usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); - spin_unlock(&priv->lock); - usb_hcd_giveback_urb(priv_to_hcd(priv), urb, status); - spin_lock(&priv->lock); -} - -static void isp1760_qtd_free(struct isp1760_qtd *qtd) -{ - kmem_cache_free(qtd_cachep, qtd); -} - -static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd) -{ - struct isp1760_qtd *tmp_qtd; - - tmp_qtd = qtd->hw_next; - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - return tmp_qtd; -} - -/* - * Remove this QTD from the QH list and free its memory. If this QTD - * isn't the last one than remove also his successor(s). - * Returns the QTD which is part of an new URB and should be enqueued. - */ -static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd) -{ - struct isp1760_qtd *tmp_qtd; - int last_one; - - do { - tmp_qtd = qtd->hw_next; - last_one = qtd->status & URB_COMPLETE_NOTIFY; - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - qtd = tmp_qtd; - } while (!last_one && qtd); - - return qtd; -} - -static void do_atl_int(struct usb_hcd *usb_hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - u32 done_map, skip_map; - struct ptd ptd; - struct urb *urb = NULL; - u32 atl_regs_base; - u32 atl_regs; - u32 queue_entry; - u32 payload; - u32 length; - u32 or_map; - u32 status = -EINVAL; - int error; - struct isp1760_qtd *qtd; - struct isp1760_qh *qh; - u32 rl; - u32 nakcount; - - done_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_DONEMAP_REG); - skip_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - - or_map = isp1760_readl(usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - or_map &= ~done_map; - isp1760_writel(or_map, usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - - atl_regs_base = ATL_REGS_OFFSET; - while (done_map) { - u32 dw1; - u32 dw2; - u32 dw3; - - status = 0; - - queue_entry = __ffs(done_map); - done_map &= ~(1 << queue_entry); - skip_map |= 1 << queue_entry; - - atl_regs = atl_regs_base + queue_entry * sizeof(struct ptd); - - urb = priv->atl_ints[queue_entry].urb; - qtd = priv->atl_ints[queue_entry].qtd; - qh = priv->atl_ints[queue_entry].qh; - payload = priv->atl_ints[queue_entry].payload; - - if (!qh) { - printk(KERN_ERR "qh is 0\n"); - continue; - } - priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs, - atl_regs, sizeof(ptd)); - - dw1 = le32_to_cpu(ptd.dw1); - dw2 = le32_to_cpu(ptd.dw2); - dw3 = le32_to_cpu(ptd.dw3); - rl = (dw2 >> 25) & 0x0f; - nakcount = (dw3 >> 19) & 0xf; - - /* Transfer Error, *but* active and no HALT -> reload */ - if ((dw3 & DW3_ERROR_BIT) && (dw3 & DW3_QTD_ACTIVE) && - !(dw3 & DW3_HALT_BIT)) { - - /* according to ppriv code, we have to - * reload this one if trasfered bytes != requested bytes - * else act like everything went smooth.. - * XXX This just doesn't feel right and hasn't - * triggered so far. - */ - - length = PTD_XFERRED_LENGTH(dw3); - printk(KERN_ERR "Should reload now.... transfered %d " - "of %zu\n", length, qtd->length); - BUG(); - } - - if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { - u32 buffstatus; - - /* XXX - * NAKs are handled in HW by the chip. Usually if the - * device is not able to send data fast enough. - * This did not trigger for a long time now. - */ - printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: " - "%d of %d done: %08x cur: %08x\n", qtd, - urb, qh, PTD_XFERRED_LENGTH(dw3), - qtd->length, done_map, - (1 << queue_entry)); - - /* RL counter = ERR counter */ - dw3 &= ~(0xf << 19); - dw3 |= rl << 19; - dw3 &= ~(3 << (55 - 32)); - dw3 |= ERR_COUNTER << (55 - 32); - - /* - * It is not needed to write skip map back because it - * is unchanged. Just make sure that this entry is - * unskipped once it gets written to the HW. - */ - skip_map &= ~(1 << queue_entry); - or_map = isp1760_readl(usb_hcd->regs + - HC_ATL_IRQ_MASK_OR_REG); - or_map |= 1 << queue_entry; - isp1760_writel(or_map, usb_hcd->regs + - HC_ATL_IRQ_MASK_OR_REG); - - ptd.dw3 = cpu_to_le32(dw3); - priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + - atl_regs, sizeof(ptd)); - - ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID); - priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + - atl_regs, sizeof(ptd)); - - buffstatus = isp1760_readl(usb_hcd->regs + - HC_BUFFER_STATUS_REG); - buffstatus |= ATL_BUFFER; - isp1760_writel(buffstatus, usb_hcd->regs + - HC_BUFFER_STATUS_REG); - continue; - } - - error = check_error(&ptd); - if (error) { - status = error; - priv->atl_ints[queue_entry].qh->toggle = 0; - priv->atl_ints[queue_entry].qh->ping = 0; - urb->status = -EPIPE; - -#if 0 - printk(KERN_ERR "Error in %s().\n", __func__); - printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x " - "dw3: %08x dw4: %08x dw5: %08x dw6: " - "%08x dw7: %08x\n", - ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, - ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); -#endif - } else { - if (usb_pipetype(urb->pipe) == PIPE_BULK) { - priv->atl_ints[queue_entry].qh->toggle = dw3 & - (1 << 25); - priv->atl_ints[queue_entry].qh->ping = dw3 & - (1 << 26); - } - } - - length = PTD_XFERRED_LENGTH(dw3); - if (length) { - switch (DW1_GET_PID(dw1)) { - case IN_PID: - priv_read_copy(priv, - priv->atl_ints[queue_entry].data_buffer, - usb_hcd->regs + payload, payload, - length); - - case OUT_PID: - - urb->actual_length += length; - - case SETUP_PID: - break; - } - } - - priv->atl_ints[queue_entry].data_buffer = NULL; - priv->atl_ints[queue_entry].urb = NULL; - priv->atl_ints[queue_entry].qtd = NULL; - priv->atl_ints[queue_entry].qh = NULL; - - free_mem(priv, payload); - - isp1760_writel(skip_map, usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - - if (urb->status == -EPIPE) { - /* HALT was received */ - - qtd = clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { - /* short BULK received */ - - printk(KERN_ERR "short bulk, %d instead %d\n", length, - qtd->length); - if (urb->transfer_flags & URB_SHORT_NOT_OK) { - urb->status = -EREMOTEIO; - printk(KERN_ERR "not okey\n"); - } - - if (urb->status == -EINPROGRESS) - urb->status = 0; - - qtd = clean_up_qtdlist(qtd); - - isp1760_urb_done(priv, urb, urb->status); - - } else if (qtd->status & URB_COMPLETE_NOTIFY) { - /* that was the last qtd of that URB */ - - if (urb->status == -EINPROGRESS) - urb->status = 0; - - qtd = clean_this_qtd(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else { - /* next QTD of this URB */ - - qtd = clean_this_qtd(qtd); - BUG_ON(!qtd); - } - - if (qtd) - enqueue_an_ATL_packet(usb_hcd, qh, qtd); - - skip_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - } -} - -static void do_intl_int(struct usb_hcd *usb_hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - u32 done_map, skip_map; - struct ptd ptd; - struct urb *urb = NULL; - u32 int_regs; - u32 int_regs_base; - u32 payload; - u32 length; - u32 or_map; - int error; - u32 queue_entry; - struct isp1760_qtd *qtd; - struct isp1760_qh *qh; - - done_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_DONEMAP_REG); - skip_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - - or_map = isp1760_readl(usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); - or_map &= ~done_map; - isp1760_writel(or_map, usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); - - int_regs_base = INT_REGS_OFFSET; - - while (done_map) { - u32 dw1; - u32 dw3; - - queue_entry = __ffs(done_map); - done_map &= ~(1 << queue_entry); - skip_map |= 1 << queue_entry; - - int_regs = int_regs_base + queue_entry * sizeof(struct ptd); - urb = priv->int_ints[queue_entry].urb; - qtd = priv->int_ints[queue_entry].qtd; - qh = priv->int_ints[queue_entry].qh; - payload = priv->int_ints[queue_entry].payload; - - if (!qh) { - printk(KERN_ERR "(INT) qh is 0\n"); - continue; - } - - priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs, - int_regs, sizeof(ptd)); - dw1 = le32_to_cpu(ptd.dw1); - dw3 = le32_to_cpu(ptd.dw3); - check_int_err_status(le32_to_cpu(ptd.dw4)); - - error = check_error(&ptd); - if (error) { -#if 0 - printk(KERN_ERR "Error in %s().\n", __func__); - printk(KERN_ERR "IN dw0: %08x dw1: %08x dw2: %08x " - "dw3: %08x dw4: %08x dw5: %08x dw6: " - "%08x dw7: %08x\n", - ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, - ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); -#endif - urb->status = -EPIPE; - priv->int_ints[queue_entry].qh->toggle = 0; - priv->int_ints[queue_entry].qh->ping = 0; - - } else { - priv->int_ints[queue_entry].qh->toggle = - dw3 & (1 << 25); - priv->int_ints[queue_entry].qh->ping = dw3 & (1 << 26); - } - - if (urb->dev->speed != USB_SPEED_HIGH) - length = PTD_XFERRED_LENGTH_LO(dw3); - else - length = PTD_XFERRED_LENGTH(dw3); - - if (length) { - switch (DW1_GET_PID(dw1)) { - case IN_PID: - priv_read_copy(priv, - priv->int_ints[queue_entry].data_buffer, - usb_hcd->regs + payload , payload, - length); - case OUT_PID: - - urb->actual_length += length; - - case SETUP_PID: - break; - } - } - - priv->int_ints[queue_entry].data_buffer = NULL; - priv->int_ints[queue_entry].urb = NULL; - priv->int_ints[queue_entry].qtd = NULL; - priv->int_ints[queue_entry].qh = NULL; - - isp1760_writel(skip_map, usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - free_mem(priv, payload); - - if (urb->status == -EPIPE) { - /* HALT received */ - - qtd = clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else if (qtd->status & URB_COMPLETE_NOTIFY) { - - if (urb->status == -EINPROGRESS) - urb->status = 0; - - qtd = clean_this_qtd(qtd); - isp1760_urb_done(priv, urb, urb->status); - - } else { - /* next QTD of this URB */ - - qtd = clean_this_qtd(qtd); - BUG_ON(!qtd); - } - - if (qtd) - enqueue_an_INT_packet(usb_hcd, qh, qtd); - - skip_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - } -} - -#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) -static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, - gfp_t flags) -{ - struct isp1760_qh *qh; - int is_input, type; - - qh = isp1760_qh_alloc(priv, flags); - if (!qh) - return qh; - - /* - * init endpoint/device data for this QH - */ - is_input = usb_pipein(urb->pipe); - type = usb_pipetype(urb->pipe); - - if (type == PIPE_INTERRUPT) { - - if (urb->dev->speed == USB_SPEED_HIGH) { - - qh->period = urb->interval >> 3; - if (qh->period == 0 && urb->interval != 1) { - /* NOTE interval 2 or 4 uframes could work. - * But interval 1 scheduling is simpler, and - * includes high bandwidth. - */ - printk(KERN_ERR "intr period %d uframes, NYET!", - urb->interval); - qh_destroy(qh); - return NULL; - } - } else { - qh->period = urb->interval; - } - } - - /* support for tt scheduling, and access to toggles */ - qh->dev = urb->dev; - - if (!usb_pipecontrol(urb->pipe)) - usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, - 1); - return qh; -} - -/* - * For control/bulk/interrupt, return QH with these TDs appended. - * Allocates and initializes the QH if necessary. - * Returns null if it can't allocate a QH it needs to. - * If the QH has TDs (urbs) already, that's great. - */ -static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, - struct urb *urb, struct list_head *qtd_list, int epnum, - void **ptr) -{ - struct isp1760_qh *qh; - struct isp1760_qtd *qtd; - struct isp1760_qtd *prev_qtd; - - qh = (struct isp1760_qh *)*ptr; - if (!qh) { - /* can't sleep here, we have priv->lock... */ - qh = qh_make(priv, urb, GFP_ATOMIC); - if (!qh) - return qh; - *ptr = qh; - } - - qtd = list_entry(qtd_list->next, struct isp1760_qtd, - qtd_list); - if (!list_empty(&qh->qtd_list)) - prev_qtd = list_entry(qh->qtd_list.prev, - struct isp1760_qtd, qtd_list); - else - prev_qtd = NULL; - - list_splice(qtd_list, qh->qtd_list.prev); - if (prev_qtd) { - BUG_ON(prev_qtd->hw_next); - prev_qtd->hw_next = qtd; - } - - urb->hcpriv = qh; - return qh; -} - -static void qtd_list_free(struct isp1760_hcd *priv, struct urb *urb, - struct list_head *qtd_list) -{ - struct list_head *entry, *temp; - - list_for_each_safe(entry, temp, qtd_list) { - struct isp1760_qtd *qtd; - - qtd = list_entry(entry, struct isp1760_qtd, qtd_list); - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - } -} - -static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb, - struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p) -{ - struct isp1760_qtd *qtd; - int epnum; - unsigned long flags; - struct isp1760_qh *qh = NULL; - int rc; - int qh_busy; - - qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list); - epnum = urb->ep->desc.bEndpointAddress; - - spin_lock_irqsave(&priv->lock, flags); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &priv_to_hcd(priv)->flags)) { - rc = -ESHUTDOWN; - goto done; - } - rc = usb_hcd_link_urb_to_ep(priv_to_hcd(priv), urb); - if (rc) - goto done; - - qh = urb->ep->hcpriv; - if (qh) - qh_busy = !list_empty(&qh->qtd_list); - else - qh_busy = 0; - - qh = qh_append_tds(priv, urb, qtd_list, epnum, &urb->ep->hcpriv); - if (!qh) { - usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); - rc = -ENOMEM; - goto done; - } - - if (!qh_busy) - p(priv_to_hcd(priv), qh, qtd); - -done: - spin_unlock_irqrestore(&priv->lock, flags); - if (!qh) - qtd_list_free(priv, urb, qtd_list); - return rc; -} - -static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv, - gfp_t flags) -{ - struct isp1760_qtd *qtd; - - qtd = kmem_cache_zalloc(qtd_cachep, flags); - if (qtd) - INIT_LIST_HEAD(&qtd->qtd_list); - - return qtd; -} - -/* - * create a list of filled qtds for this URB; won't link into qh. - */ -static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, - struct urb *urb, struct list_head *head, gfp_t flags) -{ - struct isp1760_qtd *qtd, *qtd_prev; - void *buf; - int len, maxpacket; - int is_input; - u32 token; - - /* - * URBs map to sequences of QTDs: one logical transaction - */ - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - return NULL; - - list_add_tail(&qtd->qtd_list, head); - qtd->urb = urb; - urb->status = -EINPROGRESS; - - token = 0; - /* for split transactions, SplitXState initialized to zero */ - - len = urb->transfer_buffer_length; - is_input = usb_pipein(urb->pipe); - if (usb_pipecontrol(urb->pipe)) { - /* SETUP pid */ - qtd_fill(qtd, urb->setup_packet, - sizeof(struct usb_ctrlrequest), - token | SETUP_PID); - - /* ... and always at least one more pid */ - token ^= DATA_TOGGLE; - qtd_prev = qtd; - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - goto cleanup; - qtd->urb = urb; - qtd_prev->hw_next = qtd; - list_add_tail(&qtd->qtd_list, head); - - /* for zero length DATA stages, STATUS is always IN */ - if (len == 0) - token |= IN_PID; - } - - /* - * data transfer stage: buffer setup - */ - buf = urb->transfer_buffer; - - if (is_input) - token |= IN_PID; - else - token |= OUT_PID; - - maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input)); - - /* - * buffer gets wrapped in one or more qtds; - * last one may be "short" (including zero len) - * and may serve as a control status ack - */ - for (;;) { - int this_qtd_len; - - if (!buf && len) { - /* XXX This looks like usb storage / SCSI bug */ - printk(KERN_ERR "buf is null, dma is %08lx len is %d\n", - (long unsigned)urb->transfer_dma, len); - WARN_ON(1); - } - - this_qtd_len = qtd_fill(qtd, buf, len, token); - len -= this_qtd_len; - buf += this_qtd_len; - - /* qh makes control packets use qtd toggle; maybe switch it */ - if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) - token ^= DATA_TOGGLE; - - if (len <= 0) - break; - - qtd_prev = qtd; - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - goto cleanup; - qtd->urb = urb; - qtd_prev->hw_next = qtd; - list_add_tail(&qtd->qtd_list, head); - } - - /* - * control requests may need a terminating data "status" ack; - * bulk ones may need a terminating short packet (zero length). - */ - if (urb->transfer_buffer_length != 0) { - int one_more = 0; - - if (usb_pipecontrol(urb->pipe)) { - one_more = 1; - /* "in" <--> "out" */ - token ^= IN_PID; - /* force DATA1 */ - token |= DATA_TOGGLE; - } else if (usb_pipebulk(urb->pipe) - && (urb->transfer_flags & URB_ZERO_PACKET) - && !(urb->transfer_buffer_length % maxpacket)) { - one_more = 1; - } - if (one_more) { - qtd_prev = qtd; - qtd = isp1760_qtd_alloc(priv, flags); - if (!qtd) - goto cleanup; - qtd->urb = urb; - qtd_prev->hw_next = qtd; - list_add_tail(&qtd->qtd_list, head); - - /* never any data in such packets */ - qtd_fill(qtd, NULL, 0, token); - } - } - - qtd->status = URB_COMPLETE_NOTIFY; - return head; - -cleanup: - qtd_list_free(priv, urb, head); - return NULL; -} - -static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, - gfp_t mem_flags) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - struct list_head qtd_list; - packet_enqueue *pe; - - INIT_LIST_HEAD(&qtd_list); - - switch (usb_pipetype(urb->pipe)) { - case PIPE_CONTROL: - case PIPE_BULK: - - if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) - return -ENOMEM; - pe = enqueue_an_ATL_packet; - break; - - case PIPE_INTERRUPT: - if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) - return -ENOMEM; - pe = enqueue_an_INT_packet; - break; - - case PIPE_ISOCHRONOUS: - printk(KERN_ERR "PIPE_ISOCHRONOUS ain't supported\n"); - default: - return -EPIPE; - } - - isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe); - return 0; -} - -static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, - int status) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - struct inter_packet_info *ints; - u32 i; - u32 reg_base, or_reg, skip_reg; - int flags; - struct ptd ptd; - - switch (usb_pipetype(urb->pipe)) { - case PIPE_ISOCHRONOUS: - return -EPIPE; - break; - - case PIPE_INTERRUPT: - ints = priv->int_ints; - reg_base = INT_REGS_OFFSET; - or_reg = HC_INT_IRQ_MASK_OR_REG; - skip_reg = HC_INT_PTD_SKIPMAP_REG; - break; - - default: - ints = priv->atl_ints; - reg_base = ATL_REGS_OFFSET; - or_reg = HC_ATL_IRQ_MASK_OR_REG; - skip_reg = HC_ATL_PTD_SKIPMAP_REG; - break; - } - - memset(&ptd, 0, sizeof(ptd)); - spin_lock_irqsave(&priv->lock, flags); - - for (i = 0; i < 32; i++) { - if (ints->urb == urb) { - u32 skip_map; - u32 or_map; - struct isp1760_qtd *qtd; - - skip_map = isp1760_readl(hcd->regs + skip_reg); - skip_map |= 1 << i; - isp1760_writel(skip_map, hcd->regs + skip_reg); - - or_map = isp1760_readl(hcd->regs + or_reg); - or_map &= ~(1 << i); - isp1760_writel(or_map, hcd->regs + or_reg); - - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base - + i * sizeof(ptd), sizeof(ptd)); - qtd = ints->qtd; - - clean_up_qtdlist(qtd); - - free_mem(priv, ints->payload); - - ints->urb = NULL; - ints->qh = NULL; - ints->qtd = NULL; - ints->data_buffer = NULL; - ints->payload = 0; - - isp1760_urb_done(priv, urb, status); - break; - } - ints++; - } - - spin_unlock_irqrestore(&priv->lock, flags); - return 0; -} - -static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - u32 imask; - irqreturn_t irqret = IRQ_NONE; - - spin_lock(&priv->lock); - - if (!(usb_hcd->state & HC_STATE_RUNNING)) - goto leave; - - imask = isp1760_readl(usb_hcd->regs + HC_INTERRUPT_REG); - if (unlikely(!imask)) - goto leave; - - isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); - if (imask & HC_ATL_INT) - do_atl_int(usb_hcd); - - if (imask & HC_INTL_INT) - do_intl_int(usb_hcd); - - irqret = IRQ_HANDLED; -leave: - spin_unlock(&priv->lock); - return irqret; -} - -static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 temp, status = 0; - u32 mask; - int retval = 1; - unsigned long flags; - - /* if !USB_SUSPEND, root hub timers won't get shut down ... */ - if (!HC_IS_RUNNING(hcd->state)) - return 0; - - /* init status to no-changes */ - buf[0] = 0; - mask = PORT_CSC; - - spin_lock_irqsave(&priv->lock, flags); - temp = isp1760_readl(hcd->regs + HC_PORTSC1); - - if (temp & PORT_OWNER) { - if (temp & PORT_CSC) { - temp &= ~PORT_CSC; - isp1760_writel(temp, hcd->regs + HC_PORTSC1); - goto done; - } - } - - /* - * Return status information even for ports with OWNER set. - * Otherwise khubd wouldn't see the disconnect event when a - * high-speed device is switched over to the companion - * controller by the user. - */ - - if ((temp & mask) != 0 - || ((temp & PORT_RESUME) != 0 - && time_after_eq(jiffies, - priv->reset_done))) { - buf [0] |= 1 << (0 + 1); - status = STS_PCD; - } - /* FIXME autosuspend idle root hubs */ -done: - spin_unlock_irqrestore(&priv->lock, flags); - return status ? retval : 0; -} - -static void isp1760_hub_descriptor(struct isp1760_hcd *priv, - struct usb_hub_descriptor *desc) -{ - int ports = HCS_N_PORTS(priv->hcs_params); - u16 temp; - - desc->bDescriptorType = 0x29; - /* priv 1.0, 2.3.9 says 20ms max */ - desc->bPwrOn2PwrGood = 10; - desc->bHubContrCurrent = 0; - - desc->bNbrPorts = ports; - temp = 1 + (ports / 8); - desc->bDescLength = 7 + 2 * temp; - - /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->bitmap[0], 0, temp); - memset(&desc->bitmap[temp], 0xff, temp); - - /* per-port overcurrent reporting */ - temp = 0x0008; - if (HCS_PPC(priv->hcs_params)) - /* per-port power control */ - temp |= 0x0001; - else - /* no power switching */ - temp |= 0x0002; - desc->wHubCharacteristics = cpu_to_le16(temp); -} - -#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) - -static int check_reset_complete(struct isp1760_hcd *priv, int index, - u32 __iomem *status_reg, int port_status) -{ - if (!(port_status & PORT_CONNECT)) - return port_status; - - /* if reset finished and it's still not enabled -- handoff */ - if (!(port_status & PORT_PE)) { - - printk(KERN_ERR "port %d full speed --> companion\n", - index + 1); - - port_status |= PORT_OWNER; - port_status &= ~PORT_RWC_BITS; - isp1760_writel(port_status, status_reg); - - } else - printk(KERN_ERR "port %d high speed\n", index + 1); - - return port_status; -} - -static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, - u16 wValue, u16 wIndex, char *buf, u16 wLength) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - int ports = HCS_N_PORTS(priv->hcs_params); - u32 __iomem *status_reg = hcd->regs + HC_PORTSC1; - u32 temp, status; - unsigned long flags; - int retval = 0; - unsigned selector; - - /* - * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. - * HCS_INDICATOR may say we can change LEDs to off/amber/green. - * (track current state ourselves) ... blink for diagnostics, - * power, "this is the one", etc. EHCI spec supports this. - */ - - spin_lock_irqsave(&priv->lock, flags); - switch (typeReq) { - case ClearHubFeature: - switch (wValue) { - case C_HUB_LOCAL_POWER: - case C_HUB_OVER_CURRENT: - /* no hub-wide feature/status flags */ - break; - default: - goto error; - } - break; - case ClearPortFeature: - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - temp = isp1760_readl(status_reg); - - /* - * Even if OWNER is set, so the port is owned by the - * companion controller, khubd needs to be able to clear - * the port-change status bits (especially - * USB_PORT_FEAT_C_CONNECTION). - */ - - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - isp1760_writel(temp & ~PORT_PE, status_reg); - break; - case USB_PORT_FEAT_C_ENABLE: - /* XXX error? */ - break; - case USB_PORT_FEAT_SUSPEND: - if (temp & PORT_RESET) - goto error; - - if (temp & PORT_SUSPEND) { - if ((temp & PORT_PE) == 0) - goto error; - /* resume signaling for 20 msec */ - temp &= ~(PORT_RWC_BITS); - isp1760_writel(temp | PORT_RESUME, - status_reg); - priv->reset_done = jiffies + - msecs_to_jiffies(20); - } - break; - case USB_PORT_FEAT_C_SUSPEND: - /* we auto-clear this feature */ - break; - case USB_PORT_FEAT_POWER: - if (HCS_PPC(priv->hcs_params)) - isp1760_writel(temp & ~PORT_POWER, status_reg); - break; - case USB_PORT_FEAT_C_CONNECTION: - isp1760_writel(temp | PORT_CSC, - status_reg); - break; - case USB_PORT_FEAT_C_OVER_CURRENT: - /* XXX error ?*/ - break; - case USB_PORT_FEAT_C_RESET: - /* GetPortStatus clears reset */ - break; - default: - goto error; - } - isp1760_readl(hcd->regs + HC_USBCMD); - break; - case GetHubDescriptor: - isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *) - buf); - break; - case GetHubStatus: - /* no hub-wide feature/status flags */ - memset(buf, 0, 4); - break; - case GetPortStatus: - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - status = 0; - temp = isp1760_readl(status_reg); - - /* wPortChange bits */ - if (temp & PORT_CSC) - status |= 1 << USB_PORT_FEAT_C_CONNECTION; - - - /* whoever resumes must GetPortStatus to complete it!! */ - if (temp & PORT_RESUME) { - printk(KERN_ERR "Port resume should be skipped.\n"); - - /* Remote Wakeup received? */ - if (!priv->reset_done) { - /* resume signaling for 20 msec */ - priv->reset_done = jiffies - + msecs_to_jiffies(20); - /* check the port again */ - mod_timer(&priv_to_hcd(priv)->rh_timer, - priv->reset_done); - } - - /* resume completed? */ - else if (time_after_eq(jiffies, - priv->reset_done)) { - status |= 1 << USB_PORT_FEAT_C_SUSPEND; - priv->reset_done = 0; - - /* stop resume signaling */ - temp = isp1760_readl(status_reg); - isp1760_writel( - temp & ~(PORT_RWC_BITS | PORT_RESUME), - status_reg); - retval = handshake(priv, status_reg, - PORT_RESUME, 0, 2000 /* 2msec */); - if (retval != 0) { - isp1760_err(priv, - "port %d resume error %d\n", - wIndex + 1, retval); - goto error; - } - temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); - } - } - - /* whoever resets must GetPortStatus to complete it!! */ - if ((temp & PORT_RESET) - && time_after_eq(jiffies, - priv->reset_done)) { - status |= 1 << USB_PORT_FEAT_C_RESET; - priv->reset_done = 0; - - /* force reset to complete */ - isp1760_writel(temp & ~PORT_RESET, - status_reg); - /* REVISIT: some hardware needs 550+ usec to clear - * this bit; seems too long to spin routinely... - */ - retval = handshake(priv, status_reg, - PORT_RESET, 0, 750); - if (retval != 0) { - isp1760_err(priv, "port %d reset error %d\n", - wIndex + 1, retval); - goto error; - } - - /* see what we found out */ - temp = check_reset_complete(priv, wIndex, status_reg, - isp1760_readl(status_reg)); - } - /* - * Even if OWNER is set, there's no harm letting khubd - * see the wPortStatus values (they should all be 0 except - * for PORT_POWER anyway). - */ - - if (temp & PORT_OWNER) - printk(KERN_ERR "Warning: PORT_OWNER is set\n"); - - if (temp & PORT_CONNECT) { - status |= 1 << USB_PORT_FEAT_CONNECTION; - /* status may be from integrated TT */ - status |= ehci_port_speed(priv, temp); - } - if (temp & PORT_PE) - status |= 1 << USB_PORT_FEAT_ENABLE; - if (temp & (PORT_SUSPEND|PORT_RESUME)) - status |= 1 << USB_PORT_FEAT_SUSPEND; - if (temp & PORT_RESET) - status |= 1 << USB_PORT_FEAT_RESET; - if (temp & PORT_POWER) - status |= 1 << USB_PORT_FEAT_POWER; - - put_unaligned(cpu_to_le32(status), (__le32 *) buf); - break; - case SetHubFeature: - switch (wValue) { - case C_HUB_LOCAL_POWER: - case C_HUB_OVER_CURRENT: - /* no hub-wide feature/status flags */ - break; - default: - goto error; - } - break; - case SetPortFeature: - selector = wIndex >> 8; - wIndex &= 0xff; - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - temp = isp1760_readl(status_reg); - if (temp & PORT_OWNER) - break; - -/* temp &= ~PORT_RWC_BITS; */ - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - isp1760_writel(temp | PORT_PE, status_reg); - break; - - case USB_PORT_FEAT_SUSPEND: - if ((temp & PORT_PE) == 0 - || (temp & PORT_RESET) != 0) - goto error; - - isp1760_writel(temp | PORT_SUSPEND, status_reg); - break; - case USB_PORT_FEAT_POWER: - if (HCS_PPC(priv->hcs_params)) - isp1760_writel(temp | PORT_POWER, - status_reg); - break; - case USB_PORT_FEAT_RESET: - if (temp & PORT_RESUME) - goto error; - /* line status bits may report this as low speed, - * which can be fine if this root hub has a - * transaction translator built in. - */ - if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT - && PORT_USB11(temp)) { - temp |= PORT_OWNER; - } else { - temp |= PORT_RESET; - temp &= ~PORT_PE; - - /* - * caller must wait, then call GetPortStatus - * usb 2.0 spec says 50 ms resets on root - */ - priv->reset_done = jiffies + - msecs_to_jiffies(50); - } - isp1760_writel(temp, status_reg); - break; - default: - goto error; - } - isp1760_readl(hcd->regs + HC_USBCMD); - break; - - default: -error: - /* "stall" on error */ - retval = -EPIPE; - } - spin_unlock_irqrestore(&priv->lock, flags); - return retval; -} - -static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, - struct usb_host_endpoint *ep) -{ - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); - struct isp1760_qh *qh; - struct isp1760_qtd *qtd; - u32 flags; - - spin_lock_irqsave(&priv->lock, flags); - qh = ep->hcpriv; - if (!qh) - goto out; - - ep->hcpriv = NULL; - do { - /* more than entry might get removed */ - if (list_empty(&qh->qtd_list)) - break; - - qtd = list_first_entry(&qh->qtd_list, struct isp1760_qtd, - qtd_list); - - if (qtd->status & URB_ENQUEUED) { - - spin_unlock_irqrestore(&priv->lock, flags); - isp1760_urb_dequeue(usb_hcd, qtd->urb, -ECONNRESET); - spin_lock_irqsave(&priv->lock, flags); - } else { - struct urb *urb; - - urb = qtd->urb; - clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, -ECONNRESET); - } - } while (1); - - qh_destroy(qh); - /* remove requests and leak them. - * ATL are pretty fast done, INT could take a while... - * The latter shoule be removed - */ -out: - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int isp1760_get_frame(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - u32 fr; - - fr = isp1760_readl(hcd->regs + HC_FRINDEX); - return (fr >> 3) % priv->periodic_size; -} - -static void isp1760_stop(struct usb_hcd *hcd) -{ - struct isp1760_hcd *priv = hcd_to_priv(hcd); - - isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, - NULL, 0); - mdelay(20); - - spin_lock_irq(&priv->lock); - ehci_reset(priv); - /* Disable IRQ */ - isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); - spin_unlock_irq(&priv->lock); - - isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); -} - -static void isp1760_shutdown(struct usb_hcd *hcd) -{ - u32 command; - - isp1760_stop(hcd); - isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); - - command = isp1760_readl(hcd->regs + HC_USBCMD); - command &= ~CMD_RUN; - isp1760_writel(command, hcd->regs + HC_USBCMD); -} - -static const struct hc_driver isp1760_hc_driver = { - .description = "isp1760-hcd", - .product_desc = "NXP ISP1760 USB Host Controller", - .hcd_priv_size = sizeof(struct isp1760_hcd), - .irq = isp1760_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = isp1760_hc_setup, - .start = isp1760_run, - .stop = isp1760_stop, - .shutdown = isp1760_shutdown, - .urb_enqueue = isp1760_urb_enqueue, - .urb_dequeue = isp1760_urb_dequeue, - .endpoint_disable = isp1760_endpoint_disable, - .get_frame_number = isp1760_get_frame, - .hub_status_data = isp1760_hub_status_data, - .hub_control = isp1760_hub_control, -}; - -int __init init_kmem_once(void) -{ - qtd_cachep = kmem_cache_create("isp1760_qtd", - sizeof(struct isp1760_qtd), 0, SLAB_TEMPORARY | - SLAB_MEM_SPREAD, NULL); - - if (!qtd_cachep) - return -ENOMEM; - - qh_cachep = kmem_cache_create("isp1760_qh", sizeof(struct isp1760_qh), - 0, SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL); - - if (!qh_cachep) { - kmem_cache_destroy(qtd_cachep); - return -ENOMEM; - } - - return 0; -} - -void deinit_kmem_cache(void) -{ - kmem_cache_destroy(qtd_cachep); - kmem_cache_destroy(qh_cachep); -} - -struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, - u64 irqflags, struct device *dev, const char *busname) -{ - struct usb_hcd *hcd; - struct isp1760_hcd *priv; - int ret; - - if (usb_disabled()) - return ERR_PTR(-ENODEV); - - /* prevent usb-core allocating DMA pages */ - dev->dma_mask = NULL; - - hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev->bus_id); - if (!hcd) - return ERR_PTR(-ENOMEM); - - priv = hcd_to_priv(hcd); - init_memory(priv); - hcd->regs = ioremap(res_start, res_len); - if (!hcd->regs) { - ret = -EIO; - goto err_put; - } - - ret = usb_add_hcd(hcd, irq, irqflags); - if (ret) - goto err_unmap; - - hcd->irq = irq; - hcd->rsrc_start = res_start; - hcd->rsrc_len = res_len; - - return hcd; - -err_unmap: - iounmap(hcd->regs); - -err_put: - usb_put_hcd(hcd); - - return ERR_PTR(ret); -} - -MODULE_DESCRIPTION("Driver for the ISP1760 USB-controller from NXP"); -MODULE_AUTHOR("Sebastian Siewior "); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/usb/host/isp1760-hcd.h b/trunk/drivers/usb/host/isp1760-hcd.h deleted file mode 100644 index 3d86d0f6b147..000000000000 --- a/trunk/drivers/usb/host/isp1760-hcd.h +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef _ISP1760_HCD_H_ -#define _ISP1760_HCD_H_ - -/* exports for if */ -struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, - u64 irqflags, struct device *dev, const char *busname); -int init_kmem_once(void); -void deinit_kmem_cache(void); - -/* EHCI capability registers */ -#define HC_CAPLENGTH 0x00 -#define HC_HCSPARAMS 0x04 -#define HC_HCCPARAMS 0x08 - -/* EHCI operational registers */ -#define HC_USBCMD 0x20 -#define HC_USBSTS 0x24 -#define HC_FRINDEX 0x2c -#define HC_CONFIGFLAG 0x60 -#define HC_PORTSC1 0x64 -#define HC_ISO_PTD_DONEMAP_REG 0x130 -#define HC_ISO_PTD_SKIPMAP_REG 0x134 -#define HC_ISO_PTD_LASTPTD_REG 0x138 -#define HC_INT_PTD_DONEMAP_REG 0x140 -#define HC_INT_PTD_SKIPMAP_REG 0x144 -#define HC_INT_PTD_LASTPTD_REG 0x148 -#define HC_ATL_PTD_DONEMAP_REG 0x150 -#define HC_ATL_PTD_SKIPMAP_REG 0x154 -#define HC_ATL_PTD_LASTPTD_REG 0x158 - -/* Configuration Register */ -#define HC_HW_MODE_CTRL 0x300 -#define ALL_ATX_RESET (1 << 31) -#define HW_DATA_BUS_32BIT (1 << 8) -#define HW_DACK_POL_HIGH (1 << 6) -#define HW_DREQ_POL_HIGH (1 << 5) -#define HW_INTR_HIGH_ACT (1 << 2) -#define HW_INTR_EDGE_TRIG (1 << 1) -#define HW_GLOBAL_INTR_EN (1 << 0) - -#define HC_CHIP_ID_REG 0x304 -#define HC_SCRATCH_REG 0x308 - -#define HC_RESET_REG 0x30c -#define SW_RESET_RESET_HC (1 << 1) -#define SW_RESET_RESET_ALL (1 << 0) - -#define HC_BUFFER_STATUS_REG 0x334 -#define ATL_BUFFER 0x1 -#define INT_BUFFER 0x2 -#define ISO_BUFFER 0x4 -#define BUFFER_MAP 0x7 - -#define HC_MEMORY_REG 0x33c -#define HC_PORT1_CTRL 0x374 -#define PORT1_POWER (3 << 3) -#define PORT1_INIT1 (1 << 7) -#define PORT1_INIT2 (1 << 23) - -/* Interrupt Register */ -#define HC_INTERRUPT_REG 0x310 - -#define HC_INTERRUPT_ENABLE 0x314 -#define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) -#define FINAL_HW_CONFIG (HW_GLOBAL_INTR_EN | HW_DATA_BUS_32BIT) - -#define HC_ISO_INT (1 << 9) -#define HC_ATL_INT (1 << 8) -#define HC_INTL_INT (1 << 7) -#define HC_EOT_INT (1 << 3) -#define HC_SOT_INT (1 << 1) - -#define HC_ISO_IRQ_MASK_OR_REG 0x318 -#define HC_INT_IRQ_MASK_OR_REG 0x31C -#define HC_ATL_IRQ_MASK_OR_REG 0x320 -#define HC_ISO_IRQ_MASK_AND_REG 0x324 -#define HC_INT_IRQ_MASK_AND_REG 0x328 -#define HC_ATL_IRQ_MASK_AND_REG 0x32C - -/* Register sets */ -#define HC_BEGIN_OF_ATL 0x0c00 -#define HC_BEGIN_OF_INT 0x0800 -#define HC_BEGIN_OF_ISO 0x0400 -#define HC_BEGIN_OF_PAYLOAD 0x1000 - -/* urb state*/ -#define DELETE_URB (0x0008) -#define NO_TRANSFER_ACTIVE (0xffffffff) - -#define ATL_REGS_OFFSET (0xc00) -#define INT_REGS_OFFSET (0x800) - -/* Philips Transfer Descriptor (PTD) */ -struct ptd { - __le32 dw0; - __le32 dw1; - __le32 dw2; - __le32 dw3; - __le32 dw4; - __le32 dw5; - __le32 dw6; - __le32 dw7; -}; - -struct inter_packet_info { - void *data_buffer; - u32 payload; -#define PTD_FIRE_NEXT (1 << 0) -#define PTD_URB_FINISHED (1 << 1) - struct urb *urb; - struct isp1760_qh *qh; - struct isp1760_qtd *qtd; -}; - - -typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, - struct isp1760_qtd *qtd); - -#define isp1760_info(priv, fmt, args...) \ - dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args) - -#define isp1760_err(priv, fmt, args...) \ - dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args) - -/* chip memory management */ -struct memory_chunk { - unsigned int start; - unsigned int size; - unsigned int free; -}; - -/* - * 60kb divided in: - * - 32 blocks @ 256 bytes - * - 20 blocks @ 1024 bytes - * - 4 blocks @ 8192 bytes - */ - -#define BLOCK_1_NUM 32 -#define BLOCK_2_NUM 20 -#define BLOCK_3_NUM 4 - -#define BLOCK_1_SIZE 256 -#define BLOCK_2_SIZE 1024 -#define BLOCK_3_SIZE 8192 -#define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM) -#define PAYLOAD_SIZE 0xf000 - -/* I saw if some reloads if the pointer was negative */ -#define ISP1760_NULL_POINTER (0x400) - -/* ATL */ -/* DW0 */ -#define PTD_VALID 1 -#define PTD_LENGTH(x) (((u32) x) << 3) -#define PTD_MAXPACKET(x) (((u32) x) << 18) -#define PTD_MULTI(x) (((u32) x) << 29) -#define PTD_ENDPOINT(x) (((u32) x) << 31) -/* DW1 */ -#define PTD_DEVICE_ADDR(x) (((u32) x) << 3) -#define PTD_PID_TOKEN(x) (((u32) x) << 10) -#define PTD_TRANS_BULK ((u32) 2 << 12) -#define PTD_TRANS_INT ((u32) 3 << 12) -#define PTD_TRANS_SPLIT ((u32) 1 << 14) -#define PTD_SE_USB_LOSPEED ((u32) 2 << 16) -#define PTD_PORT_NUM(x) (((u32) x) << 18) -#define PTD_HUB_NUM(x) (((u32) x) << 25) -#define PTD_PING(x) (((u32) x) << 26) -/* DW2 */ -#define PTD_RL_CNT(x) (((u32) x) << 25) -#define PTD_DATA_START_ADDR(x) (((u32) x) << 8) -#define BASE_ADDR 0x1000 -/* DW3 */ -#define PTD_CERR(x) (((u32) x) << 23) -#define PTD_NAC_CNT(x) (((u32) x) << 19) -#define PTD_ACTIVE ((u32) 1 << 31) -#define PTD_DATA_TOGGLE(x) (((u32) x) << 25) - -#define DW3_HALT_BIT (1 << 30) -#define DW3_ERROR_BIT (1 << 28) -#define DW3_QTD_ACTIVE (1 << 31) - -#define INT_UNDERRUN (1 << 2) -#define INT_BABBLE (1 << 1) -#define INT_EXACT (1 << 0) - -#define DW1_GET_PID(x) (((x) >> 10) & 0x3) -#define PTD_XFERRED_LENGTH(x) ((x) & 0x7fff) -#define PTD_XFERRED_LENGTH_LO(x) ((x) & 0x7ff) - -#define SETUP_PID (2) -#define IN_PID (1) -#define OUT_PID (0) -#define GET_QTD_TOKEN_TYPE(x) ((x) & 0x3) - -#define DATA_TOGGLE (1 << 31) -#define GET_DATA_TOGGLE(x) ((x) >> 31) - -/* Errata 1 */ -#define RL_COUNTER (0) -#define NAK_COUNTER (0) -#define ERR_COUNTER (2) - -#define HC_ATL_PL_SIZE (8192) - -#endif diff --git a/trunk/drivers/usb/host/isp1760-if.c b/trunk/drivers/usb/host/isp1760-if.c deleted file mode 100644 index 73fb2a38f1e4..000000000000 --- a/trunk/drivers/usb/host/isp1760-if.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Glue code for the ISP1760 driver and bus - * Currently there is support for - * - OpenFirmware - * - PCI - * - * (c) 2007 Sebastian Siewior - * - */ - -#include -#include - -#include "../core/hcd.h" -#include "isp1760-hcd.h" - -#ifdef CONFIG_USB_ISP1760_OF -#include -#include -#endif - -#ifdef CONFIG_USB_ISP1760_PCI -#include -#endif - -#ifdef CONFIG_USB_ISP1760_OF -static int of_isp1760_probe(struct of_device *dev, - const struct of_device_id *match) -{ - struct usb_hcd *hcd; - struct device_node *dp = dev->node; - struct resource *res; - struct resource memory; - struct of_irq oirq; - int virq; - u64 res_len; - int ret; - - ret = of_address_to_resource(dp, 0, &memory); - if (ret) - return -ENXIO; - - res = request_mem_region(memory.start, memory.end - memory.start + 1, - dev->dev.bus_id); - if (!res) - return -EBUSY; - - res_len = memory.end - memory.start + 1; - - if (of_irq_map_one(dp, 0, &oirq)) { - ret = -ENODEV; - goto release_reg; - } - - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - - hcd = isp1760_register(memory.start, res_len, virq, - IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id); - if (IS_ERR(hcd)) { - ret = PTR_ERR(hcd); - goto release_reg; - } - - dev_set_drvdata(&dev->dev, hcd); - return ret; - -release_reg: - release_mem_region(memory.start, memory.end - memory.start + 1); - return ret; -} - -static int of_isp1760_remove(struct of_device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(&dev->dev); - - dev_set_drvdata(&dev->dev, NULL); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - return 0; -} - -static struct of_device_id of_isp1760_match[] = { - { - .compatible = "nxp,usb-isp1760", - }, - { }, -}; -MODULE_DEVICE_TABLE(of, of_isp1760_match); - -static struct of_platform_driver isp1760_of_driver = { - .name = "nxp-isp1760", - .match_table = of_isp1760_match, - .probe = of_isp1760_probe, - .remove = of_isp1760_remove, -}; -#endif - -#ifdef CONFIG_USB_ISP1760_PCI -static u32 nxp_pci_io_base; -static u32 iolength; -static u32 pci_mem_phy0; -static u32 length; -static u8 *chip_addr; -static u8 *iobase; - -static int __devinit isp1761_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) -{ - u8 latency, limit; - __u32 reg_data; - int retry_count; - int length; - int status = 1; - struct usb_hcd *hcd; - - if (usb_disabled()) - return -ENODEV; - - if (pci_enable_device(dev) < 0) - return -ENODEV; - - if (!dev->irq) - return -ENODEV; - - /* Grab the PLX PCI mem maped port start address we need */ - nxp_pci_io_base = pci_resource_start(dev, 0); - iolength = pci_resource_len(dev, 0); - - if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) { - printk(KERN_ERR "request region #1\n"); - return -EBUSY; - } - - iobase = ioremap_nocache(nxp_pci_io_base, iolength); - if (!iobase) { - printk(KERN_ERR "ioremap #1\n"); - release_mem_region(nxp_pci_io_base, iolength); - return -ENOMEM; - } - /* Grab the PLX PCI shared memory of the ISP 1761 we need */ - pci_mem_phy0 = pci_resource_start(dev, 3); - length = pci_resource_len(dev, 3); - - if (length < 0xffff) { - printk(KERN_ERR "memory length for this resource is less than " - "required\n"); - release_mem_region(nxp_pci_io_base, iolength); - iounmap(iobase); - return -ENOMEM; - } - - if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) { - printk(KERN_ERR "host controller already in use\n"); - release_mem_region(nxp_pci_io_base, iolength); - iounmap(iobase); - return -EBUSY; - } - - /* bad pci latencies can contribute to overruns */ - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency); - if (latency) { - pci_read_config_byte(dev, PCI_MAX_LAT, &limit); - if (limit && limit < latency) - pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit); - } - - /* Try to check whether we can access Scratch Register of - * Host Controller or not. The initial PCI access is retried until - * local init for the PCI bridge is completed - */ - retry_count = 20; - reg_data = 0; - while ((reg_data != 0xFACE) && retry_count) { - /*by default host is in 16bit mode, so - * io operations at this stage must be 16 bit - * */ - writel(0xface, chip_addr + HC_SCRATCH_REG); - udelay(100); - reg_data = readl(chip_addr + HC_SCRATCH_REG); - retry_count--; - } - - /* Host Controller presence is detected by writing to scratch register - * and reading back and checking the contents are same or not - */ - if (reg_data != 0xFACE) { - err("scratch register mismatch %x", reg_data); - goto clean; - } - - pci_set_master(dev); - - status = readl(iobase + 0x68); - status |= 0x900; - writel(status, iobase + 0x68); - - dev->dev.dma_mask = NULL; - hcd = isp1760_register(pci_mem_phy0, length, dev->irq, - IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id); - pci_set_drvdata(dev, hcd); - if (!hcd) - return 0; -clean: - status = -ENODEV; - iounmap(iobase); - release_mem_region(pci_mem_phy0, length); - release_mem_region(nxp_pci_io_base, iolength); - return status; -} -static void isp1761_pci_remove(struct pci_dev *dev) -{ - struct usb_hcd *hcd; - - hcd = pci_get_drvdata(dev); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - - pci_disable_device(dev); - - iounmap(iobase); - iounmap(chip_addr); - - release_mem_region(nxp_pci_io_base, iolength); - release_mem_region(pci_mem_phy0, length); -} - -static void isp1761_pci_shutdown(struct pci_dev *dev) -{ - printk(KERN_ERR "ips1761_pci_shutdown\n"); -} - -static const struct pci_device_id isp1760_plx [] = { { - /* handle any USB 2.0 EHCI controller */ - PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0), - .driver_data = 0, -}, -{ /* end: all zeroes */ } -}; -MODULE_DEVICE_TABLE(pci, isp1760_plx); - -static struct pci_driver isp1761_pci_driver = { - .name = "isp1760", - .id_table = isp1760_plx, - .probe = isp1761_pci_probe, - .remove = isp1761_pci_remove, - .shutdown = isp1761_pci_shutdown, -}; -#endif - -static int __init isp1760_init(void) -{ - int ret; - - init_kmem_once(); - -#ifdef CONFIG_USB_ISP1760_OF - ret = of_register_platform_driver(&isp1760_of_driver); - if (ret) { - deinit_kmem_cache(); - return ret; - } -#endif -#ifdef CONFIG_USB_ISP1760_PCI - ret = pci_register_driver(&isp1761_pci_driver); - if (ret) - goto unreg_of; -#endif - return ret; - -#ifdef CONFIG_USB_ISP1760_PCI -unreg_of: -#endif -#ifdef CONFIG_USB_ISP1760_OF - of_unregister_platform_driver(&isp1760_of_driver); -#endif - deinit_kmem_cache(); - return ret; -} -module_init(isp1760_init); - -static void __exit isp1760_exit(void) -{ -#ifdef CONFIG_USB_ISP1760_OF - of_unregister_platform_driver(&isp1760_of_driver); -#endif -#ifdef CONFIG_USB_ISP1760_PCI - pci_unregister_driver(&isp1761_pci_driver); -#endif - deinit_kmem_cache(); -} -module_exit(isp1760_exit); diff --git a/trunk/drivers/usb/host/ohci-hub.c b/trunk/drivers/usb/host/ohci-hub.c index 79a78029f896..17dc2eccda83 100644 --- a/trunk/drivers/usb/host/ohci-hub.c +++ b/trunk/drivers/usb/host/ohci-hub.c @@ -613,7 +613,7 @@ static void start_hnp(struct ohci_hcd *ohci); static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) { __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; - u32 temp = 0; + u32 temp; u16 now = ohci_readl(ohci, &ohci->regs->fmnumber); u16 reset_done = now + PORT_RESET_MSEC; int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC); diff --git a/trunk/drivers/usb/host/uhci-hcd.c b/trunk/drivers/usb/host/uhci-hcd.c index 3a7bfe7a8874..d3e0d8aa3980 100644 --- a/trunk/drivers/usb/host/uhci-hcd.c +++ b/trunk/drivers/usb/host/uhci-hcd.c @@ -234,7 +234,7 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) return 0; } -static int global_suspend_mode_is_broken(struct uhci_hcd *uhci) +static int remote_wakeup_is_broken(struct uhci_hcd *uhci) { int port; const char *sys_info; @@ -261,60 +261,27 @@ __releases(uhci->lock) __acquires(uhci->lock) { int auto_stop; - int int_enable, egsm_enable, wakeup_enable; + int int_enable, egsm_enable; struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); dev_dbg(&rhdev->dev, "%s%s\n", __func__, (auto_stop ? " (auto-stop)" : "")); - /* Start off by assuming Resume-Detect interrupts and EGSM work - * and that remote wakeups should be enabled. + /* Enable resume-detect interrupts if they work. + * Then enter Global Suspend mode if _it_ works, still configured. */ egsm_enable = USBCMD_EGSM; - uhci->RD_enable = 1; + uhci->working_RD = 1; int_enable = USBINTR_RESUME; - wakeup_enable = 1; - - /* In auto-stop mode wakeups must always be detected, but - * Resume-Detect interrupts may be prohibited. (In the absence - * of CONFIG_PM, they are always disallowed.) - */ - if (auto_stop) { - if (!device_may_wakeup(&rhdev->dev)) - int_enable = 0; - - /* In bus-suspend mode wakeups may be disabled, but if they are - * allowed then so are Resume-Detect interrupts. - */ - } else { + if (remote_wakeup_is_broken(uhci)) + egsm_enable = 0; + if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable || #ifdef CONFIG_PM - if (!rhdev->do_remote_wakeup) - wakeup_enable = 0; + (!auto_stop && !rhdev->do_remote_wakeup) || #endif - } - - /* EGSM causes the root hub to echo a 'K' signal (resume) out any - * port which requests a remote wakeup. According to the USB spec, - * every hub is supposed to do this. But if we are ignoring - * remote-wakeup requests anyway then there's no point to it. - * We also shouldn't enable EGSM if it's broken. - */ - if (!wakeup_enable || global_suspend_mode_is_broken(uhci)) - egsm_enable = 0; - - /* If we're ignoring wakeup events then there's no reason to - * enable Resume-Detect interrupts. We also shouldn't enable - * them if they are broken or disallowed. - * - * This logic may lead us to enabling RD but not EGSM. The UHCI - * spec foolishly says that RD works only when EGSM is on, but - * there's no harm in enabling it anyway -- perhaps some chips - * will implement it! - */ - if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) || - !int_enable) - uhci->RD_enable = int_enable = 0; + (auto_stop && !device_may_wakeup(&rhdev->dev))) + uhci->working_RD = int_enable = 0; outw(int_enable, uhci->io_addr + USBINTR); outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); @@ -341,11 +308,7 @@ __acquires(uhci->lock) uhci->rh_state = new_state; uhci->is_stopped = UHCI_IS_STOPPED; - - /* If interrupts don't work and remote wakeup is enabled then - * the suspended root hub needs to be polled. - */ - uhci_to_hcd(uhci)->poll_rh = (!int_enable && wakeup_enable); + uhci_to_hcd(uhci)->poll_rh = !int_enable; uhci_scan_schedule(uhci); uhci_fsbr_off(uhci); @@ -381,12 +344,9 @@ __acquires(uhci->lock) * for 20 ms. */ if (uhci->rh_state == UHCI_RH_SUSPENDED) { - unsigned egsm; - - /* Keep EGSM on if it was set before */ - egsm = inw(uhci->io_addr + USBCMD) & USBCMD_EGSM; uhci->rh_state = UHCI_RH_RESUMING; - outw(USBCMD_FGR | USBCMD_CF | egsm, uhci->io_addr + USBCMD); + outw(USBCMD_FGR | USBCMD_EGSM | USBCMD_CF, + uhci->io_addr + USBCMD); spin_unlock_irq(&uhci->lock); msleep(20); spin_lock_irq(&uhci->lock); @@ -841,10 +801,8 @@ static int uhci_pci_resume(struct usb_hcd *hcd) spin_unlock_irq(&uhci->lock); - /* If interrupts don't work and remote wakeup is enabled then - * the suspended root hub needs to be polled. - */ - if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) { + if (!uhci->working_RD) { + /* Suspended root hub needs to be polled */ hcd->poll_rh = 1; usb_hcd_poll_rh_status(hcd); } diff --git a/trunk/drivers/usb/host/uhci-hcd.h b/trunk/drivers/usb/host/uhci-hcd.h index 7d01c5677f92..340d6ed3e6e9 100644 --- a/trunk/drivers/usb/host/uhci-hcd.h +++ b/trunk/drivers/usb/host/uhci-hcd.h @@ -400,9 +400,8 @@ struct uhci_hcd { unsigned int scan_in_progress:1; /* Schedule scan is running */ unsigned int need_rescan:1; /* Redo the schedule scan */ unsigned int dead:1; /* Controller has died */ - unsigned int RD_enable:1; /* Suspended root hub with - Resume-Detect interrupts - enabled */ + unsigned int working_RD:1; /* Suspended root hub doesn't + need to be polled */ unsigned int is_initialized:1; /* Data structure is usable */ unsigned int fsbr_is_on:1; /* FSBR is turned on */ unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */ diff --git a/trunk/drivers/usb/misc/ldusb.c b/trunk/drivers/usb/misc/ldusb.c index 7aafd53fbcab..11580e81e2c6 100644 --- a/trunk/drivers/usb/misc/ldusb.c +++ b/trunk/drivers/usb/misc/ldusb.c @@ -148,7 +148,7 @@ MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in /* Structure to hold all of our device specific stuff */ struct ld_usb { - struct mutex mutex; /* locks this structure */ + struct semaphore sem; /* locks this structure */ struct usb_interface* intf; /* save off the usb interface pointer */ int open_count; /* number of times this port has been opened */ @@ -319,7 +319,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) return -ENODEV; /* lock this device */ - if (mutex_lock_interruptible(&dev->mutex)) + if (down_interruptible(&dev->sem)) return -ERESTARTSYS; /* allow opening only once */ @@ -358,7 +358,7 @@ static int ld_usb_open(struct inode *inode, struct file *file) file->private_data = dev; unlock_exit: - mutex_unlock(&dev->mutex); + up(&dev->sem); return retval; } @@ -378,7 +378,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) goto exit; } - if (mutex_lock_interruptible(&dev->mutex)) { + if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } @@ -389,7 +389,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) } if (dev->intf == NULL) { /* the device was unplugged before the file was released */ - mutex_unlock(&dev->mutex); + up(&dev->sem); /* unlock here as ld_usb_delete frees dev */ ld_usb_delete(dev); goto exit; @@ -402,7 +402,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) dev->open_count = 0; unlock_exit: - mutex_unlock(&dev->mutex); + up(&dev->sem); exit: return retval; @@ -448,7 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, goto exit; /* lock this object */ - if (mutex_lock_interruptible(&dev->mutex)) { + if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } @@ -505,7 +505,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, unlock_exit: /* unlock the device */ - mutex_unlock(&dev->mutex); + up(&dev->sem); exit: return retval; @@ -528,7 +528,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, goto exit; /* lock this object */ - if (mutex_lock_interruptible(&dev->mutex)) { + if (down_interruptible(&dev->sem)) { retval = -ERESTARTSYS; goto exit; } @@ -602,7 +602,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, unlock_exit: /* unlock the device */ - mutex_unlock(&dev->mutex); + up(&dev->sem); exit: return retval; @@ -651,7 +651,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * dev_err(&intf->dev, "Out of memory\n"); goto exit; } - mutex_init(&dev->mutex); + init_MUTEX(&dev->sem); spin_lock_init(&dev->rbsl); dev->intf = intf; init_waitqueue_head(&dev->read_wait); @@ -765,15 +765,15 @@ static void ld_usb_disconnect(struct usb_interface *intf) /* give back our minor */ usb_deregister_dev(intf, &ld_usb_class); - mutex_lock(&dev->mutex); + down(&dev->sem); /* if the device is not opened, then we clean up right now */ if (!dev->open_count) { - mutex_unlock(&dev->mutex); + up(&dev->sem); ld_usb_delete(dev); } else { dev->intf = NULL; - mutex_unlock(&dev->mutex); + up(&dev->sem); } dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 742be3c35947..a51983854ca0 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -79,10 +79,30 @@ static struct usb_device *testdev_to_usbdev (struct usbtest_dev *test) /* set up all urbs so they can be used with either bulk or interrupt */ #define INTERRUPT_RATE 1 /* msec/transfer */ -#define ERROR(tdev, fmt, args...) \ - dev_err(&(tdev)->intf->dev , fmt , ## args) -#define WARN(tdev, fmt, args...) \ - dev_warn(&(tdev)->intf->dev , fmt , ## args) +#define xprintk(tdev,level,fmt,args...) \ + dev_printk(level , &(tdev)->intf->dev , fmt , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while (0) +#endif /* DEBUG */ + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(dev,fmt,args...) \ + do { } while (0) +#endif /* VERBOSE */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define WARN(dev,fmt,args...) \ + xprintk(dev , KERN_WARNING , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) /*-------------------------------------------------------------------------*/ @@ -216,7 +236,7 @@ static struct urb *simple_alloc_urb ( static unsigned pattern = 0; module_param (pattern, uint, S_IRUGO); -MODULE_PARM_DESC(pattern, "i/o pattern (0 == zeroes)"); +// MODULE_PARM_DESC (pattern, "i/o pattern (0 == zeroes)"); static inline void simple_fill_buf (struct urb *urb) { @@ -237,7 +257,7 @@ static inline void simple_fill_buf (struct urb *urb) } } -static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) +static inline int simple_check_buf (struct urb *urb) { unsigned i; u8 expected; @@ -265,7 +285,7 @@ static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) } if (*buf == expected) continue; - ERROR(tdev, "buf[%d] = %d (not %d)\n", i, *buf, expected); + dbg ("buf[%d] = %d (not %d)", i, *buf, expected); return -EINVAL; } return 0; @@ -279,7 +299,6 @@ static void simple_free_urb (struct urb *urb) } static int simple_io ( - struct usbtest_dev *tdev, struct urb *urb, int iterations, int vary, @@ -305,7 +324,7 @@ static int simple_io ( retval = urb->status; urb->dev = udev; if (retval == 0 && usb_pipein (urb->pipe)) - retval = simple_check_buf(tdev, urb); + retval = simple_check_buf (urb); if (vary) { int len = urb->transfer_buffer_length; @@ -322,7 +341,7 @@ static int simple_io ( urb->transfer_buffer_length = max; if (expected != retval) - dev_err(&udev->dev, + dev_dbg (&udev->dev, "%s failed, iterations left %d, status %d (not %d)\n", label, iterations, retval, expected); return retval; @@ -338,7 +357,7 @@ static int simple_io ( static void free_sglist (struct scatterlist *sg, int nents) { unsigned i; - + if (!sg) return; for (i = 0; i < nents; i++) { @@ -396,7 +415,7 @@ alloc_sglist (int nents, int max, int vary) } static int perform_sglist ( - struct usbtest_dev *tdev, + struct usb_device *udev, unsigned iterations, int pipe, struct usb_sg_request *req, @@ -404,7 +423,6 @@ static int perform_sglist ( int nents ) { - struct usb_device *udev = testdev_to_usbdev(tdev); int retval = 0; while (retval == 0 && iterations-- > 0) { @@ -413,7 +431,7 @@ static int perform_sglist ( ? (INTERRUPT_RATE << 3) : INTERRUPT_RATE, sg, nents, 0, GFP_KERNEL); - + if (retval) break; usb_sg_wait (req); @@ -428,8 +446,7 @@ static int perform_sglist ( // failure if retval is as we expected ... if (retval) - ERROR(tdev, "perform_sglist failed, " - "iterations left %d, status %d\n", + dbg ("perform_sglist failed, iterations left %d, status %d", iterations, retval); return retval; } @@ -488,28 +505,28 @@ static int set_altsetting (struct usbtest_dev *dev, int alternate) alternate); } -static int is_good_config(struct usbtest_dev *tdev, int len) +static int is_good_config (char *buf, int len) { struct usb_config_descriptor *config; - + if (len < sizeof *config) return 0; - config = (struct usb_config_descriptor *) tdev->buf; + config = (struct usb_config_descriptor *) buf; switch (config->bDescriptorType) { case USB_DT_CONFIG: case USB_DT_OTHER_SPEED_CONFIG: if (config->bLength != 9) { - ERROR(tdev, "bogus config descriptor length\n"); + dbg ("bogus config descriptor length"); return 0; } /* this bit 'must be 1' but often isn't */ if (!realworld && !(config->bmAttributes & 0x80)) { - ERROR(tdev, "high bit of config attributes not set\n"); + dbg ("high bit of config attributes not set"); return 0; } if (config->bmAttributes & 0x1f) { /* reserved == 0 */ - ERROR(tdev, "reserved config bits set\n"); + dbg ("reserved config bits set"); return 0; } break; @@ -521,7 +538,7 @@ static int is_good_config(struct usbtest_dev *tdev, int len) return 1; if (le16_to_cpu(config->wTotalLength) >= TBUF_SIZE) /* max partial read */ return 1; - ERROR(tdev, "bogus config descriptor read size\n"); + dbg ("bogus config descriptor read size"); return 0; } @@ -554,7 +571,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* 9.2.3 constrains the range here */ alt = iface->altsetting [i].desc.bAlternateSetting; if (alt < 0 || alt >= iface->num_altsetting) { - dev_err(&iface->dev, + dev_dbg (&iface->dev, "invalid alt [%d].bAltSetting = %d\n", i, alt); } @@ -566,7 +583,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [9.4.10] set_interface */ retval = set_altsetting (dev, alt); if (retval) { - dev_err(&iface->dev, "can't set_interface = %d, %d\n", + dev_dbg (&iface->dev, "can't set_interface = %d, %d\n", alt, retval); return retval; } @@ -574,7 +591,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [9.4.4] get_interface always works */ retval = get_altsetting (dev); if (retval != alt) { - dev_err(&iface->dev, "get alt should be %d, was %d\n", + dev_dbg (&iface->dev, "get alt should be %d, was %d\n", alt, retval); return (retval < 0) ? retval : -EDOM; } @@ -594,7 +611,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) USB_DIR_IN | USB_RECIP_DEVICE, 0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT); if (retval != 1 || dev->buf [0] != expected) { - dev_err(&iface->dev, "get config --> %d %d (1 %d)\n", + dev_dbg (&iface->dev, "get config --> %d %d (1 %d)\n", retval, dev->buf[0], expected); return (retval < 0) ? retval : -EDOM; } @@ -604,7 +621,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) retval = usb_get_descriptor (udev, USB_DT_DEVICE, 0, dev->buf, sizeof udev->descriptor); if (retval != sizeof udev->descriptor) { - dev_err(&iface->dev, "dev descriptor --> %d\n", retval); + dev_dbg (&iface->dev, "dev descriptor --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } @@ -612,8 +629,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { retval = usb_get_descriptor (udev, USB_DT_CONFIG, i, dev->buf, TBUF_SIZE); - if (!is_good_config(dev, retval)) { - dev_err(&iface->dev, + if (!is_good_config (dev->buf, retval)) { + dev_dbg (&iface->dev, "config [%d] descriptor --> %d\n", i, retval); return (retval < 0) ? retval : -EDOM; @@ -633,14 +650,14 @@ static int ch9_postconfig (struct usbtest_dev *dev) sizeof (struct usb_qualifier_descriptor)); if (retval == -EPIPE) { if (udev->speed == USB_SPEED_HIGH) { - dev_err(&iface->dev, + dev_dbg (&iface->dev, "hs dev qualifier --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } /* usb2.0 but not high-speed capable; fine */ } else if (retval != sizeof (struct usb_qualifier_descriptor)) { - dev_err(&iface->dev, "dev qualifier --> %d\n", retval); + dev_dbg (&iface->dev, "dev qualifier --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } else d = (struct usb_qualifier_descriptor *) dev->buf; @@ -652,8 +669,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) retval = usb_get_descriptor (udev, USB_DT_OTHER_SPEED_CONFIG, i, dev->buf, TBUF_SIZE); - if (!is_good_config(dev, retval)) { - dev_err(&iface->dev, + if (!is_good_config (dev->buf, retval)) { + dev_dbg (&iface->dev, "other speed config --> %d\n", retval); return (retval < 0) ? retval : -EDOM; @@ -666,7 +683,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) /* [9.4.5] get_status always works */ retval = usb_get_status (udev, USB_RECIP_DEVICE, 0, dev->buf); if (retval != 2) { - dev_err(&iface->dev, "get dev status --> %d\n", retval); + dev_dbg (&iface->dev, "get dev status --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } @@ -676,11 +693,11 @@ static int ch9_postconfig (struct usbtest_dev *dev) retval = usb_get_status (udev, USB_RECIP_INTERFACE, iface->altsetting [0].desc.bInterfaceNumber, dev->buf); if (retval != 2) { - dev_err(&iface->dev, "get interface status --> %d\n", retval); + dev_dbg (&iface->dev, "get interface status --> %d\n", retval); return (retval < 0) ? retval : -EDOM; } // FIXME get status for each endpoint in the interface - + return 0; } @@ -735,9 +752,8 @@ static void ctrl_complete (struct urb *urb) */ if (subcase->number > 0) { if ((subcase->number - ctx->last) != 1) { - ERROR(ctx->dev, - "subcase %d completed out of order, last %d\n", - subcase->number, ctx->last); + dbg ("subcase %d completed out of order, last %d", + subcase->number, ctx->last); status = -EDOM; ctx->last = subcase->number; goto error; @@ -761,7 +777,7 @@ static void ctrl_complete (struct urb *urb) else if (subcase->number == 12 && status == -EPIPE) status = 0; else - ERROR(ctx->dev, "subtest %d error, status %d\n", + dbg ("subtest %d error, status %d", subcase->number, status); } @@ -772,12 +788,9 @@ static void ctrl_complete (struct urb *urb) int i; ctx->status = status; - ERROR(ctx->dev, "control queue %02x.%02x, err %d, " - "%d left, subcase %d, len %d/%d\n", + info ("control queue %02x.%02x, err %d, %d left", reqp->bRequestType, reqp->bRequest, - status, ctx->count, subcase->number, - urb->actual_length, - urb->transfer_buffer_length); + status, ctx->count); /* FIXME this "unlink everything" exit route should * be a separate test case. @@ -786,8 +799,7 @@ static void ctrl_complete (struct urb *urb) /* unlink whatever's still pending */ for (i = 1; i < ctx->param->sglen; i++) { struct urb *u = ctx->urb [ - (i + subcase->number) - % ctx->param->sglen]; + (i + subcase->number) % ctx->param->sglen]; if (u == urb || !u->dev) continue; @@ -800,8 +812,7 @@ static void ctrl_complete (struct urb *urb) case -EIDRM: continue; default: - ERROR(ctx->dev, "urb unlink --> %d\n", - status); + dbg ("urb unlink --> %d", status); } } status = ctx->status; @@ -811,15 +822,14 @@ static void ctrl_complete (struct urb *urb) /* resubmit if we need to, else mark this as done */ if ((status == 0) && (ctx->pending < ctx->count)) { if ((status = usb_submit_urb (urb, GFP_ATOMIC)) != 0) { - ERROR(ctx->dev, - "can't resubmit ctrl %02x.%02x, err %d\n", + dbg ("can't resubmit ctrl %02x.%02x, err %d", reqp->bRequestType, reqp->bRequest, status); urb->dev = NULL; } else ctx->pending++; } else urb->dev = NULL; - + /* signal completion when nothing's queued */ if (ctx->pending == 0) complete (&ctx->complete); @@ -908,11 +918,11 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) req.wValue = cpu_to_le16 (USB_DT_INTERFACE << 8); // interface == 0 len = sizeof (struct usb_interface_descriptor); - expected = -EPIPE; + expected = EPIPE; break; // NOTE: two consecutive stalls in the queue here. // that tests fault recovery a bit more aggressively. - case 8: // clear endpoint halt (MAY STALL) + case 8: // clear endpoint halt (USUALLY STALLS) req.bRequest = USB_REQ_CLEAR_FEATURE; req.bRequestType = USB_RECIP_ENDPOINT; // wValue 0 == ep halt @@ -955,7 +965,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) break; case 14: // short read; try to fill the last packet req.wValue = cpu_to_le16 ((USB_DT_DEVICE << 8) | 0); - /* device descriptor size == 18 bytes */ + // device descriptor size == 18 bytes len = udev->descriptor.bMaxPacketSize0; switch (len) { case 8: len = 24; break; @@ -964,7 +974,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) expected = -EREMOTEIO; break; default: - ERROR(dev, "bogus number of ctrl queue testcases!\n"); + err ("bogus number of ctrl queue testcases!"); context.status = -EINVAL; goto cleanup; } @@ -993,7 +1003,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) for (i = 0; i < param->sglen; i++) { context.status = usb_submit_urb (urb [i], GFP_ATOMIC); if (context.status != 0) { - ERROR(dev, "can't submit urb[%d], status %d\n", + dbg ("can't submit urb[%d], status %d", i, context.status); context.count = context.pending; break; @@ -1060,7 +1070,7 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) * due to errors, or is just NAKing requests. */ if ((retval = usb_submit_urb (urb, GFP_KERNEL)) != 0) { - dev_err(&dev->intf->dev, "submit fail %d\n", retval); + dev_dbg (&dev->intf->dev, "submit fail %d\n", retval); return retval; } @@ -1077,13 +1087,13 @@ static int unlink1 (struct usbtest_dev *dev, int pipe, int size, int async) * "normal" drivers would prevent resubmission, but * since we're testing unlink paths, we can't. */ - ERROR(dev, "unlink retry\n"); + dev_dbg (&dev->intf->dev, "unlink retry\n"); goto retry; } } else usb_kill_urb (urb); if (!(retval == 0 || retval == -EINPROGRESS)) { - dev_err(&dev->intf->dev, "unlink fail %d\n", retval); + dev_dbg (&dev->intf->dev, "unlink fail %d\n", retval); return retval; } @@ -1111,7 +1121,7 @@ static int unlink_simple (struct usbtest_dev *dev, int pipe, int len) /*-------------------------------------------------------------------------*/ -static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) +static int verify_not_halted (int ep, struct urb *urb) { int retval; u16 status; @@ -1119,21 +1129,20 @@ static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) /* shouldn't look or act halted */ retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't get no-halt status, %d\n", - ep, retval); + dbg ("ep %02x couldn't get no-halt status, %d", ep, retval); return retval; } if (status != 0) { - ERROR(tdev, "ep %02x bogus status: %04x != 0\n", ep, status); + dbg ("ep %02x bogus status: %04x != 0", ep, status); return -EINVAL; } - retval = simple_io(tdev, urb, 1, 0, 0, __func__); + retval = simple_io (urb, 1, 0, 0, __func__); if (retval != 0) return -EINVAL; return 0; } -static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) +static int verify_halted (int ep, struct urb *urb) { int retval; u16 status; @@ -1141,30 +1150,29 @@ static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb) /* should look and act halted */ retval = usb_get_status (urb->dev, USB_RECIP_ENDPOINT, ep, &status); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't get halt status, %d\n", - ep, retval); + dbg ("ep %02x couldn't get halt status, %d", ep, retval); return retval; } le16_to_cpus(&status); if (status != 1) { - ERROR(tdev, "ep %02x bogus status: %04x != 1\n", ep, status); + dbg ("ep %02x bogus status: %04x != 1", ep, status); return -EINVAL; } - retval = simple_io(tdev, urb, 1, 0, -EPIPE, __func__); + retval = simple_io (urb, 1, 0, -EPIPE, __func__); if (retval != -EPIPE) return -EINVAL; - retval = simple_io(tdev, urb, 1, 0, -EPIPE, "verify_still_halted"); + retval = simple_io (urb, 1, 0, -EPIPE, "verify_still_halted"); if (retval != -EPIPE) return -EINVAL; return 0; } -static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb) +static int test_halt (int ep, struct urb *urb) { int retval; /* shouldn't look or act halted now */ - retval = verify_not_halted(tdev, ep, urb); + retval = verify_not_halted (ep, urb); if (retval < 0) return retval; @@ -1174,20 +1182,20 @@ static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb) USB_ENDPOINT_HALT, ep, NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't set halt, %d\n", ep, retval); + dbg ("ep %02x couldn't set halt, %d", ep, retval); return retval; } - retval = verify_halted(tdev, ep, urb); + retval = verify_halted (ep, urb); if (retval < 0) return retval; /* clear halt (tests API + protocol), verify it worked */ retval = usb_clear_halt (urb->dev, urb->pipe); if (retval < 0) { - ERROR(tdev, "ep %02x couldn't clear halt, %d\n", ep, retval); + dbg ("ep %02x couldn't clear halt, %d", ep, retval); return retval; } - retval = verify_not_halted(tdev, ep, urb); + retval = verify_not_halted (ep, urb); if (retval < 0) return retval; @@ -1209,7 +1217,7 @@ static int halt_simple (struct usbtest_dev *dev) if (dev->in_pipe) { ep = usb_pipeendpoint (dev->in_pipe) | USB_DIR_IN; urb->pipe = dev->in_pipe; - retval = test_halt(dev, ep, urb); + retval = test_halt (ep, urb); if (retval < 0) goto done; } @@ -1217,7 +1225,7 @@ static int halt_simple (struct usbtest_dev *dev) if (dev->out_pipe) { ep = usb_pipeendpoint (dev->out_pipe); urb->pipe = dev->out_pipe; - retval = test_halt(dev, ep, urb); + retval = test_halt (ep, urb); } done: simple_free_urb (urb); @@ -1267,7 +1275,7 @@ static int ctrl_out (struct usbtest_dev *dev, if (retval != len) { what = "write"; if (retval >= 0) { - ERROR(dev, "ctrl_out, wlen %d (expected %d)\n", + INFO(dev, "ctrl_out, wlen %d (expected %d)\n", retval, len); retval = -EBADMSG; } @@ -1281,7 +1289,7 @@ static int ctrl_out (struct usbtest_dev *dev, if (retval != len) { what = "read"; if (retval >= 0) { - ERROR(dev, "ctrl_out, rlen %d (expected %d)\n", + INFO(dev, "ctrl_out, rlen %d (expected %d)\n", retval, len); retval = -EBADMSG; } @@ -1291,7 +1299,7 @@ static int ctrl_out (struct usbtest_dev *dev, /* fail if we can't verify */ for (j = 0; j < len; j++) { if (buf [j] != (u8) (i + j)) { - ERROR(dev, "ctrl_out, byte %d is %d not %d\n", + INFO (dev, "ctrl_out, byte %d is %d not %d\n", j, buf [j], (u8) i + j); retval = -EBADMSG; break; @@ -1313,7 +1321,7 @@ static int ctrl_out (struct usbtest_dev *dev, } if (retval < 0) - ERROR (dev, "ctrl_out %s failed, code %d, count %d\n", + INFO (dev, "ctrl_out %s failed, code %d, count %d\n", what, retval, i); kfree (buf); @@ -1358,7 +1366,7 @@ static void iso_callback (struct urb *urb) case 0: goto done; default: - dev_err(&ctx->dev->intf->dev, + dev_dbg (&ctx->dev->intf->dev, "iso resubmit err %d\n", status); /* FALLTHROUGH */ @@ -1373,7 +1381,7 @@ static void iso_callback (struct urb *urb) ctx->pending--; if (ctx->pending == 0) { if (ctx->errors) - dev_err(&ctx->dev->intf->dev, + dev_dbg (&ctx->dev->intf->dev, "iso test, %lu errors out of %lu\n", ctx->errors, ctx->packet_count); complete (&ctx->done); @@ -1450,7 +1458,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, memset (urbs, 0, sizeof urbs); udev = testdev_to_usbdev (dev); - dev_info(&dev->intf->dev, + dev_dbg (&dev->intf->dev, "... iso period %d %sframes, wMaxPacket %04x\n", 1 << (desc->bInterval - 1), (udev->speed == USB_SPEED_HIGH) ? "micro" : "", @@ -1467,7 +1475,7 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, urbs [i]->context = &context; } packets *= param->iterations; - dev_info(&dev->intf->dev, + dev_dbg (&dev->intf->dev, "... total %lu msec (%lu packets)\n", (packets * (1 << (desc->bInterval - 1))) / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), @@ -1529,13 +1537,6 @@ test_iso_queue (struct usbtest_dev *dev, struct usbtest_param *param, * except indirectly by consuming USB bandwidth and CPU resources for test * threads and request completion. But the only way to know that for sure * is to test when HC queues are in use by many devices. - * - * WARNING: Because usbfs grabs udev->dev.sem before calling this ioctl(), - * it locks out usbcore in certain code paths. Notably, if you disconnect - * the device-under-test, khubd will wait block forever waiting for the - * ioctl to complete ... so that usb_disconnect() can abort the pending - * urbs and then call usbtest_disconnect(). To abort a test, you're best - * off just killing the userspace task and waiting for it to exit. */ static int @@ -1574,7 +1575,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) * altsettings; force a default so most tests don't need to check. */ if (dev->info->alt >= 0) { - int res; + int res; if (intf->altsetting->desc.bInterfaceNumber) { mutex_unlock(&dev->lock); @@ -1603,7 +1604,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) switch (param->test_num) { case 0: - dev_info(&intf->dev, "TEST 0: NOP\n"); + dev_dbg (&intf->dev, "TEST 0: NOP\n"); retval = 0; break; @@ -1611,7 +1612,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 1: if (dev->out_pipe == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 1: write %d bytes %u times\n", param->length, param->iterations); urb = simple_alloc_urb (udev, dev->out_pipe, param->length); @@ -1620,13 +1621,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = simple_io(dev, urb, param->iterations, 0, 0, "test1"); + retval = simple_io (urb, param->iterations, 0, 0, "test1"); simple_free_urb (urb); break; case 2: if (dev->in_pipe == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 2: read %d bytes %u times\n", param->length, param->iterations); urb = simple_alloc_urb (udev, dev->in_pipe, param->length); @@ -1635,13 +1636,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = simple_io(dev, urb, param->iterations, 0, 0, "test2"); + retval = simple_io (urb, param->iterations, 0, 0, "test2"); simple_free_urb (urb); break; case 3: if (dev->out_pipe == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 3: write/%d 0..%d bytes %u times\n", param->vary, param->length, param->iterations); urb = simple_alloc_urb (udev, dev->out_pipe, param->length); @@ -1650,14 +1651,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = simple_io(dev, urb, param->iterations, param->vary, + retval = simple_io (urb, param->iterations, param->vary, 0, "test3"); simple_free_urb (urb); break; case 4: if (dev->in_pipe == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 4: read/%d 0..%d bytes %u times\n", param->vary, param->length, param->iterations); urb = simple_alloc_urb (udev, dev->in_pipe, param->length); @@ -1666,7 +1667,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = simple_io(dev, urb, param->iterations, param->vary, + retval = simple_io (urb, param->iterations, param->vary, 0, "test4"); simple_free_urb (urb); break; @@ -1675,7 +1676,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 5: if (dev->out_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 5: write %d sglists %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1685,7 +1686,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = perform_sglist(dev, param->iterations, dev->out_pipe, + retval = perform_sglist (udev, param->iterations, dev->out_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; @@ -1693,7 +1694,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 6: if (dev->in_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 6: read %d sglists %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1703,14 +1704,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = perform_sglist(dev, param->iterations, dev->in_pipe, + retval = perform_sglist (udev, param->iterations, dev->in_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; case 7: if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 7: write/%d %d sglists %d entries 0..%d bytes\n", param->vary, param->iterations, param->sglen, param->length); @@ -1720,14 +1721,14 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk sink (maybe accepts short writes) - retval = perform_sglist(dev, param->iterations, dev->out_pipe, + retval = perform_sglist (udev, param->iterations, dev->out_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; case 8: if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 8: read/%d %d sglists %d entries 0..%d bytes\n", param->vary, param->iterations, param->sglen, param->length); @@ -1737,7 +1738,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) break; } // FIRMWARE: bulk source (maybe generates short writes) - retval = perform_sglist(dev, param->iterations, dev->in_pipe, + retval = perform_sglist (udev, param->iterations, dev->in_pipe, &req, sg, param->sglen); free_sglist (sg, param->sglen); break; @@ -1745,14 +1746,13 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) /* non-queued sanity tests for control (chapter 9 subset) */ case 9: retval = 0; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 9: ch9 (subset) control tests, %d times\n", param->iterations); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = ch9_postconfig (dev); if (retval) - dev_err(&intf->dev, "ch9 subset failed, " - "iterations left %d\n", i); + dbg ("ch9 subset failed, iterations left %d", i); break; /* queued control messaging */ @@ -1760,7 +1760,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (param->sglen == 0) break; retval = 0; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 10: queue %d control calls, %d times\n", param->sglen, param->iterations); @@ -1772,26 +1772,26 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (dev->in_pipe == 0 || !param->length) break; retval = 0; - dev_info(&intf->dev, "TEST 11: unlink %d reads of %d\n", + dev_dbg (&intf->dev, "TEST 11: unlink %d reads of %d\n", param->iterations, param->length); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = unlink_simple (dev, dev->in_pipe, param->length); if (retval) - dev_err(&intf->dev, "unlink reads failed %d, " + dev_dbg (&intf->dev, "unlink reads failed %d, " "iterations left %d\n", retval, i); break; case 12: if (dev->out_pipe == 0 || !param->length) break; retval = 0; - dev_info(&intf->dev, "TEST 12: unlink %d writes of %d\n", + dev_dbg (&intf->dev, "TEST 12: unlink %d writes of %d\n", param->iterations, param->length); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = unlink_simple (dev, dev->out_pipe, param->length); if (retval) - dev_err(&intf->dev, "unlink writes failed %d, " + dev_dbg (&intf->dev, "unlink writes failed %d, " "iterations left %d\n", retval, i); break; @@ -1800,24 +1800,24 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) if (dev->out_pipe == 0 && dev->in_pipe == 0) break; retval = 0; - dev_info(&intf->dev, "TEST 13: set/clear %d halts\n", + dev_dbg (&intf->dev, "TEST 13: set/clear %d halts\n", param->iterations); for (i = param->iterations; retval == 0 && i--; /* NOP */) retval = halt_simple (dev); - + if (retval) - ERROR(dev, "halts failed, iterations left %d\n", i); + DBG (dev, "halts failed, iterations left %d\n", i); break; /* control write tests */ case 14: if (!dev->info->ctrl_out) break; - dev_info(&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", + dev_dbg (&intf->dev, "TEST 14: %d ep0out, %d..%d vary %d\n", param->iterations, realworld ? 1 : 0, param->length, param->vary); - retval = ctrl_out(dev, param->iterations, + retval = ctrl_out (dev, param->iterations, param->length, param->vary); break; @@ -1825,7 +1825,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 15: if (dev->out_iso_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 15: write %d iso, %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1838,7 +1838,7 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf) case 16: if (dev->in_iso_pipe == 0 || param->sglen == 0) break; - dev_info(&intf->dev, + dev_dbg (&intf->dev, "TEST 16: read %d iso, %d entries of %d bytes\n", param->iterations, param->sglen, param->length); @@ -1898,8 +1898,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) return -ENODEV; if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product) return -ENODEV; - dev_info(&intf->dev, "matched module params, " - "vend=0x%04x prod=0x%04x\n", + dbg ("matched module params, vend=0x%04x prod=0x%04x", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); } @@ -1941,8 +1940,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) status = get_endpoints (dev, intf); if (status < 0) { - WARN(dev, "couldn't get endpoints, %d\n", - status); + dbg ("couldn't get endpoints, %d\n", status); return status; } /* may find bulk or ISO pipes */ @@ -2084,9 +2082,21 @@ static struct usbtest_info generic_info = { }; #endif +// FIXME remove this +static struct usbtest_info hact_info = { + .name = "FX2/hact", + //.ep_in = 6, + .ep_out = 2, + .alt = -1, +}; + static struct usb_device_id id_table [] = { + { USB_DEVICE (0x0547, 0x1002), + .driver_info = (unsigned long) &hact_info, + }, + /*-------------------------------------------------------------*/ /* EZ-USB devices which download firmware to replace (or in our @@ -2175,7 +2185,7 @@ static int __init usbtest_init (void) { #ifdef GENERIC if (vendor) - pr_debug("params: vend=0x%04x prod=0x%04x\n", vendor, product); + dbg ("params: vend=0x%04x prod=0x%04x", vendor, product); #endif return usb_register (&usbtest_driver); } diff --git a/trunk/drivers/usb/serial/aircable.c b/trunk/drivers/usb/serial/aircable.c index db6f97a93c02..9b1bb347dc2d 100644 --- a/trunk/drivers/usb/serial/aircable.c +++ b/trunk/drivers/usb/serial/aircable.c @@ -147,7 +147,7 @@ static void serial_buf_free(struct circ_buf *cb) */ static int serial_buf_data_avail(struct circ_buf *cb) { - return CIRC_CNT(cb->head, cb->tail, AIRCABLE_BUF_SIZE); + return CIRC_CNT(cb->head,cb->tail,AIRCABLE_BUF_SIZE); } /* @@ -171,7 +171,7 @@ static int serial_buf_put(struct circ_buf *cb, const char *buf, int count) cb->head = (cb->head + c) & (AIRCABLE_BUF_SIZE-1); buf += c; count -= c; - ret = c; + ret= c; } return ret; } @@ -197,7 +197,7 @@ static int serial_buf_get(struct circ_buf *cb, char *buf, int count) cb->tail = (cb->tail + c) & (AIRCABLE_BUF_SIZE-1); buf += c; count -= c; - ret = c; + ret= c; } return ret; } @@ -208,7 +208,7 @@ static void aircable_send(struct usb_serial_port *port) { int count, result; struct aircable_private *priv = usb_get_serial_port_data(port); - unsigned char *buf; + unsigned char* buf; __le16 *dbuf; dbg("%s - port %d", __func__, port->number); if (port->write_urb_busy) @@ -229,8 +229,7 @@ static void aircable_send(struct usb_serial_port *port) buf[1] = TX_HEADER_1; dbuf = (__le16 *)&buf[2]; *dbuf = cpu_to_le16((u16)count); - serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH, - MAX_HCI_FRAMESIZE); + serial_buf_get(priv->tx_buf,buf + HCI_HEADER_LENGTH, MAX_HCI_FRAMESIZE); memcpy(port->write_urb->transfer_buffer, buf, count + HCI_HEADER_LENGTH); @@ -262,7 +261,7 @@ static void aircable_read(struct work_struct *work) struct tty_struct *tty; unsigned char *data; int count; - if (priv->rx_flags & THROTTLED) { + if (priv->rx_flags & THROTTLED){ if (priv->rx_flags & ACTUALLY_THROTTLED) schedule_work(&priv->rx_work); return; @@ -283,10 +282,10 @@ static void aircable_read(struct work_struct *work) count = min(64, serial_buf_data_avail(priv->rx_buf)); if (count <= 0) - return; /* We have finished sending everything. */ + return; //We have finished sending everything. tty_prepare_flip_string(tty, &data, count); - if (!data) { + if (!data){ err("%s- kzalloc(%d) failed.", __func__, count); return; } @@ -305,10 +304,9 @@ static void aircable_read(struct work_struct *work) static int aircable_probe(struct usb_serial *serial, const struct usb_device_id *id) { - struct usb_host_interface *iface_desc = serial->interface-> - cur_altsetting; + struct usb_host_interface *iface_desc = serial->interface->cur_altsetting; struct usb_endpoint_descriptor *endpoint; - int num_bulk_out = 0; + int num_bulk_out=0; int i; for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { @@ -327,13 +325,13 @@ static int aircable_probe(struct usb_serial *serial, return 0; } -static int aircable_attach(struct usb_serial *serial) +static int aircable_attach (struct usb_serial *serial) { struct usb_serial_port *port = serial->port[0]; struct aircable_private *priv; priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL); - if (!priv) { + if (!priv){ err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct aircable_private)); return -ENOMEM; @@ -394,7 +392,7 @@ static int aircable_write(struct usb_serial_port *port, usb_serial_debug_data(debug, &port->dev, __func__, count, source); - if (!count) { + if (!count){ dbg("%s - write request of 0 bytes", __func__); return count; } @@ -420,31 +418,31 @@ static void aircable_write_bulk_callback(struct urb *urb) /* This has been taken from cypress_m8.c cypress_write_int_callback */ switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", - __func__, status); - port->write_urb_busy = 0; - return; - default: - /* error in the urb, so we have to resubmit it */ - dbg("%s - Overflow in write", __func__); - dbg("%s - nonzero write bulk status received: %d", - __func__, status); - port->write_urb->transfer_buffer_length = 1; - port->write_urb->dev = port->serial->dev; - result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - failed resubmitting write urb, error %d\n", - __func__, result); - else + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __func__, status); + port->write_urb_busy = 0; return; + default: + /* error in the urb, so we have to resubmit it */ + dbg("%s - Overflow in write", __func__); + dbg("%s - nonzero write bulk status received: %d", + __func__, status); + port->write_urb->transfer_buffer_length = 1; + port->write_urb->dev = port->serial->dev; + result = usb_submit_urb(port->write_urb, GFP_ATOMIC); + if (result) + dev_err(&urb->dev->dev, + "%s - failed resubmitting write urb, error %d\n", + __func__, result); + else + return; } port->write_urb_busy = 0; @@ -474,11 +472,11 @@ static void aircable_read_bulk_callback(struct urb *urb) dbg("%s - caught -EPROTO, resubmitting the urb", __func__); usb_fill_bulk_urb(port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, - port->read_urb->transfer_buffer_length, - aircable_read_bulk_callback, port); + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + aircable_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) @@ -492,7 +490,7 @@ static void aircable_read_bulk_callback(struct urb *urb) } usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, urb->transfer_buffer); + urb->actual_length,urb->transfer_buffer); tty = port->tty; if (tty && urb->actual_length) { @@ -509,9 +507,9 @@ static void aircable_read_bulk_callback(struct urb *urb) no_packages = urb->actual_length / (HCI_COMPLETE_FRAME); if (urb->actual_length % HCI_COMPLETE_FRAME != 0) - no_packages++; + no_packages+=1; - for (i = 0; i < no_packages; i++) { + for (i = 0; i < no_packages ;i++) { if (remaining > (HCI_COMPLETE_FRAME)) package_length = HCI_COMPLETE_FRAME; else @@ -531,7 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb) if (port->open_count) { usb_fill_bulk_urb(port->read_urb, port->serial->dev, usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), + port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, aircable_read_bulk_callback, port); @@ -604,7 +602,7 @@ static struct usb_serial_driver aircable_device = { .unthrottle = aircable_unthrottle, }; -static int __init aircable_init(void) +static int __init aircable_init (void) { int retval; retval = usb_serial_register(&aircable_device); @@ -621,7 +619,7 @@ static int __init aircable_init(void) return retval; } -static void __exit aircable_exit(void) +static void __exit aircable_exit (void) { usb_deregister(&aircable_driver); usb_serial_deregister(&aircable_device); diff --git a/trunk/drivers/usb/serial/airprime.c b/trunk/drivers/usb/serial/airprime.c index 0798c14ce787..725b6b94c274 100644 --- a/trunk/drivers/usb/serial/airprime.c +++ b/trunk/drivers/usb/serial/airprime.c @@ -68,9 +68,8 @@ static int airprime_send_setup(struct usb_serial_port *port) val |= 0x02; return usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), - 0x22, 0x21, val, 0, NULL, 0, - USB_CTRL_SET_TIMEOUT); + usb_rcvctrlpipe(serial->dev, 0), + 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); } return 0; @@ -91,19 +90,17 @@ static void airprime_read_bulk_callback(struct urb *urb) __func__, status); return; } - usb_serial_debug_data(debug, &port->dev, __func__, - urb->actual_length, data); + usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data); tty = port->tty; if (tty && urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); + tty_insert_flip_string (tty, data, urb->actual_length); + tty_flip_buffer_push (tty); } - result = usb_submit_urb(urb, GFP_ATOMIC); + result = usb_submit_urb (urb, GFP_ATOMIC); if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); return; } @@ -118,7 +115,7 @@ static void airprime_write_bulk_callback(struct urb *urb) dbg("%s - port %d", __func__, port->number); /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree(urb->transfer_buffer); + kfree (urb->transfer_buffer); if (status) dbg("%s - nonzero write bulk status received: %d", @@ -174,7 +171,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) } usb_fill_bulk_urb(urb, serial->dev, usb_rcvbulkpipe(serial->dev, - port->bulk_out_endpointAddress), + port->bulk_out_endpointAddress), buffer, buffer_size, airprime_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_KERNEL); @@ -186,8 +183,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) __func__, i, port->number, result); goto errout; } - /* remember this urb so we can kill it when the - port is closed */ + /* remember this urb so we can kill it when the port is closed */ priv->read_urbp[i] = urb; } @@ -196,22 +192,22 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) goto out; errout: - /* some error happened, cancel any submitted urbs and clean up - anything that got allocated successfully */ + /* some error happened, cancel any submitted urbs and clean up anything that + got allocated successfully */ while (i-- != 0) { urb = priv->read_urbp[i]; buffer = urb->transfer_buffer; - usb_kill_urb(urb); - usb_free_urb(urb); - kfree(buffer); + usb_kill_urb (urb); + usb_free_urb (urb); + kfree (buffer); } out: return result; } -static void airprime_close(struct usb_serial_port *port, struct file *filp) +static void airprime_close(struct usb_serial_port *port, struct file * filp) { struct airprime_private *priv = usb_get_serial_port_data(port); int i; @@ -224,16 +220,16 @@ static void airprime_close(struct usb_serial_port *port, struct file *filp) mutex_lock(&port->serial->disc_mutex); if (!port->serial->disconnected) airprime_send_setup(port); - mutex_unlock(&port->serial->disc_mutex); + mutex_lock(&port->serial->disc_mutex); for (i = 0; i < NUM_READ_URBS; ++i) { - usb_kill_urb(priv->read_urbp[i]); - kfree(priv->read_urbp[i]->transfer_buffer); - usb_free_urb(priv->read_urbp[i]); + usb_kill_urb (priv->read_urbp[i]); + kfree (priv->read_urbp[i]->transfer_buffer); + usb_free_urb (priv->read_urbp[i]); } /* free up private structure */ - kfree(priv); + kfree (priv); usb_set_serial_port_data(port, NULL); } @@ -263,10 +259,10 @@ static int airprime_write(struct usb_serial_port *port, urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&port->dev, "no more free urbs\n"); - kfree(buffer); + kfree (buffer); return -ENOMEM; } - memcpy(buffer, buf, count); + memcpy (buffer, buf, count); usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); @@ -283,7 +279,7 @@ static int airprime_write(struct usb_serial_port *port, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status); count = status; - kfree(buffer); + kfree (buffer); } else { spin_lock_irqsave(&priv->lock, flags); ++priv->outstanding_urbs; @@ -291,7 +287,7 @@ static int airprime_write(struct usb_serial_port *port, } /* we are done with this urb, so let the host driver * really free it when it is finished with it */ - usb_free_urb(urb); + usb_free_urb (urb); return count; } @@ -319,10 +315,8 @@ static int __init airprime_init(void) { int retval; - airprime_device.num_ports = endpoints; - if (endpoints < 0 || endpoints >= MAX_BULK_EPS) - airprime_device.num_ports = NUM_BULK_EPS; - + airprime_device.num_ports = + (endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS; retval = usb_serial_register(&airprime_device); if (retval) return retval; @@ -347,7 +341,6 @@ MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled"); module_param(buffer_size, int, 0); -MODULE_PARM_DESC(buffer_size, - "Size of the transfer buffers in bytes (default 4096)"); +MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)"); module_param(endpoints, int, 0); MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)"); diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index 77895c8f8f31..599ab2e548a7 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include static int debug; @@ -246,29 +246,29 @@ static void ark3116_set_termios(struct usb_serial_port *port, baud = tty_get_baud_rate(port->tty); switch (baud) { - case 75: - case 150: - case 300: - case 600: - case 1200: - case 1800: - case 2400: - case 4800: - case 9600: - case 19200: - case 38400: - case 57600: - 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; + case 75: + case 150: + case 300: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 9600: + case 19200: + case 38400: + case 57600: + 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; } /* @@ -380,19 +380,19 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, switch (cmd) { case TIOCGSERIAL: /* XXX: Some of these values are probably wrong. */ - memset(&serstruct, 0, sizeof(serstruct)); + memset(&serstruct, 0, sizeof (serstruct)); serstruct.type = PORT_16654; serstruct.line = port->serial->minor; serstruct.port = port->number; serstruct.custom_divisor = 0; serstruct.baud_base = 460800; - if (copy_to_user(user_arg, &serstruct, sizeof(serstruct))) + if (copy_to_user(user_arg, &serstruct, sizeof (serstruct))) return -EFAULT; return 0; case TIOCSSERIAL: - if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) + if (copy_from_user(&serstruct, user_arg, sizeof (serstruct))) return -EFAULT; return 0; default: diff --git a/trunk/drivers/usb/serial/ch341.c b/trunk/drivers/usb/serial/ch341.c index ba28fdc9ccd2..d947d955bceb 100644 --- a/trunk/drivers/usb/serial/ch341.c +++ b/trunk/drivers/usb/serial/ch341.c @@ -130,7 +130,7 @@ static int ch341_get_status(struct usb_device *dev) return -ENOMEM; r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); - if (r < 0) + if ( r < 0) goto out; /* Not having the datasheet for the CH341, we ignore the bytes returned diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 5b349ece7247..c7329f43d9c9 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -133,14 +133,6 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_3_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_4_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_5_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_6_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_7_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index 504edf8c3a3f..6da539ede0ee 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -40,17 +40,6 @@ /* AlphaMicro Components AMC-232USB01 device */ #define FTDI_AMC232_PID 0xFF00 /* Product Id */ -/* SCS HF Radio Modems PID's (http://www.scs-ptc.com) */ -/* the VID is the standard ftdi vid (FTDI_VID) */ -#define FTDI_SCS_DEVICE_0_PID 0xD010 /* SCS PTC-IIusb */ -#define FTDI_SCS_DEVICE_1_PID 0xD011 /* SCS Tracker / DSP TNC */ -#define FTDI_SCS_DEVICE_2_PID 0xD012 -#define FTDI_SCS_DEVICE_3_PID 0xD013 -#define FTDI_SCS_DEVICE_4_PID 0xD014 -#define FTDI_SCS_DEVICE_5_PID 0xD015 -#define FTDI_SCS_DEVICE_6_PID 0xD016 -#define FTDI_SCS_DEVICE_7_PID 0xD017 - /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ #define FTDI_ACTZWAVE_PID 0xF2D0 diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index 78f2f6db494d..6bcb82d3911a 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -1713,7 +1713,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, { struct moschip_port *mos7840_port; unsigned int mcr; - int status; + unsigned int status; dbg("%s - port %d", __func__, port->number); @@ -1740,10 +1740,11 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file, mos7840_port->shadowMCR = mcr; + status = 0; status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr); if (status < 0) { dbg("setting MODEM_CONTROL_REGISTER Failed\n"); - return status; + return -1; } return 0; diff --git a/trunk/drivers/usb/storage/Kconfig b/trunk/drivers/usb/storage/Kconfig index 3d9249632ae1..0f6d234d699b 100644 --- a/trunk/drivers/usb/storage/Kconfig +++ b/trunk/drivers/usb/storage/Kconfig @@ -123,8 +123,7 @@ config USB_STORAGE_ALAUDA config USB_STORAGE_ONETOUCH bool "Support OneTouch Button on Maxtor Hard Drives" - depends on USB_STORAGE - depends on INPUT=y || INPUT=USB_STORAGE + depends on USB_STORAGE && INPUT_EVDEV help Say Y here to include additional code to support the Maxtor OneTouch USB hard drive's onetouch button. diff --git a/trunk/drivers/usb/storage/libusual.c b/trunk/drivers/usb/storage/libusual.c index d617e8ae6b00..a28d49122e7a 100644 --- a/trunk/drivers/usb/storage/libusual.c +++ b/trunk/drivers/usb/storage/libusual.c @@ -135,7 +135,7 @@ static int usu_probe(struct usb_interface *intf, stat[type].fls |= USU_MOD_FL_THREAD; spin_unlock_irqrestore(&usu_lock, flags); - task = kthread_run(usu_probe_thread, (void*)type, "libusual_%ld", type); + task = kthread_run(usu_probe_thread, (void*)type, "libusual_%d", type); if (IS_ERR(task)) { rc = PTR_ERR(task); printk(KERN_WARNING "libusual: " diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index 98b89ea9e312..dfd42fe9e5f0 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -38,7 +38,7 @@ #include "onetouch.h" #include "debug.h" -static void onetouch_release_input(void *onetouch_); +void onetouch_release_input(void *onetouch_); struct usb_onetouch { char name[128]; @@ -223,7 +223,7 @@ int onetouch_connect_input(struct us_data *ss) return error; } -static void onetouch_release_input(void *onetouch_) +void onetouch_release_input(void *onetouch_) { struct usb_onetouch *onetouch = (struct usb_onetouch *) onetouch_; diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index a0ed889230aa..732bf52a775e 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -44,8 +44,7 @@ * running with this patch. * Send your submission to either Phil Dibowitz or * Alan Stern , and don't forget to CC: the - * USB development list and the USB storage list - * + * USB development list . */ /* patch submitted by Vivian Bregier @@ -558,13 +557,6 @@ UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, US_FL_SINGLE_LUN), #endif -/* Reported by Dmitry Khlystov */ -UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, - "Samsung", - "YP-U3", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_MAX_SECTORS_64), - /* Reported by Bob Sass -- only rev 1.33 tested */ UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, "Belkin", @@ -1208,17 +1200,6 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_BULK32), -/* Andrew Lunn - * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL - * on LUN 4. - * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera" -*/ -UNUSUAL_DEV( 0x0851, 0x1543, 0x0200, 0x0200, - "PanDigital", - "Photo Frame", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_NOT_LOCKABLE), - /* Submitted by Jan De Luyck */ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, "CITIZEN", @@ -1361,13 +1342,6 @@ UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), -/* Reported by Rohan Hart */ -UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010, - "INTOVA", - "Pixtreme", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* * Entry for Jenoptik JD 5200z3 * diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index e268aacb773a..a856effad3bd 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -539,8 +539,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) " has %s in unusual_devs.h (kernel" " %s)\n" " Please send a copy of this message to " - " and " - "\n", + "\n", le16_to_cpu(ddesc->idVendor), le16_to_cpu(ddesc->idProduct), le16_to_cpu(ddesc->bcdDevice), diff --git a/trunk/drivers/virtio/virtio.c b/trunk/drivers/virtio/virtio.c index 13866789b356..b535483bc556 100644 --- a/trunk/drivers/virtio/virtio.c +++ b/trunk/drivers/virtio/virtio.c @@ -80,51 +80,19 @@ static void add_status(struct virtio_device *dev, unsigned status) dev->config->set_status(dev, dev->config->get_status(dev) | status); } -void virtio_check_driver_offered_feature(const struct virtio_device *vdev, - unsigned int fbit) -{ - unsigned int i; - struct virtio_driver *drv = container_of(vdev->dev.driver, - struct virtio_driver, driver); - - for (i = 0; i < drv->feature_table_size; i++) - if (drv->feature_table[i] == fbit) - return; - BUG(); -} -EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature); - static int virtio_dev_probe(struct device *_d) { - int err, i; + int err; struct virtio_device *dev = container_of(_d,struct virtio_device,dev); struct virtio_driver *drv = container_of(dev->dev.driver, struct virtio_driver, driver); - u32 device_features; - /* We have a driver! */ add_status(dev, VIRTIO_CONFIG_S_DRIVER); - - /* Figure out what features the device supports. */ - device_features = dev->config->get_features(dev); - - /* Features supported by both device and driver into dev->features. */ - memset(dev->features, 0, sizeof(dev->features)); - for (i = 0; i < drv->feature_table_size; i++) { - unsigned int f = drv->feature_table[i]; - BUG_ON(f >= 32); - if (device_features & (1 << f)) - set_bit(f, dev->features); - } - err = drv->probe(dev); if (err) add_status(dev, VIRTIO_CONFIG_S_FAILED); - else { + else add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); - /* They should never have set feature bits beyond 32 */ - dev->config->set_features(dev, dev->features[0]); - } return err; } @@ -146,8 +114,6 @@ static int virtio_dev_remove(struct device *_d) int register_virtio_driver(struct virtio_driver *driver) { - /* Catch this early. */ - BUG_ON(driver->feature_table_size && !driver->feature_table); driver->driver.bus = &virtio_bus; driver->driver.probe = virtio_dev_probe; driver->driver.remove = virtio_dev_remove; diff --git a/trunk/drivers/virtio/virtio_balloon.c b/trunk/drivers/virtio/virtio_balloon.c index bfef604160d1..0b3efc31ee6d 100644 --- a/trunk/drivers/virtio/virtio_balloon.c +++ b/trunk/drivers/virtio/virtio_balloon.c @@ -155,9 +155,9 @@ static void virtballoon_changed(struct virtio_device *vdev) static inline s64 towards_target(struct virtio_balloon *vb) { u32 v; - vb->vdev->config->get(vb->vdev, - offsetof(struct virtio_balloon_config, num_pages), - &v, sizeof(v)); + __virtio_config_val(vb->vdev, + offsetof(struct virtio_balloon_config, num_pages), + &v); return v - vb->num_pages; } @@ -227,7 +227,7 @@ static int virtballoon_probe(struct virtio_device *vdev) } vb->tell_host_first - = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); + = vdev->config->feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); return 0; @@ -259,11 +259,7 @@ static void virtballoon_remove(struct virtio_device *vdev) kfree(vb); } -static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST }; - static struct virtio_driver virtio_balloon = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, diff --git a/trunk/drivers/virtio/virtio_pci.c b/trunk/drivers/virtio/virtio_pci.c index 27e9fc9117cd..c0df924766a7 100644 --- a/trunk/drivers/virtio/virtio_pci.c +++ b/trunk/drivers/virtio/virtio_pci.c @@ -87,22 +87,23 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) return container_of(vdev, struct virtio_pci_device, vdev); } -/* virtio config->get_features() implementation */ -static u32 vp_get_features(struct virtio_device *vdev) -{ - struct virtio_pci_device *vp_dev = to_vp_device(vdev); - - /* When someone needs more than 32 feature bits, we'll need to - * steal a bit to indicate that the rest are somewhere else. */ - return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); -} - -/* virtio config->set_features() implementation */ -static void vp_set_features(struct virtio_device *vdev, u32 features) +/* virtio config->feature() implementation */ +static bool vp_feature(struct virtio_device *vdev, unsigned bit) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); + u32 mask; + + /* Since this function is supposed to have the side effect of + * enabling a queried feature, we simulate that by doing a read + * from the host feature bitmask and then writing to the guest + * feature bitmask */ + mask = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); + if (mask & (1 << bit)) { + mask |= (1 << bit); + iowrite32(mask, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); + } - iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); + return !!(mask & (1 << bit)); } /* virtio config->get() implementation */ @@ -144,14 +145,14 @@ static void vp_set_status(struct virtio_device *vdev, u8 status) struct virtio_pci_device *vp_dev = to_vp_device(vdev); /* We should never be setting status to 0. */ BUG_ON(status == 0); - iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); + return iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); } static void vp_reset(struct virtio_device *vdev) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); /* 0 status means a reset. */ - iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); + return iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); } /* the notify function used when creating a virt queue */ @@ -292,6 +293,7 @@ static void vp_del_vq(struct virtqueue *vq) } static struct virtio_config_ops virtio_pci_config_ops = { + .feature = vp_feature, .get = vp_get, .set = vp_set, .get_status = vp_get_status, @@ -299,8 +301,6 @@ static struct virtio_config_ops virtio_pci_config_ops = { .reset = vp_reset, .find_vq = vp_find_vq, .del_vq = vp_del_vq, - .get_features = vp_get_features, - .set_features = vp_set_features, }; /* the PCI probing function */ diff --git a/trunk/drivers/virtio/virtio_ring.c b/trunk/drivers/virtio/virtio_ring.c index 937a49d6772c..c2fa5c630813 100644 --- a/trunk/drivers/virtio/virtio_ring.c +++ b/trunk/drivers/virtio/virtio_ring.c @@ -184,11 +184,6 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) START_USE(vq); - if (unlikely(vq->broken)) { - END_USE(vq); - return NULL; - } - if (!more_used(vq)) { pr_debug("No more buffers in queue\n"); END_USE(vq); diff --git a/trunk/fs/autofs4/expire.c b/trunk/fs/autofs4/expire.c index 894fee54d4d8..d96e5c14a9ca 100644 --- a/trunk/fs/autofs4/expire.c +++ b/trunk/fs/autofs4/expire.c @@ -73,8 +73,8 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) status = 0; done: DPRINTK("returning = %d", status); - dput(dentry); mntput(mnt); + dput(dentry); return status; } @@ -333,7 +333,7 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb, /* Can we expire this guy */ if (autofs4_can_expire(dentry, timeout, do_now)) { expired = dentry; - goto found; + break; } goto next; } @@ -352,7 +352,7 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb, inf->flags |= AUTOFS_INF_EXPIRING; spin_unlock(&sbi->fs_lock); expired = dentry; - goto found; + break; } spin_unlock(&sbi->fs_lock); /* @@ -363,7 +363,7 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb, expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); if (expired) { dput(dentry); - goto found; + break; } } next: @@ -371,16 +371,18 @@ static struct dentry *autofs4_expire_indirect(struct super_block *sb, spin_lock(&dcache_lock); next = next->next; } - spin_unlock(&dcache_lock); - return NULL; -found: - DPRINTK("returning %p %.*s", - expired, (int)expired->d_name.len, expired->d_name.name); - spin_lock(&dcache_lock); - list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); + if (expired) { + DPRINTK("returning %p %.*s", + expired, (int)expired->d_name.len, expired->d_name.name); + spin_lock(&dcache_lock); + list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); + spin_unlock(&dcache_lock); + return expired; + } spin_unlock(&dcache_lock); - return expired; + + return NULL; } /* Perform an expiry operation */ diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index edf5b6bddb52..aa4c5ff8a40d 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -146,17 +146,17 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) if (d_mountpoint(dentry)) { struct file *fp = NULL; - struct path fp_path = { .dentry = dentry, .mnt = mnt }; + struct vfsmount *fp_mnt = mntget(mnt); + struct dentry *fp_dentry = dget(dentry); - path_get(&fp_path); - - if (!autofs4_follow_mount(&fp_path.mnt, &fp_path.dentry)) { - path_put(&fp_path); + if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) { + dput(fp_dentry); + mntput(fp_mnt); dcache_dir_close(inode, file); goto out; } - fp = dentry_open(fp_path.dentry, fp_path.mnt, file->f_flags); + fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); status = PTR_ERR(fp); if (IS_ERR(fp)) { dcache_dir_close(inode, file); @@ -242,8 +242,7 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) { struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); struct autofs_info *ino = autofs4_dentry_ino(dentry); - struct dentry *new; - int status; + int status = 0; /* Block on any pending expiry here; invalidate the dentry when expiration is done to trigger mount request with a new @@ -319,28 +318,7 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) spin_lock(&dentry->d_lock); dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; spin_unlock(&dentry->d_lock); - - /* - * The dentry that is passed in from lookup may not be the one - * we end up using, as mkdir can create a new one. If this - * happens, and another process tries the lookup at the same time, - * it will set the PENDING flag on this new dentry, but add itself - * to our waitq. Then, if after the lookup succeeds, the first - * process that requested the mount performs another lookup of the - * same directory, it will show up as still pending! So, we need - * to redo the lookup here and clear pending on that dentry. - */ - if (d_unhashed(dentry)) { - new = d_lookup(dentry->d_parent, &dentry->d_name); - if (new) { - spin_lock(&new->d_lock); - new->d_flags &= ~DCACHE_AUTOFS_PENDING; - spin_unlock(&new->d_lock); - dput(new); - } - } - - return 0; + return status; } /* For autofs direct mounts the follow link triggers the mount */ diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index 75e5955c3f6d..1fe28e4754c2 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -171,7 +171,7 @@ static int autofs4_getpath(struct autofs_sb_info *sbi, for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent) len += tmp->d_name.len + 1; - if (!len || --len > NAME_MAX) { + if (--len > NAME_MAX) { spin_unlock(&dcache_lock); return 0; } diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index f28cf8b46f80..9ced35b00686 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -934,7 +934,7 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - npages = clamp(npages, 1, FUSE_MAX_PAGES_PER_REQ); + npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ); down_read(¤t->mm->mmap_sem); npages = get_user_pages(current, current->mm, user_addr, npages, write, 0, req->pages, NULL); diff --git a/trunk/fs/jffs2/build.c b/trunk/fs/jffs2/build.c index c5e1450d79f9..d58f845ccb85 100644 --- a/trunk/fs/jffs2/build.c +++ b/trunk/fs/jffs2/build.c @@ -46,7 +46,7 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c) static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, - struct jffs2_inode_cache *ic) + struct jffs2_inode_cache *ic) { struct jffs2_full_dirent *fd; @@ -68,17 +68,11 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c, continue; } - if (fd->type == DT_DIR) { - if (child_ic->pino_nlink) { - JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", - fd->name, fd->ino, ic->ino); - /* TODO: What do we do about it? */ - } else { - child_ic->pino_nlink = ic->ino; - } - } else - child_ic->pino_nlink++; - + if (child_ic->nlink++ && fd->type == DT_DIR) { + JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", + fd->name, fd->ino, ic->ino); + /* TODO: What do we do about it? */ + } dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino); /* Can't free scan_dents so far. We might need them in pass 2 */ } @@ -131,7 +125,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) dbg_fsbuild("pass 2 starting\n"); for_each_inode(i, c, ic) { - if (ic->pino_nlink) + if (ic->nlink) continue; jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); @@ -238,19 +232,16 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, /* Reduce nlink of the child. If it's now zero, stick it on the dead_fds list to be cleaned up later. Else just free the fd */ - if (fd->type == DT_DIR) - child_ic->pino_nlink = 0; - else - child_ic->pino_nlink--; + child_ic->nlink--; - if (!child_ic->pino_nlink) { - dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n", + if (!child_ic->nlink) { + dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n", fd->ino, fd->name); fd->next = *dead_fds; *dead_fds = fd; } else { dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", - fd->ino, fd->name, child_ic->pino_nlink); + fd->ino, fd->name, child_ic->nlink); jffs2_free_full_dirent(fd); } } diff --git a/trunk/fs/jffs2/dir.c b/trunk/fs/jffs2/dir.c index c0c141f6fde1..c63e7a96af0d 100644 --- a/trunk/fs/jffs2/dir.c +++ b/trunk/fs/jffs2/dir.c @@ -208,13 +208,6 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, f = JFFS2_INODE_INFO(inode); dir_f = JFFS2_INODE_INFO(dir_i); - /* jffs2_do_create() will want to lock it, _after_ reserving - space and taking c-alloc_sem. If we keep it locked here, - lockdep gets unhappy (although it's a false positive; - nothing else will be looking at this inode yet so there's - no chance of AB-BA deadlock involving its f->sem). */ - mutex_unlock(&f->sem); - ret = jffs2_do_create(c, dir_f, f, ri, dentry->d_name.name, dentry->d_name.len); if (ret) @@ -226,8 +219,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode, d_instantiate(dentry, inode); D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", - inode->i_ino, inode->i_mode, inode->i_nlink, - f->inocache->pino_nlink, inode->i_mapping->nrpages)); + inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); return 0; fail: @@ -251,7 +243,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry) ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, dentry->d_name.len, dead_f, now); if (dead_f->inocache) - dentry->d_inode->i_nlink = dead_f->inocache->pino_nlink; + dentry->d_inode->i_nlink = dead_f->inocache->nlink; if (!ret) dir_i->i_mtime = dir_i->i_ctime = ITIME(now); return ret; @@ -284,7 +276,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de if (!ret) { mutex_lock(&f->sem); - old_dentry->d_inode->i_nlink = ++f->inocache->pino_nlink; + old_dentry->d_inode->i_nlink = ++f->inocache->nlink; mutex_unlock(&f->sem); d_instantiate(dentry, old_dentry->d_inode); dir_i->i_mtime = dir_i->i_ctime = ITIME(now); @@ -501,13 +493,10 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) inode->i_op = &jffs2_dir_inode_operations; inode->i_fop = &jffs2_dir_operations; - - f = JFFS2_INODE_INFO(inode); - /* Directories get nlink 2 at start */ inode->i_nlink = 2; - /* but ic->pino_nlink is the parent ino# */ - f->inocache->pino_nlink = dir_i->i_ino; + + f = JFFS2_INODE_INFO(inode); ri->data_crc = cpu_to_je32(0); ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); @@ -605,25 +594,17 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) { - struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); - struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); struct jffs2_full_dirent *fd; int ret; - uint32_t now = get_seconds(); for (fd = f->dents ; fd; fd = fd->next) { if (fd->ino) return -ENOTEMPTY; } - - ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, - dentry->d_name.len, f, now); - if (!ret) { - dir_i->i_mtime = dir_i->i_ctime = ITIME(now); - clear_nlink(dentry->d_inode); + ret = jffs2_unlink(dir_i, dentry); + if (!ret) drop_nlink(dir_i); - } return ret; } @@ -836,10 +817,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, inode which didn't exist. */ if (victim_f->inocache) { mutex_lock(&victim_f->sem); - if (S_ISDIR(new_dentry->d_inode->i_mode)) - victim_f->inocache->pino_nlink = 0; - else - victim_f->inocache->pino_nlink--; + victim_f->inocache->nlink--; mutex_unlock(&victim_f->sem); } } @@ -860,8 +838,8 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); mutex_lock(&f->sem); inc_nlink(old_dentry->d_inode); - if (f->inocache && !S_ISDIR(old_dentry->d_inode->i_mode)) - f->inocache->pino_nlink++; + if (f->inocache) + f->inocache->nlink++; mutex_unlock(&f->sem); printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); diff --git a/trunk/fs/jffs2/erase.c b/trunk/fs/jffs2/erase.c index dddb2a6c9e2c..25a640e566d3 100644 --- a/trunk/fs/jffs2/erase.c +++ b/trunk/fs/jffs2/erase.c @@ -294,7 +294,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, break; #endif default: - if (ic->nodes == (void *)ic && ic->pino_nlink == 0) + if (ic->nodes == (void *)ic && ic->nlink == 0) jffs2_del_ino_cache(c, ic); } } @@ -332,8 +332,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl if (c->mtd->point) { unsigned long *wordebuf; - ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, - &retlen, &ebuf, NULL); + ret = c->mtd->point(c->mtd, jeb->offset, c->sector_size, &retlen, (unsigned char **)&ebuf); if (ret) { D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); goto do_flash_read; @@ -341,7 +340,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl if (retlen < c->sector_size) { /* Don't muck about if it won't let us point to the whole erase sector */ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); - c->mtd->unpoint(c->mtd, jeb->offset, retlen); + c->mtd->unpoint(c->mtd, ebuf, jeb->offset, retlen); goto do_flash_read; } wordebuf = ebuf-sizeof(*wordebuf); @@ -350,7 +349,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl if (*++wordebuf != ~0) break; } while(--retlen); - c->mtd->unpoint(c->mtd, jeb->offset, c->sector_size); + c->mtd->unpoint(c->mtd, ebuf, jeb->offset, c->sector_size); if (retlen) { printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n", *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf)); diff --git a/trunk/fs/jffs2/fs.c b/trunk/fs/jffs2/fs.c index 086c43830221..3eb1c84b0a33 100644 --- a/trunk/fs/jffs2/fs.c +++ b/trunk/fs/jffs2/fs.c @@ -273,7 +273,7 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime)); - inode->i_nlink = f->inocache->pino_nlink; + inode->i_nlink = f->inocache->nlink; inode->i_blocks = (inode->i_size + 511) >> 9; @@ -286,12 +286,13 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) case S_IFDIR: { struct jffs2_full_dirent *fd; - inode->i_nlink = 2; /* parent and '.' */ for (fd=f->dents; fd; fd = fd->next) { if (fd->type == DT_DIR && fd->ino) inc_nlink(inode); } + /* and '..' */ + inc_nlink(inode); /* Root dir gets i_nlink 3 for some reason */ if (inode->i_ino == 1) inc_nlink(inode); @@ -585,12 +586,11 @@ void jffs2_gc_release_inode(struct jffs2_sb_info *c, } struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, - int inum, int unlinked) + int inum, int nlink) { struct inode *inode; struct jffs2_inode_cache *ic; - - if (unlinked) { + if (!nlink) { /* The inode has zero nlink but its nodes weren't yet marked obsolete. This has to be because we're still waiting for the final (close() and) iput() to happen. @@ -638,8 +638,8 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, return ERR_CAST(inode); } if (is_bad_inode(inode)) { - printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. unlinked %d\n", - inum, unlinked); + printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n", + inum, nlink); /* NB. This will happen again. We need to do something appropriate here. */ iput(inode); return ERR_PTR(-EIO); diff --git a/trunk/fs/jffs2/gc.c b/trunk/fs/jffs2/gc.c index 090c556ffed2..bad005664e30 100644 --- a/trunk/fs/jffs2/gc.c +++ b/trunk/fs/jffs2/gc.c @@ -161,8 +161,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) continue; } - if (!ic->pino_nlink) { - D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink/pino zero\n", + if (!ic->nlink) { + D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n", ic->ino)); spin_unlock(&c->inocache_lock); jffs2_xattr_delete_inode(c, ic); @@ -398,10 +398,10 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) it's vaguely possible. */ inum = ic->ino; - nlink = ic->pino_nlink; + nlink = ic->nlink; spin_unlock(&c->inocache_lock); - f = jffs2_gc_fetch_inode(c, inum, !nlink); + f = jffs2_gc_fetch_inode(c, inum, nlink); if (IS_ERR(f)) { ret = PTR_ERR(f); goto release_sem; diff --git a/trunk/fs/jffs2/nodelist.h b/trunk/fs/jffs2/nodelist.h index 1750445556c3..8219df6eb6d8 100644 --- a/trunk/fs/jffs2/nodelist.h +++ b/trunk/fs/jffs2/nodelist.h @@ -177,10 +177,7 @@ struct jffs2_inode_cache { #ifdef CONFIG_JFFS2_FS_XATTR struct jffs2_xattr_ref *xref; #endif - uint32_t pino_nlink; /* Directories store parent inode - here; other inodes store nlink. - Zero always means that it's - completely unlinked. */ + int nlink; }; /* Inode states for 'state' above. We need the 'GC' state to prevent diff --git a/trunk/fs/jffs2/nodemgmt.c b/trunk/fs/jffs2/nodemgmt.c index a9bf9603c1ba..9df8f3ef20df 100644 --- a/trunk/fs/jffs2/nodemgmt.c +++ b/trunk/fs/jffs2/nodemgmt.c @@ -709,7 +709,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref break; #endif default: - if (ic->nodes == (void *)ic && ic->pino_nlink == 0) + if (ic->nodes == (void *)ic && ic->nlink == 0) jffs2_del_ino_cache(c, ic); break; } diff --git a/trunk/fs/jffs2/os-linux.h b/trunk/fs/jffs2/os-linux.h index 2cc866cf134f..1b10d2594092 100644 --- a/trunk/fs/jffs2/os-linux.h +++ b/trunk/fs/jffs2/os-linux.h @@ -187,7 +187,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); void jffs2_gc_release_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f); struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, - int inum, int unlinked); + int inum, int nlink); unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, struct jffs2_inode_info *f, diff --git a/trunk/fs/jffs2/readinode.c b/trunk/fs/jffs2/readinode.c index 6ca08ad887c0..4cb4d76de07f 100644 --- a/trunk/fs/jffs2/readinode.c +++ b/trunk/fs/jffs2/readinode.c @@ -63,11 +63,10 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), * adding and jffs2_flash_read_end() interface. */ if (c->mtd->point) { - err = c->mtd->point(c->mtd, ofs, len, &retlen, - (void **)&buffer, NULL); + err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); if (!err && retlen < len) { JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); - c->mtd->unpoint(c->mtd, ofs, retlen); + c->mtd->unpoint(c->mtd, buffer, ofs, retlen); } else if (err) JFFS2_WARNING("MTD point failed: error code %d.\n", err); else @@ -101,7 +100,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info kfree(buffer); #ifndef __ECOS else - c->mtd->unpoint(c->mtd, ofs, len); + c->mtd->unpoint(c->mtd, buffer, ofs, len); #endif if (crc != tn->data_crc) { @@ -137,7 +136,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info kfree(buffer); #ifndef __ECOS else - c->mtd->unpoint(c->mtd, ofs, len); + c->mtd->unpoint(c->mtd, buffer, ofs, len); #endif return err; } @@ -1124,8 +1123,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, size_t retlen; int ret; - dbg_readinode("ino #%u pino/nlink is %d\n", f->inocache->ino, - f->inocache->pino_nlink); + dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); memset(&rii, 0, sizeof(rii)); @@ -1360,7 +1358,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, } dbg_readinode("creating inocache for root inode\n"); memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); - f->inocache->ino = f->inocache->pino_nlink = 1; + f->inocache->ino = f->inocache->nlink = 1; f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->state = INO_STATE_READING; jffs2_add_ino_cache(c, f->inocache); @@ -1403,7 +1401,7 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) jffs2_clear_acl(f); jffs2_xattr_delete_inode(c, f->inocache); mutex_lock(&f->sem); - deleted = f->inocache && !f->inocache->pino_nlink; + deleted = f->inocache && !f->inocache->nlink; if (f->inocache && f->inocache->state != INO_STATE_CHECKING) jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); diff --git a/trunk/fs/jffs2/scan.c b/trunk/fs/jffs2/scan.c index 1d437de1e9a8..272872d27fd5 100644 --- a/trunk/fs/jffs2/scan.c +++ b/trunk/fs/jffs2/scan.c @@ -97,12 +97,11 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) size_t pointlen; if (c->mtd->point) { - ret = c->mtd->point(c->mtd, 0, c->mtd->size, &pointlen, - (void **)&flashbuf, NULL); + ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf); if (!ret && pointlen < c->mtd->size) { /* Don't muck about if it won't let us point to the whole flash */ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); - c->mtd->unpoint(c->mtd, 0, pointlen); + c->mtd->unpoint(c->mtd, flashbuf, 0, pointlen); flashbuf = NULL; } if (ret) @@ -268,7 +267,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) kfree(flashbuf); #ifndef __ECOS else - c->mtd->unpoint(c->mtd, 0, c->mtd->size); + c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); #endif if (s) kfree(s); @@ -941,7 +940,7 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin ic->nodes = (void *)ic; jffs2_add_ino_cache(c, ic); if (ino == 1) - ic->pino_nlink = 1; + ic->nlink = 1; return ic; } diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index 7da69eae49e4..f3353df178e7 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -31,12 +31,11 @@ static struct kmem_cache *jffs2_inode_cachep; static struct inode *jffs2_alloc_inode(struct super_block *sb) { - struct jffs2_inode_info *f; - - f = kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); - if (!f) + struct jffs2_inode_info *ei; + ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); + if (!ei) return NULL; - return &f->vfs_inode; + return &ei->vfs_inode; } static void jffs2_destroy_inode(struct inode *inode) @@ -46,10 +45,10 @@ static void jffs2_destroy_inode(struct inode *inode) static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo) { - struct jffs2_inode_info *f = foo; + struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; - mutex_init(&f->sem); - inode_init_once(&f->vfs_inode); + mutex_init(&ei->sem); + inode_init_once(&ei->vfs_inode); } static int jffs2_sync_fs(struct super_block *sb, int wait) diff --git a/trunk/fs/jffs2/wbuf.c b/trunk/fs/jffs2/wbuf.c index 0e78b00035e4..8de52b607678 100644 --- a/trunk/fs/jffs2/wbuf.c +++ b/trunk/fs/jffs2/wbuf.c @@ -494,7 +494,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) /* If it's an in-core inode, then we have to adjust any full_dirent or full_dnode structure to point to the new version instead of the old */ - f = jffs2_gc_fetch_inode(c, ic->ino, !ic->pino_nlink); + f = jffs2_gc_fetch_inode(c, ic->ino, ic->nlink); if (IS_ERR(f)) { /* Should never happen; it _must_ be present */ JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n", diff --git a/trunk/fs/jffs2/write.c b/trunk/fs/jffs2/write.c index ca29440e9435..665fce9797d3 100644 --- a/trunk/fs/jffs2/write.c +++ b/trunk/fs/jffs2/write.c @@ -19,8 +19,7 @@ #include "compr.h" -int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - uint32_t mode, struct jffs2_raw_inode *ri) +int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri) { struct jffs2_inode_cache *ic; @@ -32,7 +31,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, memset(ic, 0, sizeof(*ic)); f->inocache = ic; - f->inocache->pino_nlink = 1; /* Will be overwritten shortly for directories */ + f->inocache->nlink = 1; f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->state = INO_STATE_PRESENT; @@ -439,10 +438,10 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); - if (ret) + if (ret) { + mutex_unlock(&f->sem); return ret; - - mutex_lock(&f->sem); + } ri->data_crc = cpu_to_je32(0); ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); @@ -636,9 +635,9 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, jffs2_mark_node_obsolete(c, fd->raw); jffs2_free_full_dirent(fd); } - dead_f->inocache->pino_nlink = 0; - } else - dead_f->inocache->pino_nlink--; + } + + dead_f->inocache->nlink--; /* NB: Caller must set inode nlink if appropriate */ mutex_unlock(&dead_f->sem); } diff --git a/trunk/fs/jffs2/xattr.c b/trunk/fs/jffs2/xattr.c index 082e844ab2db..574cb7532d6c 100644 --- a/trunk/fs/jffs2/xattr.c +++ b/trunk/fs/jffs2/xattr.c @@ -592,7 +592,7 @@ void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache When an inode with XATTR is removed, those XATTRs must be removed. */ struct jffs2_xattr_ref *ref, *_ref; - if (!ic || ic->pino_nlink > 0) + if (!ic || ic->nlink > 0) return; down_write(&c->xattr_sem); @@ -829,7 +829,7 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ref->xd and ref->ic are not valid yet. */ xd = jffs2_find_xattr_datum(c, ref->xid); ic = jffs2_get_ino_cache(c, ref->ino); - if (!xd || !ic || !ic->pino_nlink) { + if (!xd || !ic || !ic->nlink) { dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n", ref->ino, ref->xid, ref->xseqno); ref->xseqno |= XREF_DELETE_MARKER; diff --git a/trunk/fs/utimes.c b/trunk/fs/utimes.c index af059d5cb485..a2bef77dc9c9 100644 --- a/trunk/fs/utimes.c +++ b/trunk/fs/utimes.c @@ -40,14 +40,9 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) #endif -static bool nsec_special(long nsec) -{ - return nsec == UTIME_OMIT || nsec == UTIME_NOW; -} - static bool nsec_valid(long nsec) { - if (nsec_special(nsec)) + if (nsec == UTIME_OMIT || nsec == UTIME_NOW) return true; return nsec >= 0 && nsec <= 999999999; @@ -124,15 +119,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; newattrs.ia_valid |= ATTR_MTIME_SET; } - } - - /* - * If times is NULL or both times are either UTIME_OMIT or - * UTIME_NOW, then need to check permissions, because - * inode_change_ok() won't do it. - */ - if (!times || (nsec_special(times[0].tv_nsec) && - nsec_special(times[1].tv_nsec))) { + } else { error = -EACCES; if (IS_IMMUTABLE(inode)) goto mnt_drop_write_and_out; diff --git a/trunk/include/asm-arm/div64.h b/trunk/include/asm-arm/div64.h index 5001390be958..0b5f881c3d85 100644 --- a/trunk/include/asm-arm/div64.h +++ b/trunk/include/asm-arm/div64.h @@ -224,4 +224,6 @@ #endif +extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); + #endif diff --git a/trunk/include/asm-frv/unaligned.h b/trunk/include/asm-frv/unaligned.h index 839a2fbffa0f..64ccc736f2d8 100644 --- a/trunk/include/asm-frv/unaligned.h +++ b/trunk/include/asm-frv/unaligned.h @@ -9,8 +9,8 @@ * 2 of the License, or (at your option) any later version. */ -#ifndef _ASM_UNALIGNED_H -#define _ASM_UNALIGNED_H +#ifndef _ASM_FRV_UNALIGNED_H +#define _ASM_FRV_UNALIGNED_H #include #include @@ -19,4 +19,4 @@ #define get_unaligned __get_unaligned_be #define put_unaligned __put_unaligned_be -#endif /* _ASM_UNALIGNED_H */ +#endif /* _ASM_FRV_UNALIGNED_H */ diff --git a/trunk/include/asm-generic/div64.h b/trunk/include/asm-generic/div64.h index 8f4e3193342e..a4a49370793c 100644 --- a/trunk/include/asm-generic/div64.h +++ b/trunk/include/asm-generic/div64.h @@ -30,6 +30,11 @@ __rem; \ }) +static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor) +{ + return dividend / divisor; +} + #elif BITS_PER_LONG == 32 extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor); @@ -49,6 +54,8 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor); __rem; \ }) +extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); + #else /* BITS_PER_LONG == ?? */ # error do_div() does not yet support the C64 diff --git a/trunk/include/asm-ia64/cpu.h b/trunk/include/asm-ia64/cpu.h index fcca30b9f110..e87fa3210a2b 100644 --- a/trunk/include/asm-ia64/cpu.h +++ b/trunk/include/asm-ia64/cpu.h @@ -14,8 +14,8 @@ DECLARE_PER_CPU(struct ia64_cpu, cpu_devices); DECLARE_PER_CPU(int, cpu_state); -#ifdef CONFIG_HOTPLUG_CPU extern int arch_register_cpu(int num); +#ifdef CONFIG_HOTPLUG_CPU extern void arch_unregister_cpu(int); #endif diff --git a/trunk/include/asm-ia64/dmi.h b/trunk/include/asm-ia64/dmi.h index 00eb1b130b63..f3efaa229525 100644 --- a/trunk/include/asm-ia64/dmi.h +++ b/trunk/include/asm-ia64/dmi.h @@ -3,9 +3,4 @@ #include -/* Use normal IO mappings for DMI */ -#define dmi_ioremap ioremap -#define dmi_iounmap(x,l) iounmap(x) -#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC) - #endif diff --git a/trunk/include/asm-ia64/io.h b/trunk/include/asm-ia64/io.h index 260a85ac9d6a..4ebed77aa472 100644 --- a/trunk/include/asm-ia64/io.h +++ b/trunk/include/asm-ia64/io.h @@ -423,6 +423,11 @@ extern void __iomem * ioremap(unsigned long offset, unsigned long size); extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size); extern void iounmap (volatile void __iomem *addr); +/* Use normal IO mappings for DMI */ +#define dmi_ioremap ioremap +#define dmi_iounmap(x,l) iounmap(x) +#define dmi_alloc(l) kmalloc(l, GFP_ATOMIC) + /* * String version of IO memory access ops: */ diff --git a/trunk/include/asm-ia64/thread_info.h b/trunk/include/asm-ia64/thread_info.h index 2422ac61658a..f30e05583869 100644 --- a/trunk/include/asm-ia64/thread_info.h +++ b/trunk/include/asm-ia64/thread_info.h @@ -108,11 +108,13 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk); #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */ #define TIF_FREEZE 20 /* is freezing for suspend */ #define TIF_RESTORE_RSE 21 /* user RBS is newer than kernel RBS */ +#define TIF_RESTORE_SIGMASK 22 /* restore signal mask in do_signal() */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SYSCALL_TRACEAUDIT (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -129,18 +131,7 @@ extern void tsk_clear_notify_resume(struct task_struct *tsk); #define TIF_WORK_MASK (TIF_ALLWORK_MASK&~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)) #define TS_POLLING 1 /* true if in idle loop and not sleeping */ -#define TS_RESTORE_SIGMASK 2 /* restore signal mask in do_signal() */ #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) -#ifndef __ASSEMBLY__ -#define HAVE_SET_RESTORE_SIGMASK 1 -static inline void set_restore_sigmask(void) -{ - struct thread_info *ti = current_thread_info(); - ti->status |= TS_RESTORE_SIGMASK; - set_bit(TIF_SIGPENDING, &ti->flags); -} -#endif /* !__ASSEMBLY__ */ - #endif /* _ASM_IA64_THREAD_INFO_H */ diff --git a/trunk/include/asm-m68k/div64.h b/trunk/include/asm-m68k/div64.h index 8243c931b5c0..33caad1628d4 100644 --- a/trunk/include/asm-m68k/div64.h +++ b/trunk/include/asm-m68k/div64.h @@ -25,4 +25,5 @@ __rem; \ }) +extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); #endif /* _M68K_DIV64_H */ diff --git a/trunk/include/asm-m68knommu/dma.h b/trunk/include/asm-m68knommu/dma.h index 939a02056217..3f20419c633a 100644 --- a/trunk/include/asm-m68knommu/dma.h +++ b/trunk/include/asm-m68knommu/dma.h @@ -35,8 +35,7 @@ /* * Set number of channels of DMA on ColdFire for different implementations. */ -#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ - defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) +#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) #define MAX_M68K_DMA_CHANNELS 4 #elif defined(CONFIG_M5272) #define MAX_M68K_DMA_CHANNELS 1 diff --git a/trunk/include/asm-m68knommu/param.h b/trunk/include/asm-m68knommu/param.h index 6044397adb64..96c451018324 100644 --- a/trunk/include/asm-m68knommu/param.h +++ b/trunk/include/asm-m68knommu/param.h @@ -1,16 +1,13 @@ #ifndef _M68KNOMMU_PARAM_H #define _M68KNOMMU_PARAM_H -#ifdef __KERNEL__ #define HZ CONFIG_HZ + +#ifdef __KERNEL__ #define USER_HZ HZ #define CLOCKS_PER_SEC (USER_HZ) #endif -#ifndef HZ -#define HZ 100 -#endif - #define EXEC_PAGESIZE 4096 #ifndef NOGROUP diff --git a/trunk/include/asm-mips/div64.h b/trunk/include/asm-mips/div64.h index d1d699105c11..716371bd0980 100644 --- a/trunk/include/asm-mips/div64.h +++ b/trunk/include/asm-mips/div64.h @@ -82,6 +82,7 @@ (n) = __quot; \ __mod; }) +extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); #endif /* (_MIPS_SZLONG == 32) */ #if (_MIPS_SZLONG == 64) @@ -105,6 +106,11 @@ (n) = __quot; \ __mod; }) +static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor) +{ + return dividend / divisor; +} + #endif /* (_MIPS_SZLONG == 64) */ #endif /* _ASM_DIV64_H */ diff --git a/trunk/include/asm-mn10300/div64.h b/trunk/include/asm-mn10300/div64.h index 3a8329b3e869..bf9c515a998c 100644 --- a/trunk/include/asm-mn10300/div64.h +++ b/trunk/include/asm-mn10300/div64.h @@ -97,4 +97,7 @@ signed __muldiv64s(signed val, signed mult, signed div) return result; } +extern __attribute__((const)) +uint64_t div64_64(uint64_t dividend, uint64_t divisor); + #endif /* _ASM_DIV64 */ diff --git a/trunk/include/asm-um/div64.h b/trunk/include/asm-um/div64.h index 1e17f7409cab..7b73b2cd5b34 100644 --- a/trunk/include/asm-um/div64.h +++ b/trunk/include/asm-um/div64.h @@ -3,4 +3,5 @@ #include "asm/arch/div64.h" +extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); #endif diff --git a/trunk/include/asm-x86/div64.h b/trunk/include/asm-x86/div64.h index 9a2d644c08ef..0dbf8bf3ef0a 100644 --- a/trunk/include/asm-x86/div64.h +++ b/trunk/include/asm-x86/div64.h @@ -33,25 +33,25 @@ __mod; \ }) -static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) +/* + * (long)X = ((long long)divs) / (long)div + * (long)rem = ((long long)divs) % (long)div + * + * Warning, this will do an exception if X overflows. + */ +#define div_long_long_rem(a, b, c) div_ll_X_l_rem(a, b, c) + +static inline long div_ll_X_l_rem(long long divs, long div, long *rem) { - union { - u64 v64; - u32 v32[2]; - } d = { dividend }; - u32 upper; - - upper = d.v32[1]; - d.v32[1] = 0; - if (upper >= divisor) { - d.v32[1] = upper / divisor; - upper %= divisor; - } - asm ("divl %2" : "=a" (d.v32[0]), "=d" (*remainder) : - "rm" (divisor), "0" (d.v32[0]), "1" (upper)); - return d.v64; + long dum2; + asm("divl %2":"=a"(dum2), "=d"(*rem) + : "rm"(div), "A"(divs)); + + return dum2; + } -#define div_u64_rem div_u64_rem + +extern uint64_t div64_64(uint64_t dividend, uint64_t divisor); #else # include diff --git a/trunk/include/asm-x86/dmi.h b/trunk/include/asm-x86/dmi.h index 4edf7514a750..1241e6ad1935 100644 --- a/trunk/include/asm-x86/dmi.h +++ b/trunk/include/asm-x86/dmi.h @@ -27,7 +27,6 @@ static inline void *dmi_alloc(unsigned len) #endif -/* Use early IO mappings for DMI because it's initialized early */ #define dmi_ioremap early_ioremap #define dmi_iounmap early_iounmap diff --git a/trunk/include/asm-x86/io_32.h b/trunk/include/asm-x86/io_32.h index 049e81e797a0..6e73467a4fb1 100644 --- a/trunk/include/asm-x86/io_32.h +++ b/trunk/include/asm-x86/io_32.h @@ -133,6 +133,11 @@ extern void *early_ioremap(unsigned long offset, unsigned long size); extern void early_iounmap(void *addr, unsigned long size); extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); +/* Use early IO mappings for DMI because it's initialized early */ +#define dmi_ioremap early_ioremap +#define dmi_iounmap early_iounmap +#define dmi_alloc alloc_bootmem + /* * ISA I/O bus memory addresses are 1:1 with the physical address. */ diff --git a/trunk/include/crypto/scatterwalk.h b/trunk/include/crypto/scatterwalk.h index 833d208c25d6..224658b8d806 100644 --- a/trunk/include/crypto/scatterwalk.h +++ b/trunk/include/crypto/scatterwalk.h @@ -57,14 +57,10 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num, struct scatterlist *sg2) { sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0); - sg1[num - 1].page_link &= ~0x02; } static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg) { - if (sg_is_last(sg)) - return NULL; - return (++sg)->length ? sg : (void *)sg_page(sg); } diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index b7d81b2a9041..78fade0a1e35 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -346,11 +346,6 @@ unifdef-y += videodev.h unifdef-y += virtio_config.h unifdef-y += virtio_blk.h unifdef-y += virtio_net.h -unifdef-y += virtio_9p.h -unifdef-y += virtio_balloon.h -unifdef-y += virtio_console.h -unifdef-y += virtio_pci.h -unifdef-y += virtio_ring.h unifdef-y += vt.h unifdef-y += wait.h unifdef-y += wanrouter.h diff --git a/trunk/include/linux/calc64.h b/trunk/include/linux/calc64.h new file mode 100644 index 000000000000..ebf4b8f38d88 --- /dev/null +++ b/trunk/include/linux/calc64.h @@ -0,0 +1,49 @@ +#ifndef _LINUX_CALC64_H +#define _LINUX_CALC64_H + +#include +#include + +/* + * This is a generic macro which is used when the architecture + * specific div64.h does not provide a optimized one. + * + * The 64bit dividend is divided by the divisor (data type long), the + * result is returned and the remainder stored in the variable + * referenced by remainder (data type long *). In contrast to the + * do_div macro the dividend is kept intact. + */ +#ifndef div_long_long_rem +#define div_long_long_rem(dividend, divisor, remainder) \ + do_div_llr((dividend), divisor, remainder) + +static inline unsigned long do_div_llr(const long long dividend, + const long divisor, long *remainder) +{ + u64 result = dividend; + + *(remainder) = do_div(result, divisor); + return (unsigned long) result; +} +#endif + +/* + * Sign aware variation of the above. On some architectures a + * negative dividend leads to an divide overflow exception, which + * is avoided by the sign check. + */ +static inline long div_long_long_rem_signed(const long long dividend, + const long divisor, long *remainder) +{ + long res; + + if (unlikely(dividend < 0)) { + res = -div_long_long_rem(-dividend, divisor, remainder); + *remainder = -(*remainder); + } else + res = div_long_long_rem(dividend, divisor, remainder); + + return res; +} + +#endif diff --git a/trunk/include/linux/clocksource.h b/trunk/include/linux/clocksource.h index 55e434feec99..35094479ca55 100644 --- a/trunk/include/linux/clocksource.h +++ b/trunk/include/linux/clocksource.h @@ -93,8 +93,6 @@ struct clocksource { #endif }; -extern struct clocksource *clock; /* current clocksource */ - /* * Clock source flags bits:: */ diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index cf8d11cad5ae..8fa7857e153b 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -65,11 +65,10 @@ struct compat_timex { compat_long_t calcnt; compat_long_t errcnt; compat_long_t stbcnt; - compat_int_t tai; compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; - compat_int_t :32; compat_int_t :32; compat_int_t :32; + compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; }; #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 8c23e3dfe3ac..832fb0eb2933 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -380,12 +380,6 @@ struct device { /* Get the wakeup routines, which depend on struct device */ #include -static inline const char *dev_name(struct device *dev) -{ - /* will be changed into kobject_name(&dev->kobj) in the near future */ - return dev->bus_id; -} - #ifdef CONFIG_NUMA static inline int dev_to_node(struct device *dev) { @@ -484,7 +478,7 @@ extern void sysdev_shutdown(void); extern const char *dev_driver_string(struct device *dev); #define dev_printk(level, dev, format, arg...) \ printk(level "%s %s: " format , dev_driver_string(dev) , \ - dev_name(dev) , ## arg) + (dev)->bus_id , ## arg) #define dev_emerg(dev, format, arg...) \ dev_printk(KERN_EMERG , dev , format , ## arg) diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 552e0ec269c9..1883a85625dd 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -61,7 +61,6 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, #define IRQ_WAKEUP 0x00100000 /* IRQ triggers system wakeup */ #define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */ #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ -#define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */ #ifdef CONFIG_IRQ_PER_CPU # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) diff --git a/trunk/include/linux/jiffies.h b/trunk/include/linux/jiffies.h index abb6ac639e8e..33ef710dac24 100644 --- a/trunk/include/linux/jiffies.h +++ b/trunk/include/linux/jiffies.h @@ -1,7 +1,7 @@ #ifndef _LINUX_JIFFIES_H #define _LINUX_JIFFIES_H -#include +#include #include #include #include diff --git a/trunk/include/linux/math64.h b/trunk/include/linux/math64.h deleted file mode 100644 index c1a5f81501ff..000000000000 --- a/trunk/include/linux/math64.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _LINUX_MATH64_H -#define _LINUX_MATH64_H - -#include -#include - -#if BITS_PER_LONG == 64 - -/** - * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder - * - * This is commonly provided by 32bit archs to provide an optimized 64bit - * divide. - */ -static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) -{ - *remainder = dividend % divisor; - return dividend / divisor; -} - -/** - * div_s64_rem - signed 64bit divide with 32bit divisor with remainder - */ -static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) -{ - *remainder = dividend % divisor; - return dividend / divisor; -} - -/** - * div64_u64 - unsigned 64bit divide with 64bit divisor - */ -static inline u64 div64_u64(u64 dividend, u64 divisor) -{ - return dividend / divisor; -} - -#elif BITS_PER_LONG == 32 - -#ifndef div_u64_rem -static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) -{ - *remainder = do_div(dividend, divisor); - return dividend; -} -#endif - -#ifndef div_s64_rem -extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); -#endif - -#ifndef div64_u64 -extern u64 div64_u64(u64 dividend, u64 divisor); -#endif - -#endif /* BITS_PER_LONG */ - -/** - * div_u64 - unsigned 64bit divide with 32bit divisor - * - * This is the most common 64bit divide and should be used if possible, - * as many 32bit archs can optimize this variant better than a full 64bit - * divide. - */ -#ifndef div_u64 -static inline u64 div_u64(u64 dividend, u32 divisor) -{ - u32 remainder; - return div_u64_rem(dividend, divisor, &remainder); -} -#endif - -/** - * div_s64 - signed 64bit divide with 32bit divisor - */ -#ifndef div_s64 -static inline s64 div_s64(s64 dividend, s32 divisor) -{ - s32 remainder; - return div_s64_rem(dividend, divisor, &remainder); -} -#endif - -#endif /* _LINUX_MATH64_H */ diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 3e03b1acbc94..819c4e889bf1 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -190,7 +190,7 @@ void *__symbol_get_gpl(const char *symbol); extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"), aligned(1))) \ + __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ __used \ @@ -229,6 +229,23 @@ enum module_state MODULE_STATE_GOING, }; +/* Similar stuff for section attributes. */ +struct module_sect_attr +{ + struct module_attribute mattr; + char *name; + unsigned long address; +}; + +struct module_sect_attrs +{ + struct attribute_group grp; + int nsections; + struct module_sect_attr attrs[0]; +}; + +struct module_param_attrs; + struct module { enum module_state state; diff --git a/trunk/include/linux/mtd/jedec.h b/trunk/include/linux/mtd/jedec.h new file mode 100644 index 000000000000..9006feb218b9 --- /dev/null +++ b/trunk/include/linux/mtd/jedec.h @@ -0,0 +1,66 @@ + +/* JEDEC Flash Interface. + * This is an older type of interface for self programming flash. It is + * commonly use in older AMD chips and is obsolete compared with CFI. + * It is called JEDEC because the JEDEC association distributes the ID codes + * for the chips. + * + * See the AMD flash databook for information on how to operate the interface. + * + * $Id: jedec.h,v 1.4 2005/11/07 11:14:54 gleixner Exp $ + */ + +#ifndef __LINUX_MTD_JEDEC_H__ +#define __LINUX_MTD_JEDEC_H__ + +#include + +#define MAX_JEDEC_CHIPS 16 + +// Listing of all supported chips and their information +struct JEDECTable +{ + __u16 jedec; + char *name; + unsigned long size; + unsigned long sectorsize; + __u32 capabilities; +}; + +// JEDEC being 0 is the end of the chip array +struct jedec_flash_chip +{ + __u16 jedec; + unsigned long size; + unsigned long sectorsize; + + // *(__u8*)(base + (adder << addrshift)) = data << datashift + // Address size = size << addrshift + unsigned long base; // Byte 0 of the flash, will be unaligned + unsigned int datashift; // Useful for 32bit/16bit accesses + unsigned int addrshift; + unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash + + __u32 capabilities; + + // These markers are filled in by the flash_chip_scan function + unsigned long start; + unsigned long length; +}; + +struct jedec_private +{ + unsigned long size; // Total size of all the devices + + /* Bank handling. If sum(bank_fill) == size then this is linear flash. + Otherwise the mapping has holes in it. bank_fill may be used to + find the holes, but in the common symetric case + bank_fill[0] == bank_fill[*], thus addresses may be computed + mathmatically. bank_fill must be powers of two */ + unsigned is_banked; + unsigned long bank_fill[MAX_JEDEC_CHIPS]; + + struct jedec_flash_chip chips[MAX_JEDEC_CHIPS]; +}; + +#endif diff --git a/trunk/include/linux/mtd/mtd.h b/trunk/include/linux/mtd/mtd.h index 245f9098e171..0a13bb35f044 100644 --- a/trunk/include/linux/mtd/mtd.h +++ b/trunk/include/linux/mtd/mtd.h @@ -143,12 +143,10 @@ struct mtd_info { int (*erase) (struct mtd_info *mtd, struct erase_info *instr); /* This stuff for eXecute-In-Place */ - /* phys is optional and may be set to NULL */ - int (*point) (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); + int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ - void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); + void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); diff --git a/trunk/include/linux/mtd/pmc551.h b/trunk/include/linux/mtd/pmc551.h index 5cc070c24d88..a7f6d20ad407 100644 --- a/trunk/include/linux/mtd/pmc551.h +++ b/trunk/include/linux/mtd/pmc551.h @@ -36,9 +36,8 @@ struct mypriv { * Function Prototypes */ static int pmc551_erase(struct mtd_info *, struct erase_info *); -static void pmc551_unpoint(struct mtd_info *, loff_t, size_t); -static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); +static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t); +static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index cf6dbd759395..e5a53daf17f1 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1429,7 +1429,6 @@ #define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA #define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB -#define PCIE_DEVICE_ID_NEO_4_IBM 0x00F4 #define PCI_VENDOR_ID_XIRCOM 0x115d #define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101 diff --git a/trunk/include/linux/quota.h b/trunk/include/linux/quota.h index dcddfb200947..52e49dce6584 100644 --- a/trunk/include/linux/quota.h +++ b/trunk/include/linux/quota.h @@ -347,9 +347,6 @@ struct quota_info { ((type) == USRQUOTA ? (sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED) : \ (sb_dqopt(sb)->flags & DQUOT_GRP_SUSPENDED)) -#define sb_any_quota_suspended(sb) (sb_has_quota_suspended(sb, USRQUOTA) | \ - sb_has_quota_suspended(sb, GRPQUOTA)) - int register_quota_format(struct quota_format_type *fmt); void unregister_quota_format(struct quota_format_type *fmt); diff --git a/trunk/include/linux/string.h b/trunk/include/linux/string.h index efdc44593b52..c5d3fcad7b57 100644 --- a/trunk/include/linux/string.h +++ b/trunk/include/linux/string.h @@ -109,7 +109,5 @@ extern void *kmemdup(const void *src, size_t len, gfp_t gfp); extern char **argv_split(gfp_t gfp, const char *str, int *argcp); extern void argv_free(char **argv); -extern bool sysfs_streq(const char *s1, const char *s2); - #endif #endif /* _LINUX_STRING_H_ */ diff --git a/trunk/include/linux/sysfs.h b/trunk/include/linux/sysfs.h index 27bad59dae79..7858eac40aa7 100644 --- a/trunk/include/linux/sysfs.h +++ b/trunk/include/linux/sysfs.h @@ -196,12 +196,6 @@ static inline int sysfs_update_group(struct kobject *kobj, return 0; } -static inline int sysfs_update_group(struct kobject *kobj, - const struct attribute_group *grp) -{ - return 0; -} - static inline void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp) { diff --git a/trunk/include/linux/timex.h b/trunk/include/linux/timex.h index fc6035d29d56..8ea3e71ba7fa 100644 --- a/trunk/include/linux/timex.h +++ b/trunk/include/linux/timex.h @@ -58,8 +58,6 @@ #include -#define NTP_API 4 /* NTP API version */ - /* * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen * for a slightly underdamped convergence characteristic. SHIFT_KH @@ -76,22 +74,24 @@ #define MAXTC 10 /* maximum time constant (shift) */ /* + * The SHIFT_UPDATE define establishes the decimal point of the + * time_offset variable which represents the current offset with + * respect to standard time. + * * SHIFT_USEC defines the scaling (shift) of the time_freq and * time_tolerance variables, which represent the current frequency * offset and maximum frequency tolerance. */ +#define SHIFT_UPDATE (SHIFT_HZ + 1) /* time offset scale (shift) */ #define SHIFT_USEC 16 /* frequency offset scale (shift) */ -#define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC)) -#define PPM_SCALE_INV_SHIFT 20 -#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \ - PPM_SCALE + 1) - -#define MAXPHASE 500000000l /* max phase error (ns) */ -#define MAXFREQ 500000 /* max frequency error (ns/s) */ -#define MAXFREQ_SCALED ((s64)MAXFREQ << NTP_SCALE_SHIFT) +#define SHIFT_NSEC 12 /* kernel frequency offset scale */ + +#define MAXPHASE 512000L /* max phase error (us) */ +#define MAXFREQ (512L << SHIFT_USEC) /* max frequency error (ppm) */ +#define MAXFREQ_NSEC (512000L << SHIFT_NSEC) /* max frequency error (ppb) */ #define MINSEC 256 /* min interval between updates (s) */ #define MAXSEC 2048 /* max interval between updates (s) */ -#define NTP_PHASE_LIMIT ((MAXPHASE / NSEC_PER_USEC) << 5) /* beyond max. dispersion */ +#define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */ /* * syscall interface - used (mainly by NTP daemon) @@ -121,11 +121,9 @@ struct timex { long errcnt; /* calibration errors (ro) */ long stbcnt; /* stability limit exceeded (ro) */ - int tai; /* TAI offset (ro) */ - int :32; int :32; int :32; int :32; int :32; int :32; int :32; int :32; - int :32; int :32; int :32; + int :32; int :32; int :32; int :32; }; /* @@ -137,9 +135,6 @@ struct timex { #define ADJ_ESTERROR 0x0008 /* estimated time error */ #define ADJ_STATUS 0x0010 /* clock status */ #define ADJ_TIMECONST 0x0020 /* pll time constant */ -#define ADJ_TAI 0x0080 /* set TAI offset */ -#define ADJ_MICRO 0x1000 /* select microsecond resolution */ -#define ADJ_NANO 0x2000 /* select nanosecond resolution */ #define ADJ_TICK 0x4000 /* tick value */ #define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */ #define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */ @@ -151,6 +146,8 @@ struct timex { #define MOD_ESTERROR ADJ_ESTERROR #define MOD_STATUS ADJ_STATUS #define MOD_TIMECONST ADJ_TIMECONST +#define MOD_CLKB ADJ_TICK +#define MOD_CLKA ADJ_OFFSET_SINGLESHOT /* 0x8000 in original */ /* @@ -172,13 +169,9 @@ struct timex { #define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */ #define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */ -#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */ -#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */ -#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */ -/* read-only bits */ #define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \ - STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) + STA_PPSERROR | STA_CLOCKERR) /* read-only bits */ /* * Clock states (time_state) @@ -210,9 +203,10 @@ extern int time_status; /* clock synchronization status bits */ extern long time_maxerror; /* maximum error */ extern long time_esterror; /* estimated error */ +extern long time_freq; /* frequency offset (scaled ppm) */ + extern long time_adjust; /* The amount of adjtime left */ -extern void ntp_init(void); extern void ntp_clear(void); /** @@ -231,7 +225,7 @@ static inline int ntp_synced(void) __x < 0 ? -(-__x >> __s) : __x >> __s; \ }) -#define NTP_SCALE_SHIFT 32 +#define TICK_LENGTH_SHIFT 32 #ifdef CONFIG_NO_HZ #define NTP_INTERVAL_FREQ (2) @@ -240,8 +234,8 @@ static inline int ntp_synced(void) #endif #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) -/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ -extern u64 tick_length; +/* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ +extern u64 current_tick_length(void); extern void second_overflow(void); extern void update_ntp_one_tick(void); diff --git a/trunk/include/linux/usb/c67x00.h b/trunk/include/linux/usb/c67x00.h deleted file mode 100644 index 83c6b45470ca..000000000000 --- a/trunk/include/linux/usb/c67x00.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * usb_c67x00.h: platform definitions for the Cypress C67X00 USB chip - * - * Copyright (C) 2006-2008 Barco N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA. - */ - -#ifndef _LINUX_USB_C67X00_H -#define _LINUX_USB_C67X00_H - -/* SIE configuration */ -#define C67X00_SIE_UNUSED 0 -#define C67X00_SIE_HOST 1 -#define C67X00_SIE_PERIPHERAL_A 2 /* peripheral on A port */ -#define C67X00_SIE_PERIPHERAL_B 3 /* peripheral on B port */ - -#define c67x00_sie_config(config, n) (((config)>>(4*(n)))&0x3) - -#define C67X00_SIE1_UNUSED (C67X00_SIE_UNUSED << 0) -#define C67X00_SIE1_HOST (C67X00_SIE_HOST << 0) -#define C67X00_SIE1_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 0) -#define C67X00_SIE1_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 0) - -#define C67X00_SIE2_UNUSED (C67X00_SIE_UNUSED << 4) -#define C67X00_SIE2_HOST (C67X00_SIE_HOST << 4) -#define C67X00_SIE2_PERIPHERAL_A (C67X00_SIE_PERIPHERAL_A << 4) -#define C67X00_SIE2_PERIPHERAL_B (C67X00_SIE_PERIPHERAL_B << 4) - -struct c67x00_platform_data { - int sie_config; /* SIEs config (C67X00_SIEx_*) */ - unsigned long hpi_regstep; /* Step between HPI registers */ -}; - -#endif /* _LINUX_USB_C67X00_H */ diff --git a/trunk/include/linux/usb/ch9.h b/trunk/include/linux/usb/ch9.h index 73a2f4eb1f7a..7e0d3084f76c 100644 --- a/trunk/include/linux/usb/ch9.h +++ b/trunk/include/linux/usb/ch9.h @@ -455,7 +455,7 @@ struct usb_encryption_descriptor { /*-------------------------------------------------------------------------*/ -/* USB_DT_BOS: group of device-level capabilities */ +/* USB_DT_BOS: group of wireless capabilities */ struct usb_bos_descriptor { __u8 bLength; __u8 bDescriptorType; @@ -501,16 +501,6 @@ struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ __u8 bReserved; } __attribute__((packed)); -#define USB_CAP_TYPE_EXT 2 - -struct usb_ext_cap_descriptor { /* Link Power Management */ - __u8 bLength; - __u8 bDescriptorType; - __u8 bDevCapabilityType; - __u8 bmAttributes; -#define USB_LPM_SUPPORT (1 << 1) /* supports LPM */ -} __attribute__((packed)); - /*-------------------------------------------------------------------------*/ /* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with diff --git a/trunk/include/linux/usb/gadget.h b/trunk/include/linux/usb/gadget.h index cf468fbdbf8e..d8128f7102c9 100644 --- a/trunk/include/linux/usb/gadget.h +++ b/trunk/include/linux/usb/gadget.h @@ -114,8 +114,6 @@ struct usb_ep_ops { int (*dequeue) (struct usb_ep *ep, struct usb_request *req); int (*set_halt) (struct usb_ep *ep, int value); - int (*set_wedge) (struct usb_ep *ep); - int (*fifo_status) (struct usb_ep *ep); void (*fifo_flush) (struct usb_ep *ep); }; @@ -350,25 +348,6 @@ static inline int usb_ep_clear_halt(struct usb_ep *ep) return ep->ops->set_halt(ep, 0); } -/** - * usb_ep_set_wedge - sets the halt feature and ignores clear requests - * @ep: the endpoint being wedged - * - * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT) - * requests. If the gadget driver clears the halt status, it will - * automatically unwedge the endpoint. - * - * Returns zero on success, else negative errno. - */ -static inline int -usb_ep_set_wedge(struct usb_ep *ep) -{ - if (ep->ops->set_wedge) - return ep->ops->set_wedge(ep); - else - return ep->ops->set_halt(ep, 1); -} - /** * usb_ep_fifo_status - returns number of bytes in fifo, or error * @ep: the endpoint whose fifo status is being checked. diff --git a/trunk/include/linux/virtio.h b/trunk/include/linux/virtio.h index 06005fa9e982..e7d10845b3c1 100644 --- a/trunk/include/linux/virtio.h +++ b/trunk/include/linux/virtio.h @@ -76,7 +76,6 @@ struct virtqueue_ops { * @dev: underlying device. * @id: the device type identification (used to match it with a driver). * @config: the configuration ops for this device. - * @features: the features supported by both driver and device. * @priv: private pointer for the driver's use. */ struct virtio_device @@ -85,8 +84,6 @@ struct virtio_device struct device dev; struct virtio_device_id id; struct virtio_config_ops *config; - /* Note that this is a Linux set_bit-style bitmap. */ - unsigned long features[1]; void *priv; }; @@ -97,8 +94,6 @@ void unregister_virtio_device(struct virtio_device *dev); * virtio_driver - operations for a virtio I/O driver * @driver: underlying device driver (populate name and owner). * @id_table: the ids serviced by this driver. - * @feature_table: an array of feature numbers supported by this device. - * @feature_table_size: number of entries in the feature table array. * @probe: the function to call when a device is found. Returns a token for * remove, or PTR_ERR(). * @remove: the function when a device is removed. @@ -108,8 +103,6 @@ void unregister_virtio_device(struct virtio_device *dev); struct virtio_driver { struct device_driver driver; const struct virtio_device_id *id_table; - const unsigned int *feature_table; - unsigned int feature_table_size; int (*probe)(struct virtio_device *dev); void (*remove)(struct virtio_device *dev); void (*config_changed)(struct virtio_device *dev); diff --git a/trunk/include/linux/virtio_blk.h b/trunk/include/linux/virtio_blk.h index d4695a3356d0..bca0b10d7947 100644 --- a/trunk/include/linux/virtio_blk.h +++ b/trunk/include/linux/virtio_blk.h @@ -9,7 +9,6 @@ #define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ #define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */ #define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ -#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ struct virtio_blk_config { @@ -19,12 +18,6 @@ struct virtio_blk_config __le32 size_max; /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ __le32 seg_max; - /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ - struct virtio_blk_geometry { - __le16 cylinders; - __u8 heads; - __u8 sectors; - } geometry; } __attribute__((packed)); /* These two define direction. */ @@ -48,8 +41,13 @@ struct virtio_blk_outhdr __u64 sector; }; -/* And this is the final byte of the write scatter-gather list. */ #define VIRTIO_BLK_S_OK 0 #define VIRTIO_BLK_S_IOERR 1 #define VIRTIO_BLK_S_UNSUPP 2 + +/* This is the first element of the write scatter-gather list */ +struct virtio_blk_inhdr +{ + unsigned char status; +}; #endif /* _LINUX_VIRTIO_BLK_H */ diff --git a/trunk/include/linux/virtio_config.h b/trunk/include/linux/virtio_config.h index 50db245c81ad..d581b2914b34 100644 --- a/trunk/include/linux/virtio_config.h +++ b/trunk/include/linux/virtio_config.h @@ -16,20 +16,27 @@ #define VIRTIO_CONFIG_S_FAILED 0x80 #ifdef __KERNEL__ -#include +struct virtio_device; /** * virtio_config_ops - operations for configuring a virtio device + * @feature: search for a feature in this config + * vdev: the virtio_device + * bit: the feature bit + * Returns true if the feature is supported. Acknowledges the feature + * so the host can see it. * @get: read the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field * buf: the buffer to write the field value into. * len: the length of the buffer + * Note that contents are conventionally little-endian. * @set: write the value of a configuration field * vdev: the virtio_device * offset: the offset of the configuration field * buf: the buffer to read the field value from. * len: the length of the buffer + * Note that contents are conventionally little-endian. * @get_status: read the status byte * vdev: the virtio_device * Returns the status byte @@ -45,15 +52,10 @@ * callback: the virqtueue callback * Returns the new virtqueue or ERR_PTR() (eg. -ENOENT). * @del_vq: free a virtqueue found by find_vq(). - * @get_features: get the array of feature bits for this device. - * vdev: the virtio_device - * Returns the first 32 feature bits (all we currently need). - * @set_features: confirm what device features we'll be using. - * vdev: the virtio_device - * feature: the first 32 feature bits */ struct virtio_config_ops { + bool (*feature)(struct virtio_device *vdev, unsigned bit); void (*get)(struct virtio_device *vdev, unsigned offset, void *buf, unsigned len); void (*set)(struct virtio_device *vdev, unsigned offset, @@ -65,52 +67,43 @@ struct virtio_config_ops unsigned index, void (*callback)(struct virtqueue *)); void (*del_vq)(struct virtqueue *vq); - u32 (*get_features)(struct virtio_device *vdev); - void (*set_features)(struct virtio_device *vdev, u32 features); }; -/* If driver didn't advertise the feature, it will never appear. */ -void virtio_check_driver_offered_feature(const struct virtio_device *vdev, - unsigned int fbit); - /** - * virtio_has_feature - helper to determine if this device has this feature. - * @vdev: the device - * @fbit: the feature bit - */ -static inline bool virtio_has_feature(const struct virtio_device *vdev, - unsigned int fbit) -{ - /* Did you forget to fix assumptions on max features? */ - if (__builtin_constant_p(fbit)) - BUILD_BUG_ON(fbit >= 32); - - virtio_check_driver_offered_feature(vdev, fbit); - return test_bit(fbit, vdev->features); -} - -/** - * virtio_config_val - look for a feature and get a virtio config entry. + * virtio_config_val - look for a feature and get a single virtio config. * @vdev: the virtio device * @fbit: the feature bit * @offset: the type to search for. * @val: a pointer to the value to fill in. * * The return value is -ENOENT if the feature doesn't exist. Otherwise - * the config value is copied into whatever is pointed to by v. */ -#define virtio_config_val(vdev, fbit, offset, v) \ - virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(v)) - -static inline int virtio_config_buf(struct virtio_device *vdev, - unsigned int fbit, - unsigned int offset, - void *buf, unsigned len) -{ - if (!virtio_has_feature(vdev, fbit)) - return -ENOENT; + * the value is endian-corrected and returned in v. */ +#define virtio_config_val(vdev, fbit, offset, v) ({ \ + int _err; \ + if ((vdev)->config->feature((vdev), (fbit))) { \ + __virtio_config_val((vdev), (offset), (v)); \ + _err = 0; \ + } else \ + _err = -ENOENT; \ + _err; \ +}) - vdev->config->get(vdev, offset, buf, len); - return 0; -} +/** + * __virtio_config_val - get a single virtio config without feature check. + * @vdev: the virtio device + * @offset: the type to search for. + * @val: a pointer to the value to fill in. + * + * The value is endian-corrected and returned in v. */ +#define __virtio_config_val(vdev, offset, v) do { \ + BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \ + && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \ + (vdev)->config->get((vdev), (offset), (v), sizeof(*(v))); \ + switch (sizeof(*(v))) { \ + case 2: le16_to_cpus((__u16 *) v); break; \ + case 4: le32_to_cpus((__u32 *) v); break; \ + case 8: le64_to_cpus((__u64 *) v); break; \ + } \ +} while(0) #endif /* __KERNEL__ */ #endif /* _LINUX_VIRTIO_CONFIG_H */ diff --git a/trunk/include/linux/virtio_net.h b/trunk/include/linux/virtio_net.h index 9405aa6cdf26..1ea3351df609 100644 --- a/trunk/include/linux/virtio_net.h +++ b/trunk/include/linux/virtio_net.h @@ -6,18 +6,9 @@ #define VIRTIO_ID_NET 1 /* The feature bitmap for virtio net */ -#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ -#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ +#define VIRTIO_NET_F_CSUM 0 /* Can handle pkts w/ partial csum */ #define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ -#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ -#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ -#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ -#define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ -#define VIRTIO_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ -#define VIRTIO_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ -#define VIRTIO_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ -#define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */ -#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ +#define VIRTIO_NET_F_GSO 6 /* Can handle pkts w/ any GSO type */ struct virtio_net_config { diff --git a/trunk/kernel/compat.c b/trunk/kernel/compat.c index 32c254a8ab9a..4a856a3643bb 100644 --- a/trunk/kernel/compat.c +++ b/trunk/kernel/compat.c @@ -955,8 +955,7 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) __put_user(txc.jitcnt, &utp->jitcnt) || __put_user(txc.calcnt, &utp->calcnt) || __put_user(txc.errcnt, &utp->errcnt) || - __put_user(txc.stbcnt, &utp->stbcnt) || - __put_user(txc.tai, &utp->tai)) + __put_user(txc.stbcnt, &utp->stbcnt)) ret = -EFAULT; return ret; diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 46d6611a33bb..46e4ad1723f0 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -150,26 +150,6 @@ void disable_irq(unsigned int irq) } EXPORT_SYMBOL(disable_irq); -static void __enable_irq(struct irq_desc *desc, unsigned int irq) -{ - switch (desc->depth) { - case 0: - printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); - WARN_ON(1); - break; - case 1: { - unsigned int status = desc->status & ~IRQ_DISABLED; - - /* Prevent probing on this irq: */ - desc->status = status | IRQ_NOPROBE; - check_irq_resend(desc, irq); - /* fall-through */ - } - default: - desc->depth--; - } -} - /** * enable_irq - enable handling of an irq * @irq: Interrupt to enable @@ -189,7 +169,22 @@ void enable_irq(unsigned int irq) return; spin_lock_irqsave(&desc->lock, flags); - __enable_irq(desc, irq); + switch (desc->depth) { + case 0: + printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq); + WARN_ON(1); + break; + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + + /* Prevent probing on this irq: */ + desc->status = status | IRQ_NOPROBE; + check_irq_resend(desc, irq); + /* fall-through */ + } + default: + desc->depth--; + } spin_unlock_irqrestore(&desc->lock, flags); } EXPORT_SYMBOL(enable_irq); @@ -370,7 +365,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) compat_irq_chip_set_default_handler(desc); desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | - IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED); + IRQ_INPROGRESS); if (!(desc->status & IRQ_NOAUTOEN)) { desc->depth = 0; @@ -386,16 +381,6 @@ int setup_irq(unsigned int irq, struct irqaction *new) /* Reset broken irq detection when installing new handler */ desc->irq_count = 0; desc->irqs_unhandled = 0; - - /* - * Check whether we disabled the irq via the spurious handler - * before. Reenable it and give it another chance. - */ - if (shared && (desc->status & IRQ_SPURIOUS_DISABLED)) { - desc->status &= ~IRQ_SPURIOUS_DISABLED; - __enable_irq(desc, irq); - } - spin_unlock_irqrestore(&desc->lock, flags); new->irq = irq; diff --git a/trunk/kernel/irq/spurious.c b/trunk/kernel/irq/spurious.c index c66d3f10e853..088dabbf2d6a 100644 --- a/trunk/kernel/irq/spurious.c +++ b/trunk/kernel/irq/spurious.c @@ -209,8 +209,8 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, * Now kill the IRQ */ printk(KERN_EMERG "Disabling IRQ #%d\n", irq); - desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED; - desc->depth++; + desc->status |= IRQ_DISABLED; + desc->depth = 1; desc->chip->disable(irq); } desc->irqs_unhandled = 0; diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index 1c5fcacbcf33..cb85c79989b4 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -1217,7 +1217,7 @@ static int __init parse_crashkernel_mem(char *cmdline, } /* match ? */ - if (system_ram >= start && system_ram < end) { + if (system_ram >= start && system_ram <= end) { *crash_size = size; break; } diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 8674a390a2e8..8d6cccc6c3cf 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -164,140 +164,131 @@ static const struct kernel_symbol *lookup_symbol(const char *name, return NULL; } -static bool always_ok(bool gplok, bool warn, const char *name) +static void printk_unused_warning(const char *name) { - return true; + printk(KERN_WARNING "Symbol %s is marked as UNUSED, " + "however this module is using it.\n", name); + printk(KERN_WARNING "This symbol will go away in the future.\n"); + printk(KERN_WARNING "Please evalute if this is the right api to use, " + "and if it really is, submit a report the linux kernel " + "mailinglist together with submitting your code for " + "inclusion.\n"); } -static bool printk_unused_warning(bool gplok, bool warn, const char *name) +/* Find a symbol, return value, crc and module which owns it */ +static unsigned long __find_symbol(const char *name, + struct module **owner, + const unsigned long **crc, + int gplok) { - if (warn) { - printk(KERN_WARNING "Symbol %s is marked as UNUSED, " - "however this module is using it.\n", name); - printk(KERN_WARNING - "This symbol will go away in the future.\n"); - printk(KERN_WARNING - "Please evalute if this is the right api to use and if " - "it really is, submit a report the linux kernel " - "mailinglist together with submitting your code for " - "inclusion.\n"); - } - return true; -} - -static bool gpl_only_unused_warning(bool gplok, bool warn, const char *name) -{ - if (!gplok) - return false; - return printk_unused_warning(gplok, warn, name); -} - -static bool gpl_only(bool gplok, bool warn, const char *name) -{ - return gplok; -} - -static bool warn_if_not_gpl(bool gplok, bool warn, const char *name) -{ - if (!gplok && warn) { - printk(KERN_WARNING "Symbol %s is being used " - "by a non-GPL module, which will not " - "be allowed in the future\n", name); - printk(KERN_WARNING "Please see the file " - "Documentation/feature-removal-schedule.txt " - "in the kernel source tree for more details.\n"); - } - return true; -} - -struct symsearch { - const struct kernel_symbol *start, *stop; - const unsigned long *crcs; - bool (*check)(bool gplok, bool warn, const char *name); -}; - -/* Look through this array of symbol tables for a symbol match which - * passes the check function. */ -static const struct kernel_symbol *search_symarrays(const struct symsearch *arr, - unsigned int num, - const char *name, - bool gplok, - bool warn, - const unsigned long **crc) -{ - unsigned int i; + struct module *mod; const struct kernel_symbol *ks; - for (i = 0; i < num; i++) { - ks = lookup_symbol(name, arr[i].start, arr[i].stop); - if (!ks || !arr[i].check(gplok, warn, name)) - continue; - - if (crc) - *crc = symversion(arr[i].crcs, ks - arr[i].start); - return ks; + /* Core kernel first. */ + *owner = NULL; + ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); + if (ks) { + *crc = symversion(__start___kcrctab, (ks - __start___ksymtab)); + return ks->value; + } + if (gplok) { + ks = lookup_symbol(name, __start___ksymtab_gpl, + __stop___ksymtab_gpl); + if (ks) { + *crc = symversion(__start___kcrctab_gpl, + (ks - __start___ksymtab_gpl)); + return ks->value; + } + } + ks = lookup_symbol(name, __start___ksymtab_gpl_future, + __stop___ksymtab_gpl_future); + if (ks) { + if (!gplok) { + printk(KERN_WARNING "Symbol %s is being used " + "by a non-GPL module, which will not " + "be allowed in the future\n", name); + printk(KERN_WARNING "Please see the file " + "Documentation/feature-removal-schedule.txt " + "in the kernel source tree for more " + "details.\n"); + } + *crc = symversion(__start___kcrctab_gpl_future, + (ks - __start___ksymtab_gpl_future)); + return ks->value; } - return NULL; -} -/* Find a symbol, return value, (optional) crc and (optional) module - * which owns it */ -static unsigned long find_symbol(const char *name, - struct module **owner, - const unsigned long **crc, - bool gplok, - bool warn) -{ - struct module *mod; - const struct kernel_symbol *ks; - const struct symsearch arr[] = { - { __start___ksymtab, __stop___ksymtab, __start___kcrctab, - always_ok }, - { __start___ksymtab_gpl, __stop___ksymtab_gpl, - __start___kcrctab_gpl, gpl_only }, - { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future, - __start___kcrctab_gpl_future, warn_if_not_gpl }, - { __start___ksymtab_unused, __stop___ksymtab_unused, - __start___kcrctab_unused, printk_unused_warning }, - { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl, - __start___kcrctab_unused_gpl, gpl_only_unused_warning }, - }; + ks = lookup_symbol(name, __start___ksymtab_unused, + __stop___ksymtab_unused); + if (ks) { + printk_unused_warning(name); + *crc = symversion(__start___kcrctab_unused, + (ks - __start___ksymtab_unused)); + return ks->value; + } - /* Core kernel first. */ - ks = search_symarrays(arr, ARRAY_SIZE(arr), name, gplok, warn, crc); + if (gplok) + ks = lookup_symbol(name, __start___ksymtab_unused_gpl, + __stop___ksymtab_unused_gpl); if (ks) { - if (owner) - *owner = NULL; + printk_unused_warning(name); + *crc = symversion(__start___kcrctab_unused_gpl, + (ks - __start___ksymtab_unused_gpl)); return ks->value; } /* Now try modules. */ list_for_each_entry(mod, &modules, list) { - struct symsearch arr[] = { - { mod->syms, mod->syms + mod->num_syms, mod->crcs, - always_ok }, - { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms, - mod->gpl_crcs, gpl_only }, - { mod->gpl_future_syms, - mod->gpl_future_syms + mod->num_gpl_future_syms, - mod->gpl_future_crcs, warn_if_not_gpl }, - { mod->unused_syms, - mod->unused_syms + mod->num_unused_syms, - mod->unused_crcs, printk_unused_warning }, - { mod->unused_gpl_syms, - mod->unused_gpl_syms + mod->num_unused_gpl_syms, - mod->unused_gpl_crcs, gpl_only_unused_warning }, - }; - - ks = search_symarrays(arr, ARRAY_SIZE(arr), - name, gplok, warn, crc); + *owner = mod; + ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); if (ks) { - if (owner) - *owner = mod; + *crc = symversion(mod->crcs, (ks - mod->syms)); return ks->value; } - } + if (gplok) { + ks = lookup_symbol(name, mod->gpl_syms, + mod->gpl_syms + mod->num_gpl_syms); + if (ks) { + *crc = symversion(mod->gpl_crcs, + (ks - mod->gpl_syms)); + return ks->value; + } + } + ks = lookup_symbol(name, mod->unused_syms, mod->unused_syms + mod->num_unused_syms); + if (ks) { + printk_unused_warning(name); + *crc = symversion(mod->unused_crcs, (ks - mod->unused_syms)); + return ks->value; + } + + if (gplok) { + ks = lookup_symbol(name, mod->unused_gpl_syms, + mod->unused_gpl_syms + mod->num_unused_gpl_syms); + if (ks) { + printk_unused_warning(name); + *crc = symversion(mod->unused_gpl_crcs, + (ks - mod->unused_gpl_syms)); + return ks->value; + } + } + ks = lookup_symbol(name, mod->gpl_future_syms, + (mod->gpl_future_syms + + mod->num_gpl_future_syms)); + if (ks) { + if (!gplok) { + printk(KERN_WARNING "Symbol %s is being used " + "by a non-GPL module, which will not " + "be allowed in the future\n", name); + printk(KERN_WARNING "Please see the file " + "Documentation/feature-removal-schedule.txt " + "in the kernel source tree for more " + "details.\n"); + } + *crc = symversion(mod->gpl_future_crcs, + (ks - mod->gpl_future_syms)); + return ks->value; + } + } DEBUGP("Failed to find symbol %s\n", name); return -ENOENT; } @@ -745,13 +736,12 @@ sys_delete_module(const char __user *name_user, unsigned int flags) if (!forced && module_refcount(mod) != 0) wait_for_zero_refcount(mod); - mutex_unlock(&module_mutex); /* Final destruction now noone is using it. */ - if (mod->exit != NULL) + if (mod->exit != NULL) { + mutex_unlock(&module_mutex); mod->exit(); - blocking_notifier_call_chain(&module_notify_list, - MODULE_STATE_GOING, mod); - mutex_lock(&module_mutex); + mutex_lock(&module_mutex); + } /* Store the name of the last unloaded module for diagnostic purposes */ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); free_module(mod); @@ -787,9 +777,10 @@ static void print_unload_info(struct seq_file *m, struct module *mod) void __symbol_put(const char *symbol) { struct module *owner; + const unsigned long *crc; preempt_disable(); - if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false))) + if (IS_ERR_VALUE(__find_symbol(symbol, &owner, &crc, 1))) BUG(); module_put(owner); preempt_enable(); @@ -933,10 +924,13 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, struct module *mod) { const unsigned long *crc; + struct module *owner; - if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false))) + if (IS_ERR_VALUE(__find_symbol("struct_module", + &owner, &crc, 1))) BUG(); - return check_version(sechdrs, versindex, "struct_module", mod, crc); + return check_version(sechdrs, versindex, "struct_module", mod, + crc); } /* First part is kernel version, which we ignore. */ @@ -980,8 +974,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, unsigned long ret; const unsigned long *crc; - ret = find_symbol(name, &owner, &crc, - !(mod->taints & TAINT_PROPRIETARY_MODULE), true); + ret = __find_symbol(name, &owner, &crc, + !(mod->taints & TAINT_PROPRIETARY_MODULE)); if (!IS_ERR_VALUE(ret)) { /* use_module can fail due to OOM, or module initialization or unloading */ @@ -997,20 +991,6 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, * J. Corbet */ #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) -struct module_sect_attr -{ - struct module_attribute mattr; - char *name; - unsigned long address; -}; - -struct module_sect_attrs -{ - struct attribute_group grp; - unsigned int nsections; - struct module_sect_attr attrs[0]; -}; - static ssize_t module_sect_show(struct module_attribute *mattr, struct module *mod, char *buf) { @@ -1021,7 +1001,7 @@ static ssize_t module_sect_show(struct module_attribute *mattr, static void free_sect_attrs(struct module_sect_attrs *sect_attrs) { - unsigned int section; + int section; for (section = 0; section < sect_attrs->nsections; section++) kfree(sect_attrs->attrs[section].name); @@ -1382,9 +1362,10 @@ void *__symbol_get(const char *symbol) { struct module *owner; unsigned long value; + const unsigned long *crc; preempt_disable(); - value = find_symbol(symbol, &owner, NULL, true, true); + value = __find_symbol(symbol, &owner, &crc, 1); if (IS_ERR_VALUE(value)) value = 0; else if (strong_try_module_get(owner)) @@ -1401,33 +1382,33 @@ EXPORT_SYMBOL_GPL(__symbol_get); */ static int verify_export_symbols(struct module *mod) { - unsigned int i; + const char *name = NULL; + unsigned long i, ret = 0; struct module *owner; - const struct kernel_symbol *s; - struct { - const struct kernel_symbol *sym; - unsigned int num; - } arr[] = { - { mod->syms, mod->num_syms }, - { mod->gpl_syms, mod->num_gpl_syms }, - { mod->gpl_future_syms, mod->num_gpl_future_syms }, - { mod->unused_syms, mod->num_unused_syms }, - { mod->unused_gpl_syms, mod->num_unused_gpl_syms }, - }; + const unsigned long *crc; - for (i = 0; i < ARRAY_SIZE(arr); i++) { - for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) { - if (!IS_ERR_VALUE(find_symbol(s->name, &owner, - NULL, true, false))) { - printk(KERN_ERR - "%s: exports duplicate symbol %s" - " (owned by %s)\n", - mod->name, s->name, module_name(owner)); - return -ENOEXEC; - } + for (i = 0; i < mod->num_syms; i++) + if (!IS_ERR_VALUE(__find_symbol(mod->syms[i].name, + &owner, &crc, 1))) { + name = mod->syms[i].name; + ret = -ENOEXEC; + goto dup; } - } - return 0; + + for (i = 0; i < mod->num_gpl_syms; i++) + if (!IS_ERR_VALUE(__find_symbol(mod->gpl_syms[i].name, + &owner, &crc, 1))) { + name = mod->gpl_syms[i].name; + ret = -ENOEXEC; + goto dup; + } + +dup: + if (ret) + printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n", + mod->name, name, module_name(owner)); + + return ret; } /* Change all symbols so that st_value encodes the pointer directly. */ @@ -1833,9 +1814,8 @@ static struct module *load_module(void __user *umod, unwindex = find_sec(hdr, sechdrs, secstrings, ARCH_UNWIND_SECTION_NAME); #endif - /* Don't keep modinfo and version sections. */ + /* Don't keep modinfo section */ sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; - sechdrs[versindex].sh_flags &= ~(unsigned long)SHF_ALLOC; #ifdef CONFIG_KALLSYMS /* Keep symbol and string tables for decoding later. */ sechdrs[symindex].sh_flags |= SHF_ALLOC; @@ -1997,8 +1977,7 @@ static struct module *load_module(void __user *umod, mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr; mod->unused_gpl_syms = (void *)sechdrs[unusedgplindex].sh_addr; if (unusedgplcrcindex) - mod->unused_gpl_crcs - = (void *)sechdrs[unusedgplcrcindex].sh_addr; + mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr; #ifdef CONFIG_MODVERSIONS if ((mod->num_syms && !crcindex) || @@ -2192,8 +2171,6 @@ sys_init_module(void __user *umod, mod->state = MODULE_STATE_GOING; synchronize_sched(); module_put(mod); - blocking_notifier_call_chain(&module_notify_list, - MODULE_STATE_GOING, mod); mutex_lock(&module_mutex); free_module(mod); mutex_unlock(&module_mutex); diff --git a/trunk/kernel/posix-cpu-timers.c b/trunk/kernel/posix-cpu-timers.c index f1525ad06cb3..ae5c6c147c4b 100644 --- a/trunk/kernel/posix-cpu-timers.c +++ b/trunk/kernel/posix-cpu-timers.c @@ -4,9 +4,8 @@ #include #include -#include -#include #include +#include static int check_clock(const clockid_t which_clock) { @@ -48,10 +47,12 @@ static void sample_to_timespec(const clockid_t which_clock, union cpu_time_count cpu, struct timespec *tp) { - if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) - *tp = ns_to_timespec(cpu.sched); - else + if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { + tp->tv_sec = div_long_long_rem(cpu.sched, + NSEC_PER_SEC, &tp->tv_nsec); + } else { cputime_to_timespec(cpu.cpu, tp); + } } static inline int cpu_time_before(const clockid_t which_clock, diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 6c19e94fd0a5..dcc199c43a12 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -534,6 +534,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid) #define arch_ptrace_attach(child) do { } while (0) #endif +#ifndef __ARCH_SYS_PTRACE asmlinkage long sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -581,6 +582,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data) unlock_kernel(); return ret; } +#endif /* __ARCH_SYS_PTRACE */ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) { diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 34bcc5bc120e..e2f7f5acc807 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -8025,7 +8025,7 @@ static void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq, se->my_q = cfs_rq; se->load.weight = tg->shares; - se->load.inv_weight = div64_u64(1ULL<<32, se->load.weight); + se->load.inv_weight = div64_64(1ULL<<32, se->load.weight); se->parent = parent; } #endif @@ -8692,7 +8692,7 @@ static void __set_se_shares(struct sched_entity *se, unsigned long shares) dequeue_entity(cfs_rq, se, 0); se->load.weight = shares; - se->load.inv_weight = div64_u64((1ULL<<32), shares); + se->load.inv_weight = div64_64((1ULL<<32), shares); if (on_rq) enqueue_entity(cfs_rq, se, 0); @@ -8787,7 +8787,7 @@ static unsigned long to_ratio(u64 period, u64 runtime) if (runtime == RUNTIME_INF) return 1ULL << 16; - return div64_u64(runtime << 16, period); + return div64_64(runtime << 16, period); } #ifdef CONFIG_CGROUP_SCHED diff --git a/trunk/kernel/sched_debug.c b/trunk/kernel/sched_debug.c index 6b4a12558e88..8a9498e7c831 100644 --- a/trunk/kernel/sched_debug.c +++ b/trunk/kernel/sched_debug.c @@ -357,8 +357,8 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) avg_per_cpu = p->se.sum_exec_runtime; if (p->se.nr_migrations) { - avg_per_cpu = div64_u64(avg_per_cpu, - p->se.nr_migrations); + avg_per_cpu = div64_64(avg_per_cpu, + p->se.nr_migrations); } else { avg_per_cpu = -1LL; } diff --git a/trunk/kernel/softirq.c b/trunk/kernel/softirq.c index 36e061740047..3c44956ee7e2 100644 --- a/trunk/kernel/softirq.c +++ b/trunk/kernel/softirq.c @@ -589,20 +589,16 @@ static void takeover_tasklets(unsigned int cpu) local_irq_disable(); /* Find end, append list for that CPU. */ - if (&per_cpu(tasklet_vec, cpu).head != per_cpu(tasklet_vec, cpu).tail) { - *(__get_cpu_var(tasklet_vec).tail) = per_cpu(tasklet_vec, cpu).head; - __get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).tail; - per_cpu(tasklet_vec, cpu).head = NULL; - per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head; - } + *__get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).head; + __get_cpu_var(tasklet_vec).tail = per_cpu(tasklet_vec, cpu).tail; + per_cpu(tasklet_vec, cpu).head = NULL; + per_cpu(tasklet_vec, cpu).tail = &per_cpu(tasklet_vec, cpu).head; raise_softirq_irqoff(TASKLET_SOFTIRQ); - if (&per_cpu(tasklet_hi_vec, cpu).head != per_cpu(tasklet_hi_vec, cpu).tail) { - *__get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).head; - __get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).tail; - per_cpu(tasklet_hi_vec, cpu).head = NULL; - per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head; - } + *__get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).head; + __get_cpu_var(tasklet_hi_vec).tail = per_cpu(tasklet_hi_vec, cpu).tail; + per_cpu(tasklet_hi_vec, cpu).head = NULL; + per_cpu(tasklet_hi_vec, cpu).tail = &per_cpu(tasklet_hi_vec, cpu).head; raise_softirq_irqoff(HI_SOFTIRQ); local_irq_enable(); diff --git a/trunk/kernel/time.c b/trunk/kernel/time.c index cbe0d5a222ff..86729042e4cd 100644 --- a/trunk/kernel/time.c +++ b/trunk/kernel/time.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -392,17 +391,13 @@ EXPORT_SYMBOL(set_normalized_timespec); struct timespec ns_to_timespec(const s64 nsec) { struct timespec ts; - s32 rem; if (!nsec) return (struct timespec) {0, 0}; - ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem); - if (unlikely(rem < 0)) { - ts.tv_sec--; - rem += NSEC_PER_SEC; - } - ts.tv_nsec = rem; + ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec); + if (unlikely(nsec < 0)) + set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec); return ts; } @@ -532,10 +527,8 @@ jiffies_to_timespec(const unsigned long jiffies, struct timespec *value) * Convert jiffies to nanoseconds and separate with * one divide. */ - u32 rem; - value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC, - NSEC_PER_SEC, &rem); - value->tv_nsec = rem; + u64 nsec = (u64)jiffies * TICK_NSEC; + value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_nsec); } EXPORT_SYMBOL(jiffies_to_timespec); @@ -573,11 +566,12 @@ void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value) * Convert jiffies to nanoseconds and separate with * one divide. */ - u32 rem; + u64 nsec = (u64)jiffies * TICK_NSEC; + long tv_usec; - value->tv_sec = div_u64_rem((u64)jiffies * TICK_NSEC, - NSEC_PER_SEC, &rem); - value->tv_usec = rem / NSEC_PER_USEC; + value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec); + tv_usec /= NSEC_PER_USEC; + value->tv_usec = tv_usec; } EXPORT_SYMBOL(jiffies_to_timeval); @@ -593,7 +587,9 @@ clock_t jiffies_to_clock_t(long x) return x / (HZ / USER_HZ); # endif #else - return div_u64((u64)x * TICK_NSEC, NSEC_PER_SEC / USER_HZ); + u64 tmp = (u64)x * TICK_NSEC; + do_div(tmp, (NSEC_PER_SEC / USER_HZ)); + return (long)tmp; #endif } EXPORT_SYMBOL(jiffies_to_clock_t); @@ -605,12 +601,16 @@ unsigned long clock_t_to_jiffies(unsigned long x) return ~0UL; return x * (HZ / USER_HZ); #else + u64 jif; + /* Don't worry about loss of precision here .. */ if (x >= ~0UL / HZ * USER_HZ) return ~0UL; /* .. but do try to contain it here */ - return div_u64((u64)x * HZ, USER_HZ); + jif = x * (u64) HZ; + do_div(jif, USER_HZ); + return jif; #endif } EXPORT_SYMBOL(clock_t_to_jiffies); @@ -619,9 +619,10 @@ u64 jiffies_64_to_clock_t(u64 x) { #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 # if HZ < USER_HZ - x = div_u64(x * USER_HZ, HZ); + x *= USER_HZ; + do_div(x, HZ); # elif HZ > USER_HZ - x = div_u64(x, HZ / USER_HZ); + do_div(x, HZ / USER_HZ); # else /* Nothing to do */ # endif @@ -631,7 +632,8 @@ u64 jiffies_64_to_clock_t(u64 x) * but even this doesn't overflow in hundreds of years * in 64 bits, so.. */ - x = div_u64(x * TICK_NSEC, (NSEC_PER_SEC / USER_HZ)); + x *= TICK_NSEC; + do_div(x, (NSEC_PER_SEC / USER_HZ)); #endif return x; } @@ -640,17 +642,21 @@ EXPORT_SYMBOL(jiffies_64_to_clock_t); u64 nsec_to_clock_t(u64 x) { #if (NSEC_PER_SEC % USER_HZ) == 0 - return div_u64(x, NSEC_PER_SEC / USER_HZ); + do_div(x, (NSEC_PER_SEC / USER_HZ)); #elif (USER_HZ % 512) == 0 - return div_u64(x * USER_HZ / 512, NSEC_PER_SEC / 512); + x *= USER_HZ/512; + do_div(x, (NSEC_PER_SEC / 512)); #else /* * max relative error 5.7e-8 (1.8s per year) for USER_HZ <= 1024, * overflow after 64.99 years. * exact for HZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ... */ - return div_u64(x * 9, (9ull * NSEC_PER_SEC + (USER_HZ / 2)) / USER_HZ); + x *= 9; + do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (USER_HZ/2)) / + USER_HZ)); #endif + return x; } #if (BITS_PER_LONG < 64) diff --git a/trunk/kernel/time/ntp.c b/trunk/kernel/time/ntp.c index 5125ddd8196b..5fd9b9469770 100644 --- a/trunk/kernel/time/ntp.c +++ b/trunk/kernel/time/ntp.c @@ -15,8 +15,7 @@ #include #include #include -#include -#include +#include #include /* @@ -24,14 +23,11 @@ */ unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */ unsigned long tick_nsec; /* ACTHZ period (nsec) */ -u64 tick_length; -static u64 tick_length_base; - -static struct hrtimer leap_timer; +static u64 tick_length, tick_length_base; #define MAX_TICKADJ 500 /* microsecs */ #define MAX_TICKADJ_SCALED (((u64)(MAX_TICKADJ * NSEC_PER_USEC) << \ - NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) + TICK_LENGTH_SHIFT) / NTP_INTERVAL_FREQ) /* * phase-lock loop variables @@ -39,12 +35,11 @@ static struct hrtimer leap_timer; /* TIME_ERROR prevents overwriting the CMOS clock */ static int time_state = TIME_OK; /* clock synchronization status */ int time_status = STA_UNSYNC; /* clock status bits */ -static long time_tai; /* TAI offset (s) */ -static s64 time_offset; /* time adjustment (ns) */ +static s64 time_offset; /* time adjustment (ns) */ static long time_constant = 2; /* pll time constant */ long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ -static s64 time_freq; /* frequency offset (scaled ns/s)*/ +long time_freq; /* frequency offset (scaled ppm)*/ static long time_reftime; /* time at last adjustment (s) */ long time_adjust; static long ntp_tick_adj; @@ -52,56 +47,16 @@ static long ntp_tick_adj; static void ntp_update_frequency(void) { u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) - << NTP_SCALE_SHIFT; - second_length += (s64)ntp_tick_adj << NTP_SCALE_SHIFT; - second_length += time_freq; + << TICK_LENGTH_SHIFT; + second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT; + second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); tick_length_base = second_length; - tick_nsec = div_u64(second_length, HZ) >> NTP_SCALE_SHIFT; - tick_length_base = div_u64(tick_length_base, NTP_INTERVAL_FREQ); -} - -static void ntp_update_offset(long offset) -{ - long mtemp; - s64 freq_adj; - - if (!(time_status & STA_PLL)) - return; + do_div(second_length, HZ); + tick_nsec = second_length >> TICK_LENGTH_SHIFT; - if (!(time_status & STA_NANO)) - offset *= NSEC_PER_USEC; - - /* - * Scale the phase adjustment and - * clamp to the operating range. - */ - offset = min(offset, MAXPHASE); - offset = max(offset, -MAXPHASE); - - /* - * Select how the frequency is to be controlled - * and in which mode (PLL or FLL). - */ - if (time_status & STA_FREQHOLD || time_reftime == 0) - time_reftime = xtime.tv_sec; - mtemp = xtime.tv_sec - time_reftime; - time_reftime = xtime.tv_sec; - - freq_adj = (s64)offset * mtemp; - freq_adj <<= NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + time_constant); - time_status &= ~STA_MODE; - if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { - freq_adj += div_s64((s64)offset << (NTP_SCALE_SHIFT - SHIFT_FLL), - mtemp); - time_status |= STA_MODE; - } - freq_adj += time_freq; - freq_adj = min(freq_adj, MAXFREQ_SCALED); - time_freq = max(freq_adj, -MAXFREQ_SCALED); - - time_offset = div_s64((s64)offset << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ); + do_div(tick_length_base, NTP_INTERVAL_FREQ); } /** @@ -123,70 +78,62 @@ void ntp_clear(void) } /* - * Leap second processing. If in leap-insert state at the end of the - * day, the system clock is set back one second; if in leap-delete - * state, the system clock is set ahead one second. + * this routine handles the overflow of the microsecond field + * + * The tricky bits of code to handle the accurate clock support + * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. + * They were originally developed for SUN and DEC kernels. + * All the kudos should go to Dave for this stuff. */ -static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer) +void second_overflow(void) { - enum hrtimer_restart res = HRTIMER_NORESTART; + long time_adj; - write_seqlock_irq(&xtime_lock); + /* Bump the maxerror field */ + time_maxerror += MAXFREQ >> SHIFT_USEC; + if (time_maxerror > NTP_PHASE_LIMIT) { + time_maxerror = NTP_PHASE_LIMIT; + time_status |= STA_UNSYNC; + } + /* + * Leap second processing. If in leap-insert state at the end of the + * day, the system clock is set back one second; if in leap-delete + * state, the system clock is set ahead one second. The microtime() + * routine or external clock driver will insure that reported time is + * always monotonic. The ugly divides should be replaced. + */ switch (time_state) { case TIME_OK: + if (time_status & STA_INS) + time_state = TIME_INS; + else if (time_status & STA_DEL) + time_state = TIME_DEL; break; case TIME_INS: - xtime.tv_sec--; - wall_to_monotonic.tv_sec++; - time_state = TIME_OOP; - printk(KERN_NOTICE "Clock: " - "inserting leap second 23:59:60 UTC\n"); - leap_timer.expires = ktime_add_ns(leap_timer.expires, - NSEC_PER_SEC); - res = HRTIMER_RESTART; + if (xtime.tv_sec % 86400 == 0) { + xtime.tv_sec--; + wall_to_monotonic.tv_sec++; + time_state = TIME_OOP; + printk(KERN_NOTICE "Clock: inserting leap second " + "23:59:60 UTC\n"); + } break; case TIME_DEL: - xtime.tv_sec++; - time_tai--; - wall_to_monotonic.tv_sec--; - time_state = TIME_WAIT; - printk(KERN_NOTICE "Clock: " - "deleting leap second 23:59:59 UTC\n"); + if ((xtime.tv_sec + 1) % 86400 == 0) { + xtime.tv_sec++; + wall_to_monotonic.tv_sec--; + time_state = TIME_WAIT; + printk(KERN_NOTICE "Clock: deleting leap second " + "23:59:59 UTC\n"); + } break; case TIME_OOP: - time_tai++; time_state = TIME_WAIT; - /* fall through */ + break; case TIME_WAIT: if (!(time_status & (STA_INS | STA_DEL))) - time_state = TIME_OK; - break; - } - update_vsyscall(&xtime, clock); - - write_sequnlock_irq(&xtime_lock); - - return res; -} - -/* - * this routine handles the overflow of the microsecond field - * - * The tricky bits of code to handle the accurate clock support - * were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame. - * They were originally developed for SUN and DEC kernels. - * All the kudos should go to Dave for this stuff. - */ -void second_overflow(void) -{ - s64 time_adj; - - /* Bump the maxerror field */ - time_maxerror += MAXFREQ / NSEC_PER_USEC; - if (time_maxerror > NTP_PHASE_LIMIT) { - time_maxerror = NTP_PHASE_LIMIT; - time_status |= STA_UNSYNC; + time_state = TIME_OK; } /* @@ -196,7 +143,7 @@ void second_overflow(void) tick_length = tick_length_base; time_adj = shift_right(time_offset, SHIFT_PLL + time_constant); time_offset -= time_adj; - tick_length += time_adj; + tick_length += (s64)time_adj << (TICK_LENGTH_SHIFT - SHIFT_UPDATE); if (unlikely(time_adjust)) { if (time_adjust > MAX_TICKADJ) { @@ -207,12 +154,25 @@ void second_overflow(void) tick_length -= MAX_TICKADJ_SCALED; } else { tick_length += (s64)(time_adjust * NSEC_PER_USEC / - NTP_INTERVAL_FREQ) << NTP_SCALE_SHIFT; + NTP_INTERVAL_FREQ) << TICK_LENGTH_SHIFT; time_adjust = 0; } } } +/* + * Return how long ticks are at the moment, that is, how much time + * update_wall_time_one_tick will add to xtime next time we call it + * (assuming no calls to do_adjtimex in the meantime). + * The return value is in fixed-point nanoseconds shifted by the + * specified number of bits to the right of the binary point. + * This function has no side-effects. + */ +u64 current_tick_length(void) +{ + return tick_length; +} + #ifdef CONFIG_GENERIC_CMOS_UPDATE /* Disable the cmos update - used by virtualization and embedded */ @@ -276,8 +236,8 @@ static inline void notify_cmos_timer(void) { } */ int do_adjtimex(struct timex *txc) { - struct timespec ts; - long save_adjust, sec; + long mtemp, save_adjust, rem; + s64 freq_adj, temp64; int result; /* In order to modify anything, you gotta be super-user! */ @@ -287,132 +247,147 @@ int do_adjtimex(struct timex *txc) /* Now we validate the data before disabling interrupts */ if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) { - /* singleshot must not be used with any other mode bits */ - if (txc->modes & ~ADJ_OFFSET_SS_READ) + /* singleshot must not be used with any other mode bits */ + if (txc->modes != ADJ_OFFSET_SINGLESHOT && + txc->modes != ADJ_OFFSET_SS_READ) return -EINVAL; } + if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET)) + /* adjustment Offset limited to +- .512 seconds */ + if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE ) + return -EINVAL; + /* if the quartz is off by more than 10% something is VERY wrong ! */ if (txc->modes & ADJ_TICK) if (txc->tick < 900000/USER_HZ || txc->tick > 1100000/USER_HZ) return -EINVAL; - if (time_state != TIME_OK && txc->modes & ADJ_STATUS) - hrtimer_cancel(&leap_timer); - getnstimeofday(&ts); - write_seqlock_irq(&xtime_lock); + result = time_state; /* mostly `TIME_OK' */ /* Save for later - semantics of adjtime is to return old value */ save_adjust = time_adjust; +#if 0 /* STA_CLOCKERR is never set yet */ + time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */ +#endif /* If there are input parameters, then process them */ - if (txc->modes) { - if (txc->modes & ADJ_STATUS) { - if ((time_status & STA_PLL) && - !(txc->status & STA_PLL)) { - time_state = TIME_OK; - time_status = STA_UNSYNC; - } - /* only set allowed bits */ - time_status &= STA_RONLY; - time_status |= txc->status & ~STA_RONLY; - - switch (time_state) { - case TIME_OK: - start_timer: - sec = ts.tv_sec; - if (time_status & STA_INS) { - time_state = TIME_INS; - sec += 86400 - sec % 86400; - hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS); - } else if (time_status & STA_DEL) { - time_state = TIME_DEL; - sec += 86400 - (sec + 1) % 86400; - hrtimer_start(&leap_timer, ktime_set(sec, 0), HRTIMER_MODE_ABS); - } - break; - case TIME_INS: - case TIME_DEL: - time_state = TIME_OK; - goto start_timer; - break; - case TIME_WAIT: - if (!(time_status & (STA_INS | STA_DEL))) - time_state = TIME_OK; - break; - case TIME_OOP: - hrtimer_restart(&leap_timer); - break; - } + if (txc->modes) + { + if (txc->modes & ADJ_STATUS) /* only set allowed bits */ + time_status = (txc->status & ~STA_RONLY) | + (time_status & STA_RONLY); + + if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */ + if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) { + result = -EINVAL; + goto leave; } - - if (txc->modes & ADJ_NANO) - time_status |= STA_NANO; - if (txc->modes & ADJ_MICRO) - time_status &= ~STA_NANO; - - if (txc->modes & ADJ_FREQUENCY) { - time_freq = (s64)txc->freq * PPM_SCALE; - time_freq = min(time_freq, MAXFREQ_SCALED); - time_freq = max(time_freq, -MAXFREQ_SCALED); + time_freq = ((s64)txc->freq * NSEC_PER_USEC) + >> (SHIFT_USEC - SHIFT_NSEC); + } + + if (txc->modes & ADJ_MAXERROR) { + if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) { + result = -EINVAL; + goto leave; } + time_maxerror = txc->maxerror; + } - if (txc->modes & ADJ_MAXERROR) - time_maxerror = txc->maxerror; - if (txc->modes & ADJ_ESTERROR) - time_esterror = txc->esterror; - - if (txc->modes & ADJ_TIMECONST) { - time_constant = txc->constant; - if (!(time_status & STA_NANO)) - time_constant += 4; - time_constant = min(time_constant, (long)MAXTC); - time_constant = max(time_constant, 0l); + if (txc->modes & ADJ_ESTERROR) { + if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) { + result = -EINVAL; + goto leave; } + time_esterror = txc->esterror; + } - if (txc->modes & ADJ_TAI && txc->constant > 0) - time_tai = txc->constant; - - if (txc->modes & ADJ_OFFSET) { - if (txc->modes == ADJ_OFFSET_SINGLESHOT) - /* adjtime() is independent from ntp_adjtime() */ - time_adjust = txc->offset; - else - ntp_update_offset(txc->offset); + if (txc->modes & ADJ_TIMECONST) { /* p. 24 */ + if (txc->constant < 0) { /* NTP v4 uses values > 6 */ + result = -EINVAL; + goto leave; } - if (txc->modes & ADJ_TICK) - tick_usec = txc->tick; + time_constant = min(txc->constant + 4, (long)MAXTC); + } - if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) - ntp_update_frequency(); - } - - result = time_state; /* mostly `TIME_OK' */ - if (time_status & (STA_UNSYNC|STA_CLOCKERR)) + if (txc->modes & ADJ_OFFSET) { /* values checked earlier */ + if (txc->modes == ADJ_OFFSET_SINGLESHOT) { + /* adjtime() is independent from ntp_adjtime() */ + time_adjust = txc->offset; + } + else if (time_status & STA_PLL) { + time_offset = txc->offset * NSEC_PER_USEC; + + /* + * Scale the phase adjustment and + * clamp to the operating range. + */ + time_offset = min(time_offset, (s64)MAXPHASE * NSEC_PER_USEC); + time_offset = max(time_offset, (s64)-MAXPHASE * NSEC_PER_USEC); + + /* + * Select whether the frequency is to be controlled + * and in which mode (PLL or FLL). Clamp to the operating + * range. Ugly multiply/divide should be replaced someday. + */ + + if (time_status & STA_FREQHOLD || time_reftime == 0) + time_reftime = xtime.tv_sec; + mtemp = xtime.tv_sec - time_reftime; + time_reftime = xtime.tv_sec; + + freq_adj = time_offset * mtemp; + freq_adj = shift_right(freq_adj, time_constant * 2 + + (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); + if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { + u64 utemp64; + temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); + if (time_offset < 0) { + utemp64 = -temp64; + do_div(utemp64, mtemp); + freq_adj -= utemp64; + } else { + utemp64 = temp64; + do_div(utemp64, mtemp); + freq_adj += utemp64; + } + } + freq_adj += time_freq; + freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); + time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC); + time_offset = div_long_long_rem_signed(time_offset, + NTP_INTERVAL_FREQ, + &rem); + time_offset <<= SHIFT_UPDATE; + } /* STA_PLL */ + } /* txc->modes & ADJ_OFFSET */ + if (txc->modes & ADJ_TICK) + tick_usec = txc->tick; + + if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) + ntp_update_frequency(); + } /* txc->modes */ +leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) result = TIME_ERROR; if ((txc->modes == ADJ_OFFSET_SINGLESHOT) || - (txc->modes == ADJ_OFFSET_SS_READ)) + (txc->modes == ADJ_OFFSET_SS_READ)) txc->offset = save_adjust; - else { - txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, - NTP_SCALE_SHIFT); - if (!(time_status & STA_NANO)) - txc->offset /= NSEC_PER_USEC; - } - txc->freq = shift_right((s32)(time_freq >> PPM_SCALE_INV_SHIFT) * - (s64)PPM_SCALE_INV, - NTP_SCALE_SHIFT); + else + txc->offset = ((long)shift_right(time_offset, SHIFT_UPDATE)) * + NTP_INTERVAL_FREQ / 1000; + txc->freq = (time_freq / NSEC_PER_USEC) << + (SHIFT_USEC - SHIFT_NSEC); txc->maxerror = time_maxerror; txc->esterror = time_esterror; txc->status = time_status; txc->constant = time_constant; txc->precision = 1; - txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; + txc->tolerance = MAXFREQ; txc->tick = tick_usec; - txc->tai = time_tai; /* PPS is not implemented, so these are zero */ txc->ppsfreq = 0; @@ -424,15 +399,9 @@ int do_adjtimex(struct timex *txc) txc->errcnt = 0; txc->stbcnt = 0; write_sequnlock_irq(&xtime_lock); - - txc->time.tv_sec = ts.tv_sec; - txc->time.tv_usec = ts.tv_nsec; - if (!(time_status & STA_NANO)) - txc->time.tv_usec /= NSEC_PER_USEC; - + do_gettimeofday(&txc->time); notify_cmos_timer(); - - return result; + return(result); } static int __init ntp_tick_adj_setup(char *str) @@ -442,10 +411,3 @@ static int __init ntp_tick_adj_setup(char *str) } __setup("ntp_tick_adj=", ntp_tick_adj_setup); - -void __init ntp_init(void) -{ - ntp_clear(); - hrtimer_init(&leap_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); - leap_timer.function = ntp_leap_second; -} diff --git a/trunk/kernel/time/timekeeping.c b/trunk/kernel/time/timekeeping.c index e91c29f961c9..2d6087c7cf98 100644 --- a/trunk/kernel/time/timekeeping.c +++ b/trunk/kernel/time/timekeeping.c @@ -53,7 +53,7 @@ void update_xtime_cache(u64 nsec) timespec_add_ns(&xtime_cache, nsec); } -struct clocksource *clock; +static struct clocksource *clock; /* pointer to current clocksource */ #ifdef CONFIG_GENERIC_TIME @@ -246,7 +246,7 @@ void __init timekeeping_init(void) write_seqlock_irqsave(&xtime_lock, flags); - ntp_init(); + ntp_clear(); clock = clocksource_get_next(); clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); @@ -371,7 +371,7 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval, * here. This is tuned so that an error of about 1 msec is adjusted * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks). */ - error2 = clock->error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ); + error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ); error2 = abs(error2); for (look_ahead = 0; error2 > 0; look_ahead++) error2 >>= 2; @@ -380,7 +380,8 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval, * Now calculate the error in (1 << look_ahead) ticks, but first * remove the single look ahead already included in the error. */ - tick_error = tick_length >> (NTP_SCALE_SHIFT - clock->shift + 1); + tick_error = current_tick_length() >> + (TICK_LENGTH_SHIFT - clock->shift + 1); tick_error -= clock->xtime_interval >> 1; error = ((error - tick_error) >> look_ahead) + tick_error; @@ -411,7 +412,7 @@ static void clocksource_adjust(s64 offset) s64 error, interval = clock->cycle_interval; int adj; - error = clock->error >> (NTP_SCALE_SHIFT - clock->shift - 1); + error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1); if (error > interval) { error >>= 2; if (likely(error <= interval)) @@ -433,7 +434,7 @@ static void clocksource_adjust(s64 offset) clock->xtime_interval += interval; clock->xtime_nsec -= offset; clock->error -= (interval - offset) << - (NTP_SCALE_SHIFT - clock->shift); + (TICK_LENGTH_SHIFT - clock->shift); } /** @@ -472,8 +473,8 @@ void update_wall_time(void) } /* accumulate error between NTP and clock interval */ - clock->error += tick_length; - clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift); + clock->error += current_tick_length(); + clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift); } /* correct the clock when NTP error is too big */ diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 29fc39f1029c..721093a22561 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -195,6 +195,7 @@ static void delayed_work_timer_fn(unsigned long __data) int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay) { + timer_stats_timer_set_start_info(&dwork->timer); if (delay == 0) return queue_work(wq, &dwork->work); @@ -218,12 +219,11 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct timer_list *timer = &dwork->timer; struct work_struct *work = &dwork->work; + timer_stats_timer_set_start_info(&dwork->timer); if (!test_and_set_bit(WORK_STRUCT_PENDING, work_data_bits(work))) { BUG_ON(timer_pending(timer)); BUG_ON(!list_empty(&work->entry)); - timer_stats_timer_set_start_info(&dwork->timer); - /* This stores cwq for the moment, for the timer_fn */ set_wq_data(work, wq_per_cpu(wq, raw_smp_processor_id())); timer->expires = jiffies + delay; @@ -564,6 +564,7 @@ EXPORT_SYMBOL(schedule_work); int schedule_delayed_work(struct delayed_work *dwork, unsigned long delay) { + timer_stats_timer_set_start_info(&dwork->timer); return queue_delayed_work(keventd_wq, dwork, delay); } EXPORT_SYMBOL(schedule_delayed_work); @@ -580,6 +581,7 @@ EXPORT_SYMBOL(schedule_delayed_work); int schedule_delayed_work_on(int cpu, struct delayed_work *dwork, unsigned long delay) { + timer_stats_timer_set_start_info(&dwork->timer); return queue_delayed_work_on(cpu, keventd_wq, dwork, delay); } EXPORT_SYMBOL(schedule_delayed_work_on); diff --git a/trunk/lib/div64.c b/trunk/lib/div64.c index bb5bd0c0f030..b71cf93c529a 100644 --- a/trunk/lib/div64.c +++ b/trunk/lib/div64.c @@ -16,8 +16,9 @@ * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S. */ +#include #include -#include +#include /* Not needed on 64bit architectures */ #if BITS_PER_LONG == 32 @@ -57,31 +58,10 @@ uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base) EXPORT_SYMBOL(__div64_32); -#ifndef div_s64_rem -s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) -{ - u64 quotient; - - if (dividend < 0) { - quotient = div_u64_rem(-dividend, abs(divisor), (u32 *)remainder); - *remainder = -*remainder; - if (divisor > 0) - quotient = -quotient; - } else { - quotient = div_u64_rem(dividend, abs(divisor), (u32 *)remainder); - if (divisor < 0) - quotient = -quotient; - } - return quotient; -} -EXPORT_SYMBOL(div_s64_rem); -#endif - /* 64bit divisor, dividend and result. dynamic precision */ -#ifndef div64_u64 -u64 div64_u64(u64 dividend, u64 divisor) +uint64_t div64_64(uint64_t dividend, uint64_t divisor) { - u32 high, d; + uint32_t high, d; high = divisor >> 32; if (high) { @@ -92,9 +72,10 @@ u64 div64_u64(u64 dividend, u64 divisor) } else d = divisor; - return div_u64(dividend, d); + do_div(dividend, d); + + return dividend; } -EXPORT_SYMBOL(div64_u64); -#endif +EXPORT_SYMBOL(div64_64); #endif /* BITS_PER_LONG == 32 */ diff --git a/trunk/lib/idr.c b/trunk/lib/idr.c index 7a02e173f027..8368c81fcb7d 100644 --- a/trunk/lib/idr.c +++ b/trunk/lib/idr.c @@ -385,8 +385,8 @@ void idr_remove(struct idr *idp, int id) while (idp->id_free_cnt >= IDR_FREE_MAX) { p = alloc_layer(idp); kmem_cache_free(idr_layer_cache, p); + return; } - return; } EXPORT_SYMBOL(idr_remove); diff --git a/trunk/lib/string.c b/trunk/lib/string.c index b19b87af65a3..5efafed3d6b6 100644 --- a/trunk/lib/string.c +++ b/trunk/lib/string.c @@ -493,33 +493,6 @@ char *strsep(char **s, const char *ct) EXPORT_SYMBOL(strsep); #endif -/** - * sysfs_streq - return true if strings are equal, modulo trailing newline - * @s1: one string - * @s2: another string - * - * This routine returns true iff two strings are equal, treating both - * NUL and newline-then-NUL as equivalent string terminations. It's - * geared for use with sysfs input strings, which generally terminate - * with newlines but are compared against values without newlines. - */ -bool sysfs_streq(const char *s1, const char *s2) -{ - while (*s1 && *s1 == *s2) { - s1++; - s2++; - } - - if (*s1 == *s2) - return true; - if (!*s1 && *s2 == '\n' && !s2[1]) - return true; - if (*s1 == '\n' && !s1[1] && !*s2) - return true; - return false; -} -EXPORT_SYMBOL(sysfs_streq); - #ifndef __HAVE_ARCH_MEMSET /** * memset - Fill a region of memory with the given value diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index e46451e1d9b7..33add96cd5fb 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -48,8 +48,6 @@ enum mem_cgroup_stat_index { */ MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */ MEM_CGROUP_STAT_RSS, /* # of pages charged as rss */ - MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */ - MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */ MEM_CGROUP_STAT_NSTATS, }; @@ -201,13 +199,6 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags, __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_CACHE, val); else __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val); - - if (charge) - __mem_cgroup_stat_add_safe(stat, - MEM_CGROUP_STAT_PGPGIN_COUNT, 1); - else - __mem_cgroup_stat_add_safe(stat, - MEM_CGROUP_STAT_PGPGOUT_COUNT, 1); } static struct mem_cgroup_per_zone * @@ -893,8 +884,6 @@ static const struct mem_cgroup_stat_desc { } mem_cgroup_stat_desc[] = { [MEM_CGROUP_STAT_CACHE] = { "cache", PAGE_SIZE, }, [MEM_CGROUP_STAT_RSS] = { "rss", PAGE_SIZE, }, - [MEM_CGROUP_STAT_PGPGIN_COUNT] = {"pgpgin", 1, }, - [MEM_CGROUP_STAT_PGPGOUT_COUNT] = {"pgpgout", 1, }, }; static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 32b62623846a..70db2897c1ea 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -22,7 +22,6 @@ #include #include #include -#include /* * Lock order: @@ -3622,10 +3621,12 @@ static int list_locations(struct kmem_cache *s, char *buf, len += sprintf(buf + len, ""); if (l->sum_time != l->min_time) { + unsigned long remainder; + len += sprintf(buf + len, " age=%ld/%ld/%ld", - l->min_time, - (long)div_u64(l->sum_time, l->count), - l->max_time); + l->min_time, + div_long_long_rem(l->sum_time, l->count, &remainder), + l->max_time); } else len += sprintf(buf + len, " age=%ld", l->min_time); diff --git a/trunk/mm/vmalloc.c b/trunk/mm/vmalloc.c index 6e45b0f3d125..2a39cf128aba 100644 --- a/trunk/mm/vmalloc.c +++ b/trunk/mm/vmalloc.c @@ -547,7 +547,6 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) * @gfp_mask: flags for the page level allocator * @prot: protection mask for the allocated pages * @node: node to use for allocation or -1 - * @caller: caller's return address * * Allocate enough pages to cover @size from the page level * allocator with @gfp_mask flags. Map them into contiguous diff --git a/trunk/net/ipv4/tcp_cubic.c b/trunk/net/ipv4/tcp_cubic.c index 4a1221e5e8ee..eb5b9854c8c7 100644 --- a/trunk/net/ipv4/tcp_cubic.c +++ b/trunk/net/ipv4/tcp_cubic.c @@ -15,8 +15,8 @@ #include #include -#include #include +#include #define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation * max_cwnd = snd_cwnd * beta @@ -128,7 +128,7 @@ static u32 cubic_root(u64 a) * x = ( 2 * x + a / x ) / 3 * k+1 k k */ - x = (2 * x + (u32)div64_u64(a, (u64)x * (u64)(x - 1))); + x = (2 * x + (u32)div64_64(a, (u64)x * (u64)(x - 1))); x = ((x * 341) >> 10); return x; } diff --git a/trunk/net/netfilter/xt_connbytes.c b/trunk/net/netfilter/xt_connbytes.c index d7e8983cd37f..b15e7e2fa143 100644 --- a/trunk/net/netfilter/xt_connbytes.c +++ b/trunk/net/netfilter/xt_connbytes.c @@ -4,11 +4,12 @@ #include #include #include -#include #include #include #include +#include + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching"); @@ -81,7 +82,7 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in, break; } if (pkts != 0) - what = div64_u64(bytes, pkts); + what = div64_64(bytes, pkts); break; } diff --git a/trunk/scripts/kconfig/lxdialog/check-lxdialog.sh b/trunk/scripts/kconfig/lxdialog/check-lxdialog.sh index 5552154cbedb..62e1e02126e6 100644 --- a/trunk/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/trunk/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -36,10 +36,8 @@ trap "rm -f $tmp" 0 1 2 3 15 # Check if we can link to ncurses check() { - $cc -xc - -o $tmp 2>/dev/null <<'EOF' -#include CURSES_LOC -main() {} -EOF + echo -e " #include CURSES_LOC \n main() {}" | + $cc -xc - -o $tmp 2> /dev/null if [ $? != 0 ]; then echo " *** Unable to find the ncurses libraries or the" 1>&2 echo " *** required header files." 1>&2