diff options
68 files changed, 739 insertions, 956 deletions
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 398d0c0511e..8b63ad89d0a 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -1,3 +1,4 @@ +#include <linux/module.h> #include <linux/sched.h> #include <linux/stacktrace.h> @@ -30,6 +31,7 @@ int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, return 0; } +EXPORT_SYMBOL(walk_stackframe); #ifdef CONFIG_STACKTRACE struct stack_trace_data { diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index aa58720f687..860e912a3fb 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c @@ -31,6 +31,7 @@ #include <linux/module.h> #include <linux/kexec.h> #include <linux/pfn.h> +#include <linux/swap.h> #include <asm/e820.h> #include <asm/setup.h> @@ -97,14 +98,8 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn, #endif extern unsigned long find_max_low_pfn(void); -extern void find_max_pfn(void); extern void add_one_highpage_init(struct page *, int, int); - -extern struct e820map e820; extern unsigned long highend_pfn, highstart_pfn; -extern unsigned long max_low_pfn; -extern unsigned long totalram_pages; -extern unsigned long totalhigh_pages; #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE) @@ -360,7 +355,9 @@ void __init zone_sizes_init(void) max_zone_pfns[ZONE_DMA] = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; max_zone_pfns[ZONE_NORMAL] = max_low_pfn; +#ifdef CONFIG_HIGHMEM max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; +#endif /* If SRAT has not registered memory, register it now */ if (find_max_pfn_with_active_regions() == 0) { diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig index e14b533558c..ff654204b7d 100644 --- a/arch/sh64/Kconfig +++ b/arch/sh64/Kconfig @@ -17,6 +17,9 @@ config MMU bool default y +config QUICKLIST + def_bool y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/arch/sh64/configs/cayman_defconfig b/arch/sh64/configs/cayman_defconfig index d81df574a7f..ed035084b05 100644 --- a/arch/sh64/configs/cayman_defconfig +++ b/arch/sh64/configs/cayman_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 13:30:51 2006 +# Linux kernel version: 2.6.22-rc1 +# Mon May 14 08:43:31 2007 # CONFIG_SUPERH=y CONFIG_SUPERH64=y @@ -10,6 +10,8 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -33,13 +35,15 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -49,14 +53,19 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -135,7 +144,7 @@ CONFIG_SH64_ID2815_WORKAROUND=y # CONFIG_HEARTBEAT=y CONFIG_HDSP253_LED=y -CONFIG_SH_DMA=y +# CONFIG_SH_DMA is not set CONFIG_PREEMPT=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -146,23 +155,20 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support # # CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# # CONFIG_HOTPLUG_PCI is not set # @@ -180,13 +186,13 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set 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 @@ -207,11 +213,13 @@ CONFIG_IP_PNP=y # 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 @@ -256,7 +264,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # 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 # # Device Drivers @@ -269,16 +286,13 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# # CONFIG_MTD is not set # @@ -289,6 +303,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -306,11 +321,18 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # +# Misc devices +# +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_BLINK is not set + +# # ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set @@ -320,6 +342,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -339,6 +362,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -378,18 +402,16 @@ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_SYM53C8XX_MMIO=y -# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# +# CONFIG_SCSI_ESP_CORE is not set +# CONFIG_SCSI_SRP is not set # CONFIG_ATA is not set # @@ -408,6 +430,7 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y # # IEEE 1394 (FireWire) support # +# CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set # @@ -428,10 +451,6 @@ CONFIG_NETDEVICES=y # ARCnet devices # # CONFIG_ARCNET is not set - -# -# PHY device support -# # CONFIG_PHYLIB is not set # @@ -479,10 +498,8 @@ CONFIG_NET_PCI=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# +# CONFIG_SC92031 is not set +CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set @@ -498,14 +515,16 @@ CONFIG_NET_PCI=y # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_MLX4_CORE is not set +CONFIG_MLX4_DEBUG=y # # Token Ring devices @@ -513,13 +532,10 @@ CONFIG_NET_PCI=y # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set @@ -571,9 +587,17 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set # CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -619,10 +643,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # IPMI # # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -639,13 +659,8 @@ CONFIG_WATCHDOG=y # CONFIG_WDTPCI is not set CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -653,11 +668,7 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -669,44 +680,60 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # - -# -# Hardware Monitoring support -# +# CONFIG_W1 is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F 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_HWMON_DEBUG_CHIP is not set # -# Misc devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y # -# Digital Video Broadcasting Devices +# Graphics support # -# CONFIG_DVB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Graphics support +# Display device support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set 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=y # CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set @@ -720,13 +747,17 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set CONFIG_FB_KYRO=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set # CONFIG_FB_VIRTUAL is not set # @@ -746,10 +777,6 @@ CONFIG_FONT_8x16=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set - -# -# Logo configuration -# CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set @@ -757,7 +784,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_SUPERH_MONO is not set # CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_LOGO_SUPERH_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -765,6 +791,12 @@ CONFIG_LOGO_SUPERH_CLUT224=y # CONFIG_SOUND is not set # +# HID Devices +# +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set + +# # USB support # CONFIG_USB_ARCH_HAS_HCD=y @@ -780,10 +812,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # USB Gadget Support # # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set # @@ -836,6 +864,7 @@ 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 is not set CONFIG_FS_MBCACHE=y @@ -843,6 +872,7 @@ CONFIG_FS_MBCACHE=y # 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=y CONFIG_ROMFS_FS=y @@ -912,6 +942,7 @@ 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 @@ -941,6 +972,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SUN_PARTITION is not set # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set # # Native Language Support @@ -948,6 +980,11 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS is not set # +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# # Profiling support # # CONFIG_PROFILING is not set @@ -959,28 +996,29 @@ CONFIG_MSDOS_PARTITION=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set # CONFIG_EARLY_PRINTK is not set # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set CONFIG_SH64_PROC_TLB=y @@ -1004,10 +1042,15 @@ CONFIG_SH64_SR_WATCH=y # # 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_LIBCRC32C is not set CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y diff --git a/arch/sh64/kernel/entry.S b/arch/sh64/kernel/entry.S index 40d45346248..7013fcb6665 100644 --- a/arch/sh64/kernel/entry.S +++ b/arch/sh64/kernel/entry.S @@ -947,14 +947,14 @@ ret_with_reschedule: ! FIXME:!!! ! no handling of TIF_SYSCALL_TRACE yet!! - movi (1 << TIF_NEED_RESCHED), r8 + movi _TIF_NEED_RESCHED, r8 and r8, r7, r8 pta work_resched, tr0 bne r8, ZERO, tr0 pta restore_all, tr1 - movi (1 << TIF_SIGPENDING), r8 + movi (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r8 and r8, r7, r8 pta work_notifysig, tr0 bne r8, ZERO, tr0 diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c index f68b4f6c9b3..9412b716670 100644 --- a/arch/sh64/kernel/irq.c +++ b/arch/sh64/kernel/irq.c @@ -94,6 +94,7 @@ asmlinkage void do_NMI(unsigned long vector_num, struct pt_regs * regs) */ asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs) { + struct pt_regs *old_regs = set_irq_regs(regs); int irq; irq_enter(); @@ -101,13 +102,14 @@ asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs) irq = irq_demux(vector_num); if (irq >= 0) { - __do_IRQ(irq, regs); + __do_IRQ(irq); } else { printk("unexpected IRQ trap at vector %03lx\n", vector_num); } irq_exit(); + set_irq_regs(old_regs); return 1; } diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c index 49862e165c0..fb51660847c 100644 --- a/arch/sh64/kernel/pci_sh5.c +++ b/arch/sh64/kernel/pci_sh5.c @@ -340,8 +340,9 @@ static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin) return result; } -irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t pcish5_err_irq(int irq, void *dev_id) { + struct pt_regs *regs = get_irq_regs(); unsigned pci_int, pci_air, pci_cir, pci_aint; pci_int = SH5PCI_READ(INT); @@ -368,15 +369,13 @@ irqreturn_t pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -irqreturn_t pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t pcish5_serr_irq(int irq, void *dev_id) { printk("SERR IRQ\n"); return IRQ_NONE; } -#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) - static void __init pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, struct resource *memr) @@ -433,8 +432,8 @@ pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, mem_res.end -= mem_res.start; /* Align the sizes up by bridge rules */ - io_res.end = ROUND_UP(io_res.end, 4*1024) - 1; - mem_res.end = ROUND_UP(mem_res.end, 1*1024*1024) - 1; + io_res.end = ALIGN(io_res.end, 4*1024) - 1; + mem_res.end = ALIGN(mem_res.end, 1*1024*1024) - 1; /* Adjust the bridge's allocation requirements */ bridge->resource[0].end = bridge->resource[0].start + io_res.end; @@ -447,18 +446,16 @@ pcibios_size_bridge(struct pci_bus *bus, struct resource *ior, /* adjust parent's resource requirements */ if (ior) { - ior->end = ROUND_UP(ior->end, 4*1024); + ior->end = ALIGN(ior->end, 4*1024); ior->end += io_res.end; } if (memr) { - memr->end = ROUND_UP(memr->end, 1*1024*1024); + memr->end = ALIGN(memr->end, 1*1024*1024); memr->end += mem_res.end; } } -#undef ROUND_UP - static void __init pcibios_size_bridges(void) { struct resource io_res, mem_res; diff --git a/arch/sh64/kernel/pci_sh5.h b/arch/sh64/kernel/pci_sh5.h index 8f21f5d2aa3..c71159dd04b 100644 --- a/arch/sh64/kernel/pci_sh5.h +++ b/arch/sh64/kernel/pci_sh5.h @@ -4,7 +4,7 @@ * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * - * Defintions for the SH5 PCI hardware. + * Definitions for the SH5 PCI hardware. */ /* Product ID */ diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c index 525d0ec19b7..1b89c9dfb93 100644 --- a/arch/sh64/kernel/process.c +++ b/arch/sh64/kernel/process.c @@ -387,7 +387,7 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) * NOTE! Only a kernel-only process(ie the swapper or direct descendants * who haven't done an "execve()") should use this: it will work within * a system call from a "real" process, but the process memory space will - * not be free'd until both the parent and the child have exited. + * not be freed until both the parent and the child have exited. */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c index b76bdfa473d..c8525ade056 100644 --- a/arch/sh64/kernel/signal.c +++ b/arch/sh64/kernel/signal.c @@ -698,7 +698,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (try_to_freeze()) goto no_signal; - if (!oldset) + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + oldset = ¤t->saved_sigmask; + else if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, 0); @@ -706,6 +708,15 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) if (signr > 0) { /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, &ka, oldset, regs); + + /* + * If a signal was successfully delivered, the saved sigmask + * is in its frame, and we can clear the TIF_RESTORE_SIGMASK + * flag. + */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) + clear_thread_flag(TIF_RESTORE_SIGMASK); + return 1; } @@ -713,13 +724,27 @@ no_signal: /* Did we come from a system call? */ if (regs->syscall_nr >= 0) { /* Restart the system call - no handlers present */ - if (regs->regs[REG_RET] == -ERESTARTNOHAND || - regs->regs[REG_RET] == -ERESTARTSYS || - regs->regs[REG_RET] == -ERESTARTNOINTR) { + switch (regs->regs[REG_RET]) { + case -ERESTARTNOHAND: + case -ERESTARTSYS: + case -ERESTARTNOINTR: /* Decode Syscall # */ regs->regs[REG_RET] = regs->syscall_nr; regs->pc -= 4; + break; + + case -ERESTART_RESTARTBLOCK: + regs->regs[REG_RET] = __NR_restart_syscall; + regs->pc -= 4; + break; } } + + /* No signal to deliver -- put the saved sigmask back */ + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { + clear_thread_flag(TIF_RESTORE_SIGMASK); + sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); + } + return 0; } diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S index c0079d54c85..a5c680d2938 100644 --- a/arch/sh64/kernel/syscalls.S +++ b/arch/sh64/kernel/syscalls.S @@ -2,7 +2,7 @@ * arch/sh64/kernel/syscalls.S * * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2004 Paul Mundt + * Copyright (C) 2004 - 2007 Paul Mundt * Copyright (C) 2003, 2004 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -20,7 +20,7 @@ */ .globl sys_call_table sys_call_table: - .long sys_ni_syscall /* 0 - old "setup()" system call */ + .long sys_restart_syscall /* 0 - old "setup()" system call */ .long sys_exit .long sys_fork .long sys_read @@ -347,4 +347,34 @@ sys_call_table: .long sys_inotify_init .long sys_inotify_add_watch .long sys_inotify_rm_watch /* 320 */ - + .long sys_ni_syscall + .long sys_migrate_pages + .long sys_openat + .long sys_mkdirat + .long sys_mknodat /* 325 */ + .long sys_fchownat + .long sys_futimesat + .long sys_fstatat64 + .long sys_unlinkat + .long sys_renameat /* 330 */ + .long sys_linkat + .long sys_symlinkat + .long sys_readlinkat + .long sys_fchmodat + .long sys_faccessat /* 335 */ + .long sys_pselect6 + .long sys_ppoll + .long sys_unshare + .long sys_set_robust_list + .long sys_get_robust_list /* 340 */ + .long sys_splice + .long sys_sync_file_range + .long sys_tee + .long sys_vmsplice + .long sys_move_pages /* 345 */ + .long sys_getcpu + .long sys_epoll_pwait + .long sys_utimensat + .long sys_signalfd + .long sys_timerfd /* 350 */ + .long sys_eventfd diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c index 390b40de7ce..b37f4f4981d 100644 --- a/arch/sh64/kernel/time.c +++ b/arch/sh64/kernel/time.c @@ -123,7 +123,7 @@ static unsigned long long usecs_per_jiffy = 1000000/HZ; /* Approximation */ static unsigned long long scaled_recip_ctc_ticks_per_jiffy; /* Estimate number of microseconds that have elapsed since the last timer tick, - by scaling the delta that has occured in the CTC register. + by scaling the delta that has occurred in the CTC register. WARNING WARNING WARNING : This algorithm relies on the CTC decrementing at the CPU clock rate. If the CPU sleeps, the CTC stops counting. Bear this @@ -282,7 +282,7 @@ static long last_rtc_update = 0; * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ -static inline void do_timer_interrupt(int irq, struct pt_regs *regs) +static inline void do_timer_interrupt(void) { unsigned long long current_ctc; asm ("getcon cr62, %0" : "=r" (current_ctc)); @@ -290,9 +290,10 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(regs)); + update_process_times(user_mode(get_irq_regs())); #endif - profile_tick(CPU_PROFILING, regs); + if (current->pid) + profile_tick(CPU_PROFILING); #ifdef CONFIG_HEARTBEAT { @@ -323,7 +324,7 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. */ -static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t timer_interrupt(int irq, void *dev_id) { unsigned long timer_status; @@ -340,7 +341,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * locally disabled. -arca */ write_lock(&xtime_lock); - do_timer_interrupt(irq, regs); + do_timer_interrupt(); write_unlock(&xtime_lock); return IRQ_HANDLED; @@ -465,9 +466,10 @@ static __init unsigned int get_cpu_hz(void) #endif } -static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id) { + struct pt_regs *regs = get_irq_regs(); + ctrl_outb(0, RCR1); /* Disable Carry Interrupts */ regs->regs[3] = 1; /* Using r3 */ diff --git a/arch/sh64/lib/.gitignore b/arch/sh64/lib/.gitignore new file mode 100644 index 00000000000..3508c2cb23c --- /dev/null +++ b/arch/sh64/lib/.gitignore @@ -0,0 +1 @@ +syscalltab.h diff --git a/arch/sh64/mach-cayman/irq.c b/arch/sh64/mach-cayman/irq.c index 228ce61c351..aaad36d37d1 100644 --- a/arch/sh64/mach-cayman/irq.c +++ b/arch/sh64/mach-cayman/irq.c @@ -29,13 +29,13 @@ unsigned long epld_virt; /* Note the SMSC SuperIO chip and SMSC LAN chip interrupts are all muxed onto the same SH-5 interrupt */ -static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id) { printk(KERN_INFO "CAYMAN: spurious SMSC interrupt\n"); return IRQ_NONE; } -static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id) { printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq); return IRQ_NONE; diff --git a/arch/sh64/mach-cayman/setup.c b/arch/sh64/mach-cayman/setup.c index 3ed87cd059d..c3611cc2735 100644 --- a/arch/sh64/mach-cayman/setup.c +++ b/arch/sh64/mach-cayman/setup.c @@ -213,7 +213,7 @@ static int __init smsc_superio_setup(void) SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ #endif - /* Exit the configuraton state */ + /* Exit the configuration state */ outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); return 0; diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c index 4dd8ee8f01c..3cd93ba5d82 100644 --- a/arch/sh64/mm/fault.c +++ b/arch/sh64/mm/fault.c @@ -135,7 +135,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, /* SIM * Note this is now called with interrupts still disabled * This is to cope with being called for a missing IO port - * address with interupts disabled. This should be fixed as + * address with interrupts disabled. This should be fixed as * soon as we have a better 'fast path' miss handler. * * Plus take care how you try and debug this stuff. diff --git a/arch/sh64/mm/init.c b/arch/sh64/mm/init.c index 5dc08787259..559717f30d1 100644 --- a/arch/sh64/mm/init.c +++ b/arch/sh64/mm/init.c @@ -84,7 +84,7 @@ void show_mem(void) printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); - printk("%ld pages in page table cache\n",pgtable_cache_size); + printk("%ld pages in page table cache\n", quicklist_total_size()); } /* diff --git a/arch/sh64/mm/tlbmiss.c b/arch/sh64/mm/tlbmiss.c index d4c5334186d..b767d6cff72 100644 --- a/arch/sh64/mm/tlbmiss.c +++ b/arch/sh64/mm/tlbmiss.c @@ -14,7 +14,7 @@ * IMPORTANT NOTES : * The do_fast_page_fault function is called from a context in entry.S where very few registers * have been saved. In particular, the code in this file must be compiled not to use ANY - * caller-save regiseters that are not part of the restricted save set. Also, it means that + * caller-save registers that are not part of the restricted save set. Also, it means that * code in this file must not make calls to functions elsewhere in the kernel, or else the * excepting context will see corruption in its caller-save registers. Plus, the entry.S save * area is non-reentrant, so this code has to run with SR.BL==1, i.e. no interrupts taken inside @@ -249,7 +249,7 @@ asmlinkage int do_fast_page_fault(unsigned long long ssr_md, unsigned long long /* SIM * Note this is now called with interrupts still disabled * This is to cope with being called for a missing IO port - * address with interupts disabled. This should be fixed as + * address with interrupts disabled. This should be fixed as * soon as we have a better 'fast path' miss handler. * * Plus take care how you try and debug this stuff. diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index a307237b796..c978b589df4 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h @@ -17,7 +17,16 @@ #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)); +#define __NO_STUBS 1 +#undef __SYSCALL +#undef _ASM_X86_64_UNISTD_H_ +#define __SYSCALL(nr, sym) [nr] = 1, +static char syscalls[] = { +#include <asm/arch/unistd.h> +}; + void foo(void) { #include <common-offsets.h> +DEFINE(UM_NR_syscall_max, sizeof(syscalls) - 1); } diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h index 5e86aa047b2..cf72256609e 100644 --- a/arch/um/include/sysdep-x86_64/syscalls.h +++ b/arch/um/include/sysdep-x86_64/syscalls.h @@ -9,6 +9,7 @@ #include <linux/msg.h> #include <linux/shm.h> +#include <kern_constants.h> typedef long syscall_handler_t(void); @@ -29,6 +30,6 @@ extern long old_mmap(unsigned long addr, unsigned long len, extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t sys_arch_prctl; -#define NR_syscalls (__NR_syscall_max + 1) +#define NR_syscalls (UM_NR_syscall_max + 1) #endif diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 9e9ad72c2ba..5133988d361 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -4,6 +4,7 @@ #include <linux/linkage.h> #include <linux/sys.h> #include <linux/cache.h> +#include <kern_constants.h> #define __NO_STUBS @@ -45,8 +46,8 @@ typedef void (*sys_call_ptr_t)(void); extern void sys_ni_syscall(void); -sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { +sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ - [0 ... __NR_syscall_max] = &sys_ni_syscall, + [0 ... UM_NR_syscall_max] = &sys_ni_syscall, #include <asm-x86_64/unistd.h> }; diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 1f5c70461b8..c17342d3e6f 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -26,6 +26,7 @@ #include <linux/delay.h> #include <linux/poll.h> #include <linux/dma-mapping.h> +#include <linux/mm.h> #include <asm/uaccess.h> #include <asm/semaphore.h> diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 9040809d2c2..b1a9b81c211 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -4,13 +4,10 @@ # Andre Hedrick <andre@linux-ide.org> # -if BLOCK - -menu "ATA/ATAPI/MFM/RLL support" - depends on HAS_IOMEM - -config IDE +menuconfig IDE tristate "ATA/ATAPI/MFM/RLL support" + depends on BLOCK + depends on HAS_IOMEM ---help--- If you say Y here, your kernel will be able to manage low cost mass storage units such as ATA/(E)IDE and ATAPI units. The most common @@ -1099,8 +1096,4 @@ config BLK_DEV_HD_ONLY config BLK_DEV_HD def_bool BLK_DEV_HD_IDE || BLK_DEV_HD_ONLY -endif - -endmenu - -endif +endif # IDE diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index c04cb25a01f..ca0341c05e5 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -1002,18 +1002,6 @@ static int cris_ide_build_dmatable (ide_drive_t *drive) return 1; /* let the PIO routines handle this weirdness */ } -static int cris_config_drive_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (!speed) - return 0; - - speed_cris_ide(drive, speed); - - return ide_dma_enable(drive); -} - /* * cris_dma_intr() is the handler for disk read/write DMA interrupts */ @@ -1043,7 +1031,7 @@ static ide_startstop_t cris_dma_intr (ide_drive_t *drive) static int cris_dma_check(ide_drive_t *drive) { - if (ide_use_dma(drive) && cris_config_drive_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; return -1; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 5fe85191d49..b77b7d138c4 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -670,41 +670,6 @@ int __ide_dma_good_drive (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_good_drive); -int ide_use_dma(ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = drive->hwif; - - if ((id->capability & 1) == 0 || drive->autodma == 0) - return 0; - - /* consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - return 0; - - /* capable of UltraDMA modes */ - if (id->field_valid & 4) { - if (hwif->ultra_mask & id->dma_ultra) - return 1; - } - - /* capable of regular DMA modes */ - if (id->field_valid & 2) { - if (hwif->mwdma_mask & id->dma_mword) - return 1; - if (hwif->swdma_mask & id->dma_1word) - return 1; - } - - /* consult the list of known "good" drives */ - if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) - return 1; - - return 0; -} - -EXPORT_SYMBOL_GPL(ide_use_dma); - static const u8 xfer_mode_bases[] = { XFER_UDMA_0, XFER_MW_DMA_0, @@ -731,10 +696,12 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) mask &= 0x07; break; case XFER_MW_DMA_0: - mask = id->dma_mword & hwif->mwdma_mask; + if (id->field_valid & 2) + mask = id->dma_mword & hwif->mwdma_mask; break; case XFER_SW_DMA_0: - mask = id->dma_1word & hwif->swdma_mask; + if (id->field_valid & 2) + mask = id->dma_1word & hwif->swdma_mask; break; default: BUG(); @@ -783,8 +750,11 @@ int ide_tune_dma(ide_drive_t *drive) { u8 speed; - /* TODO: use only ide_max_dma_mode() */ - if (!ide_use_dma(drive)) + if ((drive->id->capability & 1) == 0 || drive->autodma == 0) + return 0; + + /* consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) return 0; speed = ide_max_dma_mode(drive); @@ -792,9 +762,10 @@ int ide_tune_dma(ide_drive_t *drive) if (!speed) return 0; - drive->hwif->speedproc(drive, speed); + if (drive->hwif->speedproc(drive, speed)) + return 0; - return ide_dma_enable(drive); + return 1; } EXPORT_SYMBOL_GPL(ide_tune_dma); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 8e568143d90..bfe8f1b712b 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -223,6 +223,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * break; if (drive->hwif->ide_dma_check == NULL) break; + drive->hwif->dma_off_quietly(drive); ide_set_dma(drive); break; } diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 3be3c69383f..074bb32a4a4 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -111,18 +111,6 @@ u8 ide_rate_filter(ide_drive_t *drive, u8 speed) EXPORT_SYMBOL(ide_rate_filter); -int ide_dma_enable (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - return ((int) ((((id->dma_ultra >> 8) & hwif->ultra_mask) || - ((id->dma_mword >> 8) & hwif->mwdma_mask) || - ((id->dma_1word >> 8) & hwif->swdma_mask)) ? 1 : 0)); -} - -EXPORT_SYMBOL(ide_dma_enable); - int ide_use_fast_pio(ide_drive_t *drive) { struct hd_driveid *id = drive->id; diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index f2b547ff772..6002713a20a 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -910,6 +910,7 @@ int set_using_dma(ide_drive_t *drive, int arg) err = 0; if (arg) { + hwif->dma_off_quietly(drive); if (ide_set_dma(drive) || hwif->ide_dma_on(drive)) err = -EIO; } else diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 428efdae0c7..27525ec2e19 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -455,28 +455,6 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } - -/** - * config_chipset_for_dma - set up DMA mode - * @drive: drive to configure for - * - * Place a drive into DMA mode and tune the chipset for - * the selected speed. - * - * Returns true if DMA mode can be used - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (!(speed)) - return 0; - - (void) ali15x3_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - /** * ali15x3_config_drive_for_dma - configure for DMA * @drive: drive to configure @@ -487,48 +465,14 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int ali15x3_config_drive_for_dma(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) - goto ata_pio; - drive->init_speed = 0; - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - goto ata_pio; - if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { - if (id->dma_ultra & hwif->ultra_mask) { - /* Force if Capable UltraDMA */ - int dma = config_chipset_for_dma(drive); - if ((id->field_valid & 2) && !dma) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) { - /* Force if Capable regular DMA modes */ - if (!config_chipset_for_dma(drive)) - goto ata_pio; - } - } else if (__ide_dma_good_drive(drive) && - (id->eide_dma_time < 150)) { - /* Consult the list of known "good" drives */ - if (!config_chipset_for_dma(drive)) - goto ata_pio; - } else { - goto ata_pio; - } - } else { -ata_pio: - hwif->tuneproc(drive, 255); - return -1; - } + if (ide_tune_dma(drive)) + return 0; - return 0; + ali15x3_tune_drive(drive, 255); + + return -1; } /** @@ -739,7 +683,8 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) return; } - hwif->atapi_dma = 1; + if (m5229_revision > 0x20) + hwif->atapi_dma = 1; if (m5229_revision <= 0x20) hwif->ultra_mask = 0x00; /* no udma */ diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 61ea96b5555..7c57dc696f5 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -352,22 +352,9 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) return ide_config_drive_speed(drive, speed); } -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (!speed) - return 0; - - if (cmd64x_tune_chipset(drive, speed)) - return 0; - - return ide_dma_enable(drive); -} - static int cmd64x_config_drive_for_dma (ide_drive_t *drive) { - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index b2d7c132ef4..1eec1f308d1 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -1,10 +1,10 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.7 Sept 10, 2002 + * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 * * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> - * Ditto of GNU General Public License. - * * Copyright (C) 2000 Mark Lord <mlord@pobox.com> + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz + * * May be copied or modified under the terms of the GNU General Public License * * Development of this chipset driver was funded @@ -62,6 +62,14 @@ static unsigned int cs5530_pio_timings[2][5] = { #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132) #define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) +static void cs5530_tunepio(ide_drive_t *drive, u8 pio) +{ + unsigned long basereg = CS5530_BASEREG(drive->hwif); + unsigned int format = (inl(basereg + 4) >> 31) & 1; + + outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3)); +} + /** * cs5530_tuneproc - select/set PIO modes * @@ -74,98 +82,78 @@ static unsigned int cs5530_pio_timings[2][5] = { static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autotune" */ { - ide_hwif_t *hwif = HWIF(drive); - unsigned int format; - unsigned long basereg = CS5530_BASEREG(hwif); - static u8 modes[5] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - if (!cs5530_set_xfer_mode(drive, modes[pio])) { - format = (inl(basereg + 4) >> 31) & 1; - outl(cs5530_pio_timings[format][pio], - basereg+(drive->select.b.unit<<3)); + + if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) + cs5530_tunepio(drive, pio); +} + +/** + * cs5530_udma_filter - UDMA filter + * @drive: drive + * + * cs5530_udma_filter() does UDMA mask filtering for the given drive + * taking into the consideration capabilities of the mate device. + * + * The CS5530 specifies that two drives sharing a cable cannot mix + * UDMA/MDMA. It has to be one or the other, for the pair, though + * different timings can still be chosen for each drive. We could + * set the appropriate timing bits on the fly, but that might be + * a bit confusing. So, for now we statically handle this requirement + * by looking at our mate drive to see what it is capable of, before + * choosing a mode for our own drive. + * + * Note: This relies on the fact we never fail from UDMA to MWDMA2 + * but instead drop to PIO. + */ + +static u8 cs5530_udma_filter(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + ide_drive_t *mate = &hwif->drives[(drive->dn & 1) ^ 1]; + struct hd_driveid *mateid = mate->id; + u8 mask = hwif->ultra_mask; + + if (mate->present == 0) + goto out; + + if ((mateid->capability & 1) && __ide_dma_bad_drive(mate) == 0) { + if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) + goto out; + if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) + mask = 0; } +out: + return mask; } /** - * cs5530_config_dma - select/set DMA and UDMA modes + * cs5530_config_dma - set DMA/UDMA mode * @drive: drive to tune * - * cs5530_config_dma() handles selection/setting of DMA/UDMA modes - * for both the chipset and drive. The CS5530 has limitations about - * mixing DMA/UDMA on the same cable. + * cs5530_config_dma() handles setting of DMA/UDMA mode + * for both the chipset and drive. */ - -static int cs5530_config_dma (ide_drive_t *drive) + +static int cs5530_config_dma(ide_drive_t *drive) { - int udma_ok = 1, mode = 0; - ide_hwif_t *hwif = HWIF(drive); - int unit = drive->select.b.unit; - ide_drive_t *mate = &hwif->drives[unit^1]; - struct hd_driveid *id = drive->id; - unsigned int reg, timings = 0; - unsigned long basereg; + if (ide_tune_dma(drive)) + return 0; - /* - * Default to DMA-off in case we run into trouble here. - */ - hwif->dma_off_quietly(drive); + return 1; +} - /* - * The CS5530 specifies that two drives sharing a cable cannot - * mix UDMA/MDMA. It has to be one or the other, for the pair, - * though different timings can still be chosen for each drive. - * We could set the appropriate timing bits on the fly, - * but that might be a bit confusing. So, for now we statically - * handle this requirement by looking at our mate drive to see - * what it is capable of, before choosing a mode for our own drive. - * - * Note: This relies on the fact we never fail from UDMA to MWDMA_2 - * but instead drop to PIO - */ - if (mate->present) { - struct hd_driveid *mateid = mate->id; - if (mateid && (mateid->capability & 1) && - !__ide_dma_bad_drive(mate)) { - if ((mateid->field_valid & 4) && - (mateid->dma_ultra & 7)) - udma_ok = 1; - else if ((mateid->field_valid & 2) && - (mateid->dma_mword & 7)) - udma_ok = 0; - else - udma_ok = 1; - } - } +static int cs5530_tune_chipset(ide_drive_t *drive, u8 mode) +{ + unsigned long basereg; + unsigned int reg, timings = 0; - /* - * Now see what the current drive is capable of, - * selecting UDMA only if the mate said it was ok. - */ - if (id && (id->capability & 1) && drive->autodma && - !__ide_dma_bad_drive(drive)) { - if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { - if (id->dma_ultra & 4) - mode = XFER_UDMA_2; - else if (id->dma_ultra & 2) - mode = XFER_UDMA_1; - else if (id->dma_ultra & 1) - mode = XFER_UDMA_0; - } - if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { - if (id->dma_mword & 4) - mode = XFER_MW_DMA_2; - else if (id->dma_mword & 2) - mode = XFER_MW_DMA_1; - else if (id->dma_mword & 1) - mode = XFER_MW_DMA_0; - } - } + mode = ide_rate_filter(drive, mode); /* * Tell the drive to switch to the new mode; abort on failure. */ - if (!mode || cs5530_set_xfer_mode(drive, mode)) + if (cs5530_set_xfer_mode(drive, mode)) return 1; /* failure */ /* @@ -178,14 +166,21 @@ static int cs5530_config_dma (ide_drive_t *drive) case XFER_MW_DMA_0: timings = 0x00077771; break; case XFER_MW_DMA_1: timings = 0x00012121; break; case XFER_MW_DMA_2: timings = 0x00002020; break; + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + cs5530_tunepio(drive, mode - XFER_PIO_0); + return 0; default: BUG(); break; } - basereg = CS5530_BASEREG(hwif); + basereg = CS5530_BASEREG(drive->hwif); reg = inl(basereg + 4); /* get drive0 config register */ timings |= reg & 0x80000000; /* preserve PIO format bit */ - if (unit == 0) { /* are we configuring drive0? */ + if ((drive-> dn & 1) == 0) { /* are we configuring drive0? */ outl(timings, basereg + 4); /* write drive0 config register */ } else { if (timings & 0x00100000) @@ -311,6 +306,8 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) hwif->serialized = hwif->mate->serialized = 1; hwif->tuneproc = &cs5530_tuneproc; + hwif->speedproc = &cs5530_tune_chipset; + basereg = CS5530_BASEREG(hwif); d0_timings = inl(basereg + 0); if (CS5530_BAD_PIO(d0_timings)) { @@ -332,6 +329,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; + hwif->udma_filter = cs5530_udma_filter; hwif->ide_dma_check = &cs5530_config_dma; if (!noautodma) hwif->autodma = 1; diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 442f658c6ae..5faaff87d58 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -464,25 +464,6 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) } /** - * config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by the IDE layer when it wants the timings set up. - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (speed == 0) - return 0; - - it821x_tune_chipset(drive, speed); - - return ide_dma_enable(drive); -} - -/** * it821x_configure_drive_for_dma - set up for DMA transfers * @drive: drive we are going to set up * @@ -494,7 +475,7 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int it821x_config_drive_for_dma (ide_drive_t *drive) { - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; it821x_tuneproc(drive, 255); diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 65b1e124edf..cc0bfdcf1f1 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -228,38 +228,11 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif) return get_indexed_reg(hwif, 0x0b) & 0x04; } -static int config_chipset_for_dma(ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - u8 speed; - - if (id->capability & 4) { - /* - * Set IORDY_EN & PREFETCH_EN (this seems to have - * NO real effect since this register is reloaded - * by hardware when the transfer mode is selected) - */ - u8 tmp, adj = (drive->dn & 1) ? 0x08 : 0x00; - - tmp = get_indexed_reg(hwif, 0x13 + adj); - set_indexed_reg(hwif, 0x13 + adj, tmp | 0x03); - } - - speed = ide_max_dma_mode(drive); - - if (!speed) - return 0; - - (void) hwif->speedproc(drive, speed); - return ide_dma_enable(drive); -} - static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) { drive->init_speed = 0; - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 7146fe3f6ba..23844687dee 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -1,8 +1,9 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 * * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2006-2007 MontaVista Software, Inc. + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this * compiled into the kernel if you have more than one card installed. @@ -60,45 +61,7 @@ static const char *pdc_quirk_drives[] = { NULL }; -/* A Register */ -#define SYNC_ERRDY_EN 0xC0 - -#define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */ -#define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */ -#define IORDY_EN 0x20 /* PIO: IOREADY */ -#define PREFETCH_EN 0x10 /* PIO: PREFETCH */ - -#define PA3 0x08 /* PIO"A" timing */ -#define PA2 0x04 /* PIO"A" timing */ -#define PA1 0x02 /* PIO"A" timing */ -#define PA0 0x01 /* PIO"A" timing */ - -/* B Register */ - -#define MB2 0x80 /* DMA"B" timing */ -#define MB1 0x40 /* DMA"B" timing */ -#define MB0 0x20 /* DMA"B" timing */ - -#define PB4 0x10 /* PIO_FORCE 1:0 */ - -#define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */ -#define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */ -#define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */ -#define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */ - -/* C Register */ -#define IORDYp_NO_SPEED 0x4F -#define SPEED_DIS 0x0F - -#define DMARQp 0x80 -#define IORDYp 0x40 -#define DMAR_EN 0x20 -#define DMAW_EN 0x10 - -#define MC3 0x08 /* DMA"C" timing */ -#define MC2 0x04 /* DMA"C" timing */ -#define MC1 0x02 /* DMA"C" timing */ -#define MC0 0x01 /* DMA"C" timing */ +static void pdc_old_disable_66MHz_clock(ide_hwif_t *); static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) { @@ -107,52 +70,25 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) u8 drive_pci = 0x60 + (drive->dn << 2); u8 speed = ide_rate_filter(drive, xferspeed); - u32 drive_conf; - u8 AP, BP, CP, DP; + u8 AP = 0, BP = 0, CP = 0; u8 TA = 0, TB = 0, TC = 0; - if (drive->media != ide_disk && - drive->media != ide_cdrom && speed < XFER_SW_DMA_0) - return -1; - +#if PDC202XX_DEBUG_DRIVE_INFO + u32 drive_conf = 0; pci_read_config_dword(dev, drive_pci, &drive_conf); - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - pci_read_config_byte(dev, (drive_pci)|0x03, &DP); +#endif - if (speed < XFER_SW_DMA_0) { - if ((AP & 0x0F) || (BP & 0x07)) { - /* clear PIO modes of lower 8421 bits of A Register */ - pci_write_config_byte(dev, (drive_pci), AP &~0x0F); - pci_read_config_byte(dev, (drive_pci), &AP); - - /* clear PIO modes of lower 421 bits of B Register */ - pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0x07); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - } - } else { - if ((BP & 0xF0) && (CP & 0x0F)) { - /* clear DMA modes of upper 842 bits of B Register */ - /* clear PIO forced mode upper 1 bit of B Register */ - pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0xF0); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - - /* clear DMA modes of lower 8421 bits of C Register */ - pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - } - } + /* + * TODO: do this once per channel + */ + if (dev->device != PCI_DEVICE_ID_PROMISE_20246) + pdc_old_disable_66MHz_clock(hwif); - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); + pci_read_config_byte(dev, drive_pci, &AP); + pci_read_config_byte(dev, drive_pci + 1, &BP); + pci_read_config_byte(dev, drive_pci + 2, &CP); switch(speed) { - case XFER_UDMA_6: speed = XFER_UDMA_5; case XFER_UDMA_5: case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; @@ -161,7 +97,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_UDMA_0: case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; - case XFER_MW_DMA_0: + case XFER_MW_DMA_0: TB = 0xE0; TC = 0x0F; break; case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; @@ -174,25 +110,39 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) } if (speed < XFER_SW_DMA_0) { - pci_write_config_byte(dev, (drive_pci), AP|TA); - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); + /* + * preserve SYNC_INT / ERDDY_EN bits while clearing + * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A + */ + AP &= ~0x3f; + if (drive->id->capability & 4) + AP |= 0x20; /* set IORDY_EN bit */ + if (drive->media == ide_disk) + AP |= 0x10; /* set Prefetch_EN bit */ + /* clear PB[4:0] bits of register B */ + BP &= ~0x1f; + pci_write_config_byte(dev, drive_pci, AP | TA); + pci_write_config_byte(dev, drive_pci + 1, BP | TB); } else { - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); - pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); + /* clear MB[2:0] bits of register B */ + BP &= ~0xe0; + /* clear MC[3:0] bits of register C */ + CP &= ~0x0f; + pci_write_config_byte(dev, drive_pci + 1, BP | TB); + pci_write_config_byte(dev, drive_pci + 2, CP | TC); } #if PDC202XX_DEBUG_DRIVE_INFO printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", drive->name, ide_xfer_verbose(speed), drive->dn, drive_conf); - pci_read_config_dword(dev, drive_pci, &drive_conf); + pci_read_config_dword(dev, drive_pci, &drive_conf); printk("0x%08x\n", drive_conf); -#endif /* PDC202XX_DEBUG_DRIVE_INFO */ +#endif - return (ide_config_drive_speed(drive, speed)); + return ide_config_drive_speed(drive, speed); } - static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) { pio = ide_get_best_pio_mode(drive, pio, 4, NULL); @@ -210,6 +160,8 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) * Set the control register to use the 66MHz system * clock for UDMA 3/4/5 mode operation when necessary. * + * FIXME: this register is shared by both channels, some locking is needed + * * It may also be possible to leave the 66MHz clock on * and readjust the timing parameters. */ @@ -229,65 +181,11 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); } -static int config_chipset_for_dma (ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 drive_conf = 0; - u8 drive_pci = 0x60 + (drive->dn << 2); - u8 test1 = 0, test2 = 0, speed = -1; - u8 AP = 0; - - if (dev->device != PCI_DEVICE_ID_PROMISE_20246) - pdc_old_disable_66MHz_clock(drive->hwif); - - drive_pci = 0x60 + (drive->dn << 2); - pci_read_config_dword(dev, drive_pci, &drive_conf); - if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) - goto chipset_is_set; - - pci_read_config_byte(dev, drive_pci, &test1); - if (!(test1 & SYNC_ERRDY_EN)) { - if (drive->select.b.unit & 0x01) { - pci_read_config_byte(dev, drive_pci - 4, &test2); - if ((test2 & SYNC_ERRDY_EN) && - !(test1 & SYNC_ERRDY_EN)) { - pci_write_config_byte(dev, drive_pci, - test1|SYNC_ERRDY_EN); - } - } else { - pci_write_config_byte(dev, drive_pci, - test1|SYNC_ERRDY_EN); - } - } - -chipset_is_set: - - pci_read_config_byte(dev, (drive_pci), &AP); - if (id->capability & 4) /* IORDY_EN */ - pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); - pci_read_config_byte(dev, (drive_pci), &AP); - if (drive->media == ide_disk) /* PREFETCH_EN */ - pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - - speed = ide_max_dma_mode(drive); - - if (!(speed)) { - /* restore original pci-config space */ - pci_write_config_dword(dev, drive_pci, drive_conf); - return 0; - } - - (void) hwif->speedproc(drive, speed); - return ide_dma_enable(drive); -} - static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) { drive->init_speed = 0; - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index b5ae0c50e21..523363c9379 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -1,7 +1,9 @@ /* - * linux/drivers/ide/pci/sc1200.c Version 0.91 28-Jan-2003 + * linux/drivers/ide/pci/sc1200.c Version 0.94 Mar 10 2007 * * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com> + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz + * * May be copied or modified under the terms of the GNU General Public License * * Development of this chipset driver was funded @@ -93,64 +95,50 @@ static const unsigned int sc1200_pio_timings[4][5] = */ //#define SC1200_BAD_PIO(timings) (((timings)&~0x80000000)==0x00009172) -static int sc1200_autoselect_dma_mode (ide_drive_t *drive) +static void sc1200_tunepio(ide_drive_t *drive, u8 pio) { - int udma_ok = 1, mode = 0; - ide_hwif_t *hwif = HWIF(drive); - int unit = drive->select.b.unit; - ide_drive_t *mate = &hwif->drives[unit^1]; - struct hd_driveid *id = drive->id; - - /* - * The SC1200 specifies that two drives sharing a cable cannot - * mix UDMA/MDMA. It has to be one or the other, for the pair, - * though different timings can still be chosen for each drive. - * We could set the appropriate timing bits on the fly, - * but that might be a bit confusing. So, for now we statically - * handle this requirement by looking at our mate drive to see - * what it is capable of, before choosing a mode for our own drive. - */ - if (mate->present) { - struct hd_driveid *mateid = mate->id; - if (mateid && (mateid->capability & 1) && !__ide_dma_bad_drive(mate)) { - if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) - udma_ok = 1; - else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) - udma_ok = 0; - else - udma_ok = 1; - } - } - /* - * Now see what the current drive is capable of, - * selecting UDMA only if the mate said it was ok. - */ - if (id && (id->capability & 1) && hwif->autodma && !__ide_dma_bad_drive(drive)) { - if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { - if (id->dma_ultra & 4) - mode = XFER_UDMA_2; - else if (id->dma_ultra & 2) - mode = XFER_UDMA_1; - else if (id->dma_ultra & 1) - mode = XFER_UDMA_0; - } - if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { - if (id->dma_mword & 4) - mode = XFER_MW_DMA_2; - else if (id->dma_mword & 2) - mode = XFER_MW_DMA_1; - else if (id->dma_mword & 1) - mode = XFER_MW_DMA_0; - } - } - return mode; + ide_hwif_t *hwif = drive->hwif; + struct pci_dev *pdev = hwif->pci_dev; + unsigned int basereg = hwif->channel ? 0x50 : 0x40, format = 0; + + pci_read_config_dword(pdev, basereg + 4, &format); + format = (format >> 31) & 1; + if (format) + format += sc1200_get_pci_clock(); + pci_write_config_dword(pdev, basereg + ((drive->dn & 1) << 3), + sc1200_pio_timings[format][pio]); } /* - * sc1200_config_dma2() handles selection/setting of DMA/UDMA modes - * for both the chipset and drive. + * The SC1200 specifies that two drives sharing a cable cannot mix + * UDMA/MDMA. It has to be one or the other, for the pair, though + * different timings can still be chosen for each drive. We could + * set the appropriate timing bits on the fly, but that might be + * a bit confusing. So, for now we statically handle this requirement + * by looking at our mate drive to see what it is capable of, before + * choosing a mode for our own drive. */ -static int sc1200_config_dma2 (ide_drive_t *drive, int mode) +static u8 sc1200_udma_filter(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + ide_drive_t *mate = &hwif->drives[(drive->dn & 1) ^ 1]; + struct hd_driveid *mateid = mate->id; + u8 mask = hwif->ultra_mask; + + if (mate->present == 0) + goto out; + + if ((mateid->capability & 1) && __ide_dma_bad_drive(mate) == 0) { + if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) + goto out; + if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) + mask = 0; + } +out: + return mask; +} + +static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode) { ide_hwif_t *hwif = HWIF(drive); int unit = drive->select.b.unit; @@ -158,20 +146,26 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode) unsigned short pci_clock; unsigned int basereg = hwif->channel ? 0x50 : 0x40; - /* - * Default to DMA-off in case we run into trouble here. - */ - hwif->dma_off_quietly(drive); /* turn off DMA while we fiddle */ - outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */ + mode = ide_rate_filter(drive, mode); /* * Tell the drive to switch to the new mode; abort on failure. */ - if (!mode || sc1200_set_xfer_mode(drive, mode)) { + if (sc1200_set_xfer_mode(drive, mode)) { printk("SC1200: set xfer mode failure\n"); return 1; /* failure */ } + switch (mode) { + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + sc1200_tunepio(drive, mode - XFER_PIO_0); + return 0; + } + pci_clock = sc1200_get_pci_clock(); /* @@ -224,11 +218,9 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode) case PCI_CLK_66: timings = 0x00015151; break; } break; - } - - if (timings == 0) { - printk("%s: sc1200_config_dma: huh? mode=%02x clk=%x \n", drive->name, mode, pci_clock); - return 1; /* failure */ + default: + BUG(); + break; } if (unit == 0) { /* are we configuring drive0? */ @@ -239,8 +231,6 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode) pci_write_config_dword(hwif->pci_dev, basereg+12, timings); } - outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */ - return 0; /* success */ } @@ -250,7 +240,10 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode) */ static int sc1200_config_dma (ide_drive_t *drive) { - return sc1200_config_dma2(drive, sc1200_autoselect_dma_mode(drive)); + if (ide_tune_dma(drive)) + return 0; + + return 1; } @@ -290,10 +283,11 @@ static int sc1200_ide_dma_end (ide_drive_t *drive) static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "autotune" */ { ide_hwif_t *hwif = HWIF(drive); - unsigned int format; - static byte modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; int mode = -1; + /* + * bad abuse of ->tuneproc interface + */ switch (pio) { case 200: mode = XFER_UDMA_0; break; case 201: mode = XFER_UDMA_1; break; @@ -304,20 +298,17 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au } if (mode != -1) { printk("SC1200: %s: changing (U)DMA mode\n", drive->name); - (void)sc1200_config_dma2(drive, mode); + hwif->dma_off_quietly(drive); + if (sc1200_tune_chipset(drive, mode) == 0) + hwif->dma_host_on(drive); return; } pio = ide_get_best_pio_mode(drive, pio, 4, NULL); printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio); - if (!sc1200_set_xfer_mode(drive, modes[pio])) { - unsigned int basereg = hwif->channel ? 0x50 : 0x40; - pci_read_config_dword (hwif->pci_dev, basereg+4, &format); - format = (format >> 31) & 1; - if (format) - format += sc1200_get_pci_clock(); - pci_write_config_dword(hwif->pci_dev, basereg + (drive->select.b.unit << 3), sc1200_pio_timings[format][pio]); - } + + if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) + sc1200_tunepio(drive, pio); } #ifdef CONFIG_PM @@ -438,12 +429,12 @@ static int sc1200_resume (struct pci_dev *dev) for (d = 0; d < MAX_DRIVES; ++d) { ide_drive_t *drive = &(hwif->drives[d]); if (drive->present && !__ide_dma_bad_drive(drive)) { - int was_using_dma = drive->using_dma; + int enable_dma = drive->using_dma; hwif->dma_off_quietly(drive); - sc1200_config_dma(drive); - if (!was_using_dma && drive->using_dma) { - hwif->dma_off_quietly(drive); - } + if (sc1200_config_dma(drive)) + enable_dma = 0; + if (enable_dma) + hwif->dma_host_on(drive); } } } @@ -461,11 +452,13 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) hwif->serialized = hwif->mate->serialized = 1; hwif->autodma = 0; if (hwif->dma_base) { + hwif->udma_filter = sc1200_udma_filter; hwif->ide_dma_check = &sc1200_config_dma; hwif->ide_dma_end = &sc1200_ide_dma_end; if (!noautodma) hwif->autodma = 1; hwif->tuneproc = &sc1200_tuneproc; + hwif->speedproc = &sc1200_tune_chipset; } hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index cbf93632535..55bc0a32e34 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -322,26 +322,6 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) } /** - * scc_config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by scc_config_drive_for_dma(). - */ - -static int scc_config_chipset_for_dma(ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (!speed) - return 0; - - if (scc_tune_chipset(drive, speed)) - return 0; - - return ide_dma_enable(drive); -} - -/** * scc_configure_drive_for_dma - set up for DMA transfers * @drive: drive we are going to set up * @@ -354,7 +334,7 @@ static int scc_config_chipset_for_dma(ide_drive_t *drive) static int scc_config_drive_for_dma(ide_drive_t *drive) { - if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 2fa6d92d16c..6234f806c6b 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -1,9 +1,10 @@ /* - * linux/drivers/ide/pci/serverworks.c Version 0.8 25 Ebr 2003 + * linux/drivers/ide/pci/serverworks.c Version 0.9 Mar 4 2007 * * Copyright (C) 1998-2000 Michel Aubry * Copyright (C) 1998-2000 Andrzej Krzysztofowicz * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * Portions copyright (c) 2001 Sun Microsystems * * @@ -136,19 +137,14 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 speed; - u8 pio = ide_get_best_pio_mode(drive, 255, 5, NULL); + u8 speed = ide_rate_filter(drive, xferspeed); + u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL); u8 unit = (drive->select.b.unit & 0x01); u8 csb5 = svwks_csb_check(dev); u8 ultra_enable = 0, ultra_timing = 0; u8 dma_timing = 0, pio_timing = 0; u16 csb5_pio = 0; - if (xferspeed == 255) /* PIO auto-tuning */ - speed = XFER_PIO_0 + pio; - else - speed = ide_rate_filter(drive, xferspeed); - /* If we are about to put a disk into UDMA mode we screwed up. Our code assumes we never _ever_ do this on an OSB4 */ @@ -231,6 +227,9 @@ oem_setup_failed: case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_MW_DMA_0: + /* + * TODO: always setup PIO mode so this won't be needed + */ pio_timing |= pio_modes[pio]; csb5_pio |= (pio << (4*drive->dn)); dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; @@ -242,6 +241,9 @@ oem_setup_failed: case XFER_UDMA_2: case XFER_UDMA_1: case XFER_UDMA_0: + /* + * TODO: always setup PIO mode so this won't be needed + */ pio_timing |= pio_modes[pio]; csb5_pio |= (pio << (4*drive->dn)); dma_timing |= dma_modes[2]; @@ -262,72 +264,21 @@ oem_setup_failed: return (ide_config_drive_speed(drive, speed)); } -static void config_chipset_for_pio (ide_drive_t *drive) -{ - u16 eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; - u16 xfer_pio = drive->id->eide_pio_modes; - u8 timing, speed, pio; - - pio = ide_get_best_pio_mode(drive, 255, 5, NULL); - - if (xfer_pio > 4) - xfer_pio = 0; - - if (drive->id->eide_pio_iordy > 0) - for (xfer_pio = 5; - xfer_pio>0 && - drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; - xfer_pio--); - else - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : - (drive->id->eide_pio_modes & 2) ? 0x04 : - (drive->id->eide_pio_modes & 1) ? 0x03 : - (drive->id->tPIO & 2) ? 0x02 : - (drive->id->tPIO & 1) ? 0x01 : xfer_pio; - - timing = (xfer_pio >= pio) ? xfer_pio : pio; - - switch(timing) { - case 4: speed = XFER_PIO_4;break; - case 3: speed = XFER_PIO_3;break; - case 2: speed = XFER_PIO_2;break; - case 1: speed = XFER_PIO_1;break; - default: - speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; - break; - } - (void) svwks_tune_chipset(drive, speed); - drive->current_speed = speed; -} - static void svwks_tune_drive (ide_drive_t *drive, u8 pio) { - if(pio == 255) - (void) svwks_tune_chipset(drive, 255); - else - (void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio)); -} - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (!(speed)) - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); - - (void) svwks_tune_chipset(drive, speed); - return ide_dma_enable(drive); + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + (void)svwks_tune_chipset(drive, XFER_PIO_0 + pio); } static int svwks_config_drive_xfer_rate (ide_drive_t *drive) { drive->init_speed = 0; - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; if (ide_use_fast_pio(drive)) - config_chipset_for_pio(drive); + svwks_tune_drive(drive, 255); return -1; } diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index d09e74c2996..1a4444e7226 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -375,28 +375,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) } /** - * config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by the IDE layer when it wants the timings set up. - * For the CMD680 we also need to set up the PIO timings and - * enable DMA. - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_max_dma_mode(drive); - - if (!speed) - return 0; - - if (siimage_tune_chipset(drive, speed)) - return 0; - - return ide_dma_enable(drive); -} - -/** * siimage_configure_drive_for_dma - set up for DMA transfers * @drive: drive we are going to set up * @@ -408,7 +386,7 @@ static int config_chipset_for_dma (ide_drive_t *drive) static int siimage_config_drive_for_dma (ide_drive_t *drive) { - if (ide_use_dma(drive) && config_chipset_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; if (ide_use_fast_pio(drive)) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 2bde1b92784..bb6cc4aedd6 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -1,9 +1,11 @@ /* - * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003 + * linux/drivers/ide/pci/sis5513.c Version 0.20 Mar 4, 2007 * * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz + * * May be copied or modified under the terms of the GNU General Public License * * @@ -448,36 +450,15 @@ static void config_drive_art_rwp (ide_drive_t *drive) pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); } - /* Set per-drive active and recovery time */ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 timing, drive_pci, test1, test2; - - u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; - u16 xfer_pio = drive->id->eide_pio_modes; + u8 drive_pci, test1, test2; config_drive_art_rwp(drive); - pio = ide_get_best_pio_mode(drive, 255, pio, NULL); - - if (xfer_pio> 4) - xfer_pio = 0; - - if (drive->id->eide_pio_iordy > 0) { - for (xfer_pio = 5; - (xfer_pio > 0) && - (drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]); - xfer_pio--); - } else { - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : - (drive->id->eide_pio_modes & 2) ? 0x04 : - (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio; - } - - timing = (xfer_pio >= pio) ? xfer_pio : pio; /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ drive_pci = 0x40; @@ -500,17 +481,18 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) test1 &= ~0x0F; test2 &= ~0x07; - switch(timing) { + switch(pio) { case 4: test1 |= 0x01; test2 |= 0x03; break; case 3: test1 |= 0x03; test2 |= 0x03; break; case 2: test1 |= 0x04; test2 |= 0x04; break; case 1: test1 |= 0x07; test2 |= 0x06; break; + case 0: /* PIO0: register setting == X000 */ default: break; } pci_write_config_byte(dev, drive_pci, test1); pci_write_config_byte(dev, drive_pci+1, test2); } else if (chipset_family < ATA_133) { - switch(timing) { /* active recovery + switch(pio) { /* active recovery v v */ case 4: test1 = 0x30|0x01; break; case 3: test1 = 0x30|0x03; break; @@ -525,24 +507,28 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) pci_read_config_dword(dev, drive_pci, &test3); test3 &= 0xc0c00fff; if (test3 & 0x08) { - test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12; - test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16; - test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24; + test3 |= ini_time_value[ATA_133][pio] << 12; + test3 |= act_time_value[ATA_133][pio] << 16; + test3 |= rco_time_value[ATA_133][pio] << 24; } else { - test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12; - test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16; - test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24; + test3 |= ini_time_value[ATA_100][pio] << 12; + test3 |= act_time_value[ATA_100][pio] << 16; + test3 |= rco_time_value[ATA_100][pio] << 24; } pci_write_config_dword(dev, drive_pci, test3); } } -static int config_chipset_for_pio (ide_drive_t *drive, u8 pio) +static int sis5513_tune_drive(ide_drive_t *drive, u8 pio) { - if (pio == 255) - pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); config_art_rwp_pio(drive, pio); - return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4)); + return ide_config_drive_speed(drive, XFER_PIO_0 + pio); +} + +static void sis5513_tuneproc(ide_drive_t *drive, u8 pio) +{ + (void)sis5513_tune_drive(drive, pio); } static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) @@ -622,25 +608,26 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_SW_DMA_1: case XFER_SW_DMA_0: break; - case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4)); - case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3)); - case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2)); - case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1)); + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: case XFER_PIO_0: - default: return((int) config_chipset_for_pio(drive, 0)); + return sis5513_tune_drive(drive, speed - XFER_PIO_0); + default: + BUG(); + break; } - return ((int) ide_config_drive_speed(drive, speed)); -} - -static void sis5513_tune_drive (ide_drive_t *drive, u8 pio) -{ - (void) config_chipset_for_pio(drive, pio); + return ide_config_drive_speed(drive, speed); } static int sis5513_config_xfer_rate(ide_drive_t *drive) { - config_art_rwp_pio(drive, 5); + /* + * TODO: always set PIO mode and remove this + */ + sis5513_tuneproc(drive, 255); drive->init_speed = 0; @@ -648,7 +635,7 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - sis5513_tune_drive(drive, 5); + sis5513_tuneproc(drive, 255); return -1; } @@ -836,7 +823,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; - hwif->tuneproc = &sis5513_tune_drive; + hwif->tuneproc = &sis5513_tuneproc; hwif->speedproc = &sis5513_tune_chipset; if (!(hwif->dma_base)) { diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index fe3b4b91f85..7c383d9cc47 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -82,7 +82,14 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) pio = ide_get_best_pio_mode(drive, pio, 5, &p); - drive->drive_data = drv_ctrl = get_pio_timings(&p); + drv_ctrl = get_pio_timings(&p); + + /* + * Store the PIO timings so that we can restore them + * in case DMA will be turned off... + */ + drive->drive_data &= 0xffff0000; + drive->drive_data |= drv_ctrl; if (!drive->using_dma) { /* @@ -100,17 +107,55 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) } /* - * Configure the drive for DMA. - * We'll program the chipset only when DMA is actually turned on. + * Configure the drive and chipset for a new transfer speed. */ -static int config_for_dma(ide_drive_t *drive) +static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed) { - DBG(("config_for_dma(drive:%s)\n", drive->name)); + static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; + u16 drv_ctrl; - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 0; + DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", + drive->name, ide_xfer_verbose(speed))); - return ide_dma_enable(drive); + speed = ide_rate_filter(drive, speed); + + switch (speed) { + case XFER_MW_DMA_2: + case XFER_MW_DMA_1: + case XFER_MW_DMA_0: + drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0]; + + /* + * Store the DMA timings so that we can actually program + * them when DMA will be turned on... + */ + drive->drive_data &= 0x0000ffff; + drive->drive_data |= (unsigned long)drv_ctrl << 16; + + /* + * If we are already using DMA, we just reprogram + * the drive control register. + */ + if (drive->using_dma) { + struct pci_dev *dev = HWIF(drive)->pci_dev; + int reg = 0x44 + drive->dn * 4; + + pci_write_config_word(dev, reg, drv_ctrl); + } + break; + case XFER_PIO_5: + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + (void) sl82c105_tune_pio(drive, speed - XFER_PIO_0); + break; + default: + return -1; + } + + return ide_config_drive_speed(drive, speed); } /* @@ -120,7 +165,7 @@ static int sl82c105_ide_dma_check(ide_drive_t *drive) { DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); - if (ide_use_dma(drive) && config_for_dma(drive)) + if (ide_tune_dma(drive)) return 0; return -1; @@ -219,7 +264,7 @@ static int sl82c105_ide_dma_on(ide_drive_t *drive) rc = __ide_dma_on(drive); if (rc == 0) { - pci_write_config_word(dev, reg, 0x0200); + pci_write_config_word(dev, reg, drive->drive_data >> 16); printk(KERN_INFO "%s: DMA enabled\n", drive->name); } @@ -304,7 +349,7 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) /* * The bridge should be part of the same device, but function 0. */ - bridge = pci_find_slot(dev->bus->number, + bridge = pci_get_bus_and_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); if (!bridge) return -1; @@ -314,13 +359,15 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) */ if (bridge->vendor != PCI_VENDOR_ID_WINBOND || bridge->device != PCI_DEVICE_ID_WINBOND_83C553 || - bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) + bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) { + pci_dev_put(bridge); return -1; - + } /* * We need to find function 0's revision, not function 1 */ pci_read_config_byte(bridge, PCI_REVISION_ID, &rev); + pci_dev_put(bridge); return rev; } @@ -357,6 +404,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); hwif->tuneproc = &sl82c105_tune_drive; + hwif->speedproc = &sl82c105_tune_chipset; hwif->selectproc = &sl82c105_selectproc; hwif->resetproc = &sl82c105_resetproc; @@ -388,7 +436,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) } hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; + hwif->mwdma_mask = 0x07; hwif->ide_dma_check = &sl82c105_ide_dma_check; hwif->ide_dma_on = &sl82c105_ide_dma_on; diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 82f563e24fd..b0023452ec9 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -255,6 +255,7 @@ config JOYSTICK_JOYDUMP config JOYSTICK_XPAD tristate "X-Box gamepad support" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the X-Box pad with your computer. diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 6013ace94d9..842a7b4d16f 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -84,6 +84,7 @@ config INPUT_ATLAS_BTNS config INPUT_ATI_REMOTE tristate "ATI / X10 USB RF remote control" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use an ATI or X10 "Lola" USB remote control. @@ -99,6 +100,7 @@ config INPUT_ATI_REMOTE config INPUT_ATI_REMOTE2 tristate "ATI / Philips USB RF remote control" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use an ATI or Philips USB RF remote control. @@ -114,6 +116,7 @@ config INPUT_ATI_REMOTE2 config INPUT_KEYSPAN_REMOTE tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" depends on EXPERIMENTAL + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use a Keyspan DMR USB remote control. @@ -128,6 +131,7 @@ config INPUT_KEYSPAN_REMOTE config INPUT_POWERMATE tristate "Griffin PowerMate and Contour Jog support" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use Griffin PowerMate or Contour Jog devices. @@ -144,6 +148,7 @@ config INPUT_POWERMATE config INPUT_YEALINK tristate "Yealink usb-p1k voip phone" depends EXPERIMENTAL + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to enable keyboard and LCD functions of the diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 2ccc114b3ff..eb0167e9f0c 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -111,6 +111,7 @@ config MOUSE_SERIAL config MOUSE_APPLETOUCH tristate "Apple USB Touchpad support" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use an Apple USB Touchpad. diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index 12dfb0eb326..d371c0bdc0b 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig @@ -13,6 +13,7 @@ if INPUT_TABLET config TABLET_USB_ACECAD tristate "Acecad Flair tablet support (USB)" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the Acecad Flair @@ -25,6 +26,7 @@ config TABLET_USB_ACECAD config TABLET_USB_AIPTEK tristate "Aiptek 6000U/8000U tablet support (USB)" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the Aiptek 6000U @@ -49,6 +51,7 @@ config TABLET_USB_GTCO config TABLET_USB_KBTAB tristate "KB Gear JamStudio tablet support (USB)" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the KB Gear @@ -61,6 +64,7 @@ config TABLET_USB_KBTAB config TABLET_USB_WACOM tristate "Wacom Intuos/Graphire tablet support (USB)" + depends on USB_ARCH_HAS_HCD select USB help Say Y here if you want to use the USB version of the Wacom Intuos diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 5e640aeb03c..4f091800bfe 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -166,6 +166,7 @@ config TOUCHSCREEN_UCB1400 config TOUCHSCREEN_USB_COMPOSITE tristate "USB Touchscreen Driver" + depends on USB_ARCH_HAS_HCD select USB help USB Touchscreen driver for: diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig index 3823b62da4a..2c450bd05af 100644 --- a/drivers/media/video/em28xx/Kconfig +++ b/drivers/media/video/em28xx/Kconfig @@ -1,6 +1,6 @@ config VIDEO_EM28XX tristate "Empia EM2800/2820/2840 USB video capture support" - depends on VIDEO_V4L1 && I2C + depends on VIDEO_V4L1 && I2C && PCI select VIDEO_BUF select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index e854f3f1b70..0cc98a0e249 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -1,6 +1,6 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" - depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL + depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL && PCI select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c index 9ffdb9d29da..dfbd5809d74 100644 --- a/drivers/net/mlx4/alloc.c +++ b/drivers/net/mlx4/alloc.c @@ -33,6 +33,7 @@ #include <linux/errno.h> #include <linux/slab.h> #include <linux/bitmap.h> +#include <linux/dma-mapping.h> #include "mlx4.h" diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index af016d0ea1c..0f11adb8eb4 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -33,6 +33,7 @@ #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/dma-mapping.h> #include <linux/mlx4/cmd.h> diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index e96feaed6ed..b7a4aa8476f 100644 --- a/drivers/net/mlx4/icm.c +++ b/drivers/net/mlx4/icm.c @@ -33,6 +33,7 @@ #include <linux/init.h> #include <linux/errno.h> +#include <linux/mm.h> #include <linux/mlx4/cmd.h> diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c index 51eef8492e9..e4dfd4b11a4 100644 --- a/drivers/net/mlx4/reset.c +++ b/drivers/net/mlx4/reset.c @@ -35,6 +35,7 @@ #include <linux/pci.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/jiffies.h> #include "mlx4.h" diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index bc7f3dee6e5..8d38425e46c 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -85,6 +85,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) { struct pci_dev *pdev = mac->pdev; struct device_node *dn = pci_device_to_OF_node(pdev); + int len; const u8 *maddr; u8 addr[6]; @@ -94,9 +95,17 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - maddr = of_get_property(dn, "local-mac-address", NULL); + maddr = of_get_property(dn, "local-mac-address", &len); + + if (maddr && len == 6) { + memcpy(mac->mac_addr, maddr, 6); + return 0; + } + + /* Some old versions of firmware mistakenly uses mac-address + * (and as a string) instead of a byte array in local-mac-address. + */ - /* Fall back to mac-address for older firmware */ if (maddr == NULL) maddr = of_get_property(dn, "mac-address", NULL); @@ -106,6 +115,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } + if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) { dev_warn(&pdev->dev, @@ -113,7 +123,8 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -EINVAL; } - memcpy(mac->mac_addr, addr, sizeof(addr)); + memcpy(mac->mac_addr, addr, 6); + return 0; } @@ -384,17 +395,14 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) { - unsigned int reg, stat; + unsigned int reg, pcnt; /* Re-enable packet count interrupts: finally * ack the packet count interrupt we got in rx_intr. */ - pci_read_config_dword(mac->iob_pdev, - PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch), - &stat); + pcnt = *mac->rx_status & PAS_STATUS_PCNT_M; - reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) - | PAS_IOB_DMA_RXCH_RESET_PINTC; + reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), @@ -403,14 +411,12 @@ static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) { - unsigned int reg, stat; + unsigned int reg, pcnt; /* Re-enable packet count interrupts */ - pci_read_config_dword(mac->iob_pdev, - PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat); + pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; - reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) - | PAS_IOB_DMA_TXCH_RESET_PINTC; + reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); @@ -591,21 +597,24 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) { struct net_device *dev = data; struct pasemi_mac *mac = netdev_priv(dev); - unsigned int reg; + unsigned int reg, pcnt; if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) return IRQ_NONE; pasemi_mac_clean_tx(mac); - reg = PAS_IOB_DMA_TXCH_RESET_PINTC; + pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; + + reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; if (*mac->tx_status & PAS_STATUS_SOFT) reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; if (*mac->tx_status & PAS_STATUS_ERROR) reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), + pci_write_config_dword(mac->iob_pdev, + PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); return IRQ_HANDLED; @@ -974,6 +983,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) { spin_unlock_irqrestore(&txring->lock, flags); pasemi_mac_clean_tx(mac); + pasemi_mac_restart_tx_intr(mac); spin_lock_irqsave(&txring->lock, flags); if (txring->next_to_clean - txring->next_to_use == @@ -1210,6 +1220,7 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev) static struct pci_device_id pasemi_mac_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa005) }, { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa006) }, + { }, }; MODULE_DEVICE_TABLE(pci, pasemi_mac_pci_tbl); diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 8bc0cea8b14..c29ee159c33 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -341,7 +341,7 @@ enum { PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) #define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4) #define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 0 +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16 #define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \ PAS_IOB_DMA_RXCH_RESET_PCNT_M) #define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020 @@ -352,7 +352,7 @@ enum { #define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001 #define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4) #define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 0 +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16 #define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \ PAS_IOB_DMA_TXCH_RESET_PCNT_M) #define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020 diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 81f24847c96..db43e42bee3 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -77,7 +77,6 @@ static const char version[] = #include <linux/skbuff.h> #include <asm/io.h> -#include <asm/irq.h> #include "smc911x.h" @@ -2084,12 +2083,11 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr) lp->ctl_rspeed = 100; /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc911x_interrupt, IRQF_SHARED, dev->name, dev); + retval = request_irq(dev->irq, &smc911x_interrupt, + IRQF_SHARED | IRQF_TRIGGER_FALLING, dev->name, dev); if (retval) goto err_out; - set_irq_type(dev->irq, IRQT_FALLING); - #ifdef SMC_USE_DMA lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq); lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 0f667652fda..c2ccbd098f5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. + * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved. * * Author: Shlomi Gridish <gridish@freescale.com> * Li Yang <leoli@freescale.com> @@ -3737,21 +3737,21 @@ static int ucc_geth_close(struct net_device *dev) const struct ethtool_ops ucc_geth_ethtool_ops = { }; -static phy_interface_t to_phy_interface(const char *interface_type) +static phy_interface_t to_phy_interface(const char *phy_connection_type) { - if (strcasecmp(interface_type, "mii") == 0) + if (strcasecmp(phy_connection_type, "mii") == 0) return PHY_INTERFACE_MODE_MII; - if (strcasecmp(interface_type, "gmii") == 0) + if (strcasecmp(phy_connection_type, "gmii") == 0) return PHY_INTERFACE_MODE_GMII; - if (strcasecmp(interface_type, "tbi") == 0) + if (strcasecmp(phy_connection_type, "tbi") == 0) return PHY_INTERFACE_MODE_TBI; - if (strcasecmp(interface_type, "rmii") == 0) + if (strcasecmp(phy_connection_type, "rmii") == 0) return PHY_INTERFACE_MODE_RMII; - if (strcasecmp(interface_type, "rgmii") == 0) + if (strcasecmp(phy_connection_type, "rgmii") == 0) return PHY_INTERFACE_MODE_RGMII; - if (strcasecmp(interface_type, "rgmii-id") == 0) + if (strcasecmp(phy_connection_type, "rgmii-id") == 0) return PHY_INTERFACE_MODE_RGMII_ID; - if (strcasecmp(interface_type, "rtbi") == 0) + if (strcasecmp(phy_connection_type, "rtbi") == 0) return PHY_INTERFACE_MODE_RTBI; return PHY_INTERFACE_MODE_MII; @@ -3819,29 +3819,21 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->phy_address = *prop; /* get the phy interface type, or default to MII */ - prop = of_get_property(np, "interface-type", NULL); + prop = of_get_property(np, "phy-connection-type", NULL); if (!prop) { /* handle interface property present in old trees */ prop = of_get_property(phy, "interface", NULL); - if (prop != NULL) + if (prop != NULL) { phy_interface = enet_to_phy_interface[*prop]; - else + max_speed = enet_to_speed[*prop]; + } else phy_interface = PHY_INTERFACE_MODE_MII; } else { phy_interface = to_phy_interface((const char *)prop); } - /* get speed, or derive from interface */ - prop = of_get_property(np, "max-speed", NULL); - if (!prop) { - /* handle interface property present in old trees */ - prop = of_get_property(phy, "interface", NULL); - if (prop != NULL) - max_speed = enet_to_speed[*prop]; - } else { - max_speed = *prop; - } - if (!max_speed) { + /* get speed, or derive from PHY interface */ + if (max_speed == 0) switch (phy_interface) { case PHY_INTERFACE_MODE_GMII: case PHY_INTERFACE_MODE_RGMII: @@ -3854,9 +3846,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma max_speed = SPEED_100; break; } - } if (max_speed == SPEED_1000) { + /* configure muram FIFOs for gigabit operation */ ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT; ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT; ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT; diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 27a1ef3b7b0..f96966d4bcc 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -1,12 +1,13 @@ /* * drivers/net/ucc_geth_mii.c * - * Gianfar Ethernet Driver -- MIIM bus implementation - * Provides Bus interface for MIIM regs + * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation + * Provides Bus interface for MII Management regs in the UCC register space * - * Author: Li Yang + * Copyright (C) 2007 Freescale Semiconductor, Inc. * - * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. + * Authors: Li Yang <leoli@freescale.com> + * Kim Phillips <kim.phillips@freescale.com> * * 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 diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h index 98430fe0bfc..d8343703991 100644 --- a/drivers/net/ucc_geth_mii.h +++ b/drivers/net/ucc_geth_mii.h @@ -1,13 +1,13 @@ /* * drivers/net/ucc_geth_mii.h * - * Gianfar Ethernet Driver -- MII Management Bus Implementation - * Driver for the MDIO bus controller in the Gianfar register space + * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation + * Provides Bus interface for MII Management regs in the UCC register space * - * Author: Andy Fleming - * Maintainer: Kumar Gala + * Copyright (C) 2007 Freescale Semiconductor, Inc. * - * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. + * Authors: Li Yang <leoli@freescale.com> + * Kim Phillips <kim.phillips@freescale.com> * * 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 diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index 6c5be3ff578..df076064a3e 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c @@ -129,8 +129,9 @@ struct kobj_type ktype_dlpar_io = { }; struct kset dlpar_io_kset = { - .subsys = &pci_hotplug_slots_subsys, - .kobj = {.name = DLPAR_KOBJ_NAME, .ktype=&ktype_dlpar_io,}, + .kobj = {.name = DLPAR_KOBJ_NAME, + .ktype = &ktype_dlpar_io, + .parent = &pci_hotplug_slots_subsys.kobj}, .ktype = &ktype_dlpar_io, }; diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h index b291b2f7295..8ee73d3f316 100644 --- a/include/asm-m32r/system.h +++ b/include/asm-m32r/system.h @@ -10,6 +10,7 @@ * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> */ +#include <linux/compiler.h> #include <asm/assembler.h> #ifdef __KERNEL__ @@ -154,7 +155,7 @@ extern void __xchg_called_with_bad_pointer(void); #define DCACHE_CLEAR(reg0, reg1, addr) #endif /* CONFIG_CHIP_M32700_TS1 */ -static inline unsigned long +static __always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) { unsigned long flags; diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h index 5efe906c59f..c7c0f059cdc 100644 --- a/include/asm-sh64/dma-mapping.h +++ b/include/asm-sh64/dma-mapping.h @@ -35,6 +35,10 @@ static inline void dma_free_coherent(struct device *dev, size_t size, consistent_free(NULL, size, vaddr, dma_handle); } +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) +#define dma_is_consistent(d, h) (1) + static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) { @@ -49,7 +53,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, if (dev->bus == &pci_bus_type) return virt_to_bus(ptr); #endif - dma_cache_sync(ptr, size, dir); + dma_cache_sync(dev, ptr, size, dir); return virt_to_bus(ptr); } @@ -63,7 +67,7 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, for (i = 0; i < nents; i++) { #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) - dma_cache_sync(page_address(sg[i].page) + sg[i].offset, + dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset, sg[i].length, dir); #endif sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; @@ -94,7 +98,7 @@ static inline void dma_sync_single(struct device *dev, dma_addr_t dma_handle, if (dev->bus == &pci_bus_type) return; #endif - dma_cache_sync(bus_to_virt(dma_handle), size, dir); + dma_cache_sync(dev, bus_to_virt(dma_handle), size, dir); } static inline void dma_sync_single_range(struct device *dev, @@ -106,7 +110,7 @@ static inline void dma_sync_single_range(struct device *dev, if (dev->bus == &pci_bus_type) return; #endif - dma_cache_sync(bus_to_virt(dma_handle) + offset, size, dir); + dma_cache_sync(dev, bus_to_virt(dma_handle) + offset, size, dir); } static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, @@ -116,7 +120,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, for (i = 0; i < nelems; i++) { #if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) - dma_cache_sync(page_address(sg[i].page) + sg[i].offset, + dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset, sg[i].length, dir); #endif sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; diff --git a/include/asm-sh64/irq_regs.h b/include/asm-sh64/irq_regs.h new file mode 100644 index 00000000000..3dd9c0b7027 --- /dev/null +++ b/include/asm-sh64/irq_regs.h @@ -0,0 +1 @@ +#include <asm-generic/irq_regs.h> diff --git a/include/asm-sh64/pgalloc.h b/include/asm-sh64/pgalloc.h index cb803e56cb6..6eccab770a6 100644 --- a/include/asm-sh64/pgalloc.h +++ b/include/asm-sh64/pgalloc.h @@ -14,13 +14,9 @@ * */ -#include <linux/threads.h> #include <linux/mm.h> - -#define pgd_quicklist (current_cpu_data.pgd_quick) -#define pmd_quicklist (current_cpu_data.pmd_quick) -#define pte_quicklist (current_cpu_data.pte_quick) -#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) +#include <linux/quicklist.h> +#include <asm/page.h> static inline void pgd_init(unsigned long page) { @@ -45,84 +41,37 @@ static inline pgd_t *get_pgd_slow(void) return ret; } -static inline pgd_t *get_pgd_fast(void) -{ - unsigned long *ret; - - if ((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } else - ret = (unsigned long *)get_pgd_slow(); - - if (ret) { - memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - } - return (pgd_t *)ret; -} - -static inline void free_pgd_fast(pgd_t *pgd) -{ - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; -} - -static inline void free_pgd_slow(pgd_t *pgd) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - kfree((void *)pgd); + return quicklist_alloc(0, GFP_KERNEL, NULL); } -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); -extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted); - -static inline pte_t *get_pte_fast(void) +static inline void pgd_free(pgd_t *pgd) { - unsigned long *ret; - - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; + quicklist_free(0, NULL, pgd); } -static inline void free_pte_fast(pte_t *pte) +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) { - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; + void *pg = quicklist_alloc(0, GFP_KERNEL, NULL); + return pg ? virt_to_page(pg) : NULL; } static inline void pte_free_kernel(pte_t *pte) { - free_page((unsigned long)pte); + quicklist_free(0, NULL, pte); } static inline void pte_free(struct page *pte) { - __free_page(pte); + quicklist_free_page(0, NULL, pte); } static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - pte_t *pte; - - pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT|__GFP_ZERO); - - return pte; -} - -static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) -{ - struct page *pte; - - pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); - - return pte; + return quicklist_alloc(0, GFP_KERNEL, NULL); } #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) @@ -142,31 +91,23 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long add #elif defined(CONFIG_SH64_PGTABLE_3_LEVEL) -static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { - pmd_t *pmd; - pmd = (pmd_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); - return pmd; + return quicklist_alloc(0, GFP_KERNEL, NULL); } -static __inline__ void pmd_free(pmd_t *pmd) +static inline void pmd_free(pmd_t *pmd) { - free_page((unsigned long) pmd); + quicklist_free(0, NULL, pmd); } -#define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) +#define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) #define __pmd_free_tlb(tlb,pmd) pmd_free(pmd) #else #error "No defined page table size" #endif -#define check_pgt_cache() do { } while (0) -#define pgd_free(pgd) free_pgd_slow(pgd) -#define pgd_alloc(mm) get_pgd_fast() - -extern int do_check_pgt_cache(int, int); - #define pmd_populate_kernel(mm, pmd, pte) \ set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) (pte))) @@ -176,4 +117,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) page_address (pte))); } +static inline void check_pgt_cache(void) +{ + quicklist_trim(0, NULL, 25, 16); +} + #endif /* __ASM_SH64_PGALLOC_H */ diff --git a/include/asm-sh64/sci.h b/include/asm-sh64/sci.h new file mode 100644 index 00000000000..793c568b782 --- /dev/null +++ b/include/asm-sh64/sci.h @@ -0,0 +1 @@ +#include <asm-sh/sci.h> diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h index 1f825cb163c..f6d5117c53a 100644 --- a/include/asm-sh64/thread_info.h +++ b/include/asm-sh64/thread_info.h @@ -78,7 +78,13 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_MEMDIE 4 +#define TIF_RESTORE_SIGMASK 5 /* Restore signal mask in do_signal */ +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_MEMDIE (1 << TIF_MEMDIE) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #endif /* __KERNEL__ */ diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h index 1f38a7aacaa..ea3adc600b4 100644 --- a/include/asm-sh64/unistd.h +++ b/include/asm-sh64/unistd.h @@ -9,14 +9,14 @@ * include/asm-sh64/unistd.h * * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2007 Paul Mundt * Copyright (C) 2004 Sean McGoogan * * This file contains the system call numbers. * */ -#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_restart_syscall 0 #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 @@ -196,8 +196,8 @@ #define __NR_rt_sigtimedwait 177 #define __NR_rt_sigqueueinfo 178 #define __NR_rt_sigsuspend 179 -#define __NR_pread 180 -#define __NR_pwrite 181 +#define __NR_pread64 180 +#define __NR_pwrite64 181 #define __NR_chown 182 #define __NR_getcwd 183 #define __NR_capget 184 @@ -343,10 +343,41 @@ #define __NR_inotify_init 318 #define __NR_inotify_add_watch 319 #define __NR_inotify_rm_watch 320 +/* 321 is unused */ +#define __NR_migrate_pages 322 +#define __NR_openat 323 +#define __NR_mkdirat 324 +#define __NR_mknodat 325 +#define __NR_fchownat 326 +#define __NR_futimesat 327 +#define __NR_fstatat64 328 +#define __NR_unlinkat 329 +#define __NR_renameat 330 +#define __NR_linkat 331 +#define __NR_symlinkat 332 +#define __NR_readlinkat 333 +#define __NR_fchmodat 334 +#define __NR_faccessat 335 +#define __NR_pselect6 336 +#define __NR_ppoll 337 +#define __NR_unshare 338 +#define __NR_set_robust_list 339 +#define __NR_get_robust_list 340 +#define __NR_splice 341 +#define __NR_sync_file_range 342 +#define __NR_tee 343 +#define __NR_vmsplice 344 +#define __NR_move_pages 345 +#define __NR_getcpu 346 +#define __NR_epoll_pwait 347 +#define __NR_utimensat 348 +#define __NR_signalfd 349 +#define __NR_timerfd 350 +#define __NR_eventfd 351 -#ifdef __KERNEL__ +#ifdef __KERNEL__ -#define NR_syscalls 321 +#define NR_syscalls 352 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/linux/ide.h b/include/linux/ide.h index df4e6a51031..07aba87d369 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1281,7 +1281,6 @@ struct drive_list_entry { int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); -int ide_use_dma(ide_drive_t *); u8 ide_max_dma_mode(ide_drive_t *); int ide_tune_dma(ide_drive_t *); void ide_dma_off(ide_drive_t *); @@ -1309,7 +1308,6 @@ extern int __ide_dma_timeout(ide_drive_t *); #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ #else -static inline int ide_use_dma(ide_drive_t *drive) { return 0; } static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } static inline int ide_tune_dma(ide_drive_t *drive) { return 0; } static inline void ide_dma_off(ide_drive_t *drive) { ; } @@ -1357,7 +1355,6 @@ static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data) /* ide-lib.c */ u8 ide_rate_filter(ide_drive_t *, u8); -extern int ide_dma_enable(ide_drive_t *drive); extern char *ide_xfer_verbose(u8 xfer_rate); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 6c61263ff96..74cc0fc6bb8 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -311,6 +311,7 @@ int audit_match_class(int class, unsigned syscall) return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall); } +#ifdef CONFIG_AUDITSYSCALL static inline int audit_match_class_bits(int class, u32 *mask) { int i; @@ -347,6 +348,7 @@ static int audit_match_signal(struct audit_entry *entry) return 1; } } +#endif /* Common user-space to kernel rule translation. */ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) diff --git a/mm/Kconfig b/mm/Kconfig index a17da8bafe6..8ac412b45f1 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -166,5 +166,5 @@ config ZONE_DMA_FLAG config NR_QUICK int depends on QUICKLIST - default "2" if SUPERH + default "2" if (SUPERH && !SUPERH64) default "1" |