From cf444e89e5b74d081eec06c0d1632b30eae0b3ab Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Thu, 8 May 2008 21:38:24 -0700 Subject: [PATCH] --- yaml --- r: 96231 b: refs/heads/master c: f08269d3ecbb9300aeeb2d4272580f660afe9db9 h: refs/heads/master i: 96229: dc2a2fb0b4371eac898f5c7d3116653eb3733ceb 96227: 6227b1b31df28cd234ef5f7c021421f3407c4ae6 96223: d75fa7c92c6232107b5269d1f0dee42be72c3cba v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/kgdb.tmpl | 8 +- trunk/Documentation/filesystems/Locking | 2 + trunk/Documentation/filesystems/vfs.txt | 4 + trunk/Documentation/hwmon/w83l785ts | 3 +- .../Documentation/kbuild/kconfig-language.txt | 24 + trunk/Documentation/kdump/kdump.txt | 5 +- trunk/Documentation/kernel-parameters.txt | 5 +- trunk/Documentation/lguest/lguest.c | 62 +- .../powerpc/mpc52xx-device-tree-bindings.txt | 11 - trunk/Documentation/s390/CommonIO | 11 + .../Documentation/scheduler/sched-design.txt | 165 ++ .../Documentation/scsi/ChangeLog.megaraid_sas | 22 - trunk/Documentation/vm/slabinfo.c | 10 +- trunk/MAINTAINERS | 26 +- trunk/Makefile | 10 +- trunk/arch/alpha/kernel/osf_sys.c | 69 +- trunk/arch/arm/kernel/sys_arm.c | 17 + trunk/arch/avr32/kernel/sys_avr32.c | 13 + trunk/arch/blackfin/kernel/sys_bfin.c | 17 + trunk/arch/cris/kernel/sys_cris.c | 5 +- trunk/arch/frv/kernel/sys_frv.c | 17 + trunk/arch/frv/mm/Makefile | 2 +- trunk/arch/h8300/kernel/sys_h8300.c | 17 + 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/perfmon.c | 199 +- 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/sys_m32r.c | 5 +- trunk/arch/m32r/kernel/vmlinux.lds.S | 3 + trunk/arch/m68k/kernel/sys_m68k.c | 17 + trunk/arch/m68k/kernel/traps.c | 17 +- trunk/arch/m68k/mac/config.c | 24 + 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/sys_m68k.c | 17 + 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/mips/kernel/irixioctl.c | 55 +- trunk/arch/mips/kernel/kspd.c | 1 - trunk/arch/mn10300/kernel/sys_mn10300.c | 17 + trunk/arch/parisc/kernel/sys_parisc.c | 13 + trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts | 23 +- trunk/arch/powerpc/configs/ps3_defconfig | 132 +- trunk/arch/powerpc/kernel/smp.c | 2 - trunk/arch/powerpc/kernel/syscalls.c | 17 + trunk/arch/powerpc/kernel/time.c | 4 +- trunk/arch/powerpc/kvm/booke_guest.c | 6 - trunk/arch/powerpc/kvm/powerpc.c | 20 +- trunk/arch/powerpc/lib/Makefile | 1 - trunk/arch/powerpc/lib/devres.c | 42 - trunk/arch/powerpc/mm/slb.c | 27 +- .../powerpc/platforms/cell/spufs/coredump.c | 1 - trunk/arch/powerpc/platforms/ps3/interrupt.c | 6 +- .../arch/powerpc/platforms/pseries/scanlog.c | 19 +- trunk/arch/powerpc/sysdev/fsl_rio.c | 9 +- trunk/arch/powerpc/sysdev/fsl_soc.c | 4 +- trunk/arch/powerpc/sysdev/xilinx_intc.c | 2 +- trunk/arch/s390/Kconfig | 7 - trunk/arch/s390/kernel/compat_wrapper.S | 2 +- trunk/arch/s390/kernel/entry.S | 29 +- trunk/arch/s390/kernel/entry64.S | 57 +- trunk/arch/s390/kernel/ptrace.c | 100 +- trunk/arch/s390/kernel/sys_s390.c | 17 + trunk/arch/s390/kvm/Kconfig | 1 + trunk/arch/s390/kvm/intercept.c | 3 - trunk/arch/s390/kvm/kvm-s390.c | 5 +- trunk/arch/s390/mm/Makefile | 1 - trunk/arch/s390/mm/init.c | 3 - trunk/arch/s390/mm/page-states.c | 79 - trunk/arch/sh/kernel/sys_sh64.c | 17 + trunk/arch/sparc/kernel/process.c | 20 +- trunk/arch/sparc/kernel/setup.c | 5 +- trunk/arch/sparc/kernel/signal.c | 20 +- trunk/arch/sparc/kernel/sys_sparc.c | 3 +- trunk/arch/sparc/mm/fault.c | 61 +- trunk/arch/sparc/prom/init.c | 7 + trunk/arch/sparc/prom/memory.c | 235 +- trunk/arch/sparc64/kernel/pci.c | 130 +- trunk/arch/sparc64/kernel/pci_common.c | 6 + trunk/arch/sparc64/kernel/pci_impl.h | 9 + trunk/arch/sparc64/kernel/process.c | 24 +- trunk/arch/sparc64/kernel/signal.c | 27 +- trunk/arch/sparc64/kernel/signal32.c | 24 +- trunk/arch/sparc64/kernel/smp.c | 27 +- trunk/arch/sparc64/kernel/sys_sparc.c | 4 +- trunk/arch/sparc64/kernel/sys_sparc32.c | 31 + trunk/arch/sparc64/kernel/systbls.S | 2 +- trunk/arch/sparc64/mm/init.c | 16 +- trunk/arch/um/drivers/line.c | 4 +- trunk/arch/um/include/line.h | 2 +- trunk/arch/um/kernel/syscall.c | 17 + trunk/arch/v850/kernel/syscalls.c | 17 + trunk/arch/x86/Kconfig | 2 - trunk/arch/x86/boot/compressed/relocs.c | 2 +- trunk/arch/x86/kernel/Makefile | 4 +- trunk/arch/x86/kernel/acpi/Makefile | 2 +- trunk/arch/x86/kernel/acpi/realmode/Makefile | 5 +- trunk/arch/x86/kernel/kvmclock.c | 4 - trunk/arch/x86/kernel/mpparse.c | 7 +- trunk/arch/x86/kernel/reboot.c | 1 + trunk/arch/x86/kernel/setup.c | 2 +- trunk/arch/x86/kernel/smpboot.c | 4 +- trunk/arch/x86/kernel/sys_i386_32.c | 17 + trunk/arch/x86/kernel/sys_x86_64.c | 17 + trunk/arch/x86/kvm/i8254.c | 8 +- trunk/arch/x86/kvm/lapic.c | 6 +- trunk/arch/x86/kvm/mmu.c | 89 +- trunk/arch/x86/kvm/mmu.h | 37 +- trunk/arch/x86/kvm/svm.c | 10 - trunk/arch/x86/kvm/vmx.c | 375 +-- trunk/arch/x86/kvm/vmx.h | 38 - trunk/arch/x86/kvm/x86.c | 22 +- trunk/arch/x86/kvm/x86_emulate.c | 1 - trunk/arch/x86/mm/discontig_32.c | 26 + trunk/arch/x86/mm/pgtable_32.c | 7 + trunk/arch/x86/pci/Makefile_32 | 12 +- trunk/arch/x86/pci/acpi.c | 41 + trunk/arch/x86/pci/common.c | 69 +- trunk/arch/x86/pci/fixup.c | 2 +- trunk/arch/x86/pci/init.c | 4 - trunk/arch/x86/pci/pci.h | 3 - trunk/arch/x86/vdso/vdso32-setup.c | 2 +- trunk/arch/x86/video/fbdev.c | 2 +- trunk/block/blk-barrier.c | 3 +- trunk/block/blk-core.c | 31 +- trunk/block/blk-ioc.c | 2 +- trunk/block/blk-merge.c | 12 +- trunk/block/blk-settings.c | 20 +- trunk/block/blk-sysfs.c | 6 +- trunk/block/blk-tag.c | 17 +- trunk/block/bsg.c | 14 +- trunk/block/cfq-iosched.c | 23 +- trunk/block/elevator.c | 5 +- trunk/block/scsi_ioctl.c | 5 +- trunk/crypto/authenc.c | 5 +- trunk/crypto/cryptd.c | 4 +- trunk/crypto/eseqiv.c | 3 +- trunk/drivers/accessibility/Kconfig | 12 +- trunk/drivers/ata/Kconfig | 13 +- trunk/drivers/ata/Makefile | 1 - trunk/drivers/ata/ahci.c | 4 +- trunk/drivers/ata/ata_generic.c | 6 - trunk/drivers/ata/ata_piix.c | 25 - trunk/drivers/ata/libata-core.c | 1 - trunk/drivers/ata/libata-eh.c | 2 +- trunk/drivers/ata/libata-sff.c | 6 +- trunk/drivers/ata/pata_acpi.c | 6 - trunk/drivers/ata/pata_sch.c | 206 -- trunk/drivers/ata/sata_inic162x.c | 646 ++--- trunk/drivers/ata/sata_mv.c | 690 ++--- trunk/drivers/base/cpu.c | 10 +- trunk/drivers/base/sys.c | 3 +- trunk/drivers/block/aoe/aoecmd.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/serial167.c | 2 +- trunk/drivers/char/sx.c | 9 +- trunk/drivers/char/synclink.c | 16 +- trunk/drivers/char/tty_audit.c | 1 - trunk/drivers/char/tty_io.c | 1 - trunk/drivers/char/vt.c | 6 - .../char/xilinx_hwicap/xilinx_hwicap.c | 6 +- trunk/drivers/edac/edac_core.h | 2 +- trunk/drivers/edac/edac_device.c | 6 +- trunk/drivers/edac/edac_mc.c | 6 +- trunk/drivers/edac/edac_pci.c | 6 +- trunk/drivers/firewire/fw-sbp2.c | 4 +- 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 | 15 +- trunk/drivers/ide/legacy/falconide.c | 2 +- trunk/drivers/ieee1394/nodemgr.c | 5 +- trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c | 103 +- trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h | 12 +- .../infiniband/hw/cxgb3/cxio_resource.c | 36 +- trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c | 6 +- trunk/drivers/infiniband/hw/cxgb3/iwch_mem.c | 75 +- .../infiniband/hw/cxgb3/iwch_provider.c | 68 +- .../infiniband/hw/cxgb3/iwch_provider.h | 8 +- trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c | 13 +- .../drivers/infiniband/hw/ehca/ehca_classes.h | 2 - trunk/drivers/infiniband/hw/ehca/ehca_hca.c | 7 +- trunk/drivers/infiniband/hw/ehca/ehca_irq.c | 4 - trunk/drivers/infiniband/hw/ehca/ehca_qp.c | 5 - .../infiniband/hw/ipath/ipath_driver.c | 138 +- .../infiniband/hw/ipath/ipath_file_ops.c | 72 +- .../infiniband/hw/ipath/ipath_iba7220.c | 26 +- .../infiniband/hw/ipath/ipath_init_chip.c | 95 +- .../drivers/infiniband/hw/ipath/ipath_intr.c | 80 +- .../infiniband/hw/ipath/ipath_kernel.h | 8 +- trunk/drivers/infiniband/hw/ipath/ipath_rc.c | 6 +- trunk/drivers/infiniband/hw/ipath/ipath_ruc.c | 7 +- .../drivers/infiniband/hw/ipath/ipath_sdma.c | 44 +- .../drivers/infiniband/hw/ipath/ipath_verbs.c | 2 +- trunk/drivers/infiniband/hw/mlx4/cq.c | 4 +- trunk/drivers/infiniband/ulp/ipoib/ipoib.h | 2 - trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c | 47 +- .../infiniband/ulp/ipoib/ipoib_verbs.c | 3 +- trunk/drivers/input/misc/Kconfig | 2 +- trunk/drivers/input/serio/hp_sdc.c | 1 - trunk/drivers/isdn/hysdn/hysdn_procconf.c | 3 +- trunk/drivers/lguest/lguest_device.c | 68 +- trunk/drivers/lguest/lguest_user.c | 4 +- trunk/drivers/macintosh/adb.c | 30 +- trunk/drivers/macintosh/therm_pm72.c | 31 +- trunk/drivers/macintosh/windfarm_smu_sat.c | 10 +- trunk/drivers/md/raid10.c | 2 +- trunk/drivers/media/Makefile | 2 - trunk/drivers/media/video/cx18/cx18-driver.c | 2 +- .../media/video/saa7134/saa7134-video.c | 2 +- trunk/drivers/misc/kgdbts.c | 75 +- 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/fec_mpc52xx.c | 97 +- trunk/drivers/net/fec_mpc52xx.h | 19 + trunk/drivers/net/mlx4/mr.c | 2 +- trunk/drivers/net/usb/asix.c | 4 - trunk/drivers/net/virtio_net.c | 96 +- trunk/drivers/pci/probe.c | 33 +- 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/power/pda_power.c | 11 - trunk/drivers/power/pmu_battery.c | 2 +- trunk/drivers/ps3/ps3-lpm.c | 1 - trunk/drivers/ps3/ps3-sys-manager.c | 7 +- trunk/drivers/rtc/rtc-ds1511.c | 4 +- trunk/drivers/s390/char/tty3270.c | 15 +- trunk/drivers/s390/cio/blacklist.c | 323 ++- trunk/drivers/s390/cio/cio.c | 39 +- trunk/drivers/s390/cio/cio.h | 2 + trunk/drivers/s390/cio/cio_debug.h | 6 + trunk/drivers/s390/cio/css.c | 4 +- trunk/drivers/s390/cio/device.c | 25 +- trunk/drivers/s390/cio/device_fsm.c | 44 +- trunk/drivers/s390/cio/device_id.c | 4 +- trunk/drivers/s390/cio/device_pgid.c | 12 +- trunk/drivers/s390/s390mach.c | 3 +- trunk/drivers/s390/scsi/zfcp_dbf.c | 2 +- trunk/drivers/s390/scsi/zfcp_fsf.c | 2 +- trunk/drivers/sbus/char/bpp.c | 2 +- trunk/drivers/scsi/53c700.c | 6 +- trunk/drivers/scsi/Kconfig | 4 +- trunk/drivers/scsi/a100u2w.c | 2 +- trunk/drivers/scsi/aacraid/aachba.c | 133 +- trunk/drivers/scsi/aacraid/aacraid.h | 28 +- trunk/drivers/scsi/aacraid/comminit.c | 2 - trunk/drivers/scsi/aacraid/commsup.c | 34 +- trunk/drivers/scsi/aacraid/linit.c | 22 +- trunk/drivers/scsi/aic94xx/aic94xx_init.c | 6 +- trunk/drivers/scsi/constants.c | 10 +- trunk/drivers/scsi/dpt/dpti_ioctl.h | 16 +- trunk/drivers/scsi/dpt/dptsig.h | 8 +- trunk/drivers/scsi/dpt/sys_info.h | 4 +- trunk/drivers/scsi/dpt_i2o.c | 718 ++--- trunk/drivers/scsi/dpti.h | 28 +- trunk/drivers/scsi/gdth.c | 2 +- trunk/drivers/scsi/hptiop.c | 6 +- trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 7 +- trunk/drivers/scsi/ibmvscsi/viosrp.h | 9 - trunk/drivers/scsi/initio.c | 2 +- trunk/drivers/scsi/ipr.c | 2 +- trunk/drivers/scsi/megaraid/megaraid_mbox.c | 17 - trunk/drivers/scsi/megaraid/megaraid_mbox.h | 1 - trunk/drivers/scsi/megaraid/megaraid_sas.c | 13 +- trunk/drivers/scsi/megaraid/megaraid_sas.h | 6 +- trunk/drivers/scsi/mvsas.c | 4 +- trunk/drivers/scsi/ncr53c8xx.c | 2 +- trunk/drivers/scsi/qla1280.c | 4 +- trunk/drivers/scsi/scsi.c | 23 +- trunk/drivers/scsi/scsi_error.c | 15 +- trunk/drivers/scsi/scsi_lib.c | 7 +- trunk/drivers/scsi/scsi_tgt_lib.c | 2 - trunk/drivers/scsi/u14-34f.c | 6 +- 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/serial/mpc52xx_uart.c | 2 - trunk/drivers/serial/serial_core.c | 3 +- trunk/drivers/serial/sunhv.c | 2 +- trunk/drivers/serial/sunsab.c | 2 +- trunk/drivers/serial/sunsu.c | 2 +- trunk/drivers/serial/sunzilog.c | 2 +- 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/iuu_phoenix.c | 6 +- trunk/drivers/usb/serial/mos7840.c | 5 +- trunk/drivers/usb/storage/Kconfig | 3 +- trunk/drivers/usb/storage/cypress_atacb.c | 2 +- trunk/drivers/usb/storage/isd200.c | 2 - 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/video/bw2.c | 2 +- trunk/drivers/video/cg3.c | 2 +- trunk/drivers/video/cg6.c | 2 +- trunk/drivers/video/ffb.c | 2 +- trunk/drivers/video/leo.c | 2 +- trunk/drivers/video/p9100.c | 2 +- trunk/drivers/video/tcx.c | 20 +- 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/affs/affs.h | 4 +- trunk/fs/affs/file.c | 25 +- trunk/fs/affs/inode.c | 34 +- trunk/fs/affs/namei.c | 6 +- trunk/fs/affs/super.c | 18 +- trunk/fs/anon_inodes.c | 13 +- trunk/fs/autofs4/expire.c | 26 +- trunk/fs/autofs4/root.c | 38 +- trunk/fs/autofs4/waitq.c | 2 +- trunk/fs/bio.c | 3 +- trunk/fs/compat.c | 1 - trunk/fs/dnotify.c | 2 +- trunk/fs/eventfd.c | 15 +- trunk/fs/eventpoll.c | 23 +- trunk/fs/exec.c | 1 - trunk/fs/fcntl.c | 1 - trunk/fs/file.c | 23 +- trunk/fs/file_table.c | 1 - trunk/fs/fuse/file.c | 2 +- trunk/fs/inode.c | 5 + 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/locks.c | 18 +- trunk/fs/ocfs2/cluster/sys.c | 2 +- trunk/fs/ocfs2/dlm/dlmdebug.c | 8 +- trunk/fs/ocfs2/file.c | 4 - trunk/fs/ocfs2/localalloc.c | 4 +- trunk/fs/ocfs2/stack_o2cb.c | 2 +- trunk/fs/ocfs2/stack_user.c | 2 +- trunk/fs/ocfs2/symlink.c | 2 - trunk/fs/open.c | 1 - trunk/fs/pipe.c | 21 - trunk/fs/proc/array.c | 1 - trunk/fs/proc/base.c | 1 - trunk/fs/proc/task_mmu.c | 2 + trunk/fs/proc/task_nommu.c | 1 - trunk/fs/select.c | 3 +- trunk/fs/signalfd.c | 17 +- trunk/fs/splice.c | 31 +- trunk/fs/timerfd.c | 11 +- trunk/fs/udf/namei.c | 145 +- trunk/fs/udf/partition.c | 4 +- trunk/fs/udf/super.c | 1 - trunk/fs/udf/udfdecl.h | 1 - trunk/fs/utimes.c | 17 +- trunk/include/asm-alpha/types.h | 30 +- trunk/include/asm-arm/div64.h | 2 + trunk/include/asm-arm/types.h | 33 +- trunk/include/asm-avr32/types.h | 32 +- trunk/include/asm-blackfin/types.h | 34 +- trunk/include/asm-cris/types.h | 33 +- trunk/include/asm-frv/types.h | 34 +- trunk/include/asm-frv/unaligned.h | 6 +- trunk/include/asm-generic/Kbuild | 2 - trunk/include/asm-generic/div64.h | 7 + trunk/include/asm-generic/int-l64.h | 71 - trunk/include/asm-generic/int-ll64.h | 76 - trunk/include/asm-h8300/types.h | 33 +- 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-ia64/types.h | 31 +- trunk/include/asm-m32r/types.h | 32 +- trunk/include/asm-m68k/div64.h | 1 + trunk/include/asm-m68k/machw.h | 30 + trunk/include/asm-m68k/types.h | 32 +- trunk/include/asm-m68knommu/dma.h | 3 +- trunk/include/asm-m68knommu/param.h | 7 +- trunk/include/asm-mips/div64.h | 6 + trunk/include/asm-mips/types.h | 58 +- trunk/include/asm-mn10300/div64.h | 3 + trunk/include/asm-mn10300/processor.h | 2 +- trunk/include/asm-mn10300/types.h | 33 +- trunk/include/asm-parisc/types.h | 33 +- trunk/include/asm-powerpc/io.h | 8 +- trunk/include/asm-powerpc/kvm_host.h | 1 - trunk/include/asm-powerpc/kvm_ppc.h | 5 - trunk/include/asm-powerpc/ps3.h | 3 + trunk/include/asm-powerpc/syscalls.h | 2 +- trunk/include/asm-powerpc/types.h | 48 +- trunk/include/asm-s390/kvm_host.h | 1 - trunk/include/asm-s390/page.h | 11 - trunk/include/asm-s390/ptrace.h | 2 - trunk/include/asm-s390/system.h | 6 - trunk/include/asm-s390/types.h | 48 +- trunk/include/asm-sh/types.h | 34 +- trunk/include/asm-sparc/oplib.h | 17 + trunk/include/asm-sparc/page.h | 5 +- trunk/include/asm-sparc/types.h | 30 +- trunk/include/asm-sparc64/types.h | 30 +- trunk/include/asm-um/div64.h | 1 + trunk/include/asm-v850/types.h | 32 +- trunk/include/asm-x86/bootparam.h | 8 +- trunk/include/asm-x86/div64.h | 34 +- trunk/include/asm-x86/dmi.h | 1 - trunk/include/asm-x86/io_32.h | 5 + trunk/include/asm-x86/kvm_host.h | 10 +- trunk/include/asm-x86/pgtable_32.h | 9 +- trunk/include/asm-x86/pgtable_64.h | 6 +- trunk/include/asm-x86/types.h | 38 +- trunk/include/asm-xtensa/types.h | 33 +- trunk/include/crypto/scatterwalk.h | 4 - trunk/include/linux/Kbuild | 5 - trunk/include/linux/anon_inodes.h | 3 +- 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/exportfs.h | 21 - trunk/include/linux/fdtable.h | 99 - trunk/include/linux/file.h | 86 +- trunk/include/linux/fs.h | 6 + trunk/include/linux/genhd.h | 35 +- trunk/include/linux/hrtimer.h | 9 - trunk/include/linux/init_task.h | 2 +- trunk/include/linux/io.h | 1 - trunk/include/linux/ioprio.h | 14 - trunk/include/linux/irq.h | 1 - trunk/include/linux/jiffies.h | 2 +- trunk/include/linux/kgdb.h | 4 +- trunk/include/linux/libata.h | 16 - 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.h | 5 +- trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/pda_power.h | 4 - trunk/include/linux/poll.h | 2 - trunk/include/linux/quota.h | 3 - trunk/include/linux/rio.h | 2 - trunk/include/linux/sched.h | 38 +- trunk/include/linux/string.h | 2 - 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/vermagic.h | 8 +- 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/include/scsi/scsi.h | 40 +- trunk/include/scsi/scsi_cmnd.h | 23 +- trunk/include/scsi/scsi_eh.h | 4 +- trunk/include/scsi/scsi_host.h | 8 +- trunk/init/Kconfig | 30 +- trunk/init/main.c | 1 - trunk/ipc/mqueue.c | 3 +- trunk/kernel/Makefile | 2 +- trunk/kernel/compat.c | 3 +- trunk/kernel/cpuset.c | 52 +- trunk/kernel/exit.c | 1 - trunk/kernel/fork.c | 1 - trunk/kernel/futex.c | 176 +- trunk/kernel/hrtimer.c | 9 + trunk/kernel/irq/manage.c | 49 +- trunk/kernel/irq/spurious.c | 4 +- trunk/kernel/kexec.c | 2 +- trunk/kernel/kgdb.c | 8 +- trunk/kernel/kmod.c | 1 - trunk/kernel/module.c | 384 ++- trunk/kernel/posix-cpu-timers.c | 11 +- trunk/kernel/ptrace.c | 2 + trunk/kernel/relay.c | 2 +- trunk/kernel/sched.c | 325 ++- trunk/kernel/sched_clock.c | 236 -- trunk/kernel/sched_debug.c | 11 +- trunk/kernel/sched_fair.c | 50 +- trunk/kernel/sched_idletask.c | 2 +- trunk/kernel/sched_rt.c | 9 +- trunk/kernel/semaphore.c | 64 +- trunk/kernel/softirq.c | 20 +- trunk/kernel/time.c | 62 +- trunk/kernel/time/clocksource.c | 4 +- trunk/kernel/time/ntp.c | 398 ++- trunk/kernel/time/timekeeping.c | 17 +- trunk/kernel/timeconst.pl | 120 +- trunk/kernel/workqueue.c | 6 +- trunk/lib/Kconfig.kgdb | 16 +- trunk/lib/devres.c | 2 +- trunk/lib/div64.c | 35 +- trunk/lib/idr.c | 2 +- trunk/lib/string.c | 27 - trunk/mm/filemap.c | 2 +- trunk/mm/memcontrol.c | 11 - trunk/mm/memory.c | 5 +- trunk/mm/slub.c | 55 +- trunk/mm/vmalloc.c | 1 - trunk/net/can/bcm.c | 6 + trunk/net/ipv4/tcp_cubic.c | 4 +- trunk/net/mac80211/rc80211_pid_debugfs.c | 4 +- trunk/net/netfilter/xt_connbytes.c | 5 +- trunk/net/sunrpc/svc.c | 1 + trunk/net/tipc/core.h | 11 +- trunk/scripts/kconfig/lkc.h | 6 +- .../kconfig/lxdialog/check-lxdialog.sh | 6 +- trunk/scripts/kconfig/mconf.c | 3 +- trunk/scripts/mod/file2alias.c | 35 +- trunk/security/selinux/hooks.c | 1 - trunk/sound/drivers/Kconfig | 4 +- trunk/sound/drivers/pcsp/pcsp.c | 4 - trunk/sound/oss/kahlua.c | 2 +- trunk/sound/pci/Kconfig | 5 +- trunk/sound/pci/ac97/ac97_patch.c | 9 +- trunk/sound/pci/hda/patch_realtek.c | 5 +- trunk/sound/pci/hda/patch_sigmatel.c | 2 - trunk/sound/soc/at91/at91-pcm.c | 11 +- trunk/sound/soc/at91/at91-ssc.c | 2 +- trunk/sound/soc/s3c24xx/s3c24xx-i2s.c | 2 - trunk/sound/soc/s3c24xx/s3c24xx-pcm.c | 2 +- trunk/virt/kvm/kvm_main.c | 22 +- 620 files changed, 7599 insertions(+), 17303 deletions(-) create mode 100644 trunk/Documentation/scheduler/sched-design.txt create mode 100644 trunk/arch/m32r/defconfig delete mode 100644 trunk/arch/powerpc/lib/devres.c delete mode 100644 trunk/arch/s390/mm/page-states.c delete mode 100644 trunk/drivers/ata/pata_sch.c 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 delete mode 100644 trunk/include/asm-generic/int-l64.h delete mode 100644 trunk/include/asm-generic/int-ll64.h create mode 100644 trunk/include/linux/calc64.h delete mode 100644 trunk/include/linux/fdtable.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 delete mode 100644 trunk/kernel/sched_clock.c diff --git a/[refs] b/[refs] index 45d6e95e3c5a..ec2af7543aca 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 91e37a793b5a9436a2d12b2f0a8f52db3a133e1d +refs/heads/master: f08269d3ecbb9300aeeb2d4272580f660afe9db9 diff --git a/trunk/Documentation/DocBook/kgdb.tmpl b/trunk/Documentation/DocBook/kgdb.tmpl index 028a8444d95e..97618bed4d65 100644 --- a/trunk/Documentation/DocBook/kgdb.tmpl +++ b/trunk/Documentation/DocBook/kgdb.tmpl @@ -72,7 +72,7 @@ kgdb is a source level debugger for linux kernel. It is used along with gdb to debug a linux kernel. The expectation is that gdb can be used to "break in" to the kernel to inspect memory, variables - and look through call stack information similar to what an + and look through a cal stack information similar to what an application developer would use gdb for. It is possible to place breakpoints in kernel code and perform some limited execution stepping. @@ -93,10 +93,8 @@ Compiling a kernel - To enable CONFIG_KGDB you should first turn on - "Prompt for development and/or incomplete code/drivers" - (CONFIG_EXPERIMENTAL) in "General setup", then under the - "Kernel debugging" select "KGDB: kernel debugging with remote gdb". + To enable CONFIG_KGDB, look under the "Kernel debugging" + and then select "KGDB: kernel debugging with remote gdb". Next you should choose one of more I/O drivers to interconnect debugging diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 8b22d7d8b991..c2992bc54f2f 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -92,6 +92,7 @@ prototypes: void (*destroy_inode)(struct inode *); void (*dirty_inode) (struct inode *); int (*write_inode) (struct inode *, int); + void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -114,6 +115,7 @@ alloc_inode: no no no destroy_inode: no dirty_inode: no (must not sleep) write_inode: no +put_inode: no drop_inode: no !!!inode_lock!!! delete_inode: no put_super: yes yes no diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index b7522c6cbae3..81e5be6e6e35 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -205,6 +205,7 @@ struct super_operations { void (*dirty_inode) (struct inode *); int (*write_inode) (struct inode *, int); + void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -245,6 +246,9 @@ or bottom half). inode to disc. The second parameter indicates whether the write should be synchronous or not, not all filesystems check this flag. + put_inode: called when the VFS inode is removed from the inode + cache. + drop_inode: called when the last access to the inode is dropped, with the inode_lock spinlock held. 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/kbuild/kconfig-language.txt b/trunk/Documentation/kbuild/kconfig-language.txt index c412c245848f..00b950d1c193 100644 --- a/trunk/Documentation/kbuild/kconfig-language.txt +++ b/trunk/Documentation/kbuild/kconfig-language.txt @@ -377,3 +377,27 @@ config FOO limits FOO to module (=m) or disabled (=n). + +Build limited by a third config symbol which may be =y or =m +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A common idiom that we see (and sometimes have problems with) is this: + +When option C in B (module or subsystem) uses interfaces from A (module +or subsystem), and both A and B are tristate (could be =y or =m if they +were independent of each other, but they aren't), then we need to limit +C such that it cannot be built statically if A is built as a loadable +module. (C already depends on B, so there is no dependency issue to +take care of here.) + +If A is linked statically into the kernel image, C can be built +statically or as loadable module(s). However, if A is built as loadable +module(s), then C must be restricted to loadable module(s) also. This +can be expressed in kconfig language as: + +config C + depends on A = y || A = B + +or for real examples, use this command in a kernel tree: + +$ find . -name Kconfig\* | xargs grep -ns "depends on.*=.*||.*=" | grep -v orig + 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/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index cdd5b934f43e..a3c35446e755 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1094,6 +1094,9 @@ and is between 256 and 4096 characters. It is defined in the file mac5380= [HW,SCSI] Format: ,,,, + mac53c9x= [HW,SCSI] Format: + ,,,,,,, + machvec= [IA64] Force the use of a particular machine-vector (machvec) in a generic kernel. Example: machvec=hpzx1_swiotlb @@ -1522,8 +1525,6 @@ and is between 256 and 4096 characters. It is defined in the file This is normally done in pci_enable_device(), so this option is a temporary workaround for broken drivers that don't call it. - skip_isa_align [X86] do not align io start addr, so can - handle more pci cards firmware [ARM] Do not re-enumerate the bus but instead just use the configuration from the bootloader. This is currently used on 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/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt index 6f12f1c79c0c..cda7a7dffa6d 100644 --- a/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt +++ b/trunk/Documentation/powerpc/mpc52xx-device-tree-bindings.txt @@ -237,17 +237,6 @@ Each GPIO controller node should have the empty property gpio-controller and according to the bit numbers in the GPIO control registers. The second cell is for flags which is currently unsused. -8) FEC nodes -The FEC node can specify one of the following properties to configure -the MII link: -"fsl,7-wire-mode" - An empty property that specifies the link uses 7-wire - mode instead of MII -"current-speed" - Specifies that the MII should be configured for a fixed - speed. This property should contain two cells. The - first cell specifies the speed in Mbps and the second - should be '0' for half duplex and '1' for full duplex -"phy-handle" - Contains a phandle to an Ethernet PHY. - IV - Extra Notes ================ diff --git a/trunk/Documentation/s390/CommonIO b/trunk/Documentation/s390/CommonIO index bf0baa19ec24..8fbc0a852870 100644 --- a/trunk/Documentation/s390/CommonIO +++ b/trunk/Documentation/s390/CommonIO @@ -8,6 +8,17 @@ Command line parameters Enable logging of debug information in case of ccw device timeouts. + +* cio_msg = yes | no + + Determines whether information on found devices and sensed device + characteristics should be shown during startup or when new devices are + found, i. e. messages of the types "Detected device 0.0.4711 on subchannel + 0.0.0042" and "SenseID: Device 0.0.4711 reports: ...". + + Default is off. + + * cio_ignore = {all} | { | } | {! | !} diff --git a/trunk/Documentation/scheduler/sched-design.txt b/trunk/Documentation/scheduler/sched-design.txt new file mode 100644 index 000000000000..1605bf0cba8b --- /dev/null +++ b/trunk/Documentation/scheduler/sched-design.txt @@ -0,0 +1,165 @@ + Goals, Design and Implementation of the + new ultra-scalable O(1) scheduler + + + This is an edited version of an email Ingo Molnar sent to + lkml on 4 Jan 2002. It describes the goals, design, and + implementation of Ingo's new ultra-scalable O(1) scheduler. + Last Updated: 18 April 2002. + + +Goal +==== + +The main goal of the new scheduler is to keep all the good things we know +and love about the current Linux scheduler: + + - good interactive performance even during high load: if the user + types or clicks then the system must react instantly and must execute + the user tasks smoothly, even during considerable background load. + + - good scheduling/wakeup performance with 1-2 runnable processes. + + - fairness: no process should stay without any timeslice for any + unreasonable amount of time. No process should get an unjustly high + amount of CPU time. + + - priorities: less important tasks can be started with lower priority, + more important tasks with higher priority. + + - SMP efficiency: no CPU should stay idle if there is work to do. + + - SMP affinity: processes which run on one CPU should stay affine to + that CPU. Processes should not bounce between CPUs too frequently. + + - plus additional scheduler features: RT scheduling, CPU binding. + +and the goal is also to add a few new things: + + - fully O(1) scheduling. Are you tired of the recalculation loop + blowing the L1 cache away every now and then? Do you think the goodness + loop is taking a bit too long to finish if there are lots of runnable + processes? This new scheduler takes no prisoners: wakeup(), schedule(), + the timer interrupt are all O(1) algorithms. There is no recalculation + loop. There is no goodness loop either. + + - 'perfect' SMP scalability. With the new scheduler there is no 'big' + runqueue_lock anymore - it's all per-CPU runqueues and locks - two + tasks on two separate CPUs can wake up, schedule and context-switch + completely in parallel, without any interlocking. All + scheduling-relevant data is structured for maximum scalability. + + - better SMP affinity. The old scheduler has a particular weakness that + causes the random bouncing of tasks between CPUs if/when higher + priority/interactive tasks, this was observed and reported by many + people. The reason is that the timeslice recalculation loop first needs + every currently running task to consume its timeslice. But when this + happens on eg. an 8-way system, then this property starves an + increasing number of CPUs from executing any process. Once the last + task that has a timeslice left has finished using up that timeslice, + the recalculation loop is triggered and other CPUs can start executing + tasks again - after having idled around for a number of timer ticks. + The more CPUs, the worse this effect. + + Furthermore, this same effect causes the bouncing effect as well: + whenever there is such a 'timeslice squeeze' of the global runqueue, + idle processors start executing tasks which are not affine to that CPU. + (because the affine tasks have finished off their timeslices already.) + + The new scheduler solves this problem by distributing timeslices on a + per-CPU basis, without having any global synchronization or + recalculation. + + - batch scheduling. A significant proportion of computing-intensive tasks + benefit from batch-scheduling, where timeslices are long and processes + are roundrobin scheduled. The new scheduler does such batch-scheduling + of the lowest priority tasks - so nice +19 jobs will get + 'batch-scheduled' automatically. With this scheduler, nice +19 jobs are + in essence SCHED_IDLE, from an interactiveness point of view. + + - handle extreme loads more smoothly, without breakdown and scheduling + storms. + + - O(1) RT scheduling. For those RT folks who are paranoid about the + O(nr_running) property of the goodness loop and the recalculation loop. + + - run fork()ed children before the parent. Andrea has pointed out the + advantages of this a few months ago, but patches for this feature + do not work with the old scheduler as well as they should, + because idle processes often steal the new child before the fork()ing + CPU gets to execute it. + + +Design +====== + +The core of the new scheduler contains the following mechanisms: + + - *two* priority-ordered 'priority arrays' per CPU. There is an 'active' + array and an 'expired' array. The active array contains all tasks that + are affine to this CPU and have timeslices left. The expired array + contains all tasks which have used up their timeslices - but this array + is kept sorted as well. The active and expired array is not accessed + directly, it's accessed through two pointers in the per-CPU runqueue + structure. If all active tasks are used up then we 'switch' the two + pointers and from now on the ready-to-go (former-) expired array is the + active array - and the empty active array serves as the new collector + for expired tasks. + + - there is a 64-bit bitmap cache for array indices. Finding the highest + priority task is thus a matter of two x86 BSFL bit-search instructions. + +the split-array solution enables us to have an arbitrary number of active +and expired tasks, and the recalculation of timeslices can be done +immediately when the timeslice expires. Because the arrays are always +access through the pointers in the runqueue, switching the two arrays can +be done very quickly. + +this is a hybride priority-list approach coupled with roundrobin +scheduling and the array-switch method of distributing timeslices. + + - there is a per-task 'load estimator'. + +one of the toughest things to get right is good interactive feel during +heavy system load. While playing with various scheduler variants i found +that the best interactive feel is achieved not by 'boosting' interactive +tasks, but by 'punishing' tasks that want to use more CPU time than there +is available. This method is also much easier to do in an O(1) fashion. + +to establish the actual 'load' the task contributes to the system, a +complex-looking but pretty accurate method is used: there is a 4-entry +'history' ringbuffer of the task's activities during the last 4 seconds. +This ringbuffer is operated without much overhead. The entries tell the +scheduler a pretty accurate load-history of the task: has it used up more +CPU time or less during the past N seconds. [the size '4' and the interval +of 4x 1 seconds was found by lots of experimentation - this part is +flexible and can be changed in both directions.] + +the penalty a task gets for generating more load than the CPU can handle +is a priority decrease - there is a maximum amount to this penalty +relative to their static priority, so even fully CPU-bound tasks will +observe each other's priorities, and will share the CPU accordingly. + +the SMP load-balancer can be extended/switched with additional parallel +computing and cache hierarchy concepts: NUMA scheduling, multi-core CPUs +can be supported easily by changing the load-balancer. Right now it's +tuned for my SMP systems. + +i skipped the prev->mm == next->mm advantage - no workload i know of shows +any sensitivity to this. It can be added back by sacrificing O(1) +schedule() [the current and one-lower priority list can be searched for a +that->mm == current->mm condition], but costs a fair number of cycles +during a number of important workloads, so i wanted to avoid this as much +as possible. + +- the SMP idle-task startup code was still racy and the new scheduler +triggered this. So i streamlined the idle-setup code a bit. We do not call +into schedule() before all processors have started up fully and all idle +threads are in place. + +- the patch also cleans up a number of aspects of sched.c - moves code +into other areas of the kernel where it's appropriate, and simplifies +certain code paths and data constructs. As a result, the new scheduler's +code is smaller than the old one. + + Ingo diff --git a/trunk/Documentation/scsi/ChangeLog.megaraid_sas b/trunk/Documentation/scsi/ChangeLog.megaraid_sas index 716fcc1cafb5..91c81db0ba71 100644 --- a/trunk/Documentation/scsi/ChangeLog.megaraid_sas +++ b/trunk/Documentation/scsi/ChangeLog.megaraid_sas @@ -1,25 +1,3 @@ -1 Release Date : Mon. March 10 11:02:31 PDT 2008 - - (emaild-id:megaraidlinux@lsi.com) - Sumant Patro - Bo Yang - -2 Current Version : 00.00.03.20-RC1 -3 Older Version : 00.00.03.16 - -1. Rollback the sense info implementation - Sense buffer ptr data type in the ioctl path is reverted back - to u32 * as in previous versions of driver. - -2. Fixed the driver frame count. - When Driver sent wrong frame count to firmware. As this - particular command is sent to drive, FW is seeing continuous - chip resets and so the command will timeout. - -3. Add the new controller(1078DE) support to the driver - and Increase the max_wait to 60 from 10 in the controller - operational status. With this max_wait increase, driver will - make sure the FW will finish the pending cmd for KDUMP case. - 1 Release Date : Thur. Nov. 07 16:30:43 PST 2007 - (emaild-id:megaraidlinux@lsi.com) Sumant Patro diff --git a/trunk/Documentation/vm/slabinfo.c b/trunk/Documentation/vm/slabinfo.c index e4230ed16ee7..d3ce295bffac 100644 --- a/trunk/Documentation/vm/slabinfo.c +++ b/trunk/Documentation/vm/slabinfo.c @@ -38,7 +38,7 @@ struct slabinfo { unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill; unsigned long cpuslab_flush, deactivate_full, deactivate_empty; unsigned long deactivate_to_head, deactivate_to_tail; - unsigned long deactivate_remote_frees, order_fallback; + unsigned long deactivate_remote_frees; int numa[MAX_NODES]; int numa_partial[MAX_NODES]; } slabinfo[MAX_SLABS]; @@ -293,7 +293,7 @@ int line = 0; void first_line(void) { if (show_activity) - printf("Name Objects Alloc Free %%Fast Fallb O\n"); + printf("Name Objects Alloc Free %%Fast\n"); else printf("Name Objects Objsize Space " "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n"); @@ -573,12 +573,11 @@ void slabcache(struct slabinfo *s) total_alloc = s->alloc_fastpath + s->alloc_slowpath; total_free = s->free_fastpath + s->free_slowpath; - printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d\n", + printf("%-21s %8ld %8ld %8ld %3ld %3ld \n", s->name, s->objects, total_alloc, total_free, total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0, - total_free ? (s->free_fastpath * 100 / total_free) : 0, - s->order_fallback, s->order); + total_free ? (s->free_fastpath * 100 / total_free) : 0); } else printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n", @@ -1189,7 +1188,6 @@ void read_slab_dir(void) slab->deactivate_to_head = get_obj("deactivate_to_head"); slab->deactivate_to_tail = get_obj("deactivate_to_tail"); slab->deactivate_remote_frees = get_obj("deactivate_remote_frees"); - slab->order_fallback = get_obj("order_fallback"); chdir(".."); if (slab->name[0] == ':') alias_targets++; diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f5583dc7ea39..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 @@ -2112,10 +2104,12 @@ L: netdev@vger.kernel.org S: Maintained INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe) -P: Jeff Kirsher -M: jeffrey.t.kirsher@intel.com +P: Auke Kok +M: auke-jan.h.kok@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com +P: Jeff Kirsher +M: jeffrey.t.kirsher@intel.com P: Bruce Allan M: bruce.w.allan@intel.com P: John Ronciak @@ -3128,7 +3122,7 @@ PCI SUBSYSTEM P: Jesse Barnes M: jbarnes@virtuousgeek.org L: linux-kernel@vger.kernel.org -L: linux-pci@vger.kernel.org +L: linux-pci@atrey.karlin.mff.cuni.cz T: git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git S: Supported @@ -4049,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 4492984efc09..d3634cd6fe35 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 26 -EXTRAVERSION = -rc1 +SUBLEVEL = 25 +EXTRAVERSION = NAME = Funky Weasel is Jiggy wit it # *DOCUMENTATION* @@ -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/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 32ca1b927307..9fee37e2596f 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -981,18 +981,27 @@ asmlinkage int osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, struct timeval32 __user *tvp) { - s64 timeout = MAX_SCHEDULE_TIMEOUT; + fd_set_bits fds; + char *bits; + size_t size; + long timeout; + int ret = -EINVAL; + struct fdtable *fdt; + int max_fds; + + timeout = MAX_SCHEDULE_TIMEOUT; if (tvp) { time_t sec, usec; if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp)) || __get_user(sec, &tvp->tv_sec) || __get_user(usec, &tvp->tv_usec)) { - return -EFAULT; + ret = -EFAULT; + goto out_nofds; } if (sec < 0 || usec < 0) - return -EINVAL; + goto out_nofds; if ((unsigned long) sec < MAX_SELECT_SECONDS) { timeout = (usec + 1000000/HZ - 1) / (1000000/HZ); @@ -1000,8 +1009,60 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, } } + rcu_read_lock(); + fdt = files_fdtable(current->files); + max_fds = fdt->max_fds; + rcu_read_unlock(); + if (n < 0 || n > max_fds) + goto out_nofds; + + /* + * We need 6 bitmaps (in/out/ex for both incoming and outgoing), + * since we used fdset we need to allocate memory in units of + * long-words. + */ + ret = -ENOMEM; + size = FDS_BYTES(n); + bits = kmalloc(6 * size, GFP_KERNEL); + if (!bits) + goto out_nofds; + fds.in = (unsigned long *) bits; + fds.out = (unsigned long *) (bits + size); + fds.ex = (unsigned long *) (bits + 2*size); + fds.res_in = (unsigned long *) (bits + 3*size); + fds.res_out = (unsigned long *) (bits + 4*size); + fds.res_ex = (unsigned long *) (bits + 5*size); + + if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) || + (ret = get_fd_set(n, outp->fds_bits, fds.out)) || + (ret = get_fd_set(n, exp->fds_bits, fds.ex))) + goto out; + zero_fd_set(n, fds.res_in); + zero_fd_set(n, fds.res_out); + zero_fd_set(n, fds.res_ex); + + ret = do_select(n, &fds, &timeout); + /* OSF does not copy back the remaining time. */ - return core_sys_select(n, inp, outp, exp, &timeout); + + if (ret < 0) + goto out; + if (!ret) { + ret = -ERESTARTNOHAND; + if (signal_pending(current)) + goto out; + ret = 0; + } + + if (set_fd_set(n, inp->fds_bits, fds.res_in) || + set_fd_set(n, outp->fds_bits, fds.res_out) || + set_fd_set(n, exp->fds_bits, fds.res_ex)) + ret = -EFAULT; + + out: + kfree(bits); + out_nofds: + return ret; } struct rusage32 { diff --git a/trunk/arch/arm/kernel/sys_arm.c b/trunk/arch/arm/kernel/sys_arm.c index 0128687ba0f7..9bd1870d980e 100644 --- a/trunk/arch/arm/kernel/sys_arm.c +++ b/trunk/arch/arm/kernel/sys_arm.c @@ -34,6 +34,23 @@ extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr); +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + /* common code for old and new mmaps */ inline long do_mmap2( unsigned long addr, unsigned long len, diff --git a/trunk/arch/avr32/kernel/sys_avr32.c b/trunk/arch/avr32/kernel/sys_avr32.c index 8e8911e55c8f..8deb6003ee62 100644 --- a/trunk/arch/avr32/kernel/sys_avr32.c +++ b/trunk/arch/avr32/kernel/sys_avr32.c @@ -14,6 +14,19 @@ #include #include +asmlinkage int sys_pipe(unsigned long __user *filedes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(filedes, fd, sizeof(fd))) + error = -EFAULT; + } + return error; +} + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, off_t offset) diff --git a/trunk/arch/blackfin/kernel/sys_bfin.c b/trunk/arch/blackfin/kernel/sys_bfin.c index fce49d7cf001..efb7b25a2633 100644 --- a/trunk/arch/blackfin/kernel/sys_bfin.c +++ b/trunk/arch/blackfin/kernel/sys_bfin.c @@ -45,6 +45,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2 * sizeof(int))) + error = -EFAULT; + } + return error; +} + /* common code for old and new mmaps */ static inline long do_mmap2(unsigned long addr, unsigned long len, diff --git a/trunk/arch/cris/kernel/sys_cris.c b/trunk/arch/cris/kernel/sys_cris.c index d124066e1728..8b9984197edc 100644 --- a/trunk/arch/cris/kernel/sys_cris.c +++ b/trunk/arch/cris/kernel/sys_cris.c @@ -40,11 +40,8 @@ asmlinkage int sys_pipe(unsigned long __user * fildes) error = do_pipe(fd); unlock_kernel(); if (!error) { - if (copy_to_user(fildes, fd, 2*sizeof(int))) { - sys_close(fd[0]); - sys_close(fd[1]); + if (copy_to_user(fildes, fd, 2*sizeof(int))) error = -EFAULT; - } } return error; } diff --git a/trunk/arch/frv/kernel/sys_frv.c b/trunk/arch/frv/kernel/sys_frv.c index 49b2cf2c38f3..04c6b1677ccf 100644 --- a/trunk/arch/frv/kernel/sys_frv.c +++ b/trunk/arch/frv/kernel/sys_frv.c @@ -28,6 +28,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage long sys_pipe(unsigned long __user * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) 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/h8300/kernel/sys_h8300.c b/trunk/arch/h8300/kernel/sys_h8300.c index 2745656dcc52..00608be6d567 100644 --- a/trunk/arch/h8300/kernel/sys_h8300.c +++ b/trunk/arch/h8300/kernel/sys_h8300.c @@ -27,6 +27,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + /* common code for old and new mmaps */ static inline long do_mmap2( unsigned long addr, unsigned long len, 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/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index c1ad27de2dd2..7fbb51e10bbe 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -867,7 +867,7 @@ pfm_rvfree(void *mem, unsigned long size) } static pfm_context_t * -pfm_context_alloc(int ctx_flags) +pfm_context_alloc(void) { pfm_context_t *ctx; @@ -878,46 +878,6 @@ pfm_context_alloc(int ctx_flags) ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL); if (ctx) { DPRINT(("alloc ctx @%p\n", ctx)); - - /* - * init context protection lock - */ - spin_lock_init(&ctx->ctx_lock); - - /* - * context is unloaded - */ - ctx->ctx_state = PFM_CTX_UNLOADED; - - /* - * initialization of context's flags - */ - ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; - ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; - ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; - /* - * will move to set properties - * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; - */ - - /* - * init restart semaphore to locked - */ - init_completion(&ctx->ctx_restart_done); - - /* - * activation is used in SMP only - */ - ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; - SET_LAST_CPU(ctx, -1); - - /* - * initialize notification message queue - */ - ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; - init_waitqueue_head(&ctx->ctx_msgq_wait); - init_waitqueue_head(&ctx->ctx_zombieq); - } return ctx; } @@ -2205,21 +2165,28 @@ static struct dentry_operations pfmfs_dentry_operations = { }; -static struct file * -pfm_alloc_file(pfm_context_t *ctx) +static int +pfm_alloc_fd(struct file **cfile) { - struct file *file; - struct inode *inode; - struct dentry *dentry; + int fd, ret = 0; + struct file *file = NULL; + struct inode * inode; char name[32]; struct qstr this; + fd = get_unused_fd(); + if (fd < 0) return -ENFILE; + + ret = -ENFILE; + + file = get_empty_filp(); + if (!file) goto out; + /* * allocate a new inode */ inode = new_inode(pfmfs_mnt->mnt_sb); - if (!inode) - return ERR_PTR(-ENOMEM); + if (!inode) goto out; DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode)); @@ -2232,28 +2199,59 @@ pfm_alloc_file(pfm_context_t *ctx) this.len = strlen(name); this.hash = inode->i_ino; + ret = -ENOMEM; + /* * allocate a new dcache entry */ - dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); - if (!dentry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } + file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); + if (!file->f_path.dentry) goto out; - dentry->d_op = &pfmfs_dentry_operations; - d_add(dentry, inode); + file->f_path.dentry->d_op = &pfmfs_dentry_operations; - file = alloc_file(pfmfs_mnt, dentry, FMODE_READ, &pfm_file_ops); - if (!file) { - dput(dentry); - return ERR_PTR(-ENFILE); - } + d_add(file->f_path.dentry, inode); + file->f_path.mnt = mntget(pfmfs_mnt); + file->f_mapping = inode->i_mapping; + file->f_op = &pfm_file_ops; + file->f_mode = FMODE_READ; file->f_flags = O_RDONLY; - file->private_data = ctx; + file->f_pos = 0; + + /* + * may have to delay until context is attached? + */ + fd_install(fd, file); + + /* + * the file structure we will use + */ + *cfile = file; + + return fd; +out: + if (file) put_filp(file); + put_unused_fd(fd); + return ret; +} + +static void +pfm_free_fd(int fd, struct file *file) +{ + struct files_struct *files = current->files; + struct fdtable *fdt; - return file; + /* + * there ie no fd_uninstall(), so we do it here + */ + spin_lock(&files->file_lock); + fdt = files_fdtable(files); + rcu_assign_pointer(fdt->fd[fd], NULL); + spin_unlock(&files->file_lock); + + if (file) + put_filp(file); + put_unused_fd(fd); } static int @@ -2477,7 +2475,6 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t /* link buffer format and context */ ctx->ctx_buf_fmt = fmt; - ctx->ctx_fl_is_sampling = 1; /* assume record() is defined */ /* * check if buffer format wants to use perfmon buffer allocation/mapping service @@ -2672,45 +2669,78 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg { pfarg_context_t *req = (pfarg_context_t *)arg; struct file *filp; - struct path path; int ctx_flags; - int fd; int ret; /* let's check the arguments first */ ret = pfarg_is_sane(current, req); - if (ret < 0) - return ret; + if (ret < 0) return ret; ctx_flags = req->ctx_flags; ret = -ENOMEM; - fd = get_unused_fd(); - if (fd < 0) - return fd; + ctx = pfm_context_alloc(); + if (!ctx) goto error; - ctx = pfm_context_alloc(ctx_flags); - if (!ctx) - goto error; + ret = pfm_alloc_fd(&filp); + if (ret < 0) goto error_file; - filp = pfm_alloc_file(ctx); - if (IS_ERR(filp)) { - ret = PTR_ERR(filp); - goto error_file; - } + req->ctx_fd = ctx->ctx_fd = ret; - req->ctx_fd = ctx->ctx_fd = fd; + /* + * attach context to file + */ + filp->private_data = ctx; /* * does the user want to sample? */ if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) { ret = pfm_setup_buffer_fmt(current, filp, ctx, ctx_flags, 0, req); - if (ret) - goto buffer_error; + if (ret) goto buffer_error; } + /* + * init context protection lock + */ + spin_lock_init(&ctx->ctx_lock); + + /* + * context is unloaded + */ + ctx->ctx_state = PFM_CTX_UNLOADED; + + /* + * initialization of context's flags + */ + ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; + ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; + ctx->ctx_fl_is_sampling = ctx->ctx_buf_fmt ? 1 : 0; /* assume record() is defined */ + ctx->ctx_fl_no_msg = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0; + /* + * will move to set properties + * ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; + */ + + /* + * init restart semaphore to locked + */ + init_completion(&ctx->ctx_restart_done); + + /* + * activation is used in SMP only + */ + ctx->ctx_last_activation = PFM_INVALID_ACTIVATION; + SET_LAST_CPU(ctx, -1); + + /* + * initialize notification message queue + */ + ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0; + init_waitqueue_head(&ctx->ctx_msgq_wait); + init_waitqueue_head(&ctx->ctx_zombieq); + DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d no_msg=%d ctx_fd=%d \n", ctx, ctx_flags, @@ -2725,14 +2755,10 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg */ pfm_reset_pmu_state(ctx); - fd_install(fd, filp); - return 0; buffer_error: - path = filp->f_path; - put_filp(filp); - path_put(&path); + pfm_free_fd(ctx->ctx_fd, filp); if (ctx->ctx_buf_fmt) { pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs); @@ -2741,7 +2767,6 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg pfm_context_free(ctx); error: - put_unused_fd(fd); return ret; } 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/sys_m32r.c b/trunk/arch/m32r/kernel/sys_m32r.c index 319c79720b8a..6d7a80fdad48 100644 --- a/trunk/arch/m32r/kernel/sys_m32r.c +++ b/trunk/arch/m32r/kernel/sys_m32r.c @@ -90,11 +90,8 @@ sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2, error = do_pipe(fd); if (!error) { - if (copy_to_user((void __user *)r0, fd, 2*sizeof(int))) { - sys_close(fd[0]); - sys_close(fd[1]); + if (copy_to_user((void __user *)r0, fd, 2*sizeof(int))) error = -EFAULT; - } } return error; } 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/m68k/kernel/sys_m68k.c b/trunk/arch/m68k/kernel/sys_m68k.c index 7f54efaf60bb..e892f17ba3fa 100644 --- a/trunk/arch/m68k/kernel/sys_m68k.c +++ b/trunk/arch/m68k/kernel/sys_m68k.c @@ -30,6 +30,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long __user * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + /* common code for old and new mmaps */ static inline long do_mmap2( unsigned long addr, unsigned long len, diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index 75b8340b254b..fd4858e2dd63 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -468,26 +468,15 @@ static inline void access_error040(struct frame *fp) * (if do_page_fault didn't fix the mapping, * the writeback won't do good) */ -disable_wb: #ifdef DEBUG printk(".. disabling wb2\n"); #endif if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr) fp->un.fmt7.wb2s &= ~WBV_040; - if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr) - fp->un.fmt7.wb3s &= ~WBV_040; } - } else { - /* In case of a bus error we either kill the process or expect - * the kernel to catch the fault, which then is also responsible - * for cleaning up the mess. - */ - current->thread.signo = SIGBUS; - current->thread.faddr = fp->un.fmt7.faddr; - if (send_fault_sig(&fp->ptregs) >= 0) - printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw, - fp->un.fmt7.faddr); - goto disable_wb; + } else if (send_fault_sig(&fp->ptregs) > 0) { + printk("68040 access error, ssw=%x\n", ssw); + trap_c(fp); } do_040writebacks(fp); diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index ad3e3bacae39..735a49b4b936 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -48,6 +48,9 @@ struct mac_booter_data mac_bi_data; int mac_bisize = sizeof mac_bi_data; +struct mac_hw_present mac_hw_present; +EXPORT_SYMBOL(mac_hw_present); + /* New m68k bootinfo stuff and videobase */ extern int m68k_num_memory; @@ -814,6 +817,27 @@ void __init mac_identify(void) m68k_ramdisk.addr, m68k_ramdisk.size); #endif + /* + * TODO: set the various fields in macintosh_config->hw_present here! + */ + switch (macintosh_config->scsi_type) { + case MAC_SCSI_OLD: + MACHW_SET(MAC_SCSI_80); + break; + case MAC_SCSI_QUADRA: + case MAC_SCSI_QUADRA2: + case MAC_SCSI_QUADRA3: + MACHW_SET(MAC_SCSI_96); + if ((macintosh_config->ident == MAC_MODEL_Q900) || + (macintosh_config->ident == MAC_MODEL_Q950)) + MACHW_SET(MAC_SCSI_96_2); + break; + default: + printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n"); + MACHW_SET(MAC_SCSI_80); + break; + } + iop_init(); via_init(); oss_init(); 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/sys_m68k.c b/trunk/arch/m68knommu/kernel/sys_m68k.c index 700281638629..65f7a95f056e 100644 --- a/trunk/arch/m68knommu/kernel/sys_m68k.c +++ b/trunk/arch/m68knommu/kernel/sys_m68k.c @@ -28,6 +28,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + /* common code for old and new mmaps */ static inline long do_mmap2( unsigned long addr, unsigned long len, 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/mips/kernel/irixioctl.c b/trunk/arch/mips/kernel/irixioctl.c index b39bdba82e02..2bde200d5ad0 100644 --- a/trunk/arch/mips/kernel/irixioctl.c +++ b/trunk/arch/mips/kernel/irixioctl.c @@ -27,6 +27,33 @@ struct irix_termios { cc_t c_cc[NCCS]; }; +extern void start_tty(struct tty_struct *tty); +static struct tty_struct *get_tty(int fd) +{ + struct file *filp; + struct tty_struct *ttyp = NULL; + + rcu_read_lock(); + filp = fcheck(fd); + if(filp && filp->private_data) { + ttyp = (struct tty_struct *) filp->private_data; + + if(ttyp->magic != TTY_MAGIC) + ttyp =NULL; + } + rcu_read_unlock(); + return ttyp; +} + +static struct tty_struct *get_real_tty(struct tty_struct *tp) +{ + if (tp->driver->type == TTY_DRIVER_TYPE_PTY && + tp->driver->subtype == PTY_TYPE_MASTER) + return tp->link; + else + return tp; +} + asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg) { struct tty_struct *tp, *rtp; @@ -119,24 +146,34 @@ asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg) error = sys_ioctl(fd, TIOCNOTTY, arg); break; - case 0x00007416: { - pid_t pid; + case 0x00007416: #ifdef DEBUG_IOCTLS printk("TIOCGSID, %08lx) ", arg); #endif - old_fs = get_fs(); set_fs(get_ds()); - error = sys_ioctl(fd, TIOCGSID, (unsigned long)&pid); - set_fs(old_fs); - if (!error) - error = put_user(pid, (unsigned long __user *) arg); + tp = get_tty(fd); + if(!tp) { + error = -EINVAL; + break; + } + rtp = get_real_tty(tp); +#ifdef DEBUG_IOCTLS + printk("rtp->session=%d ", rtp->session); +#endif + error = put_user(rtp->session, (unsigned long __user *) arg); break; - } + case 0x746e: /* TIOCSTART, same effect as hitting ^Q */ #ifdef DEBUG_IOCTLS printk("TIOCSTART, %08lx) ", arg); #endif - error = sys_ioctl(fd, TCXONC, TCOON); + tp = get_tty(fd); + if(!tp) { + error = -EINVAL; + break; + } + rtp = get_real_tty(tp); + start_tty(rtp); break; case 0x20006968: diff --git a/trunk/arch/mips/kernel/kspd.c b/trunk/arch/mips/kernel/kspd.c index ceb62dce1c9c..998c4efcce88 100644 --- a/trunk/arch/mips/kernel/kspd.c +++ b/trunk/arch/mips/kernel/kspd.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mn10300/kernel/sys_mn10300.c b/trunk/arch/mn10300/kernel/sys_mn10300.c index bca5a84dc72c..5f17a1ebc825 100644 --- a/trunk/arch/mn10300/kernel/sys_mn10300.c +++ b/trunk/arch/mn10300/kernel/sys_mn10300.c @@ -28,6 +28,23 @@ #define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */ +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way Unix traditionally does this, though. + */ +asmlinkage long sys_pipe(unsigned long __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2 * sizeof(int))) + error = -EFAULT; + } + return error; +} + /* * memory mapping syscall */ diff --git a/trunk/arch/parisc/kernel/sys_parisc.c b/trunk/arch/parisc/kernel/sys_parisc.c index 71b31957c8f1..4f589216b39e 100644 --- a/trunk/arch/parisc/kernel/sys_parisc.c +++ b/trunk/arch/parisc/kernel/sys_parisc.c @@ -33,6 +33,19 @@ #include #include +int sys_pipe(int __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + static unsigned long get_unshared_area(unsigned long addr, unsigned long len) { struct vm_area_struct *vma; diff --git a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts index bba234eb14a9..1f2f1e0a5571 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8610_hpcd.dts @@ -21,7 +21,6 @@ serial1 = &serial1; pci0 = &pci0; pci1 = &pci1; - pci2 = &pci2; }; cpus { @@ -106,7 +105,7 @@ compatible = "ns16550"; reg = <0x4600 0x100>; clock-frequency = <0>; - interrupts = <42 2>; + interrupts = <28 2>; interrupt-parent = <&mpic>; }; @@ -323,24 +322,4 @@ }; }; }; - - pci2: pcie@e0009000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - device_type = "pci"; - compatible = "fsl,mpc8641-pcie"; - reg = <0xe0009000 0x00001000>; - ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000 - 0x01000000 0 0x00000000 0xe2000000 0 0x00100000>; - bus-range = <0 255>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0x0000 0 0 1 &mpic 4 1 - 0x0000 0 0 2 &mpic 5 1 - 0x0000 0 0 3 &mpic 6 1 - 0x0000 0 0 4 &mpic 7 1>; - interrupt-parent = <&mpic>; - interrupts = <25 2>; - clock-frequency = <33333333>; - }; }; diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index 71d79e428d20..7a64c564f6e6 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25 -# Mon Apr 28 12:39:10 2008 +# Linux kernel version: 2.6.25-rc6 +# Thu Mar 20 11:07:04 2008 # CONFIG_PPC64=y @@ -30,9 +30,6 @@ CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_IRQ_PER_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y CONFIG_ARCH_HAS_ILOG2_U64=y @@ -76,6 +73,8 @@ CONFIG_POSIX_MQUEUE=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_USER_SCHED is not set +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -162,6 +161,7 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set # CONFIG_PPC_PASEMI is not set +# CONFIG_PPC_CELLEB is not set CONFIG_PPC_PS3=y # @@ -181,7 +181,6 @@ CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set -# CONFIG_PPC_CELLEB is not set # # Cell Broadband Engine options @@ -206,9 +205,9 @@ CONFIG_SPU_BASE=y # # Kernel options # -CONFIG_TICK_ONESHOT=y +# CONFIG_TICK_ONESHOT is not set # CONFIG_NO_HZ is not set -CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIGH_RES_TIMERS is not set CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y @@ -222,6 +221,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y CONFIG_BINFMT_MISC=y +CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_IOMMU_VMERGE is not set CONFIG_IOMMU_HELPER=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y @@ -255,7 +255,6 @@ CONFIG_BOUNCE=y CONFIG_ARCH_MEMORY_PROBE=y # CONFIG_PPC_HAS_HASH_64K is not set # CONFIG_PPC_64K_PAGES is not set -CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -273,9 +272,7 @@ CONFIG_GENERIC_ISA_DMA=y # CONFIG_PCI_SYSCALL is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set -CONFIG_PAGE_OFFSET=0xc000000000000000 CONFIG_KERNEL_START=0xc000000000000000 -CONFIG_PHYSICAL_START=0x00000000 # # Networking @@ -295,7 +292,7 @@ CONFIG_XFRM=y # CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y @@ -304,7 +301,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set @@ -336,10 +332,8 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=y -CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MROUTE is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set @@ -398,6 +392,8 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -511,7 +507,6 @@ CONFIG_WLAN_80211=y # CONFIG_LIBERTAS is not set # CONFIG_USB_ZD1201 is not set # CONFIG_USB_NET_RNDIS_WLAN is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_HOSTAP is not set # @@ -583,7 +578,6 @@ CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_SPACEBALL is not set # CONFIG_JOYSTICK_STINGER is not set # CONFIG_JOYSTICK_TWIDJOY is not set -# CONFIG_JOYSTICK_ZHENHUA is not set # CONFIG_JOYSTICK_JOYDUMP is not set # CONFIG_JOYSTICK_XPAD is not set # CONFIG_INPUT_TABLET is not set @@ -647,7 +641,6 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set # # Multimedia devices @@ -767,6 +760,10 @@ CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 # # CONFIG_SND_SOC is not set +# +# SoC Audio support for SuperH +# + # # ALSA SoC audio for Freescale SOCs # @@ -852,7 +849,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -897,6 +893,10 @@ CONFIG_USB_MON=y # CONFIG_EDAC is not set # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set + +# +# Userspace I/O +# # CONFIG_UIO is not set # @@ -986,6 +986,7 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y @@ -1058,10 +1059,9 @@ CONFIG_NLS_ISO8859_1=y # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set -CONFIG_CRC_ITU_T=m +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set @@ -1071,7 +1071,6 @@ CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_HAVE_LMB=y # # Kernel hacking @@ -1079,7 +1078,6 @@ CONFIG_HAVE_LMB=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set @@ -1095,16 +1093,12 @@ CONFIG_SCHED_DEBUG=y # CONFIG_RT_MUTEX_TESTER is not set CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_SG is not set # CONFIG_BOOT_PRINTK_DELAY is not set @@ -1127,81 +1121,51 @@ CONFIG_IRQSTACKS=y # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y - -# -# Crypto core or helper -# CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_GF128MUL=m -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_SEQIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CTR=m -# CONFIG_CRYPTO_CTS is not set -CONFIG_CRYPTO_ECB=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# +CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_CCM=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST6 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m # CONFIG_CRYPTO_KHAZAD is not set -CONFIG_CRYPTO_SALSA20=m +# CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# +CONFIG_CRYPTO_SALSA20=m # CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_HW=y # CONFIG_PPC_CLOCK is not set -# CONFIG_VIRTUALIZATION is not set diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 1457aa0a08f1..be35ffae10f0 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -386,8 +386,6 @@ static void __init smp_create_idle(unsigned int cpu) panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p)); #ifdef CONFIG_PPC64 paca[cpu].__current = p; - paca[cpu].kstack = (unsigned long) task_thread_info(p) - + THREAD_SIZE - STACK_FRAME_OVERHEAD; #endif current_set[cpu] = task_thread_info(p); task_thread_info(p)->cpu = cpu; diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index 4fe69ca24481..e722a4eeb5d0 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -136,6 +136,23 @@ int sys_ipc(uint call, int first, unsigned long second, long third, return ret; } +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +int sys_pipe(int __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + static inline unsigned long do_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off, int shift) 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/powerpc/kvm/booke_guest.c b/trunk/arch/powerpc/kvm/booke_guest.c index 712d89a28c46..6d9884a6884a 100644 --- a/trunk/arch/powerpc/kvm/booke_guest.c +++ b/trunk/arch/powerpc/kvm/booke_guest.c @@ -49,7 +49,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "inst_emu", VCPU_STAT(emulated_inst_exits) }, { "dec", VCPU_STAT(dec_exits) }, { "ext_intr", VCPU_STAT(ext_intr_exits) }, - { "halt_wakeup", VCPU_STAT(halt_wakeup) }, { NULL } }; @@ -339,11 +338,6 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, } break; - case BOOKE_INTERRUPT_FP_UNAVAIL: - kvmppc_queue_exception(vcpu, exit_nr); - r = RESUME_GUEST; - break; - case BOOKE_INTERRUPT_DATA_STORAGE: vcpu->arch.dear = vcpu->arch.fault_dear; vcpu->arch.esr = vcpu->arch.fault_esr; diff --git a/trunk/arch/powerpc/kvm/powerpc.c b/trunk/arch/powerpc/kvm/powerpc.c index 777e0f34e0ea..bad40bd2d3ac 100644 --- a/trunk/arch/powerpc/kvm/powerpc.c +++ b/trunk/arch/powerpc/kvm/powerpc.c @@ -36,12 +36,13 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) int kvm_cpu_has_interrupt(struct kvm_vcpu *v) { - return !!(v->arch.pending_exceptions); + /* XXX implement me */ + return 0; } int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) { - return !(v->arch.msr & MSR_WE); + return 1; } @@ -213,11 +214,6 @@ static void kvmppc_decrementer_func(unsigned long data) struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_DECREMENTER); - - if (waitqueue_active(&vcpu->wq)) { - wake_up_interruptible(&vcpu->wq); - vcpu->stat.halt_wakeup++; - } } int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) @@ -343,8 +339,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) int r; sigset_t sigsaved; - vcpu_load(vcpu); - if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); @@ -369,20 +363,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &sigsaved, NULL); - vcpu_put(vcpu); - return r; } int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) { kvmppc_queue_exception(vcpu, BOOKE_INTERRUPT_EXTERNAL); - - if (waitqueue_active(&vcpu->wq)) { - wake_up_interruptible(&vcpu->wq); - vcpu->stat.halt_wakeup++; - } - return 0; } diff --git a/trunk/arch/powerpc/lib/Makefile b/trunk/arch/powerpc/lib/Makefile index f1d2cdc5331b..4bb023f4c869 100644 --- a/trunk/arch/powerpc/lib/Makefile +++ b/trunk/arch/powerpc/lib/Makefile @@ -23,4 +23,3 @@ obj-$(CONFIG_SMP) += locks.o endif obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o -obj-$(CONFIG_HAS_IOMEM) += devres.o diff --git a/trunk/arch/powerpc/lib/devres.c b/trunk/arch/powerpc/lib/devres.c deleted file mode 100644 index 292115d98ea9..000000000000 --- a/trunk/arch/powerpc/lib/devres.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include /* devres_*(), devm_ioremap_release() */ -#include /* ioremap_flags() */ -#include /* EXPORT_SYMBOL() */ - -/** - * devm_ioremap_prot - Managed ioremap_flags() - * @dev: Generic device to remap IO address for - * @offset: BUS offset to map - * @size: Size of map - * @flags: Page flags - * - * Managed ioremap_prot(). Map is automatically unmapped on driver - * detach. - */ -void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset, - size_t size, unsigned long flags) -{ - void __iomem **ptr, *addr; - - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - addr = ioremap_flags(offset, size, flags); - if (addr) { - *ptr = addr; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return addr; -} -EXPORT_SYMBOL(devm_ioremap_prot); diff --git a/trunk/arch/powerpc/mm/slb.c b/trunk/arch/powerpc/mm/slb.c index cf8705e32d60..906daeda59a8 100644 --- a/trunk/arch/powerpc/mm/slb.c +++ b/trunk/arch/powerpc/mm/slb.c @@ -30,7 +30,7 @@ #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else -#define DBG pr_debug +#define DBG(fmt...) #endif extern void slb_allocate_realmode(unsigned long ea); @@ -44,13 +44,13 @@ static void slb_allocate(unsigned long ea) slb_allocate_realmode(ea); } -#define slb_esid_mask(ssize) \ - (((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T) - static inline unsigned long mk_esid_data(unsigned long ea, int ssize, unsigned long slot) { - return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | slot; + unsigned long mask; + + mask = (ssize == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T; + return (ea & mask) | SLB_ESID_V | slot; } #define slb_vsid_shift(ssize) \ @@ -279,8 +279,8 @@ void slb_initialize(void) patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size); - DBG("SLB: linear LLP = %04lx\n", linear_llp); - DBG("SLB: io LLP = %04lx\n", io_llp); + DBG("SLB: linear LLP = %04x\n", linear_llp); + DBG("SLB: io LLP = %04x\n", io_llp); } get_paca()->stab_rr = SLB_NUM_BOLTED; @@ -301,16 +301,11 @@ void slb_initialize(void) create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1); - /* For the boot cpu, we're running on the stack in init_thread_union, - * which is in the first segment of the linear mapping, and also - * get_paca()->kstack hasn't been initialized yet. - * For secondary cpus, we need to bolt the kernel stack entry now. - */ slb_shadow_clear(2); - if (raw_smp_processor_id() != boot_cpuid && - (get_paca()->kstack & slb_esid_mask(mmu_kernel_ssize)) > PAGE_OFFSET) - create_shadowed_slbe(get_paca()->kstack, - mmu_kernel_ssize, lflags, 2); + /* We don't bolt the stack for the time being - we're in boot, + * so the stack is in the bolted segment. By the time it goes + * elsewhere, we'll call _switch() which will bolt in the new + * one. */ asm volatile("isync":::"memory"); } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/coredump.c b/trunk/arch/powerpc/platforms/cell/spufs/coredump.c index af116aadba10..b962c3ab470c 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/coredump.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index e59634f7af96..a14e5cdc2fed 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -167,8 +167,8 @@ static struct irq_chip ps3_irq_chip = { * ps3_private data. */ -static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, - unsigned int *virq) +int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, + unsigned int *virq) { int result; struct ps3_private *pd; @@ -217,7 +217,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, * Clears chip data and calls irq_dispose_mapping() for the virq. */ -static int ps3_virq_destroy(unsigned int virq) +int ps3_virq_destroy(unsigned int virq) { const struct ps3_private *pd = get_irq_chip_data(virq); diff --git a/trunk/arch/powerpc/platforms/pseries/scanlog.c b/trunk/arch/powerpc/platforms/pseries/scanlog.c index 417eca79df69..bec3803f0618 100644 --- a/trunk/arch/powerpc/platforms/pseries/scanlog.c +++ b/trunk/arch/powerpc/platforms/pseries/scanlog.c @@ -55,6 +55,11 @@ static ssize_t scanlog_read(struct file *file, char __user *buf, dp = PDE(inode); data = (unsigned int *)dp->data; + if (!data) { + printk(KERN_ERR "scanlog: read failed no data\n"); + return -EIO; + } + if (count > RTAS_DATA_BUF_SIZE) count = RTAS_DATA_BUF_SIZE; @@ -141,6 +146,11 @@ static int scanlog_open(struct inode * inode, struct file * file) struct proc_dir_entry *dp = PDE(inode); unsigned int *data = (unsigned int *)dp->data; + if (!data) { + printk(KERN_ERR "scanlog: open failed no data\n"); + return -EIO; + } + if (data[0] != 0) { /* This imperfect test stops a second copy of the * data (or a reset while data is being copied) @@ -158,6 +168,10 @@ static int scanlog_release(struct inode * inode, struct file * file) struct proc_dir_entry *dp = PDE(inode); unsigned int *data = (unsigned int *)dp->data; + if (!data) { + printk(KERN_ERR "scanlog: release failed no data\n"); + return -EIO; + } data[0] = 0; return 0; @@ -186,11 +200,12 @@ static int __init scanlog_init(void) if (!data) goto err; - ent = proc_create_data("ppc64/rtas/scan-log-dump", S_IRUSR, NULL, - &scanlog_fops, data); + ent = proc_create("ppc64/rtas/scan-log-dump", S_IRUSR, NULL, + &scanlog_fops); if (!ent) goto err; + ent->data = data; proc_ppc64_scan_log_dump = ent; return 0; diff --git a/trunk/arch/powerpc/sysdev/fsl_rio.c b/trunk/arch/powerpc/sysdev/fsl_rio.c index a0fa4ebb39c6..3d920376f58e 100644 --- a/trunk/arch/powerpc/sysdev/fsl_rio.c +++ b/trunk/arch/powerpc/sysdev/fsl_rio.c @@ -176,7 +176,6 @@ struct rio_priv { /** * fsl_rio_doorbell_send - Send a MPC85xx doorbell message - * @mport: RapidIO master port info * @index: ID of RapidIO interface * @destid: Destination ID of target device * @data: 16-bit info field of RapidIO doorbell message @@ -212,7 +211,6 @@ static int fsl_rio_doorbell_send(struct rio_mport *mport, /** * fsl_local_config_read - Generate a MPC85xx local config space read - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @offset: Offset into configuration space * @len: Length (in bytes) of the maintenance transaction @@ -234,7 +232,6 @@ static int fsl_local_config_read(struct rio_mport *mport, /** * fsl_local_config_write - Generate a MPC85xx local config space write - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @offset: Offset into configuration space * @len: Length (in bytes) of the maintenance transaction @@ -257,7 +254,6 @@ static int fsl_local_config_write(struct rio_mport *mport, /** * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @destid: Destination ID of transaction * @hopcount: Number of hops to target device @@ -299,7 +295,6 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, /** * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction - * @mport: RapidIO master port info * @index: ID of RapdiIO interface * @destid: Destination ID of transaction * @hopcount: Number of hops to target device @@ -990,8 +985,8 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr) } /** - * fsl_rio_setup - Setup Freescale PowerPC RapidIO interface - * @dev: of_device pointer + * fsl_rio_setup - Setup MPC85xx RapidIO interface + * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface * * Initializes MPC85xx RapidIO hardware interface, configures * master port with system-specific info, and registers the diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index 3a7054e2bb75..324c01b70ddd 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -389,8 +389,8 @@ static int __init gfar_of_init(void) } gfar_data.phy_id = *id; - snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx", - (unsigned long long)res.start); + snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%x", + res.start); of_node_put(phy); of_node_put(mdio); diff --git a/trunk/arch/powerpc/sysdev/xilinx_intc.c b/trunk/arch/powerpc/sysdev/xilinx_intc.c index b7aefd0d45cb..ba8eea2bcce0 100644 --- a/trunk/arch/powerpc/sysdev/xilinx_intc.c +++ b/trunk/arch/powerpc/sysdev/xilinx_intc.c @@ -107,7 +107,7 @@ xilinx_intc_init(struct device_node *np) } regs = ioremap(res.start, 32); - printk(KERN_INFO "Xilinx intc at 0x%08LX mapped to 0x%p\n", + printk(KERN_INFO "Xilinx intc at 0x%08X mapped to 0x%p\n", res.start, regs); /* Setup interrupt controller */ diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 1d035082e78e..29a7940f284f 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -430,13 +430,6 @@ config CMM_IUCV Select this option to enable the special message interface to the cooperative memory management. -config PAGE_STATES - bool "Unused page notification" - help - This enables the notification of unused pages to the - hypervisor. The ESSA instruction is used to do the states - changes between a page that has content and the unused state. - config VIRT_TIMER bool "Virtual CPU timer support" help diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index d003a6e16afb..743d54f0b8db 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -121,7 +121,7 @@ sys32_ptrace_wrapper: lgfr %r3,%r3 # long llgtr %r4,%r4 # long llgfr %r5,%r5 # long - jg compat_sys_ptrace # branch to system call + jg sys_ptrace # branch to system call .globl sys32_alarm_wrapper sys32_alarm_wrapper: diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index 708cf9cf9a35..bdbb3bcd78a5 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -279,6 +279,8 @@ sysc_do_restart: st %r2,SP_R2(%r15) # store return value (change R2 on stack) sysc_return: + tm SP_PSW+1(%r15),0x01 # returning to user ? + bno BASED(sysc_restore) tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_restore: @@ -310,8 +312,6 @@ sysc_work_loop: # One of the work bits is on. Find out which one. # sysc_work: - tm SP_PSW+1(%r15),0x01 # returning to user ? - bno BASED(sysc_restore) tm __TI_flags+3(%r9),_TIF_MCCK_PENDING bo BASED(sysc_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED @@ -602,6 +602,12 @@ io_no_vtime: la %r2,SP_PTREGS(%r15) # address of register-save area basr %r14,%r1 # branch to standard irq handler io_return: + tm SP_PSW+1(%r15),0x01 # returning to user ? +#ifdef CONFIG_PREEMPT + bno BASED(io_preempt) # no -> check for preemptive scheduling +#else + bno BASED(io_restore) # no-> skip resched & signal +#endif tm __TI_flags+3(%r9),_TIF_WORK_INT bnz BASED(io_work) # there is work to do (signals etc.) io_restore: @@ -623,18 +629,10 @@ io_restore_trace_psw: .long 0, io_restore_trace + 0x80000000 #endif -# -# switch to kernel stack, then check the TIF bits -# -io_work: - tm SP_PSW+1(%r15),0x01 # returning to user ? -#ifndef CONFIG_PREEMPT - bno BASED(io_restore) # no-> skip resched & signal -#else - bnz BASED(io_work_user) # no -> check for preemptive scheduling - # check for preemptive scheduling +#ifdef CONFIG_PREEMPT +io_preempt: icm %r0,15,__TI_precount(%r9) - bnz BASED(io_restore) # preemption disabled + bnz BASED(io_restore) l %r1,SP_R15(%r15) s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) @@ -648,7 +646,10 @@ io_resume_loop: br %r1 # call schedule #endif -io_work_user: +# +# switch to kernel stack, then check the TIF bits +# +io_work: l %r1,__LC_KERNEL_STACK s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index fee10177dbfc..5a4a7bcd2bba 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -271,6 +271,8 @@ sysc_noemu: stg %r2,SP_R2(%r15) # store return value (change R2 on stack) sysc_return: + tm SP_PSW+1(%r15),0x01 # returning to user ? + jno sysc_restore tm __TI_flags+7(%r9),_TIF_WORK_SVC jnz sysc_work # there is work to do (signals etc.) sysc_restore: @@ -302,8 +304,6 @@ sysc_work_loop: # One of the work bits is on. Find out which one. # sysc_work: - tm SP_PSW+1(%r15),0x01 # returning to user ? - jno sysc_restore tm __TI_flags+7(%r9),_TIF_MCCK_PENDING jo sysc_mcck_pending tm __TI_flags+7(%r9),_TIF_NEED_RESCHED @@ -585,6 +585,12 @@ io_no_vtime: la %r2,SP_PTREGS(%r15) # address of register-save area brasl %r14,do_IRQ # call standard irq handler io_return: + tm SP_PSW+1(%r15),0x01 # returning to user ? +#ifdef CONFIG_PREEMPT + jno io_preempt # no -> check for preemptive scheduling +#else + jno io_restore # no-> skip resched & signal +#endif tm __TI_flags+7(%r9),_TIF_WORK_INT jnz io_work # there is work to do (signals etc.) io_restore: @@ -606,41 +612,10 @@ io_restore_trace_psw: .quad 0, io_restore_trace #endif -# -# There is work todo, we need to check if we return to userspace, then -# check, if we are in SIE, if yes leave it -# -io_work: - tm SP_PSW+1(%r15),0x01 # returning to user ? -#ifndef CONFIG_PREEMPT -#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - jnz io_work_user # yes -> no need to check for SIE - la %r1, BASED(sie_opcode) # we return to kernel here - lg %r2, SP_PSW+8(%r15) - clc 0(2,%r1), 0(%r2) # is current instruction = SIE? - jne io_restore # no-> return to kernel - lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE - aghi %r1, 4 - stg %r1, SP_PSW+8(%r15) - j io_restore # return to kernel -#else - jno io_restore # no-> skip resched & signal -#endif -#else - jnz io_work_user # yes -> do resched & signal -#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) - la %r1, BASED(sie_opcode) - lg %r2, SP_PSW+8(%r15) - clc 0(2,%r1), 0(%r2) # is current instruction = SIE? - jne 0f # no -> leave PSW alone - lg %r1, SP_PSW+8(%r15) # yes-> add 4 bytes to leave SIE - aghi %r1, 4 - stg %r1, SP_PSW+8(%r15) -0: -#endif - # check for preemptive scheduling +#ifdef CONFIG_PREEMPT +io_preempt: icm %r0,15,__TI_precount(%r9) - jnz io_restore # preemption is disabled + jnz io_restore # switch to kernel stack lg %r1,SP_R15(%r15) aghi %r1,-SP_SIZE @@ -654,7 +629,10 @@ io_resume_loop: jg preempt_schedule_irq #endif -io_work_user: +# +# switch to kernel stack, then check TIF bits +# +io_work: lg %r1,__LC_KERNEL_STACK aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) @@ -675,11 +653,6 @@ io_work_loop: j io_restore io_work_done: -#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) -sie_opcode: - .long 0xb2140000 -#endif - # # _TIF_MCCK_PENDING is set, call handler # diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index 35827b9bd4d1..7f4270163744 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -292,7 +292,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) return 0; } -long arch_ptrace(struct task_struct *child, long request, long addr, long data) +static int +do_ptrace_normal(struct task_struct *child, long request, long addr, long data) { ptrace_area parea; int copied, ret; @@ -528,19 +529,35 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) return 0; } -long compat_arch_ptrace(struct task_struct *child, compat_long_t request, - compat_ulong_t caddr, compat_ulong_t cdata) +static int +do_ptrace_emu31(struct task_struct *child, long request, long addr, long data) { - unsigned long addr = caddr; - unsigned long data = cdata; + unsigned int tmp; /* 4 bytes !! */ ptrace_area_emu31 parea; int copied, ret; switch (request) { + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + /* read word at location addr. */ + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); + if (copied != sizeof(tmp)) + return -EIO; + return put_user(tmp, (unsigned int __force __user *) data); + case PTRACE_PEEKUSR: /* read the word at location addr in the USER area. */ return peek_user_emu31(child, addr, data); + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: + /* write the word at location addr. */ + tmp = data; + copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1); + if (copied != sizeof(tmp)) + return -EIO; + return 0; + case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ return poke_user_emu31(child, addr, data); @@ -570,11 +587,82 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, copied += sizeof(unsigned int); } return 0; + case PTRACE_GETEVENTMSG: + return put_user((__u32) child->ptrace_message, + (unsigned int __force __user *) data); + case PTRACE_GETSIGINFO: + if (child->last_siginfo == NULL) + return -EINVAL; + return copy_siginfo_to_user32((compat_siginfo_t + __force __user *) data, + child->last_siginfo); + case PTRACE_SETSIGINFO: + if (child->last_siginfo == NULL) + return -EINVAL; + return copy_siginfo_from_user32(child->last_siginfo, + (compat_siginfo_t + __force __user *) data); } - return compat_ptrace_request(child, request, addr, data); + return ptrace_request(child, request, addr, data); } #endif +long arch_ptrace(struct task_struct *child, long request, long addr, long data) +{ + switch (request) { + case PTRACE_SYSCALL: + /* continue and stop at next (return from) syscall */ + case PTRACE_CONT: + /* restart after signal. */ + if (!valid_signal(data)) + return -EIO; + if (request == PTRACE_SYSCALL) + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + else + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + child->exit_code = data; + /* make sure the single step bit is not set. */ + user_disable_single_step(child); + wake_up_process(child); + return 0; + + case PTRACE_KILL: + /* + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to + * exit. + */ + if (child->exit_state == EXIT_ZOMBIE) /* already dead */ + return 0; + child->exit_code = SIGKILL; + /* make sure the single step bit is not set. */ + user_disable_single_step(child); + wake_up_process(child); + return 0; + + case PTRACE_SINGLESTEP: + /* set the trap flag. */ + if (!valid_signal(data)) + return -EIO; + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + child->exit_code = data; + user_enable_single_step(child); + /* give it a chance to run. */ + wake_up_process(child); + return 0; + + /* Do requests that differ for 31/64 bit */ + default: +#ifdef CONFIG_COMPAT + if (test_thread_flag(TIF_31BIT)) + return do_ptrace_emu31(child, request, addr, data); +#endif + return do_ptrace_normal(child, request, addr, data); + } + /* Not reached. */ + return -EIO; +} + asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit) { diff --git a/trunk/arch/s390/kernel/sys_s390.c b/trunk/arch/s390/kernel/sys_s390.c index 5fdb799062b7..988d0d64c2c8 100644 --- a/trunk/arch/s390/kernel/sys_s390.c +++ b/trunk/arch/s390/kernel/sys_s390.c @@ -32,6 +32,23 @@ #include #include "entry.h" +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way Unix traditionally does this, though. + */ +asmlinkage long sys_pipe(unsigned long __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + /* common code for old and new mmaps */ static inline long do_mmap2( unsigned long addr, unsigned long len, diff --git a/trunk/arch/s390/kvm/Kconfig b/trunk/arch/s390/kvm/Kconfig index e051cad1f1e0..1761b74d639b 100644 --- a/trunk/arch/s390/kvm/Kconfig +++ b/trunk/arch/s390/kvm/Kconfig @@ -22,6 +22,7 @@ config KVM select PREEMPT_NOTIFIERS select ANON_INODES select S390_SWITCH_AMODE + select PREEMPT ---help--- Support hosting paravirtualized guest machines using the SIE virtualization capability on the mainframe. This should work diff --git a/trunk/arch/s390/kvm/intercept.c b/trunk/arch/s390/kvm/intercept.c index 47a0b642174c..349581a26103 100644 --- a/trunk/arch/s390/kvm/intercept.c +++ b/trunk/arch/s390/kvm/intercept.c @@ -105,9 +105,6 @@ static intercept_handler_t instruction_handlers[256] = { static int handle_noop(struct kvm_vcpu *vcpu) { switch (vcpu->arch.sie_block->icptcode) { - case 0x0: - vcpu->stat.exit_null++; - break; case 0x10: vcpu->stat.exit_external_request++; break; diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 0ac36a649eba..98d1e73e01f1 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -31,7 +31,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "userspace_handled", VCPU_STAT(exit_userspace) }, - { "exit_null", VCPU_STAT(exit_null) }, { "exit_validity", VCPU_STAT(exit_validity) }, { "exit_stop_request", VCPU_STAT(exit_stop_request) }, { "exit_external_request", VCPU_STAT(exit_external_request) }, @@ -222,6 +221,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK; restore_fp_regs(&vcpu->arch.guest_fpregs); restore_access_regs(vcpu->arch.guest_acrs); + + if (signal_pending(current)) + atomic_set_mask(CPUSTAT_STOP_INT, + &vcpu->arch.sie_block->cpuflags); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/s390/mm/Makefile b/trunk/arch/s390/mm/Makefile index 2a7458134544..fb988a48a754 100644 --- a/trunk/arch/s390/mm/Makefile +++ b/trunk/arch/s390/mm/Makefile @@ -5,4 +5,3 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_PAGE_STATES) += page-states.o diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 29f3a63806b9..fa31de6ae97a 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -126,9 +126,6 @@ void __init mem_init(void) /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); - /* Setup guest page hinting */ - cmma_init(); - /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem(); diff --git a/trunk/arch/s390/mm/page-states.c b/trunk/arch/s390/mm/page-states.c deleted file mode 100644 index fc0ad73ffd90..000000000000 --- a/trunk/arch/s390/mm/page-states.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * arch/s390/mm/page-states.c - * - * Copyright IBM Corp. 2008 - * - * Guest page hinting for unused pages. - * - * Author(s): Martin Schwidefsky - */ - -#include -#include -#include -#include -#include - -#define ESSA_SET_STABLE 1 -#define ESSA_SET_UNUSED 2 - -static int cmma_flag; - -static int __init cmma(char *str) -{ - char *parm; - parm = strstrip(str); - if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { - cmma_flag = 1; - return 1; - } - cmma_flag = 0; - if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0) - return 1; - return 0; -} - -__setup("cmma=", cmma); - -void __init cmma_init(void) -{ - register unsigned long tmp asm("0") = 0; - register int rc asm("1") = -EOPNOTSUPP; - - if (!cmma_flag) - return; - asm volatile( - " .insn rrf,0xb9ab0000,%1,%1,0,0\n" - "0: la %0,0\n" - "1:\n" - EX_TABLE(0b,1b) - : "+&d" (rc), "+&d" (tmp)); - if (rc) - cmma_flag = 0; -} - -void arch_free_page(struct page *page, int order) -{ - int i, rc; - - if (!cmma_flag) - return; - for (i = 0; i < (1 << order); i++) - asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" - : "=&d" (rc) - : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), - "i" (ESSA_SET_UNUSED)); -} - -void arch_alloc_page(struct page *page, int order) -{ - int i, rc; - - if (!cmma_flag) - return; - for (i = 0; i < (1 << order); i++) - asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" - : "=&d" (rc) - : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), - "i" (ESSA_SET_STABLE)); -} diff --git a/trunk/arch/sh/kernel/sys_sh64.c b/trunk/arch/sh/kernel/sys_sh64.c index 91fb8445a5a0..578004d71e02 100644 --- a/trunk/arch/sh/kernel/sys_sh64.c +++ b/trunk/arch/sh/kernel/sys_sh64.c @@ -30,6 +30,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way Unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + /* * Do a system call from kernel instead of calling sys_execve so we * end up with proper pt_regs. diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c index 36431f377dee..e7f35198ae34 100644 --- a/trunk/arch/sparc/kernel/process.c +++ b/trunk/arch/sparc/kernel/process.c @@ -419,26 +419,14 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, unsigned long stack_size) { unsigned long parent_tid_ptr, child_tid_ptr; - unsigned long orig_i1 = regs->u_regs[UREG_I1]; - long ret; parent_tid_ptr = regs->u_regs[UREG_I2]; child_tid_ptr = regs->u_regs[UREG_I4]; - ret = do_fork(clone_flags, stack_start, - regs, stack_size, - (int __user *) parent_tid_ptr, - (int __user *) child_tid_ptr); - - /* If we get an error and potentially restart the system - * call, we're screwed because copy_thread() clobbered - * the parent's %o1. So detect that case and restore it - * here. - */ - if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) - regs->u_regs[UREG_I1] = orig_i1; - - return ret; + return do_fork(clone_flags, stack_start, + regs, stack_size, + (int __user *) parent_tid_ptr, + (int __user *) child_tid_ptr); } /* Copy a Sparc thread. The fork() return value conventions diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index 8a55c4f0df84..3c13137685da 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -180,9 +180,11 @@ static void __init boot_flags_init(char *commands) /* This routine will in the future do all the nasty prom stuff * to probe for the mmu type and its parameters, etc. This will - * also be where SMP things happen. + * also be where SMP things happen plus the Sparc specific memory + * physical memory probe as on the alpha. */ +extern int prom_probe_memory(void); extern void sun4c_probe_vac(void); extern char cputypval; extern unsigned long start, end; @@ -266,6 +268,7 @@ void __init setup_arch(char **cmdline_p) if (ARCH_SUN4C_SUN4) sun4c_probe_vac(); load_mmu(); + (void) prom_probe_memory(); phys_base = 0xffffffffUL; highest_paddr = 0UL; diff --git a/trunk/arch/sparc/kernel/signal.c b/trunk/arch/sparc/kernel/signal.c index 368157926d24..3c312290c3c2 100644 --- a/trunk/arch/sparc/kernel/signal.c +++ b/trunk/arch/sparc/kernel/signal.c @@ -245,29 +245,15 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen) static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize) { - unsigned long sp = regs->u_regs[UREG_FP]; + unsigned long sp; - /* - * If we are on the alternate signal stack and would overflow it, don't. - * Return an always-bogus address instead so we will die with SIGSEGV. - */ - if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) - return (void __user *) -1L; + sp = regs->u_regs[UREG_FP]; /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { - if (sas_ss_flags(sp) == 0) + if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) sp = current->sas_ss_sp + current->sas_ss_size; } - - /* Always align the stack frame. This handles two cases. First, - * sigaltstack need not be mindful of platform specific stack - * alignment. Second, if we took this signal because the stack - * is not aligned properly, we'd like to take the signal cleanly - * and report that. - */ - sp &= ~7UL; - return (void __user *)(sp - framesize); } diff --git a/trunk/arch/sparc/kernel/sys_sparc.c b/trunk/arch/sparc/kernel/sys_sparc.c index e995491c4436..f188b5dc9fd0 100644 --- a/trunk/arch/sparc/kernel/sys_sparc.c +++ b/trunk/arch/sparc/kernel/sys_sparc.c @@ -223,7 +223,8 @@ int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) { if (ARCH_SUN4C_SUN4 && (len > 0x20000000 || - (addr < 0xe0000000 && addr + len > 0x20000000))) + ((flags & MAP_FIXED) && + addr < 0xe0000000 && addr + len > 0x20000000))) return -EINVAL; /* See asm-sparc/uaccess.h */ diff --git a/trunk/arch/sparc/mm/fault.c b/trunk/arch/sparc/mm/fault.c index abd50795a7b6..e4d9c8e19df5 100644 --- a/trunk/arch/sparc/mm/fault.c +++ b/trunk/arch/sparc/mm/fault.c @@ -47,15 +47,64 @@ int vac_size, vac_linesize, vac_do_hw_vac_flushes; int vac_entries_per_context, vac_entries_per_segment; int vac_entries_per_page; -/* Return how much physical memory we have. */ -unsigned long probe_memory(void) +/* Nice, simple, prom library does all the sweating for us. ;) */ +int prom_probe_memory (void) { - unsigned long total = 0; - int i; + register struct linux_mlist_v0 *mlist; + register unsigned long bytes, base_paddr, tally; + register int i; + + i = 0; + mlist= *prom_meminfo()->v0_available; + bytes = tally = mlist->num_bytes; + base_paddr = (unsigned long) mlist->start_adr; + + sp_banks[0].base_addr = base_paddr; + sp_banks[0].num_bytes = bytes; + + while (mlist->theres_more != (void *) 0){ + i++; + mlist = mlist->theres_more; + bytes = mlist->num_bytes; + tally += bytes; + if (i > SPARC_PHYS_BANKS-1) { + printk ("The machine has more banks than " + "this kernel can support\n" + "Increase the SPARC_PHYS_BANKS " + "setting (currently %d)\n", + SPARC_PHYS_BANKS); + i = SPARC_PHYS_BANKS-1; + break; + } + + sp_banks[i].base_addr = (unsigned long) mlist->start_adr; + sp_banks[i].num_bytes = mlist->num_bytes; + } + + i++; + sp_banks[i].base_addr = 0xdeadbeef; + sp_banks[i].num_bytes = 0; + + /* Now mask all bank sizes on a page boundary, it is all we can + * use anyways. + */ + for(i=0; sp_banks[i].num_bytes != 0; i++) + sp_banks[i].num_bytes &= PAGE_MASK; + + return tally; +} + +/* Traverse the memory lists in the prom to see how much physical we + * have. + */ +unsigned long +probe_memory(void) +{ + int total; - for (i = 0; sp_banks[i].num_bytes; i++) - total += sp_banks[i].num_bytes; + total = prom_probe_memory(); + /* Oh man, much nicer, keep the dirt in promlib. */ return total; } diff --git a/trunk/arch/sparc/prom/init.c b/trunk/arch/sparc/prom/init.c index 2fa3a474e3a2..50abfb1b880e 100644 --- a/trunk/arch/sparc/prom/init.c +++ b/trunk/arch/sparc/prom/init.c @@ -21,6 +21,8 @@ linux_sun4_romvec *sun4_romvec; /* The root node of the prom device tree. */ int prom_root_node; +int prom_stdin, prom_stdout; + /* Pointer to the device tree operations structure. */ struct linux_nodeops *prom_nodeops; @@ -72,6 +74,11 @@ void __init prom_init(struct linux_romvec *rp) (((unsigned long) prom_nodeops) == -1)) prom_halt(); + if(prom_vers == PROM_V2 || prom_vers == PROM_V3) { + prom_stdout = *romvec->pv_v2bootargs.fd_stdout; + prom_stdin = *romvec->pv_v2bootargs.fd_stdin; + } + prom_meminit(); prom_ranges_init(); diff --git a/trunk/arch/sparc/prom/memory.c b/trunk/arch/sparc/prom/memory.c index 947f047dc95a..b0c0f9c4fc14 100644 --- a/trunk/arch/sparc/prom/memory.c +++ b/trunk/arch/sparc/prom/memory.c @@ -1,100 +1,215 @@ -/* memory.c: Prom routine for acquiring various bits of information +/* $Id: memory.c,v 1.15 2000/01/29 01:09:12 anton Exp $ + * memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * - * Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1997 Michael A. Griffith (grif@acm.org) */ #include -#include #include #include #include #include -#include -static int __init prom_meminit_v0(void) -{ - struct linux_mlist_v0 *p; - int index; - - index = 0; - for (p = *(romvec->pv_v0mem.v0_available); p; p = p->theres_more) { - sp_banks[index].base_addr = (unsigned long) p->start_adr; - sp_banks[index].num_bytes = p->num_bytes; - index++; - } - - return index; -} +/* This routine, for consistency, returns the ram parameters in the + * V0 prom memory descriptor format. I choose this format because I + * think it was the easiest to work with. I feel the religious + * arguments now... ;) Also, I return the linked lists sorted to + * prevent paging_init() upset stomach as I have not yet written + * the pepto-bismol kernel module yet. + */ -static int __init prom_meminit_v2(void) -{ - struct linux_prom_registers reg[64]; - int node, size, num_ents, i; +struct linux_prom_registers prom_reg_memlist[64]; +struct linux_prom_registers prom_reg_tmp[64]; - node = prom_searchsiblings(prom_getchild(prom_root_node), "memory"); - size = prom_getproperty(node, "available", (char *) reg, sizeof(reg)); - num_ents = size / sizeof(struct linux_prom_registers); +struct linux_mlist_v0 prom_phys_total[64]; +struct linux_mlist_v0 prom_prom_taken[64]; +struct linux_mlist_v0 prom_phys_avail[64]; - for (i = 0; i < num_ents; i++) { - sp_banks[i].base_addr = reg[i].phys_addr; - sp_banks[i].num_bytes = reg[i].reg_size; - } +struct linux_mlist_v0 *prom_ptot_ptr = prom_phys_total; +struct linux_mlist_v0 *prom_ptak_ptr = prom_prom_taken; +struct linux_mlist_v0 *prom_pavl_ptr = prom_phys_avail; - return num_ents; -} +struct linux_mem_v0 prom_memlist; -static int __init prom_meminit_sun4(void) -{ -#ifdef CONFIG_SUN4 - sp_banks[0].base_addr = 0; - sp_banks[0].num_bytes = *(sun4_romvec->memoryavail); -#endif - return 1; -} -static int sp_banks_cmp(const void *a, const void *b) +/* Internal Prom library routine to sort a linux_mlist_v0 memory + * list. Used below in initialization. + */ +static void __init +prom_sortmemlist(struct linux_mlist_v0 *thislist) { - const struct sparc_phys_banks *x = a, *y = b; + int swapi = 0; + int i, mitr, tmpsize; + char *tmpaddr; + char *lowest; + + for(i=0; thislist[i].theres_more; i++) { + lowest = thislist[i].start_adr; + for(mitr = i+1; thislist[mitr-1].theres_more; mitr++) + if(thislist[mitr].start_adr < lowest) { + lowest = thislist[mitr].start_adr; + swapi = mitr; + } + if(lowest == thislist[i].start_adr) continue; + tmpaddr = thislist[swapi].start_adr; + tmpsize = thislist[swapi].num_bytes; + for(mitr = swapi; mitr > i; mitr--) { + thislist[mitr].start_adr = thislist[mitr-1].start_adr; + thislist[mitr].num_bytes = thislist[mitr-1].num_bytes; + } + thislist[i].start_adr = tmpaddr; + thislist[i].num_bytes = tmpsize; + } - if (x->base_addr > y->base_addr) - return 1; - if (x->base_addr < y->base_addr) - return -1; - return 0; + return; } /* Initialize the memory lists based upon the prom version. */ void __init prom_meminit(void) { - int i, num_ents = 0; + int node = 0; + unsigned int iter, num_regs; + struct linux_mlist_v0 *mptr; /* ptr for traversal */ - switch (prom_vers) { + switch(prom_vers) { case PROM_V0: - num_ents = prom_meminit_v0(); + /* Nice, kind of easier to do in this case. */ + /* First, the total physical descriptors. */ + for(mptr = (*(romvec->pv_v0mem.v0_totphys)), iter=0; + mptr; mptr=mptr->theres_more, iter++) { + prom_phys_total[iter].start_adr = mptr->start_adr; + prom_phys_total[iter].num_bytes = mptr->num_bytes; + prom_phys_total[iter].theres_more = &prom_phys_total[iter+1]; + } + prom_phys_total[iter-1].theres_more = NULL; + /* Second, the total prom taken descriptors. */ + for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0; + mptr; mptr=mptr->theres_more, iter++) { + prom_prom_taken[iter].start_adr = mptr->start_adr; + prom_prom_taken[iter].num_bytes = mptr->num_bytes; + prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1]; + } + prom_prom_taken[iter-1].theres_more = NULL; + /* Last, the available physical descriptors. */ + for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0; + mptr; mptr=mptr->theres_more, iter++) { + prom_phys_avail[iter].start_adr = mptr->start_adr; + prom_phys_avail[iter].num_bytes = mptr->num_bytes; + prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1]; + } + prom_phys_avail[iter-1].theres_more = NULL; + /* Sort all the lists. */ + prom_sortmemlist(prom_phys_total); + prom_sortmemlist(prom_prom_taken); + prom_sortmemlist(prom_phys_avail); break; - case PROM_V2: case PROM_V3: - num_ents = prom_meminit_v2(); + /* Grrr, have to traverse the prom device tree ;( */ + node = prom_getchild(prom_root_node); + node = prom_searchsiblings(node, "memory"); + num_regs = prom_getproperty(node, "available", + (char *) prom_reg_memlist, + sizeof(prom_reg_memlist)); + num_regs = (num_regs/sizeof(struct linux_prom_registers)); + for(iter=0; itermemorysize); + prom_phys_total[0].theres_more = NULL; + prom_prom_taken[0].start_adr = NULL; + prom_prom_taken[0].num_bytes = 0x0; + prom_prom_taken[0].theres_more = NULL; + prom_phys_avail[0].start_adr = NULL; + prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail); + prom_phys_avail[0].theres_more = NULL; +#endif break; default: break; - } - sort(sp_banks, num_ents, sizeof(struct sparc_phys_banks), - sp_banks_cmp, NULL); + }; + + /* Link all the lists into the top-level descriptor. */ + prom_memlist.v0_totphys=&prom_ptot_ptr; + prom_memlist.v0_prommap=&prom_ptak_ptr; + prom_memlist.v0_available=&prom_pavl_ptr; - /* Sentinel. */ - sp_banks[num_ents].base_addr = 0xdeadbeef; - sp_banks[num_ents].num_bytes = 0; + return; +} - for (i = 0; i < num_ents; i++) - sp_banks[i].num_bytes &= PAGE_MASK; +/* This returns a pointer to our libraries internal v0 format + * memory descriptor. + */ +struct linux_mem_v0 * +prom_meminfo(void) +{ + return &prom_memlist; } diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index 112b09f16f36..dbf2fc2f4d87 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -350,7 +350,8 @@ static void pci_parse_of_addrs(struct of_device *op, struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct device_node *node, - struct pci_bus *bus, int devfn) + struct pci_bus *bus, int devfn, + int host_controller) { struct dev_archdata *sd; struct pci_dev *dev; @@ -389,28 +390,43 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ - dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); - dev->device = of_getintprop_default(node, "device-id", 0xffff); - dev->subsystem_vendor = - of_getintprop_default(node, "subsystem-vendor-id", 0); - dev->subsystem_device = - of_getintprop_default(node, "subsystem-id", 0); - - dev->cfg_size = pci_cfg_space_size(dev); - - /* We can't actually use the firmware value, we have - * to read what is in the register right now. One - * reason is that in the case of IDE interfaces the - * firmware can sample the value before the the IDE - * interface is programmed into native mode. - */ - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); - dev->class = class >> 8; - dev->revision = class & 0xff; - - sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), - dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + if (host_controller) { + if (tlb_type != hypervisor) { + pci_read_config_word(dev, PCI_VENDOR_ID, + &dev->vendor); + pci_read_config_word(dev, PCI_DEVICE_ID, + &dev->device); + } else { + dev->vendor = PCI_VENDOR_ID_SUN; + dev->device = 0x80f0; + } + dev->cfg_size = 256; + dev->class = PCI_CLASS_BRIDGE_HOST << 8; + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + 0x00, PCI_SLOT(devfn), PCI_FUNC(devfn)); + } else { + dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); + dev->device = of_getintprop_default(node, "device-id", 0xffff); + dev->subsystem_vendor = + of_getintprop_default(node, "subsystem-vendor-id", 0); + dev->subsystem_device = + of_getintprop_default(node, "subsystem-id", 0); + + dev->cfg_size = pci_cfg_space_size(dev); + + /* We can't actually use the firmware value, we have + * to read what is in the register right now. One + * reason is that in the case of IDE interfaces the + * firmware can sample the value before the the IDE + * interface is programmed into native mode. + */ + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); + dev->class = class >> 8; + dev->revision = class & 0xff; + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + } if (ofpci_verbose) printk(" class: 0x%x device name: %s\n", dev->class, pci_name(dev)); @@ -425,21 +441,26 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { - /* a PCI-PCI bridge */ + if (host_controller) { dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; - } else if (!strcmp(type, "cardbus")) { - dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + dev->irq = PCI_IRQ_NONE; } else { - dev->hdr_type = PCI_HEADER_TYPE_NORMAL; - dev->rom_base_reg = PCI_ROM_ADDRESS; + if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + /* a PCI-PCI bridge */ + dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; + dev->rom_base_reg = PCI_ROM_ADDRESS1; + } else if (!strcmp(type, "cardbus")) { + dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + } else { + dev->hdr_type = PCI_HEADER_TYPE_NORMAL; + dev->rom_base_reg = PCI_ROM_ADDRESS; - dev->irq = sd->op->irqs[0]; - if (dev->irq == 0xffffffff) - dev->irq = PCI_IRQ_NONE; + dev->irq = sd->op->irqs[0]; + if (dev->irq == 0xffffffff) + dev->irq = PCI_IRQ_NONE; + } } - pci_parse_of_addrs(sd->op, node, dev); if (ofpci_verbose) @@ -728,7 +749,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, prev_devfn = devfn; /* create a new pci_dev for this device */ - dev = of_create_pci_dev(pbm, child, bus, devfn); + dev = of_create_pci_dev(pbm, child, bus, devfn, 0); if (!dev) continue; if (ofpci_verbose) @@ -775,9 +796,48 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } +int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 *value) +{ + static u8 fake_pci_config[] = { + 0x8e, 0x10, /* Vendor: 0x108e (Sun) */ + 0xf0, 0x80, /* Device: 0x80f0 (Fire) */ + 0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */ + 0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */ + 0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */ + 0x00, /* Cacheline: 0x00 */ + 0x40, /* Latency: 0x40 */ + 0x00, /* Header-Type: 0x00 normal */ + }; + + *value = 0; + if (where >= 0 && where < sizeof(fake_pci_config) && + (where + size) >= 0 && + (where + size) < sizeof(fake_pci_config) && + size <= sizeof(u32)) { + while (size--) { + *value <<= 8; + *value |= fake_pci_config[where + size]; + } + } + + return PCIBIOS_SUCCESSFUL; +} + +int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 value) +{ + return PCIBIOS_SUCCESSFUL; +} + struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) { struct device_node *node = pbm->prom_node; + struct pci_dev *host_pdev; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -795,6 +855,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) bus->resource[0] = &pbm->io_space; bus->resource[1] = &pbm->mem_space; + /* Create the dummy host bridge and link it in. */ + host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1); + bus->self = host_pdev; + pci_of_scan_bus(pbm, node, bus); pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); diff --git a/trunk/arch/sparc64/kernel/pci_common.c b/trunk/arch/sparc64/kernel/pci_common.c index 19fa621d6a60..923e0bcc3bfd 100644 --- a/trunk/arch/sparc64/kernel/pci_common.c +++ b/trunk/arch/sparc64/kernel/pci_common.c @@ -264,6 +264,9 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; + if (!bus && devfn == 0x00) + return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, + size, value); if (config_out_of_range(pbm, bus, devfn, where)) { ret = ~0UL; } else { @@ -297,6 +300,9 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; + if (!bus && devfn == 0x00) + return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, + size, value); if (config_out_of_range(pbm, bus, devfn, where)) { /* Do nothing. */ } else { diff --git a/trunk/arch/sparc64/kernel/pci_impl.h b/trunk/arch/sparc64/kernel/pci_impl.h index c385d126be11..218bac4ff79b 100644 --- a/trunk/arch/sparc64/kernel/pci_impl.h +++ b/trunk/arch/sparc64/kernel/pci_impl.h @@ -167,6 +167,15 @@ extern void pci_get_pbm_props(struct pci_pbm_info *pbm); extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); +extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 *value); +extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, + unsigned int devfn, + int where, int size, + u32 value); + /* Error reporting support. */ extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c index 4129c0449856..056013749157 100644 --- a/trunk/arch/sparc64/kernel/process.c +++ b/trunk/arch/sparc64/kernel/process.c @@ -503,8 +503,6 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, unsigned long stack_size) { int __user *parent_tid_ptr, *child_tid_ptr; - unsigned long orig_i1 = regs->u_regs[UREG_I1]; - long ret; #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { @@ -517,19 +515,9 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags, child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; } - ret = do_fork(clone_flags, stack_start, - regs, stack_size, - parent_tid_ptr, child_tid_ptr); - - /* If we get an error and potentially restart the system - * call, we're screwed because copy_thread() clobbered - * the parent's %o1. So detect that case and restore it - * here. - */ - if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) - regs->u_regs[UREG_I1] = orig_i1; - - return ret; + return do_fork(clone_flags, stack_start, + regs, stack_size, + parent_tid_ptr, child_tid_ptr); } /* Copy a Sparc thread. The fork() return value conventions @@ -603,6 +591,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, if (clone_flags & CLONE_SETTLS) t->kregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; + /* We do not want to accidently trigger system call restart + * handling in the new thread. Therefore, clear out the trap + * type, which will make pt_regs_regs_is_syscall() return false. + */ + pt_regs_clear_trap_type(t->kregs); + return 0; } diff --git a/trunk/arch/sparc64/kernel/signal.c b/trunk/arch/sparc64/kernel/signal.c index 07c0443ea3f5..f2d88d8f7a42 100644 --- a/trunk/arch/sparc64/kernel/signal.c +++ b/trunk/arch/sparc64/kernel/signal.c @@ -332,9 +332,6 @@ void do_rt_sigreturn(struct pt_regs *regs) regs->tpc = tpc; regs->tnpc = tnpc; - /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); - sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = set; @@ -376,29 +373,16 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize) { - unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS; + unsigned long sp; - /* - * If we are on the alternate signal stack and would overflow it, don't. - * Return an always-bogus address instead so we will die with SIGSEGV. - */ - if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) - return (void __user *) -1L; + sp = regs->u_regs[UREG_FP] + STACK_BIAS; /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (sas_ss_flags(sp) == 0) + if (!on_sig_stack(sp) && + !((current->sas_ss_sp + current->sas_ss_size) & 7)) sp = current->sas_ss_sp + current->sas_ss_size; } - - /* Always align the stack frame. This handles two cases. First, - * sigaltstack need not be mindful of platform specific stack - * alignment. Second, if we took this signal because the stack - * is not aligned properly, we'd like to take the signal cleanly - * and report that. - */ - sp &= ~7UL; - return (void __user *)(sp - framesize); } @@ -531,8 +515,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) siginfo_t info; int signr; - if (pt_regs_is_syscall(regs) && - (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) { + if (pt_regs_is_syscall(regs)) { pt_regs_clear_trap_type(regs); cookie.restart_syscall = 1; } else diff --git a/trunk/arch/sparc64/kernel/signal32.c b/trunk/arch/sparc64/kernel/signal32.c index 0f6b7b156efd..91f8d0826db1 100644 --- a/trunk/arch/sparc64/kernel/signal32.c +++ b/trunk/arch/sparc64/kernel/signal32.c @@ -268,9 +268,6 @@ void do_sigreturn32(struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); - /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); - err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); @@ -354,9 +351,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC); regs->tstate |= psr_to_tstate_icc(psr); - /* Prevent syscall restart. */ - pt_regs_clear_trap_type(regs); - err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); @@ -406,27 +400,11 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; sp = regs->u_regs[UREG_FP]; - /* - * If we are on the alternate signal stack and would overflow it, don't. - * Return an always-bogus address instead so we will die with SIGSEGV. - */ - if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) - return (void __user *) -1L; - /* This is the X/Open sanctioned signal stack switching. */ if (sa->sa_flags & SA_ONSTACK) { - if (sas_ss_flags(sp) == 0) + if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7)) sp = current->sas_ss_sp + current->sas_ss_size; } - - /* Always align the stack frame. This handles two cases. First, - * sigaltstack need not be mindful of platform specific stack - * alignment. Second, if we took this signal because the stack - * is not aligned properly, we'd like to take the signal cleanly - * and report that. - */ - sp &= ~7UL; - return (void __user *)(sp - framesize); } diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index 0d6403a630ac..3aba47624df4 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -865,14 +865,21 @@ void smp_call_function_client(int irq, struct pt_regs *regs) void *info = call_data->info; clear_softint(1 << irq); + + irq_enter(); + + if (!call_data->wait) { + /* let initiator proceed after getting data */ + atomic_inc(&call_data->finished); + } + + func(info); + + irq_exit(); + if (call_data->wait) { /* let initiator proceed only after completion */ - func(info); atomic_inc(&call_data->finished); - } else { - /* let initiator proceed after getting data */ - atomic_inc(&call_data->finished); - func(info); } } @@ -1034,7 +1041,9 @@ void smp_receive_signal(int cpu) void smp_receive_signal_client(int irq, struct pt_regs *regs) { + irq_enter(); clear_softint(1 << irq); + irq_exit(); } void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) @@ -1042,6 +1051,8 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) struct mm_struct *mm; unsigned long flags; + irq_enter(); + clear_softint(1 << irq); /* See if we need to allocate a new TLB context because @@ -1061,6 +1072,8 @@ void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) load_secondary_context(mm); __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT); + + irq_exit(); } void smp_new_mmu_context_version(void) @@ -1226,6 +1239,8 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) { clear_softint(1 << irq); + irq_enter(); + preempt_disable(); __asm__ __volatile__("flushw"); @@ -1238,6 +1253,8 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) prom_world(0); preempt_enable(); + + irq_exit(); } /* /proc/profile writes can call this, don't __init it please. */ diff --git a/trunk/arch/sparc64/kernel/sys_sparc.c b/trunk/arch/sparc64/kernel/sys_sparc.c index 0dbc941f130e..8d4761f15fa9 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc.c +++ b/trunk/arch/sparc64/kernel/sys_sparc.c @@ -549,13 +549,13 @@ int sparc64_mmap_check(unsigned long addr, unsigned long len, if (len >= STACK_TOP32) return -EINVAL; - if (addr > STACK_TOP32 - len) + if ((flags & MAP_FIXED) && addr > STACK_TOP32 - len) return -EINVAL; } else { if (len >= VA_EXCLUDE_START) return -EINVAL; - if (invalid_64bit_range(addr, len)) + if ((flags & MAP_FIXED) && invalid_64bit_range(addr, len)) return -EINVAL; } diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index 1aa4288125f2..161ce4710fe7 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -236,6 +236,13 @@ asmlinkage long sys32_getegid16(void) /* 32-bit timeval and related flotsam. */ +static long get_tv32(struct timeval *o, struct compat_timeval __user *i) +{ + return (!access_ok(VERIFY_READ, i, sizeof(*i)) || + (__get_user(o->tv_sec, &i->tv_sec) | + __get_user(o->tv_usec, &i->tv_usec))); +} + static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) { return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || @@ -750,6 +757,30 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } +asmlinkage long sys32_utimes(char __user *filename, + struct compat_timeval __user *tvs) +{ + struct timespec tv[2]; + + if (tvs) { + struct timeval ktvs[2]; + if (get_tv32(&ktvs[0], tvs) || + get_tv32(&ktvs[1], 1+tvs)) + return -EFAULT; + + if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 || + ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000) + return -EINVAL; + + tv[0].tv_sec = ktvs[0].tv_sec; + tv[0].tv_nsec = 1000 * ktvs[0].tv_usec; + tv[1].tv_sec = ktvs[1].tv_sec; + tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; + } + + return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0); +} + /* These are here just in case some old sparc32 binary calls it. */ asmlinkage long sys32_pause(void) { diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index 8b5282d433c4..a4fef2ba1ae1 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -45,7 +45,7 @@ sys_call_table32: /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate /*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall - .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 + .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64 /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write /*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64 diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index ec3e2c72302a..4cad0b32b0af 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -771,9 +771,6 @@ static void __init find_ramdisk(unsigned long phys_base) initrd_end = ramdisk_image + sparc_ramdisk_size; lmb_reserve(initrd_start, initrd_end); - - initrd_start += PAGE_OFFSET; - initrd_end += PAGE_OFFSET; } #endif } @@ -2365,3 +2362,16 @@ void __flush_tlb_all(void) __asm__ __volatile__("wrpr %0, 0, %%pstate" : : "r" (pstate)); } + +#ifdef CONFIG_MEMORY_HOTPLUG + +void online_page(struct page *page) +{ + ClearPageReserved(page); + init_page_count(page); + __free_page(page); + totalram_pages++; + num_physpages++; +} + +#endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 5047490fc299..10b86e1cc659 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -191,9 +191,9 @@ void line_flush_chars(struct tty_struct *tty) line_flush_buffer(tty); } -int line_put_char(struct tty_struct *tty, unsigned char ch) +void line_put_char(struct tty_struct *tty, unsigned char ch) { - return line_write(tty, &ch, sizeof(ch)); + line_write(tty, &ch, sizeof(ch)); } int line_write(struct tty_struct *tty, const unsigned char *buf, int len) diff --git a/trunk/arch/um/include/line.h b/trunk/arch/um/include/line.h index 979b73e6352d..1223f2c844b4 100644 --- a/trunk/arch/um/include/line.h +++ b/trunk/arch/um/include/line.h @@ -71,7 +71,7 @@ extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, char **error_out); extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); -extern int line_put_char(struct tty_struct *tty, unsigned char ch); +extern void line_put_char(struct tty_struct *tty, unsigned char ch); extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); extern int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); diff --git a/trunk/arch/um/kernel/syscall.c b/trunk/arch/um/kernel/syscall.c index 128ee85bc8d9..9cffc628a37e 100644 --- a/trunk/arch/um/kernel/syscall.c +++ b/trunk/arch/um/kernel/syscall.c @@ -73,6 +73,23 @@ long old_mmap(unsigned long addr, unsigned long len, out: return err; } +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +long sys_pipe(unsigned long __user * fildes) +{ + int fd[2]; + long error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, sizeof(fd))) + error = -EFAULT; + } + return error; +} + long sys_uname(struct old_utsname __user * name) { diff --git a/trunk/arch/v850/kernel/syscalls.c b/trunk/arch/v850/kernel/syscalls.c index 1a83daf8e24f..003db9c8c44a 100644 --- a/trunk/arch/v850/kernel/syscalls.c +++ b/trunk/arch/v850/kernel/syscalls.c @@ -132,6 +132,23 @@ sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) return ret; } +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way unix traditionally does this, though. + */ +int sys_pipe (int *fildes) +{ + int fd[2]; + int error; + + error = do_pipe (fd); + if (!error) { + if (copy_to_user (fildes, fd, 2*sizeof (int))) + error = -EFAULT; + } + return error; +} + static inline unsigned long do_mmap2 (unsigned long addr, size_t len, unsigned long prot, unsigned long flags, diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index bbcafaa160c0..c3f880902d66 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -18,7 +18,6 @@ config X86_64 ### Arch settings config X86 def_bool y - select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES @@ -1662,7 +1661,6 @@ config GEODE_MFGPT_TIMER config OLPC bool "One Laptop Per Child support" - depends on MGEODE_LX default n help Add support for detecting the unique features of the OLPC diff --git a/trunk/arch/x86/boot/compressed/relocs.c b/trunk/arch/x86/boot/compressed/relocs.c index edaadea90aaf..d01ea42187e6 100644 --- a/trunk/arch/x86/boot/compressed/relocs.c +++ b/trunk/arch/x86/boot/compressed/relocs.c @@ -191,7 +191,7 @@ static void read_ehdr(FILE *fp) die("Cannot read ELF header: %s\n", strerror(errno)); } - if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) { + if (memcmp(ehdr.e_ident, ELFMAG, 4) != 0) { die("No ELF magic\n"); } if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile index 5e618c3b4720..bbdacb398d48 100644 --- a/trunk/arch/x86/kernel/Makefile +++ b/trunk/arch/x86/kernel/Makefile @@ -83,7 +83,9 @@ obj-$(CONFIG_KVM_GUEST) += kvm.o obj-$(CONFIG_KVM_CLOCK) += kvmclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o -obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o +ifdef CONFIG_INPUT_PCSPKR +obj-y += pcspeaker.o +endif obj-$(CONFIG_SCx200) += scx200.o scx200-y += scx200_32.o diff --git a/trunk/arch/x86/kernel/acpi/Makefile b/trunk/arch/x86/kernel/acpi/Makefile index fd5ca97a2ad5..7335959b6aff 100644 --- a/trunk/arch/x86/kernel/acpi/Makefile +++ b/trunk/arch/x86/kernel/acpi/Makefile @@ -10,5 +10,5 @@ endif $(obj)/wakeup_rm.o: $(obj)/realmode/wakeup.bin $(obj)/realmode/wakeup.bin: FORCE - $(Q)$(MAKE) $(build)=$(obj)/realmode + $(Q)$(MAKE) $(build)=$(obj)/realmode $@ diff --git a/trunk/arch/x86/kernel/acpi/realmode/Makefile b/trunk/arch/x86/kernel/acpi/realmode/Makefile index 1c31cc0e9def..092900854acc 100644 --- a/trunk/arch/x86/kernel/acpi/realmode/Makefile +++ b/trunk/arch/x86/kernel/acpi/realmode/Makefile @@ -6,8 +6,7 @@ # for more details. # -always := wakeup.bin -targets := wakeup.elf wakeup.lds +targets := wakeup.bin wakeup.elf wakeup-y += wakeup.o wakemain.o video-mode.o copy.o @@ -49,7 +48,7 @@ LDFLAGS_wakeup.elf := -T CPPFLAGS_wakeup.lds += -P -C -$(obj)/wakeup.elf: $(obj)/wakeup.lds $(WAKEUP_OBJS) FORCE +$(obj)/wakeup.elf: $(src)/wakeup.lds $(WAKEUP_OBJS) FORCE $(call if_changed,ld) OBJCOPYFLAGS_wakeup.bin := -O binary diff --git a/trunk/arch/x86/kernel/kvmclock.c b/trunk/arch/x86/kernel/kvmclock.c index 4bc1be5d5472..ddee04043aeb 100644 --- a/trunk/arch/x86/kernel/kvmclock.c +++ b/trunk/arch/x86/kernel/kvmclock.c @@ -133,7 +133,6 @@ static int kvm_register_clock(void) return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high); } -#ifdef CONFIG_X86_LOCAL_APIC static void kvm_setup_secondary_clock(void) { /* @@ -144,7 +143,6 @@ static void kvm_setup_secondary_clock(void) /* ok, done with our trickery, call native */ setup_secondary_APIC_clock(); } -#endif /* * After the clock is registered, the host will keep writing to the @@ -179,9 +177,7 @@ void __init kvmclock_init(void) pv_time_ops.get_wallclock = kvm_get_wallclock; pv_time_ops.set_wallclock = kvm_set_wallclock; pv_time_ops.sched_clock = kvm_clock_read; -#ifdef CONFIG_X86_LOCAL_APIC pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock; -#endif machine_ops.shutdown = kvm_shutdown; #ifdef CONFIG_KEXEC machine_ops.crash_shutdown = kvm_crash_shutdown; diff --git a/trunk/arch/x86/kernel/mpparse.c b/trunk/arch/x86/kernel/mpparse.c index 404683b94e79..3e2c54dc8b29 100644 --- a/trunk/arch/x86/kernel/mpparse.c +++ b/trunk/arch/x86/kernel/mpparse.c @@ -794,11 +794,6 @@ void __init find_smp_config(void) ACPI-based MP Configuration -------------------------------------------------------------------------- */ -/* - * Keep this outside and initialized to 0, for !CONFIG_ACPI builds: - */ -int es7000_plat; - #ifdef CONFIG_ACPI #ifdef CONFIG_X86_IO_APIC @@ -914,6 +909,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) MP_intsrc_info(&intsrc); } +int es7000_plat; + void __init mp_config_acpi_legacy_irqs(void) { struct mpc_config_intsrc intsrc; diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c index f6be7d5f82f8..07c6d42ab5ff 100644 --- a/trunk/arch/x86/kernel/reboot.c +++ b/trunk/arch/x86/kernel/reboot.c @@ -149,6 +149,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), + DMI_MATCH(DMI_BOARD_NAME, "0WF810"), }, }, { /* Handle problems with rebooting on Dell Optiplex 745's DFF*/ diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index cc6f5eb20b24..c0c68c18a788 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -95,7 +95,7 @@ void __init setup_per_cpu_areas(void) /* Copy section for each CPU (we discard the original) */ size = PERCPU_ENOUGH_ROOM; - printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n", + printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size); for_each_possible_cpu(i) { diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 6b087ab6cd8f..84241a256dc8 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -299,7 +299,7 @@ static void __cpuinit smp_callin(void) /* * Activate a secondary processor. */ -static void __cpuinit start_secondary(void *unused) +void __cpuinit start_secondary(void *unused) { /* * Don't put *anything* before cpu_init(), SMP booting is too @@ -1306,7 +1306,7 @@ static void remove_siblinginfo(int cpu) cpu_clear(cpu, cpu_sibling_setup_map); } -static int additional_cpus __initdata = -1; +int additional_cpus __initdata = -1; static __init int setup_additional_cpus(char *s) { diff --git a/trunk/arch/x86/kernel/sys_i386_32.c b/trunk/arch/x86/kernel/sys_i386_32.c index d2ab52cc1d6b..a86d26f036e1 100644 --- a/trunk/arch/x86/kernel/sys_i386_32.c +++ b/trunk/arch/x86/kernel/sys_i386_32.c @@ -22,6 +22,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way Unix traditionally does this, though. + */ +asmlinkage int sys_pipe(unsigned long __user * fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) diff --git a/trunk/arch/x86/kernel/sys_x86_64.c b/trunk/arch/x86/kernel/sys_x86_64.c index 3b360ef33817..bd802a5e1aa3 100644 --- a/trunk/arch/x86/kernel/sys_x86_64.c +++ b/trunk/arch/x86/kernel/sys_x86_64.c @@ -17,6 +17,23 @@ #include #include +/* + * sys_pipe() is the normal C calling standard for creating + * a pipe. It's not the way Unix traditionally does this, though. + */ +asmlinkage long sys_pipe(int __user *fildes) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(fildes, fd, 2*sizeof(int))) + error = -EFAULT; + } + return error; +} + asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off) { diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index 3324d90038e4..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; } @@ -288,8 +288,6 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val) * mode 1 is one shot, mode 2 is period, otherwise del timer */ switch (ps->channels[0].mode) { case 1: - /* FIXME: enhance mode 4 precision */ - case 4: create_pit_timer(&ps->pit_timer, val, 0); break; case 2: 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/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 36c5406b1813..2ad6f5481671 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -79,6 +79,36 @@ static int dbg = 1; } #endif +#define PT64_PT_BITS 9 +#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS) +#define PT32_PT_BITS 10 +#define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS) + +#define PT_WRITABLE_SHIFT 1 + +#define PT_PRESENT_MASK (1ULL << 0) +#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) +#define PT_USER_MASK (1ULL << 2) +#define PT_PWT_MASK (1ULL << 3) +#define PT_PCD_MASK (1ULL << 4) +#define PT_ACCESSED_MASK (1ULL << 5) +#define PT_DIRTY_MASK (1ULL << 6) +#define PT_PAGE_SIZE_MASK (1ULL << 7) +#define PT_PAT_MASK (1ULL << 7) +#define PT_GLOBAL_MASK (1ULL << 8) +#define PT64_NX_SHIFT 63 +#define PT64_NX_MASK (1ULL << PT64_NX_SHIFT) + +#define PT_PAT_SHIFT 7 +#define PT_DIR_PAT_SHIFT 12 +#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT) + +#define PT32_DIR_PSE36_SIZE 4 +#define PT32_DIR_PSE36_SHIFT 13 +#define PT32_DIR_PSE36_MASK \ + (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT) + + #define PT_FIRST_AVAIL_BITS_SHIFT 9 #define PT64_SECOND_AVAIL_BITS_SHIFT 52 @@ -124,6 +154,10 @@ static int dbg = 1; #define PFERR_USER_MASK (1U << 2) #define PFERR_FETCH_MASK (1U << 4) +#define PT64_ROOT_LEVEL 4 +#define PT32_ROOT_LEVEL 2 +#define PT32E_ROOT_LEVEL 3 + #define PT_DIRECTORY_LEVEL 2 #define PT_PAGE_TABLE_LEVEL 1 @@ -152,12 +186,6 @@ static struct kmem_cache *mmu_page_header_cache; static u64 __read_mostly shadow_trap_nonpresent_pte; static u64 __read_mostly shadow_notrap_nonpresent_pte; -static u64 __read_mostly shadow_base_present_pte; -static u64 __read_mostly shadow_nx_mask; -static u64 __read_mostly shadow_x_mask; /* mutual exclusive with nx_mask */ -static u64 __read_mostly shadow_user_mask; -static u64 __read_mostly shadow_accessed_mask; -static u64 __read_mostly shadow_dirty_mask; void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte) { @@ -166,23 +194,6 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte) } EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes); -void kvm_mmu_set_base_ptes(u64 base_pte) -{ - shadow_base_present_pte = base_pte; -} -EXPORT_SYMBOL_GPL(kvm_mmu_set_base_ptes); - -void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, - u64 dirty_mask, u64 nx_mask, u64 x_mask) -{ - shadow_user_mask = user_mask; - shadow_accessed_mask = accessed_mask; - shadow_dirty_mask = dirty_mask; - shadow_nx_mask = nx_mask; - shadow_x_mask = x_mask; -} -EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes); - static int is_write_protection(struct kvm_vcpu *vcpu) { return vcpu->arch.cr0 & X86_CR0_WP; @@ -221,7 +232,7 @@ static int is_writeble_pte(unsigned long pte) static int is_dirty_pte(unsigned long pte) { - return pte & shadow_dirty_mask; + return pte & PT_DIRTY_MASK; } static int is_rmap_pte(u64 pte) @@ -376,6 +387,7 @@ static void account_shadowed(struct kvm *kvm, gfn_t gfn) write_count = slot_largepage_idx(gfn, gfn_to_memslot(kvm, gfn)); *write_count += 1; + WARN_ON(*write_count > KVM_PAGES_PER_HPAGE); } static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) @@ -535,7 +547,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) return; sp = page_header(__pa(spte)); pfn = spte_to_pfn(*spte); - if (*spte & shadow_accessed_mask) + if (*spte & PT_ACCESSED_MASK) kvm_set_pfn_accessed(pfn); if (is_writeble_pte(*spte)) kvm_release_pfn_dirty(pfn); @@ -1061,17 +1073,17 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, * whether the guest actually used the pte (in order to detect * demand paging). */ - spte = shadow_base_present_pte | shadow_dirty_mask; + spte = PT_PRESENT_MASK | PT_DIRTY_MASK; if (!speculative) pte_access |= PT_ACCESSED_MASK; if (!dirty) pte_access &= ~ACC_WRITE_MASK; - if (pte_access & ACC_EXEC_MASK) - spte |= shadow_x_mask; - else - spte |= shadow_nx_mask; + if (!(pte_access & ACC_EXEC_MASK)) + spte |= PT64_NX_MASK; + + spte |= PT_PRESENT_MASK; if (pte_access & ACC_USER_MASK) - spte |= shadow_user_mask; + spte |= PT_USER_MASK; if (largepage) spte |= PT_PAGE_SIZE_MASK; @@ -1176,9 +1188,8 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, return -ENOMEM; } - table[index] = __pa(new_table->spt) - | PT_PRESENT_MASK | PT_WRITABLE_MASK - | shadow_user_mask | shadow_x_mask; + table[index] = __pa(new_table->spt) | PT_PRESENT_MASK + | PT_WRITABLE_MASK | PT_USER_MASK; } table_addr = table[index] & PT64_BASE_ADDR_MASK; } @@ -1233,6 +1244,7 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) return; spin_lock(&vcpu->kvm->mmu_lock); +#ifdef CONFIG_X86_64 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { hpa_t root = vcpu->arch.mmu.root_hpa; @@ -1244,6 +1256,7 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) spin_unlock(&vcpu->kvm->mmu_lock); return; } +#endif for (i = 0; i < 4; ++i) { hpa_t root = vcpu->arch.mmu.pae_root[i]; @@ -1269,6 +1282,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT; +#ifdef CONFIG_X86_64 if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { hpa_t root = vcpu->arch.mmu.root_hpa; @@ -1283,6 +1297,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) vcpu->arch.mmu.root_hpa = root; return; } +#endif metaphysical = !is_paging(vcpu); if (tdp_enabled) metaphysical = 1; @@ -1362,7 +1377,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK, - largepage, gfn, pfn, kvm_x86_ops->get_tdp_level()); + largepage, gfn, pfn, TDP_ROOT_LEVEL); spin_unlock(&vcpu->kvm->mmu_lock); return r; @@ -1469,7 +1484,7 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) context->page_fault = tdp_page_fault; context->free = nonpaging_free; context->prefetch_page = nonpaging_prefetch_page; - context->shadow_root_level = kvm_x86_ops->get_tdp_level(); + context->shadow_root_level = TDP_ROOT_LEVEL; context->root_hpa = INVALID_PAGE; if (!is_paging(vcpu)) { @@ -1618,7 +1633,7 @@ static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu) { u64 *spte = vcpu->arch.last_pte_updated; - return !!(spte && (*spte & shadow_accessed_mask)); + return !!(spte && (*spte & PT_ACCESSED_MASK)); } static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, diff --git a/trunk/arch/x86/kvm/mmu.h b/trunk/arch/x86/kvm/mmu.h index 1730757bbc7a..e64e9f56a65e 100644 --- a/trunk/arch/x86/kvm/mmu.h +++ b/trunk/arch/x86/kvm/mmu.h @@ -3,38 +3,11 @@ #include -#define PT64_PT_BITS 9 -#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS) -#define PT32_PT_BITS 10 -#define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS) - -#define PT_WRITABLE_SHIFT 1 - -#define PT_PRESENT_MASK (1ULL << 0) -#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) -#define PT_USER_MASK (1ULL << 2) -#define PT_PWT_MASK (1ULL << 3) -#define PT_PCD_MASK (1ULL << 4) -#define PT_ACCESSED_MASK (1ULL << 5) -#define PT_DIRTY_MASK (1ULL << 6) -#define PT_PAGE_SIZE_MASK (1ULL << 7) -#define PT_PAT_MASK (1ULL << 7) -#define PT_GLOBAL_MASK (1ULL << 8) -#define PT64_NX_SHIFT 63 -#define PT64_NX_MASK (1ULL << PT64_NX_SHIFT) - -#define PT_PAT_SHIFT 7 -#define PT_DIR_PAT_SHIFT 12 -#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT) - -#define PT32_DIR_PSE36_SIZE 4 -#define PT32_DIR_PSE36_SHIFT 13 -#define PT32_DIR_PSE36_MASK \ - (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT) - -#define PT64_ROOT_LEVEL 4 -#define PT32_ROOT_LEVEL 2 -#define PT32E_ROOT_LEVEL 3 +#ifdef CONFIG_X86_64 +#define TDP_ROOT_LEVEL PT64_ROOT_LEVEL +#else +#define TDP_ROOT_LEVEL PT32E_ROOT_LEVEL +#endif static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) { diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index ab22615eee89..89e0be2c10d0 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -1863,15 +1863,6 @@ static bool svm_cpu_has_accelerated_tpr(void) return false; } -static int get_npt_level(void) -{ -#ifdef CONFIG_X86_64 - return PT64_ROOT_LEVEL; -#else - return PT32E_ROOT_LEVEL; -#endif -} - static struct kvm_x86_ops svm_x86_ops = { .cpu_has_kvm_support = has_svm, .disabled_by_bios = is_disabled, @@ -1929,7 +1920,6 @@ static struct kvm_x86_ops svm_x86_ops = { .inject_pending_vectors = do_interrupt_requests, .set_tss_addr = svm_set_tss_addr, - .get_tdp_level = get_npt_level, }; static int __init svm_init(void) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index bfe4db11989c..8e5d6645b90d 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -42,9 +42,6 @@ module_param(enable_vpid, bool, 0); static int flexpriority_enabled = 1; module_param(flexpriority_enabled, bool, 0); -static int enable_ept = 1; -module_param(enable_ept, bool, 0); - struct vmcs { u32 revision_id; u32 abort; @@ -87,7 +84,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) return container_of(vcpu, struct vcpu_vmx, vcpu); } -static int init_rmode(struct kvm *kvm); +static int init_rmode_tss(struct kvm *kvm); static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); @@ -110,11 +107,6 @@ static struct vmcs_config { u32 vmentry_ctrl; } vmcs_config; -struct vmx_capability { - u32 ept; - u32 vpid; -} vmx_capability; - #define VMX_SEGMENT_FIELD(seg) \ [VCPU_SREG_##seg] = { \ .selector = GUEST_##seg##_SELECTOR, \ @@ -222,32 +214,6 @@ static inline bool cpu_has_vmx_virtualize_apic_accesses(void) SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); } -static inline int cpu_has_vmx_invept_individual_addr(void) -{ - return (!!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT)); -} - -static inline int cpu_has_vmx_invept_context(void) -{ - return (!!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT)); -} - -static inline int cpu_has_vmx_invept_global(void) -{ - return (!!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT)); -} - -static inline int cpu_has_vmx_ept(void) -{ - return (vmcs_config.cpu_based_2nd_exec_ctrl & - SECONDARY_EXEC_ENABLE_EPT); -} - -static inline int vm_need_ept(void) -{ - return (cpu_has_vmx_ept() && enable_ept); -} - static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) { return ((cpu_has_vmx_virtualize_apic_accesses()) && @@ -284,18 +250,6 @@ static inline void __invvpid(int ext, u16 vpid, gva_t gva) : : "a"(&operand), "c"(ext) : "cc", "memory"); } -static inline void __invept(int ext, u64 eptp, gpa_t gpa) -{ - struct { - u64 eptp, gpa; - } operand = {eptp, gpa}; - - asm volatile (ASM_VMX_INVEPT - /* CF==1 or ZF==1 --> rc = -1 */ - "; ja 1f ; ud2 ; 1:\n" - : : "a" (&operand), "c" (ext) : "cc", "memory"); -} - static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) { int i; @@ -347,33 +301,6 @@ static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx) __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx->vpid, 0); } -static inline void ept_sync_global(void) -{ - if (cpu_has_vmx_invept_global()) - __invept(VMX_EPT_EXTENT_GLOBAL, 0, 0); -} - -static inline void ept_sync_context(u64 eptp) -{ - if (vm_need_ept()) { - if (cpu_has_vmx_invept_context()) - __invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0); - else - ept_sync_global(); - } -} - -static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa) -{ - if (vm_need_ept()) { - if (cpu_has_vmx_invept_individual_addr()) - __invept(VMX_EPT_EXTENT_INDIVIDUAL_ADDR, - eptp, gpa); - else - ept_sync_context(eptp); - } -} - static unsigned long vmcs_readl(unsigned long field) { unsigned long value; @@ -461,8 +388,6 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) eb |= 1u << 1; if (vcpu->arch.rmode.active) eb = ~0; - if (vm_need_ept()) - eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ vmcs_write32(EXCEPTION_BITMAP, eb); } @@ -1060,7 +985,7 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) { u32 vmx_msr_low, vmx_msr_high; - u32 min, opt, min2, opt2; + u32 min, opt; u32 _pin_based_exec_control = 0; u32 _cpu_based_exec_control = 0; u32 _cpu_based_2nd_exec_control = 0; @@ -1078,8 +1003,6 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING | #endif - CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING | CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MOV_DR_EXITING | CPU_BASED_USE_TSC_OFFSETING; @@ -1095,13 +1018,11 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) ~CPU_BASED_CR8_STORE_EXITING; #endif if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { - min2 = 0; - opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | + min = 0; + opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | SECONDARY_EXEC_WBINVD_EXITING | - SECONDARY_EXEC_ENABLE_VPID | - SECONDARY_EXEC_ENABLE_EPT; - if (adjust_vmx_controls(min2, opt2, - MSR_IA32_VMX_PROCBASED_CTLS2, + SECONDARY_EXEC_ENABLE_VPID; + if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS2, &_cpu_based_2nd_exec_control) < 0) return -EIO; } @@ -1110,16 +1031,6 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW; #endif - if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { - /* CR3 accesses don't need to cause VM Exits when EPT enabled */ - min &= ~(CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING); - if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS, - &_cpu_based_exec_control) < 0) - return -EIO; - rdmsr(MSR_IA32_VMX_EPT_VPID_CAP, - vmx_capability.ept, vmx_capability.vpid); - } min = 0; #ifdef CONFIG_X86_64 @@ -1345,7 +1256,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu) fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); kvm_mmu_reset_context(vcpu); - init_rmode(vcpu->kvm); + init_rmode_tss(vcpu->kvm); } #ifdef CONFIG_X86_64 @@ -1393,64 +1304,8 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK; } -static void ept_load_pdptrs(struct kvm_vcpu *vcpu) -{ - if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { - if (!load_pdptrs(vcpu, vcpu->arch.cr3)) { - printk(KERN_ERR "EPT: Fail to load pdptrs!\n"); - return; - } - vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); - vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); - vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); - vmcs_write64(GUEST_PDPTR3, vcpu->arch.pdptrs[3]); - } -} - -static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); - -static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, - unsigned long cr0, - struct kvm_vcpu *vcpu) -{ - if (!(cr0 & X86_CR0_PG)) { - /* From paging/starting to nonpaging */ - vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, - vmcs_config.cpu_based_exec_ctrl | - (CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING)); - vcpu->arch.cr0 = cr0; - vmx_set_cr4(vcpu, vcpu->arch.cr4); - *hw_cr0 |= X86_CR0_PE | X86_CR0_PG; - *hw_cr0 &= ~X86_CR0_WP; - } else if (!is_paging(vcpu)) { - /* From nonpaging to paging */ - vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, - vmcs_config.cpu_based_exec_ctrl & - ~(CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING)); - vcpu->arch.cr0 = cr0; - vmx_set_cr4(vcpu, vcpu->arch.cr4); - if (!(vcpu->arch.cr0 & X86_CR0_WP)) - *hw_cr0 &= ~X86_CR0_WP; - } -} - -static void ept_update_paging_mode_cr4(unsigned long *hw_cr4, - struct kvm_vcpu *vcpu) -{ - if (!is_paging(vcpu)) { - *hw_cr4 &= ~X86_CR4_PAE; - *hw_cr4 |= X86_CR4_PSE; - } else if (!(vcpu->arch.cr4 & X86_CR4_PAE)) - *hw_cr4 &= ~X86_CR4_PAE; -} - static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { - unsigned long hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | - KVM_VM_CR0_ALWAYS_ON; - vmx_fpu_deactivate(vcpu); if (vcpu->arch.rmode.active && (cr0 & X86_CR0_PE)) @@ -1468,61 +1323,29 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } #endif - if (vm_need_ept()) - ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu); - vmcs_writel(CR0_READ_SHADOW, cr0); - vmcs_writel(GUEST_CR0, hw_cr0); + vmcs_writel(GUEST_CR0, + (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON); vcpu->arch.cr0 = cr0; if (!(cr0 & X86_CR0_TS) || !(cr0 & X86_CR0_PE)) vmx_fpu_activate(vcpu); } -static u64 construct_eptp(unsigned long root_hpa) -{ - u64 eptp; - - /* TODO write the value reading from MSR */ - eptp = VMX_EPT_DEFAULT_MT | - VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT; - eptp |= (root_hpa & PAGE_MASK); - - return eptp; -} - static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { - unsigned long guest_cr3; - u64 eptp; - - guest_cr3 = cr3; - if (vm_need_ept()) { - eptp = construct_eptp(cr3); - vmcs_write64(EPT_POINTER, eptp); - ept_sync_context(eptp); - ept_load_pdptrs(vcpu); - guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : - VMX_EPT_IDENTITY_PAGETABLE_ADDR; - } - vmx_flush_tlb(vcpu); - vmcs_writel(GUEST_CR3, guest_cr3); + vmcs_writel(GUEST_CR3, cr3); if (vcpu->arch.cr0 & X86_CR0_PE) vmx_fpu_deactivate(vcpu); } static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { - unsigned long hw_cr4 = cr4 | (vcpu->arch.rmode.active ? - KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON); - - vcpu->arch.cr4 = cr4; - if (vm_need_ept()) - ept_update_paging_mode_cr4(&hw_cr4, vcpu); - vmcs_writel(CR4_READ_SHADOW, cr4); - vmcs_writel(GUEST_CR4, hw_cr4); + vmcs_writel(GUEST_CR4, cr4 | (vcpu->arch.rmode.active ? + KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON)); + vcpu->arch.cr4 = cr4; } static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) @@ -1707,41 +1530,6 @@ static int init_rmode_tss(struct kvm *kvm) return ret; } -static int init_rmode_identity_map(struct kvm *kvm) -{ - int i, r, ret; - pfn_t identity_map_pfn; - u32 tmp; - - if (!vm_need_ept()) - return 1; - if (unlikely(!kvm->arch.ept_identity_pagetable)) { - printk(KERN_ERR "EPT: identity-mapping pagetable " - "haven't been allocated!\n"); - return 0; - } - if (likely(kvm->arch.ept_identity_pagetable_done)) - return 1; - ret = 0; - identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT; - r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); - if (r < 0) - goto out; - /* Set up identity-mapping pagetable for EPT in real mode */ - for (i = 0; i < PT32_ENT_PER_PAGE; i++) { - tmp = (i << 22) + (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | - _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE); - r = kvm_write_guest_page(kvm, identity_map_pfn, - &tmp, i * sizeof(tmp), sizeof(tmp)); - if (r < 0) - goto out; - } - kvm->arch.ept_identity_pagetable_done = true; - ret = 1; -out: - return ret; -} - static void seg_setup(int seg) { struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; @@ -1776,31 +1564,6 @@ static int alloc_apic_access_page(struct kvm *kvm) return r; } -static int alloc_identity_pagetable(struct kvm *kvm) -{ - struct kvm_userspace_memory_region kvm_userspace_mem; - int r = 0; - - down_write(&kvm->slots_lock); - if (kvm->arch.ept_identity_pagetable) - goto out; - kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; - kvm_userspace_mem.flags = 0; - kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR; - kvm_userspace_mem.memory_size = PAGE_SIZE; - r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); - if (r) - goto out; - - down_read(¤t->mm->mmap_sem); - kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, - VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT); - up_read(¤t->mm->mmap_sem); -out: - up_write(&kvm->slots_lock); - return r; -} - static void allocate_vpid(struct vcpu_vmx *vmx) { int vpid; @@ -1875,9 +1638,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) CPU_BASED_CR8_LOAD_EXITING; #endif } - if (!vm_need_ept()) - exec_control |= CPU_BASED_CR3_STORE_EXITING | - CPU_BASED_CR3_LOAD_EXITING; vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control); if (cpu_has_secondary_exec_ctrls()) { @@ -1887,8 +1647,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; if (vmx->vpid == 0) exec_control &= ~SECONDARY_EXEC_ENABLE_VPID; - if (!vm_need_ept()) - exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); } @@ -1964,15 +1722,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) return 0; } -static int init_rmode(struct kvm *kvm) -{ - if (!init_rmode_tss(kvm)) - return 0; - if (!init_rmode_identity_map(kvm)) - return 0; - return 1; -} - static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -1980,7 +1729,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) int ret; down_read(&vcpu->kvm->slots_lock); - if (!init_rmode(vmx->vcpu.kvm)) { + if (!init_rmode_tss(vmx->vcpu.kvm)) { ret = -ENOMEM; goto out; } @@ -2245,9 +1994,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (intr_info & INTR_INFO_DELIVER_CODE_MASK) error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); if (is_page_fault(intr_info)) { - /* EPT won't cause page fault directly */ - if (vm_need_ept()) - BUG(); cr2 = vmcs_readl(EXIT_QUALIFICATION); KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, (u32)((u64)cr2 >> 32), handler); @@ -2577,64 +2323,6 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return kvm_task_switch(vcpu, tss_selector, reason); } -static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - u64 exit_qualification; - enum emulation_result er; - gpa_t gpa; - unsigned long hva; - int gla_validity; - int r; - - exit_qualification = vmcs_read64(EXIT_QUALIFICATION); - - if (exit_qualification & (1 << 6)) { - printk(KERN_ERR "EPT: GPA exceeds GAW!\n"); - return -ENOTSUPP; - } - - gla_validity = (exit_qualification >> 7) & 0x3; - if (gla_validity != 0x3 && gla_validity != 0x1 && gla_validity != 0) { - printk(KERN_ERR "EPT: Handling EPT violation failed!\n"); - printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n", - (long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS), - (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS)); - printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n", - (long unsigned int)exit_qualification); - kvm_run->exit_reason = KVM_EXIT_UNKNOWN; - kvm_run->hw.hardware_exit_reason = 0; - return -ENOTSUPP; - } - - gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); - hva = gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT); - if (!kvm_is_error_hva(hva)) { - r = kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0); - if (r < 0) { - printk(KERN_ERR "EPT: Not enough memory!\n"); - return -ENOMEM; - } - return 1; - } else { - /* must be MMIO */ - er = emulate_instruction(vcpu, kvm_run, 0, 0, 0); - - if (er == EMULATE_FAIL) { - printk(KERN_ERR - "EPT: Fail to handle EPT violation vmexit!er is %d\n", - er); - printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n", - (long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS), - (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS)); - printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n", - (long unsigned int)exit_qualification); - return -ENOTSUPP; - } else if (er == EMULATE_DO_MMIO) - return 0; - } - return 1; -} - /* * The exit handlers return 1 if the exit was handled fully and guest execution * may resume. Otherwise they set the kvm_run parameter to indicate what needs @@ -2658,7 +2346,6 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, [EXIT_REASON_APIC_ACCESS] = handle_apic_access, [EXIT_REASON_WBINVD] = handle_wbinvd, [EXIT_REASON_TASK_SWITCH] = handle_task_switch, - [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation, }; static const int kvm_vmx_max_exit_handlers = @@ -2677,13 +2364,6 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)vmcs_readl(GUEST_RIP), (u32)((u64)vmcs_readl(GUEST_RIP) >> 32), entryexit); - /* Access CR3 don't cause VMExit in paging mode, so we need - * to sync with guest real CR3. */ - if (vm_need_ept() && is_paging(vcpu)) { - vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); - ept_load_pdptrs(vcpu); - } - if (unlikely(vmx->fail)) { kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; kvm_run->fail_entry.hardware_entry_failure_reason @@ -2692,8 +2372,7 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) } if ((vectoring_info & VECTORING_INFO_VALID_MASK) && - (exit_reason != EXIT_REASON_EXCEPTION_NMI && - exit_reason != EXIT_REASON_EPT_VIOLATION)) + exit_reason != EXIT_REASON_EXCEPTION_NMI) printk(KERN_WARNING "%s: unexpected, valid vectoring info and " "exit reason is 0x%x\n", __func__, exit_reason); if (exit_reason < kvm_vmx_max_exit_handlers @@ -2995,15 +2674,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) return ERR_PTR(-ENOMEM); allocate_vpid(vmx); - if (id == 0 && vm_need_ept()) { - kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | - VMX_EPT_WRITABLE_MASK | - VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); - kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK, - VMX_EPT_FAKE_DIRTY_MASK, 0ull, - VMX_EPT_EXECUTABLE_MASK); - kvm_enable_tdp(); - } err = kvm_vcpu_init(&vmx->vcpu, kvm, id); if (err) @@ -3036,10 +2706,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) if (alloc_apic_access_page(kvm) != 0) goto free_vmcs; - if (vm_need_ept()) - if (alloc_identity_pagetable(kvm) != 0) - goto free_vmcs; - return &vmx->vcpu; free_vmcs: @@ -3069,11 +2735,6 @@ static void __init vmx_check_processor_compat(void *rtn) } } -static int get_ept_level(void) -{ - return VMX_EPT_DEFAULT_GAW + 1; -} - static struct kvm_x86_ops vmx_x86_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios, @@ -3130,7 +2791,6 @@ static struct kvm_x86_ops vmx_x86_ops = { .inject_pending_vectors = do_interrupt_requests, .set_tss_addr = vmx_set_tss_addr, - .get_tdp_level = get_ept_level, }; static int __init vmx_init(void) @@ -3183,14 +2843,9 @@ static int __init vmx_init(void) vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_ESP); vmx_disable_intercept_for_msr(vmx_msr_bitmap, MSR_IA32_SYSENTER_EIP); - if (cpu_has_vmx_ept()) - bypass_guest_pf = 0; - if (bypass_guest_pf) kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); - ept_sync_global(); - return 0; out2: diff --git a/trunk/arch/x86/kvm/vmx.h b/trunk/arch/x86/kvm/vmx.h index 79d94c610dfe..5dff4606b988 100644 --- a/trunk/arch/x86/kvm/vmx.h +++ b/trunk/arch/x86/kvm/vmx.h @@ -35,8 +35,6 @@ #define CPU_BASED_MWAIT_EXITING 0x00000400 #define CPU_BASED_RDPMC_EXITING 0x00000800 #define CPU_BASED_RDTSC_EXITING 0x00001000 -#define CPU_BASED_CR3_LOAD_EXITING 0x00008000 -#define CPU_BASED_CR3_STORE_EXITING 0x00010000 #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 #define CPU_BASED_CR8_STORE_EXITING 0x00100000 #define CPU_BASED_TPR_SHADOW 0x00200000 @@ -51,7 +49,6 @@ * Definitions of Secondary Processor-Based VM-Execution Controls. */ #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 -#define SECONDARY_EXEC_ENABLE_EPT 0x00000002 #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 @@ -103,22 +100,10 @@ enum vmcs_field { VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013, APIC_ACCESS_ADDR = 0x00002014, APIC_ACCESS_ADDR_HIGH = 0x00002015, - EPT_POINTER = 0x0000201a, - EPT_POINTER_HIGH = 0x0000201b, - GUEST_PHYSICAL_ADDRESS = 0x00002400, - GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, VMCS_LINK_POINTER = 0x00002800, VMCS_LINK_POINTER_HIGH = 0x00002801, GUEST_IA32_DEBUGCTL = 0x00002802, GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, - GUEST_PDPTR0 = 0x0000280a, - GUEST_PDPTR0_HIGH = 0x0000280b, - GUEST_PDPTR1 = 0x0000280c, - GUEST_PDPTR1_HIGH = 0x0000280d, - GUEST_PDPTR2 = 0x0000280e, - GUEST_PDPTR2_HIGH = 0x0000280f, - GUEST_PDPTR3 = 0x00002810, - GUEST_PDPTR3_HIGH = 0x00002811, PIN_BASED_VM_EXEC_CONTROL = 0x00004000, CPU_BASED_VM_EXEC_CONTROL = 0x00004002, EXCEPTION_BITMAP = 0x00004004, @@ -241,8 +226,6 @@ enum vmcs_field { #define EXIT_REASON_MWAIT_INSTRUCTION 36 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 #define EXIT_REASON_APIC_ACCESS 44 -#define EXIT_REASON_EPT_VIOLATION 48 -#define EXIT_REASON_EPT_MISCONFIG 49 #define EXIT_REASON_WBINVD 54 /* @@ -333,36 +316,15 @@ enum vmcs_field { #define MSR_IA32_VMX_CR4_FIXED1 0x489 #define MSR_IA32_VMX_VMCS_ENUM 0x48a #define MSR_IA32_VMX_PROCBASED_CTLS2 0x48b -#define MSR_IA32_VMX_EPT_VPID_CAP 0x48c #define MSR_IA32_FEATURE_CONTROL 0x3a #define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1 #define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4 #define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT 9 -#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT 10 #define VMX_NR_VPIDS (1 << 16) #define VMX_VPID_EXTENT_SINGLE_CONTEXT 1 #define VMX_VPID_EXTENT_ALL_CONTEXT 2 -#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 -#define VMX_EPT_EXTENT_CONTEXT 1 -#define VMX_EPT_EXTENT_GLOBAL 2 -#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) -#define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) -#define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) -#define VMX_EPT_DEFAULT_GAW 3 -#define VMX_EPT_MAX_GAW 0x4 -#define VMX_EPT_MT_EPTE_SHIFT 3 -#define VMX_EPT_GAW_EPTP_SHIFT 3 -#define VMX_EPT_DEFAULT_MT 0x6ull -#define VMX_EPT_READABLE_MASK 0x1ull -#define VMX_EPT_WRITABLE_MASK 0x2ull -#define VMX_EPT_EXECUTABLE_MASK 0x4ull -#define VMX_EPT_FAKE_ACCESSED_MASK (1ull << 62) -#define VMX_EPT_FAKE_DIRTY_MASK (1ull << 63) - -#define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul - #endif diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 21338bdb28ff..0ce556372a4d 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -2417,9 +2417,6 @@ int kvm_arch_init(void *opaque) kvm_x86_ops = ops; kvm_mmu_set_nonpresent_ptes(0ull, 0ull); - kvm_mmu_set_base_ptes(PT_PRESENT_MASK); - kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK, - PT_DIRTY_MASK, PT64_NX_MASK, 0); return 0; out: @@ -3022,8 +3019,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) kvm_x86_ops->decache_regs(vcpu); - vcpu->arch.exception.pending = false; - vcpu_put(vcpu); return 0; @@ -3486,7 +3481,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) } if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { - cseg_desc.type &= ~(1 << 1); //clear the B flag + cseg_desc.type &= ~(1 << 8); //clear the B flag save_guest_segment_descriptor(vcpu, tr_seg.selector, &cseg_desc); } @@ -3512,7 +3507,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) } if (reason != TASK_SWITCH_IRET) { - nseg_desc.type |= (1 << 1); + nseg_desc.type |= (1 << 8); save_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc); } @@ -3703,19 +3698,10 @@ void fx_init(struct kvm_vcpu *vcpu) { unsigned after_mxcsr_mask; - /* - * Touch the fpu the first time in non atomic context as if - * this is the first fpu instruction the exception handler - * will fire before the instruction returns and it'll have to - * allocate ram with GFP_KERNEL. - */ - if (!used_math()) - fx_save(&vcpu->arch.host_fx_image); - /* Initialize guest FPU by resetting ours and saving into guest's */ preempt_disable(); fx_save(&vcpu->arch.host_fx_image); - fx_finit(); + fpu_init(); fx_save(&vcpu->arch.guest_fx_image); fx_restore(&vcpu->arch.host_fx_image); preempt_enable(); @@ -3920,8 +3906,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kvm_free_physmem(kvm); if (kvm->arch.apic_access_page) put_page(kvm->arch.apic_access_page); - if (kvm->arch.ept_identity_pagetable) - put_page(kvm->arch.ept_identity_pagetable); kfree(kvm); } diff --git a/trunk/arch/x86/kvm/x86_emulate.c b/trunk/arch/x86/kvm/x86_emulate.c index f2a696d6a243..2ca08386f993 100644 --- a/trunk/arch/x86/kvm/x86_emulate.c +++ b/trunk/arch/x86/kvm/x86_emulate.c @@ -1761,7 +1761,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) case 6: /* lmsw */ realmode_lmsw(ctxt->vcpu, (u16)c->src.val, &ctxt->eflags); - c->dst.type = OP_NONE; break; case 7: /* invlpg*/ emulate_invlpg(ctxt->vcpu, memop); diff --git a/trunk/arch/x86/mm/discontig_32.c b/trunk/arch/x86/mm/discontig_32.c index 914ccf983687..18378850e25a 100644 --- a/trunk/arch/x86/mm/discontig_32.c +++ b/trunk/arch/x86/mm/discontig_32.c @@ -476,3 +476,29 @@ int memory_add_physaddr_to_nid(u64 addr) EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif + +#ifndef CONFIG_HAVE_ARCH_PARSE_SRAT +/* + * XXX FIXME: Make SLIT table parsing available to 32-bit NUMA + * + * These stub functions are needed to compile 32-bit NUMA when SRAT is + * not set. There are functions in srat_64.c for parsing this table + * and it may be possible to make them common functions. + */ +void acpi_numa_slit_init (struct acpi_table_slit *slit) +{ + printk(KERN_INFO "ACPI: No support for parsing SLIT table\n"); +} + +void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa) +{ +} + +void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma) +{ +} + +void acpi_numa_arch_fixup(void) +{ +} +#endif /* CONFIG_HAVE_ARCH_PARSE_SRAT */ diff --git a/trunk/arch/x86/mm/pgtable_32.c b/trunk/arch/x86/mm/pgtable_32.c index 369cf065b6a4..9ee007be9142 100644 --- a/trunk/arch/x86/mm/pgtable_32.c +++ b/trunk/arch/x86/mm/pgtable_32.c @@ -172,3 +172,10 @@ void reserve_top_address(unsigned long reserve) __FIXADDR_TOP = -reserve - PAGE_SIZE; __VMALLOC_RESERVE += reserve; } + +int pmd_bad(pmd_t pmd) +{ + WARN_ON_ONCE(pmd_bad_v1(pmd) != pmd_bad_v2(pmd)); + + return pmd_bad_v1(pmd); +} diff --git a/trunk/arch/x86/pci/Makefile_32 b/trunk/arch/x86/pci/Makefile_32 index 89ec35d00efd..7fa519868d70 100644 --- a/trunk/arch/x86/pci/Makefile_32 +++ b/trunk/arch/x86/pci/Makefile_32 @@ -6,19 +6,11 @@ obj-$(CONFIG_PCI_DIRECT) += direct.o obj-$(CONFIG_PCI_OLPC) += olpc.o pci-y := fixup.o - -# Do not change the ordering here. There is a nasty init function -# ordering dependency which breaks when you move acpi.o below -# legacy/irq.o pci-$(CONFIG_ACPI) += acpi.o pci-y += legacy.o irq.o -# Careful: VISWS and NUMAQ overrule the pci-y above. The colons are -# therefor correct. This needs a proper fix by distangling the code. -pci-$(CONFIG_X86_VISWS) := visws.o fixup.o -pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o - -# Necessary for NUMAQ as well +pci-$(CONFIG_X86_VISWS) += visws.o fixup.o +pci-$(CONFIG_X86_NUMAQ) += numa.o irq.o pci-$(CONFIG_NUMA) += mp_bus_to_node.o obj-y += $(pci-y) common.o early.o diff --git a/trunk/arch/x86/pci/acpi.c b/trunk/arch/x86/pci/acpi.c index d95de2f199cd..1a9c0c6a1a18 100644 --- a/trunk/arch/x86/pci/acpi.c +++ b/trunk/arch/x86/pci/acpi.c @@ -6,6 +6,45 @@ #include #include "pci.h" +static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) +{ + pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; + printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); + return 0; +} + +static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = { +/* + * Systems where PCI IO resource ISA alignment can be skipped + * when the ISA enable bit in the bridge control is not set + */ + { + .callback = can_skip_ioresource_align, + .ident = "IBM System x3800", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), + }, + }, + { + .callback = can_skip_ioresource_align, + .ident = "IBM System x3850", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), + }, + }, + { + .callback = can_skip_ioresource_align, + .ident = "IBM System x3950", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), + }, + }, + {} +}; + struct pci_root_info { char *name; unsigned int res_num; @@ -157,6 +196,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do int pxm; #endif + dmi_check_system(acpi_pciprobe_dmi_table); + if (domain && !pci_domains_supported) { printk(KERN_WARNING "PCI: Multiple domains not supported " "(dom %d, bus %d)\n", domain, busnum); diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 8545c8a9d107..2a4d751818b7 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -77,48 +77,17 @@ int pcibios_scanned; */ DEFINE_SPINLOCK(pci_config_lock); -static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) +static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { - pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; - printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); - return 0; -} - -static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = { -/* - * Systems where PCI IO resource ISA alignment can be skipped - * when the ISA enable bit in the bridge control is not set - */ - { - .callback = can_skip_ioresource_align, - .ident = "IBM System x3800", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), - }, - }, - { - .callback = can_skip_ioresource_align, - .ident = "IBM System x3850", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), - }, - }, - { - .callback = can_skip_ioresource_align, - .ident = "IBM System x3950", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), - }, - }, - {} -}; - -void __init dmi_check_skip_isa_align(void) -{ - dmi_check_system(can_skip_pciprobe_dmi_table); + struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; + + if (rom_r->parent) + return; + if (rom_r->start) + /* we deal with BIOS assigned ROM later */ + return; + if (!(pci_probe & PCI_ASSIGN_ROMS)) + rom_r->start = rom_r->end = rom_r->flags = 0; } /* @@ -128,7 +97,11 @@ void __init dmi_check_skip_isa_align(void) void __devinit pcibios_fixup_bus(struct pci_bus *b) { + struct pci_dev *dev; + pci_read_bridge_bases(b); + list_for_each_entry(dev, &b->devices, bus_list) + pcibios_fixup_device_resources(dev); } /* @@ -345,16 +318,13 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { {} }; -void __init dmi_check_pciprobe(void) -{ - dmi_check_system(pciprobe_dmi_table); -} - struct pci_bus * __devinit pcibios_scan_root(int busnum) { struct pci_bus *bus = NULL; struct pci_sysdata *sd; + dmi_check_system(pciprobe_dmi_table); + while ((bus = pci_find_next_bus(bus)) != NULL) { if (bus->number == busnum) { /* Already scanned */ @@ -492,9 +462,6 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "routeirq")) { pci_routeirq = 1; return NULL; - } else if (!strcmp(str, "skip_isa_align")) { - pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; - return NULL; } return str; } @@ -522,7 +489,7 @@ void pcibios_disable_device (struct pci_dev *dev) pcibios_disable_irq(dev); } -struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) +struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) { struct pci_bus *bus = NULL; struct pci_sysdata *sd; @@ -545,7 +512,7 @@ struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, return bus; } -struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno) +struct pci_bus *pci_scan_bus_with_sysdata(int busno) { return pci_scan_bus_on_node(busno, &pci_root_ops, -1); } diff --git a/trunk/arch/x86/pci/fixup.c b/trunk/arch/x86/pci/fixup.c index ff3a6a336342..b60b2abd480c 100644 --- a/trunk/arch/x86/pci/fixup.c +++ b/trunk/arch/x86/pci/fixup.c @@ -502,7 +502,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, */ static void fam10h_pci_cfg_space_size(struct pci_dev *dev) { - dev->cfg_size = pci_cfg_space_size_ext(dev); + dev->cfg_size = pci_cfg_space_size_ext(dev, 0); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size); diff --git a/trunk/arch/x86/pci/init.c b/trunk/arch/x86/pci/init.c index e70b9c57b88e..dd30c6076b5d 100644 --- a/trunk/arch/x86/pci/init.c +++ b/trunk/arch/x86/pci/init.c @@ -33,10 +33,6 @@ static __init int pci_access_init(void) printk(KERN_ERR "PCI: Fatal: No config space access function found\n"); - dmi_check_pciprobe(); - - dmi_check_skip_isa_align(); - return 0; } arch_initcall(pci_access_init); diff --git a/trunk/arch/x86/pci/pci.h b/trunk/arch/x86/pci/pci.h index f3972b12c60a..c58805a92db5 100644 --- a/trunk/arch/x86/pci/pci.h +++ b/trunk/arch/x86/pci/pci.h @@ -38,9 +38,6 @@ enum pci_bf_sort_state { pci_dmi_bf, }; -extern void __init dmi_check_pciprobe(void); -extern void __init dmi_check_skip_isa_align(void); - /* pci-i386.c */ extern unsigned int pcibios_max_latency; diff --git a/trunk/arch/x86/vdso/vdso32-setup.c b/trunk/arch/x86/vdso/vdso32-setup.c index cf058fecfcee..4dceeb1fc5e0 100644 --- a/trunk/arch/x86/vdso/vdso32-setup.c +++ b/trunk/arch/x86/vdso/vdso32-setup.c @@ -162,7 +162,7 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr) Elf32_Shdr *shdr; int i; - BUG_ON(memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 || + BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 || !elf_check_arch_ia32(ehdr) || ehdr->e_type != ET_DYN); diff --git a/trunk/arch/x86/video/fbdev.c b/trunk/arch/x86/video/fbdev.c index 69527688f794..4db42bff8c60 100644 --- a/trunk/arch/x86/video/fbdev.c +++ b/trunk/arch/x86/video/fbdev.c @@ -1,4 +1,5 @@ /* + * * Copyright (C) 2007 Antonino Daplas * * This file is subject to the terms and conditions of the GNU General Public @@ -28,4 +29,3 @@ int fb_is_primary_device(struct fb_info *info) return retval; } EXPORT_SYMBOL(fb_is_primary_device); -MODULE_LICENSE("GPL"); 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 2987fe47b5ee..5d09f8c56024 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -54,16 +54,15 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done); static void drive_stat_acct(struct request *rq, int new_io) { - struct hd_struct *part; int rw = rq_data_dir(rq); if (!blk_fs_request(rq) || !rq->rq_disk) return; - part = get_part(rq->rq_disk, rq->sector); - if (!new_io) - __all_stat_inc(rq->rq_disk, part, merges[rw], rq->sector); - else { + if (!new_io) { + __all_stat_inc(rq->rq_disk, merges[rw], rq->sector); + } else { + struct hd_struct *part = get_part(rq->rq_disk, rq->sector); disk_round_stats(rq->rq_disk); rq->rq_disk->in_flight++; if (part) { @@ -137,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; } @@ -254,11 +253,9 @@ EXPORT_SYMBOL(__generic_unplug_device); **/ void generic_unplug_device(struct request_queue *q) { - if (blk_queue_plugged(q)) { - spin_lock_irq(q->queue_lock); - __generic_unplug_device(q); - spin_unlock_irq(q->queue_lock); - } + spin_lock_irq(q->queue_lock); + __generic_unplug_device(q); + spin_unlock_irq(q->queue_lock); } EXPORT_SYMBOL(generic_unplug_device); @@ -1539,11 +1536,10 @@ static int __end_that_request_first(struct request *req, int error, } if (blk_fs_request(req) && req->rq_disk) { - struct hd_struct *part = get_part(req->rq_disk, req->sector); const int rw = rq_data_dir(req); - all_stat_add(req->rq_disk, part, sectors[rw], - nr_bytes >> 9, req->sector); + all_stat_add(req->rq_disk, sectors[rw], + nr_bytes >> 9, req->sector); } total_bytes = bio_nbytes = 0; @@ -1570,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; } @@ -1729,8 +1726,8 @@ static void end_that_request_last(struct request *req, int error) const int rw = rq_data_dir(req); struct hd_struct *part = get_part(disk, req->sector); - __all_stat_inc(disk, part, ios[rw], req->sector); - __all_stat_add(disk, part, ticks[rw], duration, req->sector); + __all_stat_inc(disk, ios[rw], req->sector); + __all_stat_add(disk, ticks[rw], duration, req->sector); disk_round_stats(disk); disk->in_flight--; if (part) { diff --git a/trunk/block/blk-ioc.c b/trunk/block/blk-ioc.c index 012f065ac8e2..e34df7c9fc36 100644 --- a/trunk/block/blk-ioc.c +++ b/trunk/block/blk-ioc.c @@ -41,8 +41,8 @@ int put_io_context(struct io_context *ioc) rcu_read_lock(); if (ioc->aic && ioc->aic->dtor) ioc->aic->dtor(ioc->aic); - cfq_dtor(ioc); rcu_read_unlock(); + cfq_dtor(ioc); kmem_cache_free(iocontext_cachep, ioc); return 1; diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c index 651136aae76e..73b23562af20 100644 --- a/trunk/block/blk-merge.c +++ b/trunk/block/blk-merge.c @@ -149,9 +149,9 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio, struct bio *nxt) { - if (!bio_flagged(bio, BIO_SEG_VALID)) + if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) blk_recount_segments(q, bio); - if (!bio_flagged(nxt, BIO_SEG_VALID)) + if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) blk_recount_segments(q, nxt); if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) @@ -312,9 +312,9 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, q->last_merge = NULL; return 0; } - if (!bio_flagged(req->biotail, BIO_SEG_VALID)) + if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID))) blk_recount_segments(q, req->biotail); - if (!bio_flagged(bio, BIO_SEG_VALID)) + if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) blk_recount_segments(q, bio); len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) @@ -352,9 +352,9 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, return 0; } len = bio->bi_hw_back_size + req->bio->bi_hw_front_size; - if (!bio_flagged(bio, BIO_SEG_VALID)) + if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) blk_recount_segments(q, bio); - if (!bio_flagged(req->bio, BIO_SEG_VALID)) + if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID))) blk_recount_segments(q, req->bio); if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && !BIOVEC_VIRT_OVERSIZE(len)) { 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-sysfs.c b/trunk/block/blk-sysfs.c index 304ec73ab821..e85c4013e8a2 100644 --- a/trunk/block/blk-sysfs.c +++ b/trunk/block/blk-sysfs.c @@ -146,13 +146,11 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page, unsigned long nm; ssize_t ret = queue_var_store(&nm, page, count); - spin_lock_irq(q->queue_lock); if (nm) - queue_flag_set(QUEUE_FLAG_NOMERGES, q); + set_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags); else - queue_flag_clear(QUEUE_FLAG_NOMERGES, q); + clear_bit(QUEUE_FLAG_NOMERGES, &q->queue_flags); - spin_unlock_irq(q->queue_lock); return ret; } diff --git a/trunk/block/blk-tag.c b/trunk/block/blk-tag.c index 32667beb03ee..e176ddbe599e 100644 --- a/trunk/block/blk-tag.c +++ b/trunk/block/blk-tag.c @@ -70,7 +70,7 @@ void __blk_queue_free_tags(struct request_queue *q) __blk_free_tags(bqt); q->queue_tags = NULL; - queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); + queue_flag_clear(QUEUE_FLAG_QUEUED, q); } /** @@ -98,7 +98,7 @@ EXPORT_SYMBOL(blk_free_tags); **/ void blk_queue_free_tags(struct request_queue *q) { - queue_flag_clear_unlocked(QUEUE_FLAG_QUEUED, q); + queue_flag_clear(QUEUE_FLAG_QUEUED, q); } EXPORT_SYMBOL(blk_queue_free_tags); @@ -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); @@ -171,9 +171,6 @@ EXPORT_SYMBOL(blk_init_tags); * @q: the request queue for the device * @depth: the maximum queue depth supported * @tags: the tag to use - * - * Queue lock must be held here if the function is called to resize an - * existing map. **/ int blk_queue_init_tags(struct request_queue *q, int depth, struct blk_queue_tag *tags) @@ -200,7 +197,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth, * assign it, all done */ q->queue_tags = tags; - queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q); + queue_flag_set(QUEUE_FLAG_QUEUED, q); INIT_LIST_HEAD(&q->tag_busy_list); return 0; fail: @@ -299,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; } /* @@ -343,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 f0b7cd343216..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 @@ -174,11 +174,7 @@ static int bsg_io_schedule(struct bsg_device *bd) static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, struct sg_io_v4 *hdr, int has_write_perm) { - if (hdr->request_len > BLK_MAX_CDB) { - rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); - if (!rq->cmd) - return -ENOMEM; - } + memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ if (copy_from_user(rq->cmd, (void *)(unsigned long)hdr->request, hdr->request_len)) @@ -215,6 +211,8 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) if (hdr->guard != 'Q') return -EINVAL; + if (hdr->request_len > BLK_MAX_CDB) + return -EINVAL; if (hdr->dout_xfer_len > (q->max_sectors << 9) || hdr->din_xfer_len > (q->max_sectors << 9)) return -EIO; @@ -304,8 +302,6 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr) } return rq; out: - if (rq->cmd != rq->__cmd) - kfree(rq->cmd); blk_put_request(rq); if (next_rq) { blk_rq_unmap_user(next_rq->bio); @@ -459,8 +455,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, ret = rq->errors; blk_rq_unmap_user(bio); - if (rq->cmd != rq->__cmd) - kfree(rq->cmd); blk_put_request(rq); return ret; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index b399c62936e0..f4e1006c253d 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -1142,17 +1142,6 @@ static void cfq_put_queue(struct cfq_queue *cfqq) kmem_cache_free(cfq_pool, cfqq); } -static void -__call_for_each_cic(struct io_context *ioc, - void (*func)(struct io_context *, struct cfq_io_context *)) -{ - struct cfq_io_context *cic; - struct hlist_node *n; - - hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) - func(ioc, cic); -} - /* * Call func for each cic attached to this ioc. */ @@ -1160,8 +1149,12 @@ static void call_for_each_cic(struct io_context *ioc, void (*func)(struct io_context *, struct cfq_io_context *)) { + struct cfq_io_context *cic; + struct hlist_node *n; + rcu_read_lock(); - __call_for_each_cic(ioc, func); + hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) + func(ioc, cic); rcu_read_unlock(); } @@ -1205,7 +1198,7 @@ static void cfq_free_io_context(struct io_context *ioc) * should be ok to iterate over the known list, we will see all cic's * since no new ones are added. */ - __call_for_each_cic(ioc, cic_free_func); + call_for_each_cic(ioc, cic_free_func); } static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) @@ -1303,10 +1296,10 @@ static void cfq_init_prio_data(struct cfq_queue *cfqq, struct io_context *ioc) printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class); case IOPRIO_CLASS_NONE: /* - * no prio set, inherit CPU scheduling settings + * no prio set, place us in the middle of the BE classes */ cfqq->ioprio = task_nice_ioprio(tsk); - cfqq->ioprio_class = task_nice_ioclass(tsk); + cfqq->ioprio_class = IOPRIO_CLASS_BE; break; case IOPRIO_CLASS_RT: cfqq->ioprio = task_ioprio(ioc); 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/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 78199c08ec92..ffa3720e6ca0 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -33,12 +33,13 @@ #include /* Command group 3 is reserved and should never be used. */ -const unsigned char scsi_command_size_tbl[8] = +const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 16, 12, 10, 10 }; -EXPORT_SYMBOL(scsi_command_size_tbl); + +EXPORT_SYMBOL(scsi_command_size); #include 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/accessibility/Kconfig b/trunk/drivers/accessibility/Kconfig index ef3b65bfdd0a..1264c4b98094 100644 --- a/trunk/drivers/accessibility/Kconfig +++ b/trunk/drivers/accessibility/Kconfig @@ -1,17 +1,7 @@ menuconfig ACCESSIBILITY bool "Accessibility support" ---help--- - Accessibility handles all special kinds of hardware devices or - software adapters which help people with disabilities (e.g. - blindness) to use computers. - - That includes braille devices, speech synthesis, keyboard - remapping, etc. - - Say Y here to get to see options for accessibility. - This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. + Enable a submenu where accessibility items may be enabled. If unsure, say N. diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index 9bf2986a2788..1c11df9a5f32 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -205,8 +205,8 @@ config SATA_VITESSE If unsure, say N. config SATA_INIC162X - tristate "Initio 162x SATA support" - depends on PCI + tristate "Initio 162x SATA support (HIGHLY EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL help This option enables support for Initio 162x Serial ATA. @@ -697,15 +697,6 @@ config PATA_SCC If unsure, say N. -config PATA_SCH - tristate "Intel SCH PATA support" - depends on PCI - help - This option enables support for Intel SCH PATA on the Intel - SCH (US15W, US15L, UL11L) series host controllers. - - If unsure, say N. - config PATA_BF54X tristate "Blackfin 54x ATAPI support" depends on BF542 || BF548 || BF549 diff --git a/trunk/drivers/ata/Makefile b/trunk/drivers/ata/Makefile index 674965fa326d..b693d829383a 100644 --- a/trunk/drivers/ata/Makefile +++ b/trunk/drivers/ata/Makefile @@ -67,7 +67,6 @@ obj-$(CONFIG_PATA_SIS) += pata_sis.o obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o obj-$(CONFIG_PATA_SCC) += pata_scc.o -obj-$(CONFIG_PATA_SCH) += pata_sch.o obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 97f83fb2ee2e..8cace9aa9c03 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -1267,7 +1267,9 @@ static int ahci_check_ready(struct ata_link *link) void __iomem *port_mmio = ahci_port_base(link->ap); u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; - return ata_check_ready(status); + if (!(status & ATA_BUSY)) + return 1; + return 0; } static int ahci_softreset(struct ata_link *link, unsigned int *class, diff --git a/trunk/drivers/ata/ata_generic.c b/trunk/drivers/ata/ata_generic.c index 75a406f5e694..47aeccd52fa9 100644 --- a/trunk/drivers/ata/ata_generic.c +++ b/trunk/drivers/ata/ata_generic.c @@ -152,12 +152,6 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id if (dev->vendor == PCI_VENDOR_ID_AL) ata_pci_bmdma_clear_simplex(dev); - if (dev->vendor == PCI_VENDOR_ID_ATI) { - int rc = pcim_enable_device(dev); - if (rc < 0) - return rc; - pcim_pin_device(dev); - } return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL); } diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index a9027b8fbdd5..ea2c7649d399 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -1348,8 +1348,6 @@ static void __devinit piix_init_sidpr(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); struct piix_host_priv *hpriv = host->private_data; - struct ata_device *dev0 = &host->ports[0]->link.device[0]; - u32 scontrol; int i; /* check for availability */ @@ -1368,29 +1366,6 @@ static void __devinit piix_init_sidpr(struct ata_host *host) return; hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; - - /* SCR access via SIDPR doesn't work on some configurations. - * Give it a test drive by inhibiting power save modes which - * we'll do anyway. - */ - scontrol = piix_sidpr_read(dev0, SCR_CONTROL); - - /* if IPM is already 3, SCR access is probably working. Don't - * un-inhibit power save modes as BIOS might have inhibited - * them for a reason. - */ - if ((scontrol & 0xf00) != 0x300) { - scontrol |= 0x300; - piix_sidpr_write(dev0, SCR_CONTROL, scontrol); - scontrol = piix_sidpr_read(dev0, SCR_CONTROL); - - if ((scontrol & 0xf00) != 0x300) { - dev_printk(KERN_INFO, host->dev, "SCR access via " - "SIDPR is available but doesn't work\n"); - return; - } - } - host->ports[0]->ops = &piix_sidpr_sata_ops; host->ports[1]->ops = &piix_sidpr_sata_ops; } diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 927b692d723c..3bc488538204 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -6292,7 +6292,6 @@ EXPORT_SYMBOL_GPL(ata_eh_freeze_port); EXPORT_SYMBOL_GPL(ata_eh_thaw_port); EXPORT_SYMBOL_GPL(ata_eh_qc_complete); EXPORT_SYMBOL_GPL(ata_eh_qc_retry); -EXPORT_SYMBOL_GPL(ata_eh_analyze_ncq_error); EXPORT_SYMBOL_GPL(ata_do_eh); EXPORT_SYMBOL_GPL(ata_std_error_handler); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index 62e033146bed..61dcd0026c64 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -1357,7 +1357,7 @@ static void ata_eh_analyze_serror(struct ata_link *link) * LOCKING: * Kernel thread context (may sleep). */ -void ata_eh_analyze_ncq_error(struct ata_link *link) +static void ata_eh_analyze_ncq_error(struct ata_link *link) { struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &link->eh_context; diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 3c2d2289f85e..2ec65a8fda79 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -314,7 +314,11 @@ static int ata_sff_check_ready(struct ata_link *link) { u8 status = link->ap->ops->sff_check_status(link->ap); - return ata_check_ready(status); + if (!(status & ATA_BUSY)) + return 1; + if (status == 0xff) + return -ENODEV; + return 0; } /** diff --git a/trunk/drivers/ata/pata_acpi.c b/trunk/drivers/ata/pata_acpi.c index fbe605711554..c5f91e629945 100644 --- a/trunk/drivers/ata/pata_acpi.c +++ b/trunk/drivers/ata/pata_acpi.c @@ -259,12 +259,6 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .port_ops = &pacpi_ops, }; const struct ata_port_info *ppi[] = { &info, NULL }; - if (pdev->vendor == PCI_VENDOR_ID_ATI) { - int rc = pcim_enable_device(pdev); - if (rc < 0) - return rc; - pcim_pin_device(pdev); - } return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL); } diff --git a/trunk/drivers/ata/pata_sch.c b/trunk/drivers/ata/pata_sch.c deleted file mode 100644 index c8cc027789fe..000000000000 --- a/trunk/drivers/ata/pata_sch.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * pata_sch.c - Intel SCH PATA controllers - * - * Copyright (c) 2008 Alek Du - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * Supports: - * Intel SCH (AF82US15W, AF82US15L, AF82UL11L) chipsets -- see spec at: - * http://download.intel.com/design/chipsets/embedded/datashts/319537.pdf - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "pata_sch" -#define DRV_VERSION "0.2" - -/* see SCH datasheet page 351 */ -enum { - D0TIM = 0x80, /* Device 0 Timing Register */ - D1TIM = 0x84, /* Device 1 Timing Register */ - PM = 0x07, /* PIO Mode Bit Mask */ - MDM = (0x03 << 8), /* Multi-word DMA Mode Bit Mask */ - UDM = (0x07 << 16), /* Ultra DMA Mode Bit Mask */ - PPE = (1 << 30), /* Prefetch/Post Enable */ - USD = (1 << 31), /* Use Synchronous DMA */ -}; - -static int sch_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent); -static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev); -static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev); - -static const struct pci_device_id sch_pci_tbl[] = { - /* Intel SCH PATA Controller */ - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_IDE), 0 }, - { } /* terminate list */ -}; - -static struct pci_driver sch_pci_driver = { - .name = DRV_NAME, - .id_table = sch_pci_tbl, - .probe = sch_init_one, - .remove = ata_pci_remove_one, -#ifdef CONFIG_PM - .suspend = ata_pci_device_suspend, - .resume = ata_pci_device_resume, -#endif -}; - -static struct scsi_host_template sch_sht = { - ATA_BMDMA_SHT(DRV_NAME), -}; - -static struct ata_port_operations sch_pata_ops = { - .inherits = &ata_bmdma_port_ops, - .cable_detect = ata_cable_unknown, - .set_piomode = sch_set_piomode, - .set_dmamode = sch_set_dmamode, -}; - -static struct ata_port_info sch_port_info = { - .flags = 0, - .pio_mask = ATA_PIO4, /* pio0-4 */ - .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ - .udma_mask = ATA_UDMA5, /* udma0-5 */ - .port_ops = &sch_pata_ops, -}; - -MODULE_AUTHOR("Alek Du "); -MODULE_DESCRIPTION("SCSI low-level driver for Intel SCH PATA controllers"); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(pci, sch_pci_tbl); -MODULE_VERSION(DRV_VERSION); - -/** - * sch_set_piomode - Initialize host controller PATA PIO timings - * @ap: Port whose timings we are configuring - * @adev: ATA device - * - * Set PIO mode for device, in host controller PCI config space. - * - * LOCKING: - * None (inherited from caller). - */ - -static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - unsigned int pio = adev->pio_mode - XFER_PIO_0; - struct pci_dev *dev = to_pci_dev(ap->host->dev); - unsigned int port = adev->devno ? D1TIM : D0TIM; - unsigned int data; - - pci_read_config_dword(dev, port, &data); - /* see SCH datasheet page 351 */ - /* set PIO mode */ - data &= ~(PM | PPE); - data |= pio; - /* enable PPE for block device */ - if (adev->class == ATA_DEV_ATA) - data |= PPE; - pci_write_config_dword(dev, port, data); -} - -/** - * sch_set_dmamode - Initialize host controller PATA DMA timings - * @ap: Port whose timings we are configuring - * @adev: ATA device - * - * Set MW/UDMA mode for device, in host controller PCI config space. - * - * LOCKING: - * None (inherited from caller). - */ - -static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev) -{ - unsigned int dma_mode = adev->dma_mode; - struct pci_dev *dev = to_pci_dev(ap->host->dev); - unsigned int port = adev->devno ? D1TIM : D0TIM; - unsigned int data; - - pci_read_config_dword(dev, port, &data); - /* see SCH datasheet page 351 */ - if (dma_mode >= XFER_UDMA_0) { - /* enable Synchronous DMA mode */ - data |= USD; - data &= ~UDM; - data |= (dma_mode - XFER_UDMA_0) << 16; - } else { /* must be MWDMA mode, since we masked SWDMA already */ - data &= ~(USD | MDM); - data |= (dma_mode - XFER_MW_DMA_0) << 8; - } - pci_write_config_dword(dev, port, data); -} - -/** - * sch_init_one - Register SCH ATA PCI device with kernel services - * @pdev: PCI device to register - * @ent: Entry in sch_pci_tbl matching with @pdev - * - * LOCKING: - * Inherited from PCI layer (may sleep). - * - * RETURNS: - * Zero on success, or -ERRNO value. - */ - -static int __devinit sch_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - static int printed_version; - const struct ata_port_info *ppi[] = { &sch_port_info, NULL }; - struct ata_host *host; - int rc; - - if (!printed_version++) - dev_printk(KERN_DEBUG, &pdev->dev, - "version " DRV_VERSION "\n"); - - /* enable device and prepare host */ - rc = pcim_enable_device(pdev); - if (rc) - return rc; - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); - if (rc) - return rc; - pci_set_master(pdev); - return ata_pci_sff_activate_host(host, ata_sff_interrupt, &sch_sht); -} - -static int __init sch_init(void) -{ - return pci_register_driver(&sch_pci_driver); -} - -static void __exit sch_exit(void) -{ - pci_unregister_driver(&sch_pci_driver); -} - -module_init(sch_init); -module_exit(sch_exit); diff --git a/trunk/drivers/ata/sata_inic162x.c b/trunk/drivers/ata/sata_inic162x.c index 3ead02fe379e..d27bb9a2568f 100644 --- a/trunk/drivers/ata/sata_inic162x.c +++ b/trunk/drivers/ata/sata_inic162x.c @@ -10,33 +10,13 @@ * right. Documentation is available at initio's website but it only * documents registers (not programming model). * - * This driver has interesting history. The first version was written - * from the documentation and a 2.4 IDE driver posted on a Taiwan - * company, which didn't use any IDMA features and couldn't handle - * LBA48. The resulting driver couldn't handle LBA48 devices either - * making it pretty useless. - * - * After a while, initio picked the driver up, renamed it to - * sata_initio162x, updated it to use IDMA for ATA DMA commands and - * posted it on their website. It only used ATA_PROT_DMA for IDMA and - * attaching both devices and issuing IDMA and !IDMA commands - * simultaneously broke it due to PIRQ masking interaction but it did - * show how to use the IDMA (ADMA + some initio specific twists) - * engine. - * - * Then, I picked up their changes again and here's the usable driver - * which uses IDMA for everything. Everything works now including - * LBA48, CD/DVD burning, suspend/resume and hotplug. There are some - * issues tho. Result Tf is not resported properly, NCQ isn't - * supported yet and CD/DVD writing works with DMA assisted PIO - * protocol (which, for native SATA devices, shouldn't cause any - * noticeable difference). - * - * Anyways, so, here's finally a working driver for inic162x. Enjoy! - * - * initio: If you guys wanna improve the driver regarding result TF - * access and other stuff, please feel free to contact me. I'll be - * happy to assist. + * - ATA disks work. + * - Hotplug works. + * - ATAPI read works but burning doesn't. This thing is really + * peculiar about ATAPI and I couldn't figure out how ATAPI PIO and + * ATAPI DMA WRITE should be programmed. If you've got a clue, be + * my guest. + * - Both STR and STD work. */ #include @@ -48,19 +28,13 @@ #include #define DRV_NAME "sata_inic162x" -#define DRV_VERSION "0.4" +#define DRV_VERSION "0.3" enum { - MMIO_BAR_PCI = 5, - MMIO_BAR_CARDBUS = 1, + MMIO_BAR = 5, NR_PORTS = 2, - IDMA_CPB_TBL_SIZE = 4 * 32, - - INIC_DMA_BOUNDARY = 0xffffff, - - HOST_ACTRL = 0x08, HOST_CTL = 0x7c, HOST_STAT = 0x7e, HOST_IRQ_STAT = 0xbc, @@ -69,37 +43,22 @@ enum { PORT_SIZE = 0x40, /* registers for ATA TF operation */ - PORT_TF_DATA = 0x00, - PORT_TF_FEATURE = 0x01, - PORT_TF_NSECT = 0x02, - PORT_TF_LBAL = 0x03, - PORT_TF_LBAM = 0x04, - PORT_TF_LBAH = 0x05, - PORT_TF_DEVICE = 0x06, - PORT_TF_COMMAND = 0x07, - PORT_TF_ALT_STAT = 0x08, + PORT_TF = 0x00, + PORT_ALT_STAT = 0x08, PORT_IRQ_STAT = 0x09, PORT_IRQ_MASK = 0x0a, PORT_PRD_CTL = 0x0b, PORT_PRD_ADDR = 0x0c, PORT_PRD_XFERLEN = 0x10, - PORT_CPB_CPBLAR = 0x18, - PORT_CPB_PTQFIFO = 0x1c, /* IDMA register */ PORT_IDMA_CTL = 0x14, - PORT_IDMA_STAT = 0x16, - - PORT_RPQ_FIFO = 0x1e, - PORT_RPQ_CNT = 0x1f, PORT_SCR = 0x20, /* HOST_CTL bits */ HCTL_IRQOFF = (1 << 8), /* global IRQ off */ - HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */ - HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/ - HCTL_PWRDWN = (1 << 12), /* power down PHYs */ + HCTL_PWRDWN = (1 << 13), /* power down PHYs */ HCTL_SOFTRST = (1 << 13), /* global reset (no phy reset) */ HCTL_RPGSEL = (1 << 15), /* register page select */ @@ -122,7 +81,9 @@ enum { PIRQ_PENDING = (1 << 7), /* port IRQ pending (STAT only) */ PIRQ_ERR = PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL, - PIRQ_MASK_DEFAULT = PIRQ_REPLY | PIRQ_ATA, + + PIRQ_MASK_DMA_READ = PIRQ_REPLY | PIRQ_ATA, + PIRQ_MASK_OTHER = PIRQ_REPLY | PIRQ_COMPLETE, PIRQ_MASK_FREEZE = 0xff, /* PORT_PRD_CTL bits */ @@ -135,104 +96,20 @@ enum { IDMA_CTL_RST_IDMA = (1 << 5), /* reset IDMA machinary */ IDMA_CTL_GO = (1 << 7), /* IDMA mode go */ IDMA_CTL_ATA_NIEN = (1 << 8), /* ATA IRQ disable */ - - /* PORT_IDMA_STAT bits */ - IDMA_STAT_PERR = (1 << 0), /* PCI ERROR MODE */ - IDMA_STAT_CPBERR = (1 << 1), /* ADMA CPB error */ - IDMA_STAT_LGCY = (1 << 3), /* ADMA legacy */ - IDMA_STAT_UIRQ = (1 << 4), /* ADMA unsolicited irq */ - IDMA_STAT_STPD = (1 << 5), /* ADMA stopped */ - IDMA_STAT_PSD = (1 << 6), /* ADMA pause */ - IDMA_STAT_DONE = (1 << 7), /* ADMA done */ - - IDMA_STAT_ERR = IDMA_STAT_PERR | IDMA_STAT_CPBERR, - - /* CPB Control Flags*/ - CPB_CTL_VALID = (1 << 0), /* CPB valid */ - CPB_CTL_QUEUED = (1 << 1), /* queued command */ - CPB_CTL_DATA = (1 << 2), /* data, rsvd in datasheet */ - CPB_CTL_IEN = (1 << 3), /* PCI interrupt enable */ - CPB_CTL_DEVDIR = (1 << 4), /* device direction control */ - - /* CPB Response Flags */ - CPB_RESP_DONE = (1 << 0), /* ATA command complete */ - CPB_RESP_REL = (1 << 1), /* ATA release */ - CPB_RESP_IGNORED = (1 << 2), /* CPB ignored */ - CPB_RESP_ATA_ERR = (1 << 3), /* ATA command error */ - CPB_RESP_SPURIOUS = (1 << 4), /* ATA spurious interrupt error */ - CPB_RESP_UNDERFLOW = (1 << 5), /* APRD deficiency length error */ - CPB_RESP_OVERFLOW = (1 << 6), /* APRD exccess length error */ - CPB_RESP_CPB_ERR = (1 << 7), /* CPB error flag */ - - /* PRD Control Flags */ - PRD_DRAIN = (1 << 1), /* ignore data excess */ - PRD_CDB = (1 << 2), /* atapi packet command pointer */ - PRD_DIRECT_INTR = (1 << 3), /* direct interrupt */ - PRD_DMA = (1 << 4), /* data transfer method */ - PRD_WRITE = (1 << 5), /* data dir, rsvd in datasheet */ - PRD_IOM = (1 << 6), /* io/memory transfer */ - PRD_END = (1 << 7), /* APRD chain end */ }; -/* Comman Parameter Block */ -struct inic_cpb { - u8 resp_flags; /* Response Flags */ - u8 error; /* ATA Error */ - u8 status; /* ATA Status */ - u8 ctl_flags; /* Control Flags */ - __le32 len; /* Total Transfer Length */ - __le32 prd; /* First PRD pointer */ - u8 rsvd[4]; - /* 16 bytes */ - u8 feature; /* ATA Feature */ - u8 hob_feature; /* ATA Ex. Feature */ - u8 device; /* ATA Device/Head */ - u8 mirctl; /* Mirror Control */ - u8 nsect; /* ATA Sector Count */ - u8 hob_nsect; /* ATA Ex. Sector Count */ - u8 lbal; /* ATA Sector Number */ - u8 hob_lbal; /* ATA Ex. Sector Number */ - u8 lbam; /* ATA Cylinder Low */ - u8 hob_lbam; /* ATA Ex. Cylinder Low */ - u8 lbah; /* ATA Cylinder High */ - u8 hob_lbah; /* ATA Ex. Cylinder High */ - u8 command; /* ATA Command */ - u8 ctl; /* ATA Control */ - u8 slave_error; /* Slave ATA Error */ - u8 slave_status; /* Slave ATA Status */ - /* 32 bytes */ -} __packed; - -/* Physical Region Descriptor */ -struct inic_prd { - __le32 mad; /* Physical Memory Address */ - __le16 len; /* Transfer Length */ - u8 rsvd; - u8 flags; /* Control Flags */ -} __packed; - -struct inic_pkt { - struct inic_cpb cpb; - struct inic_prd prd[LIBATA_MAX_PRD + 1]; /* + 1 for cdb */ - u8 cdb[ATAPI_CDB_LEN]; -} __packed; - struct inic_host_priv { - void __iomem *mmio_base; - u16 cached_hctl; + u16 cached_hctl; }; struct inic_port_priv { - struct inic_pkt *pkt; - dma_addr_t pkt_dma; - u32 *cpb_tbl; - dma_addr_t cpb_tbl_dma; + u8 dfl_prdctl; + u8 cached_prdctl; + u8 cached_pirq_mask; }; static struct scsi_host_template inic_sht = { - ATA_BASE_SHT(DRV_NAME), - .sg_tablesize = LIBATA_MAX_PRD, /* maybe it can be larger? */ - .dma_boundary = INIC_DMA_BOUNDARY, + ATA_BMDMA_SHT(DRV_NAME), }; static const int scr_map[] = { @@ -243,34 +120,54 @@ static const int scr_map[] = { static void __iomem *inic_port_base(struct ata_port *ap) { - struct inic_host_priv *hpriv = ap->host->private_data; + return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE; +} + +static void __inic_set_pirq_mask(struct ata_port *ap, u8 mask) +{ + void __iomem *port_base = inic_port_base(ap); + struct inic_port_priv *pp = ap->private_data; - return hpriv->mmio_base + ap->port_no * PORT_SIZE; + writeb(mask, port_base + PORT_IRQ_MASK); + pp->cached_pirq_mask = mask; +} + +static void inic_set_pirq_mask(struct ata_port *ap, u8 mask) +{ + struct inic_port_priv *pp = ap->private_data; + + if (pp->cached_pirq_mask != mask) + __inic_set_pirq_mask(ap, mask); } static void inic_reset_port(void __iomem *port_base) { void __iomem *idma_ctl = port_base + PORT_IDMA_CTL; + u16 ctl; - /* stop IDMA engine */ - readw(idma_ctl); /* flush */ - msleep(1); + ctl = readw(idma_ctl); + ctl &= ~(IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN | IDMA_CTL_GO); /* mask IRQ and assert reset */ - writew(IDMA_CTL_RST_IDMA, idma_ctl); + writew(ctl | IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN, idma_ctl); readw(idma_ctl); /* flush */ + + /* give it some time */ msleep(1); /* release reset */ - writew(0, idma_ctl); + writew(ctl | IDMA_CTL_ATA_NIEN, idma_ctl); /* clear irq */ writeb(0xff, port_base + PORT_IRQ_STAT); + + /* reenable ATA IRQ, turn off IDMA mode */ + writew(ctl, idma_ctl); } static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) { - void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR; + void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) @@ -287,126 +184,120 @@ static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { - void __iomem *scr_addr = inic_port_base(ap) + PORT_SCR; + void __iomem *scr_addr = ap->ioaddr.scr_addr; + void __iomem *addr; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) return -EINVAL; + addr = scr_addr + scr_map[sc_reg] * 4; writel(val, scr_addr + scr_map[sc_reg] * 4); return 0; } -static void inic_stop_idma(struct ata_port *ap) -{ - void __iomem *port_base = inic_port_base(ap); - - readb(port_base + PORT_RPQ_FIFO); - readb(port_base + PORT_RPQ_CNT); - writew(0, port_base + PORT_IDMA_CTL); -} - -static void inic_host_err_intr(struct ata_port *ap, u8 irq_stat, u16 idma_stat) +/* + * In TF mode, inic162x is very similar to SFF device. TF registers + * function the same. DMA engine behaves similary using the same PRD + * format as BMDMA but different command register, interrupt and event + * notification methods are used. The following inic_bmdma_*() + * functions do the impedance matching. + */ +static void inic_bmdma_setup(struct ata_queued_cmd *qc) { - struct ata_eh_info *ehi = &ap->link.eh_info; + struct ata_port *ap = qc->ap; struct inic_port_priv *pp = ap->private_data; - struct inic_cpb *cpb = &pp->pkt->cpb; - bool freeze = false; + void __iomem *port_base = inic_port_base(ap); + int rw = qc->tf.flags & ATA_TFLAG_WRITE; - ata_ehi_clear_desc(ehi); - ata_ehi_push_desc(ehi, "irq_stat=0x%x idma_stat=0x%x", - irq_stat, idma_stat); + /* make sure device sees PRD table writes */ + wmb(); - inic_stop_idma(ap); + /* load transfer length */ + writel(qc->nbytes, port_base + PORT_PRD_XFERLEN); - if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) { - ata_ehi_push_desc(ehi, "hotplug"); - ata_ehi_hotplugged(ehi); - freeze = true; - } - - if (idma_stat & IDMA_STAT_PERR) { - ata_ehi_push_desc(ehi, "PCI error"); - freeze = true; - } + /* turn on DMA and specify data direction */ + pp->cached_prdctl = pp->dfl_prdctl | PRD_CTL_DMAEN; + if (!rw) + pp->cached_prdctl |= PRD_CTL_WR; + writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL); - if (idma_stat & IDMA_STAT_CPBERR) { - ata_ehi_push_desc(ehi, "CPB error"); + /* issue r/w command */ + ap->ops->sff_exec_command(ap, &qc->tf); +} - if (cpb->resp_flags & CPB_RESP_IGNORED) { - __ata_ehi_push_desc(ehi, " ignored"); - ehi->err_mask |= AC_ERR_INVALID; - freeze = true; - } +static void inic_bmdma_start(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct inic_port_priv *pp = ap->private_data; + void __iomem *port_base = inic_port_base(ap); - if (cpb->resp_flags & CPB_RESP_ATA_ERR) - ehi->err_mask |= AC_ERR_DEV; + /* start host DMA transaction */ + pp->cached_prdctl |= PRD_CTL_START; + writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL); +} - if (cpb->resp_flags & CPB_RESP_SPURIOUS) { - __ata_ehi_push_desc(ehi, " spurious-intr"); - ehi->err_mask |= AC_ERR_HSM; - freeze = true; - } +static void inic_bmdma_stop(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct inic_port_priv *pp = ap->private_data; + void __iomem *port_base = inic_port_base(ap); - if (cpb->resp_flags & - (CPB_RESP_UNDERFLOW | CPB_RESP_OVERFLOW)) { - __ata_ehi_push_desc(ehi, " data-over/underflow"); - ehi->err_mask |= AC_ERR_HSM; - freeze = true; - } - } + /* stop DMA engine */ + writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL); +} - if (freeze) - ata_port_freeze(ap); - else - ata_port_abort(ap); +static u8 inic_bmdma_status(struct ata_port *ap) +{ + /* event is already verified by the interrupt handler */ + return ATA_DMA_INTR; } static void inic_host_intr(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); + struct ata_eh_info *ehi = &ap->link.eh_info; u8 irq_stat; - u16 idma_stat; - /* read and clear IRQ status */ + /* fetch and clear irq */ irq_stat = readb(port_base + PORT_IRQ_STAT); writeb(irq_stat, port_base + PORT_IRQ_STAT); - idma_stat = readw(port_base + PORT_IDMA_STAT); - - if (unlikely((irq_stat & PIRQ_ERR) || (idma_stat & IDMA_STAT_ERR))) - inic_host_err_intr(ap, irq_stat, idma_stat); - if (unlikely(!qc)) - goto spurious; + if (likely(!(irq_stat & PIRQ_ERR))) { + struct ata_queued_cmd *qc = + ata_qc_from_tag(ap, ap->link.active_tag); - if (likely(idma_stat & IDMA_STAT_DONE)) { - inic_stop_idma(ap); + if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { + ap->ops->sff_check_status(ap); /* clear ATA interrupt */ + return; + } - /* Depending on circumstances, device error - * isn't reported by IDMA, check it explicitly. - */ - if (unlikely(readb(port_base + PORT_TF_COMMAND) & - (ATA_DF | ATA_ERR))) - qc->err_mask |= AC_ERR_DEV; + if (likely(ata_sff_host_intr(ap, qc))) + return; - ata_qc_complete(qc); + ap->ops->sff_check_status(ap); /* clear ATA interrupt */ + ata_port_printk(ap, KERN_WARNING, "unhandled " + "interrupt, irq_stat=%x\n", irq_stat); return; } - spurious: - ata_port_printk(ap, KERN_WARNING, "unhandled interrupt: " - "cmd=0x%x irq_stat=0x%x idma_stat=0x%x\n", - qc ? qc->tf.command : 0xff, irq_stat, idma_stat); + /* error */ + ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat); + + if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) { + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + } else + ata_port_abort(ap); } static irqreturn_t inic_interrupt(int irq, void *dev_instance) { struct ata_host *host = dev_instance; - struct inic_host_priv *hpriv = host->private_data; + void __iomem *mmio_base = host->iomap[MMIO_BAR]; u16 host_irq_stat; int i, handled = 0;; - host_irq_stat = readw(hpriv->mmio_base + HOST_IRQ_STAT); + host_irq_stat = readw(mmio_base + HOST_IRQ_STAT); if (unlikely(!(host_irq_stat & HIRQ_GLOBAL))) goto out; @@ -436,173 +327,60 @@ static irqreturn_t inic_interrupt(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -static int inic_check_atapi_dma(struct ata_queued_cmd *qc) -{ - /* For some reason ATAPI_PROT_DMA doesn't work for some - * commands including writes and other misc ops. Use PIO - * protocol instead, which BTW is driven by the DMA engine - * anyway, so it shouldn't make much difference for native - * SATA devices. - */ - if (atapi_cmd_type(qc->cdb[0]) == READ) - return 0; - return 1; -} - -static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc) -{ - struct scatterlist *sg; - unsigned int si; - u8 flags = 0; - - if (qc->tf.flags & ATA_TFLAG_WRITE) - flags |= PRD_WRITE; - - if (ata_is_dma(qc->tf.protocol)) - flags |= PRD_DMA; - - for_each_sg(qc->sg, sg, qc->n_elem, si) { - prd->mad = cpu_to_le32(sg_dma_address(sg)); - prd->len = cpu_to_le16(sg_dma_len(sg)); - prd->flags = flags; - prd++; - } - - WARN_ON(!si); - prd[-1].flags |= PRD_END; -} - -static void inic_qc_prep(struct ata_queued_cmd *qc) -{ - struct inic_port_priv *pp = qc->ap->private_data; - struct inic_pkt *pkt = pp->pkt; - struct inic_cpb *cpb = &pkt->cpb; - struct inic_prd *prd = pkt->prd; - bool is_atapi = ata_is_atapi(qc->tf.protocol); - bool is_data = ata_is_data(qc->tf.protocol); - unsigned int cdb_len = 0; - - VPRINTK("ENTER\n"); - - if (is_atapi) - cdb_len = qc->dev->cdb_len; - - /* prepare packet, based on initio driver */ - memset(pkt, 0, sizeof(struct inic_pkt)); - - cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN; - if (is_atapi || is_data) - cpb->ctl_flags |= CPB_CTL_DATA; - - cpb->len = cpu_to_le32(qc->nbytes + cdb_len); - cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd)); - - cpb->device = qc->tf.device; - cpb->feature = qc->tf.feature; - cpb->nsect = qc->tf.nsect; - cpb->lbal = qc->tf.lbal; - cpb->lbam = qc->tf.lbam; - cpb->lbah = qc->tf.lbah; - - if (qc->tf.flags & ATA_TFLAG_LBA48) { - cpb->hob_feature = qc->tf.hob_feature; - cpb->hob_nsect = qc->tf.hob_nsect; - cpb->hob_lbal = qc->tf.hob_lbal; - cpb->hob_lbam = qc->tf.hob_lbam; - cpb->hob_lbah = qc->tf.hob_lbah; - } - - cpb->command = qc->tf.command; - /* don't load ctl - dunno why. it's like that in the initio driver */ - - /* setup PRD for CDB */ - if (is_atapi) { - memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN); - prd->mad = cpu_to_le32(pp->pkt_dma + - offsetof(struct inic_pkt, cdb)); - prd->len = cpu_to_le16(cdb_len); - prd->flags = PRD_CDB | PRD_WRITE; - if (!is_data) - prd->flags |= PRD_END; - prd++; - } - - /* setup sg table */ - if (is_data) - inic_fill_sg(prd, qc); - - pp->cpb_tbl[0] = pp->pkt_dma; -} - static unsigned int inic_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *port_base = inic_port_base(ap); - - /* fire up the ADMA engine */ - writew(HCTL_FTHD0, port_base + HOST_CTL); - writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); - writeb(0, port_base + PORT_CPB_PTQFIFO); - - return 0; -} - -static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf) -{ - void __iomem *port_base = inic_port_base(ap); - - tf->feature = readb(port_base + PORT_TF_FEATURE); - tf->nsect = readb(port_base + PORT_TF_NSECT); - tf->lbal = readb(port_base + PORT_TF_LBAL); - tf->lbam = readb(port_base + PORT_TF_LBAM); - tf->lbah = readb(port_base + PORT_TF_LBAH); - tf->device = readb(port_base + PORT_TF_DEVICE); - tf->command = readb(port_base + PORT_TF_COMMAND); -} -static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc) -{ - struct ata_taskfile *rtf = &qc->result_tf; - struct ata_taskfile tf; - - /* FIXME: Except for status and error, result TF access - * doesn't work. I tried reading from BAR0/2, CPB and BAR5. - * None works regardless of which command interface is used. - * For now return true iff status indicates device error. - * This means that we're reporting bogus sector for RW - * failures. Eeekk.... + /* ATA IRQ doesn't wait for DMA transfer completion and vice + * versa. Mask IRQ selectively to detect command completion. + * Without it, ATA DMA read command can cause data corruption. + * + * Something similar might be needed for ATAPI writes. I + * tried a lot of combinations but couldn't find the solution. */ - inic_tf_read(qc->ap, &tf); + if (qc->tf.protocol == ATA_PROT_DMA && + !(qc->tf.flags & ATA_TFLAG_WRITE)) + inic_set_pirq_mask(ap, PIRQ_MASK_DMA_READ); + else + inic_set_pirq_mask(ap, PIRQ_MASK_OTHER); - if (!(tf.command & ATA_ERR)) - return false; + /* Issuing a command to yet uninitialized port locks up the + * controller. Most of the time, this happens for the first + * command after reset which are ATA and ATAPI IDENTIFYs. + * Fast fail if stat is 0x7f or 0xff for those commands. + */ + if (unlikely(qc->tf.command == ATA_CMD_ID_ATA || + qc->tf.command == ATA_CMD_ID_ATAPI)) { + u8 stat = ap->ops->sff_check_status(ap); + if (stat == 0x7f || stat == 0xff) + return AC_ERR_HSM; + } - rtf->command = tf.command; - rtf->feature = tf.feature; - return true; + return ata_sff_qc_issue(qc); } static void inic_freeze(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - writeb(PIRQ_MASK_FREEZE, port_base + PORT_IRQ_MASK); + __inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE); + + ap->ops->sff_check_status(ap); writeb(0xff, port_base + PORT_IRQ_STAT); + + readb(port_base + PORT_IRQ_STAT); /* flush */ } static void inic_thaw(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); + ap->ops->sff_check_status(ap); writeb(0xff, port_base + PORT_IRQ_STAT); - writeb(PIRQ_MASK_DEFAULT, port_base + PORT_IRQ_MASK); -} -static int inic_check_ready(struct ata_link *link) -{ - void __iomem *port_base = inic_port_base(link->ap); + __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER); - return ata_check_ready(readb(port_base + PORT_TF_COMMAND)); + readb(port_base + PORT_IRQ_STAT); /* flush */ } /* @@ -616,15 +394,17 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, void __iomem *port_base = inic_port_base(ap); void __iomem *idma_ctl = port_base + PORT_IDMA_CTL; const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); + u16 val; int rc; /* hammer it into sane state */ inic_reset_port(port_base); - writew(IDMA_CTL_RST_ATA, idma_ctl); + val = readw(idma_ctl); + writew(val | IDMA_CTL_RST_ATA, idma_ctl); readw(idma_ctl); /* flush */ msleep(1); - writew(0, idma_ctl); + writew(val & ~IDMA_CTL_RST_ATA, idma_ctl); rc = sata_link_resume(link, timing, deadline); if (rc) { @@ -638,7 +418,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, struct ata_taskfile tf; /* wait for link to become ready */ - rc = ata_wait_after_reset(link, deadline, inic_check_ready); + rc = ata_sff_wait_after_reset(link, 1, deadline); /* link occupied, -ENODEV too is an error */ if (rc) { ata_link_printk(link, KERN_WARNING, "device not ready " @@ -646,7 +426,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, return rc; } - inic_tf_read(ap, &tf); + ata_sff_tf_read(ap, &tf); *class = ata_dev_classify(&tf); } @@ -656,8 +436,18 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, static void inic_error_handler(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); + struct inic_port_priv *pp = ap->private_data; + unsigned long flags; + /* reset PIO HSM and stop DMA engine */ inic_reset_port(port_base); + + spin_lock_irqsave(ap->lock, flags); + ap->hsm_task_state = HSM_ST_IDLE; + writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL); + spin_unlock_irqrestore(ap->lock, flags); + + /* PIO and DMA engines have been stopped, perform recovery */ ata_std_error_handler(ap); } @@ -668,18 +458,26 @@ static void inic_post_internal_cmd(struct ata_queued_cmd *qc) inic_reset_port(inic_port_base(qc->ap)); } +static void inic_dev_config(struct ata_device *dev) +{ + /* inic can only handle upto LBA28 max sectors */ + if (dev->max_sectors > ATA_MAX_SECTORS) + dev->max_sectors = ATA_MAX_SECTORS; + + if (dev->n_sectors >= 1 << 28) { + ata_dev_printk(dev, KERN_ERR, + "ERROR: This driver doesn't support LBA48 yet and may cause\n" + " data corruption on such devices. Disabling.\n"); + ata_dev_disable(dev); + } +} + static void init_port(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); - struct inic_port_priv *pp = ap->private_data; - /* clear packet and CPB table */ - memset(pp->pkt, 0, sizeof(struct inic_pkt)); - memset(pp->cpb_tbl, 0, IDMA_CPB_TBL_SIZE); - - /* setup PRD and CPB lookup table addresses */ + /* Setup PRD address */ writel(ap->prd_dma, port_base + PORT_PRD_ADDR); - writel(pp->cpb_tbl_dma, port_base + PORT_CPB_CPBLAR); } static int inic_port_resume(struct ata_port *ap) @@ -690,30 +488,28 @@ static int inic_port_resume(struct ata_port *ap) static int inic_port_start(struct ata_port *ap) { - struct device *dev = ap->host->dev; + void __iomem *port_base = inic_port_base(ap); struct inic_port_priv *pp; + u8 tmp; int rc; /* alloc and initialize private data */ - pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); + pp = devm_kzalloc(ap->host->dev, sizeof(*pp), GFP_KERNEL); if (!pp) return -ENOMEM; ap->private_data = pp; + /* default PRD_CTL value, DMAEN, WR and START off */ + tmp = readb(port_base + PORT_PRD_CTL); + tmp &= ~(PRD_CTL_DMAEN | PRD_CTL_WR | PRD_CTL_START); + pp->dfl_prdctl = tmp; + /* Alloc resources */ rc = ata_port_start(ap); - if (rc) + if (rc) { + kfree(pp); return rc; - - pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt), - &pp->pkt_dma, GFP_KERNEL); - if (!pp->pkt) - return -ENOMEM; - - pp->cpb_tbl = dmam_alloc_coherent(dev, IDMA_CPB_TBL_SIZE, - &pp->cpb_tbl_dma, GFP_KERNEL); - if (!pp->cpb_tbl) - return -ENOMEM; + } init_port(ap); @@ -721,18 +517,21 @@ static int inic_port_start(struct ata_port *ap) } static struct ata_port_operations inic_port_ops = { - .inherits = &sata_port_ops, + .inherits = &ata_sff_port_ops, - .check_atapi_dma = inic_check_atapi_dma, - .qc_prep = inic_qc_prep, + .bmdma_setup = inic_bmdma_setup, + .bmdma_start = inic_bmdma_start, + .bmdma_stop = inic_bmdma_stop, + .bmdma_status = inic_bmdma_status, .qc_issue = inic_qc_issue, - .qc_fill_rtf = inic_qc_fill_rtf, .freeze = inic_freeze, .thaw = inic_thaw, + .softreset = ATA_OP_NULL, /* softreset is broken */ .hardreset = inic_hardreset, .error_handler = inic_error_handler, .post_internal_cmd = inic_post_internal_cmd, + .dev_config = inic_dev_config, .scr_read = inic_scr_read, .scr_write = inic_scr_write, @@ -742,6 +541,12 @@ static struct ata_port_operations inic_port_ops = { }; static struct ata_port_info inic_port_info = { + /* For some reason, ATAPI_PROT_PIO is broken on this + * controller, and no, PIO_POLLING does't fix it. It somehow + * manages to report the wrong ireason and ignoring ireason + * results in machine lock up. Tell libata to always prefer + * DMA. + */ .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -794,6 +599,7 @@ static int inic_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); struct inic_host_priv *hpriv = host->private_data; + void __iomem *mmio_base = host->iomap[MMIO_BAR]; int rc; rc = ata_pci_device_do_resume(pdev); @@ -801,7 +607,7 @@ static int inic_pci_device_resume(struct pci_dev *pdev) return rc; if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl); + rc = init_controller(mmio_base, hpriv->cached_hctl); if (rc) return rc; } @@ -819,7 +625,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_host *host; struct inic_host_priv *hpriv; void __iomem * const *iomap; - int mmio_bar; int i, rc; if (!printed_version++) @@ -833,32 +638,39 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) host->private_data = hpriv; - /* Acquire resources and fill host. Note that PCI and cardbus - * use different BARs. - */ + /* acquire resources and fill host */ rc = pcim_enable_device(pdev); if (rc) return rc; - if (pci_resource_flags(pdev, MMIO_BAR_PCI) & IORESOURCE_MEM) - mmio_bar = MMIO_BAR_PCI; - else - mmio_bar = MMIO_BAR_CARDBUS; - - rc = pcim_iomap_regions(pdev, 1 << mmio_bar, DRV_NAME); + rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME); if (rc) return rc; host->iomap = iomap = pcim_iomap_table(pdev); - hpriv->mmio_base = iomap[mmio_bar]; - hpriv->cached_hctl = readw(hpriv->mmio_base + HOST_CTL); for (i = 0; i < NR_PORTS; i++) { struct ata_port *ap = host->ports[i]; - - ata_port_pbar_desc(ap, mmio_bar, -1, "mmio"); - ata_port_pbar_desc(ap, mmio_bar, i * PORT_SIZE, "port"); + struct ata_ioports *port = &ap->ioaddr; + unsigned int offset = i * PORT_SIZE; + + port->cmd_addr = iomap[2 * i]; + port->altstatus_addr = + port->ctl_addr = (void __iomem *) + ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS); + port->scr_addr = iomap[MMIO_BAR] + offset + PORT_SCR; + + ata_sff_std_ports(port); + + ata_port_pbar_desc(ap, MMIO_BAR, -1, "mmio"); + ata_port_pbar_desc(ap, MMIO_BAR, offset, "port"); + ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx", + (unsigned long long)pci_resource_start(pdev, 2 * i), + (unsigned long long)pci_resource_start(pdev, (2 * i + 1)) | + ATA_PCI_CTL_OFS); } + hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL); + /* Set dma_mask. This devices doesn't support 64bit addressing. */ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (rc) { @@ -886,7 +698,7 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return rc; } - rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl); + rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl); if (rc) { dev_printk(KERN_ERR, &pdev->dev, "failed to initialize controller\n"); diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index bb73b2222627..842b1a15b78c 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -65,7 +65,6 @@ #include #include #include -#include #include #include #include @@ -92,9 +91,9 @@ enum { MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0), MV_SATAHC0_REG_BASE = 0x20000, - MV_FLASH_CTL_OFS = 0x1046c, - MV_GPIO_PORT_CTL_OFS = 0x104f0, - MV_RESET_CFG_OFS = 0x180d8, + MV_FLASH_CTL = 0x1046c, + MV_GPIO_PORT_CTL = 0x104f0, + MV_RESET_CFG = 0x180d8, MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ, MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ, @@ -148,21 +147,18 @@ enum { /* PCI interface registers */ PCI_COMMAND_OFS = 0xc00, - PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */ PCI_MAIN_CMD_STS_OFS = 0xd30, STOP_PCI_MASTER = (1 << 2), PCI_MASTER_EMPTY = (1 << 3), GLOB_SFT_RST = (1 << 4), - MV_PCI_MODE_OFS = 0xd00, - MV_PCI_MODE_MASK = 0x30, - + MV_PCI_MODE = 0xd00, MV_PCI_EXP_ROM_BAR_CTL = 0xd2c, MV_PCI_DISC_TIMER = 0xd04, MV_PCI_MSI_TRIGGER = 0xc38, MV_PCI_SERR_MASK = 0xc28, - MV_PCI_XBAR_TMOUT_OFS = 0x1d04, + MV_PCI_XBAR_TMOUT = 0x1d04, MV_PCI_ERR_LOW_ADDRESS = 0x1d40, MV_PCI_ERR_HIGH_ADDRESS = 0x1d44, MV_PCI_ERR_ATTRIBUTE = 0x1d48, @@ -229,18 +225,16 @@ enum { PHY_MODE4 = 0x314, PHY_MODE2 = 0x330, SATA_IFCTL_OFS = 0x344, - SATA_TESTCTL_OFS = 0x348, SATA_IFSTAT_OFS = 0x34c, VENDOR_UNIQUE_FIS_OFS = 0x35c, - FISCFG_OFS = 0x360, - FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */ - FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */ + FIS_CFG_OFS = 0x360, + FIS_CFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */ MV5_PHY_MODE = 0x74, - MV5_LTMODE_OFS = 0x30, - MV5_PHY_CTL_OFS = 0x0C, - SATA_INTERFACE_CFG_OFS = 0x050, + MV5_LT_MODE = 0x30, + MV5_PHY_CTL = 0x0C, + SATA_INTERFACE_CFG = 0x050, MV_M2_PREAMP_MASK = 0x7e0, @@ -338,16 +332,10 @@ enum { EDMA_CMD_OFS = 0x28, /* EDMA command register */ EDMA_EN = (1 << 0), /* enable EDMA */ EDMA_DS = (1 << 1), /* disable EDMA; self-negated */ - EDMA_RESET = (1 << 2), /* reset eng/trans/link/phy */ - - EDMA_STATUS_OFS = 0x30, /* EDMA engine status */ - EDMA_STATUS_CACHE_EMPTY = (1 << 6), /* GenIIe command cache empty */ - EDMA_STATUS_IDLE = (1 << 7), /* GenIIe EDMA enabled/idle */ + ATA_RST = (1 << 2), /* reset trans/link/phy */ - EDMA_IORDY_TMOUT_OFS = 0x34, - EDMA_ARB_CFG_OFS = 0x38, - - EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */ + EDMA_IORDY_TMOUT = 0x34, + EDMA_ARB_CFG = 0x38, GEN_II_NCQ_MAX_SECTORS = 256, /* max sects/io on Gen2 w/NCQ */ @@ -362,19 +350,15 @@ enum { MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */ - MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */ /* Port private flags (pp_flags) */ MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */ - MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */ - MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */ }; #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) #define IS_GEN_II(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_II) #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) -#define IS_PCIE(hpriv) ((hpriv)->hp_flags & MV_HP_PCIE) #define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) #define WINDOW_CTRL(i) (0x20030 + ((i) << 4)) @@ -449,7 +433,6 @@ struct mv_port_priv { unsigned int resp_idx; u32 pp_flags; - unsigned int delayed_eh_pmp_map; }; struct mv_port_signal { @@ -496,7 +479,6 @@ static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); -static int mv_qc_defer(struct ata_queued_cmd *qc); static void mv_qc_prep(struct ata_queued_cmd *qc); static void mv_qc_prep_iie(struct ata_queued_cmd *qc); static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); @@ -545,9 +527,6 @@ static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); static int mv_softreset(struct ata_link *link, unsigned int *class, unsigned long deadline); -static void mv_pmp_error_handler(struct ata_port *ap); -static void mv_process_crpb_entries(struct ata_port *ap, - struct mv_port_priv *pp); /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below * because we have to allow room for worst case splitting of @@ -569,7 +548,6 @@ static struct scsi_host_template mv6_sht = { static struct ata_port_operations mv5_ops = { .inherits = &ata_sff_port_ops, - .qc_defer = mv_qc_defer, .qc_prep = mv_qc_prep, .qc_issue = mv_qc_issue, @@ -588,6 +566,7 @@ static struct ata_port_operations mv5_ops = { static struct ata_port_operations mv6_ops = { .inherits = &mv5_ops, + .qc_defer = sata_pmp_qc_defer_cmd_switch, .dev_config = mv6_dev_config, .scr_read = mv_scr_read, .scr_write = mv_scr_write, @@ -595,11 +574,12 @@ static struct ata_port_operations mv6_ops = { .pmp_hardreset = mv_pmp_hardreset, .pmp_softreset = mv_softreset, .softreset = mv_softreset, - .error_handler = mv_pmp_error_handler, + .error_handler = sata_pmp_error_handler, }; static struct ata_port_operations mv_iie_ops = { .inherits = &mv6_ops, + .qc_defer = ata_std_qc_defer, /* FIS-based switching */ .dev_config = ATA_OP_NULL, .qc_prep = mv_qc_prep_iie, }; @@ -895,29 +875,6 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, } } -static void mv_wait_for_edma_empty_idle(struct ata_port *ap) -{ - void __iomem *port_mmio = mv_ap_base(ap); - const u32 empty_idle = (EDMA_STATUS_CACHE_EMPTY | EDMA_STATUS_IDLE); - const int per_loop = 5, timeout = (15 * 1000 / per_loop); - int i; - - /* - * Wait for the EDMA engine to finish transactions in progress. - * No idea what a good "timeout" value might be, but measurements - * indicate that it often requires hundreds of microseconds - * with two drives in-use. So we use the 15msec value above - * as a rough guess at what even more drives might require. - */ - for (i = 0; i < timeout; ++i) { - u32 edma_stat = readl(port_mmio + EDMA_STATUS_OFS); - if ((edma_stat & empty_idle) == empty_idle) - break; - udelay(per_loop); - } - /* ata_port_printk(ap, KERN_INFO, "%s: %u+ usecs\n", __func__, i); */ -} - /** * mv_stop_edma_engine - Disable eDMA engine * @port_mmio: io base address @@ -950,7 +907,6 @@ static int mv_stop_edma(struct ata_port *ap) if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) return 0; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; - mv_wait_for_edma_empty_idle(ap); if (mv_stop_edma_engine(port_mmio)) { ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); return -EIO; @@ -1101,95 +1057,26 @@ static void mv6_dev_config(struct ata_device *adev) } } -static int mv_qc_defer(struct ata_queued_cmd *qc) +static void mv_config_fbs(void __iomem *port_mmio, int enable_fbs) { - struct ata_link *link = qc->dev->link; - struct ata_port *ap = link->ap; - struct mv_port_priv *pp = ap->private_data; - - /* - * Don't allow new commands if we're in a delayed EH state - * for NCQ and/or FIS-based switching. - */ - if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) - return ATA_DEFER_PORT; + u32 old_fcfg, new_fcfg, old_ltmode, new_ltmode; /* - * If the port is completely idle, then allow the new qc. + * Various bit settings required for operation + * in FIS-based switching (fbs) mode on GenIIe: */ - if (ap->nr_active_links == 0) - return 0; - - if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { - /* - * The port is operating in host queuing mode (EDMA). - * It can accomodate a new qc if the qc protocol - * is compatible with the current host queue mode. - */ - if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) { - /* - * The host queue (EDMA) is in NCQ mode. - * If the new qc is also an NCQ command, - * then allow the new qc. - */ - if (qc->tf.protocol == ATA_PROT_NCQ) - return 0; - } else { - /* - * The host queue (EDMA) is in non-NCQ, DMA mode. - * If the new qc is also a non-NCQ, DMA command, - * then allow the new qc. - */ - if (qc->tf.protocol == ATA_PROT_DMA) - return 0; - } - } - return ATA_DEFER_PORT; -} - -static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs) -{ - u32 new_fiscfg, old_fiscfg; - u32 new_ltmode, old_ltmode; - u32 new_haltcond, old_haltcond; - - old_fiscfg = readl(port_mmio + FISCFG_OFS); - old_ltmode = readl(port_mmio + LTMODE_OFS); - old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS); - - new_fiscfg = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR); - new_ltmode = old_ltmode & ~LTMODE_BIT8; - new_haltcond = old_haltcond | EDMA_ERR_DEV; - - if (want_fbs) { - new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC; - new_ltmode = old_ltmode | LTMODE_BIT8; - if (want_ncq) - new_haltcond &= ~EDMA_ERR_DEV; - else - new_fiscfg |= FISCFG_WAIT_DEV_ERR; - } - - if (new_fiscfg != old_fiscfg) - writelfl(new_fiscfg, port_mmio + FISCFG_OFS); + old_fcfg = readl(port_mmio + FIS_CFG_OFS); + old_ltmode = readl(port_mmio + LTMODE_OFS); + if (enable_fbs) { + new_fcfg = old_fcfg | FIS_CFG_SINGLE_SYNC; + new_ltmode = old_ltmode | LTMODE_BIT8; + } else { /* disable fbs */ + new_fcfg = old_fcfg & ~FIS_CFG_SINGLE_SYNC; + new_ltmode = old_ltmode & ~LTMODE_BIT8; + } + if (new_fcfg != old_fcfg) + writelfl(new_fcfg, port_mmio + FIS_CFG_OFS); if (new_ltmode != old_ltmode) writelfl(new_ltmode, port_mmio + LTMODE_OFS); - if (new_haltcond != old_haltcond) - writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS); -} - -static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq) -{ - struct mv_host_priv *hpriv = ap->host->private_data; - u32 old, new; - - /* workaround for 88SX60x1 FEr SATA#25 (part 1) */ - old = readl(hpriv->base + MV_GPIO_PORT_CTL_OFS); - if (want_ncq) - new = old | (1 << 22); - else - new = old & ~(1 << 22); - if (new != old) - writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS); } static void mv_edma_cfg(struct ata_port *ap, int want_ncq) @@ -1201,40 +1088,25 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq) /* set up non-NCQ EDMA configuration */ cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */ - pp->pp_flags &= ~MV_PP_FLAG_FBS_EN; if (IS_GEN_I(hpriv)) cfg |= (1 << 8); /* enab config burst size mask */ - else if (IS_GEN_II(hpriv)) { + else if (IS_GEN_II(hpriv)) cfg |= EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN; - mv_60x1_errata_sata25(ap, want_ncq); - } else if (IS_GEN_IIE(hpriv)) { - int want_fbs = sata_pmp_attached(ap); - /* - * Possible future enhancement: - * - * The chip can use FBS with non-NCQ, if we allow it, - * But first we need to have the error handling in place - * for this mode (datasheet section 7.3.15.4.2.3). - * So disallow non-NCQ FBS for now. - */ - want_fbs &= want_ncq; - - mv_config_fbs(port_mmio, want_ncq, want_fbs); + else if (IS_GEN_IIE(hpriv)) { + cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ + cfg |= (1 << 22); /* enab 4-entry host queue cache */ + cfg |= (1 << 18); /* enab early completion */ + cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */ - if (want_fbs) { - pp->pp_flags |= MV_PP_FLAG_FBS_EN; + if (want_ncq && sata_pmp_attached(ap)) { cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */ + mv_config_fbs(port_mmio, 1); + } else { + mv_config_fbs(port_mmio, 0); } - - cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */ - cfg |= (1 << 22); /* enab 4-entry host queue cache */ - if (HAS_PCI(ap->host)) - cfg |= (1 << 18); /* enab early completion */ - if (hpriv->hp_flags & MV_HP_CUT_THROUGH) - cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */ } if (want_ncq) { @@ -1611,186 +1483,25 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap) return qc; } -static void mv_pmp_error_handler(struct ata_port *ap) -{ - unsigned int pmp, pmp_map; - struct mv_port_priv *pp = ap->private_data; - - if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) { - /* - * Perform NCQ error analysis on failed PMPs - * before we freeze the port entirely. - * - * The failed PMPs are marked earlier by mv_pmp_eh_prep(). - */ - pmp_map = pp->delayed_eh_pmp_map; - pp->pp_flags &= ~MV_PP_FLAG_DELAYED_EH; - for (pmp = 0; pmp_map != 0; pmp++) { - unsigned int this_pmp = (1 << pmp); - if (pmp_map & this_pmp) { - struct ata_link *link = &ap->pmp_link[pmp]; - pmp_map &= ~this_pmp; - ata_eh_analyze_ncq_error(link); - } - } - ata_port_freeze(ap); - } - sata_pmp_error_handler(ap); -} - -static unsigned int mv_get_err_pmp_map(struct ata_port *ap) -{ - void __iomem *port_mmio = mv_ap_base(ap); - - return readl(port_mmio + SATA_TESTCTL_OFS) >> 16; -} - -static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map) -{ - struct ata_eh_info *ehi; - unsigned int pmp; - - /* - * Initialize EH info for PMPs which saw device errors - */ - ehi = &ap->link.eh_info; - for (pmp = 0; pmp_map != 0; pmp++) { - unsigned int this_pmp = (1 << pmp); - if (pmp_map & this_pmp) { - struct ata_link *link = &ap->pmp_link[pmp]; - - pmp_map &= ~this_pmp; - ehi = &link->eh_info; - ata_ehi_clear_desc(ehi); - ata_ehi_push_desc(ehi, "dev err"); - ehi->err_mask |= AC_ERR_DEV; - ehi->action |= ATA_EH_RESET; - ata_link_abort(link); - } - } -} - -static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) +static void mv_unexpected_intr(struct ata_port *ap) { struct mv_port_priv *pp = ap->private_data; - int failed_links; - unsigned int old_map, new_map; - - /* - * Device error during FBS+NCQ operation: - * - * Set a port flag to prevent further I/O being enqueued. - * Leave the EDMA running to drain outstanding commands from this port. - * Perform the post-mortem/EH only when all responses are complete. - * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.2). - */ - if (!(pp->pp_flags & MV_PP_FLAG_DELAYED_EH)) { - pp->pp_flags |= MV_PP_FLAG_DELAYED_EH; - pp->delayed_eh_pmp_map = 0; - } - old_map = pp->delayed_eh_pmp_map; - new_map = old_map | mv_get_err_pmp_map(ap); - - if (old_map != new_map) { - pp->delayed_eh_pmp_map = new_map; - mv_pmp_eh_prep(ap, new_map & ~old_map); - } - failed_links = hweight16(new_map); - - ata_port_printk(ap, KERN_INFO, "%s: pmp_map=%04x qc_map=%04x " - "failed_links=%d nr_active_links=%d\n", - __func__, pp->delayed_eh_pmp_map, - ap->qc_active, failed_links, - ap->nr_active_links); - - if (ap->nr_active_links <= failed_links) { - mv_process_crpb_entries(ap, pp); - mv_stop_edma(ap); - mv_eh_freeze(ap); - ata_port_printk(ap, KERN_INFO, "%s: done\n", __func__); - return 1; /* handled */ - } - ata_port_printk(ap, KERN_INFO, "%s: waiting\n", __func__); - return 1; /* handled */ -} + struct ata_eh_info *ehi = &ap->link.eh_info; + char *when = ""; -static int mv_handle_fbs_non_ncq_dev_err(struct ata_port *ap) -{ /* - * Possible future enhancement: - * - * FBS+non-NCQ operation is not yet implemented. - * See related notes in mv_edma_cfg(). - * - * Device error during FBS+non-NCQ operation: - * - * We need to snapshot the shadow registers for each failed command. - * Follow recovery sequence from 6042/7042 datasheet (7.3.15.4.2.3). + * We got a device interrupt from something that + * was supposed to be using EDMA or polling. */ - return 0; /* not handled */ -} - -static int mv_handle_dev_err(struct ata_port *ap, u32 edma_err_cause) -{ - struct mv_port_priv *pp = ap->private_data; - - if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) - return 0; /* EDMA was not active: not handled */ - if (!(pp->pp_flags & MV_PP_FLAG_FBS_EN)) - return 0; /* FBS was not active: not handled */ - - if (!(edma_err_cause & EDMA_ERR_DEV)) - return 0; /* non DEV error: not handled */ - edma_err_cause &= ~EDMA_ERR_IRQ_TRANSIENT; - if (edma_err_cause & ~(EDMA_ERR_DEV | EDMA_ERR_SELF_DIS)) - return 0; /* other problems: not handled */ - - if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) { - /* - * EDMA should NOT have self-disabled for this case. - * If it did, then something is wrong elsewhere, - * and we cannot handle it here. - */ - if (edma_err_cause & EDMA_ERR_SELF_DIS) { - ata_port_printk(ap, KERN_WARNING, - "%s: err_cause=0x%x pp_flags=0x%x\n", - __func__, edma_err_cause, pp->pp_flags); - return 0; /* not handled */ - } - return mv_handle_fbs_ncq_dev_err(ap); - } else { - /* - * EDMA should have self-disabled for this case. - * If it did not, then something is wrong elsewhere, - * and we cannot handle it here. - */ - if (!(edma_err_cause & EDMA_ERR_SELF_DIS)) { - ata_port_printk(ap, KERN_WARNING, - "%s: err_cause=0x%x pp_flags=0x%x\n", - __func__, edma_err_cause, pp->pp_flags); - return 0; /* not handled */ - } - return mv_handle_fbs_non_ncq_dev_err(ap); - } - return 0; /* not handled */ -} - -static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled) -{ - struct ata_eh_info *ehi = &ap->link.eh_info; - char *when = "idle"; - ata_ehi_clear_desc(ehi); - if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { - when = "disabled"; - } else if (edma_was_enabled) { - when = "EDMA enabled"; + if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { + when = " while EDMA enabled"; } else { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); if (qc && (qc->tf.flags & ATA_TFLAG_POLLING)) - when = "polling"; + when = " while polling"; } - ata_ehi_push_desc(ehi, "unexpected device interrupt while %s", when); + ata_ehi_push_desc(ehi, "unexpected device interrupt%s", when); ehi->err_mask |= AC_ERR_OTHER; ehi->action |= ATA_EH_RESET; ata_port_freeze(ap); @@ -1808,7 +1519,7 @@ static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled) * LOCKING: * Inherited from caller. */ -static void mv_err_intr(struct ata_port *ap) +static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) { void __iomem *port_mmio = mv_ap_base(ap); u32 edma_err_cause, eh_freeze_mask, serr = 0; @@ -1816,42 +1527,24 @@ static void mv_err_intr(struct ata_port *ap) struct mv_host_priv *hpriv = ap->host->private_data; unsigned int action = 0, err_mask = 0; struct ata_eh_info *ehi = &ap->link.eh_info; - struct ata_queued_cmd *qc; - int abort = 0; + + ata_ehi_clear_desc(ehi); /* - * Read and clear the SError and err_cause bits. + * Read and clear the err_cause bits. This won't actually + * clear for some errors (eg. SError), but we will be doing + * a hard reset in those cases regardless, which *will* clear it. */ - sata_scr_read(&ap->link, SCR_ERROR, &serr); - sata_scr_write_flush(&ap->link, SCR_ERROR, serr); - edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); - ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n", - __func__, edma_err_cause, pp->pp_flags); - - if (edma_err_cause & EDMA_ERR_DEV) { - /* - * Device errors during FIS-based switching operation - * require special handling. - */ - if (mv_handle_dev_err(ap, edma_err_cause)) - return; - } + ata_ehi_push_desc(ehi, "edma_err_cause=%08x", edma_err_cause); - qc = mv_get_active_qc(ap); - ata_ehi_clear_desc(ehi); - ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", - edma_err_cause, pp->pp_flags); /* * All generations share these EDMA error cause bits: */ - if (edma_err_cause & EDMA_ERR_DEV) { + if (edma_err_cause & EDMA_ERR_DEV) err_mask |= AC_ERR_DEV; - action |= ATA_EH_RESET; - ata_ehi_push_desc(ehi, "dev error"); - } if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR)) { @@ -1883,6 +1576,13 @@ static void mv_err_intr(struct ata_port *ap) ata_ehi_push_desc(ehi, "EDMA self-disable"); } if (edma_err_cause & EDMA_ERR_SERR) { + /* + * Ensure that we read our own SCR, not a pmp link SCR: + */ + ap->ops->scr_read(ap, SCR_ERROR, &serr); + /* + * Don't clear SError here; leave it for libata-eh: + */ ata_ehi_push_desc(ehi, "SError=%08x", serr); err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_RESET; @@ -1902,29 +1602,10 @@ static void mv_err_intr(struct ata_port *ap) else ehi->err_mask |= err_mask; - if (err_mask == AC_ERR_DEV) { - /* - * Cannot do ata_port_freeze() here, - * because it would kill PIO access, - * which is needed for further diagnosis. - */ - mv_eh_freeze(ap); - abort = 1; - } else if (edma_err_cause & eh_freeze_mask) { - /* - * Note to self: ata_port_freeze() calls ata_port_abort() - */ + if (edma_err_cause & eh_freeze_mask) ata_port_freeze(ap); - } else { - abort = 1; - } - - if (abort) { - if (qc) - ata_link_abort(qc->dev->link); - else - ata_port_abort(ap); - } + else + ata_port_abort(ap); } static void mv_process_crpb_response(struct ata_port *ap, @@ -1951,9 +1632,8 @@ static void mv_process_crpb_response(struct ata_port *ap, } } ata_status = edma_status >> CRPB_FLAG_STATUS_SHIFT; - if (!ac_err_mask(ata_status)) - ata_qc_complete(qc); - /* else: leave it for mv_err_intr() */ + qc->err_mask |= ac_err_mask(ata_status); + ata_qc_complete(qc); } else { ata_port_printk(ap, KERN_ERR, "%s: no qc for tag=%d\n", __func__, tag); @@ -1997,44 +1677,6 @@ static void mv_process_crpb_entries(struct ata_port *ap, struct mv_port_priv *pp port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); } -static void mv_port_intr(struct ata_port *ap, u32 port_cause) -{ - struct mv_port_priv *pp; - int edma_was_enabled; - - if (!ap || (ap->flags & ATA_FLAG_DISABLED)) { - mv_unexpected_intr(ap, 0); - return; - } - /* - * Grab a snapshot of the EDMA_EN flag setting, - * so that we have a consistent view for this port, - * even if something we call of our routines changes it. - */ - pp = ap->private_data; - edma_was_enabled = (pp->pp_flags & MV_PP_FLAG_EDMA_EN); - /* - * Process completed CRPB response(s) before other events. - */ - if (edma_was_enabled && (port_cause & DONE_IRQ)) { - mv_process_crpb_entries(ap, pp); - if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) - mv_handle_fbs_ncq_dev_err(ap); - } - /* - * Handle chip-reported errors, or continue on to handle PIO. - */ - if (unlikely(port_cause & ERR_IRQ)) { - mv_err_intr(ap); - } else if (!edma_was_enabled) { - struct ata_queued_cmd *qc = mv_get_active_qc(ap); - if (qc) - ata_sff_host_intr(ap, qc); - else - mv_unexpected_intr(ap, edma_was_enabled); - } -} - /** * mv_host_intr - Handle all interrupts on the given host controller * @host: host specific structure @@ -2046,58 +1688,66 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) static int mv_host_intr(struct ata_host *host, u32 main_irq_cause) { struct mv_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->base, *hc_mmio; + void __iomem *mmio = hpriv->base, *hc_mmio = NULL; + u32 hc_irq_cause = 0; unsigned int handled = 0, port; for (port = 0; port < hpriv->n_ports; port++) { struct ata_port *ap = host->ports[port]; - unsigned int p, shift, hardport, port_cause; - + struct mv_port_priv *pp; + unsigned int shift, hardport, port_cause; + /* + * When we move to the second hc, flag our cached + * copies of hc_mmio (and hc_irq_cause) as invalid again. + */ + if (port == MV_PORTS_PER_HC) + hc_mmio = NULL; + /* + * Do nothing if port is not interrupting or is disabled: + */ MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); + port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ); + if (!port_cause || !ap || (ap->flags & ATA_FLAG_DISABLED)) + continue; /* - * Each hc within the host has its own hc_irq_cause register, - * where the interrupting ports bits get ack'd. + * Each hc within the host has its own hc_irq_cause register. + * We defer reading it until we know we need it, right now: + * + * FIXME later: we don't really need to read this register + * (some logic changes required below if we go that way), + * because it doesn't tell us anything new. But we do need + * to write to it, outside the top of this loop, + * to reset the interrupt triggers for next time. */ - if (hardport == 0) { /* first port on this hc ? */ - u32 hc_cause = (main_irq_cause >> shift) & HC0_IRQ_PEND; - u32 port_mask, ack_irqs; - /* - * Skip this entire hc if nothing pending for any ports - */ - if (!hc_cause) { - port += MV_PORTS_PER_HC - 1; - continue; - } - /* - * We don't need/want to read the hc_irq_cause register, - * because doing so hurts performance, and - * main_irq_cause already gives us everything we need. - * - * But we do have to *write* to the hc_irq_cause to ack - * the ports that we are handling this time through. - * - * This requires that we create a bitmap for those - * ports which interrupted us, and use that bitmap - * to ack (only) those ports via hc_irq_cause. - */ - ack_irqs = 0; - for (p = 0; p < MV_PORTS_PER_HC; ++p) { - if ((port + p) >= hpriv->n_ports) - break; - port_mask = (DONE_IRQ | ERR_IRQ) << (p * 2); - if (hc_cause & port_mask) - ack_irqs |= (DMA_IRQ | DEV_IRQ) << p; - } + if (!hc_mmio) { hc_mmio = mv_hc_base_from_port(mmio, port); - writelfl(~ack_irqs, hc_mmio + HC_IRQ_CAUSE_OFS); + hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); + writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); handled = 1; } /* - * Handle interrupts signalled for this port: + * Process completed CRPB response(s) before other events. */ - port_cause = (main_irq_cause >> shift) & (DONE_IRQ | ERR_IRQ); - if (port_cause) - mv_port_intr(ap, port_cause); + pp = ap->private_data; + if (hc_irq_cause & (DMA_IRQ << hardport)) { + if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) + mv_process_crpb_entries(ap, pp); + } + /* + * Handle chip-reported errors, or continue on to handle PIO. + */ + if (unlikely(port_cause & ERR_IRQ)) { + mv_err_intr(ap, mv_get_active_qc(ap)); + } else if (hc_irq_cause & (DEV_IRQ << hardport)) { + if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { + struct ata_queued_cmd *qc = mv_get_active_qc(ap); + if (qc) { + ata_sff_host_intr(ap, qc); + continue; + } + } + mv_unexpected_intr(ap); + } } return handled; } @@ -2244,7 +1894,7 @@ static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio) static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) { - writel(0x0fcfffff, mmio + MV_FLASH_CTL_OFS); + writel(0x0fcfffff, mmio + MV_FLASH_CTL); } static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, @@ -2263,7 +1913,7 @@ static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) { u32 tmp; - writel(0, mmio + MV_GPIO_PORT_CTL_OFS); + writel(0, mmio + MV_GPIO_PORT_CTL); /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */ @@ -2281,14 +1931,14 @@ static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0); if (fix_apm_sq) { - tmp = readl(phy_mmio + MV5_LTMODE_OFS); + tmp = readl(phy_mmio + MV5_LT_MODE); tmp |= (1 << 19); - writel(tmp, phy_mmio + MV5_LTMODE_OFS); + writel(tmp, phy_mmio + MV5_LT_MODE); - tmp = readl(phy_mmio + MV5_PHY_CTL_OFS); + tmp = readl(phy_mmio + MV5_PHY_CTL); tmp &= ~0x3; tmp |= 0x1; - writel(tmp, phy_mmio + MV5_PHY_CTL_OFS); + writel(tmp, phy_mmio + MV5_PHY_CTL); } tmp = readl(phy_mmio + MV5_PHY_MODE); @@ -2306,6 +1956,11 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, { void __iomem *port_mmio = mv_port_base(mmio, port); + /* + * The datasheet warns against setting ATA_RST when EDMA is active + * (but doesn't say what the problem might be). So we first try + * to disable the EDMA engine before doing the ATA_RST operation. + */ mv_reset_channel(hpriv, mmio, port); ZERO(0x028); /* command */ @@ -2320,7 +1975,7 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, ZERO(0x024); /* respq outp */ ZERO(0x020); /* respq inp */ ZERO(0x02c); /* test control */ - writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS); + writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); } #undef ZERO @@ -2366,13 +2021,13 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio) struct mv_host_priv *hpriv = host->private_data; u32 tmp; - tmp = readl(mmio + MV_PCI_MODE_OFS); + tmp = readl(mmio + MV_PCI_MODE); tmp &= 0xff00ffff; - writel(tmp, mmio + MV_PCI_MODE_OFS); + writel(tmp, mmio + MV_PCI_MODE); ZERO(MV_PCI_DISC_TIMER); ZERO(MV_PCI_MSI_TRIGGER); - writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); + writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT); ZERO(PCI_HC_MAIN_IRQ_MASK_OFS); ZERO(MV_PCI_SERR_MASK); ZERO(hpriv->irq_cause_ofs); @@ -2390,10 +2045,10 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) mv5_reset_flash(hpriv, mmio); - tmp = readl(mmio + MV_GPIO_PORT_CTL_OFS); + tmp = readl(mmio + MV_GPIO_PORT_CTL); tmp &= 0x3; tmp |= (1 << 5) | (1 << 6); - writel(tmp, mmio + MV_GPIO_PORT_CTL_OFS); + writel(tmp, mmio + MV_GPIO_PORT_CTL); } /** @@ -2466,7 +2121,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *port_mmio; u32 tmp; - tmp = readl(mmio + MV_RESET_CFG_OFS); + tmp = readl(mmio + MV_RESET_CFG); if ((tmp & (1 << 0)) == 0) { hpriv->signal[idx].amps = 0x7 << 8; hpriv->signal[idx].pre = 0x1 << 5; @@ -2482,7 +2137,7 @@ static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) { - writel(0x00000060, mmio + MV_GPIO_PORT_CTL_OFS); + writel(0x00000060, mmio + MV_GPIO_PORT_CTL); } static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, @@ -2580,6 +2235,11 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, { void __iomem *port_mmio = mv_port_base(mmio, port); + /* + * The datasheet warns against setting ATA_RST when EDMA is active + * (but doesn't say what the problem might be). So we first try + * to disable the EDMA engine before doing the ATA_RST operation. + */ mv_reset_channel(hpriv, mmio, port); ZERO(0x028); /* command */ @@ -2594,7 +2254,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, ZERO(0x024); /* respq outp */ ZERO(0x020); /* respq inp */ ZERO(0x02c); /* test control */ - writel(0xbc, port_mmio + EDMA_IORDY_TMOUT_OFS); + writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); } #undef ZERO @@ -2637,39 +2297,38 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio) return; } -static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i) +static void mv_setup_ifctl(void __iomem *port_mmio, int want_gen2i) { - u32 ifcfg = readl(port_mmio + SATA_INTERFACE_CFG_OFS); + u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG); - ifcfg = (ifcfg & 0xf7f) | 0x9b1000; /* from chip spec */ + ifctl = (ifctl & 0xf7f) | 0x9b1000; /* from chip spec */ if (want_gen2i) - ifcfg |= (1 << 7); /* enable gen2i speed */ - writelfl(ifcfg, port_mmio + SATA_INTERFACE_CFG_OFS); + ifctl |= (1 << 7); /* enable gen2i speed */ + writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG); } +/* + * Caller must ensure that EDMA is not active, + * by first doing mv_stop_edma() where needed. + */ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int port_no) { void __iomem *port_mmio = mv_port_base(mmio, port_no); - /* - * The datasheet warns against setting EDMA_RESET when EDMA is active - * (but doesn't say what the problem might be). So we first try - * to disable the EDMA engine before doing the EDMA_RESET operation. - */ mv_stop_edma_engine(port_mmio); - writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS); + writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); if (!IS_GEN_I(hpriv)) { - /* Enable 3.0gb/s link speed: this survives EDMA_RESET */ - mv_setup_ifcfg(port_mmio, 1); + /* Enable 3.0gb/s link speed */ + mv_setup_ifctl(port_mmio, 1); } /* - * Strobing EDMA_RESET here causes a hard reset of the SATA transport, + * Strobing ATA_RST here causes a hard reset of the SATA transport, * link, and physical layers. It resets all SATA interface registers * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev. */ - writelfl(EDMA_RESET, port_mmio + EDMA_CMD_OFS); + writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); udelay(25); /* allow reset propagation */ writelfl(0, port_mmio + EDMA_CMD_OFS); @@ -2733,7 +2392,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, sata_scr_read(link, SCR_STATUS, &sstatus); if (!IS_GEN_I(hpriv) && ++attempts >= 5 && sstatus == 0x121) { /* Force 1.5gb/s link speed and try again */ - mv_setup_ifcfg(mv_ap_base(ap), 0); + mv_setup_ifctl(mv_ap_base(ap), 0); if (time_after(jiffies + HZ, deadline)) extra = HZ; /* only extend it once, max */ } @@ -2834,34 +2493,6 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); } -static unsigned int mv_in_pcix_mode(struct ata_host *host) -{ - struct mv_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->base; - u32 reg; - - if (!HAS_PCI(host) || !IS_PCIE(hpriv)) - return 0; /* not PCI-X capable */ - reg = readl(mmio + MV_PCI_MODE_OFS); - if ((reg & MV_PCI_MODE_MASK) == 0) - return 0; /* conventional PCI mode */ - return 1; /* chip is in PCI-X mode */ -} - -static int mv_pci_cut_through_okay(struct ata_host *host) -{ - struct mv_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->base; - u32 reg; - - if (!mv_in_pcix_mode(host)) { - reg = readl(mmio + PCI_COMMAND_OFS); - if (reg & PCI_COMMAND_MRDTRIG) - return 0; /* not okay */ - } - return 1; /* okay */ -} - static int mv_chip_id(struct ata_host *host, unsigned int board_idx) { struct pci_dev *pdev = to_pci_dev(host->dev); @@ -2929,7 +2560,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) break; case chip_7042: - hp_flags |= MV_HP_PCIE | MV_HP_CUT_THROUGH; + hp_flags |= MV_HP_PCIE; if (pdev->vendor == PCI_VENDOR_ID_TTI && (pdev->device == 0x2300 || pdev->device == 0x2310)) { @@ -2959,12 +2590,9 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) " and avoid the final two gigabytes on" " all RocketRAID BIOS initialized drives.\n"); } - /* drop through */ case chip_6042: hpriv->ops = &mv6xxx_ops; hp_flags |= MV_HP_GEN_IIE; - if (board_idx == chip_6042 && mv_pci_cut_through_okay(host)) - hp_flags |= MV_HP_CUT_THROUGH; switch (pdev->revision) { case 0x0: 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/base/sys.c b/trunk/drivers/base/sys.c index 358bb0be3c08..4fbb56bcb1ee 100644 --- a/trunk/drivers/base/sys.c +++ b/trunk/drivers/base/sys.c @@ -175,7 +175,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) } /* Check whether this driver has already been added to a class. */ - if (drv->entry.next && !list_empty(&drv->entry)) { + if ((drv->entry.next != drv->entry.prev) || + (drv->entry.next != NULL)) { printk(KERN_WARNING "sysdev: class %s: driver (%p) has already" " been registered to a class, something is wrong, but " "will forge on!\n", cls->name, drv); diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 41f818be2f7e..8fc429cf82b6 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -755,13 +755,11 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector { unsigned long n_sect = bio->bi_size >> 9; const int rw = bio_data_dir(bio); - struct hd_struct *part; - part = get_part(disk, sector); - all_stat_inc(disk, part, ios[rw], sector); - all_stat_add(disk, part, ticks[rw], duration, sector); - all_stat_add(disk, part, sectors[rw], n_sect, sector); - all_stat_add(disk, part, io_ticks, duration, sector); + all_stat_inc(disk, ios[rw], sector); + all_stat_add(disk, ticks[rw], duration, sector); + all_stat_add(disk, sectors[rw], n_sect, sector); + all_stat_add(disk, io_ticks, duration, sector); } void 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/serial167.c b/trunk/drivers/char/serial167.c index 3b23270eaa65..fd2db07a50fc 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -1073,7 +1073,7 @@ static int cy_put_char(struct tty_struct *tty, unsigned char ch) return 0; if (!info->xmit_buf) - return 0; + return; local_irq_save(flags); if (info->xmit_cnt >= PAGE_SIZE - 1) { diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index b1a7a8cb65ea..f39f6fd89350 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -970,8 +970,7 @@ static int sx_set_real_termios(void *ptr) sx_write_channel_byte(port, hi_mask, 0x1f); break; default: - printk(KERN_INFO "sx: Invalid wordsize: %u\n", - (unsigned int)CFLAG & CSIZE); + printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE); break; } @@ -998,8 +997,7 @@ static int sx_set_real_termios(void *ptr) set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); } sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", - (unsigned int)port->gs.tty->termios->c_iflag, - I_OTHER(port->gs.tty)); + port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty)); /* Tell line discipline whether we will do output cooking. * If OPOST is set and no other output flags are set then we can do output @@ -1012,8 +1010,7 @@ static int sx_set_real_termios(void *ptr) clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); } sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", - (unsigned int)port->gs.tty->termios->c_oflag, - O_OTHER(port->gs.tty)); + port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty)); /* port->c_dcd = sx_get_CD (port); */ func_exit(); return 0; 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/char/tty_audit.c b/trunk/drivers/char/tty_audit.c index 3582f43345a8..6342b0534f4d 100644 --- a/trunk/drivers/char/tty_audit.c +++ b/trunk/drivers/char/tty_audit.c @@ -11,7 +11,6 @@ #include #include -#include #include struct tty_audit_buf { diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 49c1a2267a55..1d298c2cf930 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -78,7 +78,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index fa1ffbf2c621..e458b08139af 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -2742,10 +2742,6 @@ static int con_open(struct tty_struct *tty, struct file *filp) tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; } - if (vc->vc_utf) - tty->termios->c_iflag |= IUTF8; - else - tty->termios->c_iflag &= ~IUTF8; release_console_sem(); vcs_make_sysfs(tty); return ret; @@ -2922,8 +2918,6 @@ int __init vty_init(void) console_driver->minor_start = 1; console_driver->type = TTY_DRIVER_TYPE_CONSOLE; console_driver->init_termios = tty_std_termios; - if (default_utf8) - console_driver->init_termios.c_iflag |= IUTF8; console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; tty_set_operations(console_driver, &con_ops); if (tty_register_driver(console_driver)) diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 3edf1fc12963..dfe6907ae15b 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -623,8 +623,8 @@ static int __devinit hwicap_setup(struct device *dev, int id, if (!request_mem_region(drvdata->mem_start, drvdata->mem_size, DRIVER_NAME)) { - dev_err(dev, "Couldn't lock memory region at %Lx\n", - regs_res->start); + dev_err(dev, "Couldn't lock memory region at %p\n", + (void *)regs_res->start); retval = -EBUSY; goto failed1; } @@ -643,7 +643,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, mutex_init(&drvdata->sem); drvdata->is_open = 0; - dev_info(dev, "ioremap %lx to %p with size %Lx\n", + dev_info(dev, "ioremap %lx to %p with size %x\n", (unsigned long int)drvdata->mem_start, drvdata->base_address, drvdata->mem_size); diff --git a/trunk/drivers/edac/edac_core.h b/trunk/drivers/edac/edac_core.h index b27b13c5eb5a..a9aa845dbe74 100644 --- a/trunk/drivers/edac/edac_core.h +++ b/trunk/drivers/edac/edac_core.h @@ -97,7 +97,7 @@ extern int edac_debug_level; #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ PCI_DEVICE_ID_ ## vend ## _ ## dev -#define edac_dev_name(dev) (dev)->dev_name +#define dev_name(dev) (dev)->dev_name /* memory devices */ enum dev_type { diff --git a/trunk/drivers/edac/edac_device.c b/trunk/drivers/edac/edac_device.c index 5fcd3d89c75d..63372fa7ecfe 100644 --- a/trunk/drivers/edac/edac_device.c +++ b/trunk/drivers/edac/edac_device.c @@ -333,7 +333,7 @@ static int add_edac_dev_to_global_list(struct edac_device_ctl_info *edac_dev) fail0: edac_printk(KERN_WARNING, EDAC_MC, "%s (%s) %s %s already assigned %d\n", - rover->dev->bus_id, edac_dev_name(rover), + rover->dev->bus_id, dev_name(rover), rover->mod_name, rover->ctl_name, rover->dev_idx); return 1; @@ -538,7 +538,7 @@ int edac_device_add_device(struct edac_device_ctl_info *edac_dev) "'%s': DEV '%s' (%s)\n", edac_dev->mod_name, edac_dev->ctl_name, - edac_dev_name(edac_dev), + dev_name(edac_dev), edac_op_state_to_string(edac_dev->op_state)); mutex_unlock(&device_ctls_mutex); @@ -599,7 +599,7 @@ struct edac_device_ctl_info *edac_device_del_device(struct device *dev) edac_printk(KERN_INFO, EDAC_MC, "Removed device %d for %s %s: DEV %s\n", edac_dev->dev_idx, - edac_dev->mod_name, edac_dev->ctl_name, edac_dev_name(edac_dev)); + edac_dev->mod_name, edac_dev->ctl_name, dev_name(edac_dev)); return edac_dev; } diff --git a/trunk/drivers/edac/edac_mc.c b/trunk/drivers/edac/edac_mc.c index d110392d48f4..a4cf1645f588 100644 --- a/trunk/drivers/edac/edac_mc.c +++ b/trunk/drivers/edac/edac_mc.c @@ -402,7 +402,7 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci) fail0: edac_printk(KERN_WARNING, EDAC_MC, "%s (%s) %s %s already assigned %d\n", p->dev->bus_id, - edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx); + dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx); return 1; fail1: @@ -517,7 +517,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) /* Report action taken */ edac_mc_printk(mci, KERN_INFO, "Giving out device to '%s' '%s':" - " DEV %s\n", mci->mod_name, mci->ctl_name, edac_dev_name(mci)); + " DEV %s\n", mci->mod_name, mci->ctl_name, dev_name(mci)); mutex_unlock(&mem_ctls_mutex); return 0; @@ -565,7 +565,7 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) edac_printk(KERN_INFO, EDAC_MC, "Removed device %d for %s %s: DEV %s\n", mci->mc_idx, - mci->mod_name, mci->ctl_name, edac_dev_name(mci)); + mci->mod_name, mci->ctl_name, dev_name(mci)); return mci; } diff --git a/trunk/drivers/edac/edac_pci.c b/trunk/drivers/edac/edac_pci.c index 22ec9d5d4312..9b24340b52e1 100644 --- a/trunk/drivers/edac/edac_pci.c +++ b/trunk/drivers/edac/edac_pci.c @@ -150,7 +150,7 @@ static int add_edac_pci_to_global_list(struct edac_pci_ctl_info *pci) fail0: edac_printk(KERN_WARNING, EDAC_PCI, "%s (%s) %s %s already assigned %d\n", - rover->dev->bus_id, edac_dev_name(rover), + rover->dev->bus_id, dev_name(rover), rover->mod_name, rover->ctl_name, rover->pci_idx); return 1; @@ -360,7 +360,7 @@ int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx) " DEV '%s' (%s)\n", pci->mod_name, pci->ctl_name, - edac_dev_name(pci), edac_op_state_to_string(pci->op_state)); + dev_name(pci), edac_op_state_to_string(pci->op_state)); mutex_unlock(&edac_pci_ctls_mutex); return 0; @@ -415,7 +415,7 @@ struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev) edac_printk(KERN_INFO, EDAC_PCI, "Removed device %d for %s %s: DEV %s\n", - pci->pci_idx, pci->mod_name, pci->ctl_name, edac_dev_name(pci)); + pci->pci_idx, pci->mod_name, pci->ctl_name, dev_name(pci)); return pci; } diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index b2458bb8e9ca..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); @@ -1487,7 +1487,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) goto out; - memcpy(orb->request.command_block, cmd->cmnd, cmd->cmd_len); + memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); orb->base.callback = complete_command_orb; orb->base.request_bus = 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 34b0d4f26b58..099a0fe1745b 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1347,14 +1347,19 @@ 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 */ if (hwif->chipset != ide_dtc2278 || hwif->channel == 0) hwif->port_ops = d->port_ops; + if ((d->host_flags & IDE_HFLAG_SERIALIZE) || + ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) { + if (hwif->mate) + hwif->mate->serialized = hwif->serialized = 1; + } + hwif->swdma_mask = d->swdma_mask; hwif->mwdma_mask = d->mwdma_mask; hwif->ultra_mask = d->udma_mask; @@ -1376,12 +1381,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, hwif->dma_ops = d->dma_ops; } - if ((d->host_flags & IDE_HFLAG_SERIALIZE) || - ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) { - if (hwif->mate) - hwif->mate->serialized = hwif->serialized = 1; - } - if (d->host_flags & IDE_HFLAG_RQSIZE_256) hwif->rqsize = 256; diff --git a/trunk/drivers/ide/legacy/falconide.c b/trunk/drivers/ide/legacy/falconide.c index 9e449a0c623f..83555ca513b5 100644 --- a/trunk/drivers/ide/legacy/falconide.c +++ b/trunk/drivers/ide/legacy/falconide.c @@ -61,7 +61,7 @@ static void falconide_output_data(ide_drive_t *drive, struct request *rq, unsigned long data_addr = drive->hwif->io_ports.data_addr; if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) - return outsw(data_addr, buf, (len + 1) / 2); + return outsw(data_adr, buf, (len + 1) / 2); outsw_swapw(data_addr, buf, (len + 1) / 2); } 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/infiniband/hw/cxgb3/cxio_hal.c b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c index ebf9d3043f80..ed2ee4ba4b7c 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -359,10 +359,9 @@ static void insert_recv_cqe(struct t3_wq *wq, struct t3_cq *cq) cq->sw_wptr++; } -int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count) +void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count) { u32 ptr; - int flushed = 0; PDBG("%s wq %p cq %p\n", __func__, wq, cq); @@ -370,11 +369,8 @@ int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count) PDBG("%s rq_rptr %u rq_wptr %u skip count %u\n", __func__, wq->rq_rptr, wq->rq_wptr, count); ptr = wq->rq_rptr + count; - while (ptr++ != wq->rq_wptr) { + while (ptr++ != wq->rq_wptr) insert_recv_cqe(wq, cq); - flushed++; - } - return flushed; } static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq, @@ -398,10 +394,9 @@ static void insert_sq_cqe(struct t3_wq *wq, struct t3_cq *cq, cq->sw_wptr++; } -int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) +void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) { __u32 ptr; - int flushed = 0; struct t3_swsq *sqp = wq->sq + Q_PTR2IDX(wq->sq_rptr, wq->sq_size_log2); ptr = wq->sq_rptr + count; @@ -410,9 +405,7 @@ int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count) insert_sq_cqe(wq, cq, sqp); sqp++; ptr++; - flushed++; } - return flushed; } /* @@ -588,7 +581,7 @@ static int cxio_hal_destroy_ctrl_qp(struct cxio_rdev *rdev_p) * caller aquires the ctrl_qp lock before the call */ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, - u32 len, void *data) + u32 len, void *data, int completion) { u32 i, nr_wqe, copy_len; u8 *copy_data; @@ -624,7 +617,7 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, flag = 0; if (i == (nr_wqe - 1)) { /* last WQE */ - flag = T3_COMPLETION_FLAG; + flag = completion ? T3_COMPLETION_FLAG : 0; if (len % 32) utx_len = len / 32 + 1; else @@ -683,20 +676,21 @@ static int cxio_hal_ctrl_qp_write_mem(struct cxio_rdev *rdev_p, u32 addr, return 0; } -/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl_size and pbl_addr - * OUT: stag index +/* IN: stag key, pdid, perm, zbva, to, len, page_size, pbl, and pbl_size + * OUT: stag index, actual pbl_size, pbl_addr allocated. * TBD: shared memory region support */ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, u32 *stag, u8 stag_state, u32 pdid, enum tpt_mem_type type, enum tpt_mem_perm perm, - u32 zbva, u64 to, u32 len, u8 page_size, - u32 pbl_size, u32 pbl_addr) + u32 zbva, u64 to, u32 len, u8 page_size, __be64 *pbl, + u32 *pbl_size, u32 *pbl_addr) { int err; struct tpt_entry tpt; u32 stag_idx; u32 wptr; + int rereg = (*stag != T3_STAG_UNSET); stag_state = stag_state > 0; stag_idx = (*stag) >> 8; @@ -710,8 +704,30 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n", __func__, stag_state, type, pdid, stag_idx); + if (reset_tpt_entry) + cxio_hal_pblpool_free(rdev_p, *pbl_addr, *pbl_size << 3); + else if (!rereg) { + *pbl_addr = cxio_hal_pblpool_alloc(rdev_p, *pbl_size << 3); + if (!*pbl_addr) { + return -ENOMEM; + } + } + mutex_lock(&rdev_p->ctrl_qp.lock); + /* write PBL first if any - update pbl only if pbl list exist */ + if (pbl) { + + PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n", + __func__, *pbl_addr, rdev_p->rnic_info.pbl_base, + *pbl_size); + err = cxio_hal_ctrl_qp_write_mem(rdev_p, + (*pbl_addr >> 5), + (*pbl_size << 3), pbl, 0); + if (err) + goto ret; + } + /* write TPT entry */ if (reset_tpt_entry) memset(&tpt, 0, sizeof(tpt)); @@ -726,23 +742,23 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) | V_TPT_PAGE_SIZE(page_size)); tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 : - cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3)); + cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, *pbl_addr)>>3)); tpt.len = cpu_to_be32(len); tpt.va_hi = cpu_to_be32((u32) (to >> 32)); tpt.va_low_or_fbo = cpu_to_be32((u32) (to & 0xFFFFFFFFULL)); tpt.rsvd_bind_cnt_or_pstag = 0; tpt.rsvd_pbl_size = reset_tpt_entry ? 0 : - cpu_to_be32(V_TPT_PBL_SIZE(pbl_size >> 2)); + cpu_to_be32(V_TPT_PBL_SIZE((*pbl_size) >> 2)); } err = cxio_hal_ctrl_qp_write_mem(rdev_p, stag_idx + (rdev_p->rnic_info.tpt_base >> 5), - sizeof(tpt), &tpt); + sizeof(tpt), &tpt, 1); /* release the stag index to free pool */ if (reset_tpt_entry) cxio_hal_put_stag(rdev_p->rscp, stag_idx); - +ret: wptr = rdev_p->ctrl_qp.wptr; mutex_unlock(&rdev_p->ctrl_qp.lock); if (!err) @@ -753,67 +769,44 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, return err; } -int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl, - u32 pbl_addr, u32 pbl_size) -{ - u32 wptr; - int err; - - PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n", - __func__, pbl_addr, rdev_p->rnic_info.pbl_base, - pbl_size); - - mutex_lock(&rdev_p->ctrl_qp.lock); - err = cxio_hal_ctrl_qp_write_mem(rdev_p, pbl_addr >> 5, pbl_size << 3, - pbl); - wptr = rdev_p->ctrl_qp.wptr; - mutex_unlock(&rdev_p->ctrl_qp.lock); - if (err) - return err; - - if (wait_event_interruptible(rdev_p->ctrl_qp.waitq, - SEQ32_GE(rdev_p->ctrl_qp.rptr, - wptr))) - return -ERESTARTSYS; - - return 0; -} - int cxio_register_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, u32 pbl_size, u32 pbl_addr) + u8 page_size, __be64 *pbl, u32 *pbl_size, + u32 *pbl_addr) { *stag = T3_STAG_UNSET; return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm, - zbva, to, len, page_size, pbl_size, pbl_addr); + zbva, to, len, page_size, pbl, pbl_size, pbl_addr); } int cxio_reregister_phys_mem(struct cxio_rdev *rdev_p, u32 *stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, u32 pbl_size, u32 pbl_addr) + u8 page_size, __be64 *pbl, u32 *pbl_size, + u32 *pbl_addr) { return __cxio_tpt_op(rdev_p, 0, stag, 1, pdid, TPT_NON_SHARED_MR, perm, - zbva, to, len, page_size, pbl_size, pbl_addr); + zbva, to, len, page_size, pbl, pbl_size, pbl_addr); } int cxio_dereg_mem(struct cxio_rdev *rdev_p, u32 stag, u32 pbl_size, u32 pbl_addr) { - return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, - pbl_size, pbl_addr); + return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL, + &pbl_size, &pbl_addr); } int cxio_allocate_window(struct cxio_rdev *rdev_p, u32 * stag, u32 pdid) { + u32 pbl_size = 0; *stag = T3_STAG_UNSET; return __cxio_tpt_op(rdev_p, 0, stag, 0, pdid, TPT_MW, 0, 0, 0ULL, 0, 0, - 0, 0); + NULL, &pbl_size, NULL); } int cxio_deallocate_window(struct cxio_rdev *rdev_p, u32 stag) { - return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, - 0, 0); + return __cxio_tpt_op(rdev_p, 1, &stag, 0, 0, 0, 0, 0, 0ULL, 0, 0, NULL, + NULL, NULL); } int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) diff --git a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h index 6e128f6bab05..2bcff7f5046e 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -154,14 +154,14 @@ int cxio_create_qp(struct cxio_rdev *rdev, u32 kernel_domain, struct t3_wq *wq, int cxio_destroy_qp(struct cxio_rdev *rdev, struct t3_wq *wq, struct cxio_ucontext *uctx); int cxio_peek_cq(struct t3_wq *wr, struct t3_cq *cq, int opcode); -int cxio_write_pbl(struct cxio_rdev *rdev_p, __be64 *pbl, - u32 pbl_addr, u32 pbl_size); int cxio_register_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, u32 pbl_size, u32 pbl_addr); + u8 page_size, __be64 *pbl, u32 *pbl_size, + u32 *pbl_addr); int cxio_reregister_phys_mem(struct cxio_rdev *rdev, u32 * stag, u32 pdid, enum tpt_mem_perm perm, u32 zbva, u64 to, u32 len, - u8 page_size, u32 pbl_size, u32 pbl_addr); + u8 page_size, __be64 *pbl, u32 *pbl_size, + u32 *pbl_addr); int cxio_dereg_mem(struct cxio_rdev *rdev, u32 stag, u32 pbl_size, u32 pbl_addr); int cxio_allocate_window(struct cxio_rdev *rdev, u32 * stag, u32 pdid); @@ -173,8 +173,8 @@ u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp); void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid); int __init cxio_hal_init(void); void __exit cxio_hal_exit(void); -int cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count); -int cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count); +void cxio_flush_rq(struct t3_wq *wq, struct t3_cq *cq, int count); +void cxio_flush_sq(struct t3_wq *wq, struct t3_cq *cq, int count); void cxio_count_rcqes(struct t3_cq *cq, struct t3_wq *wq, int *count); void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count); void cxio_flush_hw_cq(struct t3_cq *cq); diff --git a/trunk/drivers/infiniband/hw/cxgb3/cxio_resource.c b/trunk/drivers/infiniband/hw/cxgb3/cxio_resource.c index bd233c087653..45ed4f25ef78 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_resource.c +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_resource.c @@ -250,6 +250,7 @@ void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp) */ #define MIN_PBL_SHIFT 8 /* 256B == min PBL size (32 entries) */ +#define PBL_CHUNK 2*1024*1024 u32 cxio_hal_pblpool_alloc(struct cxio_rdev *rdev_p, int size) { @@ -266,35 +267,14 @@ void cxio_hal_pblpool_free(struct cxio_rdev *rdev_p, u32 addr, int size) int cxio_hal_pblpool_create(struct cxio_rdev *rdev_p) { - unsigned pbl_start, pbl_chunk; - + unsigned long i; rdev_p->pbl_pool = gen_pool_create(MIN_PBL_SHIFT, -1); - if (!rdev_p->pbl_pool) - return -ENOMEM; - - pbl_start = rdev_p->rnic_info.pbl_base; - pbl_chunk = rdev_p->rnic_info.pbl_top - pbl_start + 1; - - while (pbl_start < rdev_p->rnic_info.pbl_top) { - pbl_chunk = min(rdev_p->rnic_info.pbl_top - pbl_start + 1, - pbl_chunk); - if (gen_pool_add(rdev_p->pbl_pool, pbl_start, pbl_chunk, -1)) { - PDBG("%s failed to add PBL chunk (%x/%x)\n", - __func__, pbl_start, pbl_chunk); - if (pbl_chunk <= 1024 << MIN_PBL_SHIFT) { - printk(KERN_WARNING MOD "%s: Failed to add all PBL chunks (%x/%x)\n", - __func__, pbl_start, rdev_p->rnic_info.pbl_top - pbl_start); - return 0; - } - pbl_chunk >>= 1; - } else { - PDBG("%s added PBL chunk (%x/%x)\n", - __func__, pbl_start, pbl_chunk); - pbl_start += pbl_chunk; - } - } - - return 0; + if (rdev_p->pbl_pool) + for (i = rdev_p->rnic_info.pbl_base; + i <= rdev_p->rnic_info.pbl_top - PBL_CHUNK + 1; + i += PBL_CHUNK) + gen_pool_add(rdev_p->pbl_pool, i, PBL_CHUNK, -1); + return rdev_p->pbl_pool ? 0 : -ENOMEM; } void cxio_hal_pblpool_destroy(struct cxio_rdev *rdev_p) diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c index c325c44807e8..d44a6df9ad8c 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -67,10 +67,10 @@ int peer2peer = 0; module_param(peer2peer, int, 0644); MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)"); -static int ep_timeout_secs = 60; +static int ep_timeout_secs = 10; module_param(ep_timeout_secs, int, 0644); MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " - "in seconds (default=60)"); + "in seconds (default=10)"); static int mpa_rev = 1; module_param(mpa_rev, int, 0644); @@ -1650,8 +1650,8 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) release = 1; break; case ABORTING: - case DEAD: break; + case DEAD: default: BUG_ON(1); break; diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_mem.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_mem.c index ec49a5cbdebb..58c3d61bcd14 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_mem.c @@ -35,26 +35,17 @@ #include #include "cxio_hal.h" -#include "cxio_resource.h" #include "iwch.h" #include "iwch_provider.h" -static void iwch_finish_mem_reg(struct iwch_mr *mhp, u32 stag) -{ - u32 mmid; - - mhp->attr.state = 1; - mhp->attr.stag = stag; - mmid = stag >> 8; - mhp->ibmr.rkey = mhp->ibmr.lkey = stag; - insert_handle(mhp->rhp, &mhp->rhp->mmidr, mhp, mmid); - PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp); -} - int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, - struct iwch_mr *mhp, int shift) + struct iwch_mr *mhp, + int shift, + __be64 *page_list) { u32 stag; + u32 mmid; + if (cxio_register_phys_mem(&rhp->rdev, &stag, mhp->attr.pdid, @@ -62,21 +53,28 @@ int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, mhp->attr.zbva, mhp->attr.va_fbo, mhp->attr.len, - shift - 12, - mhp->attr.pbl_size, mhp->attr.pbl_addr)) + shift-12, + page_list, + &mhp->attr.pbl_size, &mhp->attr.pbl_addr)) return -ENOMEM; - - iwch_finish_mem_reg(mhp, stag); - + mhp->attr.state = 1; + mhp->attr.stag = stag; + mmid = stag >> 8; + mhp->ibmr.rkey = mhp->ibmr.lkey = stag; + insert_handle(rhp, &rhp->mmidr, mhp, mmid); + PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp); return 0; } int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php, struct iwch_mr *mhp, int shift, + __be64 *page_list, int npages) { u32 stag; + u32 mmid; + /* We could support this... */ if (npages > mhp->attr.pbl_size) @@ -89,40 +87,19 @@ int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php, mhp->attr.zbva, mhp->attr.va_fbo, mhp->attr.len, - shift - 12, - mhp->attr.pbl_size, mhp->attr.pbl_addr)) + shift-12, + page_list, + &mhp->attr.pbl_size, &mhp->attr.pbl_addr)) return -ENOMEM; - - iwch_finish_mem_reg(mhp, stag); - - return 0; -} - -int iwch_alloc_pbl(struct iwch_mr *mhp, int npages) -{ - mhp->attr.pbl_addr = cxio_hal_pblpool_alloc(&mhp->rhp->rdev, - npages << 3); - - if (!mhp->attr.pbl_addr) - return -ENOMEM; - - mhp->attr.pbl_size = npages; - + mhp->attr.state = 1; + mhp->attr.stag = stag; + mmid = stag >> 8; + mhp->ibmr.rkey = mhp->ibmr.lkey = stag; + insert_handle(rhp, &rhp->mmidr, mhp, mmid); + PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp); return 0; } -void iwch_free_pbl(struct iwch_mr *mhp) -{ - cxio_hal_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr, - mhp->attr.pbl_size << 3); -} - -int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset) -{ - return cxio_write_pbl(&mhp->rhp->rdev, pages, - mhp->attr.pbl_addr + (offset << 3), npages); -} - int build_phys_page_list(struct ib_phys_buf *buffer_list, int num_phys_buf, u64 *iova_start, diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c index 8934178a23ee..d07d3a377b5f 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -442,7 +442,6 @@ static int iwch_dereg_mr(struct ib_mr *ib_mr) mmid = mhp->attr.stag >> 8; cxio_dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size, mhp->attr.pbl_addr); - iwch_free_pbl(mhp); remove_handle(rhp, &rhp->mmidr, mmid); if (mhp->kva) kfree((void *) (unsigned long) mhp->kva); @@ -476,8 +475,6 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd, if (!mhp) return ERR_PTR(-ENOMEM); - mhp->rhp = rhp; - /* First check that we have enough alignment */ if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) { ret = -EINVAL; @@ -495,17 +492,7 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd, if (ret) goto err; - ret = iwch_alloc_pbl(mhp, npages); - if (ret) { - kfree(page_list); - goto err_pbl; - } - - ret = iwch_write_pbl(mhp, page_list, npages, 0); - kfree(page_list); - if (ret) - goto err_pbl; - + mhp->rhp = rhp; mhp->attr.pdid = php->pdid; mhp->attr.zbva = 0; @@ -515,15 +502,12 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd, mhp->attr.len = (u32) total_size; mhp->attr.pbl_size = npages; - ret = iwch_register_mem(rhp, php, mhp, shift); - if (ret) - goto err_pbl; - + ret = iwch_register_mem(rhp, php, mhp, shift, page_list); + kfree(page_list); + if (ret) { + goto err; + } return &mhp->ibmr; - -err_pbl: - iwch_free_pbl(mhp); - err: kfree(mhp); return ERR_PTR(ret); @@ -576,7 +560,7 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr, return ret; } - ret = iwch_reregister_mem(rhp, php, &mh, shift, npages); + ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages); kfree(page_list); if (ret) { return ret; @@ -618,8 +602,6 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (!mhp) return ERR_PTR(-ENOMEM); - mhp->rhp = rhp; - mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0); if (IS_ERR(mhp->umem)) { err = PTR_ERR(mhp->umem); @@ -633,14 +615,10 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, list_for_each_entry(chunk, &mhp->umem->chunk_list, list) n += chunk->nents; - err = iwch_alloc_pbl(mhp, n); - if (err) - goto err; - - pages = (__be64 *) __get_free_page(GFP_KERNEL); + pages = kmalloc(n * sizeof(u64), GFP_KERNEL); if (!pages) { err = -ENOMEM; - goto err_pbl; + goto err; } i = n = 0; @@ -652,38 +630,25 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, pages[i++] = cpu_to_be64(sg_dma_address( &chunk->page_list[j]) + mhp->umem->page_size * k); - if (i == PAGE_SIZE / sizeof *pages) { - err = iwch_write_pbl(mhp, pages, i, n); - if (err) - goto pbl_done; - n += i; - i = 0; - } } } - if (i) - err = iwch_write_pbl(mhp, pages, i, n); - -pbl_done: - free_page((unsigned long) pages); - if (err) - goto err_pbl; - + mhp->rhp = rhp; mhp->attr.pdid = php->pdid; mhp->attr.zbva = 0; mhp->attr.perms = iwch_ib_to_tpt_access(acc); mhp->attr.va_fbo = virt; mhp->attr.page_size = shift - 12; mhp->attr.len = (u32) length; - - err = iwch_register_mem(rhp, php, mhp, shift); + mhp->attr.pbl_size = i; + err = iwch_register_mem(rhp, php, mhp, shift, pages); + kfree(pages); if (err) - goto err_pbl; + goto err; if (udata && !t3a_device(rhp)) { uresp.pbl_addr = (mhp->attr.pbl_addr - - rhp->rdev.rnic_info.pbl_base) >> 3; + rhp->rdev.rnic_info.pbl_base) >> 3; PDBG("%s user resp pbl_addr 0x%x\n", __func__, uresp.pbl_addr); @@ -696,9 +661,6 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, return &mhp->ibmr; -err_pbl: - iwch_free_pbl(mhp); - err: ib_umem_release(mhp->umem); kfree(mhp); diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.h b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.h index 836163fc5429..db5100d27ca2 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.h +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.h @@ -340,14 +340,14 @@ int iwch_quiesce_qps(struct iwch_cq *chp); int iwch_resume_qps(struct iwch_cq *chp); void stop_read_rep_timer(struct iwch_qp *qhp); int iwch_register_mem(struct iwch_dev *rhp, struct iwch_pd *php, - struct iwch_mr *mhp, int shift); + struct iwch_mr *mhp, + int shift, + __be64 *page_list); int iwch_reregister_mem(struct iwch_dev *rhp, struct iwch_pd *php, struct iwch_mr *mhp, int shift, + __be64 *page_list, int npages); -int iwch_alloc_pbl(struct iwch_mr *mhp, int npages); -void iwch_free_pbl(struct iwch_mr *mhp); -int iwch_write_pbl(struct iwch_mr *mhp, __be64 *pages, int npages, int offset); int build_phys_page_list(struct ib_phys_buf *buffer_list, int num_phys_buf, u64 *iova_start, diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c index 79dbe5beae52..9b4be889c58e 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c @@ -655,7 +655,6 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) { struct iwch_cq *rchp, *schp; int count; - int flushed; rchp = get_chp(qhp->rhp, qhp->attr.rcq); schp = get_chp(qhp->rhp, qhp->attr.scq); @@ -670,22 +669,20 @@ static void __flush_qp(struct iwch_qp *qhp, unsigned long *flag) spin_lock(&qhp->lock); cxio_flush_hw_cq(&rchp->cq); cxio_count_rcqes(&rchp->cq, &qhp->wq, &count); - flushed = cxio_flush_rq(&qhp->wq, &rchp->cq, count); + cxio_flush_rq(&qhp->wq, &rchp->cq, count); spin_unlock(&qhp->lock); spin_unlock_irqrestore(&rchp->lock, *flag); - if (flushed) - (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); + (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); /* locking heirarchy: cq lock first, then qp lock. */ spin_lock_irqsave(&schp->lock, *flag); spin_lock(&qhp->lock); cxio_flush_hw_cq(&schp->cq); cxio_count_scqes(&schp->cq, &qhp->wq, &count); - flushed = cxio_flush_sq(&qhp->wq, &schp->cq, count); + cxio_flush_sq(&qhp->wq, &schp->cq, count); spin_unlock(&qhp->lock); spin_unlock_irqrestore(&schp->lock, *flag); - if (flushed) - (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); + (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); /* deref */ if (atomic_dec_and_test(&qhp->refcnt)) @@ -883,6 +880,7 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, ep = qhp->ep; get_ep(&ep->com); } + flush_qp(qhp, &flag); break; case IWCH_QP_STATE_TERMINATE: qhp->attr.state = IWCH_QP_STATE_TERMINATE; @@ -913,7 +911,6 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp, } switch (attrs->next_state) { case IWCH_QP_STATE_IDLE: - flush_qp(qhp, &flag); qhp->attr.state = IWCH_QP_STATE_IDLE; qhp->attr.llp_stream_handle = NULL; put_ep(&qhp->ep->com); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h index 1e9e99a13933..00bab60f6de4 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h @@ -192,8 +192,6 @@ struct ehca_qp { int mtu_shift; u32 message_count; u32 packet_count; - atomic_t nr_events; /* events seen */ - wait_queue_head_t wait_completion; }; #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_hca.c b/trunk/drivers/infiniband/hw/ehca/ehca_hca.c index bc3b37d2070f..2515cbde7e65 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_hca.c @@ -101,6 +101,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) props->max_ee = limit_uint(rblock->max_rd_ee_context); props->max_rdd = limit_uint(rblock->max_rd_domain); props->max_fmr = limit_uint(rblock->max_mr); + props->local_ca_ack_delay = limit_uint(rblock->local_ca_ack_delay); props->max_qp_rd_atom = limit_uint(rblock->max_rr_qp); props->max_ee_rd_atom = limit_uint(rblock->max_rr_ee_context); props->max_res_rd_atom = limit_uint(rblock->max_rr_hca); @@ -114,7 +115,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) } props->max_pkeys = 16; - props->local_ca_ack_delay = min_t(u8, rblock->local_ca_ack_delay, 255); + props->local_ca_ack_delay = limit_uint(rblock->local_ca_ack_delay); props->max_raw_ipv6_qp = limit_uint(rblock->max_raw_ipv6_qp); props->max_raw_ethy_qp = limit_uint(rblock->max_raw_ethy_qp); props->max_mcast_grp = limit_uint(rblock->max_mcast_grp); @@ -135,7 +136,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) return ret; } -static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu) +static int map_mtu(struct ehca_shca *shca, u32 fw_mtu) { switch (fw_mtu) { case 0x1: @@ -155,7 +156,7 @@ static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu) } } -static u8 map_number_of_vls(struct ehca_shca *shca, u32 vl_cap) +static int map_number_of_vls(struct ehca_shca *shca, u32 vl_cap) { switch (vl_cap) { case 0x1: diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c index ce1ab0571be3..ca5eb0cb628c 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_irq.c @@ -204,8 +204,6 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe, read_lock(&ehca_qp_idr_lock); qp = idr_find(&ehca_qp_idr, token); - if (qp) - atomic_inc(&qp->nr_events); read_unlock(&ehca_qp_idr_lock); if (!qp) @@ -225,8 +223,6 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe, if (fatal && qp->ext_type == EQPT_SRQBASE) dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED); - if (atomic_dec_and_test(&qp->nr_events)) - wake_up(&qp->wait_completion); return; } diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index 3f59587338ea..18fba92fa7ae 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -566,8 +566,6 @@ static struct ehca_qp *internal_create_qp( return ERR_PTR(-ENOMEM); } - atomic_set(&my_qp->nr_events, 0); - init_waitqueue_head(&my_qp->wait_completion); spin_lock_init(&my_qp->spinlock_s); spin_lock_init(&my_qp->spinlock_r); my_qp->qp_type = qp_type; @@ -1936,9 +1934,6 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, idr_remove(&ehca_qp_idr, my_qp->token); write_unlock_irqrestore(&ehca_qp_idr_lock, flags); - /* now wait until all pending events have completed */ - wait_event(my_qp->wait_completion, !atomic_read(&my_qp->nr_events)); - h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); if (h_ret != H_SUCCESS) { ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li " diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c index ce7b7c34360e..acf30c06a0c0 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c @@ -1197,7 +1197,7 @@ void ipath_kreceive(struct ipath_portdata *pd) } reloop: - for (last = 0, i = 1; !last; i += !last) { + for (last = 0, i = 1; !last; i++) { hdr = dd->ipath_f_get_msgheader(dd, rhf_addr); eflags = ipath_hdrget_err_flags(rhf_addr); etype = ipath_hdrget_rcv_type(rhf_addr); @@ -1428,40 +1428,6 @@ static void ipath_update_pio_bufs(struct ipath_devdata *dd) spin_unlock_irqrestore(&ipath_pioavail_lock, flags); } -/* - * used to force update of pioavailshadow if we can't get a pio buffer. - * Needed primarily due to exitting freeze mode after recovering - * from errors. Done lazily, because it's safer (known to not - * be writing pio buffers). - */ -static void ipath_reset_availshadow(struct ipath_devdata *dd) -{ - int i, im; - unsigned long flags; - - spin_lock_irqsave(&ipath_pioavail_lock, flags); - for (i = 0; i < dd->ipath_pioavregs; i++) { - u64 val, oldval; - /* deal with 6110 chip bug on high register #s */ - im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ? - i ^ 1 : i; - val = le64_to_cpu(dd->ipath_pioavailregs_dma[im]); - /* - * busy out the buffers not in the kernel avail list, - * without changing the generation bits. - */ - oldval = dd->ipath_pioavailshadow[i]; - dd->ipath_pioavailshadow[i] = val | - ((~dd->ipath_pioavailkernel[i] << - INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT) & - 0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */ - if (oldval != dd->ipath_pioavailshadow[i]) - ipath_dbg("shadow[%d] was %Lx, now %lx\n", - i, oldval, dd->ipath_pioavailshadow[i]); - } - spin_unlock_irqrestore(&ipath_pioavail_lock, flags); -} - /** * ipath_setrcvhdrsize - set the receive header size * @dd: the infinipath device @@ -1516,12 +1482,9 @@ static noinline void no_pio_bufs(struct ipath_devdata *dd) */ ipath_stats.sps_nopiobufs++; if (!(++dd->ipath_consec_nopiobuf % 100000)) { - ipath_force_pio_avail_update(dd); /* at start */ - ipath_dbg("%u tries no piobufavail ts%lx; dmacopy: " - "%llx %llx %llx %llx\n" - "ipath shadow: %lx %lx %lx %lx\n", + ipath_dbg("%u pio sends with no bufavail; dmacopy: " + "%llx %llx %llx %llx; shadow: %lx %lx %lx %lx\n", dd->ipath_consec_nopiobuf, - (unsigned long)get_cycles(), (unsigned long long) le64_to_cpu(dma[0]), (unsigned long long) le64_to_cpu(dma[1]), (unsigned long long) le64_to_cpu(dma[2]), @@ -1533,17 +1496,14 @@ static noinline void no_pio_bufs(struct ipath_devdata *dd) */ if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > (sizeof(shadow[0]) * 4 * 4)) - ipath_dbg("2nd group: dmacopy: " - "%llx %llx %llx %llx\n" - "ipath shadow: %lx %lx %lx %lx\n", + ipath_dbg("2nd group: dmacopy: %llx %llx " + "%llx %llx; shadow: %lx %lx %lx %lx\n", (unsigned long long)le64_to_cpu(dma[4]), (unsigned long long)le64_to_cpu(dma[5]), (unsigned long long)le64_to_cpu(dma[6]), (unsigned long long)le64_to_cpu(dma[7]), - shadow[4], shadow[5], shadow[6], shadow[7]); - - /* at end, so update likely happened */ - ipath_reset_availshadow(dd); + shadow[4], shadow[5], shadow[6], + shadow[7]); } } @@ -1692,46 +1652,19 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, unsigned len, int avail) { unsigned long flags; - unsigned end, cnt = 0, next; + unsigned end; /* There are two bits per send buffer (busy and generation) */ start *= 2; - end = start + len * 2; + len *= 2; + end = start + len; + /* Set or clear the generation bits. */ spin_lock_irqsave(&ipath_pioavail_lock, flags); - /* Set or clear the busy bit in the shadow. */ while (start < end) { if (avail) { - unsigned long dma; - int i, im; - /* - * the BUSY bit will never be set, because we disarm - * the user buffers before we hand them back to the - * kernel. We do have to make sure the generation - * bit is set correctly in shadow, since it could - * have changed many times while allocated to user. - * We can't use the bitmap functions on the full - * dma array because it is always little-endian, so - * we have to flip to host-order first. - * BITS_PER_LONG is slightly wrong, since it's - * always 64 bits per register in chip... - * We only work on 64 bit kernels, so that's OK. - */ - /* deal with 6110 chip bug on high register #s */ - i = start / BITS_PER_LONG; - im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ? - i ^ 1 : i; - __clear_bit(INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT - + start, dd->ipath_pioavailshadow); - dma = (unsigned long) le64_to_cpu( - dd->ipath_pioavailregs_dma[im]); - if (test_bit((INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT - + start) % BITS_PER_LONG, &dma)) - __set_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT - + start, dd->ipath_pioavailshadow); - else - __clear_bit(INFINIPATH_SENDPIOAVAIL_CHECK_SHIFT - + start, dd->ipath_pioavailshadow); + __clear_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT, + dd->ipath_pioavailshadow); __set_bit(start, dd->ipath_pioavailkernel); } else { __set_bit(start + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT, @@ -1740,44 +1673,7 @@ void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, } start += 2; } - - if (dd->ipath_pioupd_thresh) { - end = 2 * (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k); - next = find_first_bit(dd->ipath_pioavailkernel, end); - while (next < end) { - cnt++; - next = find_next_bit(dd->ipath_pioavailkernel, end, - next + 1); - } - } spin_unlock_irqrestore(&ipath_pioavail_lock, flags); - - /* - * When moving buffers from kernel to user, if number assigned to - * the user is less than the pio update threshold, and threshold - * is supported (cnt was computed > 0), drop the update threshold - * so we update at least once per allocated number of buffers. - * In any case, if the kernel buffers are less than the threshold, - * drop the threshold. We don't bother increasing it, having once - * decreased it, since it would typically just cycle back and forth. - * If we don't decrease below buffers in use, we can wait a long - * time for an update, until some other context uses PIO buffers. - */ - if (!avail && len < cnt) - cnt = len; - if (cnt < dd->ipath_pioupd_thresh) { - dd->ipath_pioupd_thresh = cnt; - ipath_dbg("Decreased pio update threshold to %u\n", - dd->ipath_pioupd_thresh); - spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); - dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK - << INFINIPATH_S_UPDTHRESH_SHIFT); - dd->ipath_sendctrl |= dd->ipath_pioupd_thresh - << INFINIPATH_S_UPDTHRESH_SHIFT; - ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, - dd->ipath_sendctrl); - spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); - } } /** @@ -1898,8 +1794,8 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) spin_lock_irqsave(&dd->ipath_sdma_lock, flags); skip_cancel = - test_and_set_bit(IPATH_SDMA_ABORTING, statp) - && !test_bit(IPATH_SDMA_DISABLED, statp); + !test_bit(IPATH_SDMA_DISABLED, statp) && + test_and_set_bit(IPATH_SDMA_ABORTING, statp); spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); if (skip_cancel) goto bail; @@ -1930,9 +1826,6 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) ipath_disarm_piobufs(dd, 0, dd->ipath_piobcnt2k + dd->ipath_piobcnt4k); - if (dd->ipath_flags & IPATH_HAS_SEND_DMA) - set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status); - if (restore_sendctrl) { /* else done by caller later if needed */ spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); @@ -1952,6 +1845,7 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) /* only wait so long for intr */ dd->ipath_sdma_abort_intr_timeout = jiffies + HZ; dd->ipath_sdma_reset_wait = 200; + __set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status); if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status)) tasklet_hi_schedule(&dd->ipath_sdma_abort_task); spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c b/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c index 3295177c937e..8b1752202e78 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -173,25 +173,47 @@ static int ipath_get_base_info(struct file *fp, (void *) dd->ipath_statusp - (void *) dd->ipath_pioavailregs_dma; if (!shared) { - kinfo->spi_piocnt = pd->port_piocnt; + kinfo->spi_piocnt = dd->ipath_pbufsport; kinfo->spi_piobufbase = (u64) pd->port_piobufs; kinfo->__spi_uregbase = (u64) dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; } else if (master) { - kinfo->spi_piocnt = (pd->port_piocnt / subport_cnt) + - (pd->port_piocnt % subport_cnt); + kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) + + (dd->ipath_pbufsport % subport_cnt); /* Master's PIO buffers are after all the slave's */ kinfo->spi_piobufbase = (u64) pd->port_piobufs + dd->ipath_palign * - (pd->port_piocnt - kinfo->spi_piocnt); + (dd->ipath_pbufsport - kinfo->spi_piocnt); } else { unsigned slave = subport_fp(fp) - 1; - kinfo->spi_piocnt = pd->port_piocnt / subport_cnt; + kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt; kinfo->spi_piobufbase = (u64) pd->port_piobufs + dd->ipath_palign * kinfo->spi_piocnt * slave; } + /* + * Set the PIO avail update threshold to no larger + * than the number of buffers per process. Note that + * we decrease it here, but won't ever increase it. + */ + if (dd->ipath_pioupd_thresh && + kinfo->spi_piocnt < dd->ipath_pioupd_thresh) { + unsigned long flags; + + dd->ipath_pioupd_thresh = kinfo->spi_piocnt; + ipath_dbg("Decreased pio update threshold to %u\n", + dd->ipath_pioupd_thresh); + spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); + dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK + << INFINIPATH_S_UPDTHRESH_SHIFT); + dd->ipath_sendctrl |= dd->ipath_pioupd_thresh + << INFINIPATH_S_UPDTHRESH_SHIFT; + ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, + dd->ipath_sendctrl); + spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); + } + if (shared) { kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; @@ -1287,19 +1309,19 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma) ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; if (!pd->port_subport_cnt) { /* port is not shared */ - piocnt = pd->port_piocnt; + piocnt = dd->ipath_pbufsport; piobufs = pd->port_piobufs; } else if (!subport_fp(fp)) { /* caller is the master */ - piocnt = (pd->port_piocnt / pd->port_subport_cnt) + - (pd->port_piocnt % pd->port_subport_cnt); + piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) + + (dd->ipath_pbufsport % pd->port_subport_cnt); piobufs = pd->port_piobufs + - dd->ipath_palign * (pd->port_piocnt - piocnt); + dd->ipath_palign * (dd->ipath_pbufsport - piocnt); } else { unsigned slave = subport_fp(fp) - 1; /* caller is a slave */ - piocnt = pd->port_piocnt / pd->port_subport_cnt; + piocnt = dd->ipath_pbufsport / pd->port_subport_cnt; piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave; } @@ -1611,6 +1633,9 @@ static int try_alloc_port(struct ipath_devdata *dd, int port, port_fp(fp) = pd; pd->port_pid = current->pid; strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm)); + ipath_chg_pioavailkernel(dd, + dd->ipath_pbufsport * (pd->port_port - 1), + dd->ipath_pbufsport, 0); ipath_stats.sps_ports++; ret = 0; } else @@ -1913,25 +1938,11 @@ static int ipath_do_user_init(struct file *fp, /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */ - /* some ports may get extra buffers, calculate that here */ - if (pd->port_port <= dd->ipath_ports_extrabuf) - pd->port_piocnt = dd->ipath_pbufsport + 1; - else - pd->port_piocnt = dd->ipath_pbufsport; - /* for right now, kernel piobufs are at end, so port 1 is at 0 */ - if (pd->port_port <= dd->ipath_ports_extrabuf) - pd->port_pio_base = (dd->ipath_pbufsport + 1) - * (pd->port_port - 1); - else - pd->port_pio_base = dd->ipath_ports_extrabuf + - dd->ipath_pbufsport * (pd->port_port - 1); pd->port_piobufs = dd->ipath_piobufbase + - pd->port_pio_base * dd->ipath_palign; - ipath_cdbg(VERBOSE, "piobuf base for port %u is 0x%x, piocnt %u," - " first pio %u\n", pd->port_port, pd->port_piobufs, - pd->port_piocnt, pd->port_pio_base); - ipath_chg_pioavailkernel(dd, pd->port_pio_base, pd->port_piocnt, 0); + dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign; + ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n", + pd->port_port, pd->port_piobufs); /* * Now allocate the rcvhdr Q and eager TIDs; skip the TID @@ -2096,6 +2107,7 @@ static int ipath_close(struct inode *in, struct file *fp) } if (dd->ipath_kregbase) { + int i; /* atomically clear receive enable port and intr avail. */ clear_bit(dd->ipath_r_portenable_shift + port, &dd->ipath_rcvctrl); @@ -2124,9 +2136,9 @@ static int ipath_close(struct inode *in, struct file *fp) ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, pd->port_port, dd->ipath_dummy_hdrq_phys); - ipath_disarm_piobufs(dd, pd->port_pio_base, pd->port_piocnt); - ipath_chg_pioavailkernel(dd, pd->port_pio_base, - pd->port_piocnt, 1); + i = dd->ipath_pbufsport * (port - 1); + ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport); + ipath_chg_pioavailkernel(dd, i, dd->ipath_pbufsport, 1); dd->ipath_f_clear_tids(dd, pd->port_port); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_iba7220.c b/trunk/drivers/infiniband/hw/ipath/ipath_iba7220.c index 8eee7830f042..e3ec0d1bdf50 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_iba7220.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_iba7220.c @@ -595,7 +595,7 @@ static void ipath_7220_txe_recover(struct ipath_devdata *dd) dev_info(&dd->pcidev->dev, "Recovering from TXE PIO parity error\n"); - ipath_disarm_senderrbufs(dd); + ipath_disarm_senderrbufs(dd, 1); } @@ -675,8 +675,10 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); if ((ctrl & INFINIPATH_C_FREEZEMODE) && !ipath_diag_inuse) { /* - * Parity errors in send memory are recoverable by h/w - * just do housekeeping, exit freeze mode and continue. + * Parity errors in send memory are recoverable, + * just cancel the send (if indicated in * sendbuffererror), + * count the occurrence, unfreeze (if no other handled + * hardware error bits are set), and continue. */ if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) @@ -685,6 +687,13 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT); + if (!hwerrs) { + /* else leave in freeze mode */ + ipath_write_kreg(dd, + dd->ipath_kregs->kr_control, + dd->ipath_control); + goto bail; + } } if (hwerrs) { /* @@ -714,8 +723,8 @@ static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, *dd->ipath_statusp |= IPATH_STATUS_HWERROR; dd->ipath_flags &= ~IPATH_INITTED; } else { - ipath_dbg("Clearing freezemode on ignored or " - "recovered hardware error\n"); + ipath_dbg("Clearing freezemode on ignored hardware " + "error\n"); ipath_clear_freeze(dd); } } @@ -861,9 +870,8 @@ static int ipath_7220_boardname(struct ipath_devdata *dd, char *name, "revision %u.%u!\n", dd->ipath_majrev, dd->ipath_minrev); ret = 1; - } else if (dd->ipath_minrev == 1 && - !(dd->ipath_flags & IPATH_INITTED)) { - /* Rev1 chips are prototype. Complain at init, but allow use */ + } else if (dd->ipath_minrev == 1) { + /* Rev1 chips are prototype. Complain, but allow use */ ipath_dev_err(dd, "Unsupported hardware " "revision %u.%u, Contact support@qlogic.com\n", dd->ipath_majrev, dd->ipath_minrev); @@ -1958,7 +1966,7 @@ static void ipath_7220_config_ports(struct ipath_devdata *dd, ushort cfgports) dd->ipath_rcvctrl); dd->ipath_p0_rcvegrcnt = 2048; /* always */ if (dd->ipath_flags & IPATH_HAS_SEND_DMA) - dd->ipath_pioreserved = 3; /* kpiobufs used for PIO */ + dd->ipath_pioreserved = 1; /* reserve a buffer */ } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_init_chip.c b/trunk/drivers/infiniband/hw/ipath/ipath_init_chip.c index 3e5baa43fc82..27dd89476660 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_init_chip.c @@ -41,7 +41,7 @@ /* * min buffers we want to have per port, after driver */ -#define IPATH_MIN_USER_PORT_BUFCNT 7 +#define IPATH_MIN_USER_PORT_BUFCNT 8 /* * Number of ports we are configured to use (to allow for more pio @@ -54,9 +54,13 @@ MODULE_PARM_DESC(cfgports, "Set max number of ports to use"); /* * Number of buffers reserved for driver (verbs and layered drivers.) - * Initialized based on number of PIO buffers if not set via module interface. + * Reserved at end of buffer list. Initialized based on + * number of PIO buffers if not set via module interface. * The problem with this is that it's global, but we'll use different - * numbers for different chip types. + * numbers for different chip types. So the default value is not + * very useful. I've redefined it for the 1.3 release so that it's + * zero unless set by the user to something else, in which case we + * try to respect it. */ static ushort ipath_kpiobufs; @@ -542,12 +546,9 @@ static void enable_chip(struct ipath_devdata *dd, int reinit) pioavail = dd->ipath_pioavailregs_dma[i ^ 1]; else pioavail = dd->ipath_pioavailregs_dma[i]; - /* - * don't need to worry about ipath_pioavailkernel here - * because we will call ipath_chg_pioavailkernel() later - * in initialization, to busy out buffers as needed - */ - dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail); + dd->ipath_pioavailshadow[i] = le64_to_cpu(pioavail) | + (~dd->ipath_pioavailkernel[i] << + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT); } /* can get counters, stats, etc. */ dd->ipath_flags |= IPATH_PRESENT; @@ -707,11 +708,12 @@ static void verify_interrupt(unsigned long opaque) int ipath_init_chip(struct ipath_devdata *dd, int reinit) { int ret = 0; - u32 kpiobufs, defkbufs; + u32 val32, kpiobufs; u32 piobufs, uports; u64 val; struct ipath_portdata *pd; gfp_t gfp_flags = GFP_USER | __GFP_COMP; + unsigned long flags; ret = init_housekeeping(dd, reinit); if (ret) @@ -751,52 +753,69 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) dd->ipath_pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) / (sizeof(u64) * BITS_PER_BYTE / 2); uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0; - if (piobufs > 144) - defkbufs = 32 + dd->ipath_pioreserved; + if (ipath_kpiobufs == 0) { + /* not set by user (this is default) */ + if (piobufs > 144) + kpiobufs = 32; + else + kpiobufs = 16; + } else - defkbufs = 16 + dd->ipath_pioreserved; + kpiobufs = ipath_kpiobufs; - if (ipath_kpiobufs && (ipath_kpiobufs + - (uports * IPATH_MIN_USER_PORT_BUFCNT)) > piobufs) { + if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { int i = (int) piobufs - (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); if (i < 1) i = 1; dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of " "%d for kernel leaves too few for %d user ports " - "(%d each); using %u\n", ipath_kpiobufs, + "(%d each); using %u\n", kpiobufs, piobufs, uports, IPATH_MIN_USER_PORT_BUFCNT, i); /* * shouldn't change ipath_kpiobufs, because could be * different for different devices... */ kpiobufs = i; - } else if (ipath_kpiobufs) - kpiobufs = ipath_kpiobufs; - else - kpiobufs = defkbufs; + } dd->ipath_lastport_piobuf = piobufs - kpiobufs; dd->ipath_pbufsport = uports ? dd->ipath_lastport_piobuf / uports : 0; - /* if not an even divisor, some user ports get extra buffers */ - dd->ipath_ports_extrabuf = dd->ipath_lastport_piobuf - - (dd->ipath_pbufsport * uports); - if (dd->ipath_ports_extrabuf) - ipath_dbg("%u pbufs/port leaves some unused, add 1 buffer to " - "ports <= %u\n", dd->ipath_pbufsport, - dd->ipath_ports_extrabuf); + val32 = dd->ipath_lastport_piobuf - (dd->ipath_pbufsport * uports); + if (val32 > 0) { + ipath_dbg("allocating %u pbufs/port leaves %u unused, " + "add to kernel\n", dd->ipath_pbufsport, val32); + dd->ipath_lastport_piobuf -= val32; + kpiobufs += val32; + ipath_dbg("%u pbufs/port leaves %u unused, add to kernel\n", + dd->ipath_pbufsport, val32); + } dd->ipath_lastpioindex = 0; dd->ipath_lastpioindexl = dd->ipath_piobcnt2k; - /* ipath_pioavailshadow initialized earlier */ + ipath_chg_pioavailkernel(dd, 0, piobufs, 1); ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " "each for %u user ports\n", kpiobufs, piobufs, dd->ipath_pbufsport, uports); + if (dd->ipath_pioupd_thresh) { + if (dd->ipath_pbufsport < dd->ipath_pioupd_thresh) + dd->ipath_pioupd_thresh = dd->ipath_pbufsport; + if (kpiobufs < dd->ipath_pioupd_thresh) + dd->ipath_pioupd_thresh = kpiobufs; + } + ret = dd->ipath_f_early_init(dd); if (ret) { ipath_dev_err(dd, "Early initialization failure\n"); goto done; } + /* + * Cancel any possible active sends from early driver load. + * Follows early_init because some chips have to initialize + * PIO buffers in early_init to avoid false parity errors. + */ + ipath_cancel_sends(dd, 0); + /* * Early_init sets rcvhdrentsize and rcvhdrsize, so this must be * done after early_init. @@ -817,7 +836,6 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) ipath_write_kreg(dd, dd->ipath_kregs->kr_sendpioavailaddr, dd->ipath_pioavailregs_phys); - /* * this is to detect s/w errors, which the h/w works around by * ignoring the low 6 bits of address, if it wasn't aligned. @@ -844,6 +862,12 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) ~0ULL&~INFINIPATH_HWE_MEMBISTFAILED); ipath_write_kreg(dd, dd->ipath_kregs->kr_control, 0ULL); + spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); + dd->ipath_sendctrl = INFINIPATH_S_PIOENABLE; + ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl); + ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); + spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); + /* * before error clears, since we expect serdes pll errors during * this, the first time after reset @@ -916,19 +940,6 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) else enable_chip(dd, reinit); - /* after enable_chip, so pioavailshadow setup */ - ipath_chg_pioavailkernel(dd, 0, piobufs, 1); - - /* - * Cancel any possible active sends from early driver load. - * Follows early_init because some chips have to initialize - * PIO buffers in early_init to avoid false parity errors. - * After enable and ipath_chg_pioavailkernel so we can safely - * enable pioavail updates and PIOENABLE; packets are now - * ready to go out. - */ - ipath_cancel_sends(dd, 1); - if (!reinit) { /* * Used when we close a port, for DMA already in flight diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c index 26900b3b7a4e..1b58f4737c71 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_intr.c @@ -38,12 +38,42 @@ #include "ipath_verbs.h" #include "ipath_common.h" +/* + * clear (write) a pio buffer, to clear a parity error. This routine + * should only be called when in freeze mode, and the buffer should be + * canceled afterwards. + */ +static void ipath_clrpiobuf(struct ipath_devdata *dd, u32 pnum) +{ + u32 __iomem *pbuf; + u32 dwcnt; /* dword count to write */ + if (pnum < dd->ipath_piobcnt2k) { + pbuf = (u32 __iomem *) (dd->ipath_pio2kbase + pnum * + dd->ipath_palign); + dwcnt = dd->ipath_piosize2k >> 2; + } + else { + pbuf = (u32 __iomem *) (dd->ipath_pio4kbase + + (pnum - dd->ipath_piobcnt2k) * dd->ipath_4kalign); + dwcnt = dd->ipath_piosize4k >> 2; + } + dev_info(&dd->pcidev->dev, + "Rewrite PIO buffer %u, to recover from parity error\n", + pnum); + + /* no flush required, since already in freeze */ + writel(dwcnt + 1, pbuf); + while (--dwcnt) + writel(0, pbuf++); +} /* * Called when we might have an error that is specific to a particular * PIO buffer, and may need to cancel that buffer, so it can be re-used. + * If rewrite is true, and bits are set in the sendbufferror registers, + * we'll write to the buffer, for error recovery on parity errors. */ -void ipath_disarm_senderrbufs(struct ipath_devdata *dd) +void ipath_disarm_senderrbufs(struct ipath_devdata *dd, int rewrite) { u32 piobcnt; unsigned long sbuf[4]; @@ -79,8 +109,11 @@ void ipath_disarm_senderrbufs(struct ipath_devdata *dd) } for (i = 0; i < piobcnt; i++) - if (test_bit(i, sbuf)) + if (test_bit(i, sbuf)) { + if (rewrite) + ipath_clrpiobuf(dd, i); ipath_disarm_piobufs(dd, i, 1); + } /* ignore armlaunch errs for a bit */ dd->ipath_lastcancel = jiffies+3; } @@ -131,7 +164,7 @@ static u64 handle_e_sum_errs(struct ipath_devdata *dd, ipath_err_t errs) { u64 ignore_this_time = 0; - ipath_disarm_senderrbufs(dd); + ipath_disarm_senderrbufs(dd, 0); if ((errs & E_SUM_LINK_PKTERRS) && !(dd->ipath_flags & IPATH_LINKACTIVE)) { /* @@ -876,8 +909,8 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) * processes (causing armlaunch), send errors due to going into freeze mode, * etc., and try to avoid causing extra interrupts while doing so. * Forcibly update the in-memory pioavail register copies after cleanup - * because the chip won't do it while in freeze mode (the register values - * themselves are kept correct). + * because the chip won't do it for anything changing while in freeze mode + * (we don't want to wait for the next pio buffer state change). * Make sure that we don't lose any important interrupts by using the chip * feature that says that writing 0 to a bit in *clear that is set in * *status will cause an interrupt to be generated again (if allowed by @@ -885,22 +918,43 @@ static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs) */ void ipath_clear_freeze(struct ipath_devdata *dd) { + int i, im; + u64 val; + /* disable error interrupts, to avoid confusion */ ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask, 0ULL); /* also disable interrupts; errormask is sometimes overwriten */ ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL); - ipath_cancel_sends(dd, 1); - - /* clear the freeze, and be sure chip saw it */ + /* + * clear all sends, because they have may been + * completed by usercode while in freeze mode, and + * therefore would not be sent, and eventually + * might cause the process to run out of bufs + */ + ipath_cancel_sends(dd, 0); ipath_write_kreg(dd, dd->ipath_kregs->kr_control, dd->ipath_control); - ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - /* force in-memory update now we are out of freeze */ + /* ensure pio avail updates continue */ ipath_force_pio_avail_update(dd); + /* + * We just enabled pioavailupdate, so dma copy is almost certainly + * not yet right, so read the registers directly. Similar to init + */ + for (i = 0; i < dd->ipath_pioavregs; i++) { + /* deal with 6110 chip bug */ + im = (i > 3 && (dd->ipath_flags & IPATH_SWAP_PIOBUFS)) ? + i ^ 1 : i; + val = ipath_read_kreg64(dd, (0x1000 / sizeof(u64)) + im); + dd->ipath_pioavailregs_dma[i] = cpu_to_le64(val); + dd->ipath_pioavailshadow[i] = val | + (~dd->ipath_pioavailkernel[i] << + INFINIPATH_SENDPIOAVAIL_BUSY_SHIFT); + } + /* * force new interrupt if any hwerr, error or interrupt bits are * still set, and clear "safe" send packet errors related to freeze @@ -1258,8 +1312,10 @@ irqreturn_t ipath_intr(int irq, void *data) ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); - /* always process; sdma verbs uses PIO for acks and VL15 */ - handle_layer_pioavail(dd); + if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA)) + handle_layer_pioavail(dd); + else + ipath_dbg("unexpected BUFAVAIL intr\n"); } ret = IRQ_HANDLED; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h index 02b24a340599..202337ae90dc 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -117,10 +117,6 @@ struct ipath_portdata { u16 port_subport_cnt; /* non-zero if port is being shared. */ u16 port_subport_id; - /* number of pio bufs for this port (all procs, if shared) */ - u32 port_piocnt; - /* first pio buffer for this port */ - u32 port_pio_base; /* chip offset of PIO buffers for this port */ u32 port_piobufs; /* how many alloc_pages() chunks in port_rcvegrbuf_pages */ @@ -388,8 +384,6 @@ struct ipath_devdata { u32 ipath_lastrpkts; /* pio bufs allocated per port */ u32 ipath_pbufsport; - /* if remainder on bufs/port, ports < extrabuf get 1 extra */ - u32 ipath_ports_extrabuf; u32 ipath_pioupd_thresh; /* update threshold, some chips */ /* * number of ports configured as max; zero is set to number chip @@ -1017,7 +1011,7 @@ void ipath_get_eeprom_info(struct ipath_devdata *); int ipath_update_eeprom_log(struct ipath_devdata *dd); void ipath_inc_eeprom_err(struct ipath_devdata *dd, u32 eidx, u32 incr); u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg); -void ipath_disarm_senderrbufs(struct ipath_devdata *); +void ipath_disarm_senderrbufs(struct ipath_devdata *, int); void ipath_force_pio_avail_update(struct ipath_devdata *); void signal_ib_event(struct ipath_devdata *dd, enum ib_event_type ev); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_rc.c b/trunk/drivers/infiniband/hw/ipath/ipath_rc.c index 08b11b567614..c405dfba5531 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_rc.c @@ -1746,11 +1746,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, qp->r_wrid_valid = 0; wc.wr_id = qp->r_wr_id; wc.status = IB_WC_SUCCESS; - if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) || - opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) - wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; - else - wc.opcode = IB_WC_RECV; + wc.opcode = IB_WC_RECV; wc.vendor_err = 0; wc.qp = &qp->ibqp; wc.src_qp = qp->remote_qpn; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_ruc.c b/trunk/drivers/infiniband/hw/ipath/ipath_ruc.c index 9e3fe61cbd08..8ac5c1d82ccd 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_ruc.c @@ -481,10 +481,9 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp) wake_up(&qp->wait); } -static void want_buffer(struct ipath_devdata *dd, struct ipath_qp *qp) +static void want_buffer(struct ipath_devdata *dd) { - if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA) || - qp->ibqp.qp_type == IB_QPT_SMI) { + if (!(dd->ipath_flags & IPATH_HAS_SEND_DMA)) { unsigned long flags; spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); @@ -520,7 +519,7 @@ static void ipath_no_bufs_available(struct ipath_qp *qp, spin_lock_irqsave(&dev->pending_lock, flags); list_add_tail(&qp->piowait, &dev->piowait); spin_unlock_irqrestore(&dev->pending_lock, flags); - want_buffer(dev->dd, qp); + want_buffer(dev->dd); dev->n_piowait++; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c b/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c index 3697449c1ba4..1974df7a9f78 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -308,15 +308,13 @@ static void sdma_abort_task(unsigned long opaque) spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags); /* - * Don't restart sdma here (with the exception - * below). Wait until link is up to ACTIVE. VL15 MADs - * used to bring the link up use PIO, and multiple link - * transitions otherwise cause the sdma engine to be + * Don't restart sdma here. Wait until link is up to ACTIVE. + * VL15 MADs used to bring the link up use PIO, and multiple + * link transitions otherwise cause the sdma engine to be * stopped and started multiple times. - * The disable is done here, including the shadow, - * so the state is kept consistent. - * See ipath_restart_sdma() for the actual starting - * of sdma. + * The disable is done here, including the shadow, so the + * state is kept consistent. + * See ipath_restart_sdma() for the actual starting of sdma. */ spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); dd->ipath_sendctrl &= ~INFINIPATH_S_SDMAENABLE; @@ -328,13 +326,6 @@ static void sdma_abort_task(unsigned long opaque) /* make sure I see next message */ dd->ipath_sdma_abort_jiffies = 0; - /* - * Not everything that takes SDMA offline is a link - * status change. If the link was up, restart SDMA. - */ - if (dd->ipath_flags & IPATH_LINKACTIVE) - ipath_restart_sdma(dd); - goto done; } @@ -436,12 +427,7 @@ int setup_sdma(struct ipath_devdata *dd) goto done; } - /* - * Set initial status as if we had been up, then gone down. - * This lets initial start on transition to ACTIVE be the - * same as restart after link flap. - */ - dd->ipath_sdma_status = IPATH_SDMA_ABORT_ABORTED; + dd->ipath_sdma_status = 0; dd->ipath_sdma_abort_jiffies = 0; dd->ipath_sdma_generation = 0; dd->ipath_sdma_descq_tail = 0; @@ -463,19 +449,16 @@ int setup_sdma(struct ipath_devdata *dd) ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmaheadaddr, dd->ipath_sdma_head_phys); - /* - * Reserve all the former "kernel" piobufs, using high number range - * so we get as many 4K buffers as possible - */ - n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; - i = dd->ipath_lastport_piobuf + dd->ipath_pioreserved; - ipath_chg_pioavailkernel(dd, i, n - i , 0); - for (; i < n; ++i) { + /* Reserve all the former "kernel" piobufs */ + n = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - dd->ipath_pioreserved; + for (i = dd->ipath_lastport_piobuf; i < n; ++i) { unsigned word = i / 64; unsigned bit = i & 63; BUG_ON(word >= 3); senddmabufmask[word] |= 1ULL << bit; } + ipath_chg_pioavailkernel(dd, dd->ipath_lastport_piobuf, + n - dd->ipath_lastport_piobuf, 0); ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask0, senddmabufmask[0]); ipath_write_kreg(dd, dd->ipath_kregs->kr_senddmabufmask1, @@ -632,9 +615,6 @@ void ipath_restart_sdma(struct ipath_devdata *dd) ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); - /* notify upper layers */ - ipath_ib_piobufavail(dd->verbs_dev); - bail: return; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c index 5015cd2e57bd..e63927cce5b5 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -396,6 +396,7 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) wqe = get_swqe_ptr(qp, qp->s_head); wqe->wr = *wr; + wqe->ssn = qp->s_ssn++; wqe->length = 0; if (wr->num_sge) { acc = wr->opcode >= IB_WR_RDMA_READ ? @@ -421,7 +422,6 @@ static int ipath_post_one_send(struct ipath_qp *qp, struct ib_send_wr *wr) goto bail_inval; } else if (wqe->length > to_idev(qp->ibqp.device)->dd->ipath_ibmtu) goto bail_inval; - wqe->ssn = qp->s_ssn++; qp->s_head = next; ret = 0; diff --git a/trunk/drivers/infiniband/hw/mlx4/cq.c b/trunk/drivers/infiniband/hw/mlx4/cq.c index 4521319b1406..2f199c5c4a72 100644 --- a/trunk/drivers/infiniband/hw/mlx4/cq.c +++ b/trunk/drivers/infiniband/hw/mlx4/cq.c @@ -246,7 +246,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector if (context) ib_umem_release(cq->umem); else - mlx4_ib_free_cq_buf(dev, &cq->buf, cq->ibcq.cqe); + mlx4_ib_free_cq_buf(dev, &cq->buf, entries); err_db: if (!context) @@ -434,7 +434,7 @@ int mlx4_ib_destroy_cq(struct ib_cq *cq) mlx4_ib_db_unmap_user(to_mucontext(cq->uobject->context), &mcq->db); ib_umem_release(mcq->umem); } else { - mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe); + mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe + 1); mlx4_db_free(dev->dev, &mcq->db); } diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index ca126fc2b853..9044f8803532 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -334,7 +334,6 @@ struct ipoib_dev_priv { #endif int hca_caps; struct ipoib_ethtool_st ethtool; - struct timer_list poll_timer; }; struct ipoib_ah { @@ -405,7 +404,6 @@ extern struct workqueue_struct *ipoib_workqueue; int ipoib_poll(struct napi_struct *napi, int budget); void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr); -void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr); struct ipoib_ah *ipoib_create_ah(struct net_device *dev, struct ib_pd *pd, struct ib_ah_attr *attr); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index f429bce24c20..97b815c1a3fc 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -461,26 +461,6 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) netif_rx_schedule(dev, &priv->napi); } -static void drain_tx_cq(struct net_device *dev) -{ - struct ipoib_dev_priv *priv = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&priv->tx_lock, flags); - while (poll_tx(priv)) - ; /* nothing */ - - if (netif_queue_stopped(dev)) - mod_timer(&priv->poll_timer, jiffies + 1); - - spin_unlock_irqrestore(&priv->tx_lock, flags); -} - -void ipoib_send_comp_handler(struct ib_cq *cq, void *dev_ptr) -{ - drain_tx_cq((struct net_device *)dev_ptr); -} - static inline int post_send(struct ipoib_dev_priv *priv, unsigned int wr_id, struct ib_ah *address, u32 qpn, @@ -575,22 +555,12 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, else priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; - if (++priv->tx_outstanding == ipoib_sendq_size) { - ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); - if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) - ipoib_warn(priv, "request notify on send CQ failed\n"); - netif_stop_queue(dev); - } - if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), address->ah, qpn, tx_req, phead, hlen))) { ipoib_warn(priv, "post_send failed\n"); ++dev->stats.tx_errors; - --priv->tx_outstanding; ipoib_dma_unmap_tx(priv->ca, tx_req); dev_kfree_skb_any(skb); - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); } else { dev->trans_start = jiffies; @@ -598,11 +568,14 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, ++priv->tx_head; skb_orphan(skb); + if (++priv->tx_outstanding == ipoib_sendq_size) { + ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); + netif_stop_queue(dev); + } } if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) - while (poll_tx(priv)) - ; /* nothing */ + poll_tx(priv); } static void __ipoib_reap_ah(struct net_device *dev) @@ -636,11 +609,6 @@ void ipoib_reap_ah(struct work_struct *work) round_jiffies_relative(HZ)); } -static void ipoib_ib_tx_timer_func(unsigned long ctx) -{ - drain_tx_cq((struct net_device *)ctx); -} - int ipoib_ib_dev_open(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); @@ -677,10 +645,6 @@ int ipoib_ib_dev_open(struct net_device *dev) queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task, round_jiffies_relative(HZ)); - init_timer(&priv->poll_timer); - priv->poll_timer.function = ipoib_ib_tx_timer_func; - priv->poll_timer.data = (unsigned long)dev; - set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); return 0; @@ -846,7 +810,6 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush) ipoib_dbg(priv, "All sends and receives done.\n"); timeout: - del_timer_sync(&priv->poll_timer); qp_attr.qp_state = IB_QPS_RESET; if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE)) ipoib_warn(priv, "Failed to modify QP to RESET state\n"); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 8766d29ce3b7..c1e7ece1fd44 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -187,8 +187,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) goto out_free_mr; } - priv->send_cq = ib_create_cq(priv->ca, ipoib_send_comp_handler, NULL, - dev, ipoib_sendq_size, 0); + priv->send_cq = ib_create_cq(priv->ca, NULL, NULL, dev, ipoib_sendq_size, 0); if (IS_ERR(priv->send_cq)) { printk(KERN_WARNING "%s: failed to create send CQ\n", ca->name); goto out_free_recv_cq; diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 3ad8bd9f7543..92b683411d5a 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -14,7 +14,7 @@ if INPUT_MISC config INPUT_PCSPKR tristate "PC Speaker support" - depends on PCSPKR_PLATFORM + depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES depends on SND_PCSP=n help Say Y here if you want the standard PC Speaker to be used for diff --git a/trunk/drivers/input/serio/hp_sdc.c b/trunk/drivers/input/serio/hp_sdc.c index edfedd9a166c..02b3ad8c0826 100644 --- a/trunk/drivers/input/serio/hp_sdc.c +++ b/trunk/drivers/input/serio/hp_sdc.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include 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/macintosh/adb.c b/trunk/drivers/macintosh/adb.c index b8b9e44f7f4e..20978205cd02 100644 --- a/trunk/drivers/macintosh/adb.c +++ b/trunk/drivers/macintosh/adb.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_PPC @@ -102,7 +102,7 @@ static struct adb_handler { } adb_handler[16]; /* - * The adb_handler_mutex mutex protects all accesses to the original_address + * The adb_handler_sem mutex protects all accesses to the original_address * and handler_id fields of adb_handler[i] for all i, and changes to the * handler field. * Accesses to the handler field are protected by the adb_handler_lock @@ -110,7 +110,7 @@ static struct adb_handler { * time adb_unregister returns, we know that the old handler isn't being * called. */ -static DEFINE_MUTEX(adb_handler_mutex); +static DECLARE_MUTEX(adb_handler_sem); static DEFINE_RWLOCK(adb_handler_lock); #if 0 @@ -355,7 +355,7 @@ do_adb_reset_bus(void) msleep(500); } - mutex_lock(&adb_handler_mutex); + down(&adb_handler_sem); write_lock_irq(&adb_handler_lock); memset(adb_handler, 0, sizeof(adb_handler)); write_unlock_irq(&adb_handler_lock); @@ -376,7 +376,7 @@ do_adb_reset_bus(void) if (adb_controller->autopoll) adb_controller->autopoll(autopoll_devs); } - mutex_unlock(&adb_handler_mutex); + up(&adb_handler_sem); blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL); @@ -454,7 +454,7 @@ adb_register(int default_id, int handler_id, struct adb_ids *ids, { int i; - mutex_lock(&adb_handler_mutex); + down(&adb_handler_sem); ids->nids = 0; for (i = 1; i < 16; i++) { if ((adb_handler[i].original_address == default_id) && @@ -472,7 +472,7 @@ adb_register(int default_id, int handler_id, struct adb_ids *ids, ids->id[ids->nids++] = i; } } - mutex_unlock(&adb_handler_mutex); + up(&adb_handler_sem); return ids->nids; } @@ -481,7 +481,7 @@ adb_unregister(int index) { int ret = -ENODEV; - mutex_lock(&adb_handler_mutex); + down(&adb_handler_sem); write_lock_irq(&adb_handler_lock); if (adb_handler[index].handler) { while(adb_handler[index].busy) { @@ -493,7 +493,7 @@ adb_unregister(int index) adb_handler[index].handler = NULL; } write_unlock_irq(&adb_handler_lock); - mutex_unlock(&adb_handler_mutex); + up(&adb_handler_sem); return ret; } @@ -557,19 +557,19 @@ adb_try_handler_change(int address, int new_id) { int ret; - mutex_lock(&adb_handler_mutex); + down(&adb_handler_sem); ret = try_handler_change(address, new_id); - mutex_unlock(&adb_handler_mutex); + up(&adb_handler_sem); return ret; } int adb_get_infos(int address, int *original_address, int *handler_id) { - mutex_lock(&adb_handler_mutex); + down(&adb_handler_sem); *original_address = adb_handler[address].original_address; *handler_id = adb_handler[address].handler_id; - mutex_unlock(&adb_handler_mutex); + up(&adb_handler_sem); return (*original_address != 0); } @@ -628,10 +628,10 @@ do_adb_query(struct adb_request *req) case ADB_QUERY_GETDEVINFO: if (req->nbytes < 3) break; - mutex_lock(&adb_handler_mutex); + down(&adb_handler_sem); req->reply[0] = adb_handler[req->data[2]].original_address; req->reply[1] = adb_handler[req->data[2]].handler_id; - mutex_unlock(&adb_handler_mutex); + up(&adb_handler_sem); req->complete = 1; req->reply_len = 2; adb_write_done(req); diff --git a/trunk/drivers/macintosh/therm_pm72.c b/trunk/drivers/macintosh/therm_pm72.c index ddfb426a9abd..1e0a69a5e815 100644 --- a/trunk/drivers/macintosh/therm_pm72.c +++ b/trunk/drivers/macintosh/therm_pm72.c @@ -122,7 +122,6 @@ #include #include #include -#include #include #include #include @@ -170,7 +169,7 @@ static int rackmac; static s32 dimm_output_clamp; static int fcu_rpm_shift; static int fcu_tickle_ticks; -static DEFINE_MUTEX(driver_lock); +static DECLARE_MUTEX(driver_lock); /* * We have 3 types of CPU PID control. One is "split" old style control @@ -730,9 +729,9 @@ static void fetch_cpu_pumps_minmax(void) static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ { \ ssize_t r; \ - mutex_lock(&driver_lock); \ + down(&driver_lock); \ r = sprintf(buf, "%d.%03d", FIX32TOPRINT(data)); \ - mutex_unlock(&driver_lock); \ + up(&driver_lock); \ return r; \ } #define BUILD_SHOW_FUNC_INT(name, data) \ @@ -1804,11 +1803,11 @@ static int main_control_loop(void *x) { DBG("main_control_loop started\n"); - mutex_lock(&driver_lock); + down(&driver_lock); if (start_fcu() < 0) { printk(KERN_ERR "kfand: failed to start FCU\n"); - mutex_unlock(&driver_lock); + up(&driver_lock); goto out; } @@ -1823,14 +1822,14 @@ static int main_control_loop(void *x) fcu_tickle_ticks = FCU_TICKLE_TICKS; - mutex_unlock(&driver_lock); + up(&driver_lock); while (state == state_attached) { unsigned long elapsed, start; start = jiffies; - mutex_lock(&driver_lock); + down(&driver_lock); /* Tickle the FCU just in case */ if (--fcu_tickle_ticks < 0) { @@ -1862,7 +1861,7 @@ static int main_control_loop(void *x) do_monitor_slots(&slots_state); else do_monitor_drives(&drives_state); - mutex_unlock(&driver_lock); + up(&driver_lock); if (critical_state == 1) { printk(KERN_WARNING "Temperature control detected a critical condition\n"); @@ -2020,13 +2019,13 @@ static void detach_fcu(void) */ static int therm_pm72_attach(struct i2c_adapter *adapter) { - mutex_lock(&driver_lock); + down(&driver_lock); /* Check state */ if (state == state_detached) state = state_attaching; if (state != state_attaching) { - mutex_unlock(&driver_lock); + up(&driver_lock); return 0; } @@ -2055,7 +2054,7 @@ static int therm_pm72_attach(struct i2c_adapter *adapter) state = state_attached; start_control_loops(); } - mutex_unlock(&driver_lock); + up(&driver_lock); return 0; } @@ -2066,16 +2065,16 @@ static int therm_pm72_attach(struct i2c_adapter *adapter) */ static int therm_pm72_detach(struct i2c_adapter *adapter) { - mutex_lock(&driver_lock); + down(&driver_lock); if (state != state_detached) state = state_detaching; /* Stop control loops if any */ DBG("stopping control loops\n"); - mutex_unlock(&driver_lock); + up(&driver_lock); stop_control_loops(); - mutex_lock(&driver_lock); + down(&driver_lock); if (u3_0 != NULL && !strcmp(adapter->name, "u3 0")) { DBG("lost U3-0, disposing control loops\n"); @@ -2091,7 +2090,7 @@ static int therm_pm72_detach(struct i2c_adapter *adapter) if (u3_0 == NULL && u3_1 == NULL) state = state_detached; - mutex_unlock(&driver_lock); + up(&driver_lock); return 0; } diff --git a/trunk/drivers/macintosh/windfarm_smu_sat.c b/trunk/drivers/macintosh/windfarm_smu_sat.c index 7f2be4baaeda..797918d0e59c 100644 --- a/trunk/drivers/macintosh/windfarm_smu_sat.c +++ b/trunk/drivers/macintosh/windfarm_smu_sat.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -36,7 +36,7 @@ struct wf_sat { int nr; atomic_t refcnt; - struct mutex mutex; + struct semaphore mutex; unsigned long last_read; /* jiffies when cache last updated */ u8 cache[16]; struct i2c_client i2c; @@ -163,7 +163,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value) if (sat->i2c.adapter == NULL) return -ENODEV; - mutex_lock(&sat->mutex); + down(&sat->mutex); if (time_after(jiffies, (sat->last_read + MAX_AGE))) { err = wf_sat_read_cache(sat); if (err) @@ -182,7 +182,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value) err = 0; fail: - mutex_unlock(&sat->mutex); + up(&sat->mutex); return err; } @@ -233,7 +233,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) sat->nr = -1; sat->node = of_node_get(dev); atomic_set(&sat->refcnt, 0); - mutex_init(&sat->mutex); + init_MUTEX(&sat->mutex); sat->i2c.addr = (addr >> 1) & 0x7f; sat->i2c.adapter = adapter; sat->i2c.driver = &wf_sat_driver; diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index faf3d8912979..5938fa962922 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -886,7 +886,7 @@ static int make_request(struct request_queue *q, struct bio * bio) */ raid10_find_phys(conf, r10_bio); retry_write: - blocked_rdev = NULL; + blocked_rdev = 0; rcu_read_lock(); for (i = 0; i < conf->copies; i++) { int d = r10_bio->devs[i].devnum; diff --git a/trunk/drivers/media/Makefile b/trunk/drivers/media/Makefile index cc11c4c0e7e7..73f742c7e818 100644 --- a/trunk/drivers/media/Makefile +++ b/trunk/drivers/media/Makefile @@ -2,8 +2,6 @@ # Makefile for the kernel multimedia device drivers. # -obj-y := common/ - obj-$(CONFIG_VIDEO_MEDIA) += common/ # Since hybrid devices are here, should be compiled if DVB and/or V4L diff --git a/trunk/drivers/media/video/cx18/cx18-driver.c b/trunk/drivers/media/video/cx18/cx18-driver.c index 3f55d47bc4b9..8f5ed9b4bf83 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.c +++ b/trunk/drivers/media/video/cx18/cx18-driver.c @@ -613,7 +613,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, } cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); - if (!cx) { + if (cx == 0) { spin_unlock(&cx18_cards_lock); return -ENOMEM; } diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index 48e1a01718ec..a0baf2d0ba7f 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -1634,7 +1634,7 @@ static int saa7134_s_fmt_overlay(struct file *file, void *priv, struct saa7134_fh *fh = priv; struct saa7134_dev *dev = fh->dev; int err; - unsigned long flags; + unsigned int flags; if (saa7134_no_overlay > 0) { printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); diff --git a/trunk/drivers/misc/kgdbts.c b/trunk/drivers/misc/kgdbts.c index fa394104339c..30a1af857c7a 100644 --- a/trunk/drivers/misc/kgdbts.c +++ b/trunk/drivers/misc/kgdbts.c @@ -47,7 +47,6 @@ * to test the HW NMI watchdog * F## = Break at do_fork for ## iterations * S## = Break at sys_open for ## iterations - * I## = Run the single step test ## iterations * * NOTE: that the do_fork and sys_open tests are mutually exclusive. * @@ -376,7 +375,7 @@ static void emul_sstep_get(char *arg) break; case 1: /* set breakpoint */ - break_helper("Z0", NULL, sstep_addr); + break_helper("Z0", 0, sstep_addr); break; case 2: /* Continue */ @@ -384,7 +383,7 @@ static void emul_sstep_get(char *arg) break; case 3: /* Clear breakpoint */ - break_helper("z0", NULL, sstep_addr); + break_helper("z0", 0, sstep_addr); break; default: eprintk("kgdbts: ERROR failed sstep get emulation\n"); @@ -466,11 +465,11 @@ static struct test_struct sw_breakpoint_test[] = { { "?", "S0*" }, /* Clear break points */ { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ { "c", "T0*", }, /* Continue */ - { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, + { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, { "write", "OK", write_regs }, { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ { "D", "OK" }, /* Detach */ - { "D", "OK", NULL, got_break }, /* On success we made it here */ + { "D", "OK", 0, got_break }, /* If the test worked we made it here */ { "", "" }, }; @@ -500,14 +499,14 @@ static struct test_struct singlestep_break_test[] = { { "?", "S0*" }, /* Clear break points */ { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ { "c", "T0*", }, /* Continue */ - { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, + { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, { "write", "OK", write_regs }, /* Write registers */ { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ - { "g", "kgdbts_break_test", NULL, check_single_step }, + { "g", "kgdbts_break_test", 0, check_single_step }, { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ { "c", "T0*", }, /* Continue */ - { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, + { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, { "write", "OK", write_regs }, /* Write registers */ { "D", "OK" }, /* Remove all breakpoints and continues */ { "", "" }, @@ -521,14 +520,14 @@ static struct test_struct do_fork_test[] = { { "?", "S0*" }, /* Clear break points */ { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ { "c", "T0*", }, /* Continue */ - { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */ + { "g", "do_fork", 0, check_and_rewind_pc }, /* check location */ { "write", "OK", write_regs }, /* Write registers */ { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ - { "g", "do_fork", NULL, check_single_step }, + { "g", "do_fork", 0, check_single_step }, { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ - { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ + { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */ { "", "" }, }; @@ -539,14 +538,14 @@ static struct test_struct sys_open_test[] = { { "?", "S0*" }, /* Clear break points */ { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ { "c", "T0*", }, /* Continue */ - { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */ + { "g", "sys_open", 0, check_and_rewind_pc }, /* check location */ { "write", "OK", write_regs }, /* Write registers */ { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ - { "g", "sys_open", NULL, check_single_step }, + { "g", "sys_open", 0, check_single_step }, { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ - { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ + { "D", "OK", 0, final_ack_set }, /* detach and unregister I/O */ { "", "" }, }; @@ -557,11 +556,11 @@ static struct test_struct hw_breakpoint_test[] = { { "?", "S0*" }, /* Clear break points */ { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */ { "c", "T0*", }, /* Continue */ - { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, + { "g", "kgdbts_break_test", 0, check_and_rewind_pc }, { "write", "OK", write_regs }, { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */ { "D", "OK" }, /* Detach */ - { "D", "OK", NULL, got_break }, /* On success we made it here */ + { "D", "OK", 0, got_break }, /* If the test worked we made it here */ { "", "" }, }; @@ -571,12 +570,12 @@ static struct test_struct hw_breakpoint_test[] = { static struct test_struct hw_write_break_test[] = { { "?", "S0*" }, /* Clear break points */ { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */ - { "c", "T0*", NULL, got_break }, /* Continue */ - { "g", "silent", NULL, check_and_rewind_pc }, + { "c", "T0*", 0, got_break }, /* Continue */ + { "g", "silent", 0, check_and_rewind_pc }, { "write", "OK", write_regs }, { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */ { "D", "OK" }, /* Detach */ - { "D", "OK", NULL, got_break }, /* On success we made it here */ + { "D", "OK", 0, got_break }, /* If the test worked we made it here */ { "", "" }, }; @@ -586,12 +585,12 @@ static struct test_struct hw_write_break_test[] = { static struct test_struct hw_access_break_test[] = { { "?", "S0*" }, /* Clear break points */ { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */ - { "c", "T0*", NULL, got_break }, /* Continue */ - { "g", "silent", NULL, check_and_rewind_pc }, + { "c", "T0*", 0, got_break }, /* Continue */ + { "g", "silent", 0, check_and_rewind_pc }, { "write", "OK", write_regs }, { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */ { "D", "OK" }, /* Detach */ - { "D", "OK", NULL, got_break }, /* On success we made it here */ + { "D", "OK", 0, got_break }, /* If the test worked we made it here */ { "", "" }, }; @@ -600,9 +599,9 @@ static struct test_struct hw_access_break_test[] = { */ static struct test_struct nmi_sleep_test[] = { { "?", "S0*" }, /* Clear break points */ - { "c", "T0*", NULL, got_break }, /* Continue */ + { "c", "T0*", 0, got_break }, /* Continue */ { "D", "OK" }, /* Detach */ - { "D", "OK", NULL, got_break }, /* On success we made it here */ + { "D", "OK", 0, got_break }, /* If the test worked we made it here */ { "", "" }, }; @@ -875,23 +874,18 @@ static void kgdbts_run_tests(void) { char *ptr; int fork_test = 0; - int do_sys_open_test = 0; - int sstep_test = 1000; + int sys_open_test = 0; int nmi_sleep = 0; - int i; ptr = strstr(config, "F"); if (ptr) - fork_test = simple_strtol(ptr + 1, NULL, 10); + fork_test = simple_strtol(ptr+1, NULL, 10); ptr = strstr(config, "S"); if (ptr) - do_sys_open_test = simple_strtol(ptr + 1, NULL, 10); + sys_open_test = simple_strtol(ptr+1, NULL, 10); ptr = strstr(config, "N"); if (ptr) nmi_sleep = simple_strtol(ptr+1, NULL, 10); - ptr = strstr(config, "I"); - if (ptr) - sstep_test = simple_strtol(ptr+1, NULL, 10); /* required internal KGDB tests */ v1printk("kgdbts:RUN plant and detach test\n"); @@ -900,13 +894,8 @@ static void kgdbts_run_tests(void) run_breakpoint_test(0); v1printk("kgdbts:RUN bad memory access test\n"); run_bad_read_test(); - v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test); - for (i = 0; i < sstep_test; i++) { - run_singlestep_break_test(); - if (i % 100 == 0) - v1printk("kgdbts:RUN singlestep [%i/%i]\n", - i, sstep_test); - } + v1printk("kgdbts:RUN singlestep breakpoint test\n"); + run_singlestep_break_test(); /* ===Optional tests=== */ @@ -933,7 +922,7 @@ static void kgdbts_run_tests(void) repeat_test = fork_test; printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n", repeat_test); - kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); + kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg"); run_do_fork_test(); return; } @@ -942,11 +931,11 @@ static void kgdbts_run_tests(void) * executed because a kernel thread will be spawned at the very * end to unregister the debug hooks. */ - if (do_sys_open_test) { - repeat_test = do_sys_open_test; + if (sys_open_test) { + repeat_test = sys_open_test; printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n", repeat_test); - kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg"); + kthread_run(kgdbts_unreg_thread, 0, "kgdbts_unreg"); run_sys_open_test(); return; } 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/fec_mpc52xx.c b/trunk/drivers/net/fec_mpc52xx.c index 5f9c42e7a7f1..d21b7ab64bd1 100644 --- a/trunk/drivers/net/fec_mpc52xx.c +++ b/trunk/drivers/net/fec_mpc52xx.c @@ -43,29 +43,6 @@ #define DRIVER_NAME "mpc52xx-fec" -#define FEC5200_PHYADDR_NONE (-1) -#define FEC5200_PHYADDR_7WIRE (-2) - -/* Private driver data structure */ -struct mpc52xx_fec_priv { - int duplex; - int speed; - int r_irq; - int t_irq; - struct mpc52xx_fec __iomem *fec; - struct bcom_task *rx_dmatsk; - struct bcom_task *tx_dmatsk; - spinlock_t lock; - int msg_enable; - - /* MDIO link details */ - int phy_addr; - unsigned int phy_speed; - struct phy_device *phydev; - enum phy_state link; -}; - - static irqreturn_t mpc52xx_fec_interrupt(int, void *); static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *); static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *); @@ -246,7 +223,7 @@ static int mpc52xx_fec_phy_start(struct net_device *dev) struct mpc52xx_fec_priv *priv = netdev_priv(dev); int err; - if (priv->phy_addr < 0) + if (!priv->has_phy) return 0; err = mpc52xx_fec_init_phy(dev); @@ -266,7 +243,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) { struct mpc52xx_fec_priv *priv = netdev_priv(dev); - if (!priv->phydev) + if (!priv->has_phy) return; phy_disconnect(priv->phydev); @@ -278,7 +255,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv, struct mii_ioctl_data *mii_data, int cmd) { - if (!priv->phydev) + if (!priv->has_phy) return -ENOTSUPP; return phy_mii_ioctl(priv->phydev, mii_data, cmd); @@ -288,7 +265,7 @@ static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv) { struct mpc52xx_fec __iomem *fec = priv->fec; - if (priv->phydev) + if (!priv->has_phy) return; out_be32(&fec->mii_speed, priv->phy_speed); @@ -727,7 +704,7 @@ static void mpc52xx_fec_start(struct net_device *dev) rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ rcntrl |= FEC_RCNTRL_FCE; - if (priv->phy_addr != FEC5200_PHYADDR_7WIRE) + if (priv->has_phy) rcntrl |= FEC_RCNTRL_MII_MODE; if (priv->duplex == DUPLEX_FULL) @@ -887,10 +864,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) struct net_device *ndev; struct mpc52xx_fec_priv *priv = NULL; struct resource mem; - struct device_node *phy_node; - const phandle *phy_handle; - const u32 *prop; - int prop_size; + const phandle *ph; phys_addr_t rx_fifo; phys_addr_t tx_fifo; @@ -974,37 +948,26 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT); + priv->duplex = DUPLEX_FULL; - /* - * Link mode configuration - */ + /* is the phy present in device tree? */ + ph = of_get_property(op->node, "phy-handle", NULL); + if (ph) { + const unsigned int *prop; + struct device_node *phy_dn; + priv->has_phy = 1; - /* Start with safe defaults for link connection */ - priv->phy_addr = FEC5200_PHYADDR_NONE; - priv->speed = 100; - priv->duplex = DUPLEX_HALF; - priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; - - /* the 7-wire property means don't use MII mode */ - if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) - priv->phy_addr = FEC5200_PHYADDR_7WIRE; - - /* The current speed preconfigures the speed of the MII link */ - prop = of_get_property(op->node, "current-speed", &prop_size); - if (prop && (prop_size >= sizeof(u32) * 2)) { - priv->speed = prop[0]; - priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; - } + phy_dn = of_find_node_by_phandle(*ph); + prop = of_get_property(phy_dn, "reg", NULL); + priv->phy_addr = *prop; + + of_node_put(phy_dn); - /* If there is a phy handle, setup link to that phy */ - phy_handle = of_get_property(op->node, "phy-handle", &prop_size); - if (phy_handle && (prop_size >= sizeof(phandle))) { - phy_node = of_find_node_by_phandle(*phy_handle); - prop = of_get_property(phy_node, "reg", &prop_size); - if (prop && (prop_size >= sizeof(u32))) - if ((*prop >= 0) && (*prop < PHY_MAX_ADDR)) - priv->phy_addr = *prop; - of_node_put(phy_node); + /* Phy speed */ + priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; + } else { + dev_info(&ndev->dev, "can't find \"phy-handle\" in device" + " tree, using 7-wire mode\n"); } /* Hardware init */ @@ -1019,20 +982,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) if (rv < 0) goto probe_error; - /* Now report the link setup */ - switch (priv->phy_addr) { - case FEC5200_PHYADDR_NONE: - dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n", - priv->speed, priv->duplex ? 'F' : 'H'); - break; - case FEC5200_PHYADDR_7WIRE: - dev_info(&ndev->dev, "using 7-wire PHY mode\n"); - break; - default: - dev_info(&ndev->dev, "Using PHY at MDIO address %i\n", - priv->phy_addr); - } - /* We're done ! */ dev_set_drvdata(&op->dev, ndev); diff --git a/trunk/drivers/net/fec_mpc52xx.h b/trunk/drivers/net/fec_mpc52xx.h index a227a525bdbb..8b1f75397b9a 100644 --- a/trunk/drivers/net/fec_mpc52xx.h +++ b/trunk/drivers/net/fec_mpc52xx.h @@ -26,6 +26,25 @@ #define FEC_WATCHDOG_TIMEOUT ((400*HZ)/1000) +struct mpc52xx_fec_priv { + int duplex; + int r_irq; + int t_irq; + struct mpc52xx_fec __iomem *fec; + struct bcom_task *rx_dmatsk; + struct bcom_task *tx_dmatsk; + spinlock_t lock; + int msg_enable; + + int has_phy; + unsigned int phy_speed; + unsigned int phy_addr; + struct phy_device *phydev; + enum phy_state link; + int speed; +}; + + /* ======================================================================== */ /* Hardware register sets & bits */ /* ======================================================================== */ diff --git a/trunk/drivers/net/mlx4/mr.c b/trunk/drivers/net/mlx4/mr.c index 03a9abcce524..cb46446b2691 100644 --- a/trunk/drivers/net/mlx4/mr.c +++ b/trunk/drivers/net/mlx4/mr.c @@ -551,7 +551,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, u64 mtt_seg; int err = -ENOMEM; - if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) + if (page_shift < 12 || page_shift >= 32) return -EINVAL; /* All MTTs must fit in the same page */ diff --git a/trunk/drivers/net/usb/asix.c b/trunk/drivers/net/usb/asix.c index dc6f097062df..6f245cfb6624 100644 --- a/trunk/drivers/net/usb/asix.c +++ b/trunk/drivers/net/usb/asix.c @@ -1380,10 +1380,6 @@ static const struct usb_device_id products [] = { // Buffalo LUA-U2-KTX USB_DEVICE (0x0411, 0x003d), .driver_info = (unsigned long) &ax8817x_info, -}, { - // Buffalo LUA-U2-GT 10/100/1000 - USB_DEVICE (0x0411, 0x006e), - .driver_info = (unsigned long) &ax88178_info, }, { // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" USB_DEVICE (0x6189, 0x182d), 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/pci/probe.c b/trunk/drivers/pci/probe.c index 3706ce7972dd..4a55bf380957 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -842,26 +842,14 @@ static void set_pcie_port_type(struct pci_dev *pdev) * reading the dword at 0x100 which must either be 0 or a valid extended * capability header. */ -int pci_cfg_space_size_ext(struct pci_dev *dev) -{ - u32 status; - - if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) - goto fail; - if (status == 0xffffffff) - goto fail; - - return PCI_CFG_SPACE_EXP_SIZE; - - fail: - return PCI_CFG_SPACE_SIZE; -} - -int pci_cfg_space_size(struct pci_dev *dev) +int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix) { int pos; u32 status; + if (!check_exp_pcix) + goto skip; + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); if (!pos) { pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); @@ -873,12 +861,23 @@ int pci_cfg_space_size(struct pci_dev *dev) goto fail; } - return pci_cfg_space_size_ext(dev); + skip: + if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) + goto fail; + if (status == 0xffffffff) + goto fail; + + return PCI_CFG_SPACE_EXP_SIZE; fail: return PCI_CFG_SPACE_SIZE; } +int pci_cfg_space_size(struct pci_dev *dev) +{ + return pci_cfg_space_size_ext(dev, 1); +} + static void pci_release_bus_bridge_dev(struct device *dev) { kfree(dev); 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/power/pda_power.c b/trunk/drivers/power/pda_power.c index 82810b7bff9c..c8aa55b81fd8 100644 --- a/trunk/drivers/power/pda_power.c +++ b/trunk/drivers/power/pda_power.c @@ -209,12 +209,6 @@ static int pda_power_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; - if (pdata->init) { - ret = pdata->init(dev); - if (ret < 0) - goto init_failed; - } - update_status(); update_charger(); @@ -304,9 +298,6 @@ static int pda_power_probe(struct platform_device *pdev) if (pdata->is_ac_online) power_supply_unregister(&pda_psy_ac); ac_supply_failed: - if (pdata->exit) - pdata->exit(dev); -init_failed: wrongid: return ret; } @@ -327,8 +318,6 @@ static int pda_power_remove(struct platform_device *pdev) power_supply_unregister(&pda_psy_usb); if (pdata->is_ac_online) power_supply_unregister(&pda_psy_ac); - if (pdata->exit) - pdata->exit(dev); return 0; } diff --git a/trunk/drivers/power/pmu_battery.c b/trunk/drivers/power/pmu_battery.c index 9346a862f1f2..60a8cf3a0431 100644 --- a/trunk/drivers/power/pmu_battery.c +++ b/trunk/drivers/power/pmu_battery.c @@ -159,7 +159,7 @@ static int __init pmu_bat_init(void) if (!pbat) break; - sprintf(pbat->name, "PMU_battery_%d", i); + sprintf(pbat->name, "PMU battery %d", i); pbat->bat.name = pbat->name; pbat->bat.properties = pmu_bat_props; pbat->bat.num_properties = ARRAY_SIZE(pmu_bat_props); diff --git a/trunk/drivers/ps3/ps3-lpm.c b/trunk/drivers/ps3/ps3-lpm.c index 85edf945ab86..6c9592ce4996 100644 --- a/trunk/drivers/ps3/ps3-lpm.c +++ b/trunk/drivers/ps3/ps3-lpm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/ps3/ps3-sys-manager.c b/trunk/drivers/ps3/ps3-sys-manager.c index f17513dd9d4b..7605453b74fd 100644 --- a/trunk/drivers/ps3/ps3-sys-manager.c +++ b/trunk/drivers/ps3/ps3-sys-manager.c @@ -184,7 +184,10 @@ enum ps3_sys_manager_next_op { /** * enum ps3_sys_manager_wake_source - Next-op wakeup source (bit position mask). - * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button. + * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button, IR + * controller, and bluetooth controller. + * @PS3_SM_WAKE_RTC: + * @PS3_SM_WAKE_RTC_ERROR: * @PS3_SM_WAKE_W_O_L: Ether or wireless LAN. * @PS3_SM_WAKE_P_O_R: Power on reset. * @@ -197,6 +200,8 @@ enum ps3_sys_manager_next_op { enum ps3_sys_manager_wake_source { /* version 3 */ PS3_SM_WAKE_DEFAULT = 0, + PS3_SM_WAKE_RTC = 0x00000040, + PS3_SM_WAKE_RTC_ERROR = 0x00000080, PS3_SM_WAKE_W_O_L = 0x00000400, PS3_SM_WAKE_P_O_R = 0x80000000, }; diff --git a/trunk/drivers/rtc/rtc-ds1511.c b/trunk/drivers/rtc/rtc-ds1511.c index 0f0d27d1c4ca..a83a40b3ebaa 100644 --- a/trunk/drivers/rtc/rtc-ds1511.c +++ b/trunk/drivers/rtc/rtc-ds1511.c @@ -184,7 +184,7 @@ ds1511_wdog_disable(void) static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) { u8 mon, day, dow, hrs, min, sec, yrs, cen; - unsigned long flags; + unsigned int flags; /* * won't have to change this for a while @@ -247,7 +247,7 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) { unsigned int century; - unsigned long flags; + unsigned int flags; spin_lock_irqsave(&ds1511_lock, flags); rtc_disable_update(); diff --git a/trunk/drivers/s390/char/tty3270.c b/trunk/drivers/s390/char/tty3270.c index 5043150019ac..c1f2adefad41 100644 --- a/trunk/drivers/s390/char/tty3270.c +++ b/trunk/drivers/s390/char/tty3270.c @@ -965,7 +965,8 @@ tty3270_write_room(struct tty_struct *tty) * Insert character into the screen at the current position with the * current color and highlight. This function does NOT do cursor movement. */ -static void tty3270_put_character(struct tty3270 *tp, char ch) +static int +tty3270_put_character(struct tty3270 *tp, char ch) { struct tty3270_line *line; struct tty3270_cell *cell; @@ -985,6 +986,7 @@ static void tty3270_put_character(struct tty3270 *tp, char ch) cell->character = tp->view.ascebc[(unsigned int) ch]; cell->highlight = tp->highlight; cell->f_color = tp->f_color; + return 1; } /* @@ -1610,15 +1612,16 @@ tty3270_write(struct tty_struct * tty, /* * Put single characters to the ttys character buffer */ -static int tty3270_put_char(struct tty_struct *tty, unsigned char ch) +static void +tty3270_put_char(struct tty_struct *tty, unsigned char ch) { struct tty3270 *tp; tp = tty->driver_data; - if (!tp || tp->char_count >= TTY3270_CHAR_BUF_SIZE) - return 0; - tp->char_buf[tp->char_count++] = ch; - return 1; + if (!tp) + return; + if (tp->char_count < TTY3270_CHAR_BUF_SIZE) + tp->char_buf[tp->char_count++] = ch; } /* diff --git a/trunk/drivers/s390/cio/blacklist.c b/trunk/drivers/s390/cio/blacklist.c index 9c21b8f43f9b..40ef948fcb3a 100644 --- a/trunk/drivers/s390/cio/blacklist.c +++ b/trunk/drivers/s390/cio/blacklist.c @@ -19,7 +19,6 @@ #include #include -#include #include "blacklist.h" #include "cio.h" @@ -44,169 +43,164 @@ typedef enum {add, free} range_action; * Function: blacklist_range * (Un-)blacklist the devices from-to */ -static int blacklist_range(range_action action, unsigned int from_ssid, - unsigned int to_ssid, unsigned int from, - unsigned int to, int msgtrigger) +static void +blacklist_range (range_action action, unsigned int from, unsigned int to, + unsigned int ssid) { - if ((from_ssid > to_ssid) || ((from_ssid == to_ssid) && (from > to))) { - if (msgtrigger) - printk(KERN_WARNING "cio: Invalid cio_ignore range " - "0.%x.%04x-0.%x.%04x\n", from_ssid, from, - to_ssid, to); - return 1; + if (!to) + to = from; + + if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) { + printk (KERN_WARNING "cio: Invalid blacklist range " + "0.%x.%04x to 0.%x.%04x, skipping\n", + ssid, from, ssid, to); + return; } - - while ((from_ssid < to_ssid) || ((from_ssid == to_ssid) && - (from <= to))) { + for (; from <= to; from++) { if (action == add) - set_bit(from, bl_dev[from_ssid]); + set_bit (from, bl_dev[ssid]); else - clear_bit(from, bl_dev[from_ssid]); - from++; - if (from > __MAX_SUBCHANNEL) { - from_ssid++; - from = 0; - } + clear_bit (from, bl_dev[ssid]); } - - return 0; } -static int pure_hex(char **cp, unsigned int *val, int min_digit, - int max_digit, int max_val) +/* + * Function: blacklist_busid + * Get devno/busid from given string. + * Shamelessly grabbed from dasd_devmap.c. + */ +static int +blacklist_busid(char **str, int *id0, int *ssid, int *devno) { - int diff; - unsigned int value; + int val, old_style; + char *sav; - diff = 0; - *val = 0; + sav = *str; - while (isxdigit(**cp) && (diff <= max_digit)) { - - if (isdigit(**cp)) - value = **cp - '0'; - else - value = tolower(**cp) - 'a' + 10; - *val = *val * 16 + value; - (*cp)++; - diff++; + /* check for leading '0x' */ + old_style = 0; + if ((*str)[0] == '0' && (*str)[1] == 'x') { + *str += 2; + old_style = 1; } - - if ((diff < min_digit) || (diff > max_digit) || (*val > max_val)) - return 1; - + if (!isxdigit((*str)[0])) /* We require at least one hex digit */ + goto confused; + val = simple_strtoul(*str, str, 16); + if (old_style || (*str)[0] != '.') { + *id0 = *ssid = 0; + if (val < 0 || val > 0xffff) + goto confused; + *devno = val; + if ((*str)[0] != ',' && (*str)[0] != '-' && + (*str)[0] != '\n' && (*str)[0] != '\0') + goto confused; + return 0; + } + /* New style x.y.z busid */ + if (val < 0 || val > 0xff) + goto confused; + *id0 = val; + (*str)++; + if (!isxdigit((*str)[0])) /* We require at least one hex digit */ + goto confused; + val = simple_strtoul(*str, str, 16); + if (val < 0 || val > 0xff || (*str)++[0] != '.') + goto confused; + *ssid = val; + if (!isxdigit((*str)[0])) /* We require at least one hex digit */ + goto confused; + val = simple_strtoul(*str, str, 16); + if (val < 0 || val > 0xffff) + goto confused; + *devno = val; + if ((*str)[0] != ',' && (*str)[0] != '-' && + (*str)[0] != '\n' && (*str)[0] != '\0') + goto confused; return 0; +confused: + strsep(str, ",\n"); + printk(KERN_WARNING "cio: Invalid cio_ignore parameter '%s'\n", sav); + return 1; } -static int parse_busid(char *str, int *cssid, int *ssid, int *devno, - int msgtrigger) +static int +blacklist_parse_parameters (char *str, range_action action) { - char *str_work; - int val, rc, ret; - - rc = 1; - - if (*str == '\0') - goto out; - - /* old style */ - str_work = str; - val = simple_strtoul(str, &str_work, 16); - - if (*str_work == '\0') { - if (val <= __MAX_SUBCHANNEL) { - *devno = val; - *ssid = 0; - *cssid = 0; - rc = 0; + int from, to, from_id0, to_id0, from_ssid, to_ssid; + + while (*str != 0 && *str != '\n') { + range_action ra = action; + while(*str == ',') + str++; + if (*str == '!') { + ra = !action; + ++str; } - goto out; - } - /* new style */ - str_work = str; - ret = pure_hex(&str_work, cssid, 1, 2, __MAX_CSSID); - if (ret || (str_work[0] != '.')) - goto out; - str_work++; - ret = pure_hex(&str_work, ssid, 1, 1, __MAX_SSID); - if (ret || (str_work[0] != '.')) - goto out; - str_work++; - ret = pure_hex(&str_work, devno, 4, 4, __MAX_SUBCHANNEL); - if (ret || (str_work[0] != '\0')) - goto out; - - rc = 0; -out: - if (rc && msgtrigger) - printk(KERN_WARNING "cio: Invalid cio_ignore device '%s'\n", - str); - - return rc; -} - -static int blacklist_parse_parameters(char *str, range_action action, - int msgtrigger) -{ - int from_cssid, to_cssid, from_ssid, to_ssid, from, to; - int rc, totalrc; - char *parm; - range_action ra; - - totalrc = 0; - - while ((parm = strsep(&str, ","))) { - rc = 0; - ra = action; - if (*parm == '!') { - if (ra == add) - ra = free; - else - ra = add; - parm++; - } - if (strcmp(parm, "all") == 0) { - from_cssid = 0; - from_ssid = 0; - from = 0; - to_cssid = __MAX_CSSID; - to_ssid = __MAX_SSID; - to = __MAX_SUBCHANNEL; + /* + * Since we have to parse the proc commands and the + * kernel arguments we have to check four cases + */ + if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 || + strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) { + int j; + + str += 3; + for (j=0; j <= __MAX_SSID; j++) + blacklist_range(ra, 0, __MAX_SUBCHANNEL, j); } else { - rc = parse_busid(strsep(&parm, "-"), &from_cssid, - &from_ssid, &from, msgtrigger); - if (!rc) { - if (parm != NULL) - rc = parse_busid(parm, &to_cssid, - &to_ssid, &to, - msgtrigger); - else { - to_cssid = from_cssid; - to_ssid = from_ssid; - to = from; - } + int rc; + + rc = blacklist_busid(&str, &from_id0, + &from_ssid, &from); + if (rc) + continue; + to = from; + to_id0 = from_id0; + to_ssid = from_ssid; + if (*str == '-') { + str++; + rc = blacklist_busid(&str, &to_id0, + &to_ssid, &to); + if (rc) + continue; } + if (*str == '-') { + printk(KERN_WARNING "cio: invalid cio_ignore " + "parameter '%s'\n", + strsep(&str, ",\n")); + continue; + } + if ((from_id0 != to_id0) || + (from_ssid != to_ssid)) { + printk(KERN_WARNING "cio: invalid cio_ignore " + "range %x.%x.%04x-%x.%x.%04x\n", + from_id0, from_ssid, from, + to_id0, to_ssid, to); + continue; + } + blacklist_range (ra, from, to, to_ssid); } - if (!rc) { - rc = blacklist_range(ra, from_ssid, to_ssid, from, to, - msgtrigger); - if (rc) - totalrc = 1; - } else - totalrc = 1; } - - return totalrc; + return 1; } +/* Parsing the commandline for blacklist parameters, e.g. to blacklist + * bus ids 0.0.1234, 0.0.1235 and 0.0.1236, you could use any of: + * - cio_ignore=1234-1236 + * - cio_ignore=0x1234-0x1235,1236 + * - cio_ignore=0x1234,1235-1236 + * - cio_ignore=1236 cio_ignore=1234-0x1236 + * - cio_ignore=1234 cio_ignore=1236 cio_ignore=0x1235 + * - cio_ignore=0.0.1234-0.0.1236 + * - cio_ignore=0.0.1234,0x1235,1236 + * - ... + */ static int __init blacklist_setup (char *str) { CIO_MSG_EVENT(6, "Reading blacklist parameters\n"); - if (blacklist_parse_parameters(str, add, 1)) - return 0; - return 1; + return blacklist_parse_parameters (str, add); } __setup ("cio_ignore=", blacklist_setup); @@ -230,23 +224,27 @@ is_blacklisted (int ssid, int devno) * Function: blacklist_parse_proc_parameters * parse the stuff which is piped to /proc/cio_ignore */ -static int blacklist_parse_proc_parameters(char *buf) +static void +blacklist_parse_proc_parameters (char *buf) { - int rc; - char *parm; - - parm = strsep(&buf, " "); - - if (strcmp("free", parm) == 0) - rc = blacklist_parse_parameters(buf, free, 0); - else if (strcmp("add", parm) == 0) - rc = blacklist_parse_parameters(buf, add, 0); - else - return 1; + if (strncmp (buf, "free ", 5) == 0) { + blacklist_parse_parameters (buf + 5, free); + } else if (strncmp (buf, "add ", 4) == 0) { + /* + * We don't need to check for known devices since + * css_probe_device will handle this correctly. + */ + blacklist_parse_parameters (buf + 4, add); + } else { + printk (KERN_WARNING "cio: cio_ignore: Parse error; \n" + KERN_WARNING "try using 'free all|," + ",...'\n" + KERN_WARNING "or 'add ," + ",...'\n"); + return; + } css_schedule_reprobe(); - - return rc; } /* Iterator struct for all devices. */ @@ -330,8 +328,6 @@ cio_ignore_write(struct file *file, const char __user *user_buf, size_t user_len, loff_t *offset) { char *buf; - size_t i; - ssize_t rc, ret; if (*offset) return -EINVAL; @@ -340,27 +336,16 @@ cio_ignore_write(struct file *file, const char __user *user_buf, buf = vmalloc (user_len + 1); /* maybe better use the stack? */ if (buf == NULL) return -ENOMEM; - memset(buf, 0, user_len + 1); - if (strncpy_from_user (buf, user_buf, user_len) < 0) { - rc = -EFAULT; - goto out_free; + vfree (buf); + return -EFAULT; } + buf[user_len] = '\0'; - i = user_len - 1; - while ((i >= 0) && (isspace(buf[i]) || (buf[i] == 0))) { - buf[i] = '\0'; - i--; - } - ret = blacklist_parse_proc_parameters(buf); - if (ret) - rc = -EINVAL; - else - rc = user_len; + blacklist_parse_proc_parameters (buf); -out_free: vfree (buf); - return rc; + return user_len; } static const struct seq_operations cio_ignore_proc_seq_ops = { diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index 82c6a2d45128..08a578161306 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -39,6 +39,23 @@ debug_info_t *cio_debug_msg_id; debug_info_t *cio_debug_trace_id; debug_info_t *cio_debug_crw_id; +int cio_show_msg; + +static int __init +cio_setup (char *parm) +{ + if (!strcmp (parm, "yes")) + cio_show_msg = 1; + else if (!strcmp (parm, "no")) + cio_show_msg = 0; + else + printk(KERN_ERR "cio: cio_setup: " + "invalid cio_msg parameter '%s'", parm); + return 1; +} + +__setup ("cio_msg=", cio_setup); + /* * Function: cio_debug_init * Initializes three debug logs for common I/O: @@ -149,7 +166,7 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) stsch (sch->schid, &sch->schib); - CIO_MSG_EVENT(2, "cio_start: 'not oper' status for " + CIO_MSG_EVENT(0, "cio_start: 'not oper' status for " "subchannel 0.%x.%04x!\n", sch->schid.ssid, sch->schid.sch_no); sprintf(dbf_text, "no%s", sch->dev.bus_id); @@ -550,9 +567,10 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) * ... just being curious we check for non I/O subchannels */ if (sch->st != 0) { - CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports " - "non-I/O subchannel type %04X\n", - sch->schid.ssid, sch->schid.sch_no, sch->st); + CIO_DEBUG(KERN_INFO, 0, + "Subchannel 0.%x.%04x reports " + "non-I/O subchannel type %04X\n", + sch->schid.ssid, sch->schid.sch_no, sch->st); /* We stop here for non-io subchannels. */ err = sch->st; goto out; @@ -570,7 +588,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) * This device must not be known to Linux. So we simply * say that there is no device and return ENODEV. */ - CIO_MSG_EVENT(6, "Blacklisted device detected " + CIO_MSG_EVENT(4, "Blacklisted device detected " "at devno %04X, subchannel set %x\n", sch->schib.pmcw.dev, sch->schid.ssid); err = -ENODEV; @@ -583,11 +601,12 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) sch->lpm = sch->schib.pmcw.pam & sch->opm; sch->isc = 3; - CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " - "- PIM = %02X, PAM = %02X, POM = %02X\n", - sch->schib.pmcw.dev, sch->schid.ssid, - sch->schid.sch_no, sch->schib.pmcw.pim, - sch->schib.pmcw.pam, sch->schib.pmcw.pom); + CIO_DEBUG(KERN_INFO, 0, + "Detected device %04x on subchannel 0.%x.%04X" + " - PIM = %02X, PAM = %02X, POM = %02X\n", + sch->schib.pmcw.dev, sch->schid.ssid, + sch->schid.sch_no, sch->schib.pmcw.pim, + sch->schib.pmcw.pam, sch->schib.pmcw.pom); /* * We now have to initially ... diff --git a/trunk/drivers/s390/cio/cio.h b/trunk/drivers/s390/cio/cio.h index 6e933aebe013..3c75412904dc 100644 --- a/trunk/drivers/s390/cio/cio.h +++ b/trunk/drivers/s390/cio/cio.h @@ -118,4 +118,6 @@ extern void *cio_get_console_priv(void); #define cio_get_console_priv() NULL #endif +extern int cio_show_msg; + #endif diff --git a/trunk/drivers/s390/cio/cio_debug.h b/trunk/drivers/s390/cio/cio_debug.h index e64e8278c42e..d7429ef6c666 100644 --- a/trunk/drivers/s390/cio/cio_debug.h +++ b/trunk/drivers/s390/cio/cio_debug.h @@ -31,4 +31,10 @@ static inline void CIO_HEX_EVENT(int level, void *data, int length) } } +#define CIO_DEBUG(printk_level, event_level, msg...) do { \ + if (cio_show_msg) \ + printk(printk_level "cio: " msg); \ + CIO_MSG_EVENT(event_level, msg); \ + } while (0) + #endif diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index a76956512b2d..595e327d2f76 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -570,7 +570,7 @@ static void reprobe_all(struct work_struct *unused) { int ret; - CIO_MSG_EVENT(4, "reprobe start\n"); + CIO_MSG_EVENT(2, "reprobe start\n"); need_reprobe = 0; /* Make sure initial subchannel scan is done. */ @@ -578,7 +578,7 @@ static void reprobe_all(struct work_struct *unused) atomic_read(&ccw_device_init_count) == 0); ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); - CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, + CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, need_reprobe); } diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index e22813db74a2..abfd601d237a 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -341,7 +341,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) rc = device_schedule_callback(&cdev->dev, ccw_device_remove_orphan_cb); if (rc) - CIO_MSG_EVENT(0, "Couldn't unregister orphan " + CIO_MSG_EVENT(2, "Couldn't unregister orphan " "0.%x.%04x\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -351,7 +351,7 @@ ccw_device_remove_disconnected(struct ccw_device *cdev) rc = device_schedule_callback(cdev->dev.parent, ccw_device_remove_sch_cb); if (rc) - CIO_MSG_EVENT(0, "Couldn't unregister disconnected device " + CIO_MSG_EVENT(2, "Couldn't unregister disconnected device " "0.%x.%04x\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -397,7 +397,7 @@ int ccw_device_set_offline(struct ccw_device *cdev) if (ret == 0) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else { - CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " + CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -433,7 +433,7 @@ int ccw_device_set_online(struct ccw_device *cdev) if (ret == 0) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else { - CIO_MSG_EVENT(0, "ccw_device_online returned %d, " + CIO_MSG_EVENT(2, "ccw_device_online returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -451,7 +451,7 @@ int ccw_device_set_online(struct ccw_device *cdev) if (ret == 0) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else - CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " + CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -803,7 +803,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch, other_sch = to_subchannel(get_device(cdev->dev.parent)); ret = device_move(&cdev->dev, &sch->dev); if (ret) { - CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed " + CIO_MSG_EVENT(2, "Moving disconnected device 0.%x.%04x failed " "(ret=%d)!\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno, ret); put_device(&other_sch->dev); @@ -933,7 +933,7 @@ io_subchannel_register(struct work_struct *work) ret = device_reprobe(&cdev->dev); if (ret) /* We can't do much here. */ - CIO_MSG_EVENT(0, "device_reprobe() returned" + CIO_MSG_EVENT(2, "device_reprobe() returned" " %d for 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -1086,7 +1086,7 @@ static void ccw_device_move_to_sch(struct work_struct *work) rc = device_move(&cdev->dev, &sch->dev); mutex_unlock(&sch->reg_mutex); if (rc) { - CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel " + CIO_MSG_EVENT(2, "Moving device 0.%x.%04x to subchannel " "0.%x.%04x failed (ret=%d)!\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno, sch->schid.ssid, @@ -1446,7 +1446,8 @@ ccw_device_remove (struct device *dev) wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); else - CIO_MSG_EVENT(0, "ccw_device_offline returned %d, " + //FIXME: we can't fail! + CIO_MSG_EVENT(2, "ccw_device_offline returned %d, " "device 0.%x.%04x\n", ret, cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -1523,7 +1524,7 @@ static int recovery_check(struct device *dev, void *data) spin_lock_irq(cdev->ccwlock); switch (cdev->private->state) { case DEV_STATE_DISCONNECTED: - CIO_MSG_EVENT(4, "recovery: trigger 0.%x.%04x\n", + CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); dev_fsm_event(cdev, DEV_EVENT_VERIFY); @@ -1553,7 +1554,7 @@ static void recovery_work_func(struct work_struct *unused) } spin_unlock_irq(&recovery_lock); } else - CIO_MSG_EVENT(4, "recovery: end\n"); + CIO_MSG_EVENT(2, "recovery: end\n"); } static DECLARE_WORK(recovery_work, recovery_work_func); @@ -1571,7 +1572,7 @@ void ccw_device_schedule_recovery(void) { unsigned long flags; - CIO_MSG_EVENT(4, "recovery: schedule\n"); + CIO_MSG_EVENT(2, "recovery: schedule\n"); spin_lock_irqsave(&recovery_lock, flags); if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { recovery_phase = 0; diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index e268d5a77c12..99403b0a97a7 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -322,10 +322,10 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) same_dev = 0; /* Keep the compiler quiet... */ switch (state) { case DEV_STATE_NOT_OPER: - CIO_MSG_EVENT(2, "SenseID : unknown device %04x on " - "subchannel 0.%x.%04x\n", - cdev->private->dev_id.devno, - sch->schid.ssid, sch->schid.sch_no); + CIO_DEBUG(KERN_WARNING, 2, + "SenseID : unknown device %04x on subchannel " + "0.%x.%04x\n", cdev->private->dev_id.devno, + sch->schid.ssid, sch->schid.sch_no); break; case DEV_STATE_OFFLINE: if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { @@ -348,19 +348,20 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) return; } /* Issue device info message. */ - CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: " - "CU Type/Mod = %04X/%02X, Dev Type/Mod = " - "%04X/%02X\n", - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno, - cdev->id.cu_type, cdev->id.cu_model, - cdev->id.dev_type, cdev->id.dev_model); + CIO_DEBUG(KERN_INFO, 2, + "SenseID : device 0.%x.%04x reports: " + "CU Type/Mod = %04X/%02X, Dev Type/Mod = " + "%04X/%02X\n", + cdev->private->dev_id.ssid, + cdev->private->dev_id.devno, + cdev->id.cu_type, cdev->id.cu_model, + cdev->id.dev_type, cdev->id.dev_model); break; case DEV_STATE_BOXED: - CIO_MSG_EVENT(0, "SenseID : boxed device %04x on " - " subchannel 0.%x.%04x\n", - cdev->private->dev_id.devno, - sch->schid.ssid, sch->schid.sch_no); + CIO_DEBUG(KERN_WARNING, 2, + "SenseID : boxed device %04x on subchannel " + "0.%x.%04x\n", cdev->private->dev_id.devno, + sch->schid.ssid, sch->schid.sch_no); break; } cdev->private->state = state; @@ -442,8 +443,9 @@ ccw_device_done(struct ccw_device *cdev, int state) if (state == DEV_STATE_BOXED) - CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", - cdev->private->dev_id.devno, sch->schid.sch_no); + CIO_DEBUG(KERN_WARNING, 2, + "Boxed device %04x on subchannel %04x\n", + cdev->private->dev_id.devno, sch->schid.sch_no); if (cdev->private->flags.donotify) { cdev->private->flags.donotify = 0; @@ -898,7 +900,7 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) /* Basic sense hasn't started. Try again. */ ccw_device_do_sense(cdev, irb); else { - CIO_MSG_EVENT(0, "0.%x.%04x: unsolicited " + CIO_MSG_EVENT(2, "Huh? 0.%x.%04x: unsolicited " "interrupt during w4sense...\n", cdev->private->dev_id.ssid, cdev->private->dev_id.devno); @@ -1167,10 +1169,8 @@ ccw_device_nop(struct ccw_device *cdev, enum dev_event dev_event) static void ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event) { - CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device " - "0.%x.%04x\n", cdev->private->state, dev_event, - cdev->private->dev_id.ssid, - cdev->private->dev_id.devno); + CIO_MSG_EVENT(0, "dev_jumptable[%i][%i] == NULL\n", + cdev->private->state, dev_event); BUG(); } diff --git a/trunk/drivers/s390/cio/device_id.c b/trunk/drivers/s390/cio/device_id.c index cba7020517ed..dc4d87f77f6c 100644 --- a/trunk/drivers/s390/cio/device_id.c +++ b/trunk/drivers/s390/cio/device_id.c @@ -214,7 +214,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) * sense id information. So, for intervention required, * we use the "whack it until it talks" strategy... */ - CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel " + CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel " "0.%x.%04x reports cmd reject\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no); @@ -239,7 +239,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev) lpm = to_io_private(sch)->orb.lpm; if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) - CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x " + CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x " "on subchannel 0.%x.%04x is " "'not operational'\n", lpm, cdev->private->dev_id.devno, diff --git a/trunk/drivers/s390/cio/device_pgid.c b/trunk/drivers/s390/cio/device_pgid.c index ba559053402e..c52449a1f9fc 100644 --- a/trunk/drivers/s390/cio/device_pgid.c +++ b/trunk/drivers/s390/cio/device_pgid.c @@ -79,7 +79,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) /* ret is 0, -EBUSY, -EACCES or -ENODEV */ if (ret != -EACCES) return ret; - CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel " + CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not " "operational'\n", cdev->private->dev_id.devno, @@ -159,7 +159,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev) u8 lpm; lpm = to_io_private(sch)->orb.lpm; - CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x," + CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, lpm); @@ -275,7 +275,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) return ret; } /* PGID command failed on this path. */ - CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel " + CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); @@ -317,7 +317,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev) return ret; } /* nop command failed on this path. */ - CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel " + CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel " "0.%x.%04x, lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); @@ -362,7 +362,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev) return -EAGAIN; } if (irb->scsw.cc == 3) { - CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x," + CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); @@ -391,7 +391,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev) return -ETIME; } if (irb->scsw.cc == 3) { - CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x," + CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," " lpm %02X, became 'not operational'\n", cdev->private->dev_id.devno, sch->schid.ssid, sch->schid.sch_no, cdev->private->imask); diff --git a/trunk/drivers/s390/s390mach.c b/trunk/drivers/s390/s390mach.c index 5080f343ad74..4d4b54277c43 100644 --- a/trunk/drivers/s390/s390mach.c +++ b/trunk/drivers/s390/s390mach.c @@ -48,11 +48,10 @@ s390_collect_crw_info(void *param) int ccode; struct semaphore *sem; unsigned int chain; - int ignore; sem = (struct semaphore *)param; repeat: - ignore = down_interruptible(sem); + down_interruptible(sem); chain = 0; while (1) { if (unlikely(chain > 1)) { diff --git a/trunk/drivers/s390/scsi/zfcp_dbf.c b/trunk/drivers/s390/scsi/zfcp_dbf.c index c8bad675dbd1..37b85c67b11d 100644 --- a/trunk/drivers/s390/scsi/zfcp_dbf.c +++ b/trunk/drivers/s390/scsi/zfcp_dbf.c @@ -1055,7 +1055,7 @@ static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level, rec->scsi_result = scsi_cmnd->result; rec->scsi_cmnd = (unsigned long)scsi_cmnd; rec->scsi_serial = scsi_cmnd->serial_number; - memcpy(rec->scsi_opcode, scsi_cmnd->cmnd, + memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd, min((int)scsi_cmnd->cmd_len, ZFCP_DBF_SCSI_OPCODE)); rec->scsi_retries = scsi_cmnd->retries; diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index b2ea4ea051f5..9af2330f07a2 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -4014,7 +4014,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) ZFCP_LOG_TRACE("scpnt->result =0x%x, command was:\n", scpnt->result); ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, - scpnt->cmnd, scpnt->cmd_len); + (void *) &scpnt->cmnd, scpnt->cmd_len); ZFCP_LOG_TRACE("%i bytes sense data provided by FCP\n", fcp_rsp_iu->fcp_sns_len); diff --git a/trunk/drivers/sbus/char/bpp.c b/trunk/drivers/sbus/char/bpp.c index b87037ec9805..4fab0c23814c 100644 --- a/trunk/drivers/sbus/char/bpp.c +++ b/trunk/drivers/sbus/char/bpp.c @@ -41,7 +41,7 @@ #define BPP_DELAY 100 static const unsigned BPP_MAJOR = LP_MAJOR; -static const char *bpp_dev_name = "bpp"; +static const char* dev_name = "bpp"; /* When switching from compatibility to a mode where I can read, try the following mode first. */ diff --git a/trunk/drivers/scsi/53c700.c b/trunk/drivers/scsi/53c700.c index f5a9addb7050..f4c4fe90240a 100644 --- a/trunk/drivers/scsi/53c700.c +++ b/trunk/drivers/scsi/53c700.c @@ -599,7 +599,7 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, (struct NCR_700_command_slot *)SCp->host_scribble; dma_unmap_single(hostdata->dev, slot->pCmd, - MAX_COMMAND_SIZE, DMA_TO_DEVICE); + sizeof(SCp->cmnd), DMA_TO_DEVICE); if (slot->flags == NCR_700_FLAG_AUTOSENSE) { char *cmnd = NCR_700_get_sense_cmnd(SCp->device); #ifdef NCR_700_DEBUG @@ -1004,7 +1004,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, * here */ NCR_700_unmap(hostdata, SCp, slot); dma_unmap_single(hostdata->dev, slot->pCmd, - MAX_COMMAND_SIZE, + sizeof(SCp->cmnd), DMA_TO_DEVICE); cmnd[0] = REQUEST_SENSE; @@ -1901,7 +1901,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) } slot->resume_offset = 0; slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd, - MAX_COMMAND_SIZE, DMA_TO_DEVICE); + sizeof(SCp->cmnd), DMA_TO_DEVICE); NCR_700_start_command(SCp); return 0; } diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 81ccbd7f9e34..99c57b0c1d54 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -504,9 +504,10 @@ config SCSI_AIC7XXX_OLD source "drivers/scsi/aic7xxx/Kconfig.aic79xx" source "drivers/scsi/aic94xx/Kconfig" +# All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on SCSI && PCI && VIRT_TO_BUS + depends on !64BIT && SCSI && PCI && VIRT_TO_BUS help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained @@ -1679,7 +1680,6 @@ config MAC_SCSI config SCSI_MAC_ESP tristate "Macintosh NCR53c9[46] SCSI" depends on MAC && SCSI - select SCSI_SPI_ATTRS help This is the NCR 53c9x SCSI controller found on most of the 68040 based Macintoshes. diff --git a/trunk/drivers/scsi/a100u2w.c b/trunk/drivers/scsi/a100u2w.c index ced3eebe252c..792b2e807bf3 100644 --- a/trunk/drivers/scsi/a100u2w.c +++ b/trunk/drivers/scsi/a100u2w.c @@ -895,7 +895,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru } else { scb->tag_msg = 0; /* No tag support */ } - memcpy(scb->cdb, cmd->cmnd, scb->cdb_len); + memcpy(&scb->cdb[0], &cmd->cmnd, scb->cdb_len); } /** diff --git a/trunk/drivers/scsi/aacraid/aachba.c b/trunk/drivers/scsi/aacraid/aachba.c index aa4e77c25273..460d4024c46c 100644 --- a/trunk/drivers/scsi/aacraid/aachba.c +++ b/trunk/drivers/scsi/aacraid/aachba.c @@ -498,11 +498,6 @@ static void _aac_probe_container2(void * context, struct fib * fibptr) (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr->valid = 1; - /* sense_key holds the current state of the spin-up */ - if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY)) - fsa_dev_ptr->sense_data.sense_key = NOT_READY; - else if (fsa_dev_ptr->sense_data.sense_key == NOT_READY) - fsa_dev_ptr->sense_data.sense_key = NO_SENSE; fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr->size = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + @@ -1514,35 +1509,20 @@ static void io_callback(void *context, struct fib * fibptr) scsi_dma_unmap(scsicmd); readreply = (struct aac_read_reply *)fib_data(fibptr); - switch (le32_to_cpu(readreply->status)) { - case ST_OK: - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; - dev->fsa_dev[cid].sense_data.sense_key = NO_SENSE; - break; - case ST_NOT_READY: - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; - set_sense(&dev->fsa_dev[cid].sense_data, NOT_READY, - SENCODE_BECOMING_READY, ASENCODE_BECOMING_READY, 0, 0); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), - SCSI_SENSE_BUFFERSIZE)); - break; - default: + if (le32_to_cpu(readreply->status) == ST_OK) + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + else { #ifdef AAC_DETAILED_STATUS_INFO printk(KERN_WARNING "io_callback: io failed, status = %d\n", le32_to_cpu(readreply->status)); #endif - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense(&dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); - break; } aac_fib_complete(fibptr); aac_fib_free(fibptr); @@ -1883,84 +1863,6 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd) return SCSI_MLQUEUE_HOST_BUSY; } -static void aac_start_stop_callback(void *context, struct fib *fibptr) -{ - struct scsi_cmnd *scsicmd = context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; - - BUG_ON(fibptr == NULL); - - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; - - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - scsicmd->scsi_done(scsicmd); -} - -static int aac_start_stop(struct scsi_cmnd *scsicmd) -{ - int status; - struct fib *cmd_fibcontext; - struct aac_power_management *pmcmd; - struct scsi_device *sdev = scsicmd->device; - struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; - - if (!(aac->supplement_adapter_info.SupportedOptions2 & - AAC_OPTION_POWER_MANAGEMENT)) { - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; - scsicmd->scsi_done(scsicmd); - return 0; - } - - if (aac->in_reset) - return SCSI_MLQUEUE_HOST_BUSY; - - /* - * Allocate and initialize a Fib - */ - cmd_fibcontext = aac_fib_alloc(aac); - if (!cmd_fibcontext) - return SCSI_MLQUEUE_HOST_BUSY; - - aac_fib_init(cmd_fibcontext); - - pmcmd = fib_data(cmd_fibcontext); - pmcmd->command = cpu_to_le32(VM_ContainerConfig); - pmcmd->type = cpu_to_le32(CT_POWER_MANAGEMENT); - /* Eject bit ignored, not relevant */ - pmcmd->sub = (scsicmd->cmnd[4] & 1) ? - cpu_to_le32(CT_PM_START_UNIT) : cpu_to_le32(CT_PM_STOP_UNIT); - pmcmd->cid = cpu_to_le32(sdev_id(sdev)); - pmcmd->parm = (scsicmd->cmnd[1] & 1) ? - cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0; - - /* - * Now send the Fib to the adapter - */ - status = aac_fib_send(ContainerCommand, - cmd_fibcontext, - sizeof(struct aac_power_management), - FsaNormal, - 0, 1, - (fib_callback)aac_start_stop_callback, - (void *)scsicmd); - - /* - * Check that the command queued to the controller - */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; - return 0; - } - - aac_fib_complete(cmd_fibcontext); - aac_fib_free(cmd_fibcontext); - return SCSI_MLQUEUE_HOST_BUSY; -} - /** * aac_scsi_cmd() - Process SCSI command * @scsicmd: SCSI command block @@ -1997,9 +1899,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * If the target container doesn't exist, it may have * been newly created */ - if (((fsa_dev_ptr[cid].valid & 1) == 0) || - (fsa_dev_ptr[cid].sense_data.sense_key == - NOT_READY)) { + if ((fsa_dev_ptr[cid].valid & 1) == 0) { switch (scsicmd->cmnd[0]) { case SERVICE_ACTION_IN: if (!(dev->raw_io_interface) || @@ -2191,8 +2091,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp)); /* Do not cache partition table for arrays */ scsicmd->device->removable = 1; - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; + + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); return 0; @@ -2287,32 +2187,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) * These commands are all No-Ops */ case TEST_UNIT_READY: - if (fsa_dev_ptr[cid].sense_data.sense_key == NOT_READY) { - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; - set_sense(&dev->fsa_dev[cid].sense_data, - NOT_READY, SENCODE_BECOMING_READY, - ASENCODE_BECOMING_READY, 0, 0); - memcpy(scsicmd->sense_buffer, - &dev->fsa_dev[cid].sense_data, - min_t(size_t, - sizeof(dev->fsa_dev[cid].sense_data), - SCSI_SENSE_BUFFERSIZE)); - scsicmd->scsi_done(scsicmd); - return 0; - } - /* FALLTHRU */ case RESERVE: case RELEASE: case REZERO_UNIT: case REASSIGN_BLOCKS: case SEEK_10: + case START_STOP: scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; scsicmd->scsi_done(scsicmd); return 0; - - case START_STOP: - return aac_start_stop(scsicmd); } switch (scsicmd->cmnd[0]) diff --git a/trunk/drivers/scsi/aacraid/aacraid.h b/trunk/drivers/scsi/aacraid/aacraid.h index 73916adb8f80..113ca9c8934c 100644 --- a/trunk/drivers/scsi/aacraid/aacraid.h +++ b/trunk/drivers/scsi/aacraid/aacraid.h @@ -12,7 +12,7 @@ *----------------------------------------------------------------------------*/ #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 2456 +# define AAC_DRIVER_BUILD 2455 # define AAC_DRIVER_BRANCH "-ms" #endif #define MAXIMUM_NUM_CONTAINERS 32 @@ -34,8 +34,8 @@ #define CONTAINER_TO_ID(cont) (cont) #define CONTAINER_TO_LUN(cont) (0) -#define aac_phys_to_logical(x) ((x)+1) -#define aac_logical_to_phys(x) ((x)?(x)-1:0) +#define aac_phys_to_logical(x) (x+1) +#define aac_logical_to_phys(x) (x?x-1:0) /* #define AAC_DETAILED_STATUS_INFO */ @@ -424,8 +424,6 @@ struct aac_init */ __le32 InitFlags; /* flags for supported features */ #define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001 -#define INITFLAGS_DRIVER_USES_UTC_TIME 0x00000010 -#define INITFLAGS_DRIVER_SUPPORTS_PM 0x00000020 __le32 MaxIoCommands; /* max outstanding commands */ __le32 MaxIoSize; /* largest I/O command */ __le32 MaxFibSize; /* largest FIB to adapter */ @@ -869,10 +867,8 @@ struct aac_supplement_adapter_info }; #define AAC_FEATURE_FALCON cpu_to_le32(0x00000010) #define AAC_FEATURE_JBOD cpu_to_le32(0x08000000) -/* SupportedOptions2 */ -#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001) -#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002) -#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004) +#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001) +#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002) #define AAC_SIS_VERSION_V3 3 #define AAC_SIS_SLOT_UNKNOWN 0xFF @@ -1152,7 +1148,6 @@ struct aac_dev #define ST_DQUOT 69 #define ST_STALE 70 #define ST_REMOTE 71 -#define ST_NOT_READY 72 #define ST_BADHANDLE 10001 #define ST_NOT_SYNC 10002 #define ST_BAD_COOKIE 10003 @@ -1274,18 +1269,6 @@ struct aac_synchronize_reply { u8 data[16]; }; -#define CT_POWER_MANAGEMENT 245 -#define CT_PM_START_UNIT 2 -#define CT_PM_STOP_UNIT 3 -#define CT_PM_UNIT_IMMEDIATE 1 -struct aac_power_management { - __le32 command; /* VM_ContainerConfig */ - __le32 type; /* CT_POWER_MANAGEMENT */ - __le32 sub; /* CT_PM_* */ - __le32 cid; - __le32 parm; /* CT_PM_sub_* */ -}; - #define CT_PAUSE_IO 65 #define CT_RELEASE_IO 66 struct aac_pause { @@ -1553,7 +1536,6 @@ struct aac_mntent { #define FSCS_NOTCLEAN 0x0001 /* fsck is necessary before mounting */ #define FSCS_READONLY 0x0002 /* possible result of broken mirror */ #define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */ -#define FSCS_NOT_READY 0x0008 /* Array spinning up to fulfil request */ struct aac_query_mount { __le32 command; diff --git a/trunk/drivers/scsi/aacraid/comminit.c b/trunk/drivers/scsi/aacraid/comminit.c index cbac06355107..294a802450be 100644 --- a/trunk/drivers/scsi/aacraid/comminit.c +++ b/trunk/drivers/scsi/aacraid/comminit.c @@ -97,8 +97,6 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); } - init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME | - INITFLAGS_DRIVER_SUPPORTS_PM); init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); init->MaxFibSize = cpu_to_le32(dev->max_fib_size); diff --git a/trunk/drivers/scsi/aacraid/commsup.c b/trunk/drivers/scsi/aacraid/commsup.c index 289304aab690..ef67816a6fe5 100644 --- a/trunk/drivers/scsi/aacraid/commsup.c +++ b/trunk/drivers/scsi/aacraid/commsup.c @@ -515,7 +515,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, } udelay(5); } - } else if (down_interruptible(&fibptr->event_wait)) { + } else if (down_interruptible(&fibptr->event_wait) == 0) { fibptr->done = 2; up(&fibptr->event_wait); } @@ -906,22 +906,15 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) case AifEnAddJBOD: case AifEnDeleteJBOD: container = le32_to_cpu(((__le32 *)aifcmd->data)[1]); - if ((container >> 28)) { - container = (u32)-1; + if ((container >> 28)) break; - } channel = (container >> 24) & 0xF; - if (channel >= dev->maximum_num_channels) { - container = (u32)-1; + if (channel >= dev->maximum_num_channels) break; - } id = container & 0xFFFF; - if (id >= dev->maximum_num_physicals) { - container = (u32)-1; + if (id >= dev->maximum_num_physicals) break; - } lun = (container >> 16) & 0xFF; - container = (u32)-1; channel = aac_phys_to_logical(channel); device_config_needed = (((__le32 *)aifcmd->data)[0] == @@ -940,18 +933,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) case EM_DRIVE_REMOVAL: container = le32_to_cpu( ((__le32 *)aifcmd->data)[2]); - if ((container >> 28)) { - container = (u32)-1; + if ((container >> 28)) break; - } channel = (container >> 24) & 0xF; - if (channel >= dev->maximum_num_channels) { - container = (u32)-1; + if (channel >= dev->maximum_num_channels) break; - } id = container & 0xFFFF; lun = (container >> 16) & 0xFF; - container = (u32)-1; if (id >= dev->maximum_num_physicals) { /* legacy dev_t ? */ if ((0x2000 <= id) || lun || channel || @@ -1037,10 +1025,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) break; } - container = 0; -retry_next: if (device_config_needed == NOTHING) - for (; container < dev->maximum_num_containers; ++container) { + for (container = 0; container < dev->maximum_num_containers; + ++container) { if ((dev->fsa_dev[container].config_waiting_on == 0) && (dev->fsa_dev[container].config_needed != NOTHING) && time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) { @@ -1123,11 +1110,6 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) } if (device_config_needed == ADD) scsi_add_device(dev->scsi_host_ptr, channel, id, lun); - if (channel == CONTAINER_CHANNEL) { - container++; - device_config_needed = NOTHING; - goto retry_next; - } } static int _aac_reset_adapter(struct aac_dev *aac, int forced) diff --git a/trunk/drivers/scsi/aacraid/linit.c b/trunk/drivers/scsi/aacraid/linit.c index 1f7c83607f84..c109f63f8279 100644 --- a/trunk/drivers/scsi/aacraid/linit.c +++ b/trunk/drivers/scsi/aacraid/linit.c @@ -401,8 +401,6 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, static int aac_slave_configure(struct scsi_device *sdev) { struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; - if (aac->jbod && (sdev->type == TYPE_DISK)) - sdev->removable = 1; if ((sdev->type == TYPE_DISK) && (sdev_channel(sdev) != CONTAINER_CHANNEL) && (!aac->jbod || sdev->inq_periph_qual) && @@ -811,12 +809,6 @@ static ssize_t aac_show_flags(struct device *cdev, "SAI_READ_CAPACITY_16\n"); if (dev->jbod) len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n"); - if (dev->supplement_adapter_info.SupportedOptions2 & - AAC_OPTION_POWER_MANAGEMENT) - len += snprintf(buf + len, PAGE_SIZE - len, - "SUPPORTED_POWER_MANAGEMENT\n"); - if (dev->msi) - len += snprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n"); return len; } @@ -1114,7 +1106,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, aac->pdev = pdev; aac->name = aac_driver_template.name; aac->id = shost->unique_id; - aac->cardtype = index; + aac->cardtype = index; INIT_LIST_HEAD(&aac->entry); aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); @@ -1154,19 +1146,19 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, goto out_deinit; /* - * Lets override negotiations and drop the maximum SG limit to 34 - */ + * Lets override negotiations and drop the maximum SG limit to 34 + */ if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && (shost->sg_tablesize > 34)) { shost->sg_tablesize = 34; shost->max_sectors = (shost->sg_tablesize * 8) + 112; - } + } - if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) && + if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) && (shost->sg_tablesize > 17)) { shost->sg_tablesize = 17; shost->max_sectors = (shost->sg_tablesize * 8) + 112; - } + } error = pci_set_dma_max_seg_size(pdev, (aac->adapter_info.options & AAC_OPT_NEW_COMM) ? @@ -1182,7 +1174,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, else aac->printf_enabled = 0; - /* + /* * max channel will be the physical channels plus 1 virtual channel * all containers are on the virtual channel 0 (CONTAINER_CHANNEL) * physical channels are address by their actual physical number+1 diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_init.c b/trunk/drivers/scsi/aic94xx/aic94xx_init.c index 2a730c470f62..90f5e0a6f2e3 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_init.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_init.c @@ -529,10 +529,10 @@ static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha) /* The first entry, 0, is used for dynamic ids, the rest for devices * we know about. */ -static const struct asd_pcidev_struct { +static struct asd_pcidev_struct { const char * name; int (*setup)(struct asd_ha_struct *asd_ha); -} asd_pcidev_data[] __devinitconst = { +} asd_pcidev_data[] = { /* Id 0 is used for dynamic ids. */ { .name = "Adaptec AIC-94xx SAS/SATA Host Adapter", .setup = asd_aic9410_setup @@ -735,7 +735,7 @@ static int asd_unregister_sas_ha(struct asd_ha_struct *asd_ha) static int __devinit asd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - const struct asd_pcidev_struct *asd_dev; + struct asd_pcidev_struct *asd_dev; unsigned asd_id = (unsigned) id->driver_data; struct asd_ha_struct *asd_ha; struct Scsi_Host *shost; diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index 9785d7384199..403a7f2d8f9b 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -28,6 +28,7 @@ #define SERVICE_ACTION_OUT_12 0xa9 #define SERVICE_ACTION_IN_16 0x9e #define SERVICE_ACTION_OUT_16 0x9f +#define VARIABLE_LENGTH_CMD 0x7f @@ -209,7 +210,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: - len = scsi_varlen_cdb_length(cdbp); + len = cdbp[7] + 8; if (len < 10) { printk("short variable length command, " "len=%d ext_len=%d", len, cdb_len); @@ -299,7 +300,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: - len = scsi_varlen_cdb_length(cdbp); + len = cdbp[7] + 8; if (len < 10) { printk("short opcode=0x%x command, len=%d " "ext_len=%d", cdb0, len, cdb_len); @@ -334,7 +335,10 @@ void __scsi_print_command(unsigned char *cdb) int k, len; print_opcode_name(cdb, 0); - len = scsi_command_size(cdb); + if (VARIABLE_LENGTH_CMD == cdb[0]) + len = cdb[7] + 8; + else + len = COMMAND_SIZE(cdb[0]); /* print out all bytes in cdb */ for (k = 0; k < len; ++k) printk(" %02x", cdb[k]); diff --git a/trunk/drivers/scsi/dpt/dpti_ioctl.h b/trunk/drivers/scsi/dpt/dpti_ioctl.h index f60236721e0d..cc784e8f6e9d 100644 --- a/trunk/drivers/scsi/dpt/dpti_ioctl.h +++ b/trunk/drivers/scsi/dpt/dpti_ioctl.h @@ -89,7 +89,7 @@ typedef struct { int njobs; /* # of jobs sent to HA */ int qdepth; /* Controller queue depth. */ int wakebase; /* mpx wakeup base index. */ - uINT SGsize; /* Scatter/Gather list size. */ + uLONG SGsize; /* Scatter/Gather list size. */ unsigned heads; /* heads for drives on cntlr. */ unsigned sectors; /* sectors for drives on cntlr. */ uCHAR do_drive32; /* Flag for Above 16 MB Ability */ @@ -97,8 +97,8 @@ typedef struct { char idPAL[4]; /* 4 Bytes Of The ID Pal */ uCHAR primary; /* 1 For Primary, 0 For Secondary */ uCHAR eataVersion; /* EATA Version */ - uINT cpLength; /* EATA Command Packet Length */ - uINT spLength; /* EATA Status Packet Length */ + uLONG cpLength; /* EATA Command Packet Length */ + uLONG spLength; /* EATA Status Packet Length */ uCHAR drqNum; /* DRQ Index (0,5,6,7) */ uCHAR flag1; /* EATA Flags 1 (Byte 9) */ uCHAR flag2; /* EATA Flags 2 (Byte 30) */ @@ -107,23 +107,23 @@ typedef struct { typedef struct { uSHORT length; // Remaining length of this uSHORT drvrHBAnum; // Relative HBA # used by the driver - uINT baseAddr; // Base I/O address + uLONG baseAddr; // Base I/O address uSHORT blinkState; // Blink LED state (0=Not in blink LED) uCHAR pciBusNum; // PCI Bus # (Optional) uCHAR pciDeviceNum; // PCI Device # (Optional) uSHORT hbaFlags; // Miscellaneous HBA flags uSHORT Interrupt; // Interrupt set for this device. # if (defined(_DPT_ARC)) - uINT baseLength; + uLONG baseLength; ADAPTER_OBJECT *AdapterObject; LARGE_INTEGER DmaLogicalAddress; PVOID DmaVirtualAddress; LARGE_INTEGER ReplyLogicalAddress; PVOID ReplyVirtualAddress; # else - uINT reserved1; // Reserved for future expansion - uINT reserved2; // Reserved for future expansion - uINT reserved3; // Reserved for future expansion + uLONG reserved1; // Reserved for future expansion + uLONG reserved2; // Reserved for future expansion + uLONG reserved3; // Reserved for future expansion # endif } drvrHBAinfo_S; diff --git a/trunk/drivers/scsi/dpt/dptsig.h b/trunk/drivers/scsi/dpt/dptsig.h index 72c8992fdf21..94bc894d1200 100644 --- a/trunk/drivers/scsi/dpt/dptsig.h +++ b/trunk/drivers/scsi/dpt/dptsig.h @@ -33,7 +33,11 @@ /* to make sure we are talking the same size under all OS's */ typedef unsigned char sigBYTE; typedef unsigned short sigWORD; -typedef unsigned int sigINT; +#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32)) +typedef uint32_t sigLONG; +#else +typedef unsigned long sigLONG; +#endif /* * use sigWORDLittleEndian for: @@ -296,7 +300,7 @@ typedef struct dpt_sig { sigBYTE dsFiletype; /* type of file */ sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */ sigBYTE dsOEM; /* OEM file was created for */ - sigINT dsOS; /* which Operating systems */ + sigLONG dsOS; /* which Operating systems */ sigWORD dsCapabilities; /* RAID levels, etc. */ sigWORD dsDeviceSupp; /* Types of SCSI devices supported */ sigWORD dsAdapterSupp; /* DPT adapter families supported */ diff --git a/trunk/drivers/scsi/dpt/sys_info.h b/trunk/drivers/scsi/dpt/sys_info.h index a90c4cb8ea8b..d23b70c8c768 100644 --- a/trunk/drivers/scsi/dpt/sys_info.h +++ b/trunk/drivers/scsi/dpt/sys_info.h @@ -145,8 +145,8 @@ uCHAR smartROMRevision; uSHORT flags; /* See bit definitions above */ uSHORT conventionalMemSize; /* in KB */ - uINT extendedMemSize; /* in KB */ - uINT osType; /* Same as DPTSIG's definition */ + uLONG extendedMemSize; /* in KB */ + uLONG osType; /* Same as DPTSIG's definition */ uCHAR osMajorVersion; uCHAR osMinorVersion; /* The OS version */ uCHAR osRevision; diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index 8508816f303d..ac92ac143b46 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -29,6 +29,11 @@ /*#define DEBUG 1 */ /*#define UARTDELAY 1 */ +/* On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates + high pages. Keep the macro around because of the broken unmerged ia64 tree */ + +#define ADDR32 (0) + #include MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn"); @@ -103,29 +108,28 @@ static dpt_sig_S DPTI_sig = { static DEFINE_MUTEX(adpt_configuration_lock); -static struct i2o_sys_tbl *sys_tbl; -static dma_addr_t sys_tbl_pa; -static int sys_tbl_ind; -static int sys_tbl_len; +static struct i2o_sys_tbl *sys_tbl = NULL; +static int sys_tbl_ind = 0; +static int sys_tbl_len = 0; static adpt_hba* hba_chain = NULL; static int hba_count = 0; -static struct class *adpt_sysfs_class; - -#ifdef CONFIG_COMPAT -static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long); -#endif - static const struct file_operations adpt_fops = { .ioctl = adpt_ioctl, .open = adpt_open, - .release = adpt_close, -#ifdef CONFIG_COMPAT - .compat_ioctl = compat_adpt_ioctl, -#endif + .release = adpt_close }; +#ifdef REBOOT_NOTIFIER +static struct notifier_block adpt_reboot_notifier = +{ + adpt_reboot_event, + NULL, + 0 +}; +#endif + /* Structures and definitions for synchronous message posting. * See adpt_i2o_post_wait() for description * */ @@ -147,21 +151,6 @@ static DEFINE_SPINLOCK(adpt_post_wait_lock); *============================================================================ */ -static inline int dpt_dma64(adpt_hba *pHba) -{ - return (sizeof(dma_addr_t) > 4 && (pHba)->dma64); -} - -static inline u32 dma_high(dma_addr_t addr) -{ - return upper_32_bits(addr); -} - -static inline u32 dma_low(dma_addr_t addr) -{ - return (u32)addr; -} - static u8 adpt_read_blink_led(adpt_hba* host) { if (host->FwDebugBLEDflag_P) { @@ -189,6 +178,8 @@ static int adpt_detect(struct scsi_host_template* sht) struct pci_dev *pDev = NULL; adpt_hba* pHba; + adpt_init(); + PINFO("Detecting Adaptec I2O RAID controllers...\n"); /* search for all Adatpec I2O RAID cards */ @@ -256,29 +247,13 @@ static int adpt_detect(struct scsi_host_template* sht) adpt_inquiry(pHba); } - adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o"); - if (IS_ERR(adpt_sysfs_class)) { - printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n"); - adpt_sysfs_class = NULL; - } - for (pHba = hba_chain; pHba; pHba = pHba->next) { - if (adpt_scsi_host_alloc(pHba, sht) < 0){ + if( adpt_scsi_register(pHba,sht) < 0){ adpt_i2o_delete_hba(pHba); continue; } pHba->initialized = TRUE; pHba->state &= ~DPTI_STATE_RESET; - if (adpt_sysfs_class) { - struct device *dev = device_create(adpt_sysfs_class, - NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), - "dpti%d", pHba->unit); - if (IS_ERR(dev)) { - printk(KERN_WARNING"dpti%d: unable to " - "create device in dpt_i2o class\n", - pHba->unit); - } - } } // Register our control device node @@ -307,7 +282,7 @@ static int adpt_release(struct Scsi_Host *host) static void adpt_inquiry(adpt_hba* pHba) { - u32 msg[17]; + u32 msg[14]; u32 *mptr; u32 *lenptr; int direction; @@ -315,12 +290,11 @@ static void adpt_inquiry(adpt_hba* pHba) u32 len; u32 reqlen; u8* buf; - dma_addr_t addr; u8 scb[16]; s32 rcode; memset(msg, 0, sizeof(msg)); - buf = dma_alloc_coherent(&pHba->pDev->dev, 80, &addr, GFP_KERNEL); + buf = kmalloc(80,GFP_KERNEL|ADDR32); if(!buf){ printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name); return; @@ -331,10 +305,7 @@ static void adpt_inquiry(adpt_hba* pHba) direction = 0x00000000; scsidir =0x40000000; // DATA IN (iop<--dev) - if (dpt_dma64(pHba)) - reqlen = 17; // SINGLE SGE, 64 bit - else - reqlen = 14; // SINGLE SGE, 32 bit + reqlen = 14; // SINGLE SGE /* Stick the headers on */ msg[0] = reqlen<<16 | SGL_OFFSET_12; msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID); @@ -367,16 +338,8 @@ static void adpt_inquiry(adpt_hba* pHba) /* Now fill in the SGList and command */ *lenptr = len; - if (dpt_dma64(pHba)) { - *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */ - *mptr++ = 1 << PAGE_SHIFT; - *mptr++ = 0xD0000000|direction|len; - *mptr++ = dma_low(addr); - *mptr++ = dma_high(addr); - } else { - *mptr++ = 0xD0000000|direction|len; - *mptr++ = addr; - } + *mptr++ = 0xD0000000|direction|len; + *mptr++ = virt_to_bus(buf); // Send it on it's way rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120); @@ -384,7 +347,7 @@ static void adpt_inquiry(adpt_hba* pHba) sprintf(pHba->detail, "Adaptec I2O RAID"); printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode); if (rcode != -ETIME && rcode != -EINTR) - dma_free_coherent(&pHba->pDev->dev, 80, buf, addr); + kfree(buf); } else { memset(pHba->detail, 0, sizeof(pHba->detail)); memcpy(&(pHba->detail), "Vendor: Adaptec ", 16); @@ -393,7 +356,7 @@ static void adpt_inquiry(adpt_hba* pHba) memcpy(&(pHba->detail[40]), " FW: ", 4); memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4); pHba->detail[48] = '\0'; /* precautionary */ - dma_free_coherent(&pHba->pDev->dev, 80, buf, addr); + kfree(buf); } adpt_i2o_status_get(pHba); return ; @@ -669,91 +632,6 @@ static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, of return len; } -/* - * Turn a struct scsi_cmnd * into a unique 32 bit 'context'. - */ -static u32 adpt_cmd_to_context(struct scsi_cmnd *cmd) -{ - return (u32)cmd->serial_number; -} - -/* - * Go from a u32 'context' to a struct scsi_cmnd * . - * This could probably be made more efficient. - */ -static struct scsi_cmnd * - adpt_cmd_from_context(adpt_hba * pHba, u32 context) -{ - struct scsi_cmnd * cmd; - struct scsi_device * d; - - if (context == 0) - return NULL; - - spin_unlock(pHba->host->host_lock); - shost_for_each_device(d, pHba->host) { - unsigned long flags; - spin_lock_irqsave(&d->list_lock, flags); - list_for_each_entry(cmd, &d->cmd_list, list) { - if (((u32)cmd->serial_number == context)) { - spin_unlock_irqrestore(&d->list_lock, flags); - scsi_device_put(d); - spin_lock(pHba->host->host_lock); - return cmd; - } - } - spin_unlock_irqrestore(&d->list_lock, flags); - } - spin_lock(pHba->host->host_lock); - - return NULL; -} - -/* - * Turn a pointer to ioctl reply data into an u32 'context' - */ -static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply) -{ -#if BITS_PER_LONG == 32 - return (u32)(unsigned long)reply; -#else - ulong flags = 0; - u32 nr, i; - - spin_lock_irqsave(pHba->host->host_lock, flags); - nr = ARRAY_SIZE(pHba->ioctl_reply_context); - for (i = 0; i < nr; i++) { - if (pHba->ioctl_reply_context[i] == NULL) { - pHba->ioctl_reply_context[i] = reply; - break; - } - } - spin_unlock_irqrestore(pHba->host->host_lock, flags); - if (i >= nr) { - kfree (reply); - printk(KERN_WARNING"%s: Too many outstanding " - "ioctl commands\n", pHba->name); - return (u32)-1; - } - - return i; -#endif -} - -/* - * Go from an u32 'context' to a pointer to ioctl reply data. - */ -static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context) -{ -#if BITS_PER_LONG == 32 - return (void *)(unsigned long)context; -#else - void *p = pHba->ioctl_reply_context[context]; - pHba->ioctl_reply_context[context] = NULL; - - return p; -#endif -} /*=========================================================================== * Error Handling routines @@ -782,7 +660,7 @@ static int adpt_abort(struct scsi_cmnd * cmd) msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid; msg[2] = 0; msg[3]= 0; - msg[4] = adpt_cmd_to_context(cmd); + msg[4] = (u32)cmd; if (pHba->host) spin_lock_irq(pHba->host->host_lock); rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); @@ -983,6 +861,27 @@ static void adpt_i2o_sys_shutdown(void) printk(KERN_INFO "Adaptec I2O controllers down.\n"); } +/* + * reboot/shutdown notification. + * + * - Quiesce each IOP in the system + * + */ + +#ifdef REBOOT_NOTIFIER +static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p) +{ + + if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF) + return NOTIFY_DONE; + + adpt_i2o_sys_shutdown(); + + return NOTIFY_DONE; +} +#endif + + static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) { @@ -994,7 +893,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev u32 hba_map1_area_size = 0; void __iomem *base_addr_virt = NULL; void __iomem *msg_addr_virt = NULL; - int dma64 = 0; int raptorFlag = FALSE; @@ -1008,21 +906,9 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev } pci_set_master(pDev); - - /* - * See if we should enable dma64 mode. - */ - if (sizeof(dma_addr_t) > 4 && - pci_set_dma_mask(pDev, DMA_64BIT_MASK) == 0) { - if (dma_get_required_mask(&pDev->dev) > DMA_32BIT_MASK) - dma64 = 1; - } - if (!dma64 && pci_set_dma_mask(pDev, DMA_32BIT_MASK) != 0) + if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) return -EINVAL; - /* adapter only supports message blocks below 4GB */ - pci_set_consistent_dma_mask(pDev, DMA_32BIT_MASK); - base_addr0_phys = pci_resource_start(pDev,0); hba_map0_area_size = pci_resource_len(pDev,0); @@ -1043,25 +929,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev raptorFlag = TRUE; } -#if BITS_PER_LONG == 64 - /* - * The original Adaptec 64 bit driver has this comment here: - * "x86_64 machines need more optimal mappings" - * - * I assume some HBAs report ridiculously large mappings - * and we need to limit them on platforms with IOMMUs. - */ - if (raptorFlag == TRUE) { - if (hba_map0_area_size > 128) - hba_map0_area_size = 128; - if (hba_map1_area_size > 524288) - hba_map1_area_size = 524288; - } else { - if (hba_map0_area_size > 524288) - hba_map0_area_size = 524288; - } -#endif - base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size); if (!base_addr_virt) { pci_release_regions(pDev); @@ -1124,22 +991,16 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev pHba->state = DPTI_STATE_RESET; pHba->pDev = pDev; pHba->devices = NULL; - pHba->dma64 = dma64; // Initializing the spinlocks spin_lock_init(&pHba->state_lock); spin_lock_init(&adpt_post_wait_lock); if(raptorFlag == 0){ - printk(KERN_INFO "Adaptec I2O RAID controller" - " %d at %p size=%x irq=%d%s\n", - hba_count-1, base_addr_virt, - hba_map0_area_size, pDev->irq, - dma64 ? " (64-bit DMA)" : ""); + printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", + hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq); } else { - printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d%s\n", - hba_count-1, pDev->irq, - dma64 ? " (64-bit DMA)" : ""); + printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq); printk(KERN_INFO" BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size); printk(KERN_INFO" BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size); } @@ -1192,26 +1053,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) if(pHba->msg_addr_virt != pHba->base_addr_virt){ iounmap(pHba->msg_addr_virt); } - if(pHba->FwDebugBuffer_P) - iounmap(pHba->FwDebugBuffer_P); - if(pHba->hrt) { - dma_free_coherent(&pHba->pDev->dev, - pHba->hrt->num_entries * pHba->hrt->entry_len << 2, - pHba->hrt, pHba->hrt_pa); - } - if(pHba->lct) { - dma_free_coherent(&pHba->pDev->dev, pHba->lct_size, - pHba->lct, pHba->lct_pa); - } - if(pHba->status_block) { - dma_free_coherent(&pHba->pDev->dev, sizeof(i2o_status_block), - pHba->status_block, pHba->status_block_pa); - } - if(pHba->reply_pool) { - dma_free_coherent(&pHba->pDev->dev, - pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, - pHba->reply_pool, pHba->reply_pool_pa); - } + kfree(pHba->hrt); + kfree(pHba->lct); + kfree(pHba->status_block); + kfree(pHba->reply_pool); for(d = pHba->devices; d ; d = next){ next = d->next; @@ -1230,19 +1075,23 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) pci_dev_put(pHba->pDev); kfree(pHba); - if (adpt_sysfs_class) - device_destroy(adpt_sysfs_class, - MKDEV(DPTI_I2O_MAJOR, pHba->unit)); - if(hba_count <= 0){ unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER); - if (adpt_sysfs_class) { - class_destroy(adpt_sysfs_class); - adpt_sysfs_class = NULL; - } } } + +static int adpt_init(void) +{ + printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); +#ifdef REBOOT_NOTIFIER + register_reboot_notifier(&adpt_reboot_notifier); +#endif + + return 0; +} + + static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun) { struct adpt_device* d; @@ -1434,7 +1283,6 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) { u32 msg[8]; u8* status; - dma_addr_t addr; u32 m = EMPTY_QUEUE ; ulong timeout = jiffies + (TMOUT_IOPRESET*HZ); @@ -1457,13 +1305,12 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) schedule_timeout_uninterruptible(1); } while (m == EMPTY_QUEUE); - status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL); + status = kzalloc(4, GFP_KERNEL|ADDR32); if(status == NULL) { adpt_send_nop(pHba, m); printk(KERN_ERR"IOP reset failed - no free memory.\n"); return -ENOMEM; } - memset(status,0,4); msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0; msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID; @@ -1471,8 +1318,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) msg[3]=0; msg[4]=0; msg[5]=0; - msg[6]=dma_low(addr); - msg[7]=dma_high(addr); + msg[6]=virt_to_bus(status); + msg[7]=0; memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg)); wmb(); @@ -1482,10 +1329,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) while(*status == 0){ if(time_after(jiffies,timeout)){ printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name); - /* We lose 4 bytes of "status" here, but we cannot - free these because controller may awake and corrupt - those bytes at any time */ - /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */ + kfree(status); return -ETIMEDOUT; } rmb(); @@ -1504,10 +1348,6 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) } if(time_after(jiffies,timeout)){ printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name); - /* We lose 4 bytes of "status" here, but we - cannot free these because controller may - awake and corrupt those bytes at any time */ - /* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */ return -ETIMEDOUT; } schedule_timeout_uninterruptible(1); @@ -1524,7 +1364,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) PDEBUG("%s: Reset completed.\n", pHba->name); } - dma_free_coherent(&pHba->pDev->dev, 4, status, addr); + kfree(status); #ifdef UARTDELAY // This delay is to allow someone attached to the card through the debug UART to // set up the dump levels that they want before the rest of the initialization sequence @@ -1796,7 +1636,6 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) u32 i = 0; u32 rcode = 0; void *p = NULL; - dma_addr_t addr; ulong flags = 0; memset(&msg, 0, MAX_MESSAGE_SIZE*4); @@ -1829,13 +1668,10 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) } sg_offset = (msg[0]>>4)&0xf; msg[2] = 0x40000000; // IOCTL context - msg[3] = adpt_ioctl_to_context(pHba, reply); - if (msg[3] == (u32)-1) - return -EBUSY; - + msg[3] = (u32)reply; memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize); if(sg_offset) { - // TODO add 64 bit API + // TODO 64bit fix struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset); sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); if (sg_count > pHba->sg_tablesize){ @@ -1854,7 +1690,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) } sg_size = sg[i].flag_count & 0xffffff; /* Allocate memory for the transfer */ - p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL); + p = kmalloc(sg_size, GFP_KERNEL|ADDR32); if(!p) { printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", pHba->name,sg_size,i,sg_count); @@ -1864,15 +1700,15 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. /* Copy in the user's SG buffer if necessary */ if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { - // sg_simple_element API is 32 bit - if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) { + // TODO 64bit fix + if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) { printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i); rcode = -EFAULT; goto cleanup; } } - /* sg_simple_element API is 32 bit, but addr < 4GB */ - sg[i].addr_bus = addr; + //TODO 64bit fix + sg[i].addr_bus = (u32)virt_to_bus(p); } } @@ -1900,7 +1736,7 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) if(sg_offset) { /* Copy back the Scatter Gather buffers back to user space */ u32 j; - // TODO add 64 bit API + // TODO 64bit fix struct sg_simple_element* sg; int sg_size; @@ -1920,14 +1756,14 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) } sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); - // TODO add 64 bit API + // TODO 64bit fix sg = (struct sg_simple_element*)(msg + sg_offset); for (j = 0; j < sg_count; j++) { /* Copy out the SG list to user's buffer if necessary */ if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { sg_size = sg[j].flag_count & 0xffffff; - // sg_simple_element API is 32 bit - if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) { + // TODO 64bit fix + if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) { printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus); rcode = -EFAULT; goto cleanup; @@ -1951,22 +1787,56 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) cleanup: - if (rcode != -ETIME && rcode != -EINTR) { - struct sg_simple_element *sg = - (struct sg_simple_element*) (msg +sg_offset); + if (rcode != -ETIME && rcode != -EINTR) kfree (reply); - while(sg_index) { - if(sg_list[--sg_index]) { - dma_free_coherent(&pHba->pDev->dev, - sg[sg_index].flag_count & 0xffffff, - sg_list[sg_index], - sg[sg_index].addr_bus); - } + while(sg_index) { + if(sg_list[--sg_index]) { + if (rcode != -ETIME && rcode != -EINTR) + kfree(sg_list[sg_index]); } } return rcode; } + +/* + * This routine returns information about the system. This does not effect + * any logic and if the info is wrong - it doesn't matter. + */ + +/* Get all the info we can not get from kernel services */ +static int adpt_system_info(void __user *buffer) +{ + sysInfo_S si; + + memset(&si, 0, sizeof(si)); + + si.osType = OS_LINUX; + si.osMajorVersion = 0; + si.osMinorVersion = 0; + si.osRevision = 0; + si.busType = SI_PCI_BUS; + si.processorFamily = DPTI_sig.dsProcessorFamily; + +#if defined __i386__ + adpt_i386_info(&si); +#elif defined (__ia64__) + adpt_ia64_info(&si); +#elif defined(__sparc__) + adpt_sparc_info(&si); +#elif defined (__alpha__) + adpt_alpha_info(&si); +#else + si.processorType = 0xff ; +#endif + if(copy_to_user(buffer, &si, sizeof(si))){ + printk(KERN_WARNING"dpti: Could not copy buffer TO user\n"); + return -EFAULT; + } + + return 0; +} + #if defined __ia64__ static void adpt_ia64_info(sysInfo_S* si) { @@ -1977,6 +1847,7 @@ static void adpt_ia64_info(sysInfo_S* si) } #endif + #if defined __sparc__ static void adpt_sparc_info(sysInfo_S* si) { @@ -1986,6 +1857,7 @@ static void adpt_sparc_info(sysInfo_S* si) si->processorType = PROC_ULTRASPARC; } #endif + #if defined __alpha__ static void adpt_alpha_info(sysInfo_S* si) { @@ -1997,6 +1869,7 @@ static void adpt_alpha_info(sysInfo_S* si) #endif #if defined __i386__ + static void adpt_i386_info(sysInfo_S* si) { // This is all the info we need for now @@ -2017,45 +1890,9 @@ static void adpt_i386_info(sysInfo_S* si) break; } } -#endif -/* - * This routine returns information about the system. This does not effect - * any logic and if the info is wrong - it doesn't matter. - */ - -/* Get all the info we can not get from kernel services */ -static int adpt_system_info(void __user *buffer) -{ - sysInfo_S si; - - memset(&si, 0, sizeof(si)); - - si.osType = OS_LINUX; - si.osMajorVersion = 0; - si.osMinorVersion = 0; - si.osRevision = 0; - si.busType = SI_PCI_BUS; - si.processorFamily = DPTI_sig.dsProcessorFamily; - -#if defined __i386__ - adpt_i386_info(&si); -#elif defined (__ia64__) - adpt_ia64_info(&si); -#elif defined(__sparc__) - adpt_sparc_info(&si); -#elif defined (__alpha__) - adpt_alpha_info(&si); -#else - si.processorType = 0xff ; #endif - if (copy_to_user(buffer, &si, sizeof(si))){ - printk(KERN_WARNING"dpti: Could not copy buffer TO user\n"); - return -EFAULT; - } - return 0; -} static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) @@ -2141,38 +1978,6 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, return error; } -#ifdef CONFIG_COMPAT -static long compat_adpt_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct inode *inode; - long ret; - - inode = file->f_dentry->d_inode; - - lock_kernel(); - - switch(cmd) { - case DPT_SIGNATURE: - case I2OUSRCMD: - case DPT_CTRLINFO: - case DPT_SYSINFO: - case DPT_BLINKLED: - case I2ORESETCMD: - case I2ORESCANCMD: - case (DPT_TARGET_BUSY & 0xFFFF): - case DPT_TARGET_BUSY: - ret = adpt_ioctl(inode, file, cmd, arg); - break; - default: - ret = -ENOIOCTLCMD; - } - - unlock_kernel(); - - return ret; -} -#endif static irqreturn_t adpt_isr(int irq, void *dev_id) { @@ -2204,16 +2009,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id) goto out; } } - if (pHba->reply_pool_pa <= m && - m < pHba->reply_pool_pa + - (pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4)) { - reply = (u8 *)pHba->reply_pool + - (m - pHba->reply_pool_pa); - } else { - /* Ick, we should *never* be here */ - printk(KERN_ERR "dpti: reply frame not from pool\n"); - reply = (u8 *)bus_to_virt(m); - } + reply = bus_to_virt(m); if (readl(reply) & MSG_FAIL) { u32 old_m = readl(reply+28); @@ -2233,7 +2029,7 @@ static irqreturn_t adpt_isr(int irq, void *dev_id) } context = readl(reply+8); if(context & 0x40000000){ // IOCTL - void *p = adpt_ioctl_from_context(pHba, readl(reply+12)); + void *p = (void *)readl(reply+12); if( p != NULL) { memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4); } @@ -2247,17 +2043,15 @@ static irqreturn_t adpt_isr(int irq, void *dev_id) status = I2O_POST_WAIT_OK; } if(!(context & 0x40000000)) { - cmd = adpt_cmd_from_context(pHba, - readl(reply+12)); + cmd = (struct scsi_cmnd*) readl(reply+12); if(cmd != NULL) { printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); } } adpt_i2o_post_wait_complete(context, status); } else { // SCSI message - cmd = adpt_cmd_from_context (pHba, readl(reply+12)); + cmd = (struct scsi_cmnd*) readl(reply+12); if(cmd != NULL){ - scsi_dma_unmap(cmd); if(cmd->serial_number != 0) { // If not timedout adpt_i2o_to_scsi(reply, cmd); } @@ -2278,7 +2072,6 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d int i; u32 msg[MAX_MESSAGE_SIZE]; u32* mptr; - u32* lptr; u32 *lenptr; int direction; int scsidir; @@ -2286,7 +2079,6 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d u32 len; u32 reqlen; s32 rcode; - dma_addr_t addr; memset(msg, 0 , sizeof(msg)); len = scsi_bufflen(cmd); @@ -2326,7 +2118,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d // I2O_CMD_SCSI_EXEC msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid); msg[2] = 0; - msg[3] = adpt_cmd_to_context(cmd); /* Want SCSI control block back */ + msg[3] = (u32)cmd; /* We want the SCSI control block back */ // Our cards use the transaction context as the tag for queueing // Adaptec/DPT Private stuff msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16); @@ -2344,13 +2136,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d memcpy(mptr, cmd->cmnd, cmd->cmd_len); mptr+=4; lenptr=mptr++; /* Remember me - fill in when we know */ - if (dpt_dma64(pHba)) { - reqlen = 16; // SINGLE SGE - *mptr++ = (0x7C<<24)+(2<<16)+0x02; /* Enable 64 bit */ - *mptr++ = 1 << PAGE_SHIFT; - } else { - reqlen = 14; // SINGLE SGE - } + reqlen = 14; // SINGLE SGE /* Now fill in the SGList and command */ nseg = scsi_dma_map(cmd); @@ -2360,16 +2146,12 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d len = 0; scsi_for_each_sg(cmd, sg, nseg, i) { - lptr = mptr; *mptr++ = direction|0x10000000|sg_dma_len(sg); len+=sg_dma_len(sg); - addr = sg_dma_address(sg); - *mptr++ = dma_low(addr); - if (dpt_dma64(pHba)) - *mptr++ = dma_high(addr); + *mptr++ = sg_dma_address(sg); /* Make this an end of list */ if (i == nseg - 1) - *lptr = direction|0xD0000000|sg_dma_len(sg); + mptr[-2] = direction|0xD0000000|sg_dma_len(sg); } reqlen = mptr - msg; *lenptr = len; @@ -2395,13 +2177,13 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d } -static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht) +static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) { - struct Scsi_Host *host; + struct Scsi_Host *host = NULL; - host = scsi_host_alloc(sht, sizeof(adpt_hba*)); + host = scsi_register(sht, sizeof(adpt_hba*)); if (host == NULL) { - printk("%s: scsi_host_alloc returned NULL\n", pHba->name); + printk ("%s: scsi_register returned NULL\n",pHba->name); return -1; } host->hostdata[0] = (unsigned long)pHba; @@ -2418,7 +2200,7 @@ static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht) host->max_lun = 256; host->max_channel = pHba->top_scsi_channel + 1; host->cmd_per_lun = 1; - host->unique_id = (u32)sys_tbl_pa + pHba->unit; + host->unique_id = (uint) pHba; host->sg_tablesize = pHba->sg_tablesize; host->can_queue = pHba->post_fifo_size; @@ -2858,10 +2640,11 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m) static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) { u8 *status; - dma_addr_t addr; u32 __iomem *msg = NULL; int i; ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ; + u32* ptr; + u32 outbound_frame; // This had to be a 32 bit address u32 m; do { @@ -2880,14 +2663,13 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) msg=(u32 __iomem *)(pHba->msg_addr_virt+m); - status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL); + status = kzalloc(4, GFP_KERNEL|ADDR32); if (!status) { adpt_send_nop(pHba, m); printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n", pHba->name); return -ENOMEM; } - memset(status, 0, 4); writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); @@ -2896,7 +2678,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) writel(4096, &msg[4]); /* Host page frame size */ writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]); /* Outbound msg frame size and Initcode */ writel(0xD0000004, &msg[6]); /* Simple SG LE, EOB */ - writel((u32)addr, &msg[7]); + writel(virt_to_bus(status), &msg[7]); writel(m, pHba->post_port); wmb(); @@ -2911,10 +2693,6 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) rmb(); if(time_after(jiffies,timeout)){ printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name); - /* We lose 4 bytes of "status" here, but we - cannot free these because controller may - awake and corrupt those bytes at any time */ - /* dma_free_coherent(&pHba->pDev->dev, 4, status, addr); */ return -ETIMEDOUT; } schedule_timeout_uninterruptible(1); @@ -2923,30 +2701,25 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) // If the command was successful, fill the fifo with our reply // message packets if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) { - dma_free_coherent(&pHba->pDev->dev, 4, status, addr); + kfree(status); return -2; } - dma_free_coherent(&pHba->pDev->dev, 4, status, addr); + kfree(status); - if(pHba->reply_pool != NULL) { - dma_free_coherent(&pHba->pDev->dev, - pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, - pHba->reply_pool, pHba->reply_pool_pa); - } + kfree(pHba->reply_pool); - pHba->reply_pool = dma_alloc_coherent(&pHba->pDev->dev, - pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, - &pHba->reply_pool_pa, GFP_KERNEL); + pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); if (!pHba->reply_pool) { printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name); return -ENOMEM; } - memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4); + ptr = pHba->reply_pool; for(i = 0; i < pHba->reply_fifo_size; i++) { - writel(pHba->reply_pool_pa + (i * REPLY_FRAME_SIZE * 4), - pHba->reply_port); + outbound_frame = (u32)virt_to_bus(ptr); + writel(outbound_frame, pHba->reply_port); wmb(); + ptr += REPLY_FRAME_SIZE; } adpt_i2o_status_get(pHba); return 0; @@ -2970,11 +2743,11 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) u32 m; u32 __iomem *msg; u8 *status_block=NULL; + ulong status_block_bus; if(pHba->status_block == NULL) { - pHba->status_block = dma_alloc_coherent(&pHba->pDev->dev, - sizeof(i2o_status_block), - &pHba->status_block_pa, GFP_KERNEL); + pHba->status_block = (i2o_status_block*) + kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32); if(pHba->status_block == NULL) { printk(KERN_ERR "dpti%d: Get Status Block failed; Out of memory. \n", @@ -2984,6 +2757,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) } memset(pHba->status_block, 0, sizeof(i2o_status_block)); status_block = (u8*)(pHba->status_block); + status_block_bus = virt_to_bus(pHba->status_block); timeout = jiffies+TMOUT_GETSTATUS*HZ; do { rmb(); @@ -3008,8 +2782,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) writel(0, &msg[3]); writel(0, &msg[4]); writel(0, &msg[5]); - writel( dma_low(pHba->status_block_pa), &msg[6]); - writel( dma_high(pHba->status_block_pa), &msg[7]); + writel(((u32)status_block_bus)&0xffffffff, &msg[6]); + writel(0, &msg[7]); writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes //post message @@ -3038,17 +2812,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) } // Calculate the Scatter Gather list size - if (dpt_dma64(pHba)) { - pHba->sg_tablesize - = ((pHba->status_block->inbound_frame_size * 4 - - 14 * sizeof(u32)) - / (sizeof(struct sg_simple_element) + sizeof(u32))); - } else { - pHba->sg_tablesize - = ((pHba->status_block->inbound_frame_size * 4 - - 12 * sizeof(u32)) - / sizeof(struct sg_simple_element)); - } + pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element); if (pHba->sg_tablesize > SG_LIST_ELEMENTS) { pHba->sg_tablesize = SG_LIST_ELEMENTS; } @@ -3099,9 +2863,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) } do { if (pHba->lct == NULL) { - pHba->lct = dma_alloc_coherent(&pHba->pDev->dev, - pHba->lct_size, &pHba->lct_pa, - GFP_KERNEL); + pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32); if(pHba->lct == NULL) { printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n", pHba->name); @@ -3117,7 +2879,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) msg[4] = 0xFFFFFFFF; /* All devices */ msg[5] = 0x00000000; /* Report now */ msg[6] = 0xD0000000|pHba->lct_size; - msg[7] = (u32)pHba->lct_pa; + msg[7] = virt_to_bus(pHba->lct); if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) { printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", @@ -3128,8 +2890,7 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) if ((pHba->lct->table_size << 2) > pHba->lct_size) { pHba->lct_size = pHba->lct->table_size << 2; - dma_free_coherent(&pHba->pDev->dev, pHba->lct_size, - pHba->lct, pHba->lct_pa); + kfree(pHba->lct); pHba->lct = NULL; } } while (pHba->lct == NULL); @@ -3140,19 +2901,13 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO; if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) { pHba->FwDebugBufferSize = buf[1]; - pHba->FwDebugBuffer_P = ioremap(pHba->base_addr_phys + buf[0], - pHba->FwDebugBufferSize); - if (pHba->FwDebugBuffer_P) { - pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + - FW_DEBUG_FLAGS_OFFSET; - pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + - FW_DEBUG_BLED_OFFSET; - pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1; - pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + - FW_DEBUG_STR_LENGTH_OFFSET; - pHba->FwDebugBuffer_P += buf[2]; - pHba->FwDebugFlags = 0; - } + pHba->FwDebugBuffer_P = pHba->base_addr_virt + buf[0]; + pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET; + pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET; + pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1; + pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET; + pHba->FwDebugBuffer_P += buf[2]; + pHba->FwDebugFlags = 0; } return 0; @@ -3160,30 +2915,25 @@ static int adpt_i2o_lct_get(adpt_hba* pHba) static int adpt_i2o_build_sys_table(void) { - adpt_hba* pHba = hba_chain; + adpt_hba* pHba = NULL; int count = 0; - if (sys_tbl) - dma_free_coherent(&pHba->pDev->dev, sys_tbl_len, - sys_tbl, sys_tbl_pa); - sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs (hba_count) * sizeof(struct i2o_sys_tbl_entry); - sys_tbl = dma_alloc_coherent(&pHba->pDev->dev, - sys_tbl_len, &sys_tbl_pa, GFP_KERNEL); + kfree(sys_tbl); + + sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32); if (!sys_tbl) { printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); return -ENOMEM; } - memset(sys_tbl, 0, sys_tbl_len); sys_tbl->num_entries = hba_count; sys_tbl->version = I2OVERSION; sys_tbl->change_ind = sys_tbl_ind++; for(pHba = hba_chain; pHba; pHba = pHba->next) { - u64 addr; // Get updated Status Block so we have the latest information if (adpt_i2o_status_get(pHba)) { sys_tbl->num_entries--; @@ -3199,9 +2949,8 @@ static int adpt_i2o_build_sys_table(void) sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size; sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ?? sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities; - addr = pHba->base_addr_phys + 0x40; - sys_tbl->iops[count].inbound_low = dma_low(addr); - sys_tbl->iops[count].inbound_high = dma_high(addr); + sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port); + sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32); count++; } @@ -3337,8 +3086,7 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba) do { if (pHba->hrt == NULL) { - pHba->hrt = dma_alloc_coherent(&pHba->pDev->dev, - size, &pHba->hrt_pa, GFP_KERNEL); + pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32); if (pHba->hrt == NULL) { printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name); return -ENOMEM; @@ -3350,7 +3098,7 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba) msg[2]= 0; msg[3]= 0; msg[4]= (0xD0000000 | size); /* Simple transaction */ - msg[5]= (u32)pHba->hrt_pa; /* Dump it here */ + msg[5]= virt_to_bus(pHba->hrt); /* Dump it here */ if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) { printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret); @@ -3358,10 +3106,8 @@ static s32 adpt_i2o_hrt_get(adpt_hba* pHba) } if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) { - int newsize = pHba->hrt->num_entries * pHba->hrt->entry_len << 2; - dma_free_coherent(&pHba->pDev->dev, size, - pHba->hrt, pHba->hrt_pa); - size = newsize; + size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2; + kfree(pHba->hrt); pHba->hrt = NULL; } } while(pHba->hrt == NULL); @@ -3375,54 +3121,33 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, int group, int field, void *buf, int buflen) { u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; - u8 *opblk_va; - dma_addr_t opblk_pa; - u8 *resblk_va; - dma_addr_t resblk_pa; + u8 *resblk; int size; /* 8 bytes for header */ - resblk_va = dma_alloc_coherent(&pHba->pDev->dev, - sizeof(u8) * (8 + buflen), &resblk_pa, GFP_KERNEL); - if (resblk_va == NULL) { + resblk = kmalloc(sizeof(u8) * (8+buflen), GFP_KERNEL|ADDR32); + if (resblk == NULL) { printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name); return -ENOMEM; } - opblk_va = dma_alloc_coherent(&pHba->pDev->dev, - sizeof(opblk), &opblk_pa, GFP_KERNEL); - if (opblk_va == NULL) { - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); - printk(KERN_CRIT "%s: query operatio failed; Out of memory.\n", - pHba->name); - return -ENOMEM; - } if (field == -1) /* whole group */ opblk[4] = -1; - memcpy(opblk_va, opblk, sizeof(opblk)); size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, - opblk_va, opblk_pa, sizeof(opblk), - resblk_va, resblk_pa, sizeof(u8)*(8+buflen)); - dma_free_coherent(&pHba->pDev->dev, sizeof(opblk), opblk_va, opblk_pa); + opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen)); if (size == -ETIME) { - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name); return -ETIME; } else if (size == -EINTR) { - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name); return -EINTR; } - memcpy(buf, resblk_va+8, buflen); /* cut off header */ + memcpy(buf, resblk+8, buflen); /* cut off header */ - dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen), - resblk_va, resblk_pa); + kfree(resblk); if (size < 0) return size; @@ -3439,11 +3164,10 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. */ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, - void *opblk_va, dma_addr_t opblk_pa, int oplen, - void *resblk_va, dma_addr_t resblk_pa, int reslen) + void *opblk, int oplen, void *resblk, int reslen) { u32 msg[9]; - u32 *res = (u32 *)resblk_va; + u32 *res = (u32 *)resblk; int wait_status; msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5; @@ -3452,12 +3176,12 @@ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, msg[3] = 0; msg[4] = 0; msg[5] = 0x54000000 | oplen; /* OperationBlock */ - msg[6] = (u32)opblk_pa; + msg[6] = virt_to_bus(opblk); msg[7] = 0xD0000000 | reslen; /* ResultBlock */ - msg[8] = (u32)resblk_pa; + msg[8] = virt_to_bus(resblk); if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) { - printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk_va); + printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk); return wait_status; /* -DetailedStatus */ } @@ -3560,7 +3284,7 @@ static int adpt_i2o_systab_send(adpt_hba* pHba) * Private i/o space declaration */ msg[6] = 0x54000000 | sys_tbl_len; - msg[7] = (u32)sys_tbl_pa; + msg[7] = virt_to_phys(sys_tbl); msg[8] = 0x54000000 | 0; msg[9] = 0; msg[10] = 0xD4000000 | 0; @@ -3599,10 +3323,11 @@ static static void adpt_delay(int millisec) #endif static struct scsi_host_template driver_template = { - .module = THIS_MODULE, .name = "dpt_i2o", .proc_name = "dpt_i2o", .proc_info = adpt_proc_info, + .detect = adpt_detect, + .release = adpt_release, .info = adpt_info, .queuecommand = adpt_queue, .eh_abort_handler = adpt_abort, @@ -3616,48 +3341,5 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, }; - -static int __init adpt_init(void) -{ - int error; - adpt_hba *pHba, *next; - - printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); - - error = adpt_detect(&driver_template); - if (error < 0) - return error; - if (hba_chain == NULL) - return -ENODEV; - - for (pHba = hba_chain; pHba; pHba = pHba->next) { - error = scsi_add_host(pHba->host, &pHba->pDev->dev); - if (error) - goto fail; - scsi_scan_host(pHba->host); - } - return 0; -fail: - for (pHba = hba_chain; pHba; pHba = next) { - next = pHba->next; - scsi_remove_host(pHba->host); - } - return error; -} - -static void __exit adpt_exit(void) -{ - adpt_hba *pHba, *next; - - for (pHba = hba_chain; pHba; pHba = pHba->next) - scsi_remove_host(pHba->host); - for (pHba = hba_chain; pHba; pHba = next) { - next = pHba->next; - adpt_release(pHba->host); - } -} - -module_init(adpt_init); -module_exit(adpt_exit); - +#include "scsi_module.c" MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/scsi/dpti.h b/trunk/drivers/scsi/dpti.h index 337746d46043..fd79068c5869 100644 --- a/trunk/drivers/scsi/dpti.h +++ b/trunk/drivers/scsi/dpti.h @@ -84,6 +84,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd); #define PCI_DPT_DEVICE_ID (0xA501) // DPT PCI I2O Device ID #define PCI_DPT_RAPTOR_DEVICE_ID (0xA511) +//#define REBOOT_NOTIFIER 1 /* Debugging macro from Linux Device Drivers - Rubini */ #undef PDEBUG #ifdef DEBUG @@ -228,19 +229,14 @@ typedef struct _adpt_hba { u32 post_fifo_size; u32 reply_fifo_size; u32* reply_pool; - dma_addr_t reply_pool_pa; u32 sg_tablesize; // Scatter/Gather List Size. u8 top_scsi_channel; u8 top_scsi_id; u8 top_scsi_lun; - u8 dma64; i2o_status_block* status_block; - dma_addr_t status_block_pa; i2o_hrt* hrt; - dma_addr_t hrt_pa; i2o_lct* lct; - dma_addr_t lct_pa; uint lct_size; struct i2o_device* devices; struct adpt_channel channel[MAX_CHANNEL]; @@ -253,7 +249,6 @@ typedef struct _adpt_hba { void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED u32 FwDebugFlags; - u32 *ioctl_reply_context[4]; } adpt_hba; struct sg_simple_element { @@ -269,6 +264,9 @@ static void adpt_i2o_sys_shutdown(void); static int adpt_init(void); static int adpt_i2o_build_sys_table(void); static irqreturn_t adpt_isr(int irq, void *dev_id); +#ifdef REBOOT_NOTIFIER +static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p); +#endif static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d); static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, @@ -277,8 +275,7 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, static const char *adpt_i2o_get_class_name(int class); #endif static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, - void *opblk, dma_addr_t opblk_pa, int oplen, - void *resblk, dma_addr_t resblk_pa, int reslen); + void *opblk, int oplen, void *resblk, int reslen); static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout); static int adpt_i2o_lct_get(adpt_hba* pHba); static int adpt_i2o_parse_lct(adpt_hba* pHba); @@ -292,7 +289,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba); static s32 adpt_i2o_hrt_get(adpt_hba* pHba); static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd); -static s32 adpt_scsi_host_alloc(adpt_hba* pHba,struct scsi_host_template * sht); +static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht); static s32 adpt_hba_reset(adpt_hba* pHba); static s32 adpt_i2o_reset_hba(adpt_hba* pHba); static s32 adpt_rescan(adpt_hba* pHba); @@ -316,6 +313,19 @@ static int adpt_close(struct inode *inode, struct file *file); static void adpt_delay(int millisec); #endif +#if defined __ia64__ +static void adpt_ia64_info(sysInfo_S* si); +#endif +#if defined __sparc__ +static void adpt_sparc_info(sysInfo_S* si); +#endif +#if defined __alpha__ +static void adpt_sparc_info(sysInfo_S* si); +#endif +#if defined __i386__ +static void adpt_i386_info(sysInfo_S* si); +#endif + #define PRINT_BUFFER_SIZE 512 #define HBA_FLAGS_DBG_FLAGS_MASK 0xffff0000 // Mask for debug flags diff --git a/trunk/drivers/scsi/gdth.c b/trunk/drivers/scsi/gdth.c index 8e2e964af668..c6d6e7c6559a 100644 --- a/trunk/drivers/scsi/gdth.c +++ b/trunk/drivers/scsi/gdth.c @@ -465,7 +465,7 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; scp->cmd_len = 12; - scp->cmnd = cmnd; + memcpy(scp->cmnd, cmnd, 12); cmndinfo.priority = IOCTL_PRI; cmndinfo.internal_cmd_str = gdtcmd; cmndinfo.internal_command = 1; diff --git a/trunk/drivers/scsi/hptiop.c b/trunk/drivers/scsi/hptiop.c index aaa48e0c8ed0..5b7be1e9841c 100644 --- a/trunk/drivers/scsi/hptiop.c +++ b/trunk/drivers/scsi/hptiop.c @@ -763,9 +763,9 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp, scp, host->host_no, scp->device->channel, scp->device->id, scp->device->lun, - ((u32 *)scp->cmnd)[0], - ((u32 *)scp->cmnd)[1], - ((u32 *)scp->cmnd)[2], + *((u32 *)&scp->cmnd), + *((u32 *)&scp->cmnd + 1), + *((u32 *)&scp->cmnd + 2), _req->index, _req->req_virt); scp->result = 0; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index ccfd8aca3765..4a922c57125e 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -686,7 +686,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct) } if (cmnd) { - cmnd->result |= rsp->status; + cmnd->result = rsp->status; if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION) memcpy(cmnd->sense_buffer, rsp->data, @@ -730,7 +730,6 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, u16 lun = lun_from_dev(cmnd->device); u8 out_fmt, in_fmt; - cmnd->result = (DID_OK << 16); evt_struct = get_event_struct(&hostdata->pool); if (!evt_struct) return SCSI_MLQUEUE_HOST_BUSY; @@ -739,7 +738,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd, srp_cmd = &evt_struct->iu.srp.cmd; memset(srp_cmd, 0x00, SRP_MAX_IU_LEN); srp_cmd->opcode = SRP_CMD; - memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(srp_cmd->cdb)); + memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd)); srp_cmd->lun = ((u64) lun) << 48; if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) { @@ -1348,8 +1347,6 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, del_timer(&evt_struct->timer); - if (crq->status != VIOSRP_OK && evt_struct->cmnd) - evt_struct->cmnd->result = DID_ERROR << 16; if (evt_struct->done) evt_struct->done(evt_struct); else diff --git a/trunk/drivers/scsi/ibmvscsi/viosrp.h b/trunk/drivers/scsi/ibmvscsi/viosrp.h index 4c4aadb3e405..90f1a61283ad 100644 --- a/trunk/drivers/scsi/ibmvscsi/viosrp.h +++ b/trunk/drivers/scsi/ibmvscsi/viosrp.h @@ -59,15 +59,6 @@ enum viosrp_crq_formats { VIOSRP_INLINE_FORMAT = 0x07 }; -enum viosrp_crq_status { - VIOSRP_OK = 0x0, - VIOSRP_NONRECOVERABLE_ERR = 0x1, - VIOSRP_VIOLATES_MAX_XFER = 0x2, - VIOSRP_PARTNER_PANIC = 0x3, - VIOSRP_DEVICE_BUSY = 0x8, - VIOSRP_ADAPTER_FAIL = 0x10 -}; - struct viosrp_crq { u8 valid; /* used by RPA */ u8 format; /* SCSI vs out-of-band */ diff --git a/trunk/drivers/scsi/initio.c b/trunk/drivers/scsi/initio.c index e3f739776bad..dbae3fdb8506 100644 --- a/trunk/drivers/scsi/initio.c +++ b/trunk/drivers/scsi/initio.c @@ -2590,7 +2590,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c cblk->hastat = 0; cblk->tastat = 0; /* Command the command */ - memcpy(cblk->cdb, cmnd->cmnd, cmnd->cmd_len); + memcpy(&cblk->cdb[0], &cmnd->cmnd, cmnd->cmd_len); /* Set up tags */ if (cmnd->device->tagged_supported) { /* Tag Support */ diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 999e91ea7451..de5ae6a65029 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -2791,7 +2791,7 @@ static ssize_t ipr_store_adapter_state(struct device *dev, static struct device_attribute ipr_ioa_state_attr = { .attr = { - .name = "online_state", + .name = "state", .mode = S_IRUGO | S_IWUSR, }, .show = ipr_show_adapter_state, diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.c b/trunk/drivers/scsi/megaraid/megaraid_mbox.c index 70a0f11f48b2..820f91fb63ba 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.c @@ -3168,23 +3168,6 @@ megaraid_mbox_support_random_del(adapter_t *adapter) uint8_t raw_mbox[sizeof(mbox_t)]; int rval; - /* - * Newer firmware on Dell CERC expect a different - * random deletion handling, so disable it. - */ - if (adapter->pdev->vendor == PCI_VENDOR_ID_AMI && - adapter->pdev->device == PCI_DEVICE_ID_AMI_MEGARAID3 && - adapter->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && - adapter->pdev->subsystem_device == PCI_SUBSYS_ID_CERC_ATA100_4CH && - (adapter->fw_version[0] > '6' || - (adapter->fw_version[0] == '6' && - adapter->fw_version[2] > '6') || - (adapter->fw_version[0] == '6' - && adapter->fw_version[2] == '6' - && adapter->fw_version[3] > '1'))) { - con_log(CL_DLEVEL1, ("megaraid: disable random deletion\n")); - return 0; - } mbox = (mbox_t *)raw_mbox; diff --git a/trunk/drivers/scsi/megaraid/megaraid_mbox.h b/trunk/drivers/scsi/megaraid/megaraid_mbox.h index c1d86d961a92..626459d1e902 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mbox.h +++ b/trunk/drivers/scsi/megaraid/megaraid_mbox.h @@ -88,7 +88,6 @@ #define PCI_SUBSYS_ID_PERC3_QC 0x0471 #define PCI_SUBSYS_ID_PERC3_DC 0x0493 #define PCI_SUBSYS_ID_PERC3_SC 0x0475 -#define PCI_SUBSYS_ID_CERC_ATA100_4CH 0x0511 #define MBOX_MAX_SCSI_CMDS 128 // number of cmds reserved for kernel diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.c b/trunk/drivers/scsi/megaraid/megaraid_sas.c index 7d84c8bbcf3f..b937e9cddb23 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.03.20-rc1 + * Version : v00.00.03.16-rc1 * * Authors: * (email-id : megaraidlinux@lsi.com) @@ -2650,13 +2650,12 @@ static void megasas_shutdown_controller(struct megasas_instance *instance, return; } -#ifdef CONFIG_PM /** * megasas_suspend - driver suspend entry point * @pdev: PCI device structure * @state: PCI power state to suspend routine */ -static int +static int __devinit megasas_suspend(struct pci_dev *pdev, pm_message_t state) { struct Scsi_Host *host; @@ -2688,7 +2687,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) * megasas_resume- driver resume entry point * @pdev: PCI device structure */ -static int +static int __devinit megasas_resume(struct pci_dev *pdev) { int rval; @@ -2783,16 +2782,12 @@ megasas_resume(struct pci_dev *pdev) return -ENODEV; } -#else -#define megasas_suspend NULL -#define megasas_resume NULL -#endif /** * megasas_detach_one - PCI hot"un"plug entry point * @pdev: PCI device structure */ -static void __devexit megasas_detach_one(struct pci_dev *pdev) +static void megasas_detach_one(struct pci_dev *pdev) { int i; struct Scsi_Host *host; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index b0c41e671702..3a997eb457bf 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.03.20-rc1" -#define MEGASAS_RELDATE "March 10, 2008" -#define MEGASAS_EXT_VERSION "Mon. March 10 11:02:31 PDT 2008" +#define MEGASAS_VERSION "00.00.03.16-rc1" +#define MEGASAS_RELDATE "Nov. 07, 2007" +#define MEGASAS_EXT_VERSION "Thu. Nov. 07 10:09:32 PDT 2007" /* * Device IDs 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/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c index fa060932d2b4..09ab3eac1c1a 100644 --- a/trunk/drivers/scsi/qla1280.c +++ b/trunk/drivers/scsi/qla1280.c @@ -2858,7 +2858,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) /* Load SCSI command packet. */ pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); - memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ /* Set transfer direction. */ @@ -3127,7 +3127,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) /* Load SCSI command packet. */ pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd)); - memcpy(pkt->scsi_cdb, CMD_CDBP(cmd), CMD_CDBLEN(cmd)); + memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd)); /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ /* Set transfer direction. */ diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 110e776d1a07..12d69d7c8577 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -78,6 +78,15 @@ static void scsi_done(struct scsi_cmnd *cmd); /* Do not call reset on error if we just did a reset within 15 sec. */ #define MIN_RESET_PERIOD (15*HZ) +/* + * Macro to determine the size of SCSI command. This macro takes vendor + * unique commands into account. SCSI commands in groups 6 and 7 are + * vendor unique and we will depend upon the command length being + * supplied correctly in cmd_len. + */ +#define CDB_SIZE(cmd) (((((cmd)->cmnd[0] >> 5) & 7) < 6) ? \ + COMMAND_SIZE((cmd)->cmnd[0]) : (cmd)->cmd_len) + /* * Note - the initial logging level can be set here to log events at boot time. * After the system is up, you may enable logging via the /proc interface. @@ -460,7 +469,6 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); if (!cmd) { scsi_put_host_cmd_pool(gfp_mask); - shost->cmd_pool = NULL; return -ENOMEM; } list_add(&cmd->list, &shost->free_list); @@ -473,13 +481,6 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) */ void scsi_destroy_command_freelist(struct Scsi_Host *shost) { - /* - * If cmd_pool is NULL the free list was not initialized, so - * do not attempt to release resources. - */ - if (!shost->cmd_pool) - return; - while (!list_empty(&shost->free_list)) { struct scsi_cmnd *cmd; @@ -700,11 +701,9 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) * Before we queue this command, check if the command * length exceeds what the host adapter can handle. */ - if (cmd->cmd_len > cmd->device->host->max_cmd_len) { + if (CDB_SIZE(cmd) > cmd->device->host->max_cmd_len) { SCSI_LOG_MLQUEUE(3, - printk("queuecommand : command too long. " - "cdb_size=%d host->max_cmd_len=%d\n", - cmd->cmd_len, cmd->device->host->max_cmd_len)); + printk("queuecommand : command too long.\n")); cmd->result = (DID_ABORT << 16); scsi_done(cmd); diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index eaf5a8add1ba..1eaba6cd80f4 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -626,7 +626,7 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) * @scmd: SCSI command structure to hijack * @ses: structure to save restore information * @cmnd: CDB to send. Can be NULL if no new cmnd is needed - * @cmnd_size: size in bytes of @cmnd (must be <= BLK_MAX_CDB) + * @cmnd_size: size in bytes of @cmnd * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) * * This function is used to save a scsi command information before re-execution @@ -648,14 +648,12 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, * command. */ ses->cmd_len = scmd->cmd_len; - ses->cmnd = scmd->cmnd; + memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); ses->data_direction = scmd->sc_data_direction; ses->sdb = scmd->sdb; ses->next_rq = scmd->request->next_rq; ses->result = scmd->result; - scmd->cmnd = ses->eh_cmnd; - memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(&scmd->sdb, 0, sizeof(scmd->sdb)); scmd->request->next_rq = NULL; @@ -667,13 +665,14 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, scmd->sdb.table.sgl = &ses->sense_sgl; scmd->sc_data_direction = DMA_FROM_DEVICE; scmd->sdb.table.nents = 1; + memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); scmd->cmnd[0] = REQUEST_SENSE; scmd->cmnd[4] = scmd->sdb.length; scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); } else { scmd->sc_data_direction = DMA_NONE; if (cmnd) { - BUG_ON(cmnd_size > BLK_MAX_CDB); + memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); memcpy(scmd->cmnd, cmnd, cmnd_size); scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); } @@ -706,7 +705,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) * Restore original data */ scmd->cmd_len = ses->cmd_len; - scmd->cmnd = ses->cmnd; + memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); scmd->sc_data_direction = ses->data_direction; scmd->sdb = ses->sdb; scmd->request->next_rq = ses->next_rq; @@ -1776,8 +1775,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag) scmd->request = &req; memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout)); - scmd->cmnd = req.cmd; - + memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); + scmd->scsi_done = scsi_reset_provider_done_command; memset(&scmd->sdb, 0, sizeof(scmd->sdb)); diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index a82d2fe80fb5..d545ad1cf47a 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -445,7 +445,7 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) scsi_set_resid(cmd, 0); memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); if (cmd->cmd_len == 0) - cmd->cmd_len = scsi_command_size(cmd->cmnd); + cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); } void scsi_device_unbusy(struct scsi_device *sdev) @@ -1094,8 +1094,6 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, cmd->tag = req->tag; cmd->request = req; - cmd->cmnd = req->cmd; - return cmd; } @@ -1133,6 +1131,8 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) req->buffer = NULL; } + BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); + memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); cmd->cmd_len = req->cmd_len; if (!req->data_len) cmd->sc_data_direction = DMA_NONE; @@ -1169,7 +1169,6 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) if (unlikely(!cmd)) return BLKPREP_DEFER; - memset(cmd->cmnd, 0, BLK_MAX_CDB); return scsi_init_io(cmd, GFP_ATOMIC); } EXPORT_SYMBOL(scsi_setup_fs_cmnd); diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c index 257e097c39af..ee8496aa0336 100644 --- a/trunk/drivers/scsi/scsi_tgt_lib.c +++ b/trunk/drivers/scsi/scsi_tgt_lib.c @@ -107,8 +107,6 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, cmd->jiffies_at_alloc = jiffies; cmd->request = rq; - cmd->cmnd = rq->cmd; - rq->special = cmd; rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_flags |= REQ_TYPE_BLOCK_PC; diff --git a/trunk/drivers/scsi/u14-34f.c b/trunk/drivers/scsi/u14-34f.c index 329eb8780e74..640333b1e75c 100644 --- a/trunk/drivers/scsi/u14-34f.c +++ b/trunk/drivers/scsi/u14-34f.c @@ -744,8 +744,7 @@ static int wait_on_busy(unsigned long iobase, unsigned int loop) { static int board_inquiry(unsigned int j) { struct mscp *cpp; dma_addr_t id_dma_addr; - unsigned int limit = 0; - unsigned long time; + unsigned int time, limit = 0; id_dma_addr = pci_map_single(HD(j)->pdev, HD(j)->board_id, sizeof(HD(j)->board_id), PCI_DMA_BIDIRECTIONAL); @@ -1393,8 +1392,7 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { } static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { - unsigned int i, j, k, c, limit = 0; - unsigned long time; + unsigned int i, j, time, k, c, limit = 0; int arg_done = FALSE; struct scsi_cmnd *SCpnt; 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/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index efc971d9647b..7a3625f52a03 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -783,9 +783,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) } } - spin_unlock(&port->lock); tty_flip_buffer_push(tty); - spin_lock(&port->lock); return psc_ops->raw_rx_rdy(port); } diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index eab032733790..1e2b9d826f69 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -556,7 +556,7 @@ static int uart_chars_in_buffer(struct tty_struct *tty) static void uart_flush_buffer(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; - struct uart_port *port; + struct uart_port *port = state->port; unsigned long flags; /* @@ -568,7 +568,6 @@ static void uart_flush_buffer(struct tty_struct *tty) return; } - port = state->port; pr_debug("uart_flush_buffer(%d) called\n", tty->index); spin_lock_irqsave(&port->lock, flags); diff --git a/trunk/drivers/serial/sunhv.c b/trunk/drivers/serial/sunhv.c index 145c0281495d..be0fe152891b 100644 --- a/trunk/drivers/serial/sunhv.c +++ b/trunk/drivers/serial/sunhv.c @@ -392,7 +392,7 @@ static struct uart_ops sunhv_pops = { static struct uart_driver sunhv_reg = { .owner = THIS_MODULE, - .driver_name = "sunhv", + .driver_name = "serial", .dev_name = "ttyS", .major = TTY_MAJOR, }; diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index 9ff5b38f3bee..543f93741e6f 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -826,7 +826,7 @@ static struct uart_ops sunsab_pops = { static struct uart_driver sunsab_reg = { .owner = THIS_MODULE, - .driver_name = "sunsab", + .driver_name = "serial", .dev_name = "ttyS", .major = TTY_MAJOR, }; diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index 03806a935209..4e2302d43ab1 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/drivers/serial/sunsu.c @@ -1173,7 +1173,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) static struct uart_driver sunsu_reg = { .owner = THIS_MODULE, - .driver_name = "sunsu", + .driver_name = "serial", .dev_name = "ttyS", .major = TTY_MAJOR, }; diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index 7e9fa5ef0eb7..90a20a152ebf 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -1023,7 +1023,7 @@ static struct uart_sunzilog_port *sunzilog_irq_chain; static struct uart_driver sunzilog_reg = { .owner = THIS_MODULE, - .driver_name = "sunzilog", + .driver_name = "ttyS", .dev_name = "ttyS", .major = TTY_MAJOR, }; 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 1ef6df395e0c..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 && PPC_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/iuu_phoenix.c b/trunk/drivers/usb/serial/iuu_phoenix.c index a01e987c7d32..8a217648b250 100644 --- a/trunk/drivers/usb/serial/iuu_phoenix.c +++ b/trunk/drivers/usb/serial/iuu_phoenix.c @@ -643,7 +643,7 @@ static void read_buf_callback(struct urb *urb) static int iuu_bulk_write(struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; + unsigned int flags; int result; int i; char *buf_ptr = port->write_urb->transfer_buffer; @@ -694,7 +694,7 @@ static void iuu_uart_read_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; + unsigned int flags; int status; int error = 0; int len = 0; @@ -759,7 +759,7 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf, int count) { struct iuu_private *priv = usb_get_serial_port_data(port); - unsigned long flags; + unsigned int flags; dbg("%s - enter", __func__); if (count > 256) 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/cypress_atacb.c b/trunk/drivers/usb/storage/cypress_atacb.c index 898e67d30e56..d88824b3511c 100644 --- a/trunk/drivers/usb/storage/cypress_atacb.c +++ b/trunk/drivers/usb/storage/cypress_atacb.c @@ -46,7 +46,7 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) } memcpy(save_cmnd, srb->cmnd, sizeof(save_cmnd)); - memset(srb->cmnd, 0, MAX_COMMAND_SIZE); + memset(srb->cmnd, 0, sizeof(srb->cmnd)); /* check if we support the command */ if (save_cmnd[1] >> 5) /* MULTIPLE_COUNT */ diff --git a/trunk/drivers/usb/storage/isd200.c b/trunk/drivers/usb/storage/isd200.c index 3addcd8f827b..971d13dd5e65 100644 --- a/trunk/drivers/usb/storage/isd200.c +++ b/trunk/drivers/usb/storage/isd200.c @@ -292,7 +292,6 @@ struct isd200_info { /* maximum number of LUNs supported */ unsigned char MaxLUNs; - unsigned char cmnd[BLK_MAX_CDB]; struct scsi_cmnd srb; struct scatterlist sg; }; @@ -451,7 +450,6 @@ static int isd200_action( struct us_data *us, int action, memset(&ata, 0, sizeof(ata)); memset(&srb_dev, 0, sizeof(srb_dev)); - srb->cmnd = info->cmnd; srb->device = &srb_dev; ++srb->serial_number; 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/video/bw2.c b/trunk/drivers/video/bw2.c index 79f85dc402d6..275d9dab0c61 100644 --- a/trunk/drivers/video/bw2.c +++ b/trunk/drivers/video/bw2.c @@ -329,7 +329,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id * if (!info->screen_base) goto out_unmap_regs; - bw2_blank(FB_BLANK_UNBLANK, info); + bw2_blank(0, info); bw2_init_fix(info, linebytes); diff --git a/trunk/drivers/video/cg3.c b/trunk/drivers/video/cg3.c index e31e26a6bb79..010ea53978f8 100644 --- a/trunk/drivers/video/cg3.c +++ b/trunk/drivers/video/cg3.c @@ -398,7 +398,7 @@ static int __devinit cg3_probe(struct of_device *op, if (!info->screen_base) goto out_unmap_regs; - cg3_blank(FB_BLANK_UNBLANK, info); + cg3_blank(0, info); if (!of_find_property(dp, "width", NULL)) { err = cg3_do_default_mode(par); diff --git a/trunk/drivers/video/cg6.c b/trunk/drivers/video/cg6.c index 8000bccecdc6..fc90db6da65a 100644 --- a/trunk/drivers/video/cg6.c +++ b/trunk/drivers/video/cg6.c @@ -767,7 +767,7 @@ static int __devinit cg6_probe(struct of_device *op, cg6_bt_init(par); cg6_chip_init(info); - cg6_blank(FB_BLANK_UNBLANK, info); + cg6_blank(0, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; diff --git a/trunk/drivers/video/ffb.c b/trunk/drivers/video/ffb.c index 0f42a696d176..93dca3e2aa50 100644 --- a/trunk/drivers/video/ffb.c +++ b/trunk/drivers/video/ffb.c @@ -987,7 +987,7 @@ static int __devinit ffb_probe(struct of_device *op, * chosen console, it will have video outputs off in * the DAC. */ - ffb_blank(FB_BLANK_UNBLANK, info); + ffb_blank(0, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_dac; diff --git a/trunk/drivers/video/leo.c b/trunk/drivers/video/leo.c index fb129928d5d5..f3160fc29795 100644 --- a/trunk/drivers/video/leo.c +++ b/trunk/drivers/video/leo.c @@ -601,7 +601,7 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id * leo_init_wids(info); leo_init_hw(info); - leo_blank(FB_BLANK_UNBLANK, info); + leo_blank(0, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; diff --git a/trunk/drivers/video/p9100.c b/trunk/drivers/video/p9100.c index 676ffb06d1c7..c95874fe9076 100644 --- a/trunk/drivers/video/p9100.c +++ b/trunk/drivers/video/p9100.c @@ -295,7 +295,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id if (!info->screen_base) goto out_unmap_regs; - p9100_blank(FB_BLANK_UNBLANK, info); + p9100_blank(0, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_screen; diff --git a/trunk/drivers/video/tcx.c b/trunk/drivers/video/tcx.c index 44e8c27ed0fc..a71774305772 100644 --- a/trunk/drivers/video/tcx.c +++ b/trunk/drivers/video/tcx.c @@ -84,7 +84,7 @@ struct tcx_tec { struct tcx_thc { u32 thc_rev; - u32 thc_pad0[511]; + u32 thc_pad0[511]; u32 thc_hs; /* hsync timing */ u32 thc_hsdvs; u32 thc_hd; @@ -126,10 +126,10 @@ struct tcx_par { }; /* Reset control plane so that WID is 8-bit plane. */ -static void __tcx_set_control_plane(struct tcx_par *par) +static void __tcx_set_control_plane (struct tcx_par *par) { u32 __iomem *p, *pend; - + if (par->lowdepth) return; @@ -143,8 +143,8 @@ static void __tcx_set_control_plane(struct tcx_par *par) sbus_writel(tmp, p); } } - -static void tcx_reset(struct fb_info *info) + +static void tcx_reset (struct fb_info *info) { struct tcx_par *par = (struct tcx_par *) info->par; unsigned long flags; @@ -365,8 +365,7 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info, info->screen_base, par->fbsize); } -static int __devinit tcx_probe(struct of_device *op, - const struct of_device_id *match) +static int __devinit tcx_init_one(struct of_device *op) { struct device_node *dp = op->node; struct fb_info *info; @@ -489,6 +488,13 @@ static int __devinit tcx_probe(struct of_device *op, return err; } +static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match) +{ + struct of_device *op = to_of_device(&dev->dev); + + return tcx_init_one(op); +} + static int __devexit tcx_remove(struct of_device *op) { struct fb_info *info = dev_get_drvdata(&op->dev); 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/affs/affs.h b/trunk/fs/affs/affs.h index 223b1917093e..d5bd497ab9cb 100644 --- a/trunk/fs/affs/affs.h +++ b/trunk/fs/affs/affs.h @@ -48,7 +48,7 @@ struct affs_ext_key { * affs fs inode data in memory */ struct affs_inode_info { - atomic_t i_opencnt; + u32 i_opencnt; struct semaphore i_link_lock; /* Protects internal inode access. */ struct semaphore i_ext_lock; /* Protects internal inode access. */ #define i_hash_lock i_ext_lock @@ -170,6 +170,8 @@ extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry, extern unsigned long affs_parent_ino(struct inode *dir); extern struct inode *affs_new_inode(struct inode *dir); extern int affs_notify_change(struct dentry *dentry, struct iattr *attr); +extern void affs_put_inode(struct inode *inode); +extern void affs_drop_inode(struct inode *inode); extern void affs_delete_inode(struct inode *inode); extern void affs_clear_inode(struct inode *inode); extern struct inode *affs_iget(struct super_block *sb, diff --git a/trunk/fs/affs/file.c b/trunk/fs/affs/file.c index 6eac7bdeec94..1a4f092f24ef 100644 --- a/trunk/fs/affs/file.c +++ b/trunk/fs/affs/file.c @@ -48,9 +48,8 @@ affs_file_open(struct inode *inode, struct file *filp) { if (atomic_read(&filp->f_count) != 1) return 0; - pr_debug("AFFS: open(%lu,%d)\n", - inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); - atomic_inc(&AFFS_I(inode)->i_opencnt); + pr_debug("AFFS: open(%d)\n", AFFS_I(inode)->i_opencnt); + AFFS_I(inode)->i_opencnt++; return 0; } @@ -59,16 +58,10 @@ affs_file_release(struct inode *inode, struct file *filp) { if (atomic_read(&filp->f_count) != 0) return 0; - pr_debug("AFFS: release(%lu, %d)\n", - inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); - - if (atomic_dec_and_test(&AFFS_I(inode)->i_opencnt)) { - mutex_lock(&inode->i_mutex); - if (inode->i_size != AFFS_I(inode)->mmu_private) - affs_truncate(inode); + pr_debug("AFFS: release(%d)\n", AFFS_I(inode)->i_opencnt); + AFFS_I(inode)->i_opencnt--; + if (!AFFS_I(inode)->i_opencnt) affs_free_prealloc(inode); - mutex_unlock(&inode->i_mutex); - } return 0; } @@ -187,7 +180,7 @@ affs_get_extblock(struct inode *inode, u32 ext) /* inline the simplest case: same extended block as last time */ struct buffer_head *bh = AFFS_I(inode)->i_ext_bh; if (ext == AFFS_I(inode)->i_ext_last) - get_bh(bh); + atomic_inc(&bh->b_count); else /* we have to do more (not inlined) */ bh = affs_get_extblock_slow(inode, ext); @@ -313,7 +306,7 @@ affs_get_extblock_slow(struct inode *inode, u32 ext) affs_brelse(AFFS_I(inode)->i_ext_bh); AFFS_I(inode)->i_ext_last = ext; AFFS_I(inode)->i_ext_bh = bh; - get_bh(bh); + atomic_inc(&bh->b_count); return bh; @@ -331,6 +324,7 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); + BUG_ON(block > (sector_t)0x7fffffffUL); if (block >= AFFS_I(inode)->i_blkcnt) { @@ -833,8 +827,6 @@ affs_truncate(struct inode *inode) res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata); if (!res) res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata); - else - inode->i_size = AFFS_I(inode)->mmu_private; mark_inode_dirty(inode); return; } else if (inode->i_size == AFFS_I(inode)->mmu_private) @@ -870,7 +862,6 @@ affs_truncate(struct inode *inode) blk++; } else AFFS_HEAD(ext_bh)->first_data = 0; - AFFS_HEAD(ext_bh)->block_count = cpu_to_be32(i); size = AFFS_SB(sb)->s_hashsize; if (size > blkcnt - blk + i) size = blkcnt - blk + i; diff --git a/trunk/fs/affs/inode.c b/trunk/fs/affs/inode.c index a13b334a3910..27fe6cbe43ae 100644 --- a/trunk/fs/affs/inode.c +++ b/trunk/fs/affs/inode.c @@ -58,7 +58,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) AFFS_I(inode)->i_extcnt = 1; AFFS_I(inode)->i_ext_last = ~1; AFFS_I(inode)->i_protect = prot; - atomic_set(&AFFS_I(inode)->i_opencnt, 0); + AFFS_I(inode)->i_opencnt = 0; AFFS_I(inode)->i_blkcnt = 0; AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_lc_size = 0; @@ -108,6 +108,8 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) inode->i_mode |= S_IFDIR; } else inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR; + if (tail->link_chain) + inode->i_nlink = 2; /* Maybe it should be controlled by mount parameter? */ //inode->i_mode |= S_ISVTX; inode->i_op = &affs_dir_inode_operations; @@ -242,13 +244,32 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr) return error; } +void +affs_put_inode(struct inode *inode) +{ + pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); + affs_free_prealloc(inode); +} + +void +affs_drop_inode(struct inode *inode) +{ + mutex_lock(&inode->i_mutex); + if (inode->i_size != AFFS_I(inode)->mmu_private) + affs_truncate(inode); + mutex_unlock(&inode->i_mutex); + + generic_drop_inode(inode); +} + void affs_delete_inode(struct inode *inode) { pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); truncate_inode_pages(&inode->i_data, 0); inode->i_size = 0; - affs_truncate(inode); + if (S_ISREG(inode->i_mode)) + affs_truncate(inode); clear_inode(inode); affs_free_block(inode->i_sb, inode->i_ino); } @@ -256,12 +277,9 @@ affs_delete_inode(struct inode *inode) void affs_clear_inode(struct inode *inode) { - unsigned long cache_page; + unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc; pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink); - - affs_free_prealloc(inode); - cache_page = (unsigned long)AFFS_I(inode)->i_lc; if (cache_page) { pr_debug("AFFS: freeing ext cache\n"); AFFS_I(inode)->i_lc = NULL; @@ -298,7 +316,7 @@ affs_new_inode(struct inode *dir) inode->i_ino = block; inode->i_nlink = 1; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; - atomic_set(&AFFS_I(inode)->i_opencnt, 0); + AFFS_I(inode)->i_opencnt = 0; AFFS_I(inode)->i_blkcnt = 0; AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_lc_size = 0; @@ -351,12 +369,12 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3 switch (type) { case ST_LINKFILE: case ST_LINKDIR: + inode_bh = bh; retval = -ENOSPC; block = affs_alloc_block(dir, dir->i_ino); if (!block) goto err; retval = -EIO; - inode_bh = bh; bh = affs_getzeroblk(sb, block); if (!bh) goto err; diff --git a/trunk/fs/affs/namei.c b/trunk/fs/affs/namei.c index cfcf1b6cf82b..2218f1ee71ce 100644 --- a/trunk/fs/affs/namei.c +++ b/trunk/fs/affs/namei.c @@ -234,8 +234,7 @@ affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) int affs_unlink(struct inode *dir, struct dentry *dentry) { - pr_debug("AFFS: unlink(dir=%d, %lu \"%.*s\")\n", (u32)dir->i_ino, - dentry->d_inode->i_ino, + pr_debug("AFFS: unlink(dir=%d, \"%.*s\")\n", (u32)dir->i_ino, (int)dentry->d_name.len, dentry->d_name.name); return affs_remove_header(dentry); @@ -303,8 +302,7 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode) int affs_rmdir(struct inode *dir, struct dentry *dentry) { - pr_debug("AFFS: rmdir(dir=%u, %lu \"%.*s\")\n", (u32)dir->i_ino, - dentry->d_inode->i_ino, + pr_debug("AFFS: rmdir(dir=%u, \"%.*s\")\n", (u32)dir->i_ino, (int)dentry->d_name.len, dentry->d_name.name); return affs_remove_header(dentry); diff --git a/trunk/fs/affs/super.c b/trunk/fs/affs/super.c index d214837d5e42..01d25d532541 100644 --- a/trunk/fs/affs/super.c +++ b/trunk/fs/affs/super.c @@ -71,18 +71,12 @@ static struct kmem_cache * affs_inode_cachep; static struct inode *affs_alloc_inode(struct super_block *sb) { - struct affs_inode_info *i; - - i = kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); - if (!i) + struct affs_inode_info *ei; + ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); + if (!ei) return NULL; - - i->vfs_inode.i_version = 1; - i->i_lc = NULL; - i->i_ext_bh = NULL; - i->i_pa_cnt = 0; - - return &i->vfs_inode; + ei->vfs_inode.i_version = 1; + return &ei->vfs_inode; } static void affs_destroy_inode(struct inode *inode) @@ -120,6 +114,8 @@ static const struct super_operations affs_sops = { .alloc_inode = affs_alloc_inode, .destroy_inode = affs_destroy_inode, .write_inode = affs_write_inode, + .put_inode = affs_put_inode, + .drop_inode = affs_drop_inode, .delete_inode = affs_delete_inode, .clear_inode = affs_clear_inode, .put_super = affs_put_super, diff --git a/trunk/fs/anon_inodes.c b/trunk/fs/anon_inodes.c index 977ef208c051..f42be069e085 100644 --- a/trunk/fs/anon_inodes.c +++ b/trunk/fs/anon_inodes.c @@ -57,6 +57,9 @@ static struct dentry_operations anon_inodefs_dentry_operations = { * anonymous inode, and a dentry that describe the "class" * of the file * + * @pfd: [out] pointer to the file descriptor + * @dpinode: [out] pointer to the inode + * @pfile: [out] pointer to the file struct * @name: [in] name of the "class" of the new file * @fops [in] file operations for the new file * @priv [in] private data for the new file (will be file's private_data) @@ -65,9 +68,10 @@ static struct dentry_operations anon_inodefs_dentry_operations = { * that do not need to have a full-fledged inode in order to operate correctly. * All the files created with anon_inode_getfd() will share a single inode, * hence saving memory and avoiding code duplication for the file/inode/dentry - * setup. Returns new descriptor or -error. + * setup. */ -int anon_inode_getfd(const char *name, const struct file_operations *fops, +int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, + const char *name, const struct file_operations *fops, void *priv) { struct qstr this; @@ -121,7 +125,10 @@ int anon_inode_getfd(const char *name, const struct file_operations *fops, fd_install(fd, file); - return fd; + *pfd = fd; + *pinode = anon_inode_inode; + *pfile = file; + return 0; err_dput: dput(dentry); 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/bio.c b/trunk/fs/bio.c index 78562574cb52..799f86deff24 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -158,7 +158,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) bio_init(bio); if (likely(nr_iovecs)) { - unsigned long uninitialized_var(idx); + unsigned long idx = 0; /* shut up gcc */ bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs); if (unlikely(!bvl)) { @@ -963,7 +963,6 @@ static void bio_copy_kern_endio(struct bio *bio, int err) * @data: pointer to buffer to copy * @len: length in bytes * @gfp_mask: allocation flags for bio and page allocation - * @reading: data direction is READ * * copy the kernel address into a bio suitable for io to a block * device. Returns an error pointer in case of error. diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 332a869d2c53..139dc93c092d 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/dnotify.c b/trunk/fs/dnotify.c index 676073b8dda5..eaecc4cfe540 100644 --- a/trunk/fs/dnotify.c +++ b/trunk/fs/dnotify.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include int dir_notify_enable __read_mostly = 1; diff --git a/trunk/fs/eventfd.c b/trunk/fs/eventfd.c index 343942deeec1..a9f130cd50ac 100644 --- a/trunk/fs/eventfd.c +++ b/trunk/fs/eventfd.c @@ -200,8 +200,10 @@ struct file *eventfd_fget(int fd) asmlinkage long sys_eventfd(unsigned int count) { - int fd; + int error, fd; struct eventfd_ctx *ctx; + struct file *file; + struct inode *inode; ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -214,9 +216,12 @@ asmlinkage long sys_eventfd(unsigned int count) * When we call this, the initialization must be complete, since * anon_inode_getfd() will install the fd. */ - fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx); - if (fd < 0) - kfree(ctx); - return fd; + error = anon_inode_getfd(&fd, &inode, &file, "[eventfd]", + &eventfd_fops, ctx); + if (!error) + return fd; + + kfree(ctx); + return error; } diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 990c01d2d66b..221086fef174 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1050,6 +1050,8 @@ asmlinkage long sys_epoll_create(int size) { int error, fd = -1; struct eventpoll *ep; + struct inode *inode; + struct file *file; DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", current, size)); @@ -1059,24 +1061,29 @@ asmlinkage long sys_epoll_create(int size) * structure ( "struct eventpoll" ). */ error = -EINVAL; - if (size <= 0 || (error = ep_alloc(&ep)) < 0) { - fd = error; + if (size <= 0 || (error = ep_alloc(&ep)) != 0) goto error_return; - } /* * Creates all the items needed to setup an eventpoll file. That is, - * a file structure and a free file descriptor. + * a file structure, and inode and a free file descriptor. */ - fd = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep); - if (fd < 0) - ep_free(ep); + error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]", + &eventpoll_fops, ep); + if (error) + goto error_free; -error_return: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", current, size, fd)); return fd; + +error_free: + ep_free(ep); +error_return: + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", + current, size, error)); + return error; } /* diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index aeaa9791d8be..9f9f931ef949 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index bfd776509a72..3f3ac630ccde 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 4c6f0ea12c41..5110acb1c9ef 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -150,16 +149,8 @@ static struct fdtable * alloc_fdtable(unsigned int nr) nr /= (1024 / sizeof(struct file *)); nr = roundup_pow_of_two(nr + 1); nr *= (1024 / sizeof(struct file *)); - /* - * Note that this can drive nr *below* what we had passed if sysctl_nr_open - * had been set lower between the check in expand_files() and here. Deal - * with that in caller, it's cheaper that way. - * - * We make sure that nr remains a multiple of BITS_PER_LONG - otherwise - * bitmaps handling below becomes unpleasant, to put it mildly... - */ - if (unlikely(nr > sysctl_nr_open)) - nr = ((sysctl_nr_open - 1) | (BITS_PER_LONG - 1)) + 1; + if (nr > sysctl_nr_open) + nr = sysctl_nr_open; fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); if (!fdt) @@ -207,16 +198,6 @@ static int expand_fdtable(struct files_struct *files, int nr) spin_lock(&files->file_lock); if (!new_fdt) return -ENOMEM; - /* - * extremely unlikely race - sysctl_nr_open decreased between the check in - * caller and alloc_fdtable(). Cheaper to catch it here... - */ - if (unlikely(new_fdt->max_fds <= nr)) { - free_fdarr(new_fdt); - free_fdset(new_fdt); - kfree(new_fdt); - return -EMFILE; - } /* * Check again since another task may have expanded the fd table while * we dropped the lock diff --git a/trunk/fs/file_table.c b/trunk/fs/file_table.c index 83084225b4c3..7a0a9b872251 100644 --- a/trunk/fs/file_table.c +++ b/trunk/fs/file_table.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include 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/inode.c b/trunk/fs/inode.c index c36d9480335c..bf6478130424 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -1149,8 +1149,13 @@ static inline void iput_final(struct inode *inode) void iput(struct inode *inode) { if (inode) { + const struct super_operations *op = inode->i_sb->s_op; + BUG_ON(inode->i_state == I_CLEAR); + if (op && op->put_inode) + op->put_inode(inode); + if (atomic_dec_and_lock(&inode->i_count, &inode_lock)) iput_final(inode); } 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/locks.c b/trunk/fs/locks.c index 0ac6b92cb0b6..44d9a6a7ec50 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -116,7 +116,6 @@ #include #include -#include #include #include #include @@ -1753,7 +1752,6 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, struct file_lock *file_lock = locks_alloc_lock(); struct flock flock; struct inode *inode; - struct file *f; int error; if (file_lock == NULL) @@ -1826,15 +1824,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - /* - * we need that spin_lock here - it prevents reordering between - * update of inode->i_flock and check for it done in close(). - * rcu_read_lock() wouldn't do. - */ - spin_lock(¤t->files->file_lock); - f = fcheck(fd); - spin_unlock(¤t->files->file_lock); - if (!error && f != filp && flock.l_type != F_UNLCK) { + if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } @@ -1890,7 +1880,6 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, struct file_lock *file_lock = locks_alloc_lock(); struct flock64 flock; struct inode *inode; - struct file *f; int error; if (file_lock == NULL) @@ -1963,10 +1952,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, * Attempt to detect a close/fcntl race and recover by * releasing the lock that was just acquired. */ - spin_lock(¤t->files->file_lock); - f = fcheck(fd); - spin_unlock(¤t->files->file_lock); - if (!error && f != filp && flock.l_type != F_UNLCK) { + if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { flock.l_type = F_UNLCK; goto again; } diff --git a/trunk/fs/ocfs2/cluster/sys.c b/trunk/fs/ocfs2/cluster/sys.c index bc702dab5d1f..98429fd68499 100644 --- a/trunk/fs/ocfs2/cluster/sys.c +++ b/trunk/fs/ocfs2/cluster/sys.c @@ -65,7 +65,7 @@ int o2cb_sys_init(void) { int ret; - o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); + o2cb_kset = kset_create_and_add("o2cb", NULL, NULL); if (!o2cb_kset) return -ENOMEM; diff --git a/trunk/fs/ocfs2/dlm/dlmdebug.c b/trunk/fs/ocfs2/dlm/dlmdebug.c index 1b81dcba175d..5f6d858770a2 100644 --- a/trunk/fs/ocfs2/dlm/dlmdebug.c +++ b/trunk/fs/ocfs2/dlm/dlmdebug.c @@ -44,8 +44,7 @@ #define MLOG_MASK_PREFIX ML_DLM #include "cluster/masklog.h" -static int stringify_lockname(const char *lockname, int locklen, char *buf, - int len); +int stringify_lockname(const char *lockname, int locklen, char *buf, int len); void dlm_print_one_lock_resource(struct dlm_lock_resource *res) { @@ -252,8 +251,7 @@ EXPORT_SYMBOL_GPL(dlm_errname); * * For more on lockname formats, please refer to dlmglue.c and ocfs2_lockid.h. */ -static int stringify_lockname(const char *lockname, int locklen, char *buf, - int len) +int stringify_lockname(const char *lockname, int locklen, char *buf, int len) { int out = 0; __be64 inode_blkno_be; @@ -370,7 +368,7 @@ static void dlm_debug_free(struct kref *kref) kfree(dc); } -static void dlm_debug_put(struct dlm_debug_ctxt *dc) +void dlm_debug_put(struct dlm_debug_ctxt *dc) { if (dc) kref_put(&dc->debug_refcnt, dlm_debug_free); diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index 57e0d30cde98..9154c82d3258 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -1048,10 +1048,6 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) mlog_entry("(0x%p, '%.*s')\n", dentry, dentry->d_name.len, dentry->d_name.name); - /* ensuring we don't even attempt to truncate a symlink */ - if (S_ISLNK(inode->i_mode)) - attr->ia_valid &= ~ATTR_SIZE; - if (attr->ia_valid & ATTR_MODE) mlog(0, "mode change: %d\n", attr->ia_mode); if (attr->ia_valid & ATTR_UID) diff --git a/trunk/fs/ocfs2/localalloc.c b/trunk/fs/ocfs2/localalloc.c index be774bdc8b36..ce0dc147602a 100644 --- a/trunk/fs/ocfs2/localalloc.c +++ b/trunk/fs/ocfs2/localalloc.c @@ -260,7 +260,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) bh = osb->local_alloc_bh; alloc = (struct ocfs2_dinode *) bh->b_data; - alloc_copy = kmalloc(bh->b_size, GFP_NOFS); + alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); if (!alloc_copy) { status = -ENOMEM; goto out_commit; @@ -931,7 +931,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, * local alloc shutdown won't try to double free main bitmap * bits. Make a copy so the sync function knows which bits to * free. */ - alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_NOFS); + alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_KERNEL); if (!alloc_copy) { status = -ENOMEM; mlog_errno(status); diff --git a/trunk/fs/ocfs2/stack_o2cb.c b/trunk/fs/ocfs2/stack_o2cb.c index bbd1667aa7d3..ac1d74c63bf5 100644 --- a/trunk/fs/ocfs2/stack_o2cb.c +++ b/trunk/fs/ocfs2/stack_o2cb.c @@ -385,7 +385,7 @@ static int o2cb_cluster_this_node(unsigned int *node) return 0; } -static struct ocfs2_stack_operations o2cb_stack_ops = { +struct ocfs2_stack_operations o2cb_stack_ops = { .connect = o2cb_cluster_connect, .disconnect = o2cb_cluster_disconnect, .hangup = o2cb_cluster_hangup, diff --git a/trunk/fs/ocfs2/stack_user.c b/trunk/fs/ocfs2/stack_user.c index b503772cd0ec..7428663f9cbb 100644 --- a/trunk/fs/ocfs2/stack_user.c +++ b/trunk/fs/ocfs2/stack_user.c @@ -635,7 +635,7 @@ static const struct file_operations ocfs2_control_fops = { .owner = THIS_MODULE, }; -static struct miscdevice ocfs2_control_device = { +struct miscdevice ocfs2_control_device = { .minor = MISC_DYNAMIC_MINOR, .name = "ocfs2_control", .fops = &ocfs2_control_fops, diff --git a/trunk/fs/ocfs2/symlink.c b/trunk/fs/ocfs2/symlink.c index ba9dbb51d25b..7134007ba22f 100644 --- a/trunk/fs/ocfs2/symlink.c +++ b/trunk/fs/ocfs2/symlink.c @@ -167,11 +167,9 @@ const struct inode_operations ocfs2_symlink_inode_operations = { .readlink = page_readlink, .follow_link = ocfs2_follow_link, .getattr = ocfs2_getattr, - .setattr = ocfs2_setattr, }; const struct inode_operations ocfs2_fast_symlink_inode_operations = { .readlink = ocfs2_readlink, .follow_link = ocfs2_follow_link, .getattr = ocfs2_getattr, - .setattr = ocfs2_setattr, }; diff --git a/trunk/fs/open.c b/trunk/fs/open.c index a1450086e92f..7af1f05d5978 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index ec228bc9f882..f73492b6817e 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -1076,26 +1075,6 @@ int do_pipe(int *fd) return error; } -/* - * sys_pipe() is the normal C calling standard for creating - * a pipe. It's not the way Unix traditionally does this, though. - */ -asmlinkage long __weak sys_pipe(int __user *fildes) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user(fildes, fd, sizeof(fd))) { - sys_close(fd[0]); - sys_close(fd[1]); - error = -EFAULT; - } - } - return error; -} - /* * pipefs should _never_ be mounted by userland - too much of security hassle, * no real gain from having the whole whorehouse mounted. So we don't need diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index dca997a93bff..c135cbdd9127 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -73,7 +73,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 808cbdc193d3..fcf02f2deeba 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 88717c0f941b..e2b8e769f510 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -5,9 +5,11 @@ #include #include #include +#include #include #include #include +#include #include #include diff --git a/trunk/fs/proc/task_nommu.c b/trunk/fs/proc/task_nommu.c index 4b4f9cc2f186..4b733f108455 100644 --- a/trunk/fs/proc/task_nommu.c +++ b/trunk/fs/proc/task_nommu.c @@ -1,7 +1,6 @@ #include #include -#include #include #include #include diff --git a/trunk/fs/select.c b/trunk/fs/select.c index 8dda969614a9..2c292146e246 100644 --- a/trunk/fs/select.c +++ b/trunk/fs/select.c @@ -21,7 +21,6 @@ #include #include /* for STICKY_TIMEOUTS */ #include -#include #include #include @@ -299,7 +298,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) #define MAX_SELECT_SECONDS \ ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) -int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, +static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s64 *timeout) { fd_set_bits fds; diff --git a/trunk/fs/signalfd.c b/trunk/fs/signalfd.c index 619725644c75..8ead0db35933 100644 --- a/trunk/fs/signalfd.c +++ b/trunk/fs/signalfd.c @@ -207,8 +207,11 @@ static const struct file_operations signalfd_fops = { asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask) { + int error; sigset_t sigmask; struct signalfd_ctx *ctx; + struct file *file; + struct inode *inode; if (sizemask != sizeof(sigset_t) || copy_from_user(&sigmask, user_mask, sizeof(sigmask))) @@ -227,11 +230,12 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas * When we call this, the initialization must be complete, since * anon_inode_getfd() will install the fd. */ - ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx); - if (ufd < 0) - kfree(ctx); + error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]", + &signalfd_fops, ctx); + if (error) + goto err_fdalloc; } else { - struct file *file = fget(ufd); + file = fget(ufd); if (!file) return -EBADF; ctx = file->private_data; @@ -248,4 +252,9 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas } return ufd; + +err_fdalloc: + kfree(ctx); + return error; } + diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index 78150038b584..633f58ebfb72 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -811,19 +811,24 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, { struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; - struct splice_desc sd = { - .total_len = len, - .flags = flags, - .pos = *ppos, - .u.file = out, - }; + int killsuid, killpriv; ssize_t ret; + int err = 0; + + killpriv = security_inode_need_killpriv(out->f_path.dentry); + killsuid = should_remove_suid(out->f_path.dentry); + if (unlikely(killsuid || killpriv)) { + mutex_lock(&inode->i_mutex); + if (killpriv) + err = security_inode_killpriv(out->f_path.dentry); + if (!err && killsuid) + err = __remove_suid(out->f_path.dentry, killsuid); + mutex_unlock(&inode->i_mutex); + if (err) + return err; + } - inode_double_lock(inode, pipe->inode); - ret = remove_suid(out->f_path.dentry); - if (likely(!ret)) - ret = __splice_from_pipe(pipe, &sd, pipe_to_file); - inode_double_unlock(inode, pipe->inode); + ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); if (ret > 0) { unsigned long nr_pages; @@ -835,8 +840,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, * sync it. */ if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { - int err; - mutex_lock(&inode->i_mutex); err = generic_osync_inode(inode, mapping, OSYNC_METADATA|OSYNC_DATA); @@ -1072,7 +1075,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, ret = splice_direct_to_actor(in, &sd, direct_splice_actor); if (ret > 0) - *ppos += ret; + *ppos = sd.pos; return ret; } diff --git a/trunk/fs/timerfd.c b/trunk/fs/timerfd.c index d87d354ec424..5400524e9cb1 100644 --- a/trunk/fs/timerfd.c +++ b/trunk/fs/timerfd.c @@ -181,8 +181,10 @@ static struct file *timerfd_fget(int fd) asmlinkage long sys_timerfd_create(int clockid, int flags) { - int ufd; + int error, ufd; struct timerfd_ctx *ctx; + struct file *file; + struct inode *inode; if (flags) return -EINVAL; @@ -198,9 +200,12 @@ asmlinkage long sys_timerfd_create(int clockid, int flags) ctx->clockid = clockid; hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); - ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx); - if (ufd < 0) + error = anon_inode_getfd(&ufd, &inode, &file, "[timerfd]", + &timerfd_fops, ctx); + if (error) { kfree(ctx); + return error; + } return ufd; } diff --git a/trunk/fs/udf/namei.c b/trunk/fs/udf/namei.c index d3231947db19..2b34c8ca6c83 100644 --- a/trunk/fs/udf/namei.c +++ b/trunk/fs/udf/namei.c @@ -32,7 +32,6 @@ #include #include #include -#include static inline int udf_match(int len1, const char *name1, int len2, const char *name2) @@ -159,8 +158,6 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, sector_t offset; struct extent_position epos = {}; struct udf_inode_info *dinfo = UDF_I(dir); - int isdotdot = dentry->d_name.len == 2 && - dentry->d_name.name[0] == '.' && dentry->d_name.name[1] == '.'; size = udf_ext0_offset(dir) + dir->i_size; f_pos = udf_ext0_offset(dir); @@ -228,12 +225,6 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, continue; } - if ((cfi->fileCharacteristics & FID_FILE_CHAR_PARENT) && - isdotdot) { - brelse(epos.bh); - return fi; - } - if (!lfi) continue; @@ -295,8 +286,9 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, } } unlock_kernel(); + d_add(dentry, inode); - return d_splice_alias(inode, dentry); + return NULL; } static struct fileIdentDesc *udf_add_entry(struct inode *dir, @@ -315,7 +307,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, uint16_t liu; int block; kernel_lb_addr eloc; - uint32_t elen = 0; + uint32_t elen; sector_t offset; struct extent_position epos = {}; struct udf_inode_info *dinfo; @@ -406,8 +398,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir, } add: - /* Is there any extent whose size we need to round up? */ - if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) { + if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1); if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) epos.offset -= sizeof(short_ad); @@ -1241,134 +1232,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, return retval; } -static struct dentry *udf_get_parent(struct dentry *child) -{ - struct dentry *parent; - struct inode *inode = NULL; - struct dentry dotdot; - struct fileIdentDesc cfi; - struct udf_fileident_bh fibh; - - dotdot.d_name.name = ".."; - dotdot.d_name.len = 2; - - lock_kernel(); - if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) - goto out_unlock; - - if (fibh.sbh != fibh.ebh) - brelse(fibh.ebh); - brelse(fibh.sbh); - - inode = udf_iget(child->d_inode->i_sb, - lelb_to_cpu(cfi.icb.extLocation)); - if (!inode) - goto out_unlock; - unlock_kernel(); - - parent = d_alloc_anon(inode); - if (!parent) { - iput(inode); - parent = ERR_PTR(-ENOMEM); - } - - return parent; -out_unlock: - unlock_kernel(); - return ERR_PTR(-EACCES); -} - - -static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, - u16 partref, __u32 generation) -{ - struct inode *inode; - struct dentry *result; - kernel_lb_addr loc; - - if (block == 0) - return ERR_PTR(-ESTALE); - - loc.logicalBlockNum = block; - loc.partitionReferenceNum = partref; - inode = udf_iget(sb, loc); - - if (inode == NULL) - return ERR_PTR(-ENOMEM); - - if (generation && inode->i_generation != generation) { - iput(inode); - return ERR_PTR(-ESTALE); - } - result = d_alloc_anon(inode); - if (!result) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - return result; -} - -static struct dentry *udf_fh_to_dentry(struct super_block *sb, - struct fid *fid, int fh_len, int fh_type) -{ - if ((fh_len != 3 && fh_len != 5) || - (fh_type != FILEID_UDF_WITH_PARENT && - fh_type != FILEID_UDF_WITHOUT_PARENT)) - return NULL; - - return udf_nfs_get_inode(sb, fid->udf.block, fid->udf.partref, - fid->udf.generation); -} - -static struct dentry *udf_fh_to_parent(struct super_block *sb, - struct fid *fid, int fh_len, int fh_type) -{ - if (fh_len != 5 || fh_type != FILEID_UDF_WITH_PARENT) - return NULL; - - return udf_nfs_get_inode(sb, fid->udf.parent_block, - fid->udf.parent_partref, - fid->udf.parent_generation); -} -static int udf_encode_fh(struct dentry *de, __u32 *fh, int *lenp, - int connectable) -{ - int len = *lenp; - struct inode *inode = de->d_inode; - kernel_lb_addr location = UDF_I(inode)->i_location; - struct fid *fid = (struct fid *)fh; - int type = FILEID_UDF_WITHOUT_PARENT; - - if (len < 3 || (connectable && len < 5)) - return 255; - - *lenp = 3; - fid->udf.block = location.logicalBlockNum; - fid->udf.partref = location.partitionReferenceNum; - fid->udf.generation = inode->i_generation; - - if (connectable && !S_ISDIR(inode->i_mode)) { - spin_lock(&de->d_lock); - inode = de->d_parent->d_inode; - location = UDF_I(inode)->i_location; - fid->udf.parent_block = location.logicalBlockNum; - fid->udf.parent_partref = location.partitionReferenceNum; - fid->udf.parent_generation = inode->i_generation; - spin_unlock(&de->d_lock); - *lenp = 5; - type = FILEID_UDF_WITH_PARENT; - } - - return type; -} - -const struct export_operations udf_export_ops = { - .encode_fh = udf_encode_fh, - .fh_to_dentry = udf_fh_to_dentry, - .fh_to_parent = udf_fh_to_parent, - .get_parent = udf_get_parent, -}; - const struct inode_operations udf_dir_inode_operations = { .lookup = udf_lookup, .create = udf_create, diff --git a/trunk/fs/udf/partition.c b/trunk/fs/udf/partition.c index 96dfd207c3d6..63610f026ae1 100644 --- a/trunk/fs/udf/partition.c +++ b/trunk/fs/udf/partition.c @@ -27,8 +27,8 @@ #include #include -uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, - uint16_t partition, uint32_t offset) +inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, + uint16_t partition, uint32_t offset) { struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map; diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index 7a5f69be6ac2..9fb18a340fc1 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -1933,7 +1933,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; - sb->s_export_op = &udf_export_ops; sb->dq_op = NULL; sb->s_dirt = 0; sb->s_magic = UDF_SUPER_MAGIC; diff --git a/trunk/fs/udf/udfdecl.h b/trunk/fs/udf/udfdecl.h index 8fa9c2d70911..f3f45d029277 100644 --- a/trunk/fs/udf/udfdecl.h +++ b/trunk/fs/udf/udfdecl.h @@ -73,7 +73,6 @@ struct task_struct; struct buffer_head; struct super_block; -extern const struct export_operations udf_export_ops; extern const struct inode_operations udf_dir_inode_operations; extern const struct file_operations udf_dir_operations; extern const struct inode_operations udf_file_inode_operations; 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-alpha/types.h b/trunk/include/asm-alpha/types.h index c1541353ccef..f5716139ec89 100644 --- a/trunk/include/asm-alpha/types.h +++ b/trunk/include/asm-alpha/types.h @@ -8,12 +8,28 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ -#include #ifndef __ASSEMBLY__ typedef unsigned int umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + #endif /* __ASSEMBLY__ */ /* @@ -25,6 +41,18 @@ typedef unsigned int umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long s64; +typedef unsigned long u64; + typedef u64 dma_addr_t; typedef u64 dma64_addr_t; 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-arm/types.h b/trunk/include/asm-arm/types.h index 345df01534a4..3141451a9bd6 100644 --- a/trunk/include/asm-arm/types.h +++ b/trunk/include/asm-arm/types.h @@ -1,12 +1,29 @@ #ifndef __ASM_ARM_TYPES_H #define __ASM_ARM_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -18,6 +35,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-avr32/types.h b/trunk/include/asm-avr32/types.h index 9cefda6f534a..8999a3819403 100644 --- a/trunk/include/asm-avr32/types.h +++ b/trunk/include/asm-avr32/types.h @@ -8,12 +8,28 @@ #ifndef __ASM_AVR32_TYPES_H #define __ASM_AVR32_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -25,6 +41,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-blackfin/types.h b/trunk/include/asm-blackfin/types.h index 8441cbc2bf9e..9785a6d531c6 100644 --- a/trunk/include/asm-blackfin/types.h +++ b/trunk/include/asm-blackfin/types.h @@ -8,12 +8,30 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +/* HK0617 -- Changes to unsigned long temporarily */ +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* * These aren't exported outside the kernel to avoid name space clashes @@ -24,6 +42,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-cris/types.h b/trunk/include/asm-cris/types.h index 5790262cbe8a..5a21c42bc6c5 100644 --- a/trunk/include/asm-cris/types.h +++ b/trunk/include/asm-cris/types.h @@ -1,12 +1,29 @@ #ifndef _ETRAX_TYPES_H #define _ETRAX_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -18,6 +35,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide, just like our other addresses. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-frv/types.h b/trunk/include/asm-frv/types.h index 613bf1e962f0..767e5ed71c4b 100644 --- a/trunk/include/asm-frv/types.h +++ b/trunk/include/asm-frv/types.h @@ -12,12 +12,29 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -29,6 +46,19 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; 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/Kbuild b/trunk/include/asm-generic/Kbuild index 4c9932a2503f..c18110ee30f1 100644 --- a/trunk/include/asm-generic/Kbuild +++ b/trunk/include/asm-generic/Kbuild @@ -7,7 +7,5 @@ header-y += poll.h header-y += signal.h header-y += statfs.h -unifdef-y += int-l64.h -unifdef-y += int-ll64.h unifdef-y += resource.h unifdef-y += siginfo.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-generic/int-l64.h b/trunk/include/asm-generic/int-l64.h deleted file mode 100644 index 2af9b75d77db..000000000000 --- a/trunk/include/asm-generic/int-l64.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * asm-generic/int-l64.h - * - * Integer declarations for architectures which use "long" - * for 64-bit types. - */ - -#ifndef _ASM_GENERIC_INT_L64_H -#define _ASM_GENERIC_INT_L64_H - -#ifndef __ASSEMBLY__ -/* - * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the - * header files exported to user space - */ - -typedef __signed__ char __s8; -typedef unsigned char __u8; - -typedef __signed__ short __s16; -typedef unsigned short __u16; - -typedef __signed__ int __s32; -typedef unsigned int __u32; - -typedef __signed__ long __s64; -typedef unsigned long __u64; - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -typedef signed char s8; -typedef unsigned char u8; - -typedef signed short s16; -typedef unsigned short u16; - -typedef signed int s32; -typedef unsigned int u32; - -typedef signed long s64; -typedef unsigned long u64; - -#define S8_C(x) x -#define U8_C(x) x ## U -#define S16_C(x) x -#define U16_C(x) x ## U -#define S32_C(x) x -#define U32_C(x) x ## U -#define S64_C(x) x ## L -#define U64_C(x) x ## UL - -#else /* __ASSEMBLY__ */ - -#define S8_C(x) x -#define U8_C(x) x -#define S16_C(x) x -#define U16_C(x) x -#define S32_C(x) x -#define U32_C(x) x -#define S64_C(x) x -#define U64_C(x) x - -#endif /* __ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif /* _ASM_GENERIC_INT_L64_H */ diff --git a/trunk/include/asm-generic/int-ll64.h b/trunk/include/asm-generic/int-ll64.h deleted file mode 100644 index 260948905e4e..000000000000 --- a/trunk/include/asm-generic/int-ll64.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * asm-generic/int-ll64.h - * - * Integer declarations for architectures which use "long long" - * for 64-bit types. - */ - -#ifndef _ASM_GENERIC_INT_LL64_H -#define _ASM_GENERIC_INT_LL64_H - -#ifndef __ASSEMBLY__ -/* - * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the - * header files exported to user space - */ - -typedef __signed__ char __s8; -typedef unsigned char __u8; - -typedef __signed__ short __s16; -typedef unsigned short __u16; - -typedef __signed__ int __s32; -typedef unsigned int __u32; - -#ifdef __GNUC__ -__extension__ typedef __signed__ long long __s64; -__extension__ typedef unsigned long long __u64; -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -typedef __signed__ long long __s64; -typedef unsigned long long __u64; -#endif - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ - -#ifndef __ASSEMBLY__ - -typedef signed char s8; -typedef unsigned char u8; - -typedef signed short s16; -typedef unsigned short u16; - -typedef signed int s32; -typedef unsigned int u32; - -typedef signed long long s64; -typedef unsigned long long u64; - -#define S8_C(x) x -#define U8_C(x) x ## U -#define S16_C(x) x -#define U16_C(x) x ## U -#define S32_C(x) x -#define U32_C(x) x ## U -#define S64_C(x) x ## LL -#define U64_C(x) x ## ULL - -#else /* __ASSEMBLY__ */ - -#define S8_C(x) x -#define U8_C(x) x -#define S16_C(x) x -#define U16_C(x) x -#define S32_C(x) x -#define U32_C(x) x -#define S64_C(x) x -#define U64_C(x) x - -#endif /* __ASSEMBLY__ */ - -#endif /* __KERNEL__ */ - -#endif /* _ASM_GENERIC_INT_LL64_H */ diff --git a/trunk/include/asm-h8300/types.h b/trunk/include/asm-h8300/types.h index 12875190b156..56566e2a09fd 100644 --- a/trunk/include/asm-h8300/types.h +++ b/trunk/include/asm-h8300/types.h @@ -1,8 +1,6 @@ #ifndef _H8300_TYPES_H #define _H8300_TYPES_H -#include - #if !defined(__ASSEMBLY__) /* @@ -15,11 +13,42 @@ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + /* * These aren't exported outside the kernel to avoid name space clashes */ #ifdef __KERNEL__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + #define BITS_PER_LONG 32 /* Dma addresses are 32-bits wide. */ 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-ia64/types.h b/trunk/include/asm-ia64/types.h index e36b3716e718..902850d12424 100644 --- a/trunk/include/asm-ia64/types.h +++ b/trunk/include/asm-ia64/types.h @@ -13,8 +13,6 @@ * David Mosberger-Tang , Hewlett-Packard Co */ -#include - #ifdef __ASSEMBLY__ # define __IA64_UL(x) (x) # define __IA64_UL_CONST(x) x @@ -29,11 +27,40 @@ typedef unsigned int umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + /* * These aren't exported outside the kernel to avoid name space clashes */ # ifdef __KERNEL__ +typedef __s8 s8; +typedef __u8 u8; + +typedef __s16 s16; +typedef __u16 u16; + +typedef __s32 s32; +typedef __u32 u32; + +typedef __s64 s64; +typedef __u64 u64; + #define BITS_PER_LONG 64 /* DMA addresses are 64-bits wide, in general. */ diff --git a/trunk/include/asm-m32r/types.h b/trunk/include/asm-m32r/types.h index bc9f7fff0ac3..b64c16639a7b 100644 --- a/trunk/include/asm-m32r/types.h +++ b/trunk/include/asm-m32r/types.h @@ -1,12 +1,28 @@ #ifndef _ASM_M32R_TYPES_H #define _ASM_M32R_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif #endif /* __ASSEMBLY__ */ /* @@ -18,6 +34,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* DMA addresses are 32-bits wide. */ typedef u32 dma_addr_t; 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-m68k/machw.h b/trunk/include/asm-m68k/machw.h index 35624998291c..d2e0e25d5c90 100644 --- a/trunk/include/asm-m68k/machw.h +++ b/trunk/include/asm-m68k/machw.h @@ -66,6 +66,36 @@ struct MAC_SCC # define mac_scc ((*(volatile struct SCC*)MAC_SCC_BAS)) #endif +/* hardware stuff */ + +#define MACHW_DECLARE(name) unsigned name : 1 +#define MACHW_SET(name) (mac_hw_present.name = 1) +#define MACHW_PRESENT(name) (mac_hw_present.name) + +struct mac_hw_present { + /* video hardware */ + /* sound hardware */ + /* disk storage interfaces */ + MACHW_DECLARE(MAC_SCSI_80); /* Directly mapped NCR5380 */ + MACHW_DECLARE(MAC_SCSI_96); /* 53c9[46] */ + MACHW_DECLARE(MAC_SCSI_96_2); /* 2nd 53c9[46] Q900 and Q950 */ + MACHW_DECLARE(IDE); /* IDE Interface */ + /* other I/O hardware */ + MACHW_DECLARE(SCC); /* Serial Communications Contr. */ + /* DMA */ + MACHW_DECLARE(SCSI_DMA); /* DMA for the NCR5380 */ + /* real time clocks */ + MACHW_DECLARE(RTC_CLK); /* clock chip */ + /* supporting hardware */ + MACHW_DECLARE(VIA1); /* Versatile Interface Ad. 1 */ + MACHW_DECLARE(VIA2); /* Versatile Interface Ad. 2 */ + MACHW_DECLARE(RBV); /* Versatile Interface Ad. 2+ */ + /* NUBUS */ + MACHW_DECLARE(NUBUS); /* NUBUS */ +}; + +extern struct mac_hw_present mac_hw_present; + #endif /* __ASSEMBLY__ */ #endif /* linux/machw.h */ diff --git a/trunk/include/asm-m68k/types.h b/trunk/include/asm-m68k/types.h index 6441cb5f8e7c..c35c09d93b66 100644 --- a/trunk/include/asm-m68k/types.h +++ b/trunk/include/asm-m68k/types.h @@ -8,12 +8,30 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ -#include #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -25,6 +43,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* DMA addresses are always 32-bits wide */ typedef u32 dma_addr_t; 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-mips/types.h b/trunk/include/asm-mips/types.h index bcbb8d675af5..2dd147f519d1 100644 --- a/trunk/include/asm-mips/types.h +++ b/trunk/include/asm-mips/types.h @@ -9,16 +9,38 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H -#if _MIPS_SZLONG == 64 -# include -#else -# include -#endif - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if (_MIPS_SZLONG == 64) + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#else + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + +#endif + #endif /* __ASSEMBLY__ */ /* @@ -30,6 +52,30 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ + +typedef __signed char s8; +typedef unsigned char u8; + +typedef __signed short s16; +typedef unsigned short u16; + +typedef __signed int s32; +typedef unsigned int u32; + +#if (_MIPS_SZLONG == 64) + +typedef __signed__ long s64; +typedef unsigned long u64; + +#else + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long s64; +typedef unsigned long long u64; +#endif + +#endif + #if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \ || defined(CONFIG_64BIT) typedef u64 dma_addr_t; 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-mn10300/processor.h b/trunk/include/asm-mn10300/processor.h index 73239271873d..f1b081f53468 100644 --- a/trunk/include/asm-mn10300/processor.h +++ b/trunk/include/asm-mn10300/processor.h @@ -58,7 +58,7 @@ extern struct mn10300_cpuinfo boot_cpu_data; extern void identify_cpu(struct mn10300_cpuinfo *); extern void print_cpu_info(struct mn10300_cpuinfo *); extern void dodgy_tsc(void); -#define cpu_relax() barrier() +#define cpu_relax() do {} while (0) /* * User space process size: 1.75GB (default). diff --git a/trunk/include/asm-mn10300/types.h b/trunk/include/asm-mn10300/types.h index 7b9f01042fd4..d40ea7628bfc 100644 --- a/trunk/include/asm-mn10300/types.h +++ b/trunk/include/asm-mn10300/types.h @@ -11,12 +11,29 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -28,6 +45,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-parisc/types.h b/trunk/include/asm-parisc/types.h index 7f5a39bfb4ce..56c84802da59 100644 --- a/trunk/include/asm-parisc/types.h +++ b/trunk/include/asm-parisc/types.h @@ -1,12 +1,29 @@ #ifndef _PARISC_TYPES_H #define _PARISC_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -24,6 +41,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-powerpc/io.h b/trunk/include/asm-powerpc/io.h index e0062d73db1c..afae0697e8ce 100644 --- a/trunk/include/asm-powerpc/io.h +++ b/trunk/include/asm-powerpc/io.h @@ -2,7 +2,7 @@ #define _ASM_POWERPC_IO_H #ifdef __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 @@ -18,9 +18,6 @@ extern int check_legacy_ioport(unsigned long base_port); #define _PNPWRP 0xa79 #define PNPBIOS_BASE 0xf000 -#include -#include - #include #include #include @@ -747,9 +744,6 @@ static inline void * bus_to_virt(unsigned long address) #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) -void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset, - size_t size, unsigned long flags); - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_IO_H */ diff --git a/trunk/include/asm-powerpc/kvm_host.h b/trunk/include/asm-powerpc/kvm_host.h index 81a69d711017..04ffbb8e0a35 100644 --- a/trunk/include/asm-powerpc/kvm_host.h +++ b/trunk/include/asm-powerpc/kvm_host.h @@ -59,7 +59,6 @@ struct kvm_vcpu_stat { u32 emulated_inst_exits; u32 dec_exits; u32 ext_intr_exits; - u32 halt_wakeup; }; struct tlbe { diff --git a/trunk/include/asm-powerpc/kvm_ppc.h b/trunk/include/asm-powerpc/kvm_ppc.h index b35a7e3ef978..7ac820308a7e 100644 --- a/trunk/include/asm-powerpc/kvm_ppc.h +++ b/trunk/include/asm-powerpc/kvm_ppc.h @@ -77,17 +77,12 @@ static inline void kvmppc_clear_exception(struct kvm_vcpu *vcpu, int exception) clear_bit(priority, &vcpu->arch.pending_exceptions); } -/* Helper function for "full" MSR writes. No need to call this if only EE is - * changing. */ static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr) { if ((new_msr & MSR_PR) != (vcpu->arch.msr & MSR_PR)) kvmppc_mmu_priv_switch(vcpu, new_msr & MSR_PR); vcpu->arch.msr = new_msr; - - if (vcpu->arch.msr & MSR_WE) - kvm_vcpu_block(vcpu); } #endif /* __POWERPC_KVM_PPC_H__ */ diff --git a/trunk/include/asm-powerpc/ps3.h b/trunk/include/asm-powerpc/ps3.h index 81ffe3b3c1ce..9e8ed6824e15 100644 --- a/trunk/include/asm-powerpc/ps3.h +++ b/trunk/include/asm-powerpc/ps3.h @@ -178,6 +178,9 @@ enum ps3_cpu_binding { PS3_BINDING_CPU_1 = 1, }; +int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, + unsigned int *virq); +int ps3_virq_destroy(unsigned int virq); int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, unsigned int *virq); int ps3_irq_plug_destroy(unsigned int virq); diff --git a/trunk/include/asm-powerpc/syscalls.h b/trunk/include/asm-powerpc/syscalls.h index 2b8a458f990a..b3ca41fc8bb1 100644 --- a/trunk/include/asm-powerpc/syscalls.h +++ b/trunk/include/asm-powerpc/syscalls.h @@ -30,7 +30,7 @@ asmlinkage int sys_fork(unsigned long p1, unsigned long p2, asmlinkage int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4, unsigned long p5, unsigned long p6, struct pt_regs *regs); -asmlinkage long sys_pipe(int __user *fildes); +asmlinkage int sys_pipe(int __user *fildes); asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, struct sigaction __user *oact, size_t sigsetsize); diff --git a/trunk/include/asm-powerpc/types.h b/trunk/include/asm-powerpc/types.h index d3374bc865ba..c243a6ac60e5 100644 --- a/trunk/include/asm-powerpc/types.h +++ b/trunk/include/asm-powerpc/types.h @@ -1,12 +1,6 @@ #ifndef _ASM_POWERPC_TYPES_H #define _ASM_POWERPC_TYPES_H -#ifdef __powerpc64__ -# include -#else -# include -#endif - #ifndef __ASSEMBLY__ /* @@ -28,6 +22,30 @@ typedef unsigned int umode_t; typedef unsigned short umode_t; #endif +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#ifdef __powerpc64__ +typedef __signed__ long __s64; +typedef unsigned long __u64; +#else +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif +#endif /* __powerpc64__ */ + typedef struct { __u32 u[4]; } __attribute__((aligned(16))) __vector128; @@ -46,6 +64,24 @@ typedef struct { #ifndef __ASSEMBLY__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +#ifdef __powerpc64__ +typedef signed long s64; +typedef unsigned long u64; +#else +typedef signed long long s64; +typedef unsigned long long u64; +#endif + typedef __vector128 vector128; /* Physical address used by some IO functions */ diff --git a/trunk/include/asm-s390/kvm_host.h b/trunk/include/asm-s390/kvm_host.h index 18cbd8a39796..f8204a4f2e02 100644 --- a/trunk/include/asm-s390/kvm_host.h +++ b/trunk/include/asm-s390/kvm_host.h @@ -104,7 +104,6 @@ struct sie_block { struct kvm_vcpu_stat { u32 exit_userspace; - u32 exit_null; u32 exit_external_request; u32 exit_external_interrupt; u32 exit_stop_request; diff --git a/trunk/include/asm-s390/page.h b/trunk/include/asm-s390/page.h index 12fd9c4f0f15..f0f4579eac13 100644 --- a/trunk/include/asm-s390/page.h +++ b/trunk/include/asm-s390/page.h @@ -125,17 +125,6 @@ page_get_storage_key(unsigned long addr) return skey; } -#ifdef CONFIG_PAGE_STATES - -struct page; -void arch_free_page(struct page *page, int order); -void arch_alloc_page(struct page *page, int order); - -#define HAVE_ARCH_FREE_PAGE -#define HAVE_ARCH_ALLOC_PAGE - -#endif - #endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ diff --git a/trunk/include/asm-s390/ptrace.h b/trunk/include/asm-s390/ptrace.h index d7d4e2eb3e6f..441d7c260857 100644 --- a/trunk/include/asm-s390/ptrace.h +++ b/trunk/include/asm-s390/ptrace.h @@ -471,8 +471,6 @@ struct task_struct; extern void user_enable_single_step(struct task_struct *); extern void user_disable_single_step(struct task_struct *); -#define __ARCH_WANT_COMPAT_SYS_PTRACE - #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) #define regs_return_value(regs)((regs)->gprs[2]) diff --git a/trunk/include/asm-s390/system.h b/trunk/include/asm-s390/system.h index e0d4500d5f95..c819ae25a842 100644 --- a/trunk/include/asm-s390/system.h +++ b/trunk/include/asm-s390/system.h @@ -116,12 +116,6 @@ extern void pfault_fini(void); #define pfault_fini() do { } while (0) #endif /* CONFIG_PFAULT */ -#ifdef CONFIG_PAGE_STATES -extern void cmma_init(void); -#else -static inline void cmma_init(void) { } -#endif - #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ account_vtime(prev); \ diff --git a/trunk/include/asm-s390/types.h b/trunk/include/asm-s390/types.h index 78dda038dd47..2c5879ae90ca 100644 --- a/trunk/include/asm-s390/types.h +++ b/trunk/include/asm-s390/types.h @@ -9,16 +9,34 @@ #ifndef _S390_TYPES_H #define _S390_TYPES_H -#ifndef __s390x__ -# include -#else -# include -#endif - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#ifndef __s390x__ +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif +#else /* __s390x__ */ +typedef __signed__ long __s64; +typedef unsigned long __u64; +#endif + /* A address type so that arithmetic can be done on it & it can be upgraded to 64 bit when necessary */ @@ -40,6 +58,24 @@ typedef __signed__ long saddr_t; #ifndef __ASSEMBLY__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +#ifndef __s390x__ +typedef signed long long s64; +typedef unsigned long long u64; +#else /* __s390x__ */ +typedef signed long s64; +typedef unsigned long u64; +#endif /* __s390x__ */ + typedef u32 dma_addr_t; #ifndef __s390x__ diff --git a/trunk/include/asm-sh/types.h b/trunk/include/asm-sh/types.h index beea4e6f8dfd..a6e1d4126e67 100644 --- a/trunk/include/asm-sh/types.h +++ b/trunk/include/asm-sh/types.h @@ -1,12 +1,29 @@ #ifndef __ASM_SH_TYPES_H #define __ASM_SH_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -18,6 +35,19 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ + +typedef __signed__ char s8; +typedef unsigned char u8; + +typedef __signed__ short s16; +typedef unsigned short u16; + +typedef __signed__ int s32; +typedef unsigned int u32; + +typedef __signed__ long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-sparc/oplib.h b/trunk/include/asm-sparc/oplib.h index 7becc846544a..17ba82ee220a 100644 --- a/trunk/include/asm-sparc/oplib.h +++ b/trunk/include/asm-sparc/oplib.h @@ -34,6 +34,9 @@ extern unsigned int prom_rev, prom_prev; */ extern int prom_root_node; +/* PROM stdin and stdout */ +extern int prom_stdin, prom_stdout; + /* Pointer to prom structure containing the device tree traversal * and usage utility functions. Only prom-lib should use these, * users use the interface defined by the library only! @@ -81,6 +84,20 @@ extern int prom_devclose(int device_handle); extern void prom_seek(int device_handle, unsigned int seek_hival, unsigned int seek_lowval); +/* Machine memory configuration routine. */ + +/* This function returns a V0 format memory descriptor table, it has three + * entries. One for the total amount of physical ram on the machine, one + * for the amount of physical ram available, and one describing the virtual + * areas which are allocated by the prom. So, in a sense the physical + * available is a calculation of the total physical minus the physical mapped + * by the prom with virtual mappings. + * + * These lists are returned pre-sorted, this should make your life easier + * since the prom itself is way too lazy to do such nice things. + */ +extern struct linux_mem_v0 *prom_meminfo(void); + /* Miscellaneous routines, don't really fit in any category per se. */ /* Reboot the machine with the command line passed. */ diff --git a/trunk/include/asm-sparc/page.h b/trunk/include/asm-sparc/page.h index 1625a8c3e0d2..39ccf2da297c 100644 --- a/trunk/include/asm-sparc/page.h +++ b/trunk/include/asm-sparc/page.h @@ -38,11 +38,12 @@ /* The following structure is used to hold the physical * memory configuration of the machine. This is filled in - * prom_meminit() and is later used by mem_init() to set up - * mem_map[]. We statically allocate SPARC_PHYS_BANKS+1 of + * probe_memory() and is later used by mem_init() to set up + * mem_map[]. We statically allocate SPARC_PHYS_BANKS of * these structs, this is arbitrary. The entry after the * last valid one has num_bytes==0. */ + struct sparc_phys_banks { unsigned long base_addr; unsigned long num_bytes; diff --git a/trunk/include/asm-sparc/types.h b/trunk/include/asm-sparc/types.h index 1b08ef860a66..42fc6ed98156 100644 --- a/trunk/include/asm-sparc/types.h +++ b/trunk/include/asm-sparc/types.h @@ -2,6 +2,11 @@ #ifndef _SPARC_TYPES_H #define _SPARC_TYPES_H +/* + * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space. + */ + /* * This file is never included by application software unless * explicitly requested (e.g., via linux/types.h) in which case the @@ -9,12 +14,23 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ -#include #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long long __s64; +typedef unsigned long long __u64; + #endif /* __ASSEMBLY__ */ #ifdef __KERNEL__ @@ -23,6 +39,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef __signed__ char s8; +typedef unsigned char u8; + +typedef __signed__ short s16; +typedef unsigned short u16; + +typedef __signed__ int s32; +typedef unsigned int u32; + +typedef __signed__ long long s64; +typedef unsigned long long u64; + typedef u32 dma_addr_t; typedef u32 dma64_addr_t; diff --git a/trunk/include/asm-sparc64/types.h b/trunk/include/asm-sparc64/types.h index 5dbe04f4044a..d0ee7f105838 100644 --- a/trunk/include/asm-sparc64/types.h +++ b/trunk/include/asm-sparc64/types.h @@ -9,12 +9,28 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ -#include #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * _xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space. + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + #endif /* __ASSEMBLY__ */ #ifdef __KERNEL__ @@ -23,6 +39,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef __signed__ char s8; +typedef unsigned char u8; + +typedef __signed__ short s16; +typedef unsigned short u16; + +typedef __signed__ int s32; +typedef unsigned int u32; + +typedef __signed__ long s64; +typedef unsigned long u64; + /* Dma addresses come in generic and 64-bit flavours. */ typedef u32 dma_addr_t; 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-v850/types.h b/trunk/include/asm-v850/types.h index 89f735ee41dd..284bda882112 100644 --- a/trunk/include/asm-v850/types.h +++ b/trunk/include/asm-v850/types.h @@ -10,10 +10,28 @@ * not a major issue. However, for interoperability, libraries still * need to be careful to avoid a name clashes. */ -#include typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + #endif /* !__ASSEMBLY__ */ /* @@ -25,6 +43,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + /* Dma addresses are 32-bits wide. */ typedef u32 dma_addr_t; diff --git a/trunk/include/asm-x86/bootparam.h b/trunk/include/asm-x86/bootparam.h index f62f4733606b..e8659909e5f6 100644 --- a/trunk/include/asm-x86/bootparam.h +++ b/trunk/include/asm-x86/bootparam.h @@ -14,10 +14,10 @@ /* extensible setup data list node */ struct setup_data { - __u64 next; - __u32 type; - __u32 len; - __u8 data[0]; + u64 next; + u32 type; + u32 len; + u8 data[0]; }; struct setup_header { 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/asm-x86/kvm_host.h b/trunk/include/asm-x86/kvm_host.h index 1d8cd01fa514..9d963cd6533c 100644 --- a/trunk/include/asm-x86/kvm_host.h +++ b/trunk/include/asm-x86/kvm_host.h @@ -314,9 +314,6 @@ struct kvm_arch{ struct page *apic_access_page; gpa_t wall_clock; - - struct page *ept_identity_pagetable; - bool ept_identity_pagetable_done; }; struct kvm_vm_stat { @@ -425,7 +422,6 @@ struct kvm_x86_ops { struct kvm_run *run); int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); - int (*get_tdp_level)(void); }; extern struct kvm_x86_ops *kvm_x86_ops; @@ -437,9 +433,6 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu); int kvm_mmu_create(struct kvm_vcpu *vcpu); int kvm_mmu_setup(struct kvm_vcpu *vcpu); void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64 notrap_pte); -void kvm_mmu_set_base_ptes(u64 base_pte); -void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, - u64 dirty_mask, u64 nx_mask, u64 x_mask); int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); @@ -627,7 +620,7 @@ static inline void fx_restore(struct i387_fxsave_struct *image) asm("fxrstor (%0)":: "r" (image)); } -static inline void fx_finit(void) +static inline void fpu_init(void) { asm("finit"); } @@ -651,7 +644,6 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) #define ASM_VMX_VMWRITE_RSP_RDX ".byte 0x0f, 0x79, 0xd4" #define ASM_VMX_VMXOFF ".byte 0x0f, 0x01, 0xc4" #define ASM_VMX_VMXON_RAX ".byte 0xf3, 0x0f, 0xc7, 0x30" -#define ASM_VMX_INVEPT ".byte 0x66, 0x0f, 0x38, 0x80, 0x08" #define ASM_VMX_INVVPID ".byte 0x66, 0x0f, 0x38, 0x81, 0x08" #define MSR_IA32_TIME_STAMP_COUNTER 0x010 diff --git a/trunk/include/asm-x86/pgtable_32.h b/trunk/include/asm-x86/pgtable_32.h index d7f0403bbecb..577ab79c4c27 100644 --- a/trunk/include/asm-x86/pgtable_32.h +++ b/trunk/include/asm-x86/pgtable_32.h @@ -88,7 +88,14 @@ extern unsigned long pg0[]; /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ #define pmd_none(x) (!(unsigned long)pmd_val((x))) #define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT) -#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) + +extern int pmd_bad(pmd_t pmd); + +#define pmd_bad_v1(x) \ + (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER))) +#define pmd_bad_v2(x) \ + (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER | \ + _PAGE_PSE | _PAGE_NX))) #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) diff --git a/trunk/include/asm-x86/pgtable_64.h b/trunk/include/asm-x86/pgtable_64.h index efe83dcbd412..a3bbf8766c1d 100644 --- a/trunk/include/asm-x86/pgtable_64.h +++ b/trunk/include/asm-x86/pgtable_64.h @@ -158,12 +158,14 @@ static inline unsigned long pgd_bad(pgd_t pgd) static inline unsigned long pud_bad(pud_t pud) { - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + return pud_val(pud) & + ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); } static inline unsigned long pmd_bad(pmd_t pmd) { - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); + return pmd_val(pmd) & + ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); } #define pte_none(x) (!pte_val((x))) diff --git a/trunk/include/asm-x86/types.h b/trunk/include/asm-x86/types.h index 1ac80cd9acf8..63733f315688 100644 --- a/trunk/include/asm-x86/types.h +++ b/trunk/include/asm-x86/types.h @@ -1,12 +1,34 @@ #ifndef _ASM_X86_TYPES_H #define _ASM_X86_TYPES_H -#include - #ifndef __ASSEMBLY__ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#ifdef __i386__ +# ifdef __GNUC__ +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +# endif +#else +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + #endif /* __ASSEMBLY__ */ /* @@ -22,6 +44,18 @@ typedef unsigned short umode_t; #ifndef __ASSEMBLY__ +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + typedef u64 dma64_addr_t; #if defined(CONFIG_X86_64) || defined(CONFIG_HIGHMEM64G) /* DMA addresses come in 32-bit and 64-bit flavours. */ diff --git a/trunk/include/asm-xtensa/types.h b/trunk/include/asm-xtensa/types.h index c89569a8da0c..b27d841a8eb7 100644 --- a/trunk/include/asm-xtensa/types.h +++ b/trunk/include/asm-xtensa/types.h @@ -11,7 +11,6 @@ #ifndef _XTENSA_TYPES_H #define _XTENSA_TYPES_H -#include #ifdef __ASSEMBLY__ # define __XTENSA_UL(x) (x) @@ -25,11 +24,43 @@ typedef unsigned short umode_t; +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + /* * These aren't exported outside the kernel to avoid name space clashes */ #ifdef __KERNEL__ +typedef __signed__ char s8; +typedef unsigned char u8; + +typedef __signed__ short s16; +typedef unsigned short u16; + +typedef __signed__ int s32; +typedef unsigned int u32; + +typedef __signed__ long long s64; +typedef unsigned long long u64; + + #define BITS_PER_LONG 32 /* Dma addresses are 32-bits wide. */ 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/anon_inodes.h b/trunk/include/linux/anon_inodes.h index 6129e58ca7c9..b2e1ba325b9a 100644 --- a/trunk/include/linux/anon_inodes.h +++ b/trunk/include/linux/anon_inodes.h @@ -8,7 +8,8 @@ #ifndef _LINUX_ANON_INODES_H #define _LINUX_ANON_INODES_H -int anon_inode_getfd(const char *name, const struct file_operations *fops, +int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, + const char *name, const struct file_operations *fops, void *priv); #endif /* _LINUX_ANON_INODES_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/exportfs.h b/trunk/include/linux/exportfs.h index f5abd1306638..de8387b7ceb6 100644 --- a/trunk/include/linux/exportfs.h +++ b/trunk/include/linux/exportfs.h @@ -33,19 +33,6 @@ enum fid_type { * 32 bit parent directory inode number. */ FILEID_INO32_GEN_PARENT = 2, - - /* - * 32 bit block number, 16 bit partition reference, - * 16 bit unused, 32 bit generation number. - */ - FILEID_UDF_WITHOUT_PARENT = 0x51, - - /* - * 32 bit block number, 16 bit partition reference, - * 16 bit unused, 32 bit generation number, - * 32 bit parent block number, 32 bit parent generation number - */ - FILEID_UDF_WITH_PARENT = 0x52, }; struct fid { @@ -56,14 +43,6 @@ struct fid { u32 parent_ino; u32 parent_gen; } i32; - struct { - u32 block; - u16 partref; - u16 parent_partref; - u32 generation; - u32 parent_block; - u32 parent_generation; - } udf; __u32 raw[0]; }; }; diff --git a/trunk/include/linux/fdtable.h b/trunk/include/linux/fdtable.h deleted file mode 100644 index a118f3c0b240..000000000000 --- a/trunk/include/linux/fdtable.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * descriptor table internals; you almost certainly want file.h instead. - */ - -#ifndef __LINUX_FDTABLE_H -#define __LINUX_FDTABLE_H - -#include -#include -#include -#include -#include -#include - -/* - * The default fd array needs to be at least BITS_PER_LONG, - * as this is the granularity returned by copy_fdset(). - */ -#define NR_OPEN_DEFAULT BITS_PER_LONG - -/* - * The embedded_fd_set is a small fd_set, - * suitable for most tasks (which open <= BITS_PER_LONG files) - */ -struct embedded_fd_set { - unsigned long fds_bits[1]; -}; - -struct fdtable { - unsigned int max_fds; - struct file ** fd; /* current fd array */ - fd_set *close_on_exec; - fd_set *open_fds; - struct rcu_head rcu; - struct fdtable *next; -}; - -/* - * Open file table structure - */ -struct files_struct { - /* - * read mostly part - */ - atomic_t count; - struct fdtable *fdt; - struct fdtable fdtab; - /* - * written part on a separate cache line in SMP - */ - spinlock_t file_lock ____cacheline_aligned_in_smp; - int next_fd; - struct embedded_fd_set close_on_exec_init; - struct embedded_fd_set open_fds_init; - struct file * fd_array[NR_OPEN_DEFAULT]; -}; - -#define files_fdtable(files) (rcu_dereference((files)->fdt)) - -extern struct kmem_cache *filp_cachep; - -struct file_operations; -struct vfsmount; -struct dentry; - -extern int expand_files(struct files_struct *, int nr); -extern void free_fdtable_rcu(struct rcu_head *rcu); -extern void __init files_defer_init(void); - -static inline void free_fdtable(struct fdtable *fdt) -{ - call_rcu(&fdt->rcu, free_fdtable_rcu); -} - -static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) -{ - struct file * file = NULL; - struct fdtable *fdt = files_fdtable(files); - - if (fd < fdt->max_fds) - file = rcu_dereference(fdt->fd[fd]); - return file; -} - -/* - * Check whether the specified fd has an open file. - */ -#define fcheck(fd) fcheck_files(current->files, fd) - -struct task_struct; - -struct files_struct *get_files_struct(struct task_struct *); -void put_files_struct(struct files_struct *fs); -void reset_files_struct(struct files_struct *); -int unshare_files(struct files_struct **); - -extern struct kmem_cache *files_cachep; - -#endif /* __LINUX_FDTABLE_H */ diff --git a/trunk/include/linux/file.h b/trunk/include/linux/file.h index 27c64bdc68c9..69baf5a4f0a5 100644 --- a/trunk/include/linux/file.h +++ b/trunk/include/linux/file.h @@ -5,11 +5,59 @@ #ifndef __LINUX_FILE_H #define __LINUX_FILE_H +#include +#include #include +#include +#include #include -#include -struct file; +/* + * The default fd array needs to be at least BITS_PER_LONG, + * as this is the granularity returned by copy_fdset(). + */ +#define NR_OPEN_DEFAULT BITS_PER_LONG + +/* + * The embedded_fd_set is a small fd_set, + * suitable for most tasks (which open <= BITS_PER_LONG files) + */ +struct embedded_fd_set { + unsigned long fds_bits[1]; +}; + +struct fdtable { + unsigned int max_fds; + struct file ** fd; /* current fd array */ + fd_set *close_on_exec; + fd_set *open_fds; + struct rcu_head rcu; + struct fdtable *next; +}; + +/* + * Open file table structure + */ +struct files_struct { + /* + * read mostly part + */ + atomic_t count; + struct fdtable *fdt; + struct fdtable fdtab; + /* + * written part on a separate cache line in SMP + */ + spinlock_t file_lock ____cacheline_aligned_in_smp; + int next_fd; + struct embedded_fd_set close_on_exec_init; + struct embedded_fd_set open_fds_init; + struct file * fd_array[NR_OPEN_DEFAULT]; +}; + +#define files_fdtable(files) (rcu_dereference((files)->fdt)) + +extern struct kmem_cache *filp_cachep; extern void __fput(struct file *); extern void fput(struct file *); @@ -37,7 +85,41 @@ extern void put_filp(struct file *); extern int get_unused_fd(void); extern int get_unused_fd_flags(int flags); extern void put_unused_fd(unsigned int fd); +struct kmem_cache; + +extern int expand_files(struct files_struct *, int nr); +extern void free_fdtable_rcu(struct rcu_head *rcu); +extern void __init files_defer_init(void); + +static inline void free_fdtable(struct fdtable *fdt) +{ + call_rcu(&fdt->rcu, free_fdtable_rcu); +} + +static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) +{ + struct file * file = NULL; + struct fdtable *fdt = files_fdtable(files); + + if (fd < fdt->max_fds) + file = rcu_dereference(fdt->fd[fd]); + return file; +} + +/* + * Check whether the specified fd has an open file. + */ +#define fcheck(fd) fcheck_files(current->files, fd) extern void fd_install(unsigned int fd, struct file *file); +struct task_struct; + +struct files_struct *get_files_struct(struct task_struct *); +void put_files_struct(struct files_struct *fs); +void reset_files_struct(struct files_struct *); +int unshare_files(struct files_struct **); + +extern struct kmem_cache *files_cachep; + #endif /* __LINUX_FILE_H */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index f413085f748e..a1ba005d08e7 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1289,12 +1289,17 @@ extern ssize_t vfs_readv(struct file *, const struct iovec __user *, extern ssize_t vfs_writev(struct file *, const struct iovec __user *, unsigned long, loff_t *); +/* + * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called + * without the big kernel lock held in all filesystems. + */ struct super_operations { struct inode *(*alloc_inode)(struct super_block *sb); void (*destroy_inode)(struct inode *); void (*dirty_inode) (struct inode *); int (*write_inode) (struct inode *, int); + void (*put_inode) (struct inode *); void (*drop_inode) (struct inode *); void (*delete_inode) (struct inode *); void (*put_super) (struct super_block *); @@ -1816,6 +1821,7 @@ extern void iget_failed(struct inode *); extern void clear_inode(struct inode *); extern void destroy_inode(struct inode *); extern struct inode *new_inode(struct super_block *); +extern int __remove_suid(struct dentry *, int); extern int should_remove_suid(struct dentry *); extern int remove_suid(struct dentry *); diff --git a/trunk/include/linux/genhd.h b/trunk/include/linux/genhd.h index e9874e7fcdf9..ecd2bf63fc84 100644 --- a/trunk/include/linux/genhd.h +++ b/trunk/include/linux/genhd.h @@ -178,17 +178,17 @@ static inline struct hd_struct *get_part(struct gendisk *gendiskp, static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { int i; - for_each_possible_cpu(i) memset(per_cpu_ptr(gendiskp->dkstats, i), value, - sizeof(struct disk_stats)); + sizeof (struct disk_stats)); } #define __part_stat_add(part, field, addnd) \ (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) -#define __all_stat_add(gendiskp, part, field, addnd, sector) \ +#define __all_stat_add(gendiskp, field, addnd, sector) \ ({ \ + struct hd_struct *part = get_part(gendiskp, sector); \ if (part) \ __part_stat_add(part, field, addnd); \ __disk_stat_add(gendiskp, field, addnd); \ @@ -203,13 +203,11 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { res; \ }) -static inline void part_stat_set_all(struct hd_struct *part, int value) -{ +static inline void part_stat_set_all(struct hd_struct *part, int value) { int i; - for_each_possible_cpu(i) memset(per_cpu_ptr(part->dkstats, i), value, - sizeof(struct disk_stats)); + sizeof(struct disk_stats)); } #else /* !CONFIG_SMP */ @@ -225,8 +223,9 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) #define __part_stat_add(part, field, addnd) \ (part->dkstats.field += addnd) -#define __all_stat_add(gendiskp, part, field, addnd, sector) \ +#define __all_stat_add(gendiskp, field, addnd, sector) \ ({ \ + struct hd_struct *part = get_part(gendiskp, sector); \ if (part) \ part->dkstats.field += addnd; \ __disk_stat_add(gendiskp, field, addnd); \ @@ -277,10 +276,10 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) #define part_stat_sub(gendiskp, field, subnd) \ part_stat_add(gendiskp, field, -subnd) -#define all_stat_add(gendiskp, part, field, addnd, sector) \ +#define all_stat_add(gendiskp, field, addnd, sector) \ do { \ preempt_disable(); \ - __all_stat_add(gendiskp, part, field, addnd, sector); \ + __all_stat_add(gendiskp, field, addnd, sector); \ preempt_enable(); \ } while (0) @@ -289,15 +288,15 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) #define all_stat_dec(gendiskp, field, sector) \ all_stat_add(gendiskp, field, -1, sector) -#define __all_stat_inc(gendiskp, part, field, sector) \ - __all_stat_add(gendiskp, part, field, 1, sector) -#define all_stat_inc(gendiskp, part, field, sector) \ - all_stat_add(gendiskp, part, field, 1, sector) +#define __all_stat_inc(gendiskp, field, sector) \ + __all_stat_add(gendiskp, field, 1, sector) +#define all_stat_inc(gendiskp, field, sector) \ + all_stat_add(gendiskp, field, 1, sector) -#define __all_stat_sub(gendiskp, part, field, subnd, sector) \ - __all_stat_add(gendiskp, part, field, -subnd, sector) -#define all_stat_sub(gendiskp, part, field, subnd, sector) \ - all_stat_add(gendiskp, part, field, -subnd, sector) +#define __all_stat_sub(gendiskp, field, subnd, sector) \ + __all_stat_add(gendiskp, field, -subnd, sector) +#define all_stat_sub(gendiskp, field, subnd, sector) \ + all_stat_add(gendiskp, field, -subnd, sector) /* Inlines to alloc and free disk stats in struct gendisk */ #ifdef CONFIG_SMP diff --git a/trunk/include/linux/hrtimer.h b/trunk/include/linux/hrtimer.h index 6d93dce61cbb..31a4d653389f 100644 --- a/trunk/include/linux/hrtimer.h +++ b/trunk/include/linux/hrtimer.h @@ -316,15 +316,6 @@ static inline int hrtimer_is_queued(struct hrtimer *timer) (HRTIMER_STATE_ENQUEUED | HRTIMER_STATE_PENDING); } -/* - * Helper function to check, whether the timer is running the callback - * function - */ -static inline int hrtimer_callback_running(struct hrtimer *timer) -{ - return timer->state & HRTIMER_STATE_CALLBACK; -} - /* Forward a hrtimer so it expires after now: */ extern u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index b24c2875aa05..bf6b8a61f8db 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -1,7 +1,7 @@ #ifndef _LINUX__INIT_TASK_H #define _LINUX__INIT_TASK_H -#include +#include #include #include #include diff --git a/trunk/include/linux/io.h b/trunk/include/linux/io.h index 6c7f0ba0d5fa..3a03a3604cce 100644 --- a/trunk/include/linux/io.h +++ b/trunk/include/linux/io.h @@ -65,6 +65,5 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, void devm_iounmap(struct device *dev, void __iomem *addr); int check_signature(const volatile void __iomem *io_addr, const unsigned char *signature, int length); -void devm_ioremap_release(struct device *dev, void *res); #endif /* _LINUX_IO_H */ diff --git a/trunk/include/linux/ioprio.h b/trunk/include/linux/ioprio.h index f98a656b17e5..2a3bb1bb7433 100644 --- a/trunk/include/linux/ioprio.h +++ b/trunk/include/linux/ioprio.h @@ -67,20 +67,6 @@ static inline int task_nice_ioprio(struct task_struct *task) return (task_nice(task) + 20) / 5; } -/* - * This is for the case where the task hasn't asked for a specific IO class. - * Check for idle and rt task process, and return appropriate IO class. - */ -static inline int task_nice_ioclass(struct task_struct *task) -{ - if (task->policy == SCHED_IDLE) - return IOPRIO_CLASS_IDLE; - else if (task->policy == SCHED_FIFO || task->policy == SCHED_RR) - return IOPRIO_CLASS_RT; - else - return IOPRIO_CLASS_BE; -} - /* * For inheritance, return the highest of the two given priorities */ 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/kgdb.h b/trunk/include/linux/kgdb.h index 6adcc297e354..9757b1a6d9dc 100644 --- a/trunk/include/linux/kgdb.h +++ b/trunk/include/linux/kgdb.h @@ -261,12 +261,10 @@ struct kgdb_io { extern struct kgdb_arch arch_kgdb_ops; -extern unsigned long __weak kgdb_arch_pc(int exception, struct pt_regs *regs); - extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); -extern int kgdb_hex2long(char **ptr, unsigned long *long_val); +extern int kgdb_hex2long(char **ptr, long *long_val); extern int kgdb_mem2hex(char *mem, char *buf, int count); extern int kgdb_hex2mem(char *buf, char *mem, int count); diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 7e206da1fbfb..d1dfe872ee30 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -1039,7 +1039,6 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -extern void ata_eh_analyze_ncq_error(struct ata_link *link); extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, @@ -1382,21 +1381,6 @@ static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) return *(struct ata_port **)&host->hostdata[0]; } -static inline int ata_check_ready(u8 status) -{ - /* Some controllers report 0x77 or 0x7f during intermediate - * not-ready stages. - */ - if (status == 0x77 || status == 0x7f) - return 0; - - /* 0xff indicates either no device or device not ready */ - if (status == 0xff) - return -ENODEV; - - return !(status & ATA_BUSY); -} - /************************************************************************** * PMP - drivers/ata/libata-pmp.c 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.h b/trunk/include/linux/pci.h index 509159bcd4e7..96acd0dae241 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -44,7 +44,6 @@ #include #include -#include #include #include #include @@ -475,7 +474,7 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr); void pci_bus_add_devices(struct pci_bus *bus); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); -static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, +static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) { struct pci_bus *root_bus; @@ -667,7 +666,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), void *userdata); -int pci_cfg_space_size_ext(struct pci_dev *dev); +int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); 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/pda_power.h b/trunk/include/linux/pda_power.h index cb7d10f30763..225beb136807 100644 --- a/trunk/include/linux/pda_power.h +++ b/trunk/include/linux/pda_power.h @@ -16,14 +16,10 @@ #define PDA_POWER_CHARGE_AC (1 << 0) #define PDA_POWER_CHARGE_USB (1 << 1) -struct device; - struct pda_power_pdata { - int (*init)(struct device *dev); int (*is_ac_online)(void); int (*is_usb_online)(void); void (*set_charge)(int flags); - void (*exit)(struct device *dev); char **supplied_to; size_t num_supplicants; diff --git a/trunk/include/linux/poll.h b/trunk/include/linux/poll.h index ef453828877a..16d813b364ef 100644 --- a/trunk/include/linux/poll.h +++ b/trunk/include/linux/poll.h @@ -117,8 +117,6 @@ void zero_fd_set(unsigned long nr, unsigned long *fdset) extern int do_select(int n, fd_set_bits *fds, s64 *timeout); extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, s64 *timeout); -extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, s64 *timeout); #endif /* KERNEL */ 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/rio.h b/trunk/include/linux/rio.h index dc0c75556c63..c1c99c9643d3 100644 --- a/trunk/include/linux/rio.h +++ b/trunk/include/linux/rio.h @@ -161,8 +161,6 @@ enum rio_phy_type { * @ops: configuration space functions * @id: Port ID, unique among all ports * @index: Port index, unique among all port interfaces of the same type - * @sys_size: RapidIO common transport system size - * @phy_type: RapidIO phy type * @name: Port name string * @priv: Master port private data */ diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 0c35b0343a76..03c238088aee 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -158,8 +158,6 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) } #endif -extern unsigned long long time_sync_thresh; - /* * Task state bitmask. NOTE! These bits are also * encoded in fs/proc/array.c: get_task_state(). @@ -1553,35 +1551,6 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask) extern unsigned long long sched_clock(void); -#ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK -static inline void sched_clock_init(void) -{ -} - -static inline u64 sched_clock_cpu(int cpu) -{ - return sched_clock(); -} - -static inline void sched_clock_tick(void) -{ -} - -static inline void sched_clock_idle_sleep_event(void) -{ -} - -static inline void sched_clock_idle_wakeup_event(u64 delta_ns) -{ -} -#else -extern void sched_clock_init(void); -extern u64 sched_clock_cpu(int cpu); -extern void sched_clock_tick(void); -extern void sched_clock_idle_sleep_event(void); -extern void sched_clock_idle_wakeup_event(u64 delta_ns); -#endif - /* * For kernel-internal use: high-speed (but slightly incorrect) per-cpu * clock constructed from sched_clock(): @@ -2008,11 +1977,6 @@ static inline void clear_tsk_need_resched(struct task_struct *tsk) clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED); } -static inline int test_tsk_need_resched(struct task_struct *tsk) -{ - return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); -} - static inline int signal_pending(struct task_struct *p) { return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); @@ -2027,7 +1991,7 @@ static inline int fatal_signal_pending(struct task_struct *p) static inline int need_resched(void) { - return unlikely(test_tsk_need_resched(current)); + return unlikely(test_thread_flag(TIF_NEED_RESCHED)); } /* 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/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/vermagic.h b/trunk/include/linux/vermagic.h index 79b9837d9ca0..4d0909e53595 100644 --- a/trunk/include/linux/vermagic.h +++ b/trunk/include/linux/vermagic.h @@ -17,11 +17,6 @@ #else #define MODULE_VERMAGIC_MODULE_UNLOAD "" #endif -#ifdef CONFIG_MODVERSIONS -#define MODULE_VERMAGIC_MODVERSIONS "modversions " -#else -#define MODULE_VERMAGIC_MODVERSIONS "" -#endif #ifndef MODULE_ARCH_VERMAGIC #define MODULE_ARCH_VERMAGIC "" #endif @@ -29,6 +24,5 @@ #define VERMAGIC_STRING \ UTS_RELEASE " " \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ - MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \ - MODULE_ARCH_VERMAGIC + MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC 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/include/scsi/scsi.h b/trunk/include/scsi/scsi.h index 32742c4563de..1f74bcd603fe 100644 --- a/trunk/include/scsi/scsi.h +++ b/trunk/include/scsi/scsi.h @@ -29,6 +29,13 @@ #define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS #endif +/* + * SCSI command lengths + */ + +extern const unsigned char scsi_command_size[8]; +#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] + /* * Special value for scanning to specify scanning or rescanning of all * possible channels, (target) ids, or luns on a given shost. @@ -102,7 +109,6 @@ #define MODE_SENSE_10 0x5a #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f -#define VARIABLE_LENGTH_CMD 0x7f #define REPORT_LUNS 0xa0 #define MAINTENANCE_IN 0xa3 #define MOVE_MEDIUM 0xa5 @@ -129,38 +135,6 @@ #define ATA_16 0x85 /* 16-byte pass-thru */ #define ATA_12 0xa1 /* 12-byte pass-thru */ -/* - * SCSI command lengths - */ - -#define SCSI_MAX_VARLEN_CDB_SIZE 260 - -/* defined in T10 SCSI Primary Commands-2 (SPC2) */ -struct scsi_varlen_cdb_hdr { - u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ - u8 control; - u8 misc[5]; - u8 additional_cdb_length; /* total cdb length - 8 */ - __be16 service_action; - /* service specific data follows */ -}; - -static inline unsigned -scsi_varlen_cdb_length(const void *hdr) -{ - return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8; -} - -extern const unsigned char scsi_command_size_tbl[8]; -#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7] - -static inline unsigned -scsi_command_size(const unsigned char *cmnd) -{ - return (cmnd[0] == VARIABLE_LENGTH_CMD) ? - scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]); -} - /* * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft * T10/1561-D Revision 4 Draft dated 7th November 2002. diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index 3e46dfae8194..8d20e60a94b7 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -7,28 +7,10 @@ #include #include #include -#include struct Scsi_Host; struct scsi_device; -/* - * MAX_COMMAND_SIZE is: - * The longest fixed-length SCSI CDB as per the SCSI standard. - * fixed-length means: commands that their size can be determined - * by their opcode and the CDB does not carry a length specifier, (unlike - * the VARIABLE_LENGTH_CMD(0x7f) command). This is actually not exactly - * true and the SCSI standard also defines extended commands and - * vendor specific commands that can be bigger than 16 bytes. The kernel - * will support these using the same infrastructure used for VARLEN CDB's. - * So in effect MAX_COMMAND_SIZE means the maximum size command scsi-ml - * supports without specifying a cmd_len by ULD's - */ -#define MAX_COMMAND_SIZE 16 -#if (MAX_COMMAND_SIZE > BLK_MAX_CDB) -# error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB -#endif - struct scsi_data_buffer { struct sg_table table; unsigned length; @@ -78,11 +60,12 @@ struct scsi_cmnd { int allowed; int timeout_per_command; - unsigned short cmd_len; + unsigned char cmd_len; enum dma_data_direction sc_data_direction; /* These elements define the operation we are about to perform */ - unsigned char *cmnd; +#define MAX_COMMAND_SIZE 16 + unsigned char cmnd[MAX_COMMAND_SIZE]; struct timer_list eh_timeout; /* Used to time out the command. */ diff --git a/trunk/include/scsi/scsi_eh.h b/trunk/include/scsi/scsi_eh.h index 2a9add21267d..d3a133b4a072 100644 --- a/trunk/include/scsi/scsi_eh.h +++ b/trunk/include/scsi/scsi_eh.h @@ -75,11 +75,11 @@ struct scsi_eh_save { int result; enum dma_data_direction data_direction; unsigned char cmd_len; - unsigned char *cmnd; + unsigned char cmnd[MAX_COMMAND_SIZE]; struct scsi_data_buffer sdb; struct request *next_rq; + /* new command support */ - unsigned char eh_cmnd[BLK_MAX_CDB]; struct scatterlist sense_sgl; }; diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h index 1834fdfe82a7..d967d6dc7a28 100644 --- a/trunk/include/scsi/scsi_host.h +++ b/trunk/include/scsi/scsi_host.h @@ -573,11 +573,13 @@ struct Scsi_Host { /* * The maximum length of SCSI commands that this host can accept. * Probably 12 for most host adapters, but could be 16 for others. - * or 260 if the driver supports variable length cdbs. * For drivers that don't set this field, a value of 12 is - * assumed. + * assumed. I am leaving this as a number rather than a bit + * because you never know what subsequent SCSI standards might do + * (i.e. could there be a 20 byte or a 24-byte command a few years + * down the road?). */ - unsigned short max_cmd_len; + unsigned char max_cmd_len; int this_id; int can_queue; diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index 6135d07f31ec..3e7b257fc05f 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -316,16 +316,9 @@ config CPUSETS Say N if unsure. -# -# Architectures with an unreliable sched_clock() should select this: -# -config HAVE_UNSTABLE_SCHED_CLOCK - bool - config GROUP_SCHED bool "Group CPU scheduler" - depends on EXPERIMENTAL - default n + default y help This feature lets CPU scheduler recognize task groups and control CPU bandwidth allocation to such task groups. @@ -333,7 +326,7 @@ config GROUP_SCHED config FAIR_GROUP_SCHED bool "Group scheduling for SCHED_OTHER" depends on GROUP_SCHED - default GROUP_SCHED + default y config RT_GROUP_SCHED bool "Group scheduling for SCHED_RR/FIFO" @@ -634,14 +627,6 @@ config ELF_CORE help Enable support for generating core dumps. Disabling saves about 4k. -config PCSPKR_PLATFORM - bool "Enable PC-Speaker support" if EMBEDDED - depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES - default y - help - This option allows to disable the internal PC-Speaker - support, saving some memory. - config COMPAT_BRK bool "Disable heap randomization" default y @@ -735,7 +720,7 @@ config VM_EVENT_COUNTERS config SLUB_DEBUG default y bool "Enable SLUB debugging support" if EMBEDDED - depends on SLUB && SYSFS + depends on SLUB help SLUB has extensive debug support features. Disabling these can result in significant savings in code size. This also disables @@ -840,15 +825,6 @@ menuconfig MODULES If unsure, say Y. -config MODULE_FORCE_LOAD - bool "Forced module loading" - depends on MODULES - default n - help - Allow loading of modules without version information (ie. modprobe - --force). Forced module loading sets the 'F' (forced) taint flag and - is usually a really bad idea. - config MODULE_UNLOAD bool "Module unloading" depends on MODULES diff --git a/trunk/init/main.c b/trunk/init/main.c index ddada7acf363..a87d4ca5c36c 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -602,7 +602,6 @@ asmlinkage void __init start_kernel(void) softirq_init(); timekeeping_init(); time_init(); - sched_clock_init(); profile_init(); if (!irqs_disabled()) printk("start_kernel(): bug: interrupts were enabled early\n"); diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index b3b69fd51330..94fd3b08fb77 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -673,7 +673,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, if (IS_ERR(name = getname(u_name))) return PTR_ERR(name); - fd = get_unused_fd_flags(O_CLOEXEC); + fd = get_unused_fd(); if (fd < 0) goto out_putname; @@ -709,6 +709,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, goto out_putfd; } + set_close_on_exec(fd, 1); fd_install(fd, filp); goto out_upsem; diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index 1c9938addb9d..188c43223f52 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ - notifier.o ksysfs.o pm_qos_params.o sched_clock.o + notifier.o ksysfs.o pm_qos_params.o obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o obj-$(CONFIG_STACKTRACE) += stacktrace.o 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/cpuset.c b/trunk/kernel/cpuset.c index 86ea9e34e326..8da627d33804 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -1031,9 +1031,11 @@ int current_cpuset_is_being_rebound(void) return task_cs(current) == cpuset_being_rebound; } -static int update_relax_domain_level(struct cpuset *cs, s64 val) +static int update_relax_domain_level(struct cpuset *cs, char *buf) { - if ((int)val < 0) + int val = simple_strtol(buf, NULL, 10); + + if (val < 0) val = -1; if (val != cs->relax_domain_level) { @@ -1278,6 +1280,9 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, case FILE_MEMLIST: retval = update_nodemask(cs, buffer); break; + case FILE_SCHED_RELAX_DOMAIN_LEVEL: + retval = update_relax_domain_level(cs, buffer); + break; default: retval = -EINVAL; goto out2; @@ -1343,30 +1348,6 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val) return retval; } -static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val) -{ - int retval = 0; - struct cpuset *cs = cgroup_cs(cgrp); - cpuset_filetype_t type = cft->private; - - cgroup_lock(); - - if (cgroup_is_removed(cgrp)) { - cgroup_unlock(); - return -ENODEV; - } - switch (type) { - case FILE_SCHED_RELAX_DOMAIN_LEVEL: - retval = update_relax_domain_level(cs, val); - break; - default: - retval = -EINVAL; - break; - } - cgroup_unlock(); - return retval; -} - /* * These ascii lists should be read in a single call, by using a user * buffer large enough to hold the entire map. If read in smaller @@ -1425,6 +1406,9 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont, case FILE_MEMLIST: s += cpuset_sprintf_memlist(s, cs); break; + case FILE_SCHED_RELAX_DOMAIN_LEVEL: + s += sprintf(s, "%d", cs->relax_domain_level); + break; default: retval = -EINVAL; goto out; @@ -1465,18 +1449,6 @@ static u64 cpuset_read_u64(struct cgroup *cont, struct cftype *cft) } } -static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft) -{ - struct cpuset *cs = cgroup_cs(cont); - cpuset_filetype_t type = cft->private; - switch (type) { - case FILE_SCHED_RELAX_DOMAIN_LEVEL: - return cs->relax_domain_level; - default: - BUG(); - } -} - /* * for the common functions, 'private' gives the type of file @@ -1527,8 +1499,8 @@ static struct cftype files[] = { { .name = "sched_relax_domain_level", - .read_s64 = cpuset_read_s64, - .write_s64 = cpuset_write_s64, + .read_u64 = cpuset_read_u64, + .write_u64 = cpuset_write_u64, .private = FILE_SCHED_RELAX_DOMAIN_LEVEL, }, diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 1510f78a0ffa..d3ad54677f9c 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 933e60ebccae..2bb675af4de3 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 449def8074fe..98092c9817f4 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -104,6 +104,10 @@ struct futex_q { /* Key which the futex is hashed on: */ union futex_key key; + /* For fd, sigio sent using these: */ + int fd; + struct file *filp; + /* Optional priority inheritance state: */ struct futex_pi_state *pi_state; struct task_struct *task; @@ -122,6 +126,9 @@ struct futex_hash_bucket { static struct futex_hash_bucket futex_queues[1<mmap_sem, when futex is shared */ @@ -603,6 +610,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, static void wake_futex(struct futex_q *q) { plist_del(&q->list, &q->list.plist); + if (q->filp) + send_sigio(&q->filp->f_owner, q->fd, POLL_IN); /* * The lock in wake_up_all() is a crucial memory barrier after the * plist_del() and also before assigning to q->lock_ptr. @@ -979,10 +988,14 @@ static int futex_requeue(u32 __user *uaddr1, struct rw_semaphore *fshared, } /* The key must be already stored in q->key. */ -static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) +static inline struct futex_hash_bucket * +queue_lock(struct futex_q *q, int fd, struct file *filp) { struct futex_hash_bucket *hb; + q->fd = fd; + q->filp = filp; + init_waitqueue_head(&q->waiters); get_futex_key_refs(&q->key); @@ -993,7 +1006,7 @@ static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) return hb; } -static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) +static inline void __queue_me(struct futex_q *q, struct futex_hash_bucket *hb) { int prio; @@ -1028,6 +1041,15 @@ queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb) * exactly once. They are called with the hashed spinlock held. */ +/* The key must be already stored in q->key. */ +static void queue_me(struct futex_q *q, int fd, struct file *filp) +{ + struct futex_hash_bucket *hb; + + hb = queue_lock(q, fd, filp); + __queue_me(q, hb); +} + /* Return 1 if we were still queued (ie. 0 means we were woken) */ static int unqueue_me(struct futex_q *q) { @@ -1172,7 +1194,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, if (unlikely(ret != 0)) goto out_release_sem; - hb = queue_lock(&q); + hb = queue_lock(&q, -1, NULL); /* * Access the page AFTER the futex is queued. @@ -1216,7 +1238,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, goto out_unlock_release_sem; /* Only actually queue if *uaddr contained val. */ - queue_me(&q, hb); + __queue_me(&q, hb); /* * Now the futex is queued and we have checked the data, we @@ -1364,7 +1386,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, goto out_release_sem; retry_unlocked: - hb = queue_lock(&q); + hb = queue_lock(&q, -1, NULL); retry_locked: ret = lock_taken = 0; @@ -1477,7 +1499,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, /* * Only actually queue now that the atomic ops are done: */ - queue_me(&q, hb); + __queue_me(&q, hb); /* * Now the futex is queued and we have checked the data, we @@ -1724,6 +1746,121 @@ static int futex_unlock_pi(u32 __user *uaddr, struct rw_semaphore *fshared) return ret; } +static int futex_close(struct inode *inode, struct file *filp) +{ + struct futex_q *q = filp->private_data; + + unqueue_me(q); + kfree(q); + + return 0; +} + +/* This is one-shot: once it's gone off you need a new fd */ +static unsigned int futex_poll(struct file *filp, + struct poll_table_struct *wait) +{ + struct futex_q *q = filp->private_data; + int ret = 0; + + poll_wait(filp, &q->waiters, wait); + + /* + * plist_node_empty() is safe here without any lock. + * q->lock_ptr != 0 is not safe, because of ordering against wakeup. + */ + if (plist_node_empty(&q->list)) + ret = POLLIN | POLLRDNORM; + + return ret; +} + +static const struct file_operations futex_fops = { + .release = futex_close, + .poll = futex_poll, +}; + +/* + * Signal allows caller to avoid the race which would occur if they + * set the sigio stuff up afterwards. + */ +static int futex_fd(u32 __user *uaddr, int signal) +{ + struct futex_q *q; + struct file *filp; + int ret, err; + struct rw_semaphore *fshared; + static unsigned long printk_interval; + + if (printk_timed_ratelimit(&printk_interval, 60 * 60 * 1000)) { + printk(KERN_WARNING "Process `%s' used FUTEX_FD, which " + "will be removed from the kernel in June 2007\n", + current->comm); + } + + ret = -EINVAL; + if (!valid_signal(signal)) + goto out; + + ret = get_unused_fd(); + if (ret < 0) + goto out; + filp = get_empty_filp(); + if (!filp) { + put_unused_fd(ret); + ret = -ENFILE; + goto out; + } + filp->f_op = &futex_fops; + filp->f_path.mnt = mntget(futex_mnt); + filp->f_path.dentry = dget(futex_mnt->mnt_root); + filp->f_mapping = filp->f_path.dentry->d_inode->i_mapping; + + if (signal) { + err = __f_setown(filp, task_pid(current), PIDTYPE_PID, 1); + if (err < 0) { + goto error; + } + filp->f_owner.signum = signal; + } + + q = kmalloc(sizeof(*q), GFP_KERNEL); + if (!q) { + err = -ENOMEM; + goto error; + } + q->pi_state = NULL; + + fshared = ¤t->mm->mmap_sem; + down_read(fshared); + err = get_futex_key(uaddr, fshared, &q->key); + + if (unlikely(err != 0)) { + up_read(fshared); + kfree(q); + goto error; + } + + /* + * queue_me() must be called before releasing mmap_sem, because + * key->shared.inode needs to be referenced while holding it. + */ + filp->private_data = q; + + queue_me(q, ret, filp); + up_read(fshared); + + /* Now we map fd to filp, so userspace can access it */ + fd_install(ret, filp); +out: + return ret; +error: + put_unused_fd(ret); + put_filp(filp); + ret = err; + goto out; +} + /* * Support for robust futexes: the kernel cleans up held futexes at * thread exit time. @@ -1955,6 +2092,10 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, case FUTEX_WAKE_BITSET: ret = futex_wake(uaddr, fshared, val, val3); break; + case FUTEX_FD: + /* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */ + ret = futex_fd(uaddr, val); + break; case FUTEX_REQUEUE: ret = futex_requeue(uaddr, fshared, uaddr2, val, val2, NULL); break; @@ -2015,6 +2156,19 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); } +static int futexfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) +{ + return get_sb_pseudo(fs_type, "futex", NULL, FUTEXFS_SUPER_MAGIC, mnt); +} + +static struct file_system_type futex_fs_type = { + .name = "futexfs", + .get_sb = futexfs_get_sb, + .kill_sb = kill_anon_super, +}; + static int __init futex_init(void) { u32 curval; @@ -2039,6 +2193,16 @@ static int __init futex_init(void) spin_lock_init(&futex_queues[i].lock); } + i = register_filesystem(&futex_fs_type); + if (i) + return i; + + futex_mnt = kern_mount(&futex_fs_type); + if (IS_ERR(futex_mnt)) { + unregister_filesystem(&futex_fs_type); + return PTR_ERR(futex_mnt); + } + return 0; } __initcall(futex_init); diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 421be5fe5cc7..9af1d6a8095e 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -153,6 +153,15 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) ktime_add(xtim, tomono); } +/* + * Helper function to check, whether the timer is running the callback + * function + */ +static inline int hrtimer_callback_running(struct hrtimer *timer) +{ + return timer->state & HRTIMER_STATE_CALLBACK; +} + /* * Functions and macros which are different for UP/SMP systems are kept in a * single place 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/kgdb.c b/trunk/kernel/kgdb.c index 39e31a036f5b..1bd0ec1c80b2 100644 --- a/trunk/kernel/kgdb.c +++ b/trunk/kernel/kgdb.c @@ -61,7 +61,7 @@ struct kgdb_state { int err_code; int cpu; int pass_exception; - unsigned long threadid; + long threadid; long kgdb_usethreadid; struct pt_regs *linux_regs; }; @@ -146,7 +146,7 @@ atomic_t kgdb_cpu_doing_single_step = ATOMIC_INIT(-1); * the other CPUs might interfere with your debugging context, so * use this with care: */ -static int kgdb_do_roundup = 1; +int kgdb_do_roundup = 1; static int __init opt_nokgdbroundup(char *str) { @@ -438,7 +438,7 @@ int kgdb_hex2mem(char *buf, char *mem, int count) * While we find nice hex chars, build a long_val. * Return number of chars processed. */ -int kgdb_hex2long(char **ptr, unsigned long *long_val) +int kgdb_hex2long(char **ptr, long *long_val) { int hex_val; int num = 0; @@ -709,7 +709,7 @@ int kgdb_isremovedbreak(unsigned long addr) return 0; } -static int remove_all_break(void) +int remove_all_break(void) { unsigned long addr; int error; diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 8df97d3dfda8..e2764047ec03 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index f5e9491ef7ac..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(); @@ -890,19 +881,6 @@ static struct module_attribute *modinfo_attrs[] = { static const char vermagic[] = VERMAGIC_STRING; -static int try_to_force_load(struct module *mod, const char *symname) -{ -#ifdef CONFIG_MODULE_FORCE_LOAD - if (!(tainted & TAINT_FORCED_MODULE)) - printk("%s: no version for \"%s\" found: kernel tainted.\n", - mod->name, symname); - add_taint_module(mod, TAINT_FORCED_MODULE); - return 0; -#else - return -ENOEXEC; -#endif -} - #ifdef CONFIG_MODVERSIONS static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, @@ -917,10 +895,6 @@ static int check_version(Elf_Shdr *sechdrs, if (!crc) return 1; - /* No versions at all? modprobe --force does this. */ - if (versindex == 0) - return try_to_force_load(mod, symname) == 0; - versions = (void *) sechdrs[versindex].sh_addr; num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); @@ -931,19 +905,18 @@ static int check_version(Elf_Shdr *sechdrs, if (versions[i].crc == *crc) return 1; + printk("%s: disagrees about version of symbol %s\n", + mod->name, symname); DEBUGP("Found checksum %lX vs module %lX\n", *crc, versions[i].crc); - goto bad_version; + return 0; } - - printk(KERN_WARNING "%s: no symbol version for %s\n", - mod->name, symname); - return 0; - -bad_version: - printk("%s: disagrees about version of symbol %s\n", - mod->name, symname); - return 0; + /* Not in module's version table. OK, but that taints the kernel. */ + if (!(tainted & TAINT_FORCED_MODULE)) + printk("%s: no version for \"%s\" found: kernel tainted.\n", + mod->name, symname); + add_taint_module(mod, TAINT_FORCED_MODULE); + return 1; } static inline int check_modstruct_version(Elf_Shdr *sechdrs, @@ -951,20 +924,20 @@ 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 if module has crcs. */ -static inline int same_magic(const char *amagic, const char *bmagic, - bool has_crcs) +/* First part is kernel version, which we ignore. */ +static inline int same_magic(const char *amagic, const char *bmagic) { - if (has_crcs) { - amagic += strcspn(amagic, " "); - bmagic += strcspn(bmagic, " "); - } + amagic += strcspn(amagic, " "); + bmagic += strcspn(bmagic, " "); return strcmp(amagic, bmagic) == 0; } #else @@ -984,8 +957,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, return 1; } -static inline int same_magic(const char *amagic, const char *bmagic, - bool has_crcs) +static inline int same_magic(const char *amagic, const char *bmagic) { return strcmp(amagic, bmagic) == 0; } @@ -1002,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 */ @@ -1019,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) { @@ -1043,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); @@ -1404,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)) @@ -1423,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. */ @@ -1855,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; @@ -1875,10 +1833,10 @@ static struct module *load_module(void __user *umod, modmagic = get_modinfo(sechdrs, infoindex, "vermagic"); /* This is allowed: modprobe --force will invalidate it. */ if (!modmagic) { - err = try_to_force_load(mod, "magic"); - if (err) - goto free_hdr; - } else if (!same_magic(modmagic, vermagic, versindex)) { + add_taint_module(mod, TAINT_FORCED_MODULE); + printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", + mod->name); + } else if (!same_magic(modmagic, vermagic)) { printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", mod->name, modmagic, vermagic); err = -ENOEXEC; @@ -2019,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) || @@ -2028,10 +1985,9 @@ static struct module *load_module(void __user *umod, (mod->num_gpl_future_syms && !gplfuturecrcindex) || (mod->num_unused_syms && !unusedcrcindex) || (mod->num_unused_gpl_syms && !unusedgplcrcindex)) { - printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name); - err = try_to_force_load(mod, "nocrc"); - if (err) - goto cleanup; + printk(KERN_WARNING "%s: No versions for exported symbols." + " Tainting kernel.\n", mod->name); + add_taint_module(mod, TAINT_FORCED_MODULE); } #endif markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); @@ -2215,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/relay.c b/trunk/kernel/relay.c index bc24dcdc570f..7de644cdec43 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -1191,7 +1191,7 @@ static ssize_t relay_file_splice_read(struct file *in, ret = 0; spliced = 0; - while (len) { + while (len && !spliced) { ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret); if (ret < 0) break; diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 58fb8af15776..e2f7f5acc807 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -74,6 +74,16 @@ #include #include +/* + * Scheduler clock - returns current time in nanosec units. + * This is default implementation. + * Architectures and sub-architectures can override this. + */ +unsigned long long __attribute__((weak)) sched_clock(void) +{ + return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ); +} + /* * Convert user-nice values [ -20 ... 0 ... 19 ] * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ], @@ -232,12 +242,6 @@ static void destroy_rt_bandwidth(struct rt_bandwidth *rt_b) } #endif -/* - * sched_domains_mutex serializes calls to arch_init_sched_domains, - * detach_destroy_domains and partition_sched_domains. - */ -static DEFINE_MUTEX(sched_domains_mutex); - #ifdef CONFIG_GROUP_SCHED #include @@ -304,6 +308,9 @@ static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp; */ static DEFINE_SPINLOCK(task_group_lock); +/* doms_cur_mutex serializes access to doms_cur[] array */ +static DEFINE_MUTEX(doms_cur_mutex); + #ifdef CONFIG_FAIR_GROUP_SCHED #ifdef CONFIG_USER_SCHED # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD) @@ -311,13 +318,7 @@ static DEFINE_SPINLOCK(task_group_lock); # define INIT_TASK_GROUP_LOAD NICE_0_LOAD #endif -/* - * A weight of 0, 1 or ULONG_MAX can cause arithmetics problems. - * (The default weight is 1024 - so there's no practical - * limitation from this.) - */ #define MIN_SHARES 2 -#define MAX_SHARES (ULONG_MAX - 1) static int init_task_group_load = INIT_TASK_GROUP_LOAD; #endif @@ -357,9 +358,21 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu) #endif } +static inline void lock_doms_cur(void) +{ + mutex_lock(&doms_cur_mutex); +} + +static inline void unlock_doms_cur(void) +{ + mutex_unlock(&doms_cur_mutex); +} + #else static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { } +static inline void lock_doms_cur(void) { } +static inline void unlock_doms_cur(void) { } #endif /* CONFIG_GROUP_SCHED */ @@ -547,7 +560,13 @@ struct rq { unsigned long next_balance; struct mm_struct *prev_mm; - u64 clock; + u64 clock, prev_clock_raw; + s64 clock_max_delta; + + unsigned int clock_warps, clock_overflows, clock_underflows; + u64 idle_clock; + unsigned int clock_deep_idle_events; + u64 tick_timestamp; atomic_t nr_iowait; @@ -612,6 +631,82 @@ static inline int cpu_of(struct rq *rq) #endif } +#ifdef CONFIG_NO_HZ +static inline bool nohz_on(int cpu) +{ + return tick_get_tick_sched(cpu)->nohz_mode != NOHZ_MODE_INACTIVE; +} + +static inline u64 max_skipped_ticks(struct rq *rq) +{ + return nohz_on(cpu_of(rq)) ? jiffies - rq->last_tick_seen + 2 : 1; +} + +static inline void update_last_tick_seen(struct rq *rq) +{ + rq->last_tick_seen = jiffies; +} +#else +static inline u64 max_skipped_ticks(struct rq *rq) +{ + return 1; +} + +static inline void update_last_tick_seen(struct rq *rq) +{ +} +#endif + +/* + * Update the per-runqueue clock, as finegrained as the platform can give + * us, but without assuming monotonicity, etc.: + */ +static void __update_rq_clock(struct rq *rq) +{ + u64 prev_raw = rq->prev_clock_raw; + u64 now = sched_clock(); + s64 delta = now - prev_raw; + u64 clock = rq->clock; + +#ifdef CONFIG_SCHED_DEBUG + WARN_ON_ONCE(cpu_of(rq) != smp_processor_id()); +#endif + /* + * Protect against sched_clock() occasionally going backwards: + */ + if (unlikely(delta < 0)) { + clock++; + rq->clock_warps++; + } else { + /* + * Catch too large forward jumps too: + */ + u64 max_jump = max_skipped_ticks(rq) * TICK_NSEC; + u64 max_time = rq->tick_timestamp + max_jump; + + if (unlikely(clock + delta > max_time)) { + if (clock < max_time) + clock = max_time; + else + clock++; + rq->clock_overflows++; + } else { + if (unlikely(delta > rq->clock_max_delta)) + rq->clock_max_delta = delta; + clock += delta; + } + } + + rq->prev_clock_raw = now; + rq->clock = clock; +} + +static void update_rq_clock(struct rq *rq) +{ + if (likely(smp_processor_id() == cpu_of(rq))) + __update_rq_clock(rq); +} + /* * The domain tree (rq->sd) is protected by RCU's quiescent state transition. * See detach_destroy_domains: synchronize_sched for details. @@ -627,11 +722,6 @@ static inline int cpu_of(struct rq *rq) #define task_rq(p) cpu_rq(task_cpu(p)) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) -static inline void update_rq_clock(struct rq *rq) -{ - rq->clock = sched_clock_cpu(cpu_of(rq)); -} - /* * Tunables that become constants when CONFIG_SCHED_DEBUG is off: */ @@ -667,14 +757,14 @@ const_debug unsigned int sysctl_sched_features = #define SCHED_FEAT(name, enabled) \ #name , -static __read_mostly char *sched_feat_names[] = { +__read_mostly char *sched_feat_names[] = { #include "sched_features.h" NULL }; #undef SCHED_FEAT -static int sched_feat_open(struct inode *inode, struct file *filp) +int sched_feat_open(struct inode *inode, struct file *filp) { filp->private_data = inode->i_private; return 0; @@ -809,7 +899,7 @@ static inline u64 global_rt_runtime(void) return (u64)sysctl_sched_rt_runtime * NSEC_PER_USEC; } -unsigned long long time_sync_thresh = 100000; +static const unsigned long long time_sync_thresh = 100000; static DEFINE_PER_CPU(unsigned long long, time_offset); static DEFINE_PER_CPU(unsigned long long, prev_cpu_time); @@ -823,14 +913,11 @@ static DEFINE_PER_CPU(unsigned long long, prev_cpu_time); static DEFINE_SPINLOCK(time_sync_lock); static unsigned long long prev_global_time; -static unsigned long long __sync_cpu_clock(unsigned long long time, int cpu) +static unsigned long long __sync_cpu_clock(cycles_t time, int cpu) { - /* - * We want this inlined, to not get tracer function calls - * in this critical section: - */ - spin_acquire(&time_sync_lock.dep_map, 0, 0, _THIS_IP_); - __raw_spin_lock(&time_sync_lock.raw_lock); + unsigned long flags; + + spin_lock_irqsave(&time_sync_lock, flags); if (time < prev_global_time) { per_cpu(time_offset, cpu) += prev_global_time - time; @@ -839,8 +926,7 @@ static unsigned long long __sync_cpu_clock(unsigned long long time, int cpu) prev_global_time = time; } - __raw_spin_unlock(&time_sync_lock.raw_lock); - spin_release(&time_sync_lock.dep_map, 1, _THIS_IP_); + spin_unlock_irqrestore(&time_sync_lock, flags); return time; } @@ -848,6 +934,8 @@ static unsigned long long __sync_cpu_clock(unsigned long long time, int cpu) static unsigned long long __cpu_clock(int cpu) { unsigned long long now; + unsigned long flags; + struct rq *rq; /* * Only call sched_clock() if the scheduler has already been @@ -856,7 +944,11 @@ static unsigned long long __cpu_clock(int cpu) if (unlikely(!scheduler_running)) return 0; - now = sched_clock_cpu(cpu); + local_irq_save(flags); + rq = cpu_rq(cpu); + update_rq_clock(rq); + now = rq->clock; + local_irq_restore(flags); return now; } @@ -868,18 +960,13 @@ static unsigned long long __cpu_clock(int cpu) unsigned long long cpu_clock(int cpu) { unsigned long long prev_cpu_time, time, delta_time; - unsigned long flags; - local_irq_save(flags); prev_cpu_time = per_cpu(prev_cpu_time, cpu); time = __cpu_clock(cpu) + per_cpu(time_offset, cpu); delta_time = time-prev_cpu_time; - if (unlikely(delta_time > time_sync_thresh)) { + if (unlikely(delta_time > time_sync_thresh)) time = __sync_cpu_clock(time, cpu); - per_cpu(prev_cpu_time, cpu) = time; - } - local_irq_restore(flags); return time; } @@ -1030,6 +1117,43 @@ static struct rq *this_rq_lock(void) return rq; } +/* + * We are going deep-idle (irqs are disabled): + */ +void sched_clock_idle_sleep_event(void) +{ + struct rq *rq = cpu_rq(smp_processor_id()); + + spin_lock(&rq->lock); + __update_rq_clock(rq); + spin_unlock(&rq->lock); + rq->clock_deep_idle_events++; +} +EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event); + +/* + * We just idled delta nanoseconds (called with irqs disabled): + */ +void sched_clock_idle_wakeup_event(u64 delta_ns) +{ + struct rq *rq = cpu_rq(smp_processor_id()); + u64 now = sched_clock(); + + rq->idle_clock += delta_ns; + /* + * Override the previous timestamp and ignore all + * sched_clock() deltas that occured while we idled, + * and use the PM-provided delta_ns to advance the + * rq clock: + */ + spin_lock(&rq->lock); + rq->prev_clock_raw = now; + rq->clock += delta_ns; + spin_unlock(&rq->lock); + touch_softlockup_watchdog(); +} +EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); + static void __resched_task(struct task_struct *p, int tif_bit); static inline void resched_task(struct task_struct *p) @@ -1065,7 +1189,6 @@ static inline void resched_rq(struct rq *rq) enum { HRTICK_SET, /* re-programm hrtick_timer */ HRTICK_RESET, /* not a new slice */ - HRTICK_BLOCK, /* stop hrtick operations */ }; /* @@ -1077,8 +1200,6 @@ static inline int hrtick_enabled(struct rq *rq) { if (!sched_feat(HRTICK)) return 0; - if (unlikely(test_bit(HRTICK_BLOCK, &rq->hrtick_flags))) - return 0; return hrtimer_is_hres_active(&rq->hrtick_timer); } @@ -1154,70 +1275,14 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer) WARN_ON_ONCE(cpu_of(rq) != smp_processor_id()); spin_lock(&rq->lock); - update_rq_clock(rq); + __update_rq_clock(rq); rq->curr->sched_class->task_tick(rq, rq->curr, 1); spin_unlock(&rq->lock); return HRTIMER_NORESTART; } -static void hotplug_hrtick_disable(int cpu) -{ - struct rq *rq = cpu_rq(cpu); - unsigned long flags; - - spin_lock_irqsave(&rq->lock, flags); - rq->hrtick_flags = 0; - __set_bit(HRTICK_BLOCK, &rq->hrtick_flags); - spin_unlock_irqrestore(&rq->lock, flags); - - hrtick_clear(rq); -} - -static void hotplug_hrtick_enable(int cpu) -{ - struct rq *rq = cpu_rq(cpu); - unsigned long flags; - - spin_lock_irqsave(&rq->lock, flags); - __clear_bit(HRTICK_BLOCK, &rq->hrtick_flags); - spin_unlock_irqrestore(&rq->lock, flags); -} - -static int -hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu) -{ - int cpu = (int)(long)hcpu; - - switch (action) { - case CPU_UP_CANCELED: - case CPU_UP_CANCELED_FROZEN: - case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - case CPU_DEAD: - case CPU_DEAD_FROZEN: - hotplug_hrtick_disable(cpu); - return NOTIFY_OK; - - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: - case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - hotplug_hrtick_enable(cpu); - return NOTIFY_OK; - } - - return NOTIFY_DONE; -} - -static void init_hrtick(void) -{ - hotcpu_notifier(hotplug_hrtick, 0); -} - -static void init_rq_hrtick(struct rq *rq) +static inline void init_rq_hrtick(struct rq *rq) { rq->hrtick_flags = 0; hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); @@ -1254,10 +1319,6 @@ static inline void init_rq_hrtick(struct rq *rq) void hrtick_resched(void) { } - -static inline void init_hrtick(void) -{ -} #endif /* @@ -1377,8 +1438,8 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, { u64 tmp; - if (!lw->inv_weight) - lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1); + if (unlikely(!lw->inv_weight)) + lw->inv_weight = (WMULT_CONST-lw->weight/2) / (lw->weight+1); tmp = (u64)delta_exec * weight; /* @@ -1687,8 +1748,6 @@ __update_group_shares_cpu(struct task_group *tg, struct sched_domain *sd, if (shares < MIN_SHARES) shares = MIN_SHARES; - else if (shares > MAX_SHARES) - shares = MAX_SHARES; __set_se_shares(tg->se[tcpu], shares); } @@ -4280,10 +4339,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset, struct rq *rq = this_rq(); cputime64_t tmp; - if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { - account_guest_time(p, cputime); - return; - } + if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) + return account_guest_time(p, cputime); p->stime = cputime_add(p->stime, cputime); @@ -4347,11 +4404,19 @@ void scheduler_tick(void) int cpu = smp_processor_id(); struct rq *rq = cpu_rq(cpu); struct task_struct *curr = rq->curr; - - sched_clock_tick(); + u64 next_tick = rq->tick_timestamp + TICK_NSEC; spin_lock(&rq->lock); - update_rq_clock(rq); + __update_rq_clock(rq); + /* + * Let rq->clock advance by at least TICK_NSEC: + */ + if (unlikely(rq->clock < next_tick)) { + rq->clock = next_tick; + rq->clock_underflows++; + } + rq->tick_timestamp = rq->clock; + update_last_tick_seen(rq); update_cpu_load(rq); curr->sched_class->task_tick(rq, curr, 0); spin_unlock(&rq->lock); @@ -4505,7 +4570,7 @@ asmlinkage void __sched schedule(void) * Do the rq-clock update outside the rq lock: */ local_irq_disable(); - update_rq_clock(rq); + __update_rq_clock(rq); spin_lock(&rq->lock); clear_tsk_need_resched(prev); @@ -4530,9 +4595,9 @@ asmlinkage void __sched schedule(void) prev->sched_class->put_prev_task(rq, prev); next = pick_next_task(rq, prev); - if (likely(prev != next)) { - sched_info_switch(prev, next); + sched_info_switch(prev, next); + if (likely(prev != next)) { rq->nr_switches++; rq->curr = next; ++*switch_count; @@ -7690,7 +7755,7 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, { int i, j; - mutex_lock(&sched_domains_mutex); + lock_doms_cur(); /* always unregister in case we don't destroy any domains */ unregister_sched_domain_sysctl(); @@ -7739,7 +7804,7 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, register_sched_domain_sysctl(); - mutex_unlock(&sched_domains_mutex); + unlock_doms_cur(); } #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) @@ -7748,10 +7813,8 @@ int arch_reinit_sched_domains(void) int err; get_online_cpus(); - mutex_lock(&sched_domains_mutex); detach_destroy_domains(&cpu_online_map); err = arch_init_sched_domains(&cpu_online_map); - mutex_unlock(&sched_domains_mutex); put_online_cpus(); return err; @@ -7869,16 +7932,13 @@ void __init sched_init_smp(void) BUG_ON(sched_group_nodes_bycpu == NULL); #endif get_online_cpus(); - mutex_lock(&sched_domains_mutex); arch_init_sched_domains(&cpu_online_map); cpus_andnot(non_isolated_cpus, cpu_possible_map, cpu_isolated_map); if (cpus_empty(non_isolated_cpus)) cpu_set(smp_processor_id(), non_isolated_cpus); - mutex_unlock(&sched_domains_mutex); put_online_cpus(); /* XXX: Theoretical race here - CPU may be hotplugged now */ hotcpu_notifier(update_sched_domains, 0); - init_hrtick(); /* Move init over to a non-isolated CPU */ if (set_cpus_allowed_ptr(current, &non_isolated_cpus) < 0) @@ -7965,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 = 0; + se->load.inv_weight = div64_64(1ULL<<32, se->load.weight); se->parent = parent; } #endif @@ -8089,6 +8149,8 @@ void __init sched_init(void) spin_lock_init(&rq->lock); lockdep_set_class(&rq->lock, &rq->rq_lock_key); rq->nr_running = 0; + rq->clock = 1; + update_last_tick_seen(rq); init_cfs_rq(&rq->cfs, rq); init_rt_rq(&rq->rt, rq); #ifdef CONFIG_FAIR_GROUP_SCHED @@ -8232,7 +8294,6 @@ EXPORT_SYMBOL(__might_sleep); static void normalize_task(struct rq *rq, struct task_struct *p) { int on_rq; - update_rq_clock(rq); on_rq = p->se.on_rq; if (on_rq) @@ -8264,6 +8325,7 @@ void normalize_rt_tasks(void) p->se.sleep_start = 0; p->se.block_start = 0; #endif + task_rq(p)->clock = 0; if (!rt_task(p)) { /* @@ -8630,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 = 0; + se->load.inv_weight = div64_64((1ULL<<32), shares); if (on_rq) enqueue_entity(cfs_rq, se, 0); @@ -8660,10 +8722,13 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) if (!tg->se[0]) return -EINVAL; + /* + * A weight of 0 or 1 can cause arithmetics problems. + * (The default weight is 1024 - so there's no practical + * limitation from this.) + */ if (shares < MIN_SHARES) shares = MIN_SHARES; - else if (shares > MAX_SHARES) - shares = MAX_SHARES; mutex_lock(&shares_mutex); if (tg->shares == shares) @@ -8688,7 +8753,7 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) * force a rebalance */ cfs_rq_set_shares(tg->cfs_rq[i], 0); - set_se_shares(tg->se[i], shares); + set_se_shares(tg->se[i], shares/nr_cpu_ids); } /* @@ -8722,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_clock.c b/trunk/kernel/sched_clock.c deleted file mode 100644 index 9c597e37f7de..000000000000 --- a/trunk/kernel/sched_clock.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * sched_clock for unstable cpu clocks - * - * Copyright (C) 2008 Red Hat, Inc., Peter Zijlstra - * - * Based on code by: - * Ingo Molnar - * Guillaume Chazarain - * - * Create a semi stable clock from a mixture of other events, including: - * - gtod - * - jiffies - * - sched_clock() - * - explicit idle events - * - * We use gtod as base and the unstable clock deltas. The deltas are filtered, - * making it monotonic and keeping it within an expected window. This window - * is set up using jiffies. - * - * Furthermore, explicit sleep and wakeup hooks allow us to account for time - * that is otherwise invisible (TSC gets stopped). - * - * The clock: sched_clock_cpu() is monotonic per cpu, and should be somewhat - * consistent between cpus (never more than 1 jiffies difference). - */ -#include -#include -#include -#include -#include - - -#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK - -struct sched_clock_data { - /* - * Raw spinlock - this is a special case: this might be called - * from within instrumentation code so we dont want to do any - * instrumentation ourselves. - */ - raw_spinlock_t lock; - - unsigned long prev_jiffies; - u64 prev_raw; - u64 tick_raw; - u64 tick_gtod; - u64 clock; -}; - -static DEFINE_PER_CPU_SHARED_ALIGNED(struct sched_clock_data, sched_clock_data); - -static inline struct sched_clock_data *this_scd(void) -{ - return &__get_cpu_var(sched_clock_data); -} - -static inline struct sched_clock_data *cpu_sdc(int cpu) -{ - return &per_cpu(sched_clock_data, cpu); -} - -void sched_clock_init(void) -{ - u64 ktime_now = ktime_to_ns(ktime_get()); - u64 now = 0; - int cpu; - - for_each_possible_cpu(cpu) { - struct sched_clock_data *scd = cpu_sdc(cpu); - - scd->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED; - scd->prev_jiffies = jiffies; - scd->prev_raw = now; - scd->tick_raw = now; - scd->tick_gtod = ktime_now; - scd->clock = ktime_now; - } -} - -/* - * update the percpu scd from the raw @now value - * - * - filter out backward motion - * - use jiffies to generate a min,max window to clip the raw values - */ -static void __update_sched_clock(struct sched_clock_data *scd, u64 now) -{ - unsigned long now_jiffies = jiffies; - long delta_jiffies = now_jiffies - scd->prev_jiffies; - u64 clock = scd->clock; - u64 min_clock, max_clock; - s64 delta = now - scd->prev_raw; - - WARN_ON_ONCE(!irqs_disabled()); - min_clock = scd->tick_gtod + delta_jiffies * TICK_NSEC; - - if (unlikely(delta < 0)) { - clock++; - goto out; - } - - max_clock = min_clock + TICK_NSEC; - - if (unlikely(clock + delta > max_clock)) { - if (clock < max_clock) - clock = max_clock; - else - clock++; - } else { - clock += delta; - } - - out: - if (unlikely(clock < min_clock)) - clock = min_clock; - - scd->prev_raw = now; - scd->prev_jiffies = now_jiffies; - scd->clock = clock; -} - -static void lock_double_clock(struct sched_clock_data *data1, - struct sched_clock_data *data2) -{ - if (data1 < data2) { - __raw_spin_lock(&data1->lock); - __raw_spin_lock(&data2->lock); - } else { - __raw_spin_lock(&data2->lock); - __raw_spin_lock(&data1->lock); - } -} - -u64 sched_clock_cpu(int cpu) -{ - struct sched_clock_data *scd = cpu_sdc(cpu); - u64 now, clock; - - WARN_ON_ONCE(!irqs_disabled()); - now = sched_clock(); - - if (cpu != raw_smp_processor_id()) { - /* - * in order to update a remote cpu's clock based on our - * unstable raw time rebase it against: - * tick_raw (offset between raw counters) - * tick_gotd (tick offset between cpus) - */ - struct sched_clock_data *my_scd = this_scd(); - - lock_double_clock(scd, my_scd); - - now -= my_scd->tick_raw; - now += scd->tick_raw; - - now -= my_scd->tick_gtod; - now += scd->tick_gtod; - - __raw_spin_unlock(&my_scd->lock); - } else { - __raw_spin_lock(&scd->lock); - } - - __update_sched_clock(scd, now); - clock = scd->clock; - - __raw_spin_unlock(&scd->lock); - - return clock; -} - -void sched_clock_tick(void) -{ - struct sched_clock_data *scd = this_scd(); - u64 now, now_gtod; - - WARN_ON_ONCE(!irqs_disabled()); - - now = sched_clock(); - now_gtod = ktime_to_ns(ktime_get()); - - __raw_spin_lock(&scd->lock); - __update_sched_clock(scd, now); - /* - * update tick_gtod after __update_sched_clock() because that will - * already observe 1 new jiffy; adding a new tick_gtod to that would - * increase the clock 2 jiffies. - */ - scd->tick_raw = now; - scd->tick_gtod = now_gtod; - __raw_spin_unlock(&scd->lock); -} - -/* - * We are going deep-idle (irqs are disabled): - */ -void sched_clock_idle_sleep_event(void) -{ - sched_clock_cpu(smp_processor_id()); -} -EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event); - -/* - * We just idled delta nanoseconds (called with irqs disabled): - */ -void sched_clock_idle_wakeup_event(u64 delta_ns) -{ - struct sched_clock_data *scd = this_scd(); - u64 now = sched_clock(); - - /* - * Override the previous timestamp and ignore all - * sched_clock() deltas that occured while we idled, - * and use the PM-provided delta_ns to advance the - * rq clock: - */ - __raw_spin_lock(&scd->lock); - scd->prev_raw = now; - scd->clock += delta_ns; - __raw_spin_unlock(&scd->lock); - - touch_softlockup_watchdog(); -} -EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); - -#endif - -/* - * Scheduler clock - returns current time in nanosec units. - * This is default implementation. - * Architectures and sub-architectures can override this. - */ -unsigned long long __attribute__((weak)) sched_clock(void) -{ - return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ); -} diff --git a/trunk/kernel/sched_debug.c b/trunk/kernel/sched_debug.c index 5f06118fbc31..8a9498e7c831 100644 --- a/trunk/kernel/sched_debug.c +++ b/trunk/kernel/sched_debug.c @@ -204,6 +204,13 @@ static void print_cpu(struct seq_file *m, int cpu) PN(next_balance); P(curr->pid); PN(clock); + PN(idle_clock); + PN(prev_clock_raw); + P(clock_warps); + P(clock_overflows); + P(clock_underflows); + P(clock_deep_idle_events); + PN(clock_max_delta); P(cpu_load[0]); P(cpu_load[1]); P(cpu_load[2]); @@ -350,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/sched_fair.c b/trunk/kernel/sched_fair.c index e24ecd39c4b8..89fa32b4edf2 100644 --- a/trunk/kernel/sched_fair.c +++ b/trunk/kernel/sched_fair.c @@ -662,15 +662,10 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) if (!initial) { /* sleeps upto a single latency don't count. */ if (sched_feat(NEW_FAIR_SLEEPERS)) { - unsigned long thresh = sysctl_sched_latency; - - /* - * convert the sleeper threshold into virtual time - */ if (sched_feat(NORMALIZED_SLEEPER)) - thresh = calc_delta_fair(thresh, se); - - vruntime -= thresh; + vruntime -= calc_delta_weight(sysctl_sched_latency, se); + else + vruntime -= sysctl_sched_latency; } /* ensure we never gain time by being placed backwards. */ @@ -687,7 +682,6 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); - account_entity_enqueue(cfs_rq, se); if (wakeup) { place_entity(cfs_rq, se, 0); @@ -698,6 +692,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) check_spread(cfs_rq, se); if (se != cfs_rq->curr) __enqueue_entity(cfs_rq, se); + account_entity_enqueue(cfs_rq, se); } static void update_avg(u64 *avg, u64 sample) @@ -846,10 +841,8 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) * queued ticks are scheduled to match the slice, so don't bother * validating it and just reschedule. */ - if (queued) { - resched_task(rq_of(cfs_rq)->curr); - return; - } + if (queued) + return resched_task(rq_of(cfs_rq)->curr); /* * don't let the period tick interfere with the hrtick preemption */ @@ -964,7 +957,7 @@ static void yield_task_fair(struct rq *rq) return; if (likely(!sysctl_sched_compat_yield) && curr->policy != SCHED_BATCH) { - update_rq_clock(rq); + __update_rq_clock(rq); /* * Update run-time statistics of the 'current'. */ @@ -1014,7 +1007,7 @@ static int wake_idle(int cpu, struct task_struct *p) * sibling runqueue info. This will avoid the checks and cache miss * penalities associated with that. */ - if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1) + if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1) return cpu; for_each_domain(cpu, sd) { @@ -1618,6 +1611,30 @@ static const struct sched_class fair_sched_class = { }; #ifdef CONFIG_SCHED_DEBUG +static void +print_cfs_rq_tasks(struct seq_file *m, struct cfs_rq *cfs_rq, int depth) +{ + struct sched_entity *se; + + if (!cfs_rq) + return; + + list_for_each_entry_rcu(se, &cfs_rq->tasks, group_node) { + int i; + + for (i = depth; i; i--) + seq_puts(m, " "); + + seq_printf(m, "%lu %s %lu\n", + se->load.weight, + entity_is_task(se) ? "T" : "G", + calc_delta_weight(SCHED_LOAD_SCALE, se) + ); + if (!entity_is_task(se)) + print_cfs_rq_tasks(m, group_cfs_rq(se), depth + 1); + } +} + static void print_cfs_stats(struct seq_file *m, int cpu) { struct cfs_rq *cfs_rq; @@ -1625,6 +1642,9 @@ static void print_cfs_stats(struct seq_file *m, int cpu) rcu_read_lock(); for_each_leaf_cfs_rq(cpu_rq(cpu), cfs_rq) print_cfs_rq(m, cpu, cfs_rq); + + seq_printf(m, "\nWeight tree:\n"); + print_cfs_rq_tasks(m, &cpu_rq(cpu)->cfs, 1); rcu_read_unlock(); } #endif diff --git a/trunk/kernel/sched_idletask.c b/trunk/kernel/sched_idletask.c index 3a4f92dbbe66..2bcafa375633 100644 --- a/trunk/kernel/sched_idletask.c +++ b/trunk/kernel/sched_idletask.c @@ -99,7 +99,7 @@ static void prio_changed_idle(struct rq *rq, struct task_struct *p, /* * Simple, special scheduling class for the per-CPU idle tasks: */ -static const struct sched_class idle_sched_class = { +const struct sched_class idle_sched_class = { /* .next is NULL */ /* no enqueue/yield_task for idle tasks */ diff --git a/trunk/kernel/sched_rt.c b/trunk/kernel/sched_rt.c index 060e87b0cb1c..c2730a5a4f05 100644 --- a/trunk/kernel/sched_rt.c +++ b/trunk/kernel/sched_rt.c @@ -1098,14 +1098,11 @@ static void post_schedule_rt(struct rq *rq) } } -/* - * If we are not running and we are not going to reschedule soon, we should - * try to push tasks away now - */ + static void task_wake_up_rt(struct rq *rq, struct task_struct *p) { if (!task_running(rq, p) && - !test_tsk_need_resched(rq->curr) && + (p->prio >= rq->rt.highest_prio) && rq->rt.overloaded) push_rt_tasks(rq); } @@ -1312,7 +1309,7 @@ static void set_curr_task_rt(struct rq *rq) p->se.exec_start = rq->clock; } -static const struct sched_class rt_sched_class = { +const struct sched_class rt_sched_class = { .next = &fair_sched_class, .enqueue_task = enqueue_task_rt, .dequeue_task = dequeue_task_rt, diff --git a/trunk/kernel/semaphore.c b/trunk/kernel/semaphore.c index 5e41217239e8..5c2942e768cd 100644 --- a/trunk/kernel/semaphore.c +++ b/trunk/kernel/semaphore.c @@ -54,9 +54,10 @@ void down(struct semaphore *sem) unsigned long flags; spin_lock_irqsave(&sem->lock, flags); - if (unlikely(!sem->count)) + if (likely(sem->count > 0)) + sem->count--; + else __down(sem); - sem->count--; spin_unlock_irqrestore(&sem->lock, flags); } EXPORT_SYMBOL(down); @@ -76,10 +77,10 @@ int down_interruptible(struct semaphore *sem) int result = 0; spin_lock_irqsave(&sem->lock, flags); - if (unlikely(!sem->count)) - result = __down_interruptible(sem); - if (!result) + if (likely(sem->count > 0)) sem->count--; + else + result = __down_interruptible(sem); spin_unlock_irqrestore(&sem->lock, flags); return result; @@ -102,10 +103,10 @@ int down_killable(struct semaphore *sem) int result = 0; spin_lock_irqsave(&sem->lock, flags); - if (unlikely(!sem->count)) - result = __down_killable(sem); - if (!result) + if (likely(sem->count > 0)) sem->count--; + else + result = __down_killable(sem); spin_unlock_irqrestore(&sem->lock, flags); return result; @@ -156,10 +157,10 @@ int down_timeout(struct semaphore *sem, long jiffies) int result = 0; spin_lock_irqsave(&sem->lock, flags); - if (unlikely(!sem->count)) - result = __down_timeout(sem, jiffies); - if (!result) + if (likely(sem->count > 0)) sem->count--; + else + result = __down_timeout(sem, jiffies); spin_unlock_irqrestore(&sem->lock, flags); return result; @@ -178,8 +179,9 @@ void up(struct semaphore *sem) unsigned long flags; spin_lock_irqsave(&sem->lock, flags); - sem->count++; - if (unlikely(!list_empty(&sem->wait_list))) + if (likely(list_empty(&sem->wait_list))) + sem->count++; + else __up(sem); spin_unlock_irqrestore(&sem->lock, flags); } @@ -190,6 +192,7 @@ EXPORT_SYMBOL(up); struct semaphore_waiter { struct list_head list; struct task_struct *task; + int up; }; /* @@ -202,34 +205,33 @@ static inline int __sched __down_common(struct semaphore *sem, long state, { struct task_struct *task = current; struct semaphore_waiter waiter; - int ret = 0; - waiter.task = task; list_add_tail(&waiter.list, &sem->wait_list); + waiter.task = task; + waiter.up = 0; for (;;) { - if (state == TASK_INTERRUPTIBLE && signal_pending(task)) { - ret = -EINTR; - break; - } - if (state == TASK_KILLABLE && fatal_signal_pending(task)) { - ret = -EINTR; - break; - } - if (timeout <= 0) { - ret = -ETIME; - break; - } + if (state == TASK_INTERRUPTIBLE && signal_pending(task)) + goto interrupted; + if (state == TASK_KILLABLE && fatal_signal_pending(task)) + goto interrupted; + if (timeout <= 0) + goto timed_out; __set_task_state(task, state); spin_unlock_irq(&sem->lock); timeout = schedule_timeout(timeout); spin_lock_irq(&sem->lock); - if (sem->count > 0) - break; + if (waiter.up) + return 0; } + timed_out: + list_del(&waiter.list); + return -ETIME; + + interrupted: list_del(&waiter.list); - return ret; + return -EINTR; } static noinline void __sched __down(struct semaphore *sem) @@ -256,5 +258,7 @@ static noinline void __sched __up(struct semaphore *sem) { struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, struct semaphore_waiter, list); + list_del(&waiter->list); + waiter->up = 1; wake_up_process(waiter->task); } 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 6a08660b4fac..86729042e4cd 100644 --- a/trunk/kernel/time.c +++ b/trunk/kernel/time.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -246,7 +245,7 @@ unsigned int inline jiffies_to_msecs(const unsigned long j) return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); #else # if BITS_PER_LONG == 32 - return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32; + return ((u64)HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32; # else return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN; # endif @@ -262,7 +261,7 @@ unsigned int inline jiffies_to_usecs(const unsigned long j) return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC); #else # if BITS_PER_LONG == 32 - return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; + return ((u64)HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; # else return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN; # endif @@ -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; } @@ -476,7 +471,7 @@ unsigned long msecs_to_jiffies(const unsigned int m) if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET)) return MAX_JIFFY_OFFSET; - return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32) + return ((u64)MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32) >> MSEC_TO_HZ_SHR32; #endif } @@ -491,7 +486,7 @@ unsigned long usecs_to_jiffies(const unsigned int u) #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) return u * (HZ / USEC_PER_SEC); #else - return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32) + return ((u64)USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32) >> USEC_TO_HZ_SHR32; #endif } @@ -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/clocksource.c b/trunk/kernel/time/clocksource.c index dadde5361f32..73961f35fdc8 100644 --- a/trunk/kernel/time/clocksource.c +++ b/trunk/kernel/time/clocksource.c @@ -471,10 +471,10 @@ sysfs_show_available_clocksources(struct sys_device *dev, char *buf) /* * Sysfs setup bits: */ -static SYSDEV_ATTR(current_clocksource, 0644, sysfs_show_current_clocksources, +static SYSDEV_ATTR(current_clocksource, 0600, sysfs_show_current_clocksources, sysfs_override_clocksource); -static SYSDEV_ATTR(available_clocksource, 0444, +static SYSDEV_ATTR(available_clocksource, 0600, sysfs_show_available_clocksources, NULL); static struct sysdev_class clocksource_sysclass = { 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/timeconst.pl b/trunk/kernel/timeconst.pl index eb51d76e058a..41468035473c 100644 --- a/trunk/kernel/timeconst.pl +++ b/trunk/kernel/timeconst.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # ----------------------------------------------------------------------- # -# Copyright 2007-2008 rPath, Inc. - All Rights Reserved +# Copyright 2007 rPath, Inc. - All Rights Reserved # # This file is part of the Linux kernel, and is made available under # the terms of the GNU General Public License version 2 or (at your @@ -20,138 +20,198 @@ %canned_values = ( 24 => [ '0xa6aaaaab','0x2aaaaaa',26, + '0xa6aaaaaaaaaaaaab','0x2aaaaaaaaaaaaaa',58, 125,3, '0xc49ba5e4','0x1fbe76c8b4',37, + '0xc49ba5e353f7ceda','0x1fbe76c8b439581062',69, 3,125, '0xa2c2aaab','0xaaaa',16, + '0xa2c2aaaaaaaaaaab','0xaaaaaaaaaaaa',48, 125000,3, '0xc9539b89','0x7fffbce4217d',47, + '0xc9539b8887229e91','0x7fffbce4217d2849cb25',79, 3,125000, ], 32 => [ '0xfa000000','0x6000000',27, + '0xfa00000000000000','0x600000000000000',59, 125,4, '0x83126e98','0xfdf3b645a',36, + '0x83126e978d4fdf3c','0xfdf3b645a1cac0831',68, 4,125, '0xf4240000','0x0',17, + '0xf424000000000000','0x0',49, 31250,1, '0x8637bd06','0x3fff79c842fa',46, + '0x8637bd05af6c69b6','0x3fff79c842fa5093964a',78, 1,31250, ], 48 => [ '0xa6aaaaab','0x6aaaaaa',27, + '0xa6aaaaaaaaaaaaab','0x6aaaaaaaaaaaaaa',59, 125,6, '0xc49ba5e4','0xfdf3b645a',36, + '0xc49ba5e353f7ceda','0xfdf3b645a1cac0831',68, 6,125, '0xa2c2aaab','0x15555',17, + '0xa2c2aaaaaaaaaaab','0x1555555555555',49, 62500,3, '0xc9539b89','0x3fffbce4217d',46, + '0xc9539b8887229e91','0x3fffbce4217d2849cb25',78, 3,62500, ], 64 => [ '0xfa000000','0xe000000',28, + '0xfa00000000000000','0xe00000000000000',60, 125,8, '0x83126e98','0x7ef9db22d',35, + '0x83126e978d4fdf3c','0x7ef9db22d0e560418',67, 8,125, '0xf4240000','0x0',18, + '0xf424000000000000','0x0',50, 15625,1, '0x8637bd06','0x1fff79c842fa',45, + '0x8637bd05af6c69b6','0x1fff79c842fa5093964a',77, 1,15625, ], 100 => [ '0xa0000000','0x0',28, + '0xa000000000000000','0x0',60, 10,1, '0xcccccccd','0x733333333',35, + '0xcccccccccccccccd','0x73333333333333333',67, 1,10, '0x9c400000','0x0',18, + '0x9c40000000000000','0x0',50, 10000,1, '0xd1b71759','0x1fff2e48e8a7',45, + '0xd1b71758e219652c','0x1fff2e48e8a71de69ad4',77, 1,10000, ], 122 => [ '0x8325c53f','0xfbcda3a',28, + '0x8325c53ef368eb05','0xfbcda3ac10c9714',60, 500,61, '0xf9db22d1','0x7fbe76c8b',35, + '0xf9db22d0e560418a','0x7fbe76c8b43958106',67, 61,500, '0x8012e2a0','0x3ef36',18, + '0x8012e29f79b47583','0x3ef368eb04325',50, 500000,61, '0xffda4053','0x1ffffbce4217',45, + '0xffda4052d666a983','0x1ffffbce4217d2849cb2',77, 61,500000, ], 128 => [ '0xfa000000','0x1e000000',29, + '0xfa00000000000000','0x1e00000000000000',61, 125,16, '0x83126e98','0x3f7ced916',34, + '0x83126e978d4fdf3c','0x3f7ced916872b020c',66, 16,125, '0xf4240000','0x40000',19, + '0xf424000000000000','0x4000000000000',51, 15625,2, '0x8637bd06','0xfffbce4217d',44, + '0x8637bd05af6c69b6','0xfffbce4217d2849cb25',76, 2,15625, ], 200 => [ '0xa0000000','0x0',29, + '0xa000000000000000','0x0',61, 5,1, '0xcccccccd','0x333333333',34, + '0xcccccccccccccccd','0x33333333333333333',66, 1,5, '0x9c400000','0x0',19, + '0x9c40000000000000','0x0',51, 5000,1, '0xd1b71759','0xfff2e48e8a7',44, + '0xd1b71758e219652c','0xfff2e48e8a71de69ad4',76, 1,5000, ], 250 => [ '0x80000000','0x0',29, + '0x8000000000000000','0x0',61, 4,1, '0x80000000','0x180000000',33, + '0x8000000000000000','0x18000000000000000',65, 1,4, '0xfa000000','0x0',20, + '0xfa00000000000000','0x0',52, 4000,1, '0x83126e98','0x7ff7ced9168',43, + '0x83126e978d4fdf3c','0x7ff7ced916872b020c4',75, 1,4000, ], 256 => [ '0xfa000000','0x3e000000',30, + '0xfa00000000000000','0x3e00000000000000',62, 125,32, '0x83126e98','0x1fbe76c8b',33, + '0x83126e978d4fdf3c','0x1fbe76c8b43958106',65, 32,125, '0xf4240000','0xc0000',20, + '0xf424000000000000','0xc000000000000',52, 15625,4, '0x8637bd06','0x7ffde7210be',43, + '0x8637bd05af6c69b6','0x7ffde7210be9424e592',75, 4,15625, ], 300 => [ '0xd5555556','0x2aaaaaaa',30, + '0xd555555555555556','0x2aaaaaaaaaaaaaaa',62, 10,3, '0x9999999a','0x1cccccccc',33, + '0x999999999999999a','0x1cccccccccccccccc',65, 3,10, '0xd0555556','0xaaaaa',20, + '0xd055555555555556','0xaaaaaaaaaaaaa',52, 10000,3, '0x9d495183','0x7ffcb923a29',43, + '0x9d495182a9930be1','0x7ffcb923a29c779a6b5',75, 3,10000, ], 512 => [ '0xfa000000','0x7e000000',31, + '0xfa00000000000000','0x7e00000000000000',63, 125,64, '0x83126e98','0xfdf3b645',32, + '0x83126e978d4fdf3c','0xfdf3b645a1cac083',64, 64,125, '0xf4240000','0x1c0000',21, + '0xf424000000000000','0x1c000000000000',53, 15625,8, '0x8637bd06','0x3ffef39085f',42, + '0x8637bd05af6c69b6','0x3ffef39085f4a1272c9',74, 8,15625, ], 1000 => [ '0x80000000','0x0',31, + '0x8000000000000000','0x0',63, 1,1, '0x80000000','0x0',31, + '0x8000000000000000','0x0',63, 1,1, '0xfa000000','0x0',22, + '0xfa00000000000000','0x0',54, 1000,1, '0x83126e98','0x1ff7ced9168',41, + '0x83126e978d4fdf3c','0x1ff7ced916872b020c4',73, 1,1000, ], 1024 => [ '0xfa000000','0xfe000000',32, + '0xfa00000000000000','0xfe00000000000000',64, 125,128, '0x83126e98','0x7ef9db22',31, + '0x83126e978d4fdf3c','0x7ef9db22d0e56041',63, 128,125, '0xf4240000','0x3c0000',22, + '0xf424000000000000','0x3c000000000000',54, 15625,16, '0x8637bd06','0x1fff79c842f',41, + '0x8637bd05af6c69b6','0x1fff79c842fa5093964',73, 16,15625, ], 1200 => [ '0xd5555556','0xd5555555',32, + '0xd555555555555556','0xd555555555555555',64, 5,6, '0x9999999a','0x66666666',31, + '0x999999999999999a','0x6666666666666666',63, 6,5, '0xd0555556','0x2aaaaa',22, + '0xd055555555555556','0x2aaaaaaaaaaaaa',54, 2500,3, '0x9d495183','0x1ffcb923a29',41, + '0x9d495182a9930be1','0x1ffcb923a29c779a6b5',73, 3,2500, ] ); @@ -204,15 +264,6 @@ ($$$) return 0; } -# Generate a hex value if the result fits in 64 bits; -# otherwise skip. -sub bignum_hex($) { - my($x) = @_; - my $s = $x->as_hex(); - - return (length($s) > 18) ? undef : $s; -} - # Provides mul, adj, and shr factors for a specific # (bit, time, hz) combination sub muladj($$$) { @@ -220,7 +271,7 @@ ($$$) my $s = fmuls($b, $t, $hz); my $m = fmul($s, $t, $hz); my $a = fadj($s, $t, $hz); - return (bignum_hex($m), bignum_hex($a), $s); + return ($m->as_hex(), $a->as_hex(), $s); } # Provides numerator, denominator values @@ -237,10 +288,12 @@ ($$) # HZ_TO_xx push(@val, muladj(32, $t, $hz)); + push(@val, muladj(64, $t, $hz)); push(@val, numden($t, $hz)); # xx_TO_HZ push(@val, muladj(32, $hz, $t)); + push(@val, muladj(64, $hz, $t)); push(@val, numden($hz, $t)); return @val; @@ -265,19 +318,6 @@ ($) return @val; } -sub outputval($$) -{ - my($name, $val) = @_; - my $csuf; - - if (defined($val)) { - if ($name !~ /SHR/) { - $val = "U64_C($val)"; - } - printf "#define %-23s %s\n", $name.$csuf, $val.$csuf; - } -} - sub output($@) { my($hz, @val) = @_; @@ -291,7 +331,6 @@ ($@) print "\n"; print "#include \n"; - print "#include \n"; print "\n"; print "#if HZ != $hz\n"; @@ -301,13 +340,15 @@ ($@) foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ', 'HZ_TO_USEC','USEC_TO_HZ') { - foreach $bit (32) { + foreach $bit (32, 64) { foreach $suf ('MUL', 'ADJ', 'SHR') { - outputval("${pfx}_$suf$bit", shift(@val)); + printf "#define %-23s %s\n", + "${pfx}_$suf$bit", shift(@val); } } foreach $suf ('NUM', 'DEN') { - outputval("${pfx}_$suf", shift(@val)); + printf "#define %-23s %s\n", + "${pfx}_$suf", shift(@val); } } @@ -315,23 +356,6 @@ ($@) print "#endif /* KERNEL_TIMECONST_H */\n"; } -# Pretty-print Perl values -sub perlvals(@) { - my $v; - my @l = (); - - foreach $v (@_) { - if (!defined($v)) { - push(@l, 'undef'); - } elsif ($v =~ /^0x/) { - push(@l, "\'".$v."\'"); - } else { - push(@l, $v.''); - } - } - return join(',', @l); -} - ($hz) = @ARGV; # Use this to generate the %canned_values structure @@ -349,15 +373,15 @@ (@) print "$pf$hz => [\n"; while (scalar(@values)) { my $bit; - foreach $bit (32) { + foreach $bit (32, 64) { my $m = shift(@values); my $a = shift(@values); my $s = shift(@values); - print "\t\t", perlvals($m,$a,$s), ",\n"; + print "\t\t\'",$m,"\',\'",$a,"\',",$s,",\n"; } my $n = shift(@values); my $d = shift(@values); - print "\t\t", perlvals($n,$d), ",\n"; + print "\t\t",$n,',',$d,",\n"; } print "\t]"; $pf = ', '; 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/Kconfig.kgdb b/trunk/lib/Kconfig.kgdb index a5d4b1dac2a5..f2e01ac5ab09 100644 --- a/trunk/lib/Kconfig.kgdb +++ b/trunk/lib/Kconfig.kgdb @@ -1,10 +1,4 @@ -config HAVE_ARCH_KGDB_SHADOW_INFO - bool - -config HAVE_ARCH_KGDB - bool - menuconfig KGDB bool "KGDB: kernel debugging with remote gdb" select FRAME_POINTER @@ -16,10 +10,15 @@ menuconfig KGDB at http://kgdb.sourceforge.net as well as in DocBook form in Documentation/DocBook/. If unsure, say N. -if KGDB +config HAVE_ARCH_KGDB_SHADOW_INFO + bool + +config HAVE_ARCH_KGDB + bool config KGDB_SERIAL_CONSOLE tristate "KGDB: use kgdb over the serial console" + depends on KGDB select CONSOLE_POLL select MAGIC_SYSRQ default y @@ -29,6 +28,7 @@ config KGDB_SERIAL_CONSOLE config KGDB_TESTS bool "KGDB: internal test suite" + depends on KGDB default n help This is a kgdb I/O module specifically designed to test @@ -56,5 +56,3 @@ config KGDB_TESTS_BOOT_STRING boot. See the drivers/misc/kgdbts.c for detailed information about other strings you could use beyond the default of V1F100. - -endif # KGDB diff --git a/trunk/lib/devres.c b/trunk/lib/devres.c index 72c8909006da..26c87c49d776 100644 --- a/trunk/lib/devres.c +++ b/trunk/lib/devres.c @@ -2,7 +2,7 @@ #include #include -void devm_ioremap_release(struct device *dev, void *res) +static void devm_ioremap_release(struct device *dev, void *res) { iounmap(*(void __iomem **)res); } 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/filemap.c b/trunk/mm/filemap.c index 2dead9adf8b7..239d36163bbe 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -1655,7 +1655,7 @@ int should_remove_suid(struct dentry *dentry) } EXPORT_SYMBOL(should_remove_suid); -static int __remove_suid(struct dentry *dentry, int kill) +int __remove_suid(struct dentry *dentry, int kill) { struct iattr newattrs; 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/memory.c b/trunk/mm/memory.c index 48c122d42ed7..bbab1e37055e 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -969,7 +969,7 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, goto no_page_table; pmd = pmd_offset(pud, address); - if (pmd_none(*pmd)) + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) goto no_page_table; if (pmd_huge(*pmd)) { @@ -978,9 +978,6 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, goto out; } - if (unlikely(pmd_bad(*pmd))) - goto no_page_table; - ptep = pte_offset_map_lock(mm, pmd, address, &ptl); if (!ptep) goto out; diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index a505a828ef41..70db2897c1ea 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -22,7 +22,6 @@ #include #include #include -#include /* * Lock order: @@ -217,7 +216,7 @@ struct track { enum track_item { TRACK_ALLOC, TRACK_FREE }; -#ifdef CONFIG_SLUB_DEBUG +#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) static int sysfs_slab_add(struct kmem_cache *); static int sysfs_slab_alias(struct kmem_cache *, const char *); static void sysfs_slab_remove(struct kmem_cache *); @@ -814,8 +813,7 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search) return search == NULL; } -static void trace(struct kmem_cache *s, struct page *page, void *object, - int alloc) +static void trace(struct kmem_cache *s, struct page *page, void *object, int alloc) { if (s->flags & SLAB_TRACE) { printk(KERN_INFO "TRACE %s %s 0x%p inuse=%d fp=0x%p\n", @@ -1268,7 +1266,8 @@ static void add_partial(struct kmem_cache_node *n, spin_unlock(&n->list_lock); } -static void remove_partial(struct kmem_cache *s, struct page *page) +static void remove_partial(struct kmem_cache *s, + struct page *page) { struct kmem_cache_node *n = get_node(s, page_to_nid(page)); @@ -1283,8 +1282,7 @@ static void remove_partial(struct kmem_cache *s, struct page *page) * * Must hold list_lock. */ -static inline int lock_and_freeze_slab(struct kmem_cache_node *n, - struct page *page) +static inline int lock_and_freeze_slab(struct kmem_cache_node *n, struct page *page) { if (slab_trylock(page)) { list_del(&page->lru); @@ -1421,8 +1419,8 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) * so that the others get filled first. That way the * size of the partial list stays small. * - * kmem_cache_shrink can reclaim any empty slabs from - * the partial list. + * kmem_cache_shrink can reclaim any empty slabs from the + * partial list. */ add_partial(n, page, 1); slab_unlock(page); @@ -2910,7 +2908,7 @@ static int slab_mem_going_online_callback(void *arg) return 0; /* - * We are bringing a node online. No memory is available yet. We must + * We are bringing a node online. No memory is availabe yet. We must * allocate a kmem_cache_node structure in order to bring the node * online. */ @@ -3247,7 +3245,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, return slab_alloc(s, gfpflags, node, caller); } -#ifdef CONFIG_SLUB_DEBUG +#if (defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG)) || defined(CONFIG_SLABINFO) static unsigned long count_partial(struct kmem_cache_node *n, int (*get_count)(struct page *)) { @@ -3276,7 +3274,9 @@ static int count_free(struct page *page) { return page->objects - page->inuse; } +#endif +#if defined(CONFIG_SYSFS) && defined(CONFIG_SLUB_DEBUG) static int validate_slab(struct kmem_cache *s, struct page *page, unsigned long *map) { @@ -3621,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); @@ -3762,7 +3764,7 @@ static int any_slab_objects(struct kmem_cache *s) if (!n) continue; - if (atomic_long_read(&n->total_objects)) + if (atomic_read(&n->total_objects)) return 1; } return 0; @@ -3811,12 +3813,7 @@ SLAB_ATTR_RO(objs_per_slab); static ssize_t order_store(struct kmem_cache *s, const char *buf, size_t length) { - unsigned long order; - int err; - - err = strict_strtoul(buf, 10, &order); - if (err) - return err; + int order = simple_strtoul(buf, NULL, 10); if (order > slub_max_order || order < slub_min_order) return -EINVAL; @@ -4069,16 +4066,10 @@ static ssize_t remote_node_defrag_ratio_show(struct kmem_cache *s, char *buf) static ssize_t remote_node_defrag_ratio_store(struct kmem_cache *s, const char *buf, size_t length) { - unsigned long ratio; - int err; - - err = strict_strtoul(buf, 10, &ratio); - if (err) - return err; - - if (ratio < 100) - s->remote_node_defrag_ratio = ratio * 10; + int n = simple_strtoul(buf, NULL, 10); + if (n < 100) + s->remote_node_defrag_ratio = n * 10; return length; } SLAB_ATTR(remote_node_defrag_ratio); @@ -4435,8 +4426,8 @@ __initcall(slab_sysfs_init); */ #ifdef CONFIG_SLABINFO -ssize_t slabinfo_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) +ssize_t slabinfo_write(struct file *file, const char __user * buffer, + size_t count, loff_t *ppos) { return -EINVAL; } 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/can/bcm.c b/trunk/net/can/bcm.c index d9a3a9d13bed..74fd2d33aff4 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -412,6 +412,12 @@ static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data) bcm_send_to_user(op, &head, data, 1); } +/* TODO: move to linux/hrtimer.h */ +static inline int hrtimer_callback_running(struct hrtimer *timer) +{ + return timer->state & HRTIMER_STATE_CALLBACK; +} + /* * bcm_rx_update_and_send - process a detected relevant receive content change * 1. update the last received data 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/mac80211/rc80211_pid_debugfs.c b/trunk/net/mac80211/rc80211_pid_debugfs.c index ff5c380f3c13..ae75d4178739 100644 --- a/trunk/net/mac80211/rc80211_pid_debugfs.c +++ b/trunk/net/mac80211/rc80211_pid_debugfs.c @@ -85,7 +85,7 @@ static int rate_control_pid_events_open(struct inode *inode, struct file *file) struct rc_pid_sta_info *sinfo = inode->i_private; struct rc_pid_event_buffer *events = &sinfo->events; struct rc_pid_events_file_info *file_info; - unsigned long status; + unsigned int status; /* Allocate a state struct */ file_info = kmalloc(sizeof(*file_info), GFP_KERNEL); @@ -135,7 +135,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, char pb[RC_PID_PRINT_BUF_SIZE]; int ret; int p; - unsigned long status; + unsigned int status; /* Check if there is something to read. */ if (events->next_entry == file_info->next_entry) { 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/net/sunrpc/svc.c b/trunk/net/sunrpc/svc.c index 01c7e311b904..d74c2d269539 100644 --- a/trunk/net/sunrpc/svc.c +++ b/trunk/net/sunrpc/svc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/trunk/net/tipc/core.h b/trunk/net/tipc/core.h index 325404fd4eb5..5a0e4878d3b7 100644 --- a/trunk/net/tipc/core.h +++ b/trunk/net/tipc/core.h @@ -279,15 +279,14 @@ static inline void k_term_timer(struct timer_list *timer) /* * TIPC message buffer code * - * TIPC message buffer headroom reserves space for a link-level header - * (in case the message is sent off-node), - * while ensuring TIPC header is word aligned for quicker access + * TIPC message buffer headroom reserves space for the worst-case + * link-level device header (in case the message is sent off-node). * - * The largest header currently supported is 18 bytes, which is used when - * the standard 14 byte Ethernet header has 4 added bytes for VLAN info + * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields + * are word aligned for quicker access */ -#define BUF_HEADROOM 20u +#define BUF_HEADROOM LL_MAX_HEADER struct tipc_skb_cb { void *handle; diff --git a/trunk/scripts/kconfig/lkc.h b/trunk/scripts/kconfig/lkc.h index 96521cb087ec..4bc68f20a73c 100644 --- a/trunk/scripts/kconfig/lkc.h +++ b/trunk/scripts/kconfig/lkc.h @@ -11,9 +11,9 @@ #ifndef KBUILD_NO_NLS # include #else -static inline const char *gettext(const char *txt) { return txt; } -static inline void textdomain(const char *domainname) {} -static inline void bindtextdomain(const char *name, const char *dir) {} +# define gettext(Msgid) ((const char *) (Msgid)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) #endif #ifdef __cplusplus 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 diff --git a/trunk/scripts/kconfig/mconf.c b/trunk/scripts/kconfig/mconf.c index 6841e95c0989..734cf4f3131e 100644 --- a/trunk/scripts/kconfig/mconf.c +++ b/trunk/scripts/kconfig/mconf.c @@ -773,7 +773,7 @@ static void conf_string(struct menu *menu) while (1) { int res; - const char *heading; + char *heading; switch (sym_get_type(menu->sym)) { case S_INT: @@ -925,4 +925,3 @@ int main(int ac, char **av) return 0; } - diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index cea4a790e1e9..e04c4218cb52 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -51,15 +51,6 @@ do { \ sprintf(str + strlen(str), "*"); \ } while(0) -/* Always end in a wildcard, for future extension */ -static inline void add_wildcard(char *str) -{ - int len = strlen(str); - - if (str[len - 1] != '*') - strcat(str + len, "*"); -} - unsigned int cross_build = 0; /** * Check that sizeof(device_id type) are consistent with size of section @@ -142,7 +133,9 @@ static void do_usb_entry(struct usb_device_id *id, id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL, id->bInterfaceProtocol); - add_wildcard(alias); + /* Always end in a wildcard, for future extension */ + if (alias[strlen(alias)-1] != '*') + strcat(alias, "*"); buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); } @@ -226,7 +219,6 @@ static int do_ieee1394_entry(const char *filename, ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION, id->version); - add_wildcard(alias); return 1; } @@ -269,7 +261,6 @@ static int do_pci_entry(const char *filename, ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); ADD(alias, "sc", subclass_mask == 0xFF, subclass); ADD(alias, "i", interface_mask == 0xFF, interface); - add_wildcard(alias); return 1; } @@ -292,7 +283,6 @@ static int do_ccw_entry(const char *filename, id->dev_type); ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, id->dev_model); - add_wildcard(alias); return 1; } @@ -300,7 +290,7 @@ static int do_ccw_entry(const char *filename, static int do_ap_entry(const char *filename, struct ap_device_id *id, char *alias) { - sprintf(alias, "ap:t%02X*", id->dev_type); + sprintf(alias, "ap:t%02X", id->dev_type); return 1; } @@ -319,7 +309,6 @@ static int do_serio_entry(const char *filename, ADD(alias, "id", id->id != SERIO_ANY, id->id); ADD(alias, "ex", id->extra != SERIO_ANY, id->extra); - add_wildcard(alias); return 1; } @@ -327,7 +316,7 @@ static int do_serio_entry(const char *filename, static int do_acpi_entry(const char *filename, struct acpi_device_id *id, char *alias) { - sprintf(alias, "acpi*:%s:*", id->id); + sprintf(alias, "acpi*:%s:", id->id); return 1; } @@ -335,7 +324,7 @@ static int do_acpi_entry(const char *filename, static int do_pnp_entry(const char *filename, struct pnp_device_id *id, char *alias) { - sprintf(alias, "pnp:d%s*", id->id); + sprintf(alias, "pnp:d%s", id->id); return 1; } @@ -420,7 +409,6 @@ static int do_pcmcia_entry(const char *filename, ADD(alias, "pc", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, id->prod_id_hash[2]); ADD(alias, "pd", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, id->prod_id_hash[3]); - add_wildcard(alias); return 1; } @@ -444,7 +432,6 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali if (isspace (*tmp)) *tmp = '_'; - add_wildcard(alias); return 1; } @@ -461,7 +448,6 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio, if (isspace (*tmp)) *tmp = '_'; - add_wildcard(alias); return 1; } @@ -525,8 +511,6 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, { if (eisa->sig[0]) sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", eisa->sig); - else - strcat(alias, "*"); return 1; } @@ -545,7 +529,6 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id, ADD(alias, "rev", id->hversion_rev != PA_HVERSION_REV_ANY_ID, id->hversion_rev); ADD(alias, "sv", id->sversion != PA_SVERSION_ANY_ID, id->sversion); - add_wildcard(alias); return 1; } @@ -561,7 +544,6 @@ static int do_sdio_entry(const char *filename, ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class); ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor); ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device); - add_wildcard(alias); return 1; } @@ -577,7 +559,6 @@ static int do_ssb_entry(const char *filename, ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor); ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid); ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision); - add_wildcard(alias); return 1; } @@ -592,7 +573,6 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id, ADD(alias, "d", 1, id->device); ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor); - add_wildcard(alias); return 1; } @@ -632,6 +612,9 @@ static void do_table(void *symval, unsigned long size, for (i = 0; i < size; i += id_size) { if (do_entry(mod->name, symval+i, alias)) { + /* Always end in a wildcard, for future extension */ + if (alias[strlen(alias)-1] != '*') + strcat(alias, "*"); buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); } diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 1c864c0efe2b..1b50a6ebc55f 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/drivers/Kconfig b/trunk/sound/drivers/Kconfig index 379bcb074463..a78a8d045175 100644 --- a/trunk/sound/drivers/Kconfig +++ b/trunk/sound/drivers/Kconfig @@ -5,8 +5,8 @@ menu "Generic devices" config SND_PCSP - tristate "PC-Speaker support" - depends on PCSPKR_PLATFORM && X86_PC && HIGH_RES_TIMERS + tristate "Internal PC speaker support" + depends on X86_PC && HIGH_RES_TIMERS depends on INPUT depends on SND select SND_PCM diff --git a/trunk/sound/drivers/pcsp/pcsp.c b/trunk/sound/drivers/pcsp/pcsp.c index 54a1f9036c66..59203511e77d 100644 --- a/trunk/sound/drivers/pcsp/pcsp.c +++ b/trunk/sound/drivers/pcsp/pcsp.c @@ -194,7 +194,6 @@ static void pcsp_stop_beep(struct snd_pcsp *chip) spin_unlock_irq(&chip->substream_lock); } -#ifdef CONFIG_PM static int pcsp_suspend(struct platform_device *dev, pm_message_t state) { struct snd_pcsp *chip = platform_get_drvdata(dev); @@ -202,9 +201,6 @@ static int pcsp_suspend(struct platform_device *dev, pm_message_t state) snd_pcm_suspend_all(chip->pcm); return 0; } -#else -#define pcsp_suspend NULL -#endif /* CONFIG_PM */ static void pcsp_shutdown(struct platform_device *dev) { diff --git a/trunk/sound/oss/kahlua.c b/trunk/sound/oss/kahlua.c index eb9bc365530d..dfe670f12e67 100644 --- a/trunk/sound/oss/kahlua.c +++ b/trunk/sound/oss/kahlua.c @@ -67,7 +67,7 @@ static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id return 1; mem = ioremap(base, 128); - if (!mem) + if(mem == 0UL) return 1; map = readw(mem + 0x18); /* Read the SMI enables */ iounmap(mem); diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 7e4742109572..581debf37dcb 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -515,16 +515,19 @@ config SND_FM801 config SND_FM801_TEA575X_BOOL bool "ForteMedia FM801 + TEA5757 tuner" depends on SND_FM801 - depends on VIDEO_V4L1=y || VIDEO_V4L1=SND_FM801 help Say Y here to include support for soundcards based on the ForteMedia FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media Forte SF256-PCS-02) into the snd-fm801 driver. + This will enable support for the old V4L1 API. + config SND_FM801_TEA575X tristate depends on SND_FM801_TEA575X_BOOL default SND_FM801 + select VIDEO_V4L1 + select VIDEO_DEV config SND_HDA_INTEL tristate "Intel HD Audio" diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index 2da89810ca10..39198e505b12 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -3446,7 +3446,6 @@ static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { int patch_vt1617a(struct snd_ac97 * ac97) { int err = 0; - int val; /* we choose to not fail out at this point, but we tell the caller when we return */ @@ -3457,13 +3456,7 @@ int patch_vt1617a(struct snd_ac97 * ac97) /* bring analog power consumption to normal by turning off the * headphone amplifier, like WinXP driver for EPIA SP */ - /* We need to check the bit before writing it. - * On some (many?) hardwares, setting bit actually clears it! - */ - val = snd_ac97_read(ac97, 0x5c); - if (!(val & 0x20)) - snd_ac97_write_cache(ac97, 0x5c, 0x20); - + snd_ac97_write_cache(ac97, 0x5c, 0x20); ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; ac97->build_ops = &patch_vt1616_ops; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 6d4df45e81e0..d9783a4263e0 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -11902,10 +11902,7 @@ static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type, int dac_idx) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - pin_type); - snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, - AMP_OUT_UNMUTE); + alc_set_pin_output(codec, nid, pin_type); } static void alc861_auto_init_multi_out(struct hda_codec *codec) diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 393f7fd2b1be..b3a15d616873 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -4289,8 +4289,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x }, { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x }, { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x }, - { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x }, - { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x }, /* The following does not take into account .id=0x83847661 when subsys = * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are * currently not fully supported. diff --git a/trunk/sound/soc/at91/at91-pcm.c b/trunk/sound/soc/at91/at91-pcm.c index ccac6bd2889c..67c88e322fb1 100644 --- a/trunk/sound/soc/at91/at91-pcm.c +++ b/trunk/sound/soc/at91/at91-pcm.c @@ -103,8 +103,7 @@ static void at91_pcm_dma_irq(u32 ssc_sr, if (prtd->period_ptr >= prtd->dma_buffer_end) { prtd->period_ptr = prtd->dma_buffer; } - at91_ssc_write(params->ssc_base + params->pdc->xnpr, - prtd->period_ptr); + at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr); at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->period_size / params->pdc_xfer_size); } @@ -192,12 +191,10 @@ static int at91_pcm_trigger(struct snd_pcm_substream *substream, at91_ssc_write(params->ssc_base + AT91_SSC_IER, params->mask->ssc_endx | params->mask->ssc_endbuf); - at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, - params->mask->pdc_enable); + at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable); - DBG("sr=%lx imr=%lx\n", - at91_ssc_read(params->ssc_base + AT91_SSC_SR), - at91_ssc_read(params->ssc_base + AT91_SSC_IMR)); + DBG("sr=%lx imr=%lx\n", at91_ssc_read(params->ssc_base + AT91_SSC_SR), + at91_ssc_read(params->ssc_base + AT91_SSC_IER)); break; case SNDRV_PCM_TRIGGER_STOP: diff --git a/trunk/sound/soc/at91/at91-ssc.c b/trunk/sound/soc/at91/at91-ssc.c index bc35d00a38f8..f642d2dd4ec3 100644 --- a/trunk/sound/soc/at91/at91-ssc.c +++ b/trunk/sound/soc/at91/at91-ssc.c @@ -590,7 +590,7 @@ static int at91_ssc_hw_params(struct snd_pcm_substream *substream, printk(KERN_WARNING "at91-ssc: request_irq failure\n"); DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); - at91_sys_write(AT91_PMC_PCDR, 1<ssc.pid); + at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); return ret; } diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c index 1ed6afd45459..4ebcd6a8bf28 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -224,7 +224,6 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, iismod |= S3C2410_IISMOD_SLAVE; break; case SND_SOC_DAIFMT_CBS_CFS: - iismod &= ~S3C2410_IISMOD_SLAVE; break; default: return -EINVAL; @@ -235,7 +234,6 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, iismod |= S3C2410_IISMOD_MSB; break; case SND_SOC_DAIFMT_I2S: - iismod &= ~S3C2410_IISMOD_MSB; break; default: return -EINVAL; diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c index 7806ae614617..6c70a81c730c 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -171,7 +171,7 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, ret = s3c2410_dma_request(prtd->params->channel, prtd->params->client, NULL); - if (ret < 0) { + if (ret) { DBG(KERN_ERR "failed to get dma channel\n"); return ret; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index f7ba099049ea..c82cf15730a1 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -522,7 +522,6 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) return bad_hva(); return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE); } -EXPORT_SYMBOL_GPL(gfn_to_hva); /* * Requires current->mm->mmap_sem to be held @@ -835,9 +834,16 @@ static const struct file_operations kvm_vcpu_fops = { */ static int create_vcpu_fd(struct kvm_vcpu *vcpu) { - int fd = anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu); - if (fd < 0) + int fd, r; + struct inode *inode; + struct file *file; + + r = anon_inode_getfd(&fd, &inode, &file, + "kvm-vcpu", &kvm_vcpu_fops, vcpu); + if (r) { kvm_put_kvm(vcpu->kvm); + return r; + } return fd; } @@ -1162,15 +1168,19 @@ static const struct file_operations kvm_vm_fops = { static int kvm_dev_ioctl_create_vm(void) { - int fd; + int fd, r; + struct inode *inode; + struct file *file; struct kvm *kvm; kvm = kvm_create_vm(); if (IS_ERR(kvm)) return PTR_ERR(kvm); - fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm); - if (fd < 0) + r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm); + if (r) { kvm_put_kvm(kvm); + return r; + } return fd; }