a) board_time_init - a function pointer. Invoked at the beginnig of
time_init(). It is optional.
1. (optional) set up RTC routines
- 2. (optional) calibrate and set the mips_counter_frequency
+ 2. (optional) calibrate and set the mips_hpt_frequency
b) plat_timer_setup - a function pointer. Invoked at the end of time_init()
1. (optional) over-ride any decisions made in time_init()
c) (optional) board-specific RTC routines.
- d) (optional) mips_counter_frequency - It must be definied if the board
+ d) (optional) mips_hpt_frequency - It must be definied if the board
is using CPU counter for timer interrupt or it is using fixed rate
gettimeoffset().
or use an exnternal timer?
In order to use CPU counter register as the timer interrupt source, you
- must know the counter speed (mips_counter_frequency). It is usually the
+ must know the counter speed (mips_hpt_frequency). It is usually the
same as the CPU speed or an integral divisor of it.
d) decide on whether you want to use high-level or low-level timer
if needed.
board_time_init() -
- a) (optional) set up RTC routines,
- b) (optional) calibrate and set the mips_counter_frequency
+ a) (optional) set up RTC routines,
+ b) (optional) calibrate and set the mips_hpt_frequency
(only needed if you intended to use fixed_rate_gettimeoffset
or use cpu counter as timer interrupt source)
+#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <fcntl.h>
int main(int argc, const char *argv[]) {
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 19
-EXTRAVERSION =-rc2
+EXTRAVERSION =-rc3
NAME=Avast! A bilge rat!
# *DOCUMENTATION*
ifdef CONFIG_UNWIND_INFO
CFLAGS += -fasynchronous-unwind-tables
+LDFLAGS_vmlinux += --eh-frame-hdr
endif
ifdef CONFIG_DEBUG_INFO
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
#
# USB-based Watchdog Cards
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
#
# USB-based Watchdog Cards
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
#
# USB-based Watchdog Cards
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
#
# USB-based Watchdog Cards
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
# CONFIG_NVRAM is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91_WATCHDOG=y
+CONFIG_AT91RM9200_WATCHDOG=y
#
# USB-based Watchdog Cards
if (ixdp2x00_master_npu()) {
dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
pci_remove_bus_device(dev);
- pci_dev_put(dev)
+ pci_dev_put(dev);
} else {
dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN);
pci_remove_bus_device(dev);
- pci_dev_put(dev)
+ pci_dev_put(dev);
ixdp2x00_slave_pci_postinit();
}
bool "LPD7A400 Card Engine"
select ARCH_LH7A400
# select IDE_POLL
- select HAS_TOUCHSCREEN_ADS7843_LH7
+# select HAS_TOUCHSCREEN_ADS7843_LH7
help
Say Y here if you are using Logic Product Development's
LPD7A400 CardEngine. For the time being, the LPD7A400 and
bool "LPD7A404 Card Engine"
select ARCH_LH7A404
# select IDE_POLL
- select HAS_TOUCHSCREEN_ADC_LH7
+# select HAS_TOUCHSCREEN_ADC_LH7
help
Say Y here if you are using Logic Product Development's
LPD7A404 CardEngine. For the time being, the LPD7A400 and
# Default target when executing plain make
.PHONY: all
-all: uImage vmlinux.elf linux.lst
+all: uImage vmlinux.elf
KBUILD_DEFCONFIG := atstk1002_defconfig
CFLAGS += $(cpuflags-y)
AFLAGS += $(cpuflags-y)
-CHECKFLAGS += -D__avr32__
-
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+CHECKFLAGS += -D__avr32__ -D__BIG_ENDIAN
head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o
head-y += arch/avr32/kernel/head.o
core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
core-y += arch/avr32/kernel/
core-y += arch/avr32/mm/
-libs-y += arch/avr32/lib/ #$(LIBGCC)
+libs-y += arch/avr32/lib/
archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap
archprepare: include/asm-avr32/.arch
+CLEAN_FILES += include/asm-avr32/.arch include/asm-avr32/arch
+
BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec
.PHONY: $(BOOT_TARGETS) install
install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
-linux.s: vmlinux
+vmlinux.s: vmlinux
$(call if_changed,disasm)
-linux.lst: vmlinux
+vmlinux.lst: vmlinux
$(call if_changed,listing)
+CLEAN_FILES += vmlinux.s vmlinux.lst
+
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
define archhelp
@echo '* vmlinux.elf - ELF image with load address 0'
@echo ' vmlinux.cso - PathFinder CSO image'
- @echo ' uImage - Create a bootable image for U-Boot'
+ @echo '* uImage - Create a bootable image for U-Boot'
endef
--change-section-lma .data-0x80000000 \
--change-section-lma .init-0x80000000 \
--change-section-lma .bss-0x80000000 \
- --change-section-lma .initrd-0x80000000 \
--change-section-lma __param-0x80000000 \
--change-section-lma __ksymtab-0x80000000 \
--change-section-lma __ksymtab_gpl-0x80000000 \
--change-section-lma __kcrctab-0x80000000 \
--change-section-lma __kcrctab_gpl-0x80000000 \
--change-section-lma __ksymtab_strings-0x80000000 \
- --change-section-lma .got-0x80000000 \
--set-start 0xa0000000
$(obj)/vmlinux.elf: vmlinux FORCE
$(call if_changed,objcopy)
sh $(srctree)/install-kernel.sh $<
# Generated files to be removed upon make clean
-clean-files := vmlinux* uImage uImage.srec
+clean-files := vmlinux.elf vmlinux.bin vmlinux.gz uImage uImage.srec
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Tue Jul 11 12:41:36 2006
+# Linux kernel version: 2.6.19-rc2
+# Fri Oct 20 11:52:37 2006
#
CONFIG_AVR32=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
-# CONFIG_SYSVIPC is not set
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
# CONFIG_IKCONFIG is not set
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_TASK_XACCT is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_BUG=y
CONFIG_ELF_CORE=y
# CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
CONFIG_SHMEM=y
-# CONFIG_SLAB is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=1
-CONFIG_SLOB=y
+# CONFIG_SLOB is not set
#
# Loadable module support
#
# Block layer
#
+CONFIG_BLOCK=y
# CONFIG_BLK_DEV_IO_TRACE is not set
#
# CONFIG_INET_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
#
# Memory Technology Devices (MTD)
#
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
#
# Parallel port support
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
#
# ATA/ATAPI/MFM/RLL support
#
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
#
# Multi-device support (RAID and LVM)
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
+# CONFIG_NET_ETHERNET is not set
#
# Ethernet (1000 Mbit)
CONFIG_PPP_ASYNC=m
# CONFIG_PPP_SYNC_TTY is not set
CONFIG_PPP_DEFLATE=m
-# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_BSDCOMP=m
# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=m
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
#
# SPI support
#
-CONFIG_SPI=y
-# CONFIG_SPI_DEBUG is not set
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-CONFIG_SPI_ATMEL=m
-# CONFIG_SPI_BITBANG is not set
-
-#
-# SPI Protocol Masters
-#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
# CONFIG_HWMON is not set
# CONFIG_HWMON_VID is not set
-#
-# Misc devices
-#
-
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
# Graphics support
#
# CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB=m
-CONFIG_FB_CFB_FILLRECT=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_SIDSA=m
-CONFIG_FB_SIDSA_DEFAULT_BPP=24
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_LCD_DEVICE=y
-CONFIG_LCD_LTV350QV=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# File systems
#
-CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS=m
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
CONFIG_MINIX_FS=m
-CONFIG_ROMFS_FS=m
-# CONFIG_INOTIFY is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
CONFIG_CONFIGFS_FS=m
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
#
# Network File Systems
#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
CONFIG_NLS_CODEPAGE_437=m
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS 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_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_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_KPROBES=y
+# CONFIG_KPROBES is not set
#
# Security options
#
# CONFIG_CRYPTO is not set
-#
-# Hardware crypto devices
-#
-
#
# Library routines
#
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
-CONFIG_CRC32=m
+CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/io.h>
#include <linux/module.h>
#include <asm/checksum.h>
EXPORT_SYMBOL(find_first_bit);
EXPORT_SYMBOL(find_next_bit);
EXPORT_SYMBOL(generic_find_next_zero_le_bit);
+
+/* I/O primitives (lib/io-*.S) */
+EXPORT_SYMBOL(__raw_readsb);
+EXPORT_SYMBOL(__raw_readsw);
+EXPORT_SYMBOL(__raw_readsl);
+EXPORT_SYMBOL(__raw_writesb);
+EXPORT_SYMBOL(__raw_writesw);
+EXPORT_SYMBOL(__raw_writesl);
void *addr = (void *)regs->pc;
int ret = 0;
- pr_debug("kprobe_handler: kprobe_running=%d\n",
+ pr_debug("kprobe_handler: kprobe_running=%p\n",
kprobe_running());
/*
* value of PC. Just subtract the value of
* GOT, and we're done.
*/
- pr_debug("GOTPC: PC=0x%lx, got_offset=0x%lx, core=0x%p\n",
+ pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n",
relocation, module->arch.got_offset,
module->module_core);
relocation -= ((unsigned long)module->module_core
&& (relocation & 0xffff0000) != 0xffff0000)
return reloc_overflow(module, "R_AVR32_GOT16S",
relocation);
- pr_debug("GOT reloc @ 0x%lx -> %lu\n",
+ pr_debug("GOT reloc @ 0x%x -> %u\n",
rel->r_offset, relocation);
value = *location;
value = ((value & 0xffff0000)
unsigned long tmp;
int ret;
- pr_debug("arch_ptrace(%ld, %ld, %#lx, %#lx)\n",
+ pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n",
request, child->pid, addr, data);
pr_debug("ptrace: Enabling monitor mode...\n");
lib-y += delay.o memset.o memcpy.o findbit.o
lib-y += csum_partial.o csum_partial_copy_generic.o
lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o
+lib-y += io-readsb.o io-writesb.o
lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o
--- /dev/null
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .text
+.Lnot_word_aligned:
+1: ld.ub r8, r12[0]
+ sub r10, 1
+ st.b r11++, r8
+ reteq r12
+ tst r11, r9
+ brne 1b
+
+ /* fall through */
+
+ .global __raw_readsb
+ .type __raw_readsb,@function
+__raw_readsb:
+ cp.w r10, 0
+ mov r9, 3
+ reteq r12
+
+ tst r11, r9
+ brne .Lnot_word_aligned
+
+ sub r10, 4
+ brlt 2f
+
+1: ldins.b r8:t, r12[0]
+ ldins.b r8:u, r12[0]
+ ldins.b r8:l, r12[0]
+ ldins.b r8:b, r12[0]
+ st.w r11++, r8
+ sub r10, 4
+ brge 1b
+
+2: sub r10, -4
+ reteq r12
+
+3: ld.uh r8, r12[0]
+ sub r10, 1
+ st.b r11++, r8
+ brne 3b
--- /dev/null
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .text
+.Lnot_word_aligned:
+1: ld.ub r8, r11++
+ sub r10, 1
+ st.b r12[0], r8
+ reteq r12
+ tst r11, r9
+ brne 1b
+
+ /* fall through */
+
+ .global __raw_writesb
+ .type __raw_writesb,@function
+__raw_writesb:
+ cp.w r10, 0
+ mov r9, 3
+ reteq r12
+
+ tst r11, r9
+ brne .Lnot_word_aligned
+
+ sub r10, 4
+ brlt 2f
+
+1: ld.w r8, r11++
+ bfextu r9, r8, 24, 8
+ st.b r12[0], r9
+ bfextu r9, r8, 16, 8
+ st.b r12[0], r9
+ bfextu r9, r8, 8, 8
+ st.b r12[0], r9
+ st.b r12[0], r8
+ sub r10, 4
+ brge 1b
+
+2: sub r10, -4
+ reteq r12
+
+3: ld.ub r8, r11++
+ sub r10, 1
+ st.b r12[0], r8
+ brne 3b
+
+ retal r12
/* Register access macros */
#define hsmc_readl(port,reg) \
- readl((port)->regs + HSMC_##reg)
+ __raw_readl((port)->regs + HSMC_##reg)
#define hsmc_writel(port,reg,value) \
- writel((value), (port)->regs + HSMC_##reg)
+ __raw_writel((value), (port)->regs + HSMC_##reg)
#endif /* __ASM_AVR32_HSMC_H__ */
#define INTC_MKBF(name, value) (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET)
#define INTC_GETBF(name, value) (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1))
-#define intc_readl(port,reg) readl((port)->regs + INTC_##reg)
-#define intc_writel(port,reg,value) writel((value), (port)->regs + INTC_##reg)
+#define intc_readl(port,reg) \
+ __raw_readl((port)->regs + INTC_##reg)
+#define intc_writel(port,reg,value) \
+ __raw_writel((value), (port)->regs + INTC_##reg)
#endif /* __ASM_AVR32_PERIHP_INTC_H__ */
#define PIO_BFINS(name,value,old) (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value))
/* Register access macros */
-#define pio_readl(port,reg) readl((port)->regs + PIO_##reg)
-#define pio_writel(port,reg,value) writel((value), (port)->regs + PIO_##reg)
+#define pio_readl(port,reg) \
+ __raw_readl((port)->regs + PIO_##reg)
+#define pio_writel(port,reg,value) \
+ __raw_writel((value), (port)->regs + PIO_##reg)
void at32_init_pio(struct platform_device *pdev);
#define SM_BFINS(name,value,old) (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value))
/* Register access macros */
-#define sm_readl(port,reg) readl((port)->regs + SM_##reg)
-#define sm_writel(port,reg,value) writel((value), (port)->regs + SM_##reg)
+#define sm_readl(port,reg) \
+ __raw_readl((port)->regs + SM_##reg)
+#define sm_writel(port,reg,value) \
+ __raw_writel((value), (port)->regs + SM_##reg)
#endif /* __ASM_AVR32_SM_H__ */
if (mem_ramdisk) {
#ifdef CONFIG_BLK_DEV_INITRD
- initrd_start = __va(mem_ramdisk->addr);
+ initrd_start = (unsigned long)__va(mem_ramdisk->addr);
initrd_end = initrd_start + mem_ramdisk->size;
print_memory_map("RAMDISK images", mem_ramdisk);
if ((unsigned long)addr >= P4SEG)
return;
+ if (PXSEG(addr) == P2SEG)
+ return;
p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
if (unlikely(!p)) {
# temporary until string.h is fixed
cflags-y += -ffreestanding
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
# a lot more stack due to the lack of sharing of stacklots:
CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
-cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
CFLAGS += $(cflags-y)
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Thu Oct 5 13:04:53 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:56 2006
#
CONFIG_X86_32=y
CONFIG_GENERIC_TIME=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
#
# ATA/ATAPI/MFM/RLL support
#
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
# CONFIG_HWMON is not set
# CONFIG_HWMON_VID is not set
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-# CONFIG_TIFM_CORE is not set
-
#
# Multimedia devices
#
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB Imaging devices
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_TEST is not set
#
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# 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
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
#
# CD-ROM/DVD Filesystems
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
#
# Partition Types
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
-#
-# Distributed Lock Manager
-#
-
#
# Instrumentation Support
#
CONFIG_UNWIND_INFO=y
CONFIG_STACK_UNWIND=y
# CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
CONFIG_EARLY_PRINTK=y
movl %eax,%gs
lldt %ax
cld # gcc2 wants the direction flag cleared at all times
- pushl %eax # fake return address
+ pushl $0 # fake return address for unwinder
#ifdef CONFIG_SMP
movb ready, %cl
movb $1, ready
int cpu;
/* Enable NMI watchdog for newer systems.
- Actually it should be safe for most systems before 2004 too except
- for some IBM systems that corrupt registers when NMI happens
- during SMM. Unfortunately we don't have more exact information
- on these and use this coarse check. */
- if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
+ Probably safe on most older systems too, but let's be careful.
+ IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
+ which hangs the system. Disable watchdog for all thinkpads */
+ if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
+ !dmi_name_in_vendors("ThinkPad"))
nmi_watchdog = NMI_LOCAL_APIC;
if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;
- int err;
memset(®s, 0, sizeof(regs));
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
/* Ok, create the new process.. */
- err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
- if (err == 0) /* terminate kernel stack */
- task_pt_regs(current)->eip = 0;
- return err;
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);
}
/*
- * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
*/
static unsigned int __init estimate_cpu_frequency(void)
{
/*
- * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
*/
static unsigned int __init estimate_cpu_frequency(void)
{
#include <asm/cachectl.h>
#include <asm/cpu.h>
#include <asm/dma.h>
+#include <asm/kmap_types.h>
#include <asm/mmu_context.h>
#include <asm/sections.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlb.h>
+#include <asm/fixmap.h>
+
+/* Atomicity and interruptability */
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#include <asm/mipsmtregs.h>
+
+#define ENTER_CRITICAL(flags) \
+ { \
+ unsigned int mvpflags; \
+ local_irq_save(flags);\
+ mvpflags = dvpe()
+#define EXIT_CRITICAL(flags) \
+ evpe(mvpflags); \
+ local_irq_restore(flags); \
+ }
+#else
+
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
+
+#endif /* CONFIG_MIPS_MT_SMTC */
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
return 1UL << order;
}
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
+/*
+ * These are almost like kmap_atomic / kunmap_atmic except they take an
+ * additional address argument as the hint.
+ */
#define kmap_get_fixmap_pte(vaddr) \
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+#ifdef CONFIG_MIPS_MT_SMTC
+static pte_t *kmap_coherent_pte;
+static void __init kmap_coherent_init(void)
+{
+ unsigned long vaddr;
+
+ /* cache the first coherent kmap pte */
+ vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+ kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+#else
+static inline void kmap_coherent_init(void) {}
+#endif
+
+static inline void *kmap_coherent(struct page *page, unsigned long addr)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr, flags, entrylo;
+ unsigned long old_ctx;
+ pte_t pte;
+ int tlbidx;
+
+ inc_preempt_count();
+ idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
+#ifdef CONFIG_MIPS_MT_SMTC
+ idx += FIX_N_COLOURS * smp_processor_id();
+#endif
+ vaddr = __fix_to_virt(FIX_CMAP_END - idx);
+ pte = mk_pte(page, PAGE_KERNEL);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+ entrylo = pte.pte_high;
+#else
+ entrylo = pte_val(pte) >> 6;
+#endif
+
+ ENTER_CRITICAL(flags);
+ old_ctx = read_c0_entryhi();
+ write_c0_entryhi(vaddr & (PAGE_MASK << 1));
+ write_c0_entrylo0(entrylo);
+ write_c0_entrylo1(entrylo);
+#ifdef CONFIG_MIPS_MT_SMTC
+ set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
+ /* preload TLB instead of local_flush_tlb_one() */
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ tlbidx = read_c0_index();
+ mtc0_tlbw_hazard();
+ if (tlbidx < 0)
+ tlb_write_random();
+ else
+ tlb_write_indexed();
+#else
+ tlbidx = read_c0_wired();
+ write_c0_wired(tlbidx + 1);
+ write_c0_index(tlbidx);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+#endif
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ EXIT_CRITICAL(flags);
+
+ return (void*) vaddr;
+}
+
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+static inline void kunmap_coherent(struct page *page)
+{
+#ifndef CONFIG_MIPS_MT_SMTC
+ unsigned int wired;
+ unsigned long flags, old_ctx;
+
+ ENTER_CRITICAL(flags);
+ old_ctx = read_c0_entryhi();
+ wired = read_c0_wired() - 1;
+ write_c0_wired(wired);
+ write_c0_index(wired);
+ write_c0_entryhi(UNIQUE_ENTRYHI(wired));
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ EXIT_CRITICAL(flags);
+#endif
+ dec_preempt_count();
+ preempt_check_resched();
+}
+
+void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases) {
+ void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(vto, src, len);
+ kunmap_coherent(page);
+ } else
+ memcpy(dst, src, len);
+ if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+EXPORT_SYMBOL(copy_to_user_page);
+
+void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases) {
+ void *vfrom =
+ kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(dst, vfrom, len);
+ kunmap_coherent(page);
+ } else
+ memcpy(dst, src, len);
+}
+
+EXPORT_SYMBOL(copy_from_user_page);
+
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
static void __init kmap_init(void)
{
unsigned long kmap_vstart;
kmap_prot = PAGE_KERNEL;
}
+#endif /* CONFIG_HIGHMEM */
-#ifdef CONFIG_32BIT
void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- set_pmd(pmd, __pmd(pte));
+ set_pmd(pmd, __pmd((unsigned long)pte));
if (pte != pte_offset_kernel(pmd, 0))
BUG();
}
}
j = 0;
}
+#endif
}
-#endif /* CONFIG_32BIT */
-#endif /* CONFIG_HIGHMEM */
#ifndef CONFIG_NEED_MULTIPLE_NODES
extern void pagetable_init(void);
#ifdef CONFIG_HIGHMEM
kmap_init();
#endif
+ kmap_coherent_init();
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
void __init pagetable_init(void)
{
-#ifdef CONFIG_HIGHMEM
unsigned long vaddr;
- pgd_t *pgd, *pgd_base;
+ pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+ pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
pgd_init((unsigned long)swapper_pg_dir
+ sizeof(pgd_t) * USER_PTRS_PER_PGD);
-#ifdef CONFIG_HIGHMEM
pgd_base = swapper_pg_dir;
/*
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, 0, pgd_base);
+#ifdef CONFIG_HIGHMEM
/*
* Permanent kmaps:
*/
*/
#include <linux/init.h>
#include <linux/mm.h>
+#include <asm/fixmap.h>
#include <asm/pgtable.h>
void pgd_init(unsigned long page)
void __init pagetable_init(void)
{
+ unsigned long vaddr;
+ pgd_t *pgd_base;
+
/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+
+ pgd_base = swapper_pg_dir;
+ /*
+ * Fixed mappings:
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+ fixrange_init(vaddr, 0, pgd_base);
}
def_bool y
depends on MEMORY_HOTPLUG
+# Some NUMA nodes have memory ranges that span
+# other nodes. Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node. See memmap_init_zone()
+# for details.
+config NODES_SPAN_OTHER_NODES
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
config PPC_64K_PAGES
bool "64k page size"
depends on PPC64
quiet_cmd_wrap = WRAP $@
cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux
quiet_cmd_wrap_initrd = WRAP $@
- cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
+ cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
-i $(obj)/ramdisk.image.gz vmlinux
$(obj)/zImage.chrp: vmlinux $(wrapperbits)
CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_INET6_TUNNEL=m
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_SIT is not set
CONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_SUBTREES is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
#
# ATA/ATAPI/MFM/RLL support
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
# CONFIG_HWMON is not set
# CONFIG_HWMON_VID is not set
-#
-# Misc devices
-#
-
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
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
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_MIGRATION=y
CONFIG_RESOURCES_64BIT=y
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
# CONFIG_PPC_64K_PAGES is not set
CONFIG_SCHED_SMT=y
CONFIG_PROC_DEVICETREE=y
#include <asm/oprofile_impl.h>
#include <asm/cputable.h>
+#include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */
struct cpu_spec* cur_cpu_spec = NULL;
EXPORT_SYMBOL(cur_cpu_spec);
#define PPC_FEATURE_SPE_COMP 0
#endif
-struct cpu_spec cpu_specs[] = {
+static struct cpu_spec cpu_specs[] = {
#ifdef CONFIG_PPC64
{ /* Power3 */
.pvr_mask = 0xffff0000,
.oprofile_type = PPC_OPROFILE_POWER4,
.platform = "ppc970",
},
+ { /* PPC970GX */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00450000,
+ .cpu_name = "PPC970GX",
+ .cpu_features = CPU_FTRS_PPC970,
+ .cpu_user_features = COMMON_USER_POWER4 |
+ PPC_FEATURE_HAS_ALTIVEC_COMP,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 8,
+ .cpu_setup = __setup_cpu_ppc970,
+ .oprofile_cpu_type = "ppc64/970",
+ .oprofile_type = PPC_OPROFILE_POWER4,
+ .platform = "ppc970",
+ },
{ /* Power5 GR */
.pvr_mask = 0xffff0000,
.pvr_value = 0x003a0000,
#endif /* !CLASSIC_PPC */
#endif /* CONFIG_PPC32 */
};
+
+struct cpu_spec *identify_cpu(unsigned long offset)
+{
+ struct cpu_spec *s = cpu_specs;
+ struct cpu_spec **cur = &cur_cpu_spec;
+ unsigned int pvr = mfspr(SPRN_PVR);
+ int i;
+
+ s = PTRRELOC(s);
+ cur = PTRRELOC(cur);
+
+ if (*cur != NULL)
+ return PTRRELOC(*cur);
+
+ for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
+ if ((pvr & s->pvr_mask) == s->pvr_value) {
+ *cur = cpu_specs + i;
+#ifdef CONFIG_PPC64
+ /* ppc64 expects identify_cpu to also call setup_cpu
+ * for that processor. I will consolidate that at a
+ * later time, for now, just use our friend #ifdef.
+ * we also don't need to PTRRELOC the function pointer
+ * on ppc64 as we are running at 0 in real mode.
+ */
+ if (s->cpu_setup) {
+ s->cpu_setup(offset, s);
+ }
+#endif /* CONFIG_PPC64 */
+ return s;
+ }
+ BUG();
+ return NULL;
+}
+
+void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
+{
+ struct fixup_entry {
+ unsigned long mask;
+ unsigned long value;
+ long start_off;
+ long end_off;
+ } *fcur, *fend;
+
+ fcur = fixup_start;
+ fend = fixup_end;
+
+ for (; fcur < fend; fcur++) {
+ unsigned int *pstart, *pend, *p;
+
+ if ((value & fcur->mask) == fcur->value)
+ continue;
+
+ /* These PTRRELOCs will disappear once the new scheme for
+ * modules and vdso is implemented
+ */
+ pstart = ((unsigned int *)fcur) + (fcur->start_off / 4);
+ pend = ((unsigned int *)fcur) + (fcur->end_off / 4);
+
+ for (p = pstart; p < pend; p++) {
+ *p = 0x60000000u;
+ asm volatile ("dcbst 0, %0" : : "r" (p));
+ }
+ asm volatile ("sync" : : : "memory");
+ for (p = pstart; p < pend; p++)
+ asm volatile ("icbi 0,%0" : : "r" (p));
+ asm volatile ("sync; isync" : : : "memory");
+ }
+}
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
- LOAD_REG_IMMEDIATE(r3,cpu_specs)
- LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
- li r5,0
- bl .identify_cpu
-
LOAD_REG_IMMEDIATE(r2,__toc_start)
addi r2,r2,0x4000
addi r2,r2,0x4000
cmpwi r0,0x3c /* 970FX */
beq 1f
cmpwi r0,0x44 /* 970MP */
+ beq 1f
+ cmpwi r0,0x45 /* 970GX */
bne 2f
1: bl .__cpu_preinit_ppc970
2:
addi r2,r2,0x4000
add r2,r2,r26
- LOAD_REG_IMMEDIATE(r3, cpu_specs)
- add r3,r3,r26
- LOAD_REG_IMMEDIATE(r4,cur_cpu_spec)
- add r4,r4,r26
- mr r5,r26
- bl .identify_cpu
-
/* Do very early kernel initializations, including initial hash table,
* stab and slb setup before we turn on relocation. */
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
- /* Apply the CPUs-specific fixups (nop out sections not relevant
- * to this CPU
- */
- li r3,0
- bl .do_cpu_ftr_fixups
- bl .do_fw_ftr_fixups
-
/* ptr to current */
LOAD_REG_IMMEDIATE(r4, init_task)
std r4,PACACURRENT(r13)
mtlr r11
blr
-/*
- * identify_cpu,
- * called with r3 = data offset and r4 = CPU number
- * doesn't change r3
- */
-_GLOBAL(identify_cpu)
- addis r8,r3,cpu_specs@ha
- addi r8,r8,cpu_specs@l
- mfpvr r7
-1:
- lwz r5,CPU_SPEC_PVR_MASK(r8)
- and r5,r5,r7
- lwz r6,CPU_SPEC_PVR_VALUE(r8)
- cmplw 0,r6,r5
- beq 1f
- addi r8,r8,CPU_SPEC_ENTRY_SIZE
- b 1b
-1:
- addis r6,r3,cur_cpu_spec@ha
- addi r6,r6,cur_cpu_spec@l
- sub r8,r8,r3
- stw r8,0(r6)
- blr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
- /* Get CPU 0 features */
- addis r6,r3,cur_cpu_spec@ha
- addi r6,r6,cur_cpu_spec@l
- lwz r4,0(r6)
- add r4,r4,r3
- lwz r4,CPU_SPEC_FEATURES(r4)
-
- /* Get the fixup table */
- addis r6,r3,__start___ftr_fixup@ha
- addi r6,r6,__start___ftr_fixup@l
- addis r7,r3,__stop___ftr_fixup@ha
- addi r7,r7,__stop___ftr_fixup@l
-
- /* Do the fixup */
-1: cmplw 0,r6,r7
- bgelr
- addi r6,r6,16
- lwz r8,-16(r6) /* mask */
- and r8,r8,r4
- lwz r9,-12(r6) /* value */
- cmplw 0,r8,r9
- beq 1b
- lwz r8,-8(r6) /* section begin */
- lwz r9,-4(r6) /* section end */
- subf. r9,r8,r9
- beq 1b
- /* write nops over the section of code */
- /* todo: if large section, add a branch at the start of it */
- srwi r9,r9,2
- mtctr r9
- add r8,r8,r3
- lis r0,0x60000000@h /* nop */
-3: stw r0,0(r8)
- andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
- beq 2f
- dcbst 0,r8 /* suboptimal, but simpler */
- sync
- icbi 0,r8
-2: addi r8,r8,4
- bdnz 3b
- sync /* additional sync needed on g4 */
- isync
- b 1b
-
/*
* call_setup_cpu - call the setup_cpu function for this cpu
* r3 = data offset, r24 = cpu number
isync
blr
-/*
- * identify_cpu and calls setup_cpu
- * In: r3 = base of the cpu_specs array
- * r4 = address of cur_cpu_spec
- * r5 = relocation offset
- */
-_GLOBAL(identify_cpu)
- mfpvr r7
-1:
- lwz r8,CPU_SPEC_PVR_MASK(r3)
- and r8,r8,r7
- lwz r9,CPU_SPEC_PVR_VALUE(r3)
- cmplw 0,r9,r8
- beq 1f
- addi r3,r3,CPU_SPEC_ENTRY_SIZE
- b 1b
-1:
- sub r0,r3,r5
- std r0,0(r4)
- ld r4,CPU_SPEC_SETUP(r3)
- cmpdi 0,r4,0
- add r4,r4,r5
- beqlr
- ld r4,0(r4)
- add r4,r4,r5
- mtctr r4
- /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
- mr r4,r3
- mr r3,r5
- bctr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
- /* Get CPU 0 features */
- LOAD_REG_IMMEDIATE(r6,cur_cpu_spec)
- sub r6,r6,r3
- ld r4,0(r6)
- sub r4,r4,r3
- ld r4,CPU_SPEC_FEATURES(r4)
- /* Get the fixup table */
- LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup)
- sub r6,r6,r3
- LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup)
- sub r7,r7,r3
- /* Do the fixup */
-1: cmpld r6,r7
- bgelr
- addi r6,r6,32
- ld r8,-32(r6) /* mask */
- and r8,r8,r4
- ld r9,-24(r6) /* value */
- cmpld r8,r9
- beq 1b
- ld r8,-16(r6) /* section begin */
- ld r9,-8(r6) /* section end */
- subf. r9,r8,r9
- beq 1b
- /* write nops over the section of code */
- /* todo: if large section, add a branch at the start of it */
- srwi r9,r9,2
- mtctr r9
- sub r8,r8,r3
- lis r0,0x60000000@h /* nop */
-3: stw r0,0(r8)
- andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
- beq 2f
- dcbst 0,r8 /* suboptimal, but simpler */
- sync
- icbi 0,r8
-2: addi r8,r8,4
- bdnz 3b
- sync /* additional sync needed on g4 */
- isync
- b 1b
-
-/*
- * do_fw_ftr_fixups - goes through the list of firmware feature fixups
- * and writes nop's over sections of code that don't apply for this firmware.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_fw_ftr_fixups)
- /* Get firmware features */
- LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features)
- sub r6,r6,r3
- ld r4,0(r6)
- /* Get the fixup table */
- LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup)
- sub r6,r6,r3
- LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup)
- sub r7,r7,r3
- /* Do the fixup */
-1: cmpld r6,r7
- bgelr
- addi r6,r6,32
- ld r8,-32(r6) /* mask */
- and r8,r8,r4
- ld r9,-24(r6) /* value */
- cmpld r8,r9
- beq 1b
- ld r8,-16(r6) /* section begin */
- ld r9,-8(r6) /* section end */
- subf. r9,r8,r9
- beq 1b
- /* write nops over the section of code */
- /* todo: if large section, add a branch at the start of it */
- srwi r9,r9,2
- mtctr r9
- sub r8,r8,r3
- lis r0,0x60000000@h /* nop */
-3: stw r0,0(r8)
-BEGIN_FTR_SECTION
- dcbst 0,r8 /* suboptimal, but simpler */
- sync
- icbi 0,r8
-END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE)
- addi r8,r8,4
- bdnz 3b
- sync /* additional sync needed on g4 */
- isync
- b 1b
#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
/*
#include <linux/kernel.h>
#include <linux/cache.h>
+#include "setup.h"
+
#if 0
#define DEBUGP printk
#else
return 0;
}
+static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ const char *name)
+{
+ char *secstrings;
+ unsigned int i;
+
+ secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ for (i = 1; i < hdr->e_shnum; i++)
+ if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+ return &sechdrs[i];
+ return NULL;
+}
+
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- char *secstrings;
- unsigned int i;
+ const Elf_Shdr *sect;
me->arch.bug_table = NULL;
me->arch.num_bugs = 0;
/* Find the __bug_table section, if present */
- secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
- for (i = 1; i < hdr->e_shnum; i++) {
- if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
- continue;
- me->arch.bug_table = (void *) sechdrs[i].sh_addr;
- me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
- break;
+ sect = find_section(hdr, sechdrs, "__bug_table");
+ if (sect != NULL) {
+ me->arch.bug_table = (void *) sect->sh_addr;
+ me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
}
- /*
+ /*
* Strictly speaking this should have a spinlock to protect against
* traversals, but since we only traverse on BUG()s, a spinlock
* could potentially lead to deadlock and thus be counter-productive.
*/
list_add(&me->arch.bug_list, &module_bug_list);
+ /* Apply feature fixups */
+ sect = find_section(hdr, sechdrs, "__ftr_fixup");
+ if (sect != NULL)
+ do_feature_fixups(cur_cpu_spec->cpu_features,
+ (void *)sect->sh_addr,
+ (void *)sect->sh_addr + sect->sh_size);
+
return 0;
}
#include <linux/vmalloc.h>
#include <asm/module.h>
#include <asm/uaccess.h>
+#include <asm/firmware.h>
+
+#include "setup.h"
/* FIXME: We don't do .init separately. To do this, we'd need to have
a separate r2 value in the init and core section, and stub between
| (value & 0x03fffffc);
break;
+ case R_PPC64_REL64:
+ /* 64 bits relative (used by features fixups) */
+ *location = value - (unsigned long)location;
+ break;
+
default:
printk("%s: Unknown ADD relocation: %lu\n",
me->name,
LIST_HEAD(module_bug_list);
-int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs, struct module *me)
+static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ const char *name)
{
char *secstrings;
unsigned int i;
+ secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ for (i = 1; i < hdr->e_shnum; i++)
+ if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
+ return &sechdrs[i];
+ return NULL;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs, struct module *me)
+{
+ const Elf_Shdr *sect;
+
me->arch.bug_table = NULL;
me->arch.num_bugs = 0;
/* Find the __bug_table section, if present */
- secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
- for (i = 1; i < hdr->e_shnum; i++) {
- if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
- continue;
- me->arch.bug_table = (void *) sechdrs[i].sh_addr;
- me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
- break;
+ sect = find_section(hdr, sechdrs, "__bug_table");
+ if (sect != NULL) {
+ me->arch.bug_table = (void *) sect->sh_addr;
+ me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry);
}
/*
*/
list_add(&me->arch.bug_list, &module_bug_list);
+ /* Apply feature fixups */
+ sect = find_section(hdr, sechdrs, "__ftr_fixup");
+ if (sect != NULL)
+ do_feature_fixups(cur_cpu_spec->cpu_features,
+ (void *)sect->sh_addr,
+ (void *)sect->sh_addr + sect->sh_size);
+
+ sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
+ if (sect != NULL)
+ do_feature_fixups(powerpc_firmware_features,
+ (void *)sect->sh_addr,
+ (void *)sect->sh_addr + sect->sh_size);
+
return 0;
}
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
-int device_is_compatible(struct device_node *device, const char *compat)
+int device_is_compatible(const struct device_node *device, const char *compat)
{
const char* cp;
int cplen, l;
__initcall(prom_reconfig_setup);
#endif
-struct property *of_find_property(struct device_node *np, const char *name,
+struct property *of_find_property(const struct device_node *np,
+ const char *name,
int *lenp)
{
struct property *pp;
* Find a property with a given name for a given node
* and return the value.
*/
-const void *get_property(struct device_node *np, const char *name, int *lenp)
+const void *get_property(const struct device_node *np, const char *name,
+ int *lenp)
{
struct property *pp = of_find_property(np,name,lenp);
return pp ? pp->value : NULL;
unsigned long __init early_init(unsigned long dt_ptr)
{
unsigned long offset = reloc_offset();
+ struct cpu_spec *spec;
/* First zero the BSS -- use memset_io, some platforms don't have
* caches on yet */
* Identify the CPU type and fix up code sections
* that depend on which cpu we have.
*/
- identify_cpu(offset, 0);
- do_cpu_ftr_fixups(offset);
+ spec = identify_cpu(offset);
+
+ do_feature_fixups(spec->cpu_features,
+ PTRRELOC(&__start___ftr_fixup),
+ PTRRELOC(&__stop___ftr_fixup));
return KERNELBASE + offset;
}
void __init early_setup(unsigned long dt_ptr)
{
+ /* Identify CPU type */
+ identify_cpu(0);
+
/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
setup_paca(0);
{
DBG(" -> setup_system()\n");
+ /* Apply the CPUs-specific and firmware specific fixups to kernel
+ * text (nop out sections not relevant to this CPU or this firmware)
+ */
+ do_feature_fixups(cur_cpu_spec->cpu_features,
+ &__start___ftr_fixup, &__stop___ftr_fixup);
+ do_feature_fixups(powerpc_firmware_features,
+ &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
+
/*
* Unflatten the device-tree passed by prom_init or kexec
*/
*/
struct cpu_purr_data {
int initialized; /* thread is running */
- u64 tb0; /* timebase at origin time */
- u64 purr0; /* PURR at origin time */
u64 tb; /* last TB value read */
u64 purr; /* last PURR value read */
- u64 stolen; /* stolen time so far */
spinlock_t lock;
};
{
struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
- p->tb0 = mftb();
- p->purr0 = mfspr(SPRN_PURR);
- p->tb = p->tb0;
- p->purr = 0;
+ p->tb = mftb();
+ p->purr = mfspr(SPRN_PURR);
wmb();
p->initialized = 1;
}
void calculate_steal_time(void)
{
- u64 tb, purr, t0;
+ u64 tb, purr;
s64 stolen;
- struct cpu_purr_data *p0, *pme, *phim;
- int cpu;
+ struct cpu_purr_data *pme;
if (!cpu_has_feature(CPU_FTR_PURR))
return;
- cpu = smp_processor_id();
- pme = &per_cpu(cpu_purr_data, cpu);
+ pme = &per_cpu(cpu_purr_data, smp_processor_id());
if (!pme->initialized)
return; /* this can happen in early boot */
- p0 = &per_cpu(cpu_purr_data, cpu & ~1);
- phim = &per_cpu(cpu_purr_data, cpu ^ 1);
- spin_lock(&p0->lock);
+ spin_lock(&pme->lock);
tb = mftb();
- purr = mfspr(SPRN_PURR) - pme->purr0;
- if (!phim->initialized || !cpu_online(cpu ^ 1)) {
- stolen = (tb - pme->tb) - (purr - pme->purr);
- } else {
- t0 = pme->tb0;
- if (phim->tb0 < t0)
- t0 = phim->tb0;
- stolen = phim->tb - t0 - phim->purr - purr - p0->stolen;
- }
- if (stolen > 0) {
+ purr = mfspr(SPRN_PURR);
+ stolen = (tb - pme->tb) - (purr - pme->purr);
+ if (stolen > 0)
account_steal_time(current, stolen);
- p0->stolen += stolen;
- }
pme->tb = tb;
pme->purr = purr;
- spin_unlock(&p0->lock);
+ spin_unlock(&pme->lock);
}
/*
*/
static void snapshot_purr(void)
{
- int cpu;
- u64 purr;
- struct cpu_purr_data *p0, *pme, *phim;
+ struct cpu_purr_data *pme;
unsigned long flags;
if (!cpu_has_feature(CPU_FTR_PURR))
return;
- cpu = smp_processor_id();
- pme = &per_cpu(cpu_purr_data, cpu);
- p0 = &per_cpu(cpu_purr_data, cpu & ~1);
- phim = &per_cpu(cpu_purr_data, cpu ^ 1);
- spin_lock_irqsave(&p0->lock, flags);
- pme->tb = pme->tb0 = mftb();
- purr = mfspr(SPRN_PURR);
- if (!phim->initialized) {
- pme->purr = 0;
- pme->purr0 = purr;
- } else {
- /* set p->purr and p->purr0 for no change in p0->stolen */
- pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen;
- pme->purr0 = purr - pme->purr;
- }
+ pme = &per_cpu(cpu_purr_data, smp_processor_id());
+ spin_lock_irqsave(&pme->lock, flags);
+ pme->tb = mftb();
+ pme->purr = mfspr(SPRN_PURR);
pme->initialized = 1;
- spin_unlock_irqrestore(&p0->lock, flags);
+ spin_unlock_irqrestore(&pme->lock, flags);
}
#endif /* CONFIG_PPC_SPLPAR */
#include <asm/vdso.h>
#include <asm/vdso_datapage.h>
+#include "setup.h"
+
#undef DEBUG
#ifdef DEBUG
return 0;
}
+
+static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
+ struct lib64_elfinfo *v64)
+{
+ void *start32;
+ unsigned long size32;
+
+#ifdef CONFIG_PPC64
+ void *start64;
+ unsigned long size64;
+
+ start64 = find_section64(v64->hdr, "__ftr_fixup", &size64);
+ if (start64)
+ do_feature_fixups(cur_cpu_spec->cpu_features,
+ start64, start64 + size64);
+
+ start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64);
+ if (start64)
+ do_feature_fixups(powerpc_firmware_features,
+ start64, start64 + size64);
+#endif /* CONFIG_PPC64 */
+
+ start32 = find_section32(v32->hdr, "__ftr_fixup", &size32);
+ if (start32)
+ do_feature_fixups(cur_cpu_spec->cpu_features,
+ start32, start32 + size32);
+
+#ifdef CONFIG_PPC64
+ start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32);
+ if (start32)
+ do_feature_fixups(powerpc_firmware_features,
+ start32, start32 + size32);
+#endif /* CONFIG_PPC64 */
+
+ return 0;
+}
+
static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,
struct lib64_elfinfo *v64)
{
if (vdso_fixup_datapage(&v32, &v64))
return -1;
+ if (vdso_fixup_features(&v32, &v64))
+ return -1;
+
if (vdso_fixup_alt_funcs(&v32, &v64))
return -1;
* Setup the syscall map in the vDOS
*/
vdso_setup_syscall_map();
+
/*
* Initialize the vDSO images in memory, that is do necessary
* fixups of vDSO symbols, locate trampolines, etc...
PROVIDE (_etext = .);
PROVIDE (etext = .);
+ . = ALIGN(8);
+ __ftr_fixup : {
+ *(__ftr_fixup)
+ }
+
+#ifdef CONFIG_PPC64
+ . = ALIGN(8);
+ __fw_ftr_fixup : {
+ *(__fw_ftr_fixup)
+ }
+#endif
+
/* Other stuff is appended to the text segment: */
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
xor r0,r8,r8 /* create dependency */
add r3,r3,r0
- /* Get TB & offset it */
- mftb r7
+ /* Get TB & offset it. We use the MFTB macro which will generate
+ * workaround code for Cell.
+ */
+ MFTB(r7)
ld r9,CFG_TB_ORIG_STAMP(r3)
subf r7,r9,r7
PROVIDE (_etext = .);
PROVIDE (etext = .);
+ . = ALIGN(8);
+ __ftr_fixup : {
+ *(__ftr_fixup)
+ }
+
+ . = ALIGN(8);
+ __fw_ftr_fixup : {
+ *(__fw_ftr_fixup)
+ }
+
/* Other stuff is appended to the text segment: */
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
{
if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) ||
__is_processor(PV_970) || __is_processor(PV_970FX) ||
- __is_processor(PV_970MP))
+ __is_processor(PV_970MP) || __is_processor(PV_970GX))
return 1;
return 0;
udata = (void __user *)buf;
spu_acquire(ctx);
- for (count = 0; count <= len; count += 4, udata++) {
+ for (count = 0; (count + 4) <= len; count += 4, udata++) {
int ret;
ret = ctx->ops->mbox_read(ctx, &mbox_data);
if (ret == 0)
static u32 spu_hw_signal2_read(struct spu_context *ctx)
{
- return in_be32(&ctx->spu->problem->signal_notify1);
+ return in_be32(&ctx->spu->problem->signal_notify2);
}
static void spu_hw_signal2_write(struct spu_context *ctx, u32 data)
" address, polling\n");
i8259_init(pic, chrp_int_ack);
- if (ppc_md.get_irq == NULL)
+ if (ppc_md.get_irq == NULL) {
ppc_md.get_irq = i8259_irq;
+ irq_set_default_host(i8259_get_host());
+ }
if (chrp_mpic != NULL) {
cascade_irq = irq_of_parse_and_map(pic, 0);
if (cascade_irq == NO_IRQ)
{
unsigned long phys_mem_size;
+ /* Identify CPU type. This is done again by the common code later
+ * on but calling this function multiple times is fine.
+ */
+ identify_cpu(0);
+
powerpc_firmware_features |= FW_FEATURE_ISERIES;
powerpc_firmware_features |= FW_FEATURE_LPAR;
.section .text
.align 5
-#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
+#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \
+ (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32))
/* This gets called by via-pmu.c late during the sleep process.
* The PMU was already send the sleep command and will shut us down
.xlate = i8259_host_xlate,
};
+struct irq_host *i8259_get_host(void)
+{
+ return i8259_host;
+}
+
/**
* i8259_init - Initialize the legacy controller
* @node: device node of the legacy PIC (can be NULL, but then, it will match
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
if (flow_type & IRQ_TYPE_LEVEL_LOW) {
desc->status |= IRQ_LEVEL;
- set_irq_handler(virq, handle_level_irq);
+ desc->handle_irq = handle_level_irq;
} else {
- set_irq_handler(virq, handle_edge_irq);
+ desc->handle_irq = handle_edge_irq;
}
/* only EXT IRQ senses are programmable on ipic
case QE_CLK18: source = 8; break;
case QE_CLK7: source = 9; break;
case QE_CLK8: source = 10; break;
+ case QE_CLK16: source = 11; break;
default: source = -1; break;
}
break;
case QE_CLK22: source = 8; break;
case QE_CLK7: source = 9; break;
case QE_CLK8: source = 10; break;
+ case QE_CLK16: source = 11; break;
default: source = -1; break;
}
break;
/* check if the UCC port number is in range. */
if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
- uccf_err("ucc_fast_init: Illagal UCC number!");
+ uccf_err("ucc_fast_init: Illegal UCC number!");
return -EINVAL;
}
/* check if the UCC port number is in range. */
if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
- uccs_err("ucc_slow_init: Illagal UCC number!");
+ uccs_err("ucc_slow_init: Illegal UCC number!");
return -EINVAL;
}
tsi = of_find_node_by_type(NULL, "tsi-bridge");
if (tsi) {
unsigned int size;
- void *prop = get_property(tsi, "reg", &size);
+ const void *prop = get_property(tsi, "reg", &size);
tsi108_csr_base = of_translate_address(tsi, prop);
of_node_put(tsi);
};
hw_info tsi_eth_data;
unsigned int *id;
unsigned int *phy_id;
- void *mac_addr;
+ const void *mac_addr;
phandle *ph;
memset(r, 0, sizeof(r));
start_ldr:
/* Clear all of BSS and set up stack for C calls */
- lis r3,edata@h
- ori r3,r3,edata@l
+ lis r3,__bss_start@h
+ ori r3,r3,__bss_start@l
lis r4,end@h
ori r4,r4,end@l
subi r3,r3,4
li r0,0
50: stwu r0,4(r3)
cmpw cr0,r3,r4
- bne 50b
+ blt 50b
90: mr r9,r1 /* Save old stack pointer (in case it matters) */
lis r1,.stack@h
ori r1,r1,.stack@l
mtlr r11
blr
-/*
- * identify_cpu,
- * called with r3 = data offset and r4 = CPU number
- * doesn't change r3
- */
-_GLOBAL(identify_cpu)
- addis r8,r3,cpu_specs@ha
- addi r8,r8,cpu_specs@l
- mfpvr r7
-1:
- lwz r5,CPU_SPEC_PVR_MASK(r8)
- and r5,r5,r7
- lwz r6,CPU_SPEC_PVR_VALUE(r8)
- cmplw 0,r6,r5
- beq 1f
- addi r8,r8,CPU_SPEC_ENTRY_SIZE
- b 1b
-1:
- addis r6,r3,cur_cpu_spec@ha
- addi r6,r6,cur_cpu_spec@l
- sub r8,r8,r3
- stw r8,0(r6)
- blr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
- /* Get CPU 0 features */
- addis r6,r3,cur_cpu_spec@ha
- addi r6,r6,cur_cpu_spec@l
- lwz r4,0(r6)
- add r4,r4,r3
- lwz r4,CPU_SPEC_FEATURES(r4)
-
- /* Get the fixup table */
- addis r6,r3,__start___ftr_fixup@ha
- addi r6,r6,__start___ftr_fixup@l
- addis r7,r3,__stop___ftr_fixup@ha
- addi r7,r7,__stop___ftr_fixup@l
-
- /* Do the fixup */
-1: cmplw 0,r6,r7
- bgelr
- addi r6,r6,16
- lwz r8,-16(r6) /* mask */
- and r8,r8,r4
- lwz r9,-12(r6) /* value */
- cmplw 0,r8,r9
- beq 1b
- lwz r8,-8(r6) /* section begin */
- lwz r9,-4(r6) /* section end */
- subf. r9,r8,r9
- beq 1b
- /* write nops over the section of code */
- /* todo: if large section, add a branch at the start of it */
- srwi r9,r9,2
- mtctr r9
- add r8,r8,r3
- lis r0,0x60000000@h /* nop */
-3: stw r0,0(r8)
- andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
- beq 2f
- dcbst 0,r8 /* suboptimal, but simpler */
- sync
- icbi 0,r8
-2: addi r8,r8,4
- bdnz 3b
- sync /* additional sync needed on g4 */
- isync
- b 1b
-
/*
* call_setup_cpu - call the setup_cpu function for this cpu
* r3 = data offset, r24 = cpu number
#include <asm/nvram.h>
#include <asm/xmon.h>
#include <asm/ocp.h>
+#include <asm/prom.h>
#define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \
defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
extern void platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
-extern void identify_cpu(unsigned long offset, unsigned long cpu);
-extern void do_cpu_ftr_fixups(unsigned long offset);
extern void reloc_got2(unsigned long offset);
extern void ppc6xx_idle(void);
{
unsigned long phys;
unsigned long offset = reloc_offset();
+ struct cpu_spec *spec;
/* Default */
phys = offset + KERNELBASE;
* Identify the CPU type and fix up code sections
* that depend on which cpu we have.
*/
- identify_cpu(offset, 0);
- do_cpu_ftr_fixups(offset);
+ spec = identify_cpu(offset);
+ do_feature_fixups(spec->cpu_features,
+ PTRRELOC(&__start___ftr_fixup),
+ PTRRELOC(&__stop___ftr_fixup));
return phys;
}
#include <asm/io.h>
#include <asm/apm.h>
#include <asm/adc.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
#define SH7709_PGDR 0xa400012c
#include <linux/time.h>
#include <asm/io.h>
#include <asm/hd64461.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
#include <asm/cpu/dac.h>
#include <asm/pm.h>
#include <asm/hd64461.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
#include <asm/cpu/dac.h>
#define SCPCR 0xa4000116
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
+#include <asm/hs7751rvoip.h>
#include <asm/addrspace.h>
extern void *area6_io8_base; /* Area 6 8bit I/O Base address */
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
+#include <asm/hs7751rvoip.h>
static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7};
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
#include <linux/pm.h>
+#include <asm/hs7751rvoip.h>
#include <asm/io.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
#include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/irq.h>
static void __init hs7751rvoip_init_irq(void)
{
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
#include <asm/addrspace.h>
#include <asm/io.h>
*/
#include <linux/init.h>
#include <linux/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/r7780rp.h>
#ifdef CONFIG_SH_R7780MP
static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
}
static struct irq_chip r7780rp_irq_chip __read_mostly = {
- .name = "r7780rp",
+ .name = "R7780RP",
.mask = disable_r7780rp_irq,
.unmask = enable_r7780rp_irq,
.mask_ack = disable_r7780rp_irq,
for (i = 0; i < 15; i++) {
disable_irq_nosync(i);
- set_irq_chip_and_handler(i, &r7780rp_irq_chip,
- handle_level_irq);
+ set_irq_chip_and_handler_name(i, &r7780rp_irq_chip,
+ handle_level_irq, "level");
enable_r7780rp_irq(i);
}
}
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
#include <asm/clock.h>
#include <asm/io.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
#include <asm/addrspace.h>
/*
* Modified for RTS7751R2D by
* Atom Create Engineering Co., Ltd. 2002.
*/
-
#include <linux/init.h>
#include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
#if defined(CONFIG_RTS7751R2D_REV11)
static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
*
* This file contains Renesas Technology Sales RTS7751R2D specific LED code.
*/
-
-#include <asm/io.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-
-#ifdef CONFIG_HEARTBEAT
-
+#include <linux/io.h>
#include <linux/sched.h>
+#include <asm/rts7751r2d.h>
/* Cycle the LED's in the clasic Knightriger/Sun pattern */
void heartbeat_rts7751r2d(void)
else
bit--;
}
-#endif /* CONFIG_HEARTBEAT */
-
-void rts7751r2d_led(unsigned short value)
-{
- ctrl_outw(value, PA_OUTPORT);
-}
-
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/pm.h>
-#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/mach/rts7751r2d.h>
+#include <asm/io.h>
#include <asm/voyagergx.h>
extern void heartbeat_rts7751r2d(void);
*/
#include <linux/init.h>
#include <asm/machvec.h>
-#include <asm/shmin/shmin.h>
+#include <asm/shmin.h>
#include <asm/clock.h>
#include <asm/irq.h>
#include <asm/io.h>
Copyright 2003 (c) Lineo uSolutions,Inc.
*/
-/* -------------------------------------------------------------------- */
-
-#undef DEBUG
-
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
#include <asm/voyagergx.h>
+#include <asm/rts7751r2d.h>
static void disable_voyagergx_irq(unsigned int irq)
{
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
- pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+ pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
val = inl(VOYAGER_INT_MASK);
val &= ~mask;
outl(val, VOYAGER_INT_MASK);
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
- pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+ pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
val = inl(VOYAGER_INT_MASK);
val |= mask;
outl(val, VOYAGER_INT_MASK);
} else {
printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
}
- pr_debug("voyagergx_irq_demux %d \n", i);
+ pr_debug("voyagergx_irq_demux %ld\n", i);
#else
for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++)
if (val & bit)
setup_irq(IRQ_VOYAGER, &irq0);
}
-
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
#include <asm/io.h>
#include "pci-sh4.h"
*
* PCI initialization for the Renesas SH7751R RTS7751R2D board
*/
-
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/pci.h>
-#include <linux/module.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
#include "pci-sh4.h"
+static u8 rts7751r2d_irq_tab[] __initdata = {
+ IRQ_PCISLOT1,
+ IRQ_PCISLOT2,
+ IRQ_PCMCIA,
+ IRQ_PCIETH,
+};
+
int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
- switch (slot) {
- case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */
- case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */
- case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */
- case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */
- default:
- printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
- return -1;
- }
+ return rts7751r2d_irq_tab[slot];
}
static struct resource sh7751_io_resource = {
* Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
*/
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <asm/system.h>
-#include <asm/io.h>
static void disable_intc2_irq(unsigned int irq)
{
}
static struct irq_chip intc2_irq_chip = {
- .typename = "intc2",
+ .name = "INTC2",
.mask = disable_intc2_irq,
.unmask = enable_intc2_irq,
.mask_ack = disable_intc2_irq,
* PIO1 which is INTPRI00[19,16] and INTMSK00[13]
* would be: ^ ^ ^ ^
* | | | |
- * make_intc2_irq(84, 0, 16, 0, 13);
+ * { 84, 0, 16, 0, 13 },
+ *
+ * in the intc2_data table.
*/
-void make_intc2_irq(struct intc2_data *p)
+void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs)
{
- unsigned int flags;
- unsigned long ipr;
-
- disable_irq_nosync(p->irq);
-
- /* Set the priority level */
- local_irq_save(flags);
-
- ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset);
- ipr &= ~(0xf << p->ipr_shift);
- ipr |= p->priority << p->ipr_shift;
- ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset);
-
- local_irq_restore(flags);
+ int i;
- set_irq_chip_and_handler(p->irq, &intc2_irq_chip, handle_level_irq);
- set_irq_chip_data(p->irq, p);
+ for (i = 0; i < nr_irqs; i++) {
+ unsigned long ipr, flags;
+ struct intc2_data *p = table + i;
- enable_intc2_irq(p->irq);
-}
+ disable_irq_nosync(p->irq);
-static struct intc2_data intc2_irq_table[] = {
-#if defined(CONFIG_CPU_SUBTYPE_ST40)
- {64, 0, 0, 0, 0, 13}, /* PCI serr */
- {65, 0, 4, 0, 1, 13}, /* PCI err */
- {66, 0, 4, 0, 2, 13}, /* PCI ad */
- {67, 0, 4, 0, 3, 13}, /* PCI pwd down */
- {72, 0, 8, 0, 5, 13}, /* DMAC INT0 */
- {73, 0, 8, 0, 6, 13}, /* DMAC INT1 */
- {74, 0, 8, 0, 7, 13}, /* DMAC INT2 */
- {75, 0, 8, 0, 8, 13}, /* DMAC INT3 */
- {76, 0, 8, 0, 9, 13}, /* DMAC INT4 */
- {78, 0, 8, 0, 11, 13}, /* DMAC ERR */
- {80, 0, 12, 0, 12, 13}, /* PIO0 */
- {84, 0, 16, 0, 13, 13}, /* PIO1 */
- {88, 0, 20, 0, 14, 13}, /* PIO2 */
- {112, 4, 0, 4, 0, 13}, /* Mailbox */
- #ifdef CONFIG_CPU_SUBTYPE_ST40GX1
- {116, 4, 4, 4, 4, 13}, /* SSC0 */
- {120, 4, 8, 4, 8, 13}, /* IR Blaster */
- {124, 4, 12, 4, 12, 13}, /* USB host */
- {128, 4, 16, 4, 16, 13}, /* Video processor BLITTER */
- {132, 4, 20, 4, 20, 13}, /* UART0 */
- {134, 4, 20, 4, 22, 13}, /* UART2 */
- {136, 4, 24, 4, 24, 13}, /* IO_PIO0 */
- {140, 4, 28, 4, 28, 13}, /* EMPI */
- {144, 8, 0, 8, 0, 13}, /* MAFE */
- {148, 8, 4, 8, 4, 13}, /* PWM */
- {152, 8, 8, 8, 8, 13}, /* SSC1 */
- {156, 8, 12, 8, 12, 13}, /* IO_PIO1 */
- {160, 8, 16, 8, 16, 13}, /* USB target */
- {164, 8, 20, 8, 20, 13}, /* UART1 */
- {168, 8, 24, 8, 24, 13}, /* Teletext */
- {172, 8, 28, 8, 28, 13}, /* VideoSync VTG */
- {173, 8, 28, 8, 29, 13}, /* VideoSync DVP0 */
- {174, 8, 28, 8, 30, 13}, /* VideoSync DVP1 */
-#endif
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-/*
- * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
- */
- /* INTPRIO0 | INTMSK0 */
- {48, 0, 28, 0, 31, 3}, /* IRQ 4 */
- {49, 0, 24, 0, 30, 3}, /* IRQ 3 */
- {50, 0, 20, 0, 29, 3}, /* IRQ 2 */
- {51, 0, 16, 0, 28, 3}, /* IRQ 1 */
- /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
- /* INTPRIO4 | INTMSK0 */
- {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */
- {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */
- {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */
- {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */
- {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */
- {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */
- {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */
- {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */
- /* INTPRIO8 | INTMSK0 */
- {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */
- {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */
- {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */
- {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */
- {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */
- {65, 8, 24, 0, 16, 3}, /* LCDC */
- /* 66, 67 unused */
- {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */
- {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */
- {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */
- /* 71 unused */
- {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */
- {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */
- {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */
- {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */
- {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */
- {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */
- {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */
- {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */
- /* | INTMSK4 */
- {80, 8, 4, 4, 23, 3}, /* SIM_ERI */
- {81, 8, 4, 4, 22, 3}, /* SIM_RXI */
- {82, 8, 4, 4, 21, 3}, /* SIM_TXI */
- {83, 8, 4, 4, 20, 3}, /* SIM_TEI */
- {84, 8, 0, 4, 19, 3}, /* HSPII */
- /* INTPRIOC | INTMSK4 */
- /* 85-87 unused/reserved */
- {88, 12, 20, 4, 18, 3}, /* MMCI0 */
- {89, 12, 20, 4, 17, 3}, /* MMCI1 */
- {90, 12, 20, 4, 16, 3}, /* MMCI2 */
- {91, 12, 20, 4, 15, 3}, /* MMCI3 */
- {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/
- /* 93-107 reserved/undocumented */
- {108,12, 4, 4, 1, 3}, /* ADC */
- {109,12, 0, 4, 0, 3}, /* CMTI */
- /* 110-111 reserved/unused */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
- { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2},
- { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
- { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
- { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
- { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
- { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
- { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
- { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ /* Set the priority level */
+ local_irq_save(flags);
- { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
- { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
- { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
- { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET +
+ p->ipr_offset);
+ ipr &= ~(0xf << p->ipr_shift);
+ ipr |= p->priority << p->ipr_shift;
+ ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET +
+ p->ipr_offset);
- { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
- { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
- { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
- { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
- { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
-#endif
-};
+ local_irq_restore(flags);
-void __init init_IRQ_intc2(void)
-{
- int i;
+ set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip,
+ handle_level_irq, "level");
+ set_irq_chip_data(p->irq, p);
- for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++)
- make_intc2_irq(intc2_irq_table + i);
+ enable_intc2_irq(p->irq);
+ }
}
}
static struct irq_chip ipr_irq_chip = {
- .name = "ipr",
+ .name = "IPR",
.mask = disable_ipr_irq,
.unmask = enable_ipr_irq,
.mask_ack = disable_ipr_irq,
ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */
ipr_data.priority = priority;
- set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq);
+ set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
+ handle_level_irq, "level");
set_irq_chip_data(irq, &ipr_data);
enable_ipr_irq(irq);
* The SH-3 exception vector table.
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
+ * Copyright (C) 2003 - 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
#endif
ENTRY(user_break_point_trap)
.long break_point_trap /* 1E0 */
+
+ /*
+ * Pad the remainder of the table out, exceptions residing in far
+ * away offsets can be manually inserted in to their appropriate
+ * location via set_exception_table_{evt,vec}().
+ */
+ .balign 4096,0,4096
* The SH-4 exception vector table.
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
+ * Copyright (C) 2003 - 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
#endif
ENTRY(user_break_point_trap)
.long break_point_trap /* 1E0 */
+
+ /*
+ * Pad the remainder of the table out, exceptions residing in far
+ * away offsets can be manually inserted in to their appropriate
+ * location via set_exception_table_{evt,vec}().
+ */
+ .balign 4096,0,4096
ARRAY_SIZE(sh7760_devices));
}
__initcall(sh7760_devices_setup);
+
+/*
+ * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
+ */
+static struct intc2_data intc2_irq_table[] = {
+ /* INTPRIO0 | INTMSK0 */
+ {48, 0, 28, 0, 31, 3}, /* IRQ 4 */
+ {49, 0, 24, 0, 30, 3}, /* IRQ 3 */
+ {50, 0, 20, 0, 29, 3}, /* IRQ 2 */
+ {51, 0, 16, 0, 28, 3}, /* IRQ 1 */
+ /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
+ /* INTPRIO4 | INTMSK0 */
+ {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */
+ {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */
+ {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */
+ {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */
+ {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */
+ {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */
+ {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */
+ {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */
+ /* INTPRIO8 | INTMSK0 */
+ {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */
+ {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */
+ {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */
+ {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */
+ {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */
+ {65, 8, 24, 0, 16, 3}, /* LCDC */
+ /* 66, 67 unused */
+ {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */
+ {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */
+ {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */
+ /* 71 unused */
+ {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */
+ {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */
+ {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */
+ {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */
+ {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */
+ {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */
+ {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */
+ {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */
+ /* | INTMSK4 */
+ {80, 8, 4, 4, 23, 3}, /* SIM_ERI */
+ {81, 8, 4, 4, 22, 3}, /* SIM_RXI */
+ {82, 8, 4, 4, 21, 3}, /* SIM_TXI */
+ {83, 8, 4, 4, 20, 3}, /* SIM_TEI */
+ {84, 8, 0, 4, 19, 3}, /* HSPII */
+ /* INTPRIOC | INTMSK4 */
+ /* 85-87 unused/reserved */
+ {88, 12, 20, 4, 18, 3}, /* MMCI0 */
+ {89, 12, 20, 4, 17, 3}, /* MMCI1 */
+ {90, 12, 20, 4, 16, 3}, /* MMCI2 */
+ {91, 12, 20, 4, 15, 3}, /* MMCI3 */
+ {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/
+ /* 93-107 reserved/undocumented */
+ {108,12, 4, 4, 1, 3}, /* ADC */
+ {109,12, 0, 4, 0, 3}, /* CMTI */
+ /* 110-111 reserved/unused */
+};
+
+void __init init_IRQ_intc2(void)
+{
+ make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
ARRAY_SIZE(sh7780_devices));
}
__initcall(sh7780_devices_setup);
+
+static struct intc2_data intc2_irq_table[] = {
+ { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 },
+ { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+ { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+ { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+ { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+
+ { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+
+ { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
+ { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
+ { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
+ { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
+ { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
+};
+
+void __init init_IRQ_intc2(void)
+{
+ make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
seq_printf(p, " %14s", irq_desc[i].chip->name);
- seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
+ seq_printf(p, "-%-8s", irq_desc[i].name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
{
printk("\n");
printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
- print_symbol("PC is at %s\n", regs->pc);
+ print_symbol("PC is at %s\n", instruction_pointer(regs));
printk("PC : %08lx SP : %08lx SR : %08lx ",
regs->pc, regs->regs[15], regs->sr);
#ifdef CONFIG_MMU
printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n",
regs->mach, regs->macl, regs->gbr, regs->pr);
- /*
- * If we're in kernel mode, dump the stack too..
- */
- if (!user_mode(regs)) {
- extern void show_task(unsigned long *sp);
- unsigned long sp = regs->regs[15];
-
- show_task((unsigned long *)sp);
- }
+ show_trace(NULL, (unsigned long *)regs->regs[15], regs);
}
/*
-/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $
- *
- * linux/arch/sh/traps.c
+/*
+ * 'traps.c' handles hardware traps and faults after we have saved some
+ * state in 'entry.S'.
*
* SuperH version: Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2000 Philipp Rumpf
* Copyright (C) 2000 David Howells
- * Copyright (C) 2002, 2003 Paul Mundt
- */
-
-/*
- * 'Traps.c' handles hardware traps and faults after we have saved some
- * state in 'entry.S'.
+ * Copyright (C) 2002 - 2006 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
*/
-#include <linux/sched.h>
#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
#include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
-
+#include <linux/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/processor.h>
-#include <asm/sections.h>
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
#define TRAP_ILLEGAL_SLOT_INST 13
#endif
-/*
- * These constants are for searching for possible module text
- * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
- * a guess of how much space is likely to be vmalloced.
- */
-#define VMALLOC_OFFSET (8*1024*1024)
-#define MODULE_RANGE (8*1024*1024)
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+{
+ unsigned long p;
+ int i;
+
+ printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
+ for (p = bottom & ~31; p < top; ) {
+ printk("%04lx: ", p & 0xffff);
+
+ for (i = 0; i < 8; i++, p += 4) {
+ unsigned int val;
+
+ if (p < bottom || p >= top)
+ printk(" ");
+ else {
+ if (__get_user(val, (unsigned int __user *)p)) {
+ printk("\n");
+ return;
+ }
+ printk("%08x ", val);
+ }
+ }
+ printk("\n");
+ }
+}
DEFINE_SPINLOCK(die_lock);
console_verbose();
spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+
printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+
CHK_REMOTE_DEBUG(regs);
+ print_modules();
show_regs(regs);
+
+ printk("Process: %s (pid: %d, stack limit = %p)\n",
+ current->comm, current->pid, task_stack_page(current) + 1);
+
+ if (!user_mode(regs) || in_interrupt())
+ dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
+ (unsigned long)task_stack_page(current));
+
+ bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
}
-static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs,
+ long err)
{
if (!user_mode(regs))
die(str, regs, err);
*/
static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
{
- if (!user_mode(regs))
- {
+ if (!user_mode(regs)) {
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->pc);
if (fixup) {
#define is_dsp_inst(regs) (0)
#endif /* CONFIG_SH_DSP */
-extern int do_fpu_inst(unsigned short, struct pt_regs*);
+/* arch/sh/kernel/cpu/sh4/fpu.c */
+extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7, struct pt_regs regs);
asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
: "memory");
}
-void __init trap_init(void)
+void *set_exception_table_vec(unsigned int vec, void *handler)
{
extern void *exception_handling_table[];
+ void *old_handler;
+
+ old_handler = exception_handling_table[vec];
+ exception_handling_table[vec] = handler;
+ return old_handler;
+}
- exception_handling_table[TRAP_RESERVED_INST]
- = (void *)do_reserved_inst;
- exception_handling_table[TRAP_ILLEGAL_SLOT_INST]
- = (void *)do_illegal_slot_inst;
+void __init trap_init(void)
+{
+ set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
+ set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst);
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
defined(CONFIG_SH_FPU_EMU)
* reserved. They'll be handled in the math-emu case, or faulted on
* otherwise.
*/
- /* entry 64 corresponds to EXPEVT=0x800 */
- exception_handling_table[64] = (void *)do_reserved_inst;
- exception_handling_table[65] = (void *)do_illegal_slot_inst;
+ set_exception_table_evt(0x800, do_reserved_inst);
+ set_exception_table_evt(0x820, do_illegal_slot_inst);
+#elif defined(CONFIG_SH_FPU)
+ set_exception_table_evt(0x800, do_fpu_state_restore);
+ set_exception_table_evt(0x820, do_fpu_state_restore);
#endif
/* Setup VBR for boot cpu */
per_cpu_trap_init();
}
-void show_stack(struct task_struct *tsk, unsigned long *sp)
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+ struct pt_regs *regs)
{
- unsigned long *stack, addr;
- unsigned long module_start = VMALLOC_START;
- unsigned long module_end = VMALLOC_END;
- int i = 1;
-
- if (!tsk)
- tsk = current;
- if (tsk == current)
- sp = (unsigned long *)current_stack_pointer;
- else
- sp = (unsigned long *)tsk->thread.sp;
+ unsigned long addr;
- stack = sp;
+ if (regs && user_mode(regs))
+ return;
printk("\nCall trace: ");
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
- while (!kstack_end(stack)) {
- addr = *stack++;
- if (((addr >= (unsigned long)_text) &&
- (addr <= (unsigned long)_etext)) ||
- ((addr >= module_start) && (addr <= module_end))) {
- /*
- * For 80-columns display, 6 entry is maximum.
- * NOTE: '[<8c00abcd>] ' consumes 13 columns .
- */
-#ifndef CONFIG_KALLSYMS
- if (i && ((i % 6) == 0))
- printk("\n ");
-#endif
- printk("[<%08lx>] ", addr);
- print_symbol("%s\n", addr);
- i++;
- }
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (kernel_text_address(addr))
+ print_ip_sym(addr);
}
printk("\n");
}
-void show_task(unsigned long *sp)
+void show_stack(struct task_struct *tsk, unsigned long *sp)
{
- show_stack(NULL, sp);
+ unsigned long stack;
+
+ if (!tsk)
+ tsk = current;
+ if (tsk == current)
+ sp = (unsigned long *)current_stack_pointer;
+ else
+ sp = (unsigned long *)tsk->thread.sp;
+
+ stack = (unsigned long)sp;
+ dump_mem("Stack: ", stack, THREAD_SIZE +
+ (unsigned long)task_stack_page(tsk));
+ show_trace(tsk, sp, NULL);
}
void dump_stack(void)
/* long to avoid size mismatch warnings from gcc */
long fd;
struct mconsole_entry *new;
- struct mc_request req;
+ static struct mc_request req; /* that's OK */
fd = (long) dev_id;
while (mconsole_get_request(fd, &req)){
mconsole_reply(&req, "Out of memory", 1, 0);
else {
new->request = req;
+ new->request.regs = get_irq_regs()->regs;
list_add(&new->list, &mc_requests);
}
}
{
deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
os_set_fd_block(req->originating_fd, 1);
- mconsole_reply(req, "", 0, 0);
- while(mconsole_get_request(req->originating_fd, req)){
- if(req->cmd->handler == mconsole_go) break;
+ mconsole_reply(req, "stopped", 0, 0);
+ while (mconsole_get_request(req->originating_fd, req)) {
+ if (req->cmd->handler == mconsole_go)
+ break;
+ if (req->cmd->handler == mconsole_stop) {
+ mconsole_reply(req, "Already stopped", 1, 0);
+ continue;
+ }
+ if (req->cmd->handler == mconsole_sysrq) {
+ struct pt_regs *old_regs;
+ old_regs = set_irq_regs((struct pt_regs *)&req->regs);
+ mconsole_sysrq(req);
+ set_irq_regs(old_regs);
+ continue;
+ }
(*req->cmd->handler)(req);
}
os_set_fd_block(req->originating_fd, 0);
static void sysrq_proc(void *arg)
{
char *op = arg;
- struct pt_regs *old_regs = set_irq_regs(¤t->thread.regs);
handle_sysrq(*op, NULL);
- set_irq_regs(old_regs);
}
void mconsole_sysrq(struct mc_request *req)
#include <sys/un.h>
#include <unistd.h>
#include "user.h"
+#include "sysdep/ptrace.h"
#include "mconsole.h"
#include "umid.h"
#include "user_util.h"
struct mconsole_request request;
struct mconsole_command *cmd;
+ union uml_pt_regs regs;
};
extern char mconsole_socket_name[];
cflags-y += $(call cc-option,-funit-at-a-time)
# prevent gcc from generating any FP code by mistake
cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
# do binutils support CFI?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc1
-# Thu Oct 5 13:04:43 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:52 2006
#
CONFIG_X86_64=y
CONFIG_64BIT=y
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
#
# ATA/ATAPI/MFM/RLL support
#
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
# CONFIG_SENSORS_HDAPS is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-# CONFIG_TIFM_CORE is not set
-
#
# Multimedia devices
#
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
#
# USB Imaging devices
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_TEST is not set
#
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# 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
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
#
# CD-ROM/DVD Filesystems
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
-CONFIG_GENERIC_ACL=y
#
# Partition Types
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
-#
-# Distributed Lock Manager
-#
-
#
# Instrumentation Support
#
CONFIG_UNWIND_INFO=y
CONFIG_STACK_UNWIND=y
# CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
# CONFIG_DEBUG_RODATA is not set
/* various gunk below that needed for SMP startup */
if (addr < 0x8000) {
- *addrp = 0x8000;
+ *addrp = PAGE_ALIGN(0x8000);
return 1;
}
/* direct mapping tables of the kernel */
if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) {
- *addrp = table_end << PAGE_SHIFT;
+ *addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
return 1;
}
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE && INITRD_START && last >= INITRD_START &&
addr < INITRD_START+INITRD_SIZE) {
- *addrp = INITRD_START + INITRD_SIZE;
+ *addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
return 1;
}
#endif
/* kernel code */
- if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
- *addrp = __pa_symbol(&_end);
+ if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) {
+ *addrp = PAGE_ALIGN(__pa_symbol(&_end));
return 1;
}
if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
- *addrp = ebda_addr + ebda_size;
+ *addrp = PAGE_ALIGN(ebda_addr + ebda_size);
return 1;
}
continue;
while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
;
- last = addr + size;
+ last = PAGE_ALIGN(addr) + size;
if (last > ei->addr + ei->size)
continue;
if (last > end)
static void ati_bugs(void)
{
-#if 1 /* for testing */
- printk("ATI board detected\n");
-#endif
- /* No bugs right now */
+ if (timer_over_8254 == 1) {
+ timer_over_8254 = 0;
+ printk(KERN_INFO
+ "ATI board detected. Disabling timer routing over 8254.\n");
+ }
}
struct chipset {
LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
RESTORE_REST
cmpq $__NR_syscall_max,%rax
+ movq $-ENOSYS,%rcx
+ cmova %rcx,%rax
ja 1f
movq %r10,%rcx /* fixup for C */
call *sys_call_table(,%rax,8)
1: incl %gs:pda_irqcount
cmoveq %gs:pda_irqstackptr,%rsp
push %rbp # backlink for old unwinder
- CFI_ADJUST_CFA_OFFSET 8
- CFI_REL_OFFSET rbp,0
/*
* We entered an interrupt context - irqs are off:
*/
call do_fork
movq %rax,RAX(%rsp)
xorl %edi,%edi
- test %rax,%rax
- jnz 1f
- /* terminate stack in child */
- movq %rdi,RIP(%rsp)
-1:
/*
* It isn't worth to check for reschedule here,
incl %gs:pda_irqcount
cmove %gs:pda_irqstackptr,%rsp
push %rbp # backlink for old unwinder
- CFI_ADJUST_CFA_OFFSET 8
call __do_softirq
leaveq
CFI_DEF_CFA_REGISTER rsp
static cpumask_t physflat_target_cpus(void)
{
- return cpumask_of_cpu(0);
+ return cpu_online_map;
}
static cpumask_t physflat_vector_allocation_domain(int cpu)
static int disable_timer_pin_1 __initdata;
-int timer_over_8254 __initdata = 0;
+int timer_over_8254 __initdata = 1;
/* Where if anywhere is the i8259 connect in external int mode */
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock);
-static DEFINE_SPINLOCK(vector_lock);
+DEFINE_SPINLOCK(vector_lock);
/*
* # of IRQ routing registers
* Also, we've got to be careful not to trash gate
* 0x80, because int 0x80 is hm, kind of importantish. ;)
*/
- static struct {
- int vector;
- int offset;
- } pos[NR_CPUS] = { [ 0 ... NR_CPUS - 1] = {FIRST_DEVICE_VECTOR, 0} };
+ static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
int old_vector = -1;
int cpu;
BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
+ /* Only try and allocate irqs on cpus that are present */
+ cpus_and(mask, mask, cpu_online_map);
+
if (irq_vector[irq] > 0)
old_vector = irq_vector[irq];
if (old_vector > 0) {
}
for_each_cpu_mask(cpu, mask) {
- cpumask_t domain;
- int first, new_cpu;
+ cpumask_t domain, new_mask;
+ int new_cpu;
int vector, offset;
domain = vector_allocation_domain(cpu);
- first = first_cpu(domain);
+ cpus_and(new_mask, domain, cpu_online_map);
- vector = pos[first].vector;
- offset = pos[first].offset;
+ vector = current_vector;
+ offset = current_offset;
next:
vector += 8;
if (vector >= FIRST_SYSTEM_VECTOR) {
offset = (offset + 1) % 8;
vector = FIRST_DEVICE_VECTOR + offset;
}
- if (unlikely(pos[first].vector == vector))
+ if (unlikely(current_vector == vector))
continue;
if (vector == IA32_SYSCALL_VECTOR)
goto next;
- for_each_cpu_mask(new_cpu, domain)
- if (per_cpu(vector_irq, cpu)[vector] != -1)
+ for_each_cpu_mask(new_cpu, new_mask)
+ if (per_cpu(vector_irq, new_cpu)[vector] != -1)
goto next;
/* Found one! */
- for_each_cpu_mask(new_cpu, domain) {
- pos[cpu].vector = vector;
- pos[cpu].offset = offset;
- }
+ current_vector = vector;
+ current_offset = offset;
if (old_vector >= 0) {
+ cpumask_t old_mask;
int old_cpu;
- for_each_cpu_mask(old_cpu, irq_domain[irq])
+ cpus_and(old_mask, irq_domain[irq], cpu_online_map);
+ for_each_cpu_mask(old_cpu, old_mask)
per_cpu(vector_irq, old_cpu)[old_vector] = -1;
}
- for_each_cpu_mask(new_cpu, domain)
+ for_each_cpu_mask(new_cpu, new_mask)
per_cpu(vector_irq, new_cpu)[vector] = irq;
irq_vector[irq] = vector;
irq_domain[irq] = domain;
return vector;
}
+void __setup_vector_irq(int cpu)
+{
+ /* Initialize vector_irq on a new cpu */
+ /* This function must be called with vector_lock held */
+ unsigned long flags;
+ int irq, vector;
+
+
+ /* Mark the inuse vectors */
+ for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) {
+ if (!cpu_isset(cpu, irq_domain[irq]))
+ continue;
+ vector = irq_vector[irq];
+ per_cpu(vector_irq, cpu)[vector] = irq;
+ }
+ /* Mark the free vectors */
+ for (vector = 0; vector < NR_VECTORS; ++vector) {
+ irq = per_cpu(vector_irq, cpu)[vector];
+ if (irq < 0)
+ continue;
+ if (!cpu_isset(cpu, irq_domain[irq]))
+ per_cpu(vector_irq, cpu)[vector] = -1;
+ }
+}
+
+
extern void (*interrupt[NR_IRQS])(void);
static struct irq_chip ioapic_chip;
{
cpumask_t mask;
unsigned vector;
+ unsigned long flags;
+ spin_lock_irqsave(&vector_lock, flags);
vector = irq_vector[irq];
cpus_clear(mask);
- cpu_set(vector >> 8, mask);
+ cpu_set(first_cpu(irq_domain[irq]), mask);
- send_IPI_mask(mask, vector & 0xff);
+ send_IPI_mask(mask, vector);
+ spin_unlock_irqrestore(&vector_lock, flags);
return 1;
}
#define ONE_BASED_CHASSIS_NUM 1
/* register offsets inside the host bridge space */
-#define PHB_CSR_OFFSET 0x0110
+#define CALGARY_CONFIG_REG 0x0108
+#define PHB_CSR_OFFSET 0x0110 /* Channel Status */
#define PHB_PLSSR_OFFSET 0x0120
#define PHB_CONFIG_RW_OFFSET 0x0160
#define PHB_IOBASE_BAR_LOW 0x0170
#define TAR_VALID 0x0000000000000008UL
/* CSR (Channel/DMA Status Register) */
#define CSR_AGENT_MASK 0xffe0ffff
+/* CCR (Calgary Configuration Register) */
+#define CCR_2SEC_TIMEOUT 0x000000000000000EUL
#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */
#define MAX_NUM_CHASSIS 8 /* max number of chassis */
}
}
+static void __init calgary_increase_split_completion_timeout(void __iomem *bbar,
+ unsigned char busnum)
+{
+ u64 val64;
+ void __iomem *target;
+ unsigned long phb_shift = -1;
+ u64 mask;
+
+ switch (busno_to_phbid(busnum)) {
+ case 0: phb_shift = (63 - 19);
+ break;
+ case 1: phb_shift = (63 - 23);
+ break;
+ case 2: phb_shift = (63 - 27);
+ break;
+ case 3: phb_shift = (63 - 35);
+ break;
+ default:
+ BUG_ON(busno_to_phbid(busnum));
+ }
+
+ target = calgary_reg(bbar, CALGARY_CONFIG_REG);
+ val64 = be64_to_cpu(readq(target));
+
+ /* zero out this PHB's timer bits */
+ mask = ~(0xFUL << phb_shift);
+ val64 &= mask;
+ val64 |= (CCR_2SEC_TIMEOUT << phb_shift);
+ writeq(cpu_to_be64(val64), target);
+ readq(target); /* flush */
+}
+
static void __init calgary_enable_translation(struct pci_dev *dev)
{
u32 val32;
writel(cpu_to_be32(val32), target);
readl(target); /* flush */
+ /*
+ * Give split completion a longer timeout on bus 1 for aic94xx
+ * http://bugzilla.kernel.org/show_bug.cgi?id=7180
+ */
+ if (busnum == 1)
+ calgary_increase_split_completion_timeout(bbar, busnum);
+
init_timer(&tbl->watchdog_timer);
tbl->watchdog_timer.function = &calgary_watchdog;
tbl->watchdog_timer.data = (unsigned long)dev;
* smp_call_function().
*/
lock_ipi_call_lock();
+ spin_lock(&vector_lock);
+ /* Setup the per cpu irq handling data structures */
+ __setup_vector_irq(smp_processor_id());
/*
* Allow the master to continue.
*/
cpu_set(smp_processor_id(), cpu_online_map);
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+ spin_unlock(&vector_lock);
unlock_ipi_call_lock();
cpu_idle();
cpu, node);
}
-
alternatives_smp_switch(1);
c_idle.idle = get_idle_for_cpu(cpu);
local_irq_disable();
remove_siblinginfo(cpu);
+ spin_lock(&vector_lock);
/* It's now safe to remove this processor from the online map */
cpu_clear(cpu, cpu_online_map);
+ spin_unlock(&vector_lock);
remove_cpu_from_maps();
fixup_irqs(cpu_online_map);
return 0;
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
#ifdef CONFIG_ACPI
/* But TSC doesn't tick in C3 so don't use it there */
- if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
+ if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
return 1;
#endif
return 0;
text PT_LOAD FLAGS(5); /* R_E */
data PT_LOAD FLAGS(7); /* RWE */
user PT_LOAD FLAGS(7); /* RWE */
+ data.init PT_LOAD FLAGS(7); /* RWE */
note PT_NOTE FLAGS(4); /* R__ */
}
SECTIONS
. = ALIGN(8192); /* init_task */
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
*(.data.init_task)
- } :data
+ }:data.init
. = ALIGN(4096);
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
return hotadd_percent > 0;
}
#else
-int update_end_of_memory(unsigned long end) {return 0;}
+int update_end_of_memory(unsigned long end) {return -1;}
static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
static inline int save_add_info(void) {return 1;}
push_node_boundaries(node, nd->start >> PAGE_SHIFT,
nd->end >> PAGE_SHIFT);
- if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
+ if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) {
/* Ignore hotadd region. Undo damage */
printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
*nd = oldnode;
#
# Reuse the i386 PCI subsystem
#
-CFLAGS += -Iarch/i386/pci
+EXTRA_CFLAGS += -Iarch/i386/pci
obj-y := i386.o
obj-$(CONFIG_PCI_DIRECT)+= direct.o
config ATA
tristate "ATA device support"
+ depends on BLOCK
depends on !(M32R || M68K) || BROKEN
depends on !SUN4 || BROKEN
select SCSI
/* hmmm... a spurious interupt */
/* some devices send D2H reg with I bit set during NCQ command phase */
- if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS)
+ if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
return;
/* ignore interim PIO setup fis interrupts */
.present_shift = 8,
.map = {
/* PM PS SM SS MAP */
- { P0, NA, P1, NA }, /* 00b (hardwired) */
+ { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */
{ RV, RV, RV, RV },
- { RV, RV, RV, RV }, /* 10b (never) */
+ { IDE, IDE, NA, NA }, /* 10b (IDE mode) */
{ RV, RV, RV, RV },
},
};
mask = (1 << 2) | (1 << 0);
if ((tmp8 & mask) != mask)
legacy_mode = (1 << 3);
+#if defined(CONFIG_NO_ATA_LEGACY)
+ /* Some platforms with PCI limits cannot address compat
+ port space. In that case we punt if their firmware has
+ left a device in compatibility mode */
+ if (legacy_mode) {
+ printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
+ return -EOPNOTSUPP;
+ }
+#endif
}
rc = pci_request_regions(pdev, DRV_NAME);
static void __exit amb_module_exit (void)
{
PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module");
-
- return pci_unregister_driver(&amb_driver);
+
+ pci_unregister_driver(&amb_driver);
}
module_init(amb_module_init);
r = ROUND_UP;
}
error = make_rate (pcr, r, &tmc0, NULL);
+ if (error) {
+ kfree(tc);
+ return error;
+ }
}
fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
}
WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK);
}
-static u16 __init read_bia (const hrz_dev * dev, u16 addr)
+static u16 __devinit read_bia (const hrz_dev * dev, u16 addr)
{
u32 ctrl = rd_regl (dev, CONTROL_0_REG);
static void __exit hrz_module_exit (void) {
PRINTD (DBG_FLOW, "cleanup_module");
-
- return pci_unregister_driver(&hrz_driver);
+
+ pci_unregister_driver(&hrz_driver);
}
module_init(hrz_module_init);
{
ns_dev *card;
pool_levels pl;
- int btype;
+ long btype;
unsigned long flags;
card = dev->dev_data;
case NS_ADJBUFLEV:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- btype = (int) arg; /* an int is the same size as a pointer */
+ btype = (long) arg; /* a long is the same size as a pointer or bigger */
switch (btype)
{
case NS_BUFTYPE_SMALL:
{
int return_code;
unsigned long t;
- unsigned long rem;
memset(inq_buff, 0, sizeof(InquiryData_struct));
if (withirq)
printk(KERN_WARNING
"cciss: reading geometry failed, volume "
"does not support reading geometry\n");
- drv->block_size = block_size;
- drv->nr_blocks = total_size;
drv->heads = 255;
drv->sectors = 32; // Sectors per track
- t = drv->heads * drv->sectors;
- drv->cylinders = total_size;
- rem = do_div(drv->cylinders, t);
} else {
- drv->block_size = block_size;
- drv->nr_blocks = total_size;
drv->heads = inq_buff->data_byte[6];
drv->sectors = inq_buff->data_byte[7];
drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
drv->cylinders += inq_buff->data_byte[5];
drv->raid_level = inq_buff->data_byte[8];
- t = drv->heads * drv->sectors;
- if (t > 1) {
- drv->cylinders = total_size;
- rem = do_div(drv->cylinders, t);
- }
+ }
+ drv->block_size = block_size;
+ drv->nr_blocks = total_size;
+ t = drv->heads * drv->sectors;
+ if (t > 1) {
+ unsigned rem = sector_div(total_size, t);
+ if (rem)
+ total_size++;
+ drv->cylinders = total_size;
}
} else { /* Get geometry failed */
printk(KERN_WARNING "cciss: reading geometry failed\n");
static int uninorth_rev;
static int is_u3;
+static char __devinitdata *aperture = NULL;
static int uninorth_fetch_size(void)
{
- int i;
- u32 temp;
- struct aper_size_info_32 *values;
-
- pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
- temp &= ~(0xfffff000);
- values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
-
- for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
- if (temp == values[i].size_value) {
- agp_bridge->previous_size =
- agp_bridge->current_size = (void *) (values + i);
- agp_bridge->aperture_size_idx = i;
- return values[i].size;
+ int i, size = 0;
+ struct aper_size_info_32 *values =
+ A_SIZE_32(agp_bridge->driver->aperture_sizes);
+
+ if (aperture) {
+ char *save = aperture;
+
+ size = memparse(aperture, &aperture) >> 20;
+ aperture = save;
+
+ for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+ if (size == values[i].size)
+ break;
+
+ if (i == agp_bridge->driver->num_aperture_sizes) {
+ printk(KERN_ERR PFX "Invalid aperture size, using"
+ " default\n");
+ size = 0;
+ aperture = NULL;
}
}
- agp_bridge->previous_size =
- agp_bridge->current_size = (void *) (values + 1);
- agp_bridge->aperture_size_idx = 1;
- return values[1].size;
+ if (!size) {
+ for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+ if (values[i].size == 32)
+ break;
+ }
- return 0;
+ agp_bridge->previous_size =
+ agp_bridge->current_size = (void *)(values + i);
+ agp_bridge->aperture_size_idx = i;
+ return values[i].size;
}
static void uninorth_tlbflush(struct agp_memory *mem)
module_init(agp_uninorth_init);
module_exit(agp_uninorth_cleanup);
+module_param(aperture, charp, 0);
+MODULE_PARM_DESC(aperture,
+ "Aperture size, must be power of two between 4MB and an\n"
+ "\t\tupper limit specific to the UniNorth revision.\n"
+ "\t\tDefault: 32M");
+
MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
MODULE_LICENSE("GPL");
list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
if (!list) {
+ if (map->type == _DRM_REGISTERS)
+ drm_ioremapfree(map->handle, map->size, dev);
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
map->offset;
ret = drm_map_handle(dev, &list->hash, user_token, 0);
if (ret) {
+ if (map->type == _DRM_REGISTERS)
+ drm_ioremapfree(map->handle, map->size, dev);
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
mutex_unlock(&dev->struct_mutex);
struct class *drm_sysfs_create(struct module *owner, char *name)
{
struct class *class;
+ int err;
class = class_create(owner, name);
- if (!class)
- return class;
+ if (!class) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ err = class_create_file(class, &class_attr_version);
+ if (err)
+ goto err_out_class;
- class_create_file(class, &class_attr_version);
return class;
+
+err_out_class:
+ class_destroy(class);
+err_out:
+ return ERR_PTR(err);
}
/**
struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
{
struct class_device *class_dev;
- int i;
+ int i, j, err;
class_dev = class_device_create(cs, NULL,
MKDEV(DRM_MAJOR, head->minor),
&(head->dev->pdev)->dev,
"card%d", head->minor);
- if (!class_dev)
- return NULL;
+ if (!class_dev) {
+ err = -ENOMEM;
+ goto err_out;
+ }
class_set_devdata(class_dev, head);
- for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
- class_device_create_file(class_dev, &class_device_attrs[i]);
+ for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) {
+ err = class_device_create_file(class_dev,
+ &class_device_attrs[i]);
+ if (err)
+ goto err_out_files;
+ }
+
return class_dev;
+
+err_out_files:
+ if (i > 0)
+ for (j = 0; j < i; j++)
+ class_device_remove_file(class_dev,
+ &class_device_attrs[i]);
+ class_device_unregister(class_dev);
+err_out:
+ return ERR_PTR(err);
}
/**
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_IRQ_VBL,
+ .dev_priv_size = sizeof(drm_mga_buf_priv_t),
.load = mga_driver_load,
.unload = mga_driver_unload,
.lastclose = mga_driver_lastclose,
return 0;
}
+static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
+{
+ u32 *cmd = (u32 *) cmdbuf->buf;
+ int count, ret;
+ RING_LOCALS;
+
+ count=(cmd[0]>>16) & 0x3fff;
+
+ if ((cmd[1] & 0x8000ffff) != 0x80000810) {
+ DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+ return DRM_ERR(EINVAL);
+ }
+ ret = r300_check_offset(dev_priv, cmd[2]);
+ if (ret) {
+ DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+ return DRM_ERR(EINVAL);
+ }
+
+ BEGIN_RING(count+2);
+ OUT_RING(cmd[0]);
+ OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
+ ADVANCE_RING();
+
+ cmdbuf->buf += (count+2)*4;
+ cmdbuf->bufsz -= (count+2)*4;
+
+ return 0;
+}
+
static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
drm_radeon_kcmd_buffer_t *cmdbuf)
{
case RADEON_CNTL_BITBLT_MULTI:
return r300_emit_bitblt_multi(dev_priv, cmdbuf);
+ case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
+ return r300_emit_indx_buffer(dev_priv, cmdbuf);
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
- case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
case RADEON_WAIT_FOR_IDLE:
case RADEON_CP_NOP:
/* these packets are safe */
unsigned int *cmdsz)
{
u32 *cmd = (u32 *) cmdbuf->buf;
+ u32 offset, narrays;
+ int count, i, k;
*cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
return DRM_ERR(EINVAL);
}
- /* Check client state and fix it up if necessary */
- if (cmd[0] & 0x8000) { /* MSB of opcode: next DWORD GUI_CNTL */
- u32 offset;
+ switch(cmd[0] & 0xff00) {
+ /* XXX Are there old drivers needing other packets? */
+ case RADEON_3D_DRAW_IMMD:
+ case RADEON_3D_DRAW_VBUF:
+ case RADEON_3D_DRAW_INDX:
+ case RADEON_WAIT_FOR_IDLE:
+ case RADEON_CP_NOP:
+ case RADEON_3D_CLEAR_ZMASK:
+/* case RADEON_CP_NEXT_CHAR:
+ case RADEON_CP_PLY_NEXTSCAN:
+ case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
+ /* these packets are safe */
+ break;
+
+ case RADEON_CP_3D_DRAW_IMMD_2:
+ case RADEON_CP_3D_DRAW_VBUF_2:
+ case RADEON_CP_3D_DRAW_INDX_2:
+ case RADEON_3D_CLEAR_HIZ:
+ /* safe but r200 only */
+ if (dev_priv->microcode_version != UCODE_R200) {
+ DRM_ERROR("Invalid 3d packet for r100-class chip\n");
+ return DRM_ERR(EINVAL);
+ }
+ break;
+
+ case RADEON_3D_LOAD_VBPNTR:
+ count = (cmd[0] >> 16) & 0x3fff;
+
+ if (count > 18) { /* 12 arrays max */
+ DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
+ count);
+ return DRM_ERR(EINVAL);
+ }
+
+ /* carefully check packet contents */
+ narrays = cmd[1] & ~0xc000;
+ k = 0;
+ i = 2;
+ while ((k < narrays) && (i < (count + 2))) {
+ i++; /* skip attribute field */
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
+ DRM_ERROR
+ ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
+ k, i);
+ return DRM_ERR(EINVAL);
+ }
+ k++;
+ i++;
+ if (k == narrays)
+ break;
+ /* have one more to process, they come in pairs */
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[i])) {
+ DRM_ERROR
+ ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
+ k, i);
+ return DRM_ERR(EINVAL);
+ }
+ k++;
+ i++;
+ }
+ /* do the counts match what we expect ? */
+ if ((k != narrays) || (i != (count + 2))) {
+ DRM_ERROR
+ ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
+ k, i, narrays, count + 1);
+ return DRM_ERR(EINVAL);
+ }
+ break;
+
+ case RADEON_3D_RNDR_GEN_INDX_PRIM:
+ if (dev_priv->microcode_version != UCODE_R100) {
+ DRM_ERROR("Invalid 3d packet for r200-class chip\n");
+ return DRM_ERR(EINVAL);
+ }
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[1])) {
+ DRM_ERROR("Invalid rndr_gen_indx offset\n");
+ return DRM_ERR(EINVAL);
+ }
+ break;
+
+ case RADEON_CP_INDX_BUFFER:
+ if (dev_priv->microcode_version != UCODE_R200) {
+ DRM_ERROR("Invalid 3d packet for r100-class chip\n");
+ return DRM_ERR(EINVAL);
+ }
+ if ((cmd[1] & 0x8000ffff) != 0x80000810) {
+ DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+ return DRM_ERR(EINVAL);
+ }
+ if (radeon_check_and_fixup_offset(dev_priv, filp_priv, &cmd[2])) {
+ DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+ return DRM_ERR(EINVAL);
+ }
+ break;
+
+ case RADEON_CNTL_HOSTDATA_BLT:
+ case RADEON_CNTL_PAINT_MULTI:
+ case RADEON_CNTL_BITBLT_MULTI:
+ /* MSB of opcode: next DWORD GUI_CNTL */
if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
| RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
offset = cmd[2] << 10;
}
cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
}
+ break;
+
+ default:
+ DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
+ return DRM_ERR(EINVAL);
}
return 0;
dev_priv->status = NULL;
}
if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) {
+ dev->agp_buffer_token = init->buffers_offset;
dev->agp_buffer_map = drm_core_findmap(dev,
init->buffers_offset);
if (!dev->agp_buffer_map) {
if (cmdbuf.size) {
kcmd_addr = drm_alloc(cmdbuf.size * 8, DRM_MEM_DRIVER);
if (kcmd_addr == NULL)
- return ENOMEM;
+ return DRM_ERR(ENOMEM);
if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf.cmd_addr,
cmdbuf.size * 8))
typedef struct _moxa_pci_devinfo {
ushort busNum;
ushort devNum;
+ struct pci_dev *pdev;
} moxa_pci_devinfo;
typedef struct _moxa_board_conf {
board->busType = MOXA_BUS_TYPE_PCI;
board->pciInfo.busNum = p->bus->number;
board->pciInfo.devNum = p->devfn >> 3;
+ board->pciInfo.pdev = p;
+ /* don't lose the reference in the next pci_get_device iteration */
+ pci_dev_get(p);
return (0);
}
if (tty_unregister_driver(moxaDriver))
printk("Couldn't unregister MOXA Intellio family serial driver\n");
put_tty_driver(moxaDriver);
+
+ for (i = 0; i < MAX_BOARDS; i++)
+ if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
+ pci_dev_put(moxa_boards[i].pciInfo.pdev);
+
if (verbose)
printk("Done\n");
}
** the host.
*/
struct Host {
+ struct pci_dev *pdev;
unsigned char Type; /* RIO_EISA, RIO_MCA, ... */
unsigned char Ivec; /* POLLED or ivec number */
unsigned char Mode; /* Control stuff */
rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
fix_rio_pci(pdev);
+
+ p->RIOHosts[p->RIONumHosts].pdev = pdev;
+ pci_dev_get(pdev);
+
p->RIOLastPCISearch = 0;
p->RIONumHosts++;
found++;
((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24);
rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
+ p->RIOHosts[p->RIONumHosts].pdev = pdev;
+ pci_dev_get(pdev);
+
p->RIOLastPCISearch = 0;
p->RIONumHosts++;
found++;
}
/* It is safe/allowed to del_timer a non-active timer */
del_timer(&hp->timer);
+ if (hp->Type == RIO_PCI)
+ pci_dev_put(hp->pdev);
}
if (misc_deregister(&rio_fw_device) < 0) {
subsequently opening the file and then failing to write to it for
longer than 1 minute will result in rebooting the machine. This
could be useful for a networked machine that needs to come back
- online as fast as possible after a lock-up. There's both a watchdog
+ on-line as fast as possible after a lock-up. There's both a watchdog
implementation entirely in software (which can sometimes fail to
reboot the machine) and a driver for hardware watchdog boards, which
are more robust and can also keep track of the temperature inside
# ARM Architecture
-config AT91_WATCHDOG
+config AT91RM9200_WATCHDOG
tristate "AT91RM9200 watchdog"
depends on WATCHDOG && ARCH_AT91RM9200
help
tristate "DC21285 watchdog"
depends on WATCHDOG && FOOTBRIDGE
help
- The Intel Footbridge chip contains a builtin watchdog circuit. Say Y
+ The Intel Footbridge chip contains a built-in watchdog circuit. Say Y
here if you wish to use this. Alternatively say M to compile the
driver as a module, which will be called wdt285.
Most people will say N.
config IBMASR
- tristate "IBM Automatic Server Restart"
- depends on WATCHDOG && X86
- help
+ tristate "IBM Automatic Server Restart"
+ depends on WATCHDOG && X86
+ help
This is the driver for the IBM Automatic Server Restart watchdog
- timer builtin into some eServer xSeries machines.
+ timer built-in into some eServer xSeries machines.
To compile this driver as a module, choose M here: the
module will be called ibmasr.
To compile this driver as a module, choose M here: the
module will be called i8xx_tco.
+ Note: This driver will be removed in the near future. Please
+ use the Intel TCO Timer/Watchdog driver.
+
config ITCO_WDT
- tristate "Intel TCO Timer/Watchdog (EXPERIMENTAL)"
- depends on WATCHDOG && (X86 || IA64) && PCI && EXPERIMENTAL
+ tristate "Intel TCO Timer/Watchdog"
+ depends on WATCHDOG && (X86 || IA64) && PCI
---help---
Hardware driver for the intel TCO timer based watchdog devices.
These drivers are included in the Intel 82801 I/O Controller
- Hub family 'from ICH0 up to ICH7) and in the Intel 6300ESB
+ Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB
controller hub.
The TCO (Total Cost of Ownership) timer is a watchdog timer
To compile this driver as a module, choose M here: the
module will be called cpu5wdt.
+config SMSC37B787_WDT
+ tristate "Winbond SMsC37B787 Watchdog Timer"
+ depends on WATCHDOG && X86
+ ---help---
+ This is the driver for the hardware watchdog component on the
+ Winbond SMsC37B787 chipset as used on the NetRunner Mainboard
+ from Vision Systems and maybe others.
+
+ This watchdog simply watches your kernel to make sure it doesn't
+ freeze, and if it does, it reboots your computer after a certain
+ amount of time.
+
+ Usually a userspace daemon will notify the kernel WDT driver that
+ userspace is still alive, at regular intervals.
+
+ To compile this driver as a module, choose M here: the
+ module will be called smsc37b787_wdt.
+
+ Most people will say N.
+
config W83627HF_WDT
tristate "W83627HF Watchdog Timer"
depends on WATCHDOG && X86
Most people will say N.
+config W83697HF_WDT
+ tristate "W83697HF/W83697HG Watchdog Timer"
+ depends on WATCHDOG && X86
+ ---help---
+ This is the driver for the hardware watchdog on the W83697HF/HG
+ chipset as used in Dedibox/VIA motherboards (and likely others).
+ This watchdog simply watches your kernel to make sure it doesn't
+ freeze, and if it does, it reboots your computer after a certain
+ amount of time.
+
+ To compile this driver as a module, choose M here: the
+ module will be called w83697hf_wdt.
+
+ Most people will say N.
+
config W83877F_WDT
tristate "W83877F (EMACS) Watchdog Timer"
depends on WATCHDOG && X86
depends on WATCHDOG && X86
---help---
If you are using a ZF Micro MachZ processor, say Y here, otherwise
- N. This is the driver for the watchdog timer builtin on that
+ N. This is the driver for the watchdog timer built-in on that
processor using ZF-Logic interface. This watchdog simply watches
your kernel to make sure it doesn't freeze, and if it does, it
reboots your computer after a certain amount of time.
To compile this driver as a module, choose M here: the
module will be called sbc_epx_c3.
-
# PowerPC Architecture
config 8xx_WDT
help
This driver adds watchdog support for the RTAS watchdog.
- To compile this driver as a module, choose M here. The module
+ To compile this driver as a module, choose M here. The module
will be called wdrtas.
# MIPS Architecture
help
If you say Y here, user applications will be able to mmap the
WDT/CPG registers.
-#
+
# SPARC64 Architecture
config WATCHDOG_CP1XXX
obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
# ARM Architecture
-obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
+obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
+obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
+obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
* 82801GDH (ICH7DH) : document number 307013-002, 307014-009,
* 82801GBM (ICH7-M) : document number 307013-002, 307014-009,
* 82801GHM (ICH7-M DH) : document number 307013-002, 307014-009,
+ * 82801HB (ICH8) : document number 313056-002, 313057-004,
+ * 82801HR (ICH8R) : document number 313056-002, 313057-004,
+ * 82801HH (ICH8DH) : document number 313056-002, 313057-004,
+ * 82801HO (ICH8DO) : document number 313056-002, 313057-004,
* 6300ESB (6300ESB) : document number 300641-003
*/
/* Module and version information */
#define DRV_NAME "iTCO_wdt"
#define DRV_VERSION "1.00"
-#define DRV_RELDATE "30-Jul-2006"
+#define DRV_RELDATE "08-Oct-2006"
#define PFX DRV_NAME ": "
/* Includes */
TCO_ICH7, /* ICH7 & ICH7R */
TCO_ICH7M, /* ICH7-M */
TCO_ICH7MDH, /* ICH7-M DH */
+ TCO_ICH8, /* ICH8 & ICH8R */
+ TCO_ICH8DH, /* ICH8DH */
+ TCO_ICH8DO, /* ICH8DO */
};
static struct {
{"ICH7 or ICH7R", 2},
{"ICH7-M", 2},
{"ICH7-M DH", 2},
+ {"ICH8 or ICH8R", 2},
+ {"ICH8DH", 2},
+ {"ICH8DO", 2},
{NULL,0}
};
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7M },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH7MDH },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO },
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
spin_unlock(&iTCO_wdt_private.io_lock);
*time_left = (val8 * 6) / 10;
- }
+ } else
+ return -EINVAL;
return 0;
}
{
int new_options, retval = -EINVAL;
int new_heartbeat;
- int time_left;
void __user *argp = (void __user *)arg;
int __user *p = argp;
static struct watchdog_info ident = {
case WDIOC_GETTIMELEFT:
{
+ int time_left;
+
if (iTCO_wdt_get_timeleft(&time_left))
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res == NULL) {
printk(KERN_INFO PFX "failed to get irq resource\n");
+ iounmap(wdt_base);
return -ENOENT;
}
ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
if (ret != 0) {
printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
+ iounmap(wdt_base);
return ret;
}
wdt_clock = clk_get(&pdev->dev, "watchdog");
if (wdt_clock == NULL) {
printk(KERN_INFO PFX "failed to find watchdog clock source\n");
+ iounmap(wdt_base);
return -ENOENT;
}
if (ret) {
printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
WATCHDOG_MINOR, ret);
+ iounmap(wdt_base);
return ret;
}
wdt_clock = NULL;
}
+ iounmap(wdt_base);
misc_deregister(&s3c2410wdt_miscdev);
return 0;
}
--- /dev/null
+/*
+ * SMsC 37B787 Watchdog Timer driver for Linux 2.6.x.x
+ *
+ * Based on acquirewdt.c by Alan Cox <alan@redhat.com>
+ * and some other existing drivers
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * The authors do NOT admit liability nor provide warranty for
+ * any of this software. This material is provided "AS-IS" in
+ * the hope that it may be useful for others.
+ *
+ * (C) Copyright 2003-2006 Sven Anders <anders@anduras.de>
+ *
+ * History:
+ * 2003 - Created version 1.0 for Linux 2.4.x.
+ * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE
+ * features. Released version 1.1
+ *
+ * Theory of operation:
+ *
+ * A Watchdog Timer (WDT) is a hardware circuit that can
+ * reset the computer system in case of a software fault.
+ * You probably knew that already.
+ *
+ * Usually a userspace daemon will notify the kernel WDT driver
+ * via the /dev/watchdog special device file that userspace is
+ * still alive, at regular intervals. When such a notification
+ * occurs, the driver will usually tell the hardware watchdog
+ * that everything is in order, and that the watchdog should wait
+ * for yet another little while to reset the system.
+ * If userspace fails (RAM error, kernel bug, whatever), the
+ * notifications cease to occur, and the hardware watchdog will
+ * reset the system (causing a reboot) after the timeout occurs.
+ *
+ * Create device with:
+ * mknod /dev/watchdog c 10 130
+ *
+ * For an example userspace keep-alive daemon, see:
+ * Documentation/watchdog/watchdog.txt
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+/* enable support for minutes as units? */
+/* (does not always work correctly, so disabled by default!) */
+#define SMSC_SUPPORT_MINUTES
+#undef SMSC_SUPPORT_MINUTES
+
+#define MAX_TIMEOUT 255
+
+#define UNIT_SECOND 0
+#define UNIT_MINUTE 1
+
+#define MODNAME "smsc37b787_wdt: "
+#define VERSION "1.1"
+
+#define IOPORT 0x3F0
+#define IOPORT_SIZE 2
+#define IODEV_NO 8
+
+static int unit = UNIT_SECOND; /* timer's unit */
+static int timeout = 60; /* timeout value: default is 60 "units" */
+static unsigned long timer_enabled = 0; /* is the timer enabled? */
+
+static char expect_close; /* is the close expected? */
+
+static spinlock_t io_lock; /* to guard the watchdog from io races */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+/* -- Low level function ----------------------------------------*/
+
+/* unlock the IO chip */
+
+static inline void open_io_config(void)
+{
+ outb(0x55, IOPORT);
+ mdelay(1);
+ outb(0x55, IOPORT);
+}
+
+/* lock the IO chip */
+static inline void close_io_config(void)
+{
+ outb(0xAA, IOPORT);
+}
+
+/* select the IO device */
+static inline void select_io_device(unsigned char devno)
+{
+ outb(0x07, IOPORT);
+ outb(devno, IOPORT+1);
+}
+
+/* write to the control register */
+static inline void write_io_cr(unsigned char reg, unsigned char data)
+{
+ outb(reg, IOPORT);
+ outb(data, IOPORT+1);
+}
+
+/* read from the control register */
+static inline char read_io_cr(unsigned char reg)
+{
+ outb(reg, IOPORT);
+ return inb(IOPORT+1);
+}
+
+/* -- Medium level functions ------------------------------------*/
+
+static inline void gpio_bit12(unsigned char reg)
+{
+ // -- General Purpose I/O Bit 1.2 --
+ // Bit 0, In/Out: 0 = Output, 1 = Input
+ // Bit 1, Polarity: 0 = No Invert, 1 = Invert
+ // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
+ // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17,
+ // 11 = Either Edge Triggered Intr. 2
+ // Bit 5/6 (Reserved)
+ // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
+ write_io_cr(0xE2, reg);
+}
+
+static inline void gpio_bit13(unsigned char reg)
+{
+ // -- General Purpose I/O Bit 1.3 --
+ // Bit 0, In/Out: 0 = Output, 1 = Input
+ // Bit 1, Polarity: 0 = No Invert, 1 = Invert
+ // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
+ // Bit 3, Function select: 0 = GPI/O, 1 = LED
+ // Bit 4-6 (Reserved)
+ // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
+ write_io_cr(0xE3, reg);
+}
+
+static inline void wdt_timer_units(unsigned char new_units)
+{
+ // -- Watchdog timer units --
+ // Bit 0-6 (Reserved)
+ // Bit 7, WDT Time-out Value Units Select
+ // (0 = Minutes, 1 = Seconds)
+ write_io_cr(0xF1, new_units);
+}
+
+static inline void wdt_timeout_value(unsigned char new_timeout)
+{
+ // -- Watchdog Timer Time-out Value --
+ // Bit 0-7 Binary coded units (0=Disabled, 1..255)
+ write_io_cr(0xF2, new_timeout);
+}
+
+static inline void wdt_timer_conf(unsigned char conf)
+{
+ // -- Watchdog timer configuration --
+ // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O
+ // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
+ // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr.
+ // Bit 3 Reset the timer
+ // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled)
+ // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
+ // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
+ write_io_cr(0xF3, conf);
+}
+
+static inline void wdt_timer_ctrl(unsigned char reg)
+{
+ // -- Watchdog timer control --
+ // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured
+ // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz
+ // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning)
+ // Bit 3 P20 Force Timeout enabled:
+ // 0 = P20 activity does not generate the WD timeout event
+ // 1 = P20 Allows rising edge of P20, from the keyboard
+ // controller, to force the WD timeout event.
+ // Bit 4 (Reserved)
+ // -- Soft power management --
+ // Bit 5 Stop Counter: 1 = Stop software power down counter
+ // set via register 0xB8, (self-cleaning)
+ // (Upon read: 0 = Counter running, 1 = Counter stopped)
+ // Bit 6 Restart Counter: 1 = Restart software power down counter
+ // set via register 0xB8, (self-cleaning)
+ // Bit 7 SPOFF: 1 = Force software power down (self-cleaning)
+
+ write_io_cr(0xF4, reg);
+}
+
+/* -- Higher level functions ------------------------------------*/
+
+/* initialize watchdog */
+
+static void wb_smsc_wdt_initialize(void)
+{
+ unsigned char old;
+
+ spin_lock(&io_lock);
+ open_io_config();
+ select_io_device(IODEV_NO);
+
+ // enable the watchdog
+ gpio_bit13(0x08); // Select pin 80 = LED not GPIO
+ gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert
+
+ // disable the timeout
+ wdt_timeout_value(0);
+
+ // reset control register
+ wdt_timer_ctrl(0x00);
+
+ // reset configuration register
+ wdt_timer_conf(0x00);
+
+ // read old (timer units) register
+ old = read_io_cr(0xF1) & 0x7F;
+ if (unit == UNIT_SECOND) old |= 0x80; // set to seconds
+
+ // set the watchdog timer units
+ wdt_timer_units(old);
+
+ close_io_config();
+ spin_unlock(&io_lock);
+}
+
+/* shutdown the watchdog */
+
+static void wb_smsc_wdt_shutdown(void)
+{
+ spin_lock(&io_lock);
+ open_io_config();
+ select_io_device(IODEV_NO);
+
+ // disable the watchdog
+ gpio_bit13(0x09);
+ gpio_bit12(0x09);
+
+ // reset watchdog config register
+ wdt_timer_conf(0x00);
+
+ // reset watchdog control register
+ wdt_timer_ctrl(0x00);
+
+ // disable timeout
+ wdt_timeout_value(0x00);
+
+ close_io_config();
+ spin_unlock(&io_lock);
+}
+
+/* set timeout => enable watchdog */
+
+static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
+{
+ spin_lock(&io_lock);
+ open_io_config();
+ select_io_device(IODEV_NO);
+
+ // set Power LED to blink, if we enable the timeout
+ wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02);
+
+ // set timeout value
+ wdt_timeout_value(new_timeout);
+
+ close_io_config();
+ spin_unlock(&io_lock);
+}
+
+/* get timeout */
+
+static unsigned char wb_smsc_wdt_get_timeout(void)
+{
+ unsigned char set_timeout;
+
+ spin_lock(&io_lock);
+ open_io_config();
+ select_io_device(IODEV_NO);
+ set_timeout = read_io_cr(0xF2);
+ close_io_config();
+ spin_unlock(&io_lock);
+
+ return set_timeout;
+}
+
+/* disable watchdog */
+
+static void wb_smsc_wdt_disable(void)
+{
+ // set the timeout to 0 to disable the watchdog
+ wb_smsc_wdt_set_timeout(0);
+}
+
+/* enable watchdog by setting the current timeout */
+
+static void wb_smsc_wdt_enable(void)
+{
+ // set the current timeout...
+ wb_smsc_wdt_set_timeout(timeout);
+}
+
+/* reset the timer */
+
+static void wb_smsc_wdt_reset_timer(void)
+{
+ spin_lock(&io_lock);
+ open_io_config();
+ select_io_device(IODEV_NO);
+
+ // reset the timer
+ wdt_timeout_value(timeout);
+ wdt_timer_conf(0x08);
+
+ close_io_config();
+ spin_unlock(&io_lock);
+}
+
+/* return, if the watchdog is enabled (timeout is set...) */
+
+static int wb_smsc_wdt_status(void)
+{
+ return (wb_smsc_wdt_get_timeout() == 0) ? 0 : WDIOF_KEEPALIVEPING;
+}
+
+
+/* -- File operations -------------------------------------------*/
+
+/* open => enable watchdog and set initial timeout */
+
+static int wb_smsc_wdt_open(struct inode *inode, struct file *file)
+{
+ /* /dev/watchdog can only be opened once */
+
+ if (test_and_set_bit(0, &timer_enabled))
+ return -EBUSY;
+
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ /* Reload and activate timer */
+ wb_smsc_wdt_enable();
+
+ printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
+
+ return nonseekable_open(inode, file);
+}
+
+/* close => shut off the timer */
+
+static int wb_smsc_wdt_release(struct inode *inode, struct file *file)
+{
+ /* Shut off the timer. */
+
+ if (expect_close == 42) {
+ wb_smsc_wdt_disable();
+ printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n");
+ } else {
+ printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n");
+ wb_smsc_wdt_reset_timer();
+ }
+
+ clear_bit(0, &timer_enabled);
+ expect_close = 0;
+ return 0;
+}
+
+/* write => update the timer to keep the machine alive */
+
+static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
+ size_t len, loff_t *ppos)
+{
+ /* See if we got the magic character 'V' and reload the timer */
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ /* reset expect flag */
+ expect_close = 0;
+
+ /* scan to see whether or not we got the magic character */
+ for (i = 0; i != len; i++) {
+ char c;
+ if (get_user(c, data+i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+
+ /* someone wrote to us, we should reload the timer */
+ wb_smsc_wdt_reset_timer();
+ }
+ return len;
+}
+
+/* ioctl => control interface */
+
+static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int new_timeout;
+
+ union {
+ struct watchdog_info __user *ident;
+ int __user *i;
+ } uarg;
+
+ static struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING |
+ WDIOF_SETTIMEOUT |
+ WDIOF_MAGICCLOSE,
+ .firmware_version = 0,
+ .identity = "SMsC 37B787 Watchdog"
+ };
+
+ uarg.i = (int __user *)arg;
+
+ switch (cmd) {
+ default:
+ return -ENOTTY;
+
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(uarg.ident, &ident,
+ sizeof(ident)) ? -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ return put_user(wb_smsc_wdt_status(), uarg.i);
+
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, uarg.i);
+
+ case WDIOC_KEEPALIVE:
+ wb_smsc_wdt_reset_timer();
+ return 0;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_timeout, uarg.i))
+ return -EFAULT;
+
+ // the API states this is given in secs
+ if (unit == UNIT_MINUTE)
+ new_timeout /= 60;
+
+ if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
+ return -EINVAL;
+
+ timeout = new_timeout;
+ wb_smsc_wdt_set_timeout(timeout);
+
+ // fall through and return the new timeout...
+
+ case WDIOC_GETTIMEOUT:
+
+ new_timeout = timeout;
+
+ if (unit == UNIT_MINUTE)
+ new_timeout *= 60;
+
+ return put_user(new_timeout, uarg.i);
+
+ case WDIOC_SETOPTIONS:
+ {
+ int options, retval = -EINVAL;
+
+ if (get_user(options, uarg.i))
+ return -EFAULT;
+
+ if (options & WDIOS_DISABLECARD) {
+ wb_smsc_wdt_disable();
+ retval = 0;
+ }
+
+ if (options & WDIOS_ENABLECARD) {
+ wb_smsc_wdt_enable();
+ retval = 0;
+ }
+
+ return retval;
+ }
+ }
+}
+
+/* -- Notifier funtions -----------------------------------------*/
+
+static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT)
+ {
+ // set timeout to 0, to avoid possible race-condition
+ timeout = 0;
+ wb_smsc_wdt_disable();
+ }
+ return NOTIFY_DONE;
+}
+
+/* -- Module's structures ---------------------------------------*/
+
+static struct file_operations wb_smsc_wdt_fops =
+{
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = wb_smsc_wdt_write,
+ .ioctl = wb_smsc_wdt_ioctl,
+ .open = wb_smsc_wdt_open,
+ .release = wb_smsc_wdt_release,
+};
+
+static struct notifier_block wb_smsc_wdt_notifier =
+{
+ .notifier_call = wb_smsc_wdt_notify_sys,
+};
+
+static struct miscdevice wb_smsc_wdt_miscdev =
+{
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &wb_smsc_wdt_fops,
+};
+
+/* -- Module init functions -------------------------------------*/
+
+/* module's "constructor" */
+
+static int __init wb_smsc_wdt_init(void)
+{
+ int ret;
+
+ spin_lock_init(&io_lock);
+
+ printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n");
+
+ if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) {
+ printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT);
+ ret = -EBUSY;
+ goto out_pnp;
+ }
+
+ // set new maximum, if it's too big
+ if (timeout > MAX_TIMEOUT)
+ timeout = MAX_TIMEOUT;
+
+ // init the watchdog timer
+ wb_smsc_wdt_initialize();
+
+ ret = register_reboot_notifier(&wb_smsc_wdt_notifier);
+ if (ret) {
+ printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret);
+ goto out_io;
+ }
+
+ ret = misc_register(&wb_smsc_wdt_miscdev);
+ if (ret) {
+ printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR);
+ goto out_rbt;
+ }
+
+ // output info
+ printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
+ printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout);
+
+ // ret = 0
+
+out_clean:
+ return ret;
+
+out_rbt:
+ unregister_reboot_notifier(&wb_smsc_wdt_notifier);
+
+out_io:
+ release_region(IOPORT, IOPORT_SIZE);
+
+out_pnp:
+ goto out_clean;
+}
+
+/* module's "destructor" */
+
+static void __exit wb_smsc_wdt_exit(void)
+{
+ /* Stop the timer before we leave */
+ if (!nowayout)
+ {
+ wb_smsc_wdt_shutdown();
+ printk(KERN_INFO MODNAME "Watchdog disabled.\n");
+ }
+
+ misc_deregister(&wb_smsc_wdt_miscdev);
+ unregister_reboot_notifier(&wb_smsc_wdt_notifier);
+ release_region(IOPORT, IOPORT_SIZE);
+
+ printk("SMsC 37B787 watchdog component driver removed.\n");
+}
+
+module_init(wb_smsc_wdt_init);
+module_exit(wb_smsc_wdt_exit);
+
+MODULE_AUTHOR("Sven Anders <anders@anduras.de>");
+MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")");
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+#ifdef SMSC_SUPPORT_MINUTES
+module_param(unit, int, 0);
+MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0");
+#endif
+
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
static unsigned long wdt_is_open;
static char expect_close;
+static spinlock_t io_lock;
/* You must set this - there is no sane way to probe for this board. */
static int wdt_io = 0x2E;
static void
wdt_ctrl(int timeout)
{
+ spin_lock(&io_lock);
+
w83627hf_select_wd_register();
outb_p(0xF6, WDT_EFER); /* Select CRF6 */
outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */
w83627hf_unselect_wd_register();
+
+ spin_unlock(&io_lock);
}
static int
{
int ret;
+ spin_lock_init(&io_lock);
+
printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n");
if (wdt_set_heartbeat(timeout)) {
--- /dev/null
+/*
+ * w83697hf/hg WDT driver
+ *
+ * (c) Copyright 2006 Samuel Tardieu <sam@rfc1149.net>
+ * (c) Copyright 2006 Marcus Junker <junker@anduras.de>
+ *
+ * Based on w83627hf_wdt.c which is based on advantechwdt.c
+ * which is based on wdt.c.
+ * Original copyright messages:
+ *
+ * (c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
+ *
+ * (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
+ *
+ * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ * http://www.redhat.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 Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Neither Marcus Junker nor ANDURAS AG admit liability nor provide
+ * warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#define WATCHDOG_NAME "w83697hf/hg WDT"
+#define PFX WATCHDOG_NAME ": "
+#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
+
+static unsigned long wdt_is_open;
+static char expect_close;
+static spinlock_t io_lock;
+
+/* You must set this - there is no sane way to probe for this board. */
+static int wdt_io = 0x2e;
+module_param(wdt_io, int, 0);
+MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)");
+
+static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Kernel methods.
+ */
+
+#define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */
+#define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */
+#define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */
+
+static inline void
+w83697hf_unlock(void)
+{
+ outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */
+ outb_p(0x87, W83697HF_EFER); /* Again according to manual */
+}
+
+static inline void
+w83697hf_lock(void)
+{
+ outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */
+}
+
+/*
+ * The three functions w83697hf_get_reg(), w83697hf_set_reg() and
+ * w83697hf_write_timeout() must be called with the device unlocked.
+ */
+
+static unsigned char
+w83697hf_get_reg(unsigned char reg)
+{
+ outb_p(reg, W83697HF_EFIR);
+ return inb_p(W83697HF_EFDR);
+}
+
+static void
+w83697hf_set_reg(unsigned char reg, unsigned char data)
+{
+ outb_p(reg, W83697HF_EFIR);
+ outb_p(data, W83697HF_EFDR);
+}
+
+static void
+w83697hf_write_timeout(int timeout)
+{
+ w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */
+}
+
+static void
+w83697hf_select_wdt(void)
+{
+ w83697hf_unlock();
+ w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */
+}
+
+static inline void
+w83697hf_deselect_wdt(void)
+{
+ w83697hf_lock();
+}
+
+static void
+w83697hf_init(void)
+{
+ unsigned char bbuf;
+
+ w83697hf_select_wdt();
+
+ bbuf = w83697hf_get_reg(0x29);
+ bbuf &= ~0x60;
+ bbuf |= 0x20;
+ w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
+
+ bbuf = w83697hf_get_reg(0xF3);
+ bbuf &= ~0x04;
+ w83697hf_set_reg(0xF3, bbuf); /* Count mode is seconds */
+
+ w83697hf_deselect_wdt();
+}
+
+static int
+wdt_ping(void)
+{
+ spin_lock(&io_lock);
+ w83697hf_select_wdt();
+
+ w83697hf_write_timeout(timeout);
+
+ w83697hf_deselect_wdt();
+ spin_unlock(&io_lock);
+ return 0;
+}
+
+static int
+wdt_enable(void)
+{
+ spin_lock(&io_lock);
+ w83697hf_select_wdt();
+
+ w83697hf_write_timeout(timeout);
+ w83697hf_set_reg(0x30, 1); /* Enable timer */
+
+ w83697hf_deselect_wdt();
+ spin_unlock(&io_lock);
+ return 0;
+}
+
+static int
+wdt_disable(void)
+{
+ spin_lock(&io_lock);
+ w83697hf_select_wdt();
+
+ w83697hf_set_reg(0x30, 0); /* Disable timer */
+ w83697hf_write_timeout(0);
+
+ w83697hf_deselect_wdt();
+ spin_unlock(&io_lock);
+ return 0;
+}
+
+static int
+wdt_set_heartbeat(int t)
+{
+ if ((t < 1) || (t > 255))
+ return -EINVAL;
+
+ timeout = t;
+ return 0;
+}
+
+static ssize_t
+wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{
+ if (count) {
+ if (!nowayout) {
+ size_t i;
+
+ expect_close = 0;
+
+ for (i = 0; i != count; i++) {
+ char c;
+ if (get_user(c, buf+i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+ wdt_ping();
+ }
+ return count;
+}
+
+static int
+wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int new_timeout;
+ static struct watchdog_info ident = {
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
+ .firmware_version = 1,
+ .identity = "W83697HF WDT",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &ident, sizeof(ident)))
+ return -EFAULT;
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, p);
+
+ case WDIOC_KEEPALIVE:
+ wdt_ping();
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_timeout, p))
+ return -EFAULT;
+ if (wdt_set_heartbeat(new_timeout))
+ return -EINVAL;
+ wdt_ping();
+ /* Fall */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(timeout, p);
+
+ case WDIOC_SETOPTIONS:
+ {
+ int options, retval = -EINVAL;
+
+ if (get_user(options, p))
+ return -EFAULT;
+
+ if (options & WDIOS_DISABLECARD) {
+ wdt_disable();
+ retval = 0;
+ }
+
+ if (options & WDIOS_ENABLECARD) {
+ wdt_enable();
+ retval = 0;
+ }
+
+ return retval;
+ }
+
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int
+wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &wdt_is_open))
+ return -EBUSY;
+ /*
+ * Activate
+ */
+
+ wdt_enable();
+ return nonseekable_open(inode, file);
+}
+
+static int
+wdt_close(struct inode *inode, struct file *file)
+{
+ if (expect_close == 42) {
+ wdt_disable();
+ } else {
+ printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+ wdt_ping();
+ }
+ expect_close = 0;
+ clear_bit(0, &wdt_is_open);
+ return 0;
+}
+
+/*
+ * Notifier for system down
+ */
+
+static int
+wdt_notify_sys(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT) {
+ /* Turn the WDT off */
+ wdt_disable();
+ }
+ return NOTIFY_DONE;
+}
+
+/*
+ * Kernel Interfaces
+ */
+
+static struct file_operations wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = wdt_write,
+ .ioctl = wdt_ioctl,
+ .open = wdt_open,
+ .release = wdt_close,
+};
+
+static struct miscdevice wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &wdt_fops,
+};
+
+/*
+ * The WDT needs to learn about soft shutdowns in order to
+ * turn the timebomb registers off.
+ */
+
+static struct notifier_block wdt_notifier = {
+ .notifier_call = wdt_notify_sys,
+};
+
+static int
+w83697hf_check_wdt(void)
+{
+ if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
+ printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io);
+ return -EIO;
+ }
+
+ printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io);
+ w83697hf_unlock();
+ if (w83697hf_get_reg(0x20) == 0x60) {
+ printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io);
+ w83697hf_lock();
+ return 0;
+ }
+ w83697hf_lock(); /* Reprotect in case it was a compatible device */
+
+ printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io);
+ release_region(wdt_io, 2);
+ return -EIO;
+}
+
+static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 };
+
+static int __init
+wdt_init(void)
+{
+ int ret, i, found = 0;
+
+ spin_lock_init(&io_lock);
+
+ printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n");
+
+ if (wdt_io == 0) {
+ /* we will autodetect the W83697HF/HG watchdog */
+ for (i = 0; ((!found) && (w83697hf_ioports[i] != 0)); i++) {
+ wdt_io = w83697hf_ioports[i];
+ if (!w83697hf_check_wdt())
+ found++;
+ }
+ } else {
+ if (!w83697hf_check_wdt())
+ found++;
+ }
+
+ if (!found) {
+ printk (KERN_ERR PFX "No W83697HF/HG could be found\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ w83697hf_init();
+ wdt_disable(); /* Disable watchdog until first use */
+
+ if (wdt_set_heartbeat(timeout)) {
+ wdt_set_heartbeat(WATCHDOG_TIMEOUT);
+ printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n",
+ WATCHDOG_TIMEOUT);
+ }
+
+ ret = register_reboot_notifier(&wdt_notifier);
+ if (ret != 0) {
+ printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+ ret);
+ goto unreg_regions;
+ }
+
+ ret = misc_register(&wdt_miscdev);
+ if (ret != 0) {
+ printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ WATCHDOG_MINOR, ret);
+ goto unreg_reboot;
+ }
+
+ printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
+ timeout, nowayout);
+
+out:
+ return ret;
+unreg_reboot:
+ unregister_reboot_notifier(&wdt_notifier);
+unreg_regions:
+ release_region(wdt_io, 2);
+ goto out;
+}
+
+static void __exit
+wdt_exit(void)
+{
+ misc_deregister(&wdt_miscdev);
+ unregister_reboot_notifier(&wdt_notifier);
+ release_region(wdt_io, 2);
+}
+
+module_init(wdt_init);
+module_exit(wdt_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marcus Junker <junker@anduras.de>, Samuel Tardieu <sam@rfc1149.net>");
+MODULE_DESCRIPTION("w83697hf/hg WDT driver");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
v1 = read_pmtmr();
v2 = read_pmtmr();
v3 = read_pmtmr();
- } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
- || (v3 > v1 && v3 < v2));
+ } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+ || (v3 > v1 && v3 < v2)));
return (cycle_t)v2;
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
acpi_pm_check_graylist);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
+ acpi_pm_check_graylist);
#endif
#define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp))
#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0]))
-#define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp)))
+#define SC_FCMND(fcmnd) ((struct scsi_cmnd *)((long)fcmnd - (long)&(((struct scsi_cmnd *)0)->SCp)))
-static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int);
+static int fcp_scsi_queue_it(fc_channel *, struct scsi_cmnd *, fcp_cmnd *, int);
void fcp_queue_empty(fc_channel *);
static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd)
printk ("FC: %segistering unknown type %02x\n", unregister ? "Unr" : "R", type);
}
-static void fcp_scsi_done(Scsi_Cmnd *SCpnt);
+static void fcp_scsi_done(struct scsi_cmnd *SCpnt);
static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch)
{
fcp_cmnd *fcmd;
fcp_rsp *rsp;
int host_status;
- Scsi_Cmnd *SCpnt;
+ struct scsi_cmnd *SCpnt;
int sense_len;
int rsp_status;
}
-static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
+static void fcp_scsi_done(struct scsi_cmnd *SCpnt)
{
if (FCP_CMND(SCpnt)->done)
FCP_CMND(SCpnt)->done(SCpnt);
}
-static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
+static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt,
+ fcp_cmnd *fcmd, int prepare)
{
long i;
fcp_cmd *cmd;
return 0;
}
-int fcp_scsi_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *))
+int fcp_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+ void (* done)(struct scsi_cmnd *))
{
fcp_cmnd *fcmd = FCP_CMND(SCpnt);
fc_channel *fc = FC_SCMND(SCpnt);
}
}
-int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
+int fcp_scsi_abort(struct scsi_cmnd *SCpnt)
{
/* Internal bookkeeping only. Lose 1 cmd_slots slot. */
fcp_cmnd *fcmd = FCP_CMND(SCpnt);
}
#if 0
-void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt)
+void fcp_scsi_reset_done(struct scsi_cmnd *SCpnt)
{
fc_channel *fc = FC_SCMND(SCpnt);
#define FCP_RESET_TIMEOUT (2*HZ)
-int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
+int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt)
{
#if 0 /* broken junk, but if davem wants to compile this driver, let him.. */
unsigned long flags;
DECLARE_MUTEX_LOCKED(sem);
if (!fc->rst_pkt) {
- fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
+ fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
if (!fc->rst_pkt) return FAILED;
fcmd = FCP_CMND(fc->rst_pkt);
return SUCCESS;
}
-static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
+static int __fcp_scsi_host_reset(struct scsi_cmnd *SCpnt)
{
fc_channel *fc = FC_SCMND(SCpnt);
fcp_cmnd *fcmd = FCP_CMND(SCpnt);
else return FAILED;
}
-int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
+int fcp_scsi_host_reset(struct scsi_cmnd *SCpnt)
{
unsigned long flags;
int rc;
typedef struct fcp_cmnd {
struct fcp_cmnd *next;
struct fcp_cmnd *prev;
- void (*done)(Scsi_Cmnd *);
+ void (*done)(struct scsi_cmnd *);
unsigned short proto;
unsigned short token;
unsigned int did;
long *scsi_bitmap;
long scsi_bitmap_end;
int scsi_free;
- int (*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *);
+ int (*encode_addr)(struct scsi_cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *);
fcp_cmnd *scsi_que;
char scsi_name[4];
fcp_cmnd **cmd_slots;
int channels;
int targets;
long *ages;
- Scsi_Cmnd *rst_pkt;
+ struct scsi_cmnd *rst_pkt;
fcp_posmap *posmap;
/* LOGIN stuff */
fcp_cmnd *login;
for_each_fc_channel(fc) \
if (fc->state == FC_STATE_ONLINE)
-int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int fcp_scsi_abort(Scsi_Cmnd *);
-int fcp_scsi_dev_reset(Scsi_Cmnd *);
-int fcp_scsi_host_reset(Scsi_Cmnd *);
+int fcp_scsi_queuecommand(struct scsi_cmnd *,
+ void (* done) (struct scsi_cmnd *));
+int fcp_scsi_abort(struct scsi_cmnd *);
+int fcp_scsi_dev_reset(struct scsi_cmnd *);
+int fcp_scsi_host_reset(struct scsi_cmnd *);
#endif /* !(_FCP_SCSI_H) */
}
EXPORT_SYMBOL(dmi_get_system_info);
+
+/**
+ * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ * @str: Case sensitive Name
+ */
+int dmi_name_in_vendors(char *str)
+{
+ static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
+ DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
+ DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+ int i;
+ for (i = 0; fields[i] != DMI_NONE; i++) {
+ int f = fields[i];
+ if (dmi_ident[f] && strstr(dmi_ident[f], str))
+ return 1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dmi_name_in_vendors);
+
/**
* dmi_find_device - find onboard device by type/name
* @type: device type or %DMI_DEV_TYPE_ANY to match all device types
static int ide_generic_all; /* Set to claim all devices */
+/*
+ * the module_param_named() was added for the modular case
+ * the __setup() is left as compatibility for existing setups
+ */
+#ifndef MODULE
+static int __init ide_generic_all_on(char *unused)
+{
+ ide_generic_all = 1;
+ printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.");
+ return 1;
+}
+__setup("all-generic-ide", ide_generic_all_on);
+#endif
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/adc.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
#define MODNAME "hp680_ts_input"
printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) "
"-- forcing full recovery\n", bmname(bitmap), events,
(unsigned long long) bitmap->mddev->events);
- sb->state |= BITMAP_STALE;
+ sb->state |= cpu_to_le32(BITMAP_STALE);
}
success:
/* assign fields using values from superblock */
bitmap->daemon_sleep = daemon_sleep;
bitmap->daemon_lastrun = jiffies;
bitmap->max_write_behind = write_behind;
- bitmap->flags |= sb->state;
+ bitmap->flags |= le32_to_cpu(sb->state);
if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
bitmap->flags |= BITMAP_HOSTENDIAN;
bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
- if (sb->state & BITMAP_STALE)
+ if (sb->state & cpu_to_le32(BITMAP_STALE))
bitmap->events_cleared = bitmap->mddev->events;
err = 0;
out:
spin_unlock_irqrestore(&bitmap->lock, flags);
sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
switch (op) {
- case MASK_SET: sb->state |= bits;
+ case MASK_SET: sb->state |= cpu_to_le32(bits);
break;
- case MASK_UNSET: sb->state &= ~bits;
+ case MASK_UNSET: sb->state &= cpu_to_le32(~bits);
break;
default: BUG();
}
* version 1 superblock
*/
-static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
+static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb)
{
- unsigned int disk_csum, csum;
+ __le32 disk_csum;
+ u32 csum;
unsigned long long newcsum;
int size = 256 + le32_to_cpu(sb->max_dev)*2;
- unsigned int *isuper = (unsigned int*)sb;
+ __le32 *isuper = (__le32*)sb;
int i;
disk_csum = sb->sb_csum;
newcsum += le32_to_cpu(*isuper++);
if (size == 2)
- newcsum += le16_to_cpu(*(unsigned short*) isuper);
+ newcsum += le16_to_cpu(*(__le16*) isuper);
csum = (newcsum & 0xffffffff) + (newcsum >> 32);
sb->sb_csum = disk_csum;
if (le32_to_cpu(sb->chunksize))
rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
- if (le32_to_cpu(sb->size) > rdev->size*2)
+ if (le64_to_cpu(sb->size) > rdev->size*2)
return -EINVAL;
return ret;
}
else
sb->resync_offset = cpu_to_le64(0);
- sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+ sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
sb->raid_disks = cpu_to_le32(mddev->raid_disks);
sb->size = cpu_to_le64(mddev->size<<1);
mdname(mddev));
goto out_free_conf;
}
- mddev->degraded = conf->raid_disks = conf->working_disks;
+ mddev->degraded = conf->raid_disks - conf->working_disks;
conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
sizeof(struct multipath_bh));
disk = conf->mirrors + i;
if (!disk->rdev ||
- !test_bit(In_sync, &rdev->flags)) {
+ !test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0;
mddev->degraded++;
}
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.04.01"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01"
+#define MPT_LINUX_VERSION_COMMON "3.04.02"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.02"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
static void mptfc_target_destroy(struct scsi_target *starget);
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
static void __devexit mptfc_remove(struct pci_dev *pdev);
+static int mptfc_abort(struct scsi_cmnd *SCpnt);
+static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
+static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
+static int mptfc_host_reset(struct scsi_cmnd *SCpnt);
static struct scsi_host_template mptfc_driver_template = {
.module = THIS_MODULE,
.target_destroy = mptfc_target_destroy,
.slave_destroy = mptscsih_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
- .eh_abort_handler = mptscsih_abort,
- .eh_device_reset_handler = mptscsih_dev_reset,
- .eh_bus_reset_handler = mptscsih_bus_reset,
- .eh_host_reset_handler = mptscsih_host_reset,
+ .eh_abort_handler = mptfc_abort,
+ .eh_device_reset_handler = mptfc_dev_reset,
+ .eh_bus_reset_handler = mptfc_bus_reset,
+ .eh_host_reset_handler = mptfc_host_reset,
.bios_param = mptscsih_bios_param,
.can_queue = MPT_FC_CAN_QUEUE,
.this_id = -1,
.show_host_symbolic_name = 1,
};
+static int
+mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
+ int (*func)(struct scsi_cmnd *SCpnt),
+ const char *caller)
+{
+ struct scsi_device *sdev = SCpnt->device;
+ struct Scsi_Host *shost = sdev->host;
+ struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+ unsigned long flags;
+ int ready;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ dfcprintk ((MYIOC_s_INFO_FMT
+ "mptfc_block_error_handler.%d: %d:%d, port status is "
+ "DID_IMM_RETRY, deferring %s recovery.\n",
+ ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
+ ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
+ SCpnt->device->id,SCpnt->device->lun,caller));
+ msleep(1000);
+ spin_lock_irqsave(shost->host_lock, flags);
+ }
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) {
+ dfcprintk ((MYIOC_s_INFO_FMT
+ "%s.%d: %d:%d, failing recovery, "
+ "port state %d, vdev %p.\n", caller,
+ ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
+ ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
+ SCpnt->device->id,SCpnt->device->lun,ready,
+ SCpnt->device->hostdata));
+ return FAILED;
+ }
+ dfcprintk ((MYIOC_s_INFO_FMT
+ "%s.%d: %d:%d, executing recovery.\n", caller,
+ ((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
+ ((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
+ SCpnt->device->id,SCpnt->device->lun));
+ return (*func)(SCpnt);
+}
+
+static int
+mptfc_abort(struct scsi_cmnd *SCpnt)
+{
+ return
+ mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__);
+}
+
+static int
+mptfc_dev_reset(struct scsi_cmnd *SCpnt)
+{
+ return
+ mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__);
+}
+
+static int
+mptfc_bus_reset(struct scsi_cmnd *SCpnt)
+{
+ return
+ mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__);
+}
+
+static int
+mptfc_host_reset(struct scsi_cmnd *SCpnt)
+{
+ return
+ mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__);
+}
+
static void
mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
{
return 0;
}
+ if (!SCpnt->device->hostdata) { /* vdev */
+ SCpnt->result = DID_NO_CONNECT << 16;
+ done(SCpnt);
+ return 0;
+ }
+
/* dd_data is null until finished adding target */
ri = *((struct mptfc_rport_info **)rport->dd_data);
if (unlikely(!ri)) {
DECLARE_WAIT_QUEUE_HEAD(wq);
struct i2o_exec_wait *wait;
static u32 tcntxt = 0x80000000;
- long flags;
+ unsigned long flags;
int rc = 0;
wait = i2o_exec_wait_alloc();
config SGI_IOC4
tristate "SGI IOC4 Base IO support"
+ depends on PCI
---help---
This option enables basic support for the IOC4 chip on certain
SGI IO controller cards (IO9, IO10, and PCI-RT). This option
#include <linux/ktime.h>
#include <linux/mutex.h>
#include <linux/time.h>
+#include <asm/io.h>
/***************
* Definitions *
#include <linux/mmc/protocol.h>
#include <linux/mmc/host.h>
#include <linux/highmem.h>
+#include <asm/io.h>
#define DRIVER_NAME "tifm_sd"
#define DRIVER_VERSION "0.6"
select CRYPTO
select CRYPTO_SHA1
select CRYPTO_ARC4
+ select CRYPTO_ECB
---help---
Support for the MPPE Encryption protocol, as employed by the
Microsoft Point-to-Point Tunneling Protocol.
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
+#include <linux/dma-mapping.h>
#include <linux/linkage.h>
#include <asm/atomic.h>
(ZFCP_MAX_SBALS_PER_REQ * ZFCP_MAX_SBALES_PER_SBAL - 2)
/* request ID + QTCB in SBALE 0 + 1 of first SBAL in chain */
+#define ZFCP_MAX_SECTORS (ZFCP_MAX_SBALES_PER_REQ * 8)
+ /* max. number of (data buffer) SBALEs in largest SBAL chain
+ multiplied with number of sectors per 4k block */
+
/* FIXME(tune): free space should be one max. SBAL chain plus what? */
#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \
- (ZFCP_MAX_SBALS_PER_REQ + 4))
.cmd_per_lun = 1,
.use_clustering = 1,
.sdev_attrs = zfcp_sysfs_sdev_attrs,
+ .max_sectors = ZFCP_MAX_SECTORS,
},
.driver_version = ZFCP_VERSION,
};
struct scb_platform_data;
/****************************** Useful Macros *********************************/
-#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
#ifndef TRUE
#define TRUE 1
#endif
int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count);
-int ahd_wait_seeprom(struct ahd_softc *ahd);
-int ahd_verify_vpd_cksum(struct vpd_config *vpd);
int ahd_verify_cksum(struct seeprom_config *sc);
int ahd_acquire_seeprom(struct ahd_softc *ahd);
void ahd_release_seeprom(struct ahd_softc *ahd);
char *name;
ahd_device_setup_t *setup;
};
-extern struct ahd_pci_identity ahd_pci_ident_table [];
-extern const u_int ahd_num_pci_devs;
/***************************** VL/EISA Declarations ***************************/
struct aic7770_identity {
/*************************** Function Declarations ****************************/
/******************************************************************************/
void ahd_reset_cmds_pending(struct ahd_softc *ahd);
-u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
-void ahd_busy_tcl(struct ahd_softc *ahd,
- u_int tcl, u_int busyid);
-static __inline void ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl);
-static __inline void
-ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
-{
- ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
-}
/***************************** PCI Front End *********************************/
struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
int ahd_pci_test_register_access(struct ahd_softc *);
/************************** SCB and SCB queue management **********************/
-int ahd_probe_scbs(struct ahd_softc *);
void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
struct scb *scb);
int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
int ahd_parse_cfgdata(struct ahd_softc *ahd,
struct seeprom_config *sc);
void ahd_intr_enable(struct ahd_softc *ahd, int enable);
-void ahd_update_coalescing_values(struct ahd_softc *ahd,
- u_int timer,
- u_int maxcmds,
- u_int mincmds);
-void ahd_enable_coalescing(struct ahd_softc *ahd,
- int enable);
void ahd_pause_and_flushwork(struct ahd_softc *ahd);
int ahd_suspend(struct ahd_softc *ahd);
-int ahd_resume(struct ahd_softc *ahd);
void ahd_set_unit(struct ahd_softc *, int);
void ahd_set_name(struct ahd_softc *, char *);
struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
void ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
-void ahd_alloc_scbs(struct ahd_softc *ahd);
void ahd_free(struct ahd_softc *ahd);
int ahd_reset(struct ahd_softc *ahd, int reinit);
-void ahd_shutdown(void *arg);
int ahd_write_flexport(struct ahd_softc *ahd,
u_int addr, u_int value);
int ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
uint8_t *value);
-int ahd_wait_flexport(struct ahd_softc *ahd);
/*************************** Interrupt Services *******************************/
-void ahd_pci_intr(struct ahd_softc *ahd);
-void ahd_clear_intstat(struct ahd_softc *ahd);
-void ahd_flush_qoutfifo(struct ahd_softc *ahd);
void ahd_run_qoutfifo(struct ahd_softc *ahd);
#ifdef AHD_TARGET_MODE
void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
void ahd_handle_scsiint(struct ahd_softc *ahd,
u_int intstat);
-void ahd_clear_critical_section(struct ahd_softc *ahd);
/***************************** Error Recovery *********************************/
typedef enum {
char channel, int lun, u_int tag,
int stop_on_first, int remove,
int save_state);
-void ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
int ahd_reset_channel(struct ahd_softc *ahd, char channel,
int initiate_reset);
-int ahd_abort_scbs(struct ahd_softc *ahd, int target,
- char channel, int lun, u_int tag,
- role_t role, uint32_t status);
-void ahd_restart(struct ahd_softc *ahd);
-void ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo);
-void ahd_handle_scb_status(struct ahd_softc *ahd,
- struct scb *scb);
-void ahd_handle_scsi_status(struct ahd_softc *ahd,
- struct scb *scb);
-void ahd_calc_residual(struct ahd_softc *ahd,
- struct scb *scb);
/*************************** Utility Functions ********************************/
-struct ahd_phase_table_entry*
- ahd_lookup_phase_entry(int phase);
void ahd_compile_devinfo(struct ahd_devinfo *devinfo,
u_int our_id, u_int target,
u_int lun, char channel,
/************************** Transfer Negotiation ******************************/
void ahd_find_syncrate(struct ahd_softc *ahd, u_int *period,
u_int *ppr_options, u_int maxsync);
-void ahd_validate_offset(struct ahd_softc *ahd,
- struct ahd_initiator_tinfo *tinfo,
- u_int period, u_int *offset,
- int wide, role_t role);
-void ahd_validate_width(struct ahd_softc *ahd,
- struct ahd_initiator_tinfo *tinfo,
- u_int *bus_width,
- role_t role);
/*
* Negotiation types. These are used to qualify if we should renegotiate
* even if our goal and current transport parameters are identical.
AHD_QUEUE_TAGGED
} ahd_queue_alg;
-void ahd_set_tags(struct ahd_softc *ahd,
- struct scsi_cmnd *cmd,
- struct ahd_devinfo *devinfo,
- ahd_queue_alg alg);
-
/**************************** Target Mode *************************************/
#ifdef AHD_TARGET_MODE
void ahd_send_lstate_events(struct ahd_softc *,
#define AHD_SHOW_INT_COALESCING 0x10000
#define AHD_DEBUG_SEQUENCER 0x20000
#endif
-void ahd_print_scb(struct scb *scb);
void ahd_print_devinfo(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo);
-void ahd_dump_sglist(struct scb *scb);
void ahd_dump_card_state(struct ahd_softc *ahd);
int ahd_print_register(ahd_reg_parse_entry_t *table,
u_int num_entries,
u_int value,
u_int *cur_column,
u_int wrap_point);
-void ahd_dump_scbs(struct ahd_softc *ahd);
#endif /* _AIC79XX_H_ */
/***************************** Lookup Tables **********************************/
-char *ahd_chip_names[] =
+static char *ahd_chip_names[] =
{
"NONE",
"aic7901",
struct target_cmd *cmd);
#endif
+static int ahd_abort_scbs(struct ahd_softc *ahd, int target,
+ char channel, int lun, u_int tag,
+ role_t role, uint32_t status);
+static void ahd_alloc_scbs(struct ahd_softc *ahd);
+static void ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl,
+ u_int scbid);
+static void ahd_calc_residual(struct ahd_softc *ahd,
+ struct scb *scb);
+static void ahd_clear_critical_section(struct ahd_softc *ahd);
+static void ahd_clear_intstat(struct ahd_softc *ahd);
+static void ahd_enable_coalescing(struct ahd_softc *ahd,
+ int enable);
+static u_int ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl);
+static void ahd_freeze_devq(struct ahd_softc *ahd,
+ struct scb *scb);
+static void ahd_handle_scb_status(struct ahd_softc *ahd,
+ struct scb *scb);
+static struct ahd_phase_table_entry* ahd_lookup_phase_entry(int phase);
+static void ahd_shutdown(void *arg);
+static void ahd_update_coalescing_values(struct ahd_softc *ahd,
+ u_int timer,
+ u_int maxcmds,
+ u_int mincmds);
+static int ahd_verify_vpd_cksum(struct vpd_config *vpd);
+static int ahd_wait_seeprom(struct ahd_softc *ahd);
+
/******************************** Private Inlines *****************************/
-static __inline void ahd_assert_atn(struct ahd_softc *ahd);
-static __inline int ahd_currently_packetized(struct ahd_softc *ahd);
-static __inline int ahd_set_active_fifo(struct ahd_softc *ahd);
static __inline void
ahd_assert_atn(struct ahd_softc *ahd)
}
}
+static __inline void
+ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
+{
+ ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
+}
+
+/*
+ * Determine whether the sequencer reported a residual
+ * for this SCB/transaction.
+ */
+static __inline void
+ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
+{
+ uint32_t sgptr;
+
+ sgptr = ahd_le32toh(scb->hscb->sgptr);
+ if ((sgptr & SG_STATUS_VALID) != 0)
+ ahd_calc_residual(ahd, scb);
+}
+
+static __inline void
+ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
+{
+ uint32_t sgptr;
+
+ sgptr = ahd_le32toh(scb->hscb->sgptr);
+ if ((sgptr & SG_STATUS_VALID) != 0)
+ ahd_handle_scb_status(ahd, scb);
+ else
+ ahd_done(ahd, scb);
+}
+
+
/************************* Sequencer Execution Control ************************/
/*
* Restart the sequencer program from address zero
*/
-void
+static void
ahd_restart(struct ahd_softc *ahd)
{
ahd_unpause(ahd);
}
-void
+static void
ahd_clear_fifo(struct ahd_softc *ahd, u_int fifo)
{
ahd_mode_state saved_modes;
* Flush and completed commands that are sitting in the command
* complete queues down on the chip but have yet to be dma'ed back up.
*/
-void
+static void
ahd_flush_qoutfifo(struct ahd_softc *ahd)
{
struct scb *scb;
ahd_free(ahd);
}
+#ifdef AHD_DEBUG
+static void
+ahd_dump_sglist(struct scb *scb)
+{
+ int i;
+
+ if (scb->sg_count > 0) {
+ if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
+ struct ahd_dma64_seg *sg_list;
+
+ sg_list = (struct ahd_dma64_seg*)scb->sg_list;
+ for (i = 0; i < scb->sg_count; i++) {
+ uint64_t addr;
+ uint32_t len;
+
+ addr = ahd_le64toh(sg_list[i].addr);
+ len = ahd_le32toh(sg_list[i].len);
+ printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+ i,
+ (uint32_t)((addr >> 32) & 0xFFFFFFFF),
+ (uint32_t)(addr & 0xFFFFFFFF),
+ sg_list[i].len & AHD_SG_LEN_MASK,
+ (sg_list[i].len & AHD_DMA_LAST_SEG)
+ ? " Last" : "");
+ }
+ } else {
+ struct ahd_dma_seg *sg_list;
+
+ sg_list = (struct ahd_dma_seg*)scb->sg_list;
+ for (i = 0; i < scb->sg_count; i++) {
+ uint32_t len;
+
+ len = ahd_le32toh(sg_list[i].len);
+ printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+ i,
+ (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
+ ahd_le32toh(sg_list[i].addr),
+ len & AHD_SG_LEN_MASK,
+ len & AHD_DMA_LAST_SEG ? " Last" : "");
+ }
+ }
+ }
+}
+#endif /* AHD_DEBUG */
+
void
ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat)
{
* If a target takes us into the command phase
* assume that it has been externally reset and
* has thus lost our previous packetized negotiation
- * agreement.
- * Revert to async/narrow transfers until we
- * can renegotiate with the device and notify
- * the OSM about the reset.
+ * agreement. Since we have not sent an identify
+ * message and may not have fully qualified the
+ * connection, we change our command to TUR, assert
+ * ATN and ABORT the task when we go to message in
+ * phase. The OSM will see the REQUEUE_REQUEST
+ * status and retry the command.
*/
scbid = ahd_get_scbptr(ahd);
scb = ahd_lookup_scb(ahd, scbid);
ahd_set_syncrate(ahd, &devinfo, /*period*/0,
/*offset*/0, /*ppr_options*/0,
AHD_TRANS_ACTIVE, /*paused*/TRUE);
- scb->flags |= SCB_EXTERNAL_RESET;
+ /* Hand-craft TUR command */
+ ahd_outb(ahd, SCB_CDB_STORE, 0);
+ ahd_outb(ahd, SCB_CDB_STORE+1, 0);
+ ahd_outb(ahd, SCB_CDB_STORE+2, 0);
+ ahd_outb(ahd, SCB_CDB_STORE+3, 0);
+ ahd_outb(ahd, SCB_CDB_STORE+4, 0);
+ ahd_outb(ahd, SCB_CDB_STORE+5, 0);
+ ahd_outb(ahd, SCB_CDB_LEN, 6);
+ scb->hscb->control &= ~(TAG_ENB|SCB_TAG_TYPE);
+ scb->hscb->control |= MK_MESSAGE;
+ ahd_outb(ahd, SCB_CONTROL, scb->hscb->control);
+ ahd_outb(ahd, MSG_OUT, HOST_MSG);
+ ahd_outb(ahd, SAVED_SCSIID, scb->hscb->scsiid);
+ /*
+ * The lun is 0, regardless of the SCB's lun
+ * as we have not sent an identify message.
+ */
+ ahd_outb(ahd, SAVED_LUN, 0);
+ ahd_outb(ahd, SEQ_FLAGS, 0);
+ ahd_assert_atn(ahd);
+ scb->flags &= ~SCB_PACKETIZED;
+ scb->flags |= SCB_ABORT|SCB_EXTERNAL_RESET;
ahd_freeze_devq(ahd, scb);
ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
ahd_freeze_scb(scb);
/*
* Ignore external resets after a bus reset.
*/
- if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE))
+ if (((status & SCSIRSTI) != 0) && (ahd->flags & AHD_BUS_RESET_ACTIVE)) {
+ ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
return;
+ }
/*
* Clear bus reset flag
if (sent_msg == MSG_ABORT_TAG)
tag = SCB_GET_TAG(scb);
+ if ((scb->flags & SCB_EXTERNAL_RESET) != 0) {
+ /*
+ * This abort is in response to an
+ * unexpected switch to command phase
+ * for a packetized connection. Since
+ * the identify message was never sent,
+ * "saved lun" is 0. We really want to
+ * abort only the SCB that encountered
+ * this error, which could have a different
+ * lun. The SCB will be retried so the OS
+ * will see the UA after renegotiating to
+ * packetized.
+ */
+ tag = SCB_GET_TAG(scb);
+ saved_lun = scb->hscb->lun;
+ }
found = ahd_abort_scbs(ahd, target, 'A', saved_lun,
tag, ROLE_INITIATOR,
CAM_REQ_ABORTED);
}
#define AHD_MAX_STEPS 2000
-void
+static void
ahd_clear_critical_section(struct ahd_softc *ahd)
{
ahd_mode_state saved_modes;
/*
* Clear any pending interrupt status.
*/
-void
+static void
ahd_clear_intstat(struct ahd_softc *ahd)
{
AHD_ASSERT_MODES(ahd, ~(AHD_MODE_UNKNOWN_MSK|AHD_MODE_CFG_MSK),
#ifdef AHD_DEBUG
uint32_t ahd_debug = AHD_DEBUG_OPTS;
#endif
+
+#if 0
void
ahd_print_scb(struct scb *scb)
{
SCB_GET_TAG(scb));
ahd_dump_sglist(scb);
}
-
-void
-ahd_dump_sglist(struct scb *scb)
-{
- int i;
-
- if (scb->sg_count > 0) {
- if ((scb->ahd_softc->flags & AHD_64BIT_ADDRESSING) != 0) {
- struct ahd_dma64_seg *sg_list;
-
- sg_list = (struct ahd_dma64_seg*)scb->sg_list;
- for (i = 0; i < scb->sg_count; i++) {
- uint64_t addr;
- uint32_t len;
-
- addr = ahd_le64toh(sg_list[i].addr);
- len = ahd_le32toh(sg_list[i].len);
- printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
- i,
- (uint32_t)((addr >> 32) & 0xFFFFFFFF),
- (uint32_t)(addr & 0xFFFFFFFF),
- sg_list[i].len & AHD_SG_LEN_MASK,
- (sg_list[i].len & AHD_DMA_LAST_SEG)
- ? " Last" : "");
- }
- } else {
- struct ahd_dma_seg *sg_list;
-
- sg_list = (struct ahd_dma_seg*)scb->sg_list;
- for (i = 0; i < scb->sg_count; i++) {
- uint32_t len;
-
- len = ahd_le32toh(sg_list[i].len);
- printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
- i,
- (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
- ahd_le32toh(sg_list[i].addr),
- len & AHD_SG_LEN_MASK,
- len & AHD_DMA_LAST_SEG ? " Last" : "");
- }
- }
- }
-}
+#endif /* 0 */
/************************* Transfer Negotiation *******************************/
/*
transinfo = &tinfo->goal;
*ppr_options &= (transinfo->ppr_options|MSG_EXT_PPR_PCOMP_EN);
if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
- maxsync = MAX(maxsync, AHD_SYNCRATE_ULTRA2);
+ maxsync = max(maxsync, (u_int)AHD_SYNCRATE_ULTRA2);
*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
}
if (transinfo->period == 0) {
*period = 0;
*ppr_options = 0;
} else {
- *period = MAX(*period, transinfo->period);
+ *period = max(*period, (u_int)transinfo->period);
ahd_find_syncrate(ahd, period, ppr_options, maxsync);
}
}
* Truncate the given synchronous offset to a value the
* current adapter type and syncrate are capable of.
*/
-void
+static void
ahd_validate_offset(struct ahd_softc *ahd,
struct ahd_initiator_tinfo *tinfo,
u_int period, u_int *offset, int wide,
maxoffset = MAX_OFFSET_PACED;
} else
maxoffset = MAX_OFFSET_NON_PACED;
- *offset = MIN(*offset, maxoffset);
+ *offset = min(*offset, maxoffset);
if (tinfo != NULL) {
if (role == ROLE_TARGET)
- *offset = MIN(*offset, tinfo->user.offset);
+ *offset = min(*offset, (u_int)tinfo->user.offset);
else
- *offset = MIN(*offset, tinfo->goal.offset);
+ *offset = min(*offset, (u_int)tinfo->goal.offset);
}
}
* Truncate the given transfer width parameter to a value the
* current adapter type is capable of.
*/
-void
+static void
ahd_validate_width(struct ahd_softc *ahd, struct ahd_initiator_tinfo *tinfo,
u_int *bus_width, role_t role)
{
}
if (tinfo != NULL) {
if (role == ROLE_TARGET)
- *bus_width = MIN(tinfo->user.width, *bus_width);
+ *bus_width = min((u_int)tinfo->user.width, *bus_width);
else
- *bus_width = MIN(tinfo->goal.width, *bus_width);
+ *bus_width = min((u_int)tinfo->goal.width, *bus_width);
}
}
/*
* Update the current state of tagged queuing for a given target.
*/
-void
+static void
ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
struct ahd_devinfo *devinfo, ahd_queue_alg alg)
{
devinfo->target, devinfo->lun);
}
-struct ahd_phase_table_entry*
+static struct ahd_phase_table_entry*
ahd_lookup_phase_entry(int phase)
{
struct ahd_phase_table_entry *entry;
return;
}
-void
+static void
ahd_shutdown(void *arg)
{
struct ahd_softc *ahd;
/*
* Determine the number of SCBs available on the controller
*/
-int
+static int
ahd_probe_scbs(struct ahd_softc *ahd) {
int i;
ahd_platform_scb_free(ahd, scb);
}
-void
+static void
ahd_alloc_scbs(struct ahd_softc *ahd)
{
struct scb_data *scb_data;
#endif
}
- newcount = MIN(scb_data->sense_left, scb_data->scbs_left);
- newcount = MIN(newcount, scb_data->sgs_left);
- newcount = MIN(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
+ newcount = min(scb_data->sense_left, scb_data->scbs_left);
+ newcount = min(newcount, scb_data->sgs_left);
+ newcount = min(newcount, (AHD_SCB_MAX_ALLOC - scb_data->numscbs));
for (i = 0; i < newcount; i++) {
struct scb_platform_data *pdata;
u_int col_tag;
ahd_outb(ahd, HCNTRL, hcntrl);
}
-void
+static void
ahd_update_coalescing_values(struct ahd_softc *ahd, u_int timer, u_int maxcmds,
u_int mincmds)
{
ahd_outb(ahd, INT_COALESCING_MINCMDS, -mincmds);
}
-void
+static void
ahd_enable_coalescing(struct ahd_softc *ahd, int enable)
{
ahd->flags &= ~AHD_ALL_INTERRUPTS;
}
+#if 0
int
ahd_suspend(struct ahd_softc *ahd)
{
ahd_shutdown(ahd);
return (0);
}
+#endif /* 0 */
+#if 0
int
ahd_resume(struct ahd_softc *ahd)
{
ahd_restart(ahd);
return (0);
}
+#endif /* 0 */
/************************** Busy Target Table *********************************/
/*
/*
* Return the untagged transaction id for a given target/channel lun.
*/
-u_int
+static u_int
ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
{
u_int scbid;
return (scbid);
}
-void
+static void
ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
{
u_int scb_offset;
return match;
}
-void
+static void
ahd_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
{
int target;
* been modified from CAM_REQ_INPROG. This routine assumes that the sequencer
* is paused before it is called.
*/
-int
+static int
ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
int lun, u_int tag, role_t role, uint32_t status)
{
ahd_clear_fifo(ahd, 0);
ahd_clear_fifo(ahd, 1);
+ /*
+ * Clear SCSI interrupt status
+ */
+ ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
+
/*
* Reenable selections
*/
}
}
#endif
- /* Notify the XPT that a bus reset occurred */
- ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
- CAM_LUN_WILDCARD, AC_BUS_RESET);
-
/*
* Revert to async/narrow transfers until we renegotiate.
*/
}
}
+ /* Notify the XPT that a bus reset occurred */
+ ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD,
+ CAM_LUN_WILDCARD, AC_BUS_RESET);
+
ahd_restart(ahd);
return (found);
}
/****************************** Status Processing *****************************/
-void
-ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
-{
- if (scb->hscb->shared_data.istatus.scsi_status != 0) {
- ahd_handle_scsi_status(ahd, scb);
- } else {
- ahd_calc_residual(ahd, scb);
- ahd_done(ahd, scb);
- }
-}
-void
+static void
ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
{
struct hardware_scb *hscb;
}
}
+static void
+ahd_handle_scb_status(struct ahd_softc *ahd, struct scb *scb)
+{
+ if (scb->hscb->shared_data.istatus.scsi_status != 0) {
+ ahd_handle_scsi_status(ahd, scb);
+ } else {
+ ahd_calc_residual(ahd, scb);
+ ahd_done(ahd, scb);
+ }
+}
+
/*
* Calculate the residual for a just completed SCB.
*/
-void
+static void
ahd_calc_residual(struct ahd_softc *ahd, struct scb *scb)
{
struct hardware_scb *hscb;
if (skip_addr > i) {
int end_addr;
- end_addr = MIN(address, skip_addr);
+ end_addr = min(address, skip_addr);
address_offset += end_addr - i;
i = skip_addr;
} else {
ahd_unpause(ahd);
}
+#if 0
void
ahd_dump_scbs(struct ahd_softc *ahd)
{
ahd_set_scbptr(ahd, saved_scb_index);
ahd_restore_modes(ahd, saved_modes);
}
+#endif /* 0 */
/**************************** Flexport Logic **********************************/
/*
/*
* Wait ~100us for the serial eeprom to satisfy our request.
*/
-int
+static int
ahd_wait_seeprom(struct ahd_softc *ahd)
{
int cnt;
* Validate the two checksums in the per_channel
* vital product data struct.
*/
-int
+static int
ahd_verify_vpd_cksum(struct vpd_config *vpd)
{
int i;
/* Currently a no-op */
}
+/*
+ * Wait at most 2 seconds for flexport arbitration to succeed.
+ */
+static int
+ahd_wait_flexport(struct ahd_softc *ahd)
+{
+ int cnt;
+
+ AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
+ cnt = 1000000 * 2 / 5;
+ while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
+ ahd_delay(5);
+
+ if (cnt == 0)
+ return (ETIMEDOUT);
+ return (0);
+}
+
int
ahd_write_flexport(struct ahd_softc *ahd, u_int addr, u_int value)
{
return (0);
}
-/*
- * Wait at most 2 seconds for flexport arbitration to succeed.
- */
-int
-ahd_wait_flexport(struct ahd_softc *ahd)
-{
- int cnt;
-
- AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
- cnt = 1000000 * 2 / 5;
- while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
- ahd_delay(5);
-
- if (cnt == 0)
- return (ETIMEDOUT);
- return (0);
-}
-
/************************* Target Mode ****************************************/
#ifdef AHD_TARGET_MODE
cam_status
}
/*********************** Miscelaneous Support Functions ***********************/
-static __inline void ahd_complete_scb(struct ahd_softc *ahd,
- struct scb *scb);
-static __inline void ahd_update_residual(struct ahd_softc *ahd,
- struct scb *scb);
static __inline struct ahd_initiator_tinfo *
ahd_fetch_transinfo(struct ahd_softc *ahd,
char channel, u_int our_id,
ahd_get_sense_bufaddr(struct ahd_softc *ahd,
struct scb *scb);
-static __inline void
-ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
-{
- uint32_t sgptr;
-
- sgptr = ahd_le32toh(scb->hscb->sgptr);
- if ((sgptr & SG_STATUS_VALID) != 0)
- ahd_handle_scb_status(ahd, scb);
- else
- ahd_done(ahd, scb);
-}
-
-/*
- * Determine whether the sequencer reported a residual
- * for this SCB/transaction.
- */
-static __inline void
-ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
-{
- uint32_t sgptr;
-
- sgptr = ahd_le32toh(scb->hscb->sgptr);
- if ((sgptr & SG_STATUS_VALID) != 0)
- ahd_calc_residual(ahd, scb);
-}
-
/*
* Return pointers to the transfer negotiation information
* for the specified our_id/remote_id pair.
* force all outstanding transactions to be serviced prior to a new
* transaction.
*/
-uint32_t aic79xx_periodic_otag;
+static uint32_t aic79xx_periodic_otag;
/* Some storage boxes are using an LSI chip which has a bug making it
* impossible to use aic79xx Rev B chip in 320 speeds. The following
#endif
.can_queue = AHD_MAX_QUEUE,
.this_id = -1,
+ .max_sectors = 8192,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = ahd_linux_slave_alloc,
u_int sense_offset;
if (scb->flags & SCB_SENSE) {
- sense_size = MIN(sizeof(struct scsi_sense_data)
+ sense_size = min(sizeof(struct scsi_sense_data)
- ahd_get_sense_residual(scb),
- sizeof(cmd->sense_buffer));
+ (u_long)sizeof(cmd->sense_buffer));
sense_offset = 0;
} else {
/*
*/
siu = (struct scsi_status_iu_header *)
scb->sense_data;
- sense_size = MIN(scsi_4btoul(siu->sense_length),
+ sense_size = min_t(size_t,
+ scsi_4btoul(siu->sense_length),
sizeof(cmd->sense_buffer));
sense_offset = SIU_SENSE_OFFSET(siu);
}
pcomp ? "Enable" : "Disable");
#endif
- if (pcomp)
+ if (pcomp) {
+ uint8_t precomp;
+
+ if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
+ struct ahd_linux_iocell_opts *iocell_opts;
+
+ iocell_opts = &aic79xx_iocell_info[ahd->unit];
+ precomp = iocell_opts->precomp;
+ } else {
+ precomp = AIC79XX_DEFAULT_PRECOMP;
+ }
ppr_options |= MSG_EXT_PPR_PCOMP_EN;
+ AHD_SET_PRECOMP(ahd, precomp);
+ } else {
+ AHD_SET_PRECOMP(ahd, 0);
+ }
ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
starget->channel + 'A', ROLE_INITIATOR);
ahd_unlock(ahd, &flags);
}
+static void ahd_linux_get_signalling(struct Scsi_Host *shost)
+{
+ struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
+ unsigned long flags;
+ u8 mode;
+
+ ahd_lock(ahd, &flags);
+ ahd_pause(ahd);
+ mode = ahd_inb(ahd, SBLKCTL);
+ ahd_unpause(ahd);
+ ahd_unlock(ahd, &flags);
+ if (mode & ENAB40)
+ spi_signalling(shost) = SPI_SIGNAL_LVD;
+ else if (mode & ENAB20)
+ spi_signalling(shost) = SPI_SIGNAL_SE;
+ else
+ spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
+}
static struct spi_function_template ahd_linux_transport_functions = {
.set_offset = ahd_linux_set_offset,
.show_pcomp_en = 1,
.set_hold_mcs = ahd_linux_set_hold_mcs,
.show_hold_mcs = 1,
+ .get_signalling = ahd_linux_get_signalling,
};
static int __init
int pos;
};
-void ahd_format_transinfo(struct info_str *info,
- struct ahd_transinfo *tinfo);
-
/******************************** Locking *************************************/
static __inline void
ahd_lockinit(struct ahd_softc *ahd)
#define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */
#define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */
-extern struct pci_driver aic79xx_pci_driver;
-
typedef enum
{
AHD_POWER_STATE_D0,
MODULE_DEVICE_TABLE(pci, ahd_linux_pci_id_table);
-struct pci_driver aic79xx_pci_driver = {
+static struct pci_driver aic79xx_pci_driver = {
.name = "aic79xx",
.probe = ahd_linux_pci_dev_probe,
.remove = ahd_linux_pci_dev_remove,
static ahd_device_setup_t ahd_aic7902_setup;
static ahd_device_setup_t ahd_aic790X_setup;
-struct ahd_pci_identity ahd_pci_ident_table [] =
+static struct ahd_pci_identity ahd_pci_ident_table [] =
{
/* aic7901 based controllers */
{
}
};
-const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
+static const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
#define DEVCONFIG 0x40
#define PCIXINITPAT 0x0000E000ul
static void ahd_configure_termination(struct ahd_softc *ahd,
u_int adapter_control);
static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
+static void ahd_pci_intr(struct ahd_softc *ahd);
struct ahd_pci_identity *
ahd_find_pci_device(ahd_dev_softc_t pci)
"%s: Address or Write Phase Parity Error Detected in %s.\n"
};
-void
+static void
ahd_pci_intr(struct ahd_softc *ahd)
{
uint8_t pci_status[8];
return (len);
}
-void
+static void
ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
{
u_int speed;
struct seeprom_descriptor;
/****************************** Useful Macros *********************************/
-#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
#ifndef TRUE
#define TRUE 1
#endif
char *name;
ahc_device_setup_t *setup;
};
-extern struct ahc_pci_identity ahc_pci_ident_table[];
-extern const u_int ahc_num_pci_devs;
/***************************** VL/EISA Declarations ***************************/
struct aic7770_identity {
} ahc_queue_alg;
void ahc_set_tags(struct ahc_softc *ahc,
+ struct scsi_cmnd *cmd,
struct ahc_devinfo *devinfo,
ahc_queue_alg alg);
transinfo = &tinfo->goal;
*ppr_options &= transinfo->ppr_options;
if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
- maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
+ maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2);
*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
}
if (transinfo->period == 0) {
*ppr_options = 0;
return (NULL);
}
- *period = MAX(*period, transinfo->period);
+ *period = max(*period, (u_int)transinfo->period);
return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
}
else
maxoffset = MAX_OFFSET_8BIT;
}
- *offset = MIN(*offset, maxoffset);
+ *offset = min(*offset, maxoffset);
if (tinfo != NULL) {
if (role == ROLE_TARGET)
- *offset = MIN(*offset, tinfo->user.offset);
+ *offset = min(*offset, (u_int)tinfo->user.offset);
else
- *offset = MIN(*offset, tinfo->goal.offset);
+ *offset = min(*offset, (u_int)tinfo->goal.offset);
}
}
}
if (tinfo != NULL) {
if (role == ROLE_TARGET)
- *bus_width = MIN(tinfo->user.width, *bus_width);
+ *bus_width = min((u_int)tinfo->user.width, *bus_width);
else
- *bus_width = MIN(tinfo->goal.width, *bus_width);
+ *bus_width = min((u_int)tinfo->goal.width, *bus_width);
}
}
tinfo->curr.ppr_options = ppr_options;
ahc_send_async(ahc, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+ CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
if (offset != 0) {
printf("%s: target %d synchronous at %sMHz%s, "
tinfo->curr.width = width;
ahc_send_async(ahc, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL);
+ CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
if (bootverbose) {
printf("%s: target %d using %dbit transfers\n",
ahc_name(ahc), devinfo->target,
* Update the current state of tagged queuing for a given target.
*/
void
-ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
- ahc_queue_alg alg)
+ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+ struct ahc_devinfo *devinfo, ahc_queue_alg alg)
{
- ahc_platform_set_tags(ahc, devinfo, alg);
+ struct scsi_device *sdev = cmd->device;
+
+ ahc_platform_set_tags(ahc, sdev, devinfo, alg);
ahc_send_async(ahc, devinfo->channel, devinfo->target,
- devinfo->lun, AC_TRANSFER_NEG, &alg);
+ devinfo->lun, AC_TRANSFER_NEG);
}
/*
printf("(%s:%c:%d:%d): refuses tagged commands. "
"Performing non-tagged I/O\n", ahc_name(ahc),
devinfo->channel, devinfo->target, devinfo->lun);
- ahc_set_tags(ahc, devinfo, AHC_QUEUE_NONE);
+ ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE);
mask = ~0x23;
} else {
printf("(%s:%c:%d:%d): refuses %s tagged commands. "
ahc_name(ahc), devinfo->channel, devinfo->target,
devinfo->lun, tag_type == MSG_ORDERED_TASK
? "ordered" : "head of queue");
- ahc_set_tags(ahc, devinfo, AHC_QUEUE_BASIC);
+ ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);
mask = ~0x03;
}
if (status != CAM_SEL_TIMEOUT)
ahc_send_async(ahc, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+ CAM_LUN_WILDCARD, AC_SENT_BDR);
if (message != NULL
&& (verbose_level <= bootverbose))
physaddr = sg_map->sg_physaddr;
newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
- newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
+ newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
for (i = 0; i < newcount; i++) {
struct scb_platform_data *pdata;
#ifndef __linux__
#endif
/* Notify the XPT that a bus reset occurred */
ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
- CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
+ CAM_LUN_WILDCARD, AC_BUS_RESET);
/*
* Revert to async/narrow transfers until we renegotiate.
if (skip_addr > i) {
int end_addr;
- end_addr = MIN(address, skip_addr);
+ end_addr = min(address, skip_addr);
address_offset += end_addr - i;
i = skip_addr;
} else {
* force all outstanding transactions to be serviced prior to a new
* transaction.
*/
-uint32_t aic7xxx_periodic_otag;
+static uint32_t aic7xxx_periodic_otag;
/*
* Module information and settable options.
struct seeprom_config *sc = ahc->seep_config;
unsigned long flags;
struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
- struct ahc_linux_target *targ = scsi_transport_target_data(starget);
unsigned short scsirate;
struct ahc_devinfo devinfo;
struct ahc_initiator_tinfo *tinfo;
BUG_ON(*ahc_targp != NULL);
*ahc_targp = starget;
- memset(targ, 0, sizeof(*targ));
if (sc) {
int maxsync = AHC_SYNCRATE_DT;
struct ahc_softc *ahc =
*((struct ahc_softc **)sdev->host->hostdata);
struct scsi_target *starget = sdev->sdev_target;
- struct ahc_linux_target *targ = scsi_transport_target_data(starget);
struct ahc_linux_device *dev;
if (bootverbose)
printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
- BUG_ON(targ->sdev[sdev->lun] != NULL);
-
dev = scsi_transport_device_data(sdev);
memset(dev, 0, sizeof(*dev));
*/
dev->maxtags = 0;
- targ->sdev[sdev->lun] = sdev;
-
spi_period(starget) = 0;
return 0;
return 0;
}
-static void
-ahc_linux_slave_destroy(struct scsi_device *sdev)
-{
- struct ahc_softc *ahc;
- struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
- struct ahc_linux_target *targ = scsi_transport_target_data(sdev->sdev_target);
-
- ahc = *((struct ahc_softc **)sdev->host->hostdata);
- if (bootverbose)
- printf("%s: Slave Destroy %d\n", ahc_name(ahc), sdev->id);
-
- BUG_ON(dev->active);
-
- targ->sdev[sdev->lun] = NULL;
-}
-
#if defined(__i386__)
/*
* Return the disk geometry for the given SCSI device.
#endif
.can_queue = AHC_MAX_QUEUE,
.this_id = -1,
+ .max_sectors = 8192,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = ahc_linux_slave_alloc,
.slave_configure = ahc_linux_slave_configure,
- .slave_destroy = ahc_linux_slave_destroy,
.target_alloc = ahc_linux_target_alloc,
.target_destroy = ahc_linux_target_destroy,
};
ahc_platform_free(struct ahc_softc *ahc)
{
struct scsi_target *starget;
- int i, j;
+ int i;
if (ahc->platform_data != NULL) {
/* destroy all of the device and target objects */
for (i = 0; i < AHC_NUM_TARGETS; i++) {
starget = ahc->platform_data->starget[i];
if (starget != NULL) {
- for (j = 0; j < AHC_NUM_LUNS; j++) {
- struct ahc_linux_target *targ =
- scsi_transport_target_data(starget);
-
- if (targ->sdev[j] == NULL)
- continue;
- targ->sdev[j] = NULL;
- }
ahc->platform_data->starget[i] = NULL;
}
}
}
void
-ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
- ahc_queue_alg alg)
+ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
+ struct ahc_devinfo *devinfo, ahc_queue_alg alg)
{
- struct scsi_target *starget;
- struct ahc_linux_target *targ;
struct ahc_linux_device *dev;
- struct scsi_device *sdev;
- u_int target_offset;
int was_queuing;
int now_queuing;
- target_offset = devinfo->target;
- if (devinfo->channel != 'A')
- target_offset += 8;
- starget = ahc->platform_data->starget[target_offset];
- targ = scsi_transport_target_data(starget);
- BUG_ON(targ == NULL);
- sdev = targ->sdev[devinfo->lun];
if (sdev == NULL)
return;
dev = scsi_transport_device_data(sdev);
tags = ahc_linux_user_tagdepth(ahc, &devinfo);
if (tags != 0 && sdev->tagged_supported != 0) {
- ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
+ ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED);
+ ahc_send_async(ahc, devinfo.channel, devinfo.target,
+ devinfo.lun, AC_TRANSFER_NEG);
ahc_print_devinfo(ahc, &devinfo);
printf("Tagged Queuing enabled. Depth %d\n", tags);
} else {
- ahc_set_tags(ahc, &devinfo, AHC_QUEUE_NONE);
+ ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE);
+ ahc_send_async(ahc, devinfo.channel, devinfo.target,
+ devinfo.lun, AC_TRANSFER_NEG);
}
}
void
ahc_send_async(struct ahc_softc *ahc, char channel,
- u_int target, u_int lun, ac_code code, void *arg)
+ u_int target, u_int lun, ac_code code)
{
switch (code) {
case AC_TRANSFER_NEG:
if (scb->flags & SCB_SENSE) {
u_int sense_size;
- sense_size = MIN(sizeof(struct scsi_sense_data)
+ sense_size = min(sizeof(struct scsi_sense_data)
- ahc_get_sense_residual(scb),
- sizeof(cmd->sense_buffer));
+ (u_long)sizeof(cmd->sense_buffer));
memcpy(cmd->sense_buffer,
ahc_get_sense_buf(ahc, scb), sense_size);
if (sense_size < sizeof(cmd->sense_buffer))
}
ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
ahc_set_scsi_status(scb, SCSI_STATUS_OK);
- ahc_platform_set_tags(ahc, &devinfo,
+ ahc_platform_set_tags(ahc, sdev, &devinfo,
(dev->flags & AHC_DEV_Q_BASIC)
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
break;
*/
dev->openings = 1;
ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
- ahc_platform_set_tags(ahc, &devinfo,
+ ahc_platform_set_tags(ahc, sdev, &devinfo,
(dev->flags & AHC_DEV_Q_BASIC)
? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
break;
if (!ahc_linux_transport_template)
return -ENODEV;
- scsi_transport_reserve_target(ahc_linux_transport_template,
- sizeof(struct ahc_linux_target));
scsi_transport_reserve_device(ahc_linux_transport_template,
sizeof(struct ahc_linux_device));
AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
} ahc_linux_dev_flags;
-struct ahc_linux_target;
struct ahc_linux_device {
/*
* The number of transactions currently
#define AHC_OTAG_THRESH 500
};
-struct ahc_linux_target {
- struct scsi_device *sdev[AHC_NUM_LUNS];
- struct ahc_transinfo last_tinfo;
- struct ahc_softc *ahc;
-};
-
/********************* Definitions Required by the Core ***********************/
/*
* Number of SG segments we require. So long as the S/G segments for
#define PCIR_SUBVEND_0 0x2c
#define PCIR_SUBDEV_0 0x2e
-extern struct pci_driver aic7xxx_pci_driver;
-
typedef enum
{
AHC_POWER_STATE_D0,
}
}
-void ahc_platform_set_tags(struct ahc_softc *ahc,
+void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
struct ahc_devinfo *devinfo, ahc_queue_alg);
int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
char channel, int lun, u_int tag,
void ahc_platform_flushwork(struct ahc_softc *ahc);
void ahc_done(struct ahc_softc*, struct scb*);
void ahc_send_async(struct ahc_softc *, char channel,
- u_int target, u_int lun, ac_code, void *);
+ u_int target, u_int lun, ac_code);
void ahc_print_path(struct ahc_softc *, struct scb *);
void ahc_platform_dump_card_state(struct ahc_softc *ahc);
MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
-struct pci_driver aic7xxx_pci_driver = {
+static struct pci_driver aic7xxx_pci_driver = {
.name = "aic7xxx",
.probe = ahc_linux_pci_dev_probe,
.remove = ahc_linux_pci_dev_remove,
static ahc_device_setup_t ahc_aha494XX_setup;
static ahc_device_setup_t ahc_aha398XX_setup;
-struct ahc_pci_identity ahc_pci_ident_table [] =
+static struct ahc_pci_identity ahc_pci_ident_table [] =
{
/* aic7850 based controllers */
{
}
};
-const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
+static const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
#define AHC_394X_SLOT_CHANNEL_A 4
#define AHC_394X_SLOT_CHANNEL_B 5
u_int our_id, char channel, u_int target_id,
u_int target_offset)
{
- struct ahc_linux_target *targ;
struct scsi_target *starget;
struct ahc_initiator_tinfo *tinfo;
struct ahc_tmode_tstate *tstate;
starget = ahc->platform_data->starget[target_offset];
if (!starget)
return;
- targ = scsi_transport_target_data(starget);
copy_info(info, "\tGoal: ");
ahc_format_transinfo(info, &tinfo->goal);
for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
struct scsi_device *sdev;
- sdev = targ->sdev[lun];
+ sdev = scsi_device_lookup_by_target(starget, lun);
if (sdev == NULL)
continue;
}
copy_info(&info, "\n");
- max_targ = 15;
+ max_targ = 16;
if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
- max_targ = 7;
+ max_targ = 8;
- for (i = 0; i <= max_targ; i++) {
+ for (i = 0; i < max_targ; i++) {
u_int our_id;
u_int target_id;
char channel;
while (p->completeq.head != NULL) {
cmd = p->completeq.head;
- p->completeq.head = (struct scsi_Cmnd *) cmd->host_scribble;
+ p->completeq.head = (struct scsi_cmnd *) cmd->host_scribble;
cmd->host_scribble = NULL;
cmd->scsi_done(cmd);
}
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E
+#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E
0, 0, 1},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E),
0, 0, 1},
+ {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F),
+ 0, 0, 1},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30),
0, 0, 2},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32),
reg = asd_read_reg_dword(asd_ha, EXSICNFGR);
- if (!(reg & FLASHEX)) {
- ASD_DPRINTK("flash doesn't exist\n");
- return -ENOENT;
- }
if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR,
&asd_ha->hw_prof.flash.bar)) {
asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n",
static int bios_major;
static int bios_minor;
static int PCI_bus;
+static struct pci_dev *PCI_dev;
static int Quantum; /* Quantum board variant */
static int interrupt_level;
static volatile int in_command;
PCI_DEVICE_ID_FD_36C70 );
#endif
- if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
+ if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL)
return 0;
- if (pci_enable_device(pdev)) return 0;
+ if (pci_enable_device(pdev))
+ goto fail;
#if DEBUG_DETECT
printk( "scsi: <fdomain> TMC-3260 detect:"
pci_irq = pdev->irq;
if (!request_region( pci_base, 0x10, "fdomain" ))
- return 0;
+ goto fail;
/* Now we have the I/O base address and interrupt from the PCI
configuration registers. */
if (!fdomain_is_valid_port(pci_base)) {
printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
release_region(pci_base, 0x10);
- return 0;
+ goto fail;
}
/* Fill in a few global variables. Ugh. */
bios_major = bios_minor = -1;
PCI_bus = 1;
+ PCI_dev = pdev;
Quantum = 0;
bios_base = 0;
return 1;
+fail:
+ pci_dev_put(pdev);
+ return 0;
}
+
#endif
struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt )
if (setup_called) {
printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n");
}
- release_region(port_base, 0x10);
- return NULL;
+ goto fail;
}
if (this_id) {
/* Log IRQ with kernel */
if (!interrupt_level) {
printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
- release_region(port_base, 0x10);
- return NULL;
+ goto fail;
} else {
/* Register the IRQ with the kernel */
printk(KERN_ERR " Send mail to faith@acm.org\n" );
}
printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
- release_region(port_base, 0x10);
- return NULL;
+ goto fail;
}
}
return shpnt;
+fail:
+ pci_dev_put(pdev);
+ release_region(port_base, 0x10);
+ return NULL;
}
static int fdomain_16x0_detect(struct scsi_host_template *tpnt)
free_irq(shpnt->irq, shpnt);
if (shpnt->io_port && shpnt->n_io_port)
release_region(shpnt->io_port, shpnt->n_io_port);
+ if (PCI_bus)
+ pci_dev_put(PCI_dev);
return 0;
}
"ibmvscsi: Re-enabling adapter!\n");
purge_requests(hostdata, DID_REQUEUE);
if ((ibmvscsi_reenable_crq_queue(&hostdata->queue,
- hostdata) == 0) ||
+ hostdata)) ||
(ibmvscsi_send_crq(hostdata,
0xC001000000000000LL, 0))) {
atomic_set(&hostdata->request_limit,
break;
case ISCSI_OP_ASYNC_EVENT:
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
- /* we need sth like iscsi_async_event_rsp() */
- rc = ISCSI_ERR_BAD_OPCODE;
+ if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
+ rc = ISCSI_ERR_CONN_FAILED;
break;
default:
rc = ISCSI_ERR_BAD_OPCODE;
}
EXPORT_SYMBOL_GPL(iscsi_conn_failure);
+static int iscsi_xmit_imm_task(struct iscsi_conn *conn)
+{
+ struct iscsi_hdr *hdr = conn->mtask->hdr;
+ int rc, was_logout = 0;
+
+ if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) {
+ conn->session->state = ISCSI_STATE_IN_RECOVERY;
+ iscsi_block_session(session_to_cls(conn->session));
+ was_logout = 1;
+ }
+ rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask);
+ if (rc)
+ return rc;
+
+ if (was_logout) {
+ set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+ return -ENODATA;
+ }
+ return 0;
+}
+
/**
* iscsi_data_xmit - xmit any command into the scheduled connection
* @conn: iscsi connection
conn->ctask = NULL;
}
if (conn->mtask) {
- rc = tt->xmit_mgmt_task(conn, conn->mtask);
+ rc = iscsi_xmit_imm_task(conn);
if (rc)
goto again;
/* done with this in-progress mtask */
list_add_tail(&conn->mtask->running,
&conn->mgmt_run_list);
spin_unlock_bh(&conn->session->lock);
- rc = tt->xmit_mgmt_task(conn, conn->mtask);
+ rc = iscsi_xmit_imm_task(conn);
if (rc)
goto again;
}
spin_unlock_bh(&conn->session->lock);
rc = tt->xmit_cmd_task(conn, conn->ctask);
- if (rc)
- goto again;
spin_lock_bh(&conn->session->lock);
__iscsi_put_ctask(conn->ctask);
}
conn = session->leadconn;
+ if (!conn) {
+ reason = FAILURE_SESSION_FREED;
+ goto fault;
+ }
if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
sizeof(void*))) {
}
spin_lock_init(&session->lock);
- INIT_LIST_HEAD(&session->connections);
/* initialize immediate command pool */
if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
kfree(conn->persistent_address);
__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
sizeof(void*));
- list_del(&conn->item);
- if (list_empty(&session->connections))
+ if (session->leadconn == conn) {
session->leadconn = NULL;
- if (session->leadconn && session->leadconn == conn)
- session->leadconn = container_of(session->connections.next,
- struct iscsi_conn, item);
-
- if (session->leadconn == NULL)
/* no connections exits.. reset sequencing */
session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
+ }
spin_unlock_bh(&session->lock);
kfifo_free(conn->immqueue);
struct iscsi_cls_conn *cls_conn, int is_leading)
{
struct iscsi_session *session = class_to_transport_session(cls_session);
- struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data;
+ struct iscsi_conn *conn = cls_conn->dd_data;
- /* lookup for existing connection */
spin_lock_bh(&session->lock);
- list_for_each_entry(tmp, &session->connections, item) {
- if (tmp == conn) {
- if (conn->c_stage != ISCSI_CONN_STOPPED ||
- conn->stop_stage == STOP_CONN_TERM) {
- printk(KERN_ERR "iscsi: can't bind "
- "non-stopped connection (%d:%d)\n",
- conn->c_stage, conn->stop_stage);
- spin_unlock_bh(&session->lock);
- return -EIO;
- }
- break;
- }
- }
- if (tmp != conn) {
- /* bind new iSCSI connection to session */
- conn->session = session;
- list_add(&conn->item, &session->connections);
- }
- spin_unlock_bh(&session->lock);
-
if (is_leading)
session->leadconn = conn;
+ spin_unlock_bh(&session->lock);
/*
* Unblock xmitworker(), Login Phase will pass through.
{
struct Scsi_Host *host = class_to_shost(cdev);
struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
- return snprintf(buf, PAGE_SIZE, "0x%llx\n", phba->cfg_soft_wwpn);
+ return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+ (unsigned long long)phba->cfg_soft_wwpn);
}
if (!mp->virt) {
kfree(mp);
- lpfc_free_ct_rsp(phba, mlist);
+ if (mlist)
+ lpfc_free_ct_rsp(phba, mlist);
return NULL;
}
* Clenaup parameters and call done() functions.
* You must be set SCpnt->result before call this function.
*/
-static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
+static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
{
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
SCpnt->scsi_done(SCpnt);
}
-static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+ void (*done)(struct scsi_cmnd *))
{
#ifdef NSP_DEBUG
/*unsigned int host_id = SCpnt->device->host->this_id;*/
/*
* Start selection phase
*/
-static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
+static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
{
unsigned int host_id = SCpnt->device->host->this_id;
unsigned int base = SCpnt->device->host->io_port;
/*
* setup synchronous data transfer mode
*/
-static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
+static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
{
unsigned char target = scmd_id(SCpnt);
// unsigned char lun = SCpnt->device->lun;
/*
* start ninja hardware timer
*/
-static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
+static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
{
unsigned int base = SCpnt->device->host->io_port;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
/*
* wait for bus phase change
*/
-static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
+static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
+ char *str)
{
unsigned int base = SCpnt->device->host->io_port;
unsigned char reg;
/*
* expect Ninja Irq
*/
-static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
- unsigned char current_phase,
- unsigned char mask)
+static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
+ unsigned char current_phase,
+ unsigned char mask)
{
unsigned int base = SCpnt->device->host->io_port;
int time_out;
/*
* transfer SCSI message
*/
-static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
+static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
{
unsigned int base = SCpnt->device->host->io_port;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
/*
* get extra SCSI data from fifo
*/
-static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
+static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
{
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
unsigned int count;
/*
* accept reselection
*/
-static int nsp_reselected(Scsi_Cmnd *SCpnt)
+static int nsp_reselected(struct scsi_cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
unsigned int host_id = SCpnt->device->host->this_id;
/*
* count how many data transferd
*/
-static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
+static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
unsigned int count;
/*
* read data in DATA IN phase
*/
-static void nsp_pio_read(Scsi_Cmnd *SCpnt)
+static void nsp_pio_read(struct scsi_cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
unsigned long mmio_base = SCpnt->device->host->base;
/*
* write data in DATA OUT phase
*/
-static void nsp_pio_write(Scsi_Cmnd *SCpnt)
+static void nsp_pio_write(struct scsi_cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
unsigned long mmio_base = SCpnt->device->host->base;
/*
* setup synchronous/asynchronous data transfer mode
*/
-static int nsp_nexus(Scsi_Cmnd *SCpnt)
+static int nsp_nexus(struct scsi_cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
unsigned char target = scmd_id(SCpnt);
{
unsigned int base;
unsigned char irq_status, irq_phase, phase;
- Scsi_Cmnd *tmpSC;
+ struct scsi_cmnd *tmpSC;
unsigned char target, lun;
unsigned int *sync_neg;
int i, tmp;
/*---------------------------------------------------------------*/
/*
-static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
+static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
{
nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
return SUCCESS;
}
-static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
+static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
{
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
return nsp_bus_reset(data);
}
-static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
+static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
{
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
int TimerCount;
int SelectionTimeOut;
- Scsi_Cmnd *CurrentSC;
+ struct scsi_cmnd *CurrentSC;
//int CurrnetTarget;
int FifoCount;
int hostno,
#endif
int inout);
-static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt));
+static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+ void (* done)(struct scsi_cmnd *SCpnt));
/* Error handler */
-/*static int nsp_eh_abort (Scsi_Cmnd *SCpnt);*/
-/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
-static int nsp_eh_bus_reset (Scsi_Cmnd *SCpnt);
-static int nsp_eh_host_reset (Scsi_Cmnd *SCpnt);
+/*static int nsp_eh_abort (struct scsi_cmnd *SCpnt);*/
+/*static int nsp_eh_device_reset(struct scsi_cmnd *SCpnt);*/
+static int nsp_eh_bus_reset (struct scsi_cmnd *SCpnt);
+static int nsp_eh_host_reset (struct scsi_cmnd *SCpnt);
static int nsp_bus_reset (nsp_hw_data *data);
/* */
static int nsphw_init (nsp_hw_data *data);
-static int nsphw_start_selection(Scsi_Cmnd *SCpnt);
-static void nsp_start_timer (Scsi_Cmnd *SCpnt, int time);
-static int nsp_fifo_count (Scsi_Cmnd *SCpnt);
-static void nsp_pio_read (Scsi_Cmnd *SCpnt);
-static void nsp_pio_write (Scsi_Cmnd *SCpnt);
-static int nsp_nexus (Scsi_Cmnd *SCpnt);
-static void nsp_scsi_done (Scsi_Cmnd *SCpnt);
-static int nsp_analyze_sdtr (Scsi_Cmnd *SCpnt);
-static int nsp_negate_signal (Scsi_Cmnd *SCpnt, unsigned char mask, char *str);
-static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char mask);
-static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase);
-static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt);
-static int nsp_reselected (Scsi_Cmnd *SCpnt);
+static int nsphw_start_selection(struct scsi_cmnd *SCpnt);
+static void nsp_start_timer (struct scsi_cmnd *SCpnt, int time);
+static int nsp_fifo_count (struct scsi_cmnd *SCpnt);
+static void nsp_pio_read (struct scsi_cmnd *SCpnt);
+static void nsp_pio_write (struct scsi_cmnd *SCpnt);
+static int nsp_nexus (struct scsi_cmnd *SCpnt);
+static void nsp_scsi_done (struct scsi_cmnd *SCpnt);
+static int nsp_analyze_sdtr (struct scsi_cmnd *SCpnt);
+static int nsp_negate_signal (struct scsi_cmnd *SCpnt,
+ unsigned char mask, char *str);
+static int nsp_expect_signal (struct scsi_cmnd *SCpnt,
+ unsigned char current_phase,
+ unsigned char mask);
+static int nsp_xfer (struct scsi_cmnd *SCpnt, int phase);
+static int nsp_dataphase_bypass (struct scsi_cmnd *SCpnt);
+static int nsp_reselected (struct scsi_cmnd *SCpnt);
static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht);
/* Interrupt handler */
/* Debug */
#ifdef NSP_DEBUG
-static void show_command (Scsi_Cmnd *SCpnt);
-static void show_phase (Scsi_Cmnd *SCpnt);
+static void show_command (struct scsi_cmnd *SCpnt);
+static void show_phase (struct scsi_cmnd *SCpnt);
static void show_busphase(unsigned char stat);
static void show_message (nsp_hw_data *data);
#else
printk("\n");
}
-static void show_command(Scsi_Cmnd *SCpnt)
+static void show_command(struct scsi_cmnd *SCpnt)
{
print_commandk(SCpnt->cmnd);
}
-static void show_phase(Scsi_Cmnd *SCpnt)
+static void show_phase(struct scsi_cmnd *SCpnt)
{
int i = SCpnt->SCp.phase;
/* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */
-static void nsp_message_in(Scsi_Cmnd *SCpnt)
+static void nsp_message_in(struct scsi_cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
}
-static void nsp_message_out(Scsi_Cmnd *SCpnt)
+static void nsp_message_out(struct scsi_cmnd *SCpnt)
{
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
int ret = 1;
{
USHORT ports[13];
OUR_DEVICE device[8];
- Scsi_Cmnd *pSCmnd;
+ struct scsi_cmnd *pSCmnd;
IDE_STRUCT ide;
ULONG startSector;
USHORT sectorCount;
- Scsi_Cmnd *SCpnt;
+ struct scsi_cmnd *SCpnt;
VOID *buffer;
USHORT expectingIRQ;
} ADAPTER240I, *PADAPTER240I;
****************************************************************/
static void Irq_Handler (int irq, void *dev_id)
{
- struct Scsi_Host *shost; // Pointer to host data block
- PADAPTER240I padapter; // Pointer to adapter control structure
- USHORT *pports; // I/O port array
- Scsi_Cmnd *SCpnt;
- UCHAR status;
- int z;
+ struct Scsi_Host *shost; // Pointer to host data block
+ PADAPTER240I padapter; // Pointer to adapter control structure
+ USHORT *pports; // I/O port array
+ struct scsi_cmnd *SCpnt;
+ UCHAR status;
+ int z;
DEB(printk ("\npsi240i received interrupt\n"));
* Returns: Status code.
*
****************************************************************/
-static int Psi240i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int Psi240i_QueueCommand(struct scsi_cmnd *SCpnt,
+ void (*done)(struct scsi_cmnd *))
{
- UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB
- PADAPTER240I padapter = HOSTDATA (SCpnt->device->host); // Pointer to adapter control structure
- POUR_DEVICE pdev = &padapter->device [SCpnt->device->id];// Pointer to device information
- UCHAR rc; // command return code
+ UCHAR *cdb = (UCHAR *)SCpnt->cmnd;
+ // Pointer to SCSI CDB
+ PADAPTER240I padapter = HOSTDATA (SCpnt->device->host);
+ // Pointer to adapter control structure
+ POUR_DEVICE pdev = &padapter->device [SCpnt->device->id];
+ // Pointer to device information
+ UCHAR rc;
+ // command return code
SCpnt->scsi_done = done;
padapter->ide.ide.ides.spigot = pdev->spigot;
#endif // PSI_EIDE_SCSIOP
// function prototypes
-int Psi240i_Command (Scsi_Cmnd *SCpnt);
-int Psi240i_Abort (Scsi_Cmnd *SCpnt);
-int Psi240i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags);
+int Psi240i_Command(struct scsi_cmnd *SCpnt);
+int Psi240i_Abort(struct scsi_cmnd *SCpnt);
+int Psi240i_Reset(struct scsi_cmnd *SCpnt, unsigned int flags);
#endif
case BUS_RESET:
if (qla1280_verbose)
- printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS "
- "DEVICE RESET\n", ha->host_no, bus);
- if (qla1280_bus_reset(ha, bus == 0))
+ printk(KERN_INFO "qla1280(%ld:%d): Issued bus "
+ "reset.\n", ha->host_no, bus);
+ if (qla1280_bus_reset(ha, bus) == 0)
result = SUCCESS;
-
break;
case ADAPTER_RESET:
.read = qla2x00_sysfs_read_sfp,
};
+static struct sysfs_entry {
+ char *name;
+ struct bin_attribute *attr;
+ int is4GBp_only;
+} bin_file_entries[] = {
+ { "fw_dump", &sysfs_fw_dump_attr, },
+ { "nvram", &sysfs_nvram_attr, },
+ { "optrom", &sysfs_optrom_attr, },
+ { "optrom_ctl", &sysfs_optrom_ctl_attr, },
+ { "vpd", &sysfs_vpd_attr, 1 },
+ { "sfp", &sysfs_sfp_attr, 1 },
+ { 0 },
+};
+
void
qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
{
struct Scsi_Host *host = ha->host;
+ struct sysfs_entry *iter;
+ int ret;
- sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
- sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
- sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
- sysfs_create_bin_file(&host->shost_gendev.kobj,
- &sysfs_optrom_ctl_attr);
- if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
- sysfs_create_bin_file(&host->shost_gendev.kobj,
- &sysfs_vpd_attr);
- sysfs_create_bin_file(&host->shost_gendev.kobj,
- &sysfs_sfp_attr);
+ for (iter = bin_file_entries; iter->name; iter++) {
+ if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
+ continue;
+
+ ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
+ iter->attr);
+ if (ret)
+ qla_printk(KERN_INFO, ha,
+ "Unable to create sysfs %s binary attribute "
+ "(%d).\n", iter->name, ret);
}
}
qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
{
struct Scsi_Host *host = ha->host;
+ struct sysfs_entry *iter;
+
+ for (iter = bin_file_entries; iter->name; iter++) {
+ if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
+ continue;
- sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
- sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
- sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr);
- sysfs_remove_bin_file(&host->shost_gendev.kobj,
- &sysfs_optrom_ctl_attr);
- if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
- sysfs_remove_bin_file(&host->shost_gendev.kobj,
- &sysfs_vpd_attr);
sysfs_remove_bin_file(&host->shost_gendev.kobj,
- &sysfs_sfp_attr);
+ iter->attr);
}
if (ha->beacon_blink_led == 1)
* Macros use for debugging the driver.
*/
-#define DEBUG(x) do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_1)
#define DEBUG1(x) do {x;} while (0)
#define DEBUG1(x) do {} while (0)
#endif
-#define DEBUG2(x) do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_3(x) do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_3_11(x) do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_9_10(x) do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_11(x) do { if (qla2_extended_error_logging) { x; } } while (0)
-#define DEBUG2_13(x) do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2(x) do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_3(x) do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_3_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0)
#if defined(QL_DEBUG_LEVEL_3)
#define DEBUG3(x) do {x;} while (0)
spinlock_t rport_lock;
struct fc_rport *rport, *drport;
u32 supported_classes;
+
+ unsigned long last_queue_full;
+ unsigned long last_ramp_up;
} fc_port_t;
/*
uint16_t mgmt_svr_loop_id;
uint32_t login_retry_count;
+ int max_q_depth;
/* Fibre Channel Device List. */
struct list_head fcports;
extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
+extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
/*
* Global Data in qla_os.c source file.
extern int ql2xloginretrycount;
extern int ql2xfdmienable;
extern int ql2xallocfwdump;
-extern int qla2_extended_error_logging;
+extern int ql2xextended_error_logging;
+extern int ql2xqfullrampup;
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
* Set host adapter parameters.
*/
if (nv->host_p[0] & BIT_7)
- qla2_extended_error_logging = 1;
+ ql2xextended_error_logging = 1;
ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);
/* Always load RISC code on non ISP2[12]00 chips. */
if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
fail_fw_integrity:
return QLA_FUNCTION_FAILED;
}
+
+void
+qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
+{
+ int ret, retries;
+
+ if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+ return;
+
+ ret = qla2x00_stop_firmware(ha);
+ for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) {
+ qla2x00_reset_chip(ha);
+ if (qla2x00_chip_diag(ha) != QLA_SUCCESS)
+ continue;
+ if (qla2x00_setup_chip(ha) != QLA_SUCCESS)
+ continue;
+ qla_printk(KERN_INFO, ha,
+ "Attempting retry of stop-firmware command...\n");
+ ret = qla2x00_stop_firmware(ha);
+ }
+}
*/
#include "qla_def.h"
+#include <scsi/scsi_tcq.h>
+
static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
}
}
+static void
+qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
+{
+ fc_port_t *fcport = data;
+
+ if (fcport->ha->max_q_depth <= sdev->queue_depth)
+ return;
+
+ if (sdev->ordered_tags)
+ scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
+ sdev->queue_depth + 1);
+ else
+ scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG,
+ sdev->queue_depth + 1);
+
+ fcport->last_ramp_up = jiffies;
+
+ DEBUG2(qla_printk(KERN_INFO, fcport->ha,
+ "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
+ fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
+ sdev->queue_depth));
+}
+
+static void
+qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
+{
+ fc_port_t *fcport = data;
+
+ if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
+ return;
+
+ DEBUG2(qla_printk(KERN_INFO, fcport->ha,
+ "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
+ fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
+ sdev->queue_depth));
+}
+
+static inline void
+qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
+{
+ fc_port_t *fcport;
+ struct scsi_device *sdev;
+
+ sdev = sp->cmd->device;
+ if (sdev->queue_depth >= ha->max_q_depth)
+ return;
+
+ fcport = sp->fcport;
+ if (time_before(jiffies,
+ fcport->last_ramp_up + ql2xqfullrampup * HZ))
+ return;
+ if (time_before(jiffies,
+ fcport->last_queue_full + ql2xqfullrampup * HZ))
+ return;
+
+ spin_unlock_irq(&ha->hardware_lock);
+ starget_for_each_device(sdev->sdev_target, fcport,
+ qla2x00_adjust_sdev_qdepth_up);
+ spin_lock_irq(&ha->hardware_lock);
+}
+
/**
* qla2x00_process_completed_request() - Process a Fast Post response.
* @ha: SCSI driver HA context
/* Save ISP completion status */
sp->cmd->result = DID_OK << 16;
+
+ qla2x00_ramp_up_queue_depth(ha, sp);
qla2x00_sp_compl(ha, sp);
} else {
DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
*/
switch (comp_status) {
case CS_COMPLETE:
+ case CS_QUEUE_FULL:
if (scsi_status == 0) {
cp->result = DID_OK << 16;
break;
}
cp->result = DID_OK << 16 | lscsi_status;
+ if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
+ DEBUG2(printk(KERN_INFO
+ "scsi(%ld): QUEUE FULL status detected "
+ "0x%x-0x%x.\n", ha->host_no, comp_status,
+ scsi_status));
+
+ /* Adjust queue depth for all luns on the port. */
+ fcport->last_queue_full = jiffies;
+ spin_unlock_irq(&ha->hardware_lock);
+ starget_for_each_device(cp->device->sdev_target,
+ fcport, qla2x00_adjust_sdev_qdepth_down);
+ spin_lock_irq(&ha->hardware_lock);
+ break;
+ }
if (lscsi_status != SS_CHECK_CONDITION)
break;
qla2x00_mark_device_lost(ha, fcport, 1, 1);
break;
- case CS_QUEUE_FULL:
- DEBUG2(printk(KERN_INFO
- "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n",
- ha->host_no, comp_status, scsi_status));
-
- /* SCSI Mid-Layer handles device queue full */
-
- cp->result = DID_OK << 16 | lscsi_status;
-
- break;
-
default:
DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
"0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
"during HBA initialization. Memory allocation requirements "
"vary by ISP type. Default is 1 - allocate memory.");
-int qla2_extended_error_logging;
-module_param(qla2_extended_error_logging, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(qla2_extended_error_logging,
+int ql2xextended_error_logging;
+module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xextended_error_logging,
"Option to enable extended error logging, "
"Default is 0 - no logging. 1 - log errors.");
"Enables FDMI registratons "
"Default is 0 - no FDMI. 1 - perfom FDMI.");
+#define MAX_Q_DEPTH 32
+static int ql2xmaxqdepth = MAX_Q_DEPTH;
+module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xmaxqdepth,
+ "Maximum queue depth to report for target devices.");
+
+int ql2xqfullrampup = 120;
+module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(ql2xqfullrampup,
+ "Number of seconds to wait to begin to ramp-up the queue "
+ "depth for a device after a queue-full condition has been "
+ "detected. Default is 120 seconds.");
+
/*
* SCSI host template entry points
*/
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
if (sdev->tagged_supported)
- scsi_activate_tcq(sdev, 32);
+ scsi_activate_tcq(sdev, ha->max_q_depth);
else
- scsi_deactivate_tcq(sdev, 32);
+ scsi_deactivate_tcq(sdev, ha->max_q_depth);
rport->dev_loss_tmo = ha->port_down_retry_count + 5;
ha->link_data_rate = PORT_SPEED_UNKNOWN;
ha->optrom_size = OPTROM_SIZE_2300;
+ ha->max_q_depth = MAX_Q_DEPTH;
+ if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU)
+ ha->max_q_depth = ql2xmaxqdepth;
+
/* Assign ISP specific operations. */
ha->isp_ops.pci_config = qla2100_pci_config;
ha->isp_ops.reset_chip = qla2x00_reset_chip;
if (ha->eft)
qla2x00_trace_control(ha, TC_DISABLE, 0, 0);
+ ha->flags.online = 0;
+
/* Stop currently executing firmware. */
- qla2x00_stop_firmware(ha);
+ qla2x00_try_to_stop_firmware(ha);
/* turn-off interrupts on the card */
if (ha->interrupts_on)
qla2x00_mem_free(ha);
- ha->flags.online = 0;
-
/* Detach interrupts */
if (ha->host->irq)
free_irq(ha->host->irq, ha);
/* Derive version string. */
strcpy(qla2x00_version_str, QLA2XXX_VERSION);
- if (qla2_extended_error_logging)
+ if (ql2xextended_error_logging)
strcat(qla2x00_version_str, "-debug");
qla2xxx_transport_template =
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.01.07-k2"
+#define QLA2XXX_VERSION "8.01.07-k3"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 1
#endif
#if defined(QL_DEBUG_LEVEL_2)
-#define DEBUG2(x) do {if(qla4_extended_error_logging == 2) x;} while (0);
+#define DEBUG2(x) do {if(ql4xextended_error_logging == 2) x;} while (0);
#define DEBUG2_3(x) do {x;} while (0);
#else /* */
#define DEBUG2(x) do {} while (0);
#endif /* */
#if defined(QL_DEBUG_LEVEL_3)
-#define DEBUG3(x) do {if(qla4_extended_error_logging == 3) x;} while (0);
+#define DEBUG3(x) do {if(ql4xextended_error_logging == 3) x;} while (0);
#else /* */
#define DEBUG3(x) do {} while (0);
#if !defined(QL_DEBUG_LEVEL_2)
int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha,
uint32_t fw_ddb_index, uint32_t state);
-extern int qla4_extended_error_logging;
+extern int ql4xextended_error_logging;
extern int ql4xdiscoverywait;
extern int ql4xdontresethba;
#endif /* _QLA4x_GBL_H */
DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
ha->host_no, num_valid_entries));
- if (qla4_extended_error_logging == 3) {
+ if (ql4xextended_error_logging == 3) {
if (oldest_entry == 0) {
/* Circular Buffer has not wrapped around */
for (i=0; i < num_valid_entries; i++) {
" default it will reset hba :0"
" set to 1 to avoid resetting HBA");
-int qla4_extended_error_logging = 0; /* 0 = off, 1 = log errors */
-module_param(qla4_extended_error_logging, int, S_IRUGO | S_IRUSR);
-MODULE_PARM_DESC(qla4_extended_error_logging,
+int ql4xextended_error_logging = 0; /* 0 = off, 1 = log errors */
+module_param(ql4xextended_error_logging, int, S_IRUGO | S_IRUSR);
+MODULE_PARM_DESC(ql4xextended_error_logging,
"Option to enable extended error logging, "
"Default is 0 - no logging, 1 - debug logging");
/* Derive version string. */
strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION);
- if (qla4_extended_error_logging)
+ if (ql4xextended_error_logging)
strcat(qla4xxx_version_str, "-debug");
qla4xxx_scsi_transport =
goto release_srb_cache;
}
- printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
ret = pci_register_driver(&qla4xxx_pci_driver);
if (ret)
goto unregister_transport;
printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
return 0;
+
unregister_transport:
iscsi_unregister_transport(&qla4xxx_iscsi_transport);
release_srb_cache:
* caller must hold host lock
*/
-static void ql_icmd(Scsi_Cmnd * cmd)
+static void ql_icmd(struct scsi_cmnd *cmd)
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
int qbase = priv->qbase;
* Process scsi command - usually after interrupt
*/
-static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
+static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
{
unsigned int i, j;
unsigned long k;
static void ql_ihandl(void *dev_id)
{
- Scsi_Cmnd *icmd;
+ struct scsi_cmnd *icmd;
struct Scsi_Host *host = dev_id;
struct qlogicfas408_priv *priv = get_priv_by_host(host);
int qbase = priv->qbase;
* Queued command
*/
-int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
+ void (*done) (struct scsi_cmnd *))
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
if (scmd_id(cmd) == priv->qinitid) {
* Return bios parameters
*/
-int qlogicfas408_biosparam(struct scsi_device * disk,
- struct block_device *dev,
- sector_t capacity, int ip[])
+int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev,
+ sector_t capacity, int ip[])
{
/* This should mimic the DOS Qlogic driver's behavior exactly */
ip[0] = 0x40;
* Abort a command in progress
*/
-int qlogicfas408_abort(Scsi_Cmnd * cmd)
+int qlogicfas408_abort(struct scsi_cmnd *cmd)
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
priv->qabort = 1;
* the PCMCIA qlogic_stub code. This wants fixing
*/
-int qlogicfas408_bus_reset(Scsi_Cmnd * cmd)
+int qlogicfas408_bus_reset(struct scsi_cmnd *cmd)
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
unsigned long flags;
/*----------------------------------------------------------------*/
struct qlogicfas408_priv {
- int qbase; /* Port */
- int qinitid; /* initiator ID */
- int qabort; /* Flag to cause an abort */
- int qlirq; /* IRQ being used */
- int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */
- char qinfo[80]; /* description */
- Scsi_Cmnd *qlcmd; /* current command being processed */
- struct Scsi_Host *shost; /* pointer back to host */
- struct qlogicfas408_priv *next; /* next private struct */
+ int qbase; /* Port */
+ int qinitid; /* initiator ID */
+ int qabort; /* Flag to cause an abort */
+ int qlirq; /* IRQ being used */
+ int int_type; /* type of irq, 2 for ISA board, 0 for PCMCIA */
+ char qinfo[80]; /* description */
+ struct scsi_cmnd *qlcmd; /* current command being processed */
+ struct Scsi_Host *shost; /* pointer back to host */
+ struct qlogicfas408_priv *next; /* next private struct */
};
/* The qlogic card uses two register maps - These macros select which one */
#define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0])
irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id);
-int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
+int qlogicfas408_queuecommand(struct scsi_cmnd * cmd,
+ void (*done) (struct scsi_cmnd *));
int qlogicfas408_biosparam(struct scsi_device * disk,
- struct block_device *dev,
- sector_t capacity, int ip[]);
-int qlogicfas408_abort(Scsi_Cmnd * cmd);
-int qlogicfas408_bus_reset(Scsi_Cmnd * cmd);
+ struct block_device *dev,
+ sector_t capacity, int ip[]);
+int qlogicfas408_abort(struct scsi_cmnd * cmd);
+int qlogicfas408_bus_reset(struct scsi_cmnd * cmd);
const char *qlogicfas408_info(struct Scsi_Host *host);
int qlogicfas408_get_chip_type(int qbase, int int_type);
void qlogicfas408_setup(int qbase, int id, int int_type);
#include "scsi_debug.h"
#define SCSI_DEBUG_VERSION "1.80"
-static const char * scsi_debug_version_date = "20060914";
+static const char * scsi_debug_version_date = "20061018";
/* Additional Sense Code (ASC) used */
#define NO_ADDITIONAL_SENSE 0x0
struct sdebug_dev_info * devip);
static int resp_start_stop(struct scsi_cmnd * scp,
struct sdebug_dev_info * devip);
+static int resp_report_tgtpgs(struct scsi_cmnd * scp,
+ struct sdebug_dev_info * devip);
static int resp_readcap(struct scsi_cmnd * SCpnt,
struct sdebug_dev_info * devip);
static int resp_readcap16(struct scsi_cmnd * SCpnt,
static void __init init_all_queued(void);
static void stop_all_queued(void);
static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
-static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
- int dev_id_num, const char * dev_id_str,
- int dev_id_str_len);
+static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
+ int target_dev_id, int dev_id_num,
+ const char * dev_id_str, int dev_id_str_len);
static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
static int do_create_driverfs_files(void);
static void do_remove_driverfs_files(void);
}
errsts = resp_readcap16(SCpnt, devip);
break;
+ case MAINTENANCE_IN:
+ if (MI_REPORT_TARGET_PGS != cmd[1]) {
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ INVALID_OPCODE, 0);
+ errsts = check_condition_result;
+ break;
+ }
+ errsts = resp_report_tgtpgs(SCpnt, devip);
+ break;
case READ_16:
case READ_12:
case READ_10:
static const char * inq_product_id = "scsi_debug ";
static const char * inq_product_rev = "0004";
-static int inquiry_evpd_83(unsigned char * arr, int target_dev_id,
- int dev_id_num, const char * dev_id_str,
+static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
+ int target_dev_id, int dev_id_num,
+ const char * dev_id_str,
int dev_id_str_len)
{
int num, port_a;
arr[num++] = (port_a >> 16) & 0xff;
arr[num++] = (port_a >> 8) & 0xff;
arr[num++] = port_a & 0xff;
+ /* NAA-5, Target port group identifier */
+ arr[num++] = 0x61; /* proto=sas, binary */
+ arr[num++] = 0x95; /* piv=1, target port group id */
+ arr[num++] = 0x0;
+ arr[num++] = 0x4;
+ arr[num++] = 0;
+ arr[num++] = 0;
+ arr[num++] = (port_group_id >> 8) & 0xff;
+ arr[num++] = port_group_id & 0xff;
/* NAA-5, Target device identifier */
arr[num++] = 0x61; /* proto=sas, binary */
arr[num++] = 0xa3; /* piv=1, target device, naa */
struct sdebug_dev_info * devip)
{
unsigned char pq_pdt;
- unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
+ unsigned char * arr;
unsigned char *cmd = (unsigned char *)scp->cmnd;
- int alloc_len, n;
+ int alloc_len, n, ret;
alloc_len = (cmd[3] << 8) + cmd[4];
- memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
+ arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL);
if (devip->wlun)
pq_pdt = 0x1e; /* present, wlun */
else if (scsi_debug_no_lun_0 && (0 == devip->lun))
if (0x2 & cmd[1]) { /* CMDDT bit set */
mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
+ kfree(arr);
return check_condition_result;
} else if (0x1 & cmd[1]) { /* EVPD bit set */
- int lu_id_num, target_dev_id, len;
+ int lu_id_num, port_group_id, target_dev_id, len;
char lu_id_str[6];
int host_no = devip->sdbg_host->shost->host_no;
+ port_group_id = (((host_no + 1) & 0x7f) << 8) +
+ (devip->channel & 0x7f);
if (0 == scsi_debug_vpd_use_hostno)
host_no = 0;
lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) +
memcpy(&arr[4], lu_id_str, len);
} else if (0x83 == cmd[2]) { /* device identification */
arr[1] = cmd[2]; /*sanity */
- arr[3] = inquiry_evpd_83(&arr[4], target_dev_id,
- lu_id_num, lu_id_str, len);
+ arr[3] = inquiry_evpd_83(&arr[4], port_group_id,
+ target_dev_id, lu_id_num,
+ lu_id_str, len);
} else if (0x84 == cmd[2]) { /* Software interface ident. */
arr[1] = cmd[2]; /*sanity */
arr[3] = inquiry_evpd_84(&arr[4]);
/* Illegal request, invalid field in cdb */
mk_sense_buffer(devip, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
+ kfree(arr);
return check_condition_result;
}
len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len);
- return fill_from_dev_buffer(scp, arr,
+ ret = fill_from_dev_buffer(scp, arr,
min(len, SDEBUG_MAX_INQ_ARR_SZ));
+ kfree(arr);
+ return ret;
}
/* drops through here for a standard inquiry */
arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */
arr[2] = scsi_debug_scsi_level;
arr[3] = 2; /* response_data_format==2 */
arr[4] = SDEBUG_LONG_INQ_SZ - 5;
+ if (0 == scsi_debug_vpd_use_hostno)
+ arr[5] = 0x10; /* claim: implicit TGPS */
arr[6] = 0x10; /* claim: MultiP */
/* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */
arr[7] = 0xa; /* claim: LINKED + CMDQUE */
arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */
}
arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */
- return fill_from_dev_buffer(scp, arr,
+ ret = fill_from_dev_buffer(scp, arr,
min(alloc_len, SDEBUG_LONG_INQ_SZ));
+ kfree(arr);
+ return ret;
}
static int resp_requests(struct scsi_cmnd * scp,
min(alloc_len, SDEBUG_READCAP16_ARR_SZ));
}
+#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
+
+static int resp_report_tgtpgs(struct scsi_cmnd * scp,
+ struct sdebug_dev_info * devip)
+{
+ unsigned char *cmd = (unsigned char *)scp->cmnd;
+ unsigned char * arr;
+ int host_no = devip->sdbg_host->shost->host_no;
+ int n, ret, alen, rlen;
+ int port_group_a, port_group_b, port_a, port_b;
+
+ alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
+ + cmd[9]);
+
+ arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL);
+ /*
+ * EVPD page 0x88 states we have two ports, one
+ * real and a fake port with no device connected.
+ * So we create two port groups with one port each
+ * and set the group with port B to unavailable.
+ */
+ port_a = 0x1; /* relative port A */
+ port_b = 0x2; /* relative port B */
+ port_group_a = (((host_no + 1) & 0x7f) << 8) +
+ (devip->channel & 0x7f);
+ port_group_b = (((host_no + 1) & 0x7f) << 8) +
+ (devip->channel & 0x7f) + 0x80;
+
+ /*
+ * The asymmetric access state is cycled according to the host_id.
+ */
+ n = 4;
+ if (0 == scsi_debug_vpd_use_hostno) {
+ arr[n++] = host_no % 3; /* Asymm access state */
+ arr[n++] = 0x0F; /* claim: all states are supported */
+ } else {
+ arr[n++] = 0x0; /* Active/Optimized path */
+ arr[n++] = 0x01; /* claim: only support active/optimized paths */
+ }
+ arr[n++] = (port_group_a >> 8) & 0xff;
+ arr[n++] = port_group_a & 0xff;
+ arr[n++] = 0; /* Reserved */
+ arr[n++] = 0; /* Status code */
+ arr[n++] = 0; /* Vendor unique */
+ arr[n++] = 0x1; /* One port per group */
+ arr[n++] = 0; /* Reserved */
+ arr[n++] = 0; /* Reserved */
+ arr[n++] = (port_a >> 8) & 0xff;
+ arr[n++] = port_a & 0xff;
+ arr[n++] = 3; /* Port unavailable */
+ arr[n++] = 0x08; /* claim: only unavailalbe paths are supported */
+ arr[n++] = (port_group_b >> 8) & 0xff;
+ arr[n++] = port_group_b & 0xff;
+ arr[n++] = 0; /* Reserved */
+ arr[n++] = 0; /* Status code */
+ arr[n++] = 0; /* Vendor unique */
+ arr[n++] = 0x1; /* One port per group */
+ arr[n++] = 0; /* Reserved */
+ arr[n++] = 0; /* Reserved */
+ arr[n++] = (port_b >> 8) & 0xff;
+ arr[n++] = port_b & 0xff;
+
+ rlen = n - 4;
+ arr[0] = (rlen >> 24) & 0xff;
+ arr[1] = (rlen >> 16) & 0xff;
+ arr[2] = (rlen >> 8) & 0xff;
+ arr[3] = rlen & 0xff;
+
+ /*
+ * Return the smallest value of either
+ * - The allocated length
+ * - The constructed command length
+ * - The maximum array size
+ */
+ rlen = min(alen,n);
+ ret = fill_from_dev_buffer(scp, arr,
+ min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ));
+ kfree(arr);
+ return ret;
+}
+
/* <<Following mode page info copied from ST318451LW>> */
static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
{
struct request *req = cmd->request;
- BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
+ BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
cmd->cmd_len = req->cmd_len;
if (!req->data_len)
shost_rd_attr(unique_id, "%u\n");
shost_rd_attr(host_busy, "%hu\n");
shost_rd_attr(cmd_per_lun, "%hd\n");
+shost_rd_attr(can_queue, "%hd\n");
shost_rd_attr(sg_tablesize, "%hu\n");
shost_rd_attr(unchecked_isa_dma, "%d\n");
shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
&class_device_attr_unique_id,
&class_device_attr_host_busy,
&class_device_attr_cmd_per_lun,
+ &class_device_attr_can_queue,
&class_device_attr_sg_tablesize,
&class_device_attr_unchecked_isa_dma,
&class_device_attr_proc_name,
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/module.h>
-#include <linux/mempool.h>
#include <linux/mutex.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
static struct sock *nls;
static DEFINE_MUTEX(rx_queue_mutex);
-struct mempool_zone {
- mempool_t *pool;
- atomic_t allocated;
- int size;
- int hiwat;
- struct list_head freequeue;
- spinlock_t freelock;
-};
-
-static struct mempool_zone *z_reply;
-
-/*
- * Z_MAX_* - actual mempool size allocated at the mempool_zone_init() time
- * Z_HIWAT_* - zone's high watermark when if_error bit will be set to -ENOMEM
- * so daemon will notice OOM on NETLINK tranposrt level and will
- * be able to predict or change operational behavior
- */
-#define Z_MAX_REPLY 8
-#define Z_HIWAT_REPLY 6
-#define Z_MAX_PDU 8
-#define Z_HIWAT_PDU 6
-#define Z_MAX_ERROR 16
-#define Z_HIWAT_ERROR 12
-
static LIST_HEAD(sesslist);
static DEFINE_SPINLOCK(sesslock);
static LIST_HEAD(connlist);
}
EXPORT_SYMBOL_GPL(iscsi_destroy_session);
-static void mempool_zone_destroy(struct mempool_zone *zp)
-{
- mempool_destroy(zp->pool);
- kfree(zp);
-}
-
-static void*
-mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
-{
- struct mempool_zone *zone = pool_data;
-
- return alloc_skb(zone->size, gfp_mask);
-}
-
-static void
-mempool_zone_free_skb(void *element, void *pool_data)
-{
- kfree_skb(element);
-}
-
-static struct mempool_zone *
-mempool_zone_init(unsigned max, unsigned size, unsigned hiwat)
-{
- struct mempool_zone *zp;
-
- zp = kzalloc(sizeof(*zp), GFP_KERNEL);
- if (!zp)
- return NULL;
-
- zp->size = size;
- zp->hiwat = hiwat;
- INIT_LIST_HEAD(&zp->freequeue);
- spin_lock_init(&zp->freelock);
- atomic_set(&zp->allocated, 0);
-
- zp->pool = mempool_create(max, mempool_zone_alloc_skb,
- mempool_zone_free_skb, zp);
- if (!zp->pool) {
- kfree(zp);
- return NULL;
- }
-
- return zp;
-}
-
static void iscsi_conn_release(struct device *dev)
{
struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
struct device *parent = conn->dev.parent;
- mempool_zone_destroy(conn->z_pdu);
- mempool_zone_destroy(conn->z_error);
-
kfree(conn);
put_device(parent);
}
return dev->release == iscsi_conn_release;
}
-static int iscsi_create_event_pools(struct iscsi_cls_conn *conn)
-{
- conn->z_pdu = mempool_zone_init(Z_MAX_PDU,
- NLMSG_SPACE(sizeof(struct iscsi_uevent) +
- sizeof(struct iscsi_hdr) +
- DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH),
- Z_HIWAT_PDU);
- if (!conn->z_pdu) {
- dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
- "pdu zone for new conn\n");
- return -ENOMEM;
- }
-
- conn->z_error = mempool_zone_init(Z_MAX_ERROR,
- NLMSG_SPACE(sizeof(struct iscsi_uevent)),
- Z_HIWAT_ERROR);
- if (!conn->z_error) {
- dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate "
- "error zone for new conn\n");
- mempool_zone_destroy(conn->z_pdu);
- return -ENOMEM;
- }
- return 0;
-}
-
/**
* iscsi_create_conn - create iscsi class connection
* @session: iscsi cls session
conn->transport = transport;
conn->cid = cid;
- if (iscsi_create_event_pools(conn))
- goto free_conn;
-
/* this is released in the dev's release function */
if (!get_device(&session->dev))
- goto free_conn_pools;
+ goto free_conn;
snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
session->sid, cid);
release_parent_ref:
put_device(&session->dev);
-free_conn_pools:
-
free_conn:
kfree(conn);
return NULL;
return NULL;
}
-static inline struct list_head *skb_to_lh(struct sk_buff *skb)
-{
- return (struct list_head *)&skb->cb;
-}
-
-static void
-mempool_zone_complete(struct mempool_zone *zone)
-{
- unsigned long flags;
- struct list_head *lh, *n;
-
- spin_lock_irqsave(&zone->freelock, flags);
- list_for_each_safe(lh, n, &zone->freequeue) {
- struct sk_buff *skb = (struct sk_buff *)((char *)lh -
- offsetof(struct sk_buff, cb));
- if (!skb_shared(skb)) {
- list_del(skb_to_lh(skb));
- mempool_free(skb, zone->pool);
- atomic_dec(&zone->allocated);
- }
- }
- spin_unlock_irqrestore(&zone->freelock, flags);
-}
-
-static struct sk_buff*
-mempool_zone_get_skb(struct mempool_zone *zone)
-{
- struct sk_buff *skb;
-
- skb = mempool_alloc(zone->pool, GFP_ATOMIC);
- if (skb)
- atomic_inc(&zone->allocated);
- return skb;
-}
-
static int
-iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb, gfp_t gfp)
+iscsi_broadcast_skb(struct sk_buff *skb, gfp_t gfp)
{
- unsigned long flags;
int rc;
- skb_get(skb);
rc = netlink_broadcast(nls, skb, 0, 1, gfp);
if (rc < 0) {
- mempool_free(skb, zone->pool);
printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc);
return rc;
}
- spin_lock_irqsave(&zone->freelock, flags);
- INIT_LIST_HEAD(skb_to_lh(skb));
- list_add(skb_to_lh(skb), &zone->freequeue);
- spin_unlock_irqrestore(&zone->freelock, flags);
return 0;
}
static int
-iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
+iscsi_unicast_skb(struct sk_buff *skb, int pid)
{
- unsigned long flags;
int rc;
- skb_get(skb);
rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
if (rc < 0) {
- mempool_free(skb, zone->pool);
printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
return rc;
}
- spin_lock_irqsave(&zone->freelock, flags);
- INIT_LIST_HEAD(skb_to_lh(skb));
- list_add(skb_to_lh(skb), &zone->freequeue);
- spin_unlock_irqrestore(&zone->freelock, flags);
-
return 0;
}
if (!priv)
return -EINVAL;
- mempool_zone_complete(conn->z_pdu);
-
- skb = mempool_zone_get_skb(conn->z_pdu);
+ skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED);
dev_printk(KERN_ERR, &conn->dev, "iscsi: can not deliver "
memset(ev, 0, sizeof(*ev));
ev->transport_handle = iscsi_handle(conn->transport);
ev->type = ISCSI_KEVENT_RECV_PDU;
- if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
- ev->iferror = -ENOMEM;
ev->r.recv_req.cid = conn->cid;
ev->r.recv_req.sid = iscsi_conn_get_sid(conn);
pdu = (char*)ev + sizeof(*ev);
memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
- return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
+ return iscsi_unicast_skb(skb, priv->daemon_pid);
}
EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
if (!priv)
return;
- mempool_zone_complete(conn->z_error);
-
- skb = mempool_zone_get_skb(conn->z_error);
+ skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
dev_printk(KERN_ERR, &conn->dev, "iscsi: gracefully ignored "
"conn error (%d)\n", error);
ev = NLMSG_DATA(nlh);
ev->transport_handle = iscsi_handle(conn->transport);
ev->type = ISCSI_KEVENT_CONN_ERROR;
- if (atomic_read(&conn->z_error->allocated) >= conn->z_error->hiwat)
- ev->iferror = -ENOMEM;
ev->r.connerror.error = error;
ev->r.connerror.cid = conn->cid;
ev->r.connerror.sid = iscsi_conn_get_sid(conn);
- iscsi_broadcast_skb(conn->z_error, skb, GFP_ATOMIC);
+ iscsi_broadcast_skb(skb, GFP_ATOMIC);
dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
error);
int flags = multi ? NLM_F_MULTI : 0;
int t = done ? NLMSG_DONE : type;
- mempool_zone_complete(z_reply);
-
- skb = mempool_zone_get_skb(z_reply);
+ skb = alloc_skb(len, GFP_ATOMIC);
/*
* FIXME:
* user is supposed to react on iferror == -ENOMEM;
nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
nlh->nlmsg_flags = flags;
memcpy(NLMSG_DATA(nlh), payload, size);
- return iscsi_unicast_skb(z_reply, skb, pid);
+ return iscsi_unicast_skb(skb, pid);
}
static int
do {
int actual_size;
- mempool_zone_complete(conn->z_pdu);
-
- skbstat = mempool_zone_get_skb(conn->z_pdu);
+ skbstat = alloc_skb(len, GFP_ATOMIC);
if (!skbstat) {
dev_printk(KERN_ERR, &conn->dev, "iscsi: can not "
"deliver stats: OOM\n");
memset(evstat, 0, sizeof(*evstat));
evstat->transport_handle = iscsi_handle(conn->transport);
evstat->type = nlh->nlmsg_type;
- if (atomic_read(&conn->z_pdu->allocated) >= conn->z_pdu->hiwat)
- evstat->iferror = -ENOMEM;
evstat->u.get_stats.cid =
ev->u.get_stats.cid;
evstat->u.get_stats.sid =
skb_trim(skbstat, NLMSG_ALIGN(actual_size));
nlhstat->nlmsg_len = actual_size;
- err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid);
+ err = iscsi_unicast_skb(skbstat, priv->daemon_pid);
} while (err < 0 && err != -ECONNREFUSED);
return err;
session = iscsi_dev_to_session(conn->dev.parent);
shost = iscsi_session_to_shost(session);
- mempool_zone_complete(conn->z_pdu);
-
- skb = mempool_zone_get_skb(conn->z_pdu);
+ skb = alloc_skb(len, GFP_KERNEL);
if (!skb) {
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
"session creation event\n");
* this will occur if the daemon is not up, so we just warn
* the user and when the daemon is restarted it will handle it
*/
- rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL);
+ rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
if (rc < 0)
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
"session destruction event. Check iscsi daemon\n");
session = iscsi_dev_to_session(conn->dev.parent);
shost = iscsi_session_to_shost(session);
- mempool_zone_complete(conn->z_pdu);
-
- skb = mempool_zone_get_skb(conn->z_pdu);
+ skb = alloc_skb(len, GFP_KERNEL);
if (!skb) {
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
"session creation event\n");
* this will occur if the daemon is not up, so we just warn
* the user and when the daemon is restarted it will handle it
*/
- rc = iscsi_broadcast_skb(conn->z_pdu, skb, GFP_KERNEL);
+ rc = iscsi_broadcast_skb(skb, GFP_KERNEL);
if (rc < 0)
dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of "
"session creation event. Check iscsi daemon\n");
err = iscsi_if_send_reply(
NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
- if (atomic_read(&z_reply->allocated) >=
- z_reply->hiwat)
- ev->iferror = -ENOMEM;
} while (err < 0 && err != -ECONNREFUSED);
skb_pull(skb, rlen);
}
}
EXPORT_SYMBOL_GPL(iscsi_unregister_transport);
-static int
-iscsi_rcv_nl_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
- struct netlink_notify *n = ptr;
-
- if (event == NETLINK_URELEASE &&
- n->protocol == NETLINK_ISCSI && n->pid) {
- struct iscsi_cls_conn *conn;
- unsigned long flags;
-
- mempool_zone_complete(z_reply);
- spin_lock_irqsave(&connlock, flags);
- list_for_each_entry(conn, &connlist, conn_list) {
- mempool_zone_complete(conn->z_error);
- mempool_zone_complete(conn->z_pdu);
- }
- spin_unlock_irqrestore(&connlock, flags);
- }
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block iscsi_nl_notifier = {
- .notifier_call = iscsi_rcv_nl_event,
-};
-
static __init int iscsi_transport_init(void)
{
int err;
if (err)
goto unregister_conn_class;
- err = netlink_register_notifier(&iscsi_nl_notifier);
- if (err)
- goto unregister_session_class;
-
nls = netlink_kernel_create(NETLINK_ISCSI, 1, iscsi_if_rx,
THIS_MODULE);
if (!nls) {
err = -ENOBUFS;
- goto unregister_notifier;
+ goto unregister_session_class;
}
- z_reply = mempool_zone_init(Z_MAX_REPLY,
- NLMSG_SPACE(sizeof(struct iscsi_uevent)), Z_HIWAT_REPLY);
- if (z_reply)
- return 0;
+ return 0;
- sock_release(nls->sk_socket);
-unregister_notifier:
- netlink_unregister_notifier(&iscsi_nl_notifier);
unregister_session_class:
transport_class_unregister(&iscsi_session_class);
unregister_conn_class:
static void __exit iscsi_transport_exit(void)
{
- mempool_zone_destroy(z_reply);
sock_release(nls->sk_socket);
- netlink_unregister_notifier(&iscsi_nl_notifier);
transport_class_unregister(&iscsi_connection_class);
transport_class_unregister(&iscsi_session_class);
transport_class_unregister(&iscsi_host_class);
goto err_out;
if ((filp->f_flags & O_NONBLOCK) == 0 &&
retval != CHKRES_READY) {
- retval = (-EIO);
+ if (STp->ready == NO_TAPE)
+ retval = (-ENOMEDIUM);
+ else
+ retval = (-EIO);
goto err_out;
}
return 0;
(struct NCR5380_hostdata *)(in)->hostdata
#define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
-#define NEXT(cmd) ((Scsi_Cmnd *)((cmd)->host_scribble))
-#define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble))
+#define NEXT(cmd) ((struct scsi_cmnd *)((cmd)->host_scribble))
+#define NEXTADDR(cmd) ((struct scsi_cmnd **)&((cmd)->host_scribble))
#define HOSTNO instance->host_no
#define H_NO(cmd) (cmd)->device->host->host_no
* conditions.
*/
-static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged )
+static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
{
SETUP_HOSTDATA(cmd->device->host);
* untagged.
*/
-static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged )
+static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
{
SETUP_HOSTDATA(cmd->device->host);
* unlock the LUN.
*/
-static void cmd_free_tag( Scsi_Cmnd *cmd )
+static void cmd_free_tag(struct scsi_cmnd *cmd)
{
SETUP_HOSTDATA(cmd->device->host);
/*
- * Function: void merge_contiguous_buffers( Scsi_Cmnd *cmd )
+ * Function: void merge_contiguous_buffers(struct scsi_cmnd *cmd)
*
* Purpose: Try to merge several scatter-gather requests into one DMA
* transfer. This is possible if the scatter buffers lie on
* physical contiguous addresses.
*
- * Parameters: Scsi_Cmnd *cmd
+ * Parameters: struct scsi_cmnd *cmd
* The command to work on. The first scatter buffer's data are
* assumed to be already transfered into ptr/this_residual.
*/
-static void merge_contiguous_buffers( Scsi_Cmnd *cmd )
+static void merge_contiguous_buffers(struct scsi_cmnd *cmd)
{
unsigned long endaddr;
#if (NDEBUG & NDEBUG_MERGING)
}
/*
- * Function : void initialize_SCp(Scsi_Cmnd *cmd)
+ * Function : void initialize_SCp(struct scsi_cmnd *cmd)
*
* Purpose : initialize the saved data pointers for cmd to point to the
* start of the buffer.
*
- * Inputs : cmd - Scsi_Cmnd structure to have pointers reset.
+ * Inputs : cmd - struct scsi_cmnd structure to have pointers reset.
*/
-static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
+static __inline__ void initialize_SCp(struct scsi_cmnd *cmd)
{
/*
* Initialize the Scsi Pointer field so that all of the commands in the
do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \
pos += sprintf(pos, fmt , ## args); } while(0)
static
-char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
+char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer,
+ int length);
-static int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start,
- off_t offset, int length, int inout)
+static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer,
+ char **start, off_t offset, int length, int inout)
{
char *pos = buffer;
struct NCR5380_hostdata *hostdata;
- Scsi_Cmnd *ptr;
+ struct scsi_cmnd *ptr;
unsigned long flags;
off_t begin = 0;
#define check_offset() \
if (!hostdata->connected)
SPRINTF("scsi%d: no currently connected command\n", HOSTNO);
else
- pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected,
+ pos = lprint_Scsi_Cmnd ((struct scsi_cmnd *) hostdata->connected,
pos, buffer, length);
SPRINTF("scsi%d: issue_queue\n", HOSTNO);
check_offset();
- for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) {
+ for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr))
+ {
pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
check_offset();
}
SPRINTF("scsi%d: disconnected_queue\n", HOSTNO);
check_offset();
- for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
+ for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
ptr = NEXT(ptr)) {
pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
check_offset();
return length;
}
-static char *
-lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length)
+static char *lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, char *pos, char *buffer,
+ int length)
{
int i, s;
unsigned char *command;
}
/*
- * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd,
- * void (*done)(Scsi_Cmnd *))
+ * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd,
+ * void (*done)(struct scsi_cmnd *))
*
* Purpose : enqueues a SCSI command
*
*/
/* Only make static if a wrapper function is used */
-static int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int NCR5380_queue_command(struct scsi_cmnd *cmd,
+ void (*done)(struct scsi_cmnd *))
{
SETUP_HOSTDATA(cmd->device->host);
- Scsi_Cmnd *tmp;
+ struct scsi_cmnd *tmp;
unsigned long flags;
#if (NDEBUG & NDEBUG_NO_WRITE)
NEXT(cmd) = hostdata->issue_queue;
hostdata->issue_queue = cmd;
} else {
- for (tmp = (Scsi_Cmnd *)hostdata->issue_queue;
+ for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
NEXT(tmp); tmp = NEXT(tmp))
;
LIST(cmd, tmp);
static void NCR5380_main (void *bl)
{
- Scsi_Cmnd *tmp, *prev;
+ struct scsi_cmnd *tmp, *prev;
struct Scsi_Host *instance = first_instance;
struct NCR5380_hostdata *hostdata = HOSTDATA(instance);
int done;
* for a target that's not busy.
*/
#if (NDEBUG & NDEBUG_LISTS)
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL;
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL;
tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
;
if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/
#endif
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
+ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) {
#if (NDEBUG & NDEBUG_LISTS)
}
#ifdef NCR5380_STATS
-static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd)
+static void collect_stats(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *cmd)
{
# ifdef NCR5380_STAT_LIMIT
if (cmd->request_bufflen > NCR5380_STAT_LIMIT)
#endif
/*
- * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
- * int tag);
+ * Function : int NCR5380_select(struct Scsi_Host *instance,
+ * struct scsi_cmnd *cmd, int tag);
*
* Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
* including ARBITRATION, SELECTION, and initial message out for
* cmd->result host byte set to DID_BAD_TARGET.
*/
-static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
+static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd,
+ int tag)
{
SETUP_HOSTDATA(instance);
unsigned char tmp[3], phase;
#endif
unsigned char *data;
unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
- Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
+ struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
#ifdef SUN3_SCSI_VME
dregs->csr |= CSR_INTR;
local_irq_save(flags);
LIST(cmd,hostdata->issue_queue);
NEXT(cmd) = hostdata->issue_queue;
- hostdata->issue_queue = (Scsi_Cmnd *) cmd;
+ hostdata->issue_queue = (struct scsi_cmnd *) cmd;
local_irq_restore(flags);
QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
"issue queue\n", H_NO(cmd));
* Function : void NCR5380_reselect (struct Scsi_Host *instance)
*
* Purpose : does reselection, initializing the instance->connected
- * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q
+ * field to point to the struct scsi_cmnd for which the I_T_L or I_T_L_Q
* nexus has been reestablished,
*
* Inputs : instance - this instance of the NCR5380.
unsigned char tag;
#endif
unsigned char msg[3];
- Scsi_Cmnd *tmp = NULL, *prev;
+ struct scsi_cmnd *tmp = NULL, *prev;
/* unsigned long flags; */
/*
* just reestablished, and remove it from the disconnected queue.
*/
- for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
+ for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
tmp; prev = tmp, tmp = NEXT(tmp) ) {
if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
#ifdef SUPPORT_TAGS
/*
- * Function : int NCR5380_abort (Scsi_Cmnd *cmd)
+ * Function : int NCR5380_abort(struct scsi_cmnd *cmd)
*
* Purpose : abort a command
*
- * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the
+ * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the
* host byte of the result field to, if zero DID_ABORTED is
* used.
*
* called where the loop started in NCR5380_main().
*/
-static int NCR5380_abort (Scsi_Cmnd *cmd)
+static int NCR5380_abort(struct scsi_cmnd *cmd)
{
struct Scsi_Host *instance = cmd->device->host;
SETUP_HOSTDATA(instance);
- Scsi_Cmnd *tmp, **prev;
+ struct scsi_cmnd *tmp, **prev;
unsigned long flags;
printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO);
* Case 2 : If the command hasn't been issued yet, we simply remove it
* from the issue queue.
*/
- for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue),
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
- tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) )
+ for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue),
+ tmp = (struct scsi_cmnd *) hostdata->issue_queue;
+ tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp))
if (cmd == tmp) {
REMOVE(5, *prev, tmp, NEXT(tmp));
(*prev) = NEXT(tmp);
* it from the disconnected queue.
*/
- for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
+ for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
tmp = NEXT(tmp))
if (cmd == tmp) {
local_irq_restore(flags);
do_abort (instance);
local_irq_save(flags);
- for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue),
- tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
+ for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue),
+ tmp = (struct scsi_cmnd *) hostdata->disconnected_queue;
tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) )
if (cmd == tmp) {
REMOVE(5, *prev, tmp, NEXT(tmp));
/*
- * Function : int NCR5380_bus_reset (Scsi_Cmnd *cmd)
+ * Function : int NCR5380_bus_reset(struct scsi_cmnd *cmd)
*
* Purpose : reset the SCSI bus.
*
*
*/
-static int NCR5380_bus_reset( Scsi_Cmnd *cmd)
+static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
{
SETUP_HOSTDATA(cmd->device->host);
int i;
unsigned long flags;
#if 1
- Scsi_Cmnd *connected, *disconnected_queue;
+ struct scsi_cmnd *connected, *disconnected_queue;
#endif
* remembered in local variables first.
*/
local_irq_save(flags);
- connected = (Scsi_Cmnd *)hostdata->connected;
+ connected = (struct scsi_cmnd *)hostdata->connected;
hostdata->connected = NULL;
- disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue;
+ disconnected_queue = (struct scsi_cmnd *)hostdata->disconnected_queue;
hostdata->disconnected_queue = NULL;
#ifdef SUPPORT_TAGS
free_all_tags();
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
-static Scsi_Cmnd *sun3_dma_setup_done = NULL;
+static struct scsi_cmnd *sun3_dma_setup_done = NULL;
#define AFTER_RESET_DELAY (HZ/2)
return last_residual;
}
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
- int write_flag)
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
+ struct scsi_cmnd *cmd,
+ int write_flag)
{
if(blk_fs_request(cmd->request))
return wanted;
#define IOBASE_SUN3_VMESCSI 0xff200000
-static int sun3scsi_abort (Scsi_Cmnd *);
+static int sun3scsi_abort(struct scsi_cmnd *);
static int sun3scsi_detect (struct scsi_host_template *);
static const char *sun3scsi_info (struct Scsi_Host *);
-static int sun3scsi_bus_reset(Scsi_Cmnd *);
-static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sun3scsi_bus_reset(struct scsi_cmnd *);
+static int sun3scsi_queue_command(struct scsi_cmnd *,
+ void (*done)(struct scsi_cmnd *));
static int sun3scsi_release (struct Scsi_Host *);
#ifndef CMD_PER_LUN
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
-static Scsi_Cmnd *sun3_dma_setup_done = NULL;
+static struct scsi_cmnd *sun3_dma_setup_done = NULL;
#define AFTER_RESET_DELAY (HZ/2)
return last_residual;
}
-static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, Scsi_Cmnd *cmd,
- int write_flag)
+static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted,
+ struct scsi_cmnd *cmd,
+ int write_flag)
{
if(blk_fs_request(cmd->request))
return wanted;
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .max_sectors = 0x4000, /* 8MiB = 16 * 1024 * 512 */
};
/***********************************************************************
.update_status = corgibl_set_intensity,
};
-static int __init corgibl_probe(struct platform_device *pdev)
+static int corgibl_probe(struct platform_device *pdev)
{
struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
MODULE_DESCRIPTION("Corgi Backlight Driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL");
#include <asm/io.h>
#include <asm/hd64461.h>
#include <asm/cpu/dac.h>
-#include <asm/hp6xx/hp6xx.h>
#define WIDTH 640
return 1;
/* Find the bridge device. It is always 0:0.0 */
- if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) {
+ if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) {
ERR_MSG("cannot find bridge device\n");
return 1;
}
/* Get the fb aperture size and "stolen" memory amount. */
tmp = 0;
pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
+ pci_dev_put(bridge_dev);
+
switch (pdev->device) {
case PCI_DEVICE_ID_INTEL_915G:
case PCI_DEVICE_ID_INTEL_915GM:
int index = dinfo->pll_index;
DBG_MSG("intelfbhw_print_hw_state\n");
- if (!hw || !dinfo)
+ if (!hw)
return;
/* Read in as much of the HW state as possible. */
printk("hw state dump start\n");
select CRYPTO
select CRYPTO_MD5
select CRYPTO_DES
+ select CRYPTO_CBC
help
Provides for secure RPC calls by means of a gss-api
mechanism based on Kerberos V5. This is required for
select CRYPTO_MD5
select CRYPTO_DES
select CRYPTO_CAST5
+ select CRYPTO_CBC
help
Provides for secure RPC calls by means of a gss-api
mechanism based on the SPKM3 public-key mechanism.
* deleted it.
*/
-/**
- * d_move - move a dentry
+/*
+ * d_move_locked - move a dentry
* @dentry: entry to move
* @target: new dentry
*
* Update the dcache to reflect the move of a file name. Negative
* dcache entries should not be moved in this way.
*/
-
-void d_move(struct dentry * dentry, struct dentry * target)
+static void d_move_locked(struct dentry * dentry, struct dentry * target)
{
struct hlist_head *list;
if (!dentry->d_inode)
printk(KERN_WARNING "VFS: moving negative dcache entry\n");
- spin_lock(&dcache_lock);
write_seqlock(&rename_lock);
/*
* XXXX: do we really need to take target->d_lock?
fsnotify_d_move(dentry);
spin_unlock(&dentry->d_lock);
write_sequnlock(&rename_lock);
+}
+
+/**
+ * d_move - move a dentry
+ * @dentry: entry to move
+ * @target: new dentry
+ *
+ * Update the dcache to reflect the move of a file name. Negative
+ * dcache entries should not be moved in this way.
+ */
+
+void d_move(struct dentry * dentry, struct dentry * target)
+{
+ spin_lock(&dcache_lock);
+ d_move_locked(dentry, target);
spin_unlock(&dcache_lock);
}
+/*
+ * Helper that returns 1 if p1 is a parent of p2, else 0
+ */
+static int d_isparent(struct dentry *p1, struct dentry *p2)
+{
+ struct dentry *p;
+
+ for (p = p2; p->d_parent != p; p = p->d_parent) {
+ if (p->d_parent == p1)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * This helper attempts to cope with remotely renamed directories
+ *
+ * It assumes that the caller is already holding
+ * dentry->d_parent->d_inode->i_mutex and the dcache_lock
+ *
+ * Note: If ever the locking in lock_rename() changes, then please
+ * remember to update this too...
+ *
+ * On return, dcache_lock will have been unlocked.
+ */
+static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
+{
+ struct mutex *m1 = NULL, *m2 = NULL;
+ struct dentry *ret;
+
+ /* If alias and dentry share a parent, then no extra locks required */
+ if (alias->d_parent == dentry->d_parent)
+ goto out_unalias;
+
+ /* Check for loops */
+ ret = ERR_PTR(-ELOOP);
+ if (d_isparent(alias, dentry))
+ goto out_err;
+
+ /* See lock_rename() */
+ ret = ERR_PTR(-EBUSY);
+ if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
+ goto out_err;
+ m1 = &dentry->d_sb->s_vfs_rename_mutex;
+ if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
+ goto out_err;
+ m2 = &alias->d_parent->d_inode->i_mutex;
+out_unalias:
+ d_move_locked(alias, dentry);
+ ret = alias;
+out_err:
+ spin_unlock(&dcache_lock);
+ if (m2)
+ mutex_unlock(m2);
+ if (m1)
+ mutex_unlock(m1);
+ return ret;
+}
+
/*
* Prepare an anonymous dentry for life in the superblock's dentry tree as a
* named dentry in place of the dentry to be replaced.
*/
struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
{
- struct dentry *alias, *actual;
+ struct dentry *actual;
BUG_ON(!d_unhashed(dentry));
goto found_lock;
}
- /* See if a disconnected directory already exists as an anonymous root
- * that we should splice into the tree instead */
- if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) {
- spin_lock(&alias->d_lock);
-
- /* Is this a mountpoint that we could splice into our tree? */
- if (IS_ROOT(alias))
- goto connect_mountpoint;
-
- if (alias->d_name.len == dentry->d_name.len &&
- alias->d_parent == dentry->d_parent &&
- memcmp(alias->d_name.name,
- dentry->d_name.name,
- dentry->d_name.len) == 0)
- goto replace_with_alias;
-
- spin_unlock(&alias->d_lock);
-
- /* Doh! Seem to be aliasing directories for some reason... */
- dput(alias);
+ if (S_ISDIR(inode->i_mode)) {
+ struct dentry *alias;
+
+ /* Does an aliased dentry already exist? */
+ alias = __d_find_alias(inode, 0);
+ if (alias) {
+ actual = alias;
+ /* Is this an anonymous mountpoint that we could splice
+ * into our tree? */
+ if (IS_ROOT(alias)) {
+ spin_lock(&alias->d_lock);
+ __d_materialise_dentry(dentry, alias);
+ __d_drop(alias);
+ goto found;
+ }
+ /* Nope, but we must(!) avoid directory aliasing */
+ actual = __d_unalias(dentry, alias);
+ if (IS_ERR(actual))
+ dput(alias);
+ goto out_nolock;
+ }
}
/* Add a unique reference */
_d_rehash(actual);
spin_unlock(&actual->d_lock);
spin_unlock(&dcache_lock);
-
+out_nolock:
if (actual == dentry) {
security_d_instantiate(dentry, inode);
return NULL;
iput(inode);
return actual;
- /* Convert the anonymous/root alias into an ordinary dentry */
-connect_mountpoint:
- __d_materialise_dentry(dentry, alias);
-
- /* Replace the candidate dentry with the alias in the tree */
-replace_with_alias:
- __d_drop(alias);
- actual = alias;
- goto found;
-
shouldnt_be_hashed:
spin_unlock(&dcache_lock);
BUG();
struct inomap *imap;
int block_offset;
int inodes_left;
- uint pageno;
+ unsigned long pageno;
int rel_inode;
jfs_info("diRead: ino = %ld", ip->i_ino);
int block_offset;
int inodes_left;
struct metapage *mp;
- uint pageno;
+ unsigned long pageno;
int rel_inode;
int dioffset;
struct inode *ipimap;
no_entry:
res = d_materialise_unique(dentry, inode);
- if (res != NULL)
+ if (res != NULL) {
+ struct dentry *parent;
+ if (IS_ERR(res))
+ goto out_unlock;
+ /* Was a directory renamed! */
+ parent = dget_parent(res);
+ if (!IS_ROOT(parent))
+ nfs_mark_for_revalidate(parent->d_inode);
+ dput(parent);
dentry = res;
+ }
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_unlock:
alias = d_materialise_unique(dentry, inode);
if (alias != NULL) {
dput(dentry);
+ if (IS_ERR(alias))
+ return NULL;
dentry = alias;
}
#define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
#if defined(CONFIG_PXA25x)
-#define PXA_LAST_GPIO 80
+#define PXA_LAST_GPIO 84
#elif defined(CONFIG_PXA27x)
#define PXA_LAST_GPIO 127
#endif
" stcond %1, %0\n"
" brne 1b"
: "=&r"(result), "=o"(v->counter)
- : "m"(v->counter), "ir"(i)
+ : "m"(v->counter), "rKs21"(i)
: "cc");
return result;
{
int result;
- if (__builtin_constant_p(i))
+ if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
result = atomic_sub_return(-i, v);
else
asm volatile(
" mov %1, 1\n"
"1:"
: "=&r"(tmp), "=&r"(result), "=o"(v->counter)
- : "m"(v->counter), "ir"(a), "ir"(u)
+ : "m"(v->counter), "rKs21"(a), "rKs21"(u)
: "cc", "memory");
return result;
{
int tmp, result;
- if (__builtin_constant_p(a))
+ if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
result = atomic_sub_unless(v, -a, u);
else {
result = 0;
#define readsw(p, d, l) __raw_readsw((unsigned int)p, d, l)
#define readsl(p, d, l) __raw_readsl((unsigned int)p, d, l)
+
+/*
+ * io{read,write}{8,16,32} macros in both le (for PCI style consumers) and native be
+ */
+#ifndef ioread8
+
+#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; })
+
+#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
+#define ioread16be(p) ({ unsigned int __v = be16_to_cpu(__raw_readw(p)); __v; })
+
+#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
+#define ioread32be(p) ({ unsigned int __v = be32_to_cpu(__raw_readl(p)); __v; })
+
+#define iowrite8(v,p) __raw_writeb(v, p)
+
+#define iowrite16(v,p) __raw_writew(cpu_to_le16(v), p)
+#define iowrite16be(v,p) __raw_writew(cpu_to_be16(v), p)
+
+#define iowrite32(v,p) __raw_writel(cpu_to_le32(v), p)
+#define iowrite32be(v,p) __raw_writel(cpu_to_be32(v), p)
+
+#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
+#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
+#define ioread32_rep(p,d,c) __raw_readsl(p,d,c)
+
+#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c)
+#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c)
+#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c)
+
+#endif
+
+
/*
* These two are only here because ALSA _thinks_ it needs them...
*/
*(__param) \
VMLINUX_SYMBOL(__stop___param) = .; \
} \
+ \
+ /* Unwind data binary search table */ \
+ EH_FRAME_HDR \
+ \
__end_rodata = .; \
. = ALIGN(4096);
*(.kprobes.text) \
VMLINUX_SYMBOL(__kprobes_text_end) = .;
+#ifdef CONFIG_STACK_UNWIND
+ /* Unwind data binary search table */
+#define EH_FRAME_HDR \
+ .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_unwind_hdr) = .; \
+ *(.eh_frame_hdr) \
+ VMLINUX_SYMBOL(__end_unwind_hdr) = .; \
+ }
+#else
+#define EH_FRAME_HDR
+#endif
+
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to
the beginning of the section so we begin them at 0. */
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
-static inline void copy_to_user_page(struct vm_area_struct *vma,
+extern void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
-{
- if (cpu_has_dc_aliases)
- flush_cache_page(vma, vaddr, page_to_pfn(page));
- memcpy(dst, src, len);
- __flush_icache_page(vma, page);
-}
+ unsigned long len);
-static inline void copy_from_user_page(struct vm_area_struct *vma,
+extern void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
- unsigned long len)
-{
- if (cpu_has_dc_aliases)
- flush_cache_page(vma, vaddr, page_to_pfn(page));
- memcpy(dst, src, len);
-}
+ unsigned long len);
extern void (*flush_cache_sigtramp)(unsigned long addr);
extern void (*flush_icache_all)(void);
* fix-mapped?
*/
enum fixed_addresses {
+#define FIX_N_COLOURS 8
+ FIX_CMAP_BEGIN,
+#ifdef CONFIG_MIPS_MT_SMTC
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS),
+#else
+ FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+#endif
#ifdef CONFIG_HIGHMEM
- FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+ /* reserved pte's for temporary kernel mappings */
+ FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
__end_of_fixed_addresses
* at the top of mem..
*/
#if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
-#define FIXADDR_TOP (0xff000000UL - 0x2000)
+#define FIXADDR_TOP ((unsigned long)(long)(int)(0xff000000 - 0x20000))
#else
-#define FIXADDR_TOP (0xffffe000UL)
+#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000)
#endif
#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
# define ASM_CONST(x) __ASM_CONST(x)
#endif
+
+/*
+ * Feature section common macros
+ *
+ * Note that the entries now contain offsets between the table entry
+ * and the code rather than absolute code pointers in order to be
+ * useable with the vdso shared library. There is also an assumption
+ * that values will be negative, that is, the fixup table has to be
+ * located after the code it fixes up.
+ */
+#ifdef CONFIG_PPC64
+#ifdef __powerpc64__
+/* 64 bits kernel, 64 bits code */
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \
+99: \
+ .section sect,"a"; \
+ .align 3; \
+98: \
+ .llong msk; \
+ .llong val; \
+ .llong label##b-98b; \
+ .llong 99b-98b; \
+ .previous
+#else /* __powerpc64__ */
+/* 64 bits kernel, 32 bits code (ie. vdso32) */
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \
+99: \
+ .section sect,"a"; \
+ .align 3; \
+98: \
+ .llong msk; \
+ .llong val; \
+ .long 0xffffffff; \
+ .long label##b-98b; \
+ .long 0xffffffff; \
+ .long 99b-98b; \
+ .previous
+#endif /* !__powerpc64__ */
+#else /* CONFIG_PPC64 */
+/* 32 bits kernel, 32 bits code */
+#define MAKE_FTR_SECTION_ENTRY(msk, val, label, sect) \
+99: \
+ .section sect,"a"; \
+ .align 2; \
+98: \
+ .long msk; \
+ .long val; \
+ .long label##b-98b; \
+ .long 99b-98b; \
+ .previous
+#endif /* !CONFIG_PPC64 */
+
#ifdef __powerpc64__
/* operations for longs and pointers */
extern struct cpu_spec *cur_cpu_spec;
-extern void identify_cpu(unsigned long offset, unsigned long cpu);
-extern void do_cpu_ftr_fixups(unsigned long offset);
+extern unsigned int __start___ftr_fixup, __stop___ftr_fixup;
+
+extern struct cpu_spec *identify_cpu(unsigned long offset);
+extern void do_feature_fixups(unsigned long value, void *fixup_start,
+ void *fixup_end);
#endif /* __ASSEMBLY__ */
#define CPU_FTR_CI_LARGE_PAGE LONG_ASM_CONST(0x0000100000000000)
#define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000200000000000)
#define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000)
+#define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000800000000000)
#ifndef __ASSEMBLY__
#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
- CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE)
+ CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_CELL_TB_BUG)
#define CPU_FTRS_PA6T (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
#ifdef __ASSEMBLY__
-#define BEGIN_FTR_SECTION 98:
-
-#ifndef __powerpc64__
+#define BEGIN_FTR_SECTION_NESTED(label) label:
+#define BEGIN_FTR_SECTION BEGIN_FTR_SECTION_NESTED(97)
+#define END_FTR_SECTION_NESTED(msk, val, label) \
+ MAKE_FTR_SECTION_ENTRY(msk, val, label, __ftr_fixup)
#define END_FTR_SECTION(msk, val) \
-99: \
- .section __ftr_fixup,"a"; \
- .align 2; \
- .long msk; \
- .long val; \
- .long 98b; \
- .long 99b; \
- .previous
-#else /* __powerpc64__ */
-#define END_FTR_SECTION(msk, val) \
-99: \
- .section __ftr_fixup,"a"; \
- .align 3; \
- .llong msk; \
- .llong val; \
- .llong 98b; \
- .llong 99b; \
- .previous
-#endif /* __powerpc64__ */
+ END_FTR_SECTION_NESTED(msk, val, 97)
#define END_FTR_SECTION_IFSET(msk) END_FTR_SECTION((msk), (msk))
#define END_FTR_SECTION_IFCLR(msk) END_FTR_SECTION((msk), 0)
/* This is true if we are using the firmware NMI handler (typically LPAR) */
extern int fwnmi_active;
-#else /* __ASSEMBLY__ */
+extern unsigned int __start___fw_ftr_fixup, __stop___fw_ftr_fixup;
-#define BEGIN_FW_FTR_SECTION 96:
+#else /* __ASSEMBLY__ */
+#define BEGIN_FW_FTR_SECTION_NESTED(label) label:
+#define BEGIN_FW_FTR_SECTION BEGIN_FW_FTR_SECTION_NESTED(97)
+#define END_FW_FTR_SECTION_NESTED(msk, val, label) \
+ MAKE_FTR_SECTION_ENTRY(msk, val, label, __fw_ftr_fixup)
#define END_FW_FTR_SECTION(msk, val) \
-97: \
- .section __fw_ftr_fixup,"a"; \
- .align 3; \
- .llong msk; \
- .llong val; \
- .llong 96b; \
- .llong 97b; \
- .previous
+ END_FW_FTR_SECTION_NESTED(msk, val, 97)
#define END_FW_FTR_SECTION_IFSET(msk) END_FW_FTR_SECTION((msk), (msk))
#define END_FW_FTR_SECTION_IFCLR(msk) END_FW_FTR_SECTION((msk), 0)
#ifdef CONFIG_PPC_MERGE
extern void i8259_init(struct device_node *node, unsigned long intack_addr);
extern unsigned int i8259_irq(void);
+extern struct irq_host *i8259_get_host(void);
#else
extern void i8259_init(unsigned long intack_addr, int offset);
extern int i8259_irq(void);
mfspr ra,SPRN_PURR; /* get processor util. reg */ \
END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
BEGIN_FTR_SECTION; \
- mftb ra; /* or get TB if no PURR */ \
+ MFTB(ra); /* or get TB if no PURR */ \
END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
- ld rb,PACA_STARTPURR(r13); \
+ ld rb,PACA_STARTPURR(r13); \
std ra,PACA_STARTPURR(r13); \
subf rb,rb,ra; /* subtract start value */ \
ld ra,PACA_USER_TIME(r13); \
mfspr ra,SPRN_PURR; /* get processor util. reg */ \
END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
BEGIN_FTR_SECTION; \
- mftb ra; /* or get TB if no PURR */ \
+ MFTB(ra); /* or get TB if no PURR */ \
END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
- ld rb,PACA_STARTPURR(r13); \
+ ld rb,PACA_STARTPURR(r13); \
std ra,PACA_STARTPURR(r13); \
subf rb,rb,ra; /* subtract start value */ \
ld ra,PACA_SYSTEM_TIME(r13); \
#define ISYNC_601
#endif
+#ifdef CONFIG_PPC_CELL
+#define MFTB(dest) \
+90: mftb dest; \
+BEGIN_FTR_SECTION_NESTED(96); \
+ cmpwi dest,0; \
+ beq- 90b; \
+END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
+#else
+#define MFTB(dest) mftb dest
+#endif
#ifndef CONFIG_SMP
#define TLBSYNC
extern struct device_node *of_get_parent(const struct device_node *node);
extern struct device_node *of_get_next_child(const struct device_node *node,
struct device_node *prev);
-extern struct property *of_find_property(struct device_node *np,
+extern struct property *of_find_property(const struct device_node *np,
const char *name,
int *lenp);
extern struct device_node *of_node_get(struct device_node *node);
extern void finish_device_tree(void);
extern void unflatten_device_tree(void);
extern void early_init_devtree(void *);
-extern int device_is_compatible(struct device_node *device, const char *);
+extern int device_is_compatible(const struct device_node *device,
+ const char *);
extern int machine_is_compatible(const char *compat);
-extern const void *get_property(struct device_node *node, const char *name,
- int *lenp);
+extern const void *get_property(const struct device_node *node,
+ const char *name,
+ int *lenp);
extern void print_properties(struct device_node *node);
extern int prom_n_addr_cells(struct device_node* np);
extern int prom_n_size_cells(struct device_node* np);
#define PV_630 0x0040
#define PV_630p 0x0041
#define PV_970MP 0x0044
+#define PV_970GX 0x0045
#define PV_BE 0x0070
#define PV_PA6T 0x0090
: "=r" (rval)); rval;})
#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
+#ifdef __powerpc64__
+#ifdef CONFIG_PPC_CELL
+#define mftb() ({unsigned long rval; \
+ asm volatile( \
+ "90: mftb %0;\n" \
+ "97: cmpwi %0,0;\n" \
+ " beq- 90b;\n" \
+ "99:\n" \
+ ".section __ftr_fixup,\"a\"\n" \
+ ".align 3\n" \
+ "98:\n" \
+ " .llong %1\n" \
+ " .llong %1\n" \
+ " .llong 97b-98b\n" \
+ " .llong 99b-98b\n" \
+ ".previous" \
+ : "=r" (rval) : "i" (CPU_FTR_CELL_TB_BUG)); rval;})
+#else
#define mftb() ({unsigned long rval; \
asm volatile("mftb %0" : "=r" (rval)); rval;})
+#endif /* !CONFIG_PPC_CELL */
+
+#else /* __powerpc64__ */
+
#define mftbl() ({unsigned long rval; \
asm volatile("mftbl %0" : "=r" (rval)); rval;})
+#define mftbu() ({unsigned long rval; \
+ asm volatile("mftbu %0" : "=r" (rval)); rval;})
+#endif /* !__powerpc64__ */
#define mttbl(v) asm volatile("mttbl %0":: "r"(v))
#define mttbu(v) asm volatile("mttbu %0":: "r"(v))
#define __USE_RTC() 0
#endif
-/* On ppc64 this gets us the whole timebase; on ppc32 just the lower half */
+#ifdef CONFIG_PPC64
+
+/* For compatibility, get_tbl() is defined as get_tb() on ppc64 */
+#define get_tbl get_tb
+
+#else
+
static inline unsigned long get_tbl(void)
{
- unsigned long tbl;
-
#if defined(CONFIG_403GCX)
+ unsigned long tbl;
asm volatile("mfspr %0, 0x3dd" : "=r" (tbl));
+ return tbl;
#else
- asm volatile("mftb %0" : "=r" (tbl));
+ return mftbl();
#endif
- return tbl;
}
static inline unsigned int get_tbu(void)
{
+#ifdef CONFIG_403GCX
unsigned int tbu;
-
-#if defined(CONFIG_403GCX)
asm volatile("mfspr %0, 0x3dc" : "=r" (tbu));
+ return tbu;
#else
- asm volatile("mftbu %0" : "=r" (tbu));
+ return mftbu();
#endif
- return tbu;
}
+#endif /* !CONFIG_PPC64 */
static inline unsigned int get_rtcl(void)
{
{
return mftb();
}
-#else
+#else /* CONFIG_PPC64 */
static inline u64 get_tb(void)
{
unsigned int tbhi, tblo, tbhi2;
return ((u64)tbhi << 32) | tblo;
}
-#endif
+#endif /* !CONFIG_PPC64 */
static inline void set_tb(unsigned int upper, unsigned int lower)
{
*/
#include <asm/cputable.h>
+#include <asm/reg.h>
#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
static inline cycles_t get_cycles(void)
{
- cycles_t ret;
-
#ifdef __powerpc64__
-
- __asm__ __volatile__("mftb %0" : "=r" (ret) : );
-
+ return mftb();
#else
+ cycles_t ret;
+
/*
* For the "cycle" counter we use the timebase lower half.
* Currently only used on SMP.
ret = 0;
__asm__ __volatile__(
- "98: mftb %0\n"
+ "97: mftb %0\n"
"99:\n"
".section __ftr_fixup,\"a\"\n"
+ ".align 2\n"
+ "98:\n"
" .long %1\n"
" .long 0\n"
- " .long 98b\n"
- " .long 99b\n"
+ " .long 97b-98b\n"
+ " .long 99b-98b\n"
".previous"
: "=r" (ret) : "i" (CPU_FTR_601));
-#endif
-
return ret;
+#endif
}
#endif /* __KERNEL__ */
+++ /dev/null
-#ifndef __ASM_SH_HP6XX_IDE_H
-#define __ASM_SH_HP6XX_IDE_H
-
-#define IRQ_CFCARD 93
-#define IRQ_PCMCIA 94
-
-#endif /* __ASM_SH_HP6XX_IDE_H */
-
+++ /dev/null
-#ifndef __ASM_SH_HP6XX_IO_H
-#define __ASM_SH_HP6XX_IO_H
-
-/*
- * Nothing special here.. just use the generic cchip io routines.
- */
-#include <asm/hd64461.h>
-
-#endif /* __ASM_SH_HP6XX_IO_H */
-
+++ /dev/null
-#ifndef __ASM_SH_HS7751RVOIP_IDE_H
-#define __ASM_SH_HS7751RVOIP_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/hs7751rvoip/hs7751rvoip.h>
-
-#endif /* __ASM_SH_HS7751RVOIP_IDE_H */
-
*
* Copyright (C) 2004 Takashi SHUDO <shudo@hitachi-ul.co.jp>
*/
-
-#ifdef CONFIG_IDE
-# ifndef IRQ_CFCARD
-# define IRQ_CFCARD 14
-# endif
-# ifndef IRQ_PCMCIA
-# define IRQ_PCMCIA 15
-# endif
-#endif
-
#define INTC_BASE 0xffd00000
#define INTC_ICR0 (INTC_BASE+0x0)
#define INTC_ICR1 (INTC_BASE+0x1c)
#include <asm/machvec.h>
#include <asm/ptrace.h> /* for pt_regs */
-#if defined(CONFIG_SH_HP6XX) || \
- defined(CONFIG_SH_RTS7751R2D) || \
- defined(CONFIG_SH_HS7751RVOIP) || \
- defined(CONFIG_SH_HS7751RVOIP) || \
- defined(CONFIG_SH_SH03) || \
- defined(CONFIG_SH_R7780RP) || \
- defined(CONFIG_SH_LANDISK)
-#include <asm/mach/ide.h>
-#endif
-
#ifndef CONFIG_CPU_SUBTYPE_SH7780
#define INTC_DMAC0_MSK 0
#define INTC_IPRD 0xffd00010UL
#endif
-#ifdef CONFIG_IDE
-# ifndef IRQ_CFCARD
-# define IRQ_CFCARD 14
-# endif
-# ifndef IRQ_PCMCIA
-# define IRQ_PCMCIA 15
-# endif
-#endif
-
#define TIMER_IRQ 16
#define TIMER_IPR_ADDR INTC_IPRA
#define TIMER_IPR_POS 3
unsigned char priority;
};
-void make_intc2_irq(struct intc2_data *);
+void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs);
void init_IRQ_intc2(void);
#endif
+++ /dev/null
-/*
- * modifed by kogiidena
- * 2005.03.03
- */
-
-#ifndef __ASM_SH_LANDISK_IDE_H
-#define __ASM_SH_LANDISK_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/landisk/iodata_landisk.h>
-#define IRQ_CFCARD IRQ_FATA /* CF Card IRQ */
-#define IRQ_PCMCIA IRQ_ATA /* PCMCIA IRQ */
-
-#endif /* __ASM_SH_LANDISK_IDE_H */
*/
#define thread_saved_pc(tsk) (tsk->thread.pc)
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+ struct pt_regs *regs);
extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
#define PA_AX88796L 0xa4100400 /* AX88796L Area */
#define PA_SC1602BSLB 0xa6000000 /* SC1602BSLB Area */
-#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */
-#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */
#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */
#define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */
#define IRQ_PCISLOT2 66 /* PCI Slot #2 IRQ */
#define IRQ_PCISLOT3 67 /* PCI Slot #3 IRQ */
#define IRQ_PCISLOT4 68 /* PCI Slot #4 IRQ */
-#define IRQ_CFCARD 1 /* CF Card IRQ */
// #define IRQ_CFINST 0 /* CF Card Insert IRQ */
#define IRQ_TP 2 /* Touch Panel IRQ */
#define IRQ_SCI1 3 /* SCI1 IRQ */
#define PA_AX88796L 0xa5800400 /* AX88796L Area */
#define PA_SC1602BSLB 0xa6000000 /* SC1602BSLB Area */
-#define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */
-#define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */
#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */
#define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */
#define IRQ_PCISLOT2 1 /* PCI Slot #2 IRQ */
#define IRQ_PCISLOT3 2 /* PCI Slot #3 IRQ */
#define IRQ_PCISLOT4 3 /* PCI Slot #4 IRQ */
-#define IRQ_CFCARD 4 /* CF Card IRQ */
#define IRQ_CFINST 5 /* CF Card Insert IRQ */
#define IRQ_M66596 6 /* M66596 IRQ */
#define IRQ_SDCARD 7 /* SD Card IRQ */
+++ /dev/null
-#ifndef __ASM_SH_R7780RP_IDE_H
-#define __ASM_SH_R7780RP_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/mach/r7780rp.h>
-
-#endif /* __ASM_SH_R7780RP_IDE_H */
-
+++ /dev/null
-#ifndef __ASM_SH_RTS7751R2D_IDE_H
-#define __ASM_SH_RTS7751R2D_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/rts7751r2d/rts7751r2d.h>
-
-#endif /* __ASM_SH_RTS7751R2D_IDE_H */
-
+++ /dev/null
-#ifndef __ASM_SH_SH03_IDE_H
-#define __ASM_SH_SH03_IDE_H
-
-#define IRQ_CFCARD 8
-#define IRQ_PCMCIA 8
-
-#endif /* __ASM_SH_SH03_IDE_H */
(unsigned long)_n_, sizeof(*(ptr))); \
})
+extern void *set_exception_table_vec(unsigned int vec, void *handler);
+
+static inline void *set_exception_table_evt(unsigned int evt, void *handler)
+{
+ return set_exception_table_vec(evt >> 5, handler);
+}
+
/* XXX
* disable hlt during certain critical i/o operations
*/
return (u32)(unsigned long)uptr;
}
-static __inline__ void __user *compat_alloc_user_space(long len)
+static inline void __user *compat_alloc_user_space(long len)
{
struct pt_regs *regs = current_thread_info()->kregs;
unsigned long usp = regs->u_regs[UREG_I6];
else
usp &= 0xffffffffUL;
- return (void __user *) (usp - len);
+ usp -= len;
+ usp &= ~0x7UL;
+
+ return (void __user *) usp;
}
struct compat_ipc64_perm {
#ifndef __ASSEMBLY__
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
+extern void __setup_vector_irq(int cpu);
+extern spinlock_t vector_lock;
/*
* Various low-level irq details needed by irq.c, process.c,
{
pte_t pte;
pte_val(pte) = physpage | pgprot_val(pgprot);
+ pte_val(pte) &= __supported_pte_mask;
return pte;
}
extern int reboot_force;
extern int notsc_setup(char *);
+extern int timer_over_8254;
+
extern int gsi_irq_sharing(int gsi);
extern void smp_local_timer_interrupt(void);
COMPATIBLE_IOCTL(STOP_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY_RO)
COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+COMPATIBLE_IOCTL(GET_BITMAP_FILE)
ULONG_IOCTL(SET_BITMAP_FILE)
/* DM */
COMPATIBLE_IOCTL(DM_VERSION_32)
extern void device_initialize(struct device * dev);
extern int __must_check device_add(struct device * dev);
extern void device_del(struct device * dev);
-extern int __must_check device_for_each_child(struct device *, void *,
+extern int device_for_each_child(struct device *, void *,
int (*fn)(struct device *, void *));
extern int device_rename(struct device *dev, char *new_name);
struct dmi_device *from);
extern void dmi_scan_machine(void);
extern int dmi_get_year(int field);
+extern int dmi_name_in_vendors(char *str);
#else
static inline struct dmi_device * dmi_find_device(int type, const char *name,
struct dmi_device *from) { return NULL; }
static inline int dmi_get_year(int year) { return 0; }
+static inline int dmi_name_in_vendors(char *s) { return 0; }
#endif
ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
- ATA_DFLAG_NCQ_OFF = (1 << 9), /* devied limited to non-NCQ mode */
+ ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */
ATA_DFLAG_SUSPENDED = (1 << 10), /* device suspended */
ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
extern void mpol_fix_fork_child_flag(struct task_struct *p);
#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
-#ifdef CONFIG_CPUSET
+#ifdef CONFIG_CPUSETS
#define current_cpuset_is_being_rebound() \
(cpuset_being_rebound == current->cpuset)
#else
#define sparse_index_init(_sec, _nid) do {} while (0)
#endif /* CONFIG_SPARSEMEM */
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
+#else
+#define early_pfn_in_nid(pfn, nid) (1)
+#endif
+
#ifndef early_pfn_valid
#define early_pfn_valid(pfn) (1)
#endif
int pci_find_ext_capability (struct pci_dev *dev, int cap);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
-struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
+struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
+ struct pci_dev *from);
+struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device,
+ struct pci_dev *from);
+
struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device,
struct pci_dev *from);
static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
{ return NULL; }
-static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
+static inline struct pci_dev *pci_get_device(unsigned int vendor,
+ unsigned int device, struct pci_dev *from)
+{ return NULL; }
+
+static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor,
+ unsigned int device, struct pci_dev *from)
{ return NULL; }
static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
/* the superblock at the front of the bitmap file -- little endian */
typedef struct bitmap_super_s {
- __u32 magic; /* 0 BITMAP_MAGIC */
- __u32 version; /* 4 the bitmap major for now, could change... */
- __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */
- __u64 events; /* 24 event counter for the bitmap (1)*/
- __u64 events_cleared;/*32 event counter when last bit cleared (2) */
- __u64 sync_size; /* 40 the size of the md device's sync range(3) */
- __u32 state; /* 48 bitmap state information */
- __u32 chunksize; /* 52 the bitmap chunk size in bytes */
- __u32 daemon_sleep; /* 56 seconds between disk flushes */
- __u32 write_behind; /* 60 number of outstanding write-behind writes */
+ __le32 magic; /* 0 BITMAP_MAGIC */
+ __le32 version; /* 4 the bitmap major for now, could change... */
+ __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */
+ __le64 events; /* 24 event counter for the bitmap (1)*/
+ __le64 events_cleared;/*32 event counter when last bit cleared (2) */
+ __le64 sync_size; /* 40 the size of the md device's sync range(3) */
+ __le32 state; /* 48 bitmap state information */
+ __le32 chunksize; /* 52 the bitmap chunk size in bytes */
+ __le32 daemon_sleep; /* 56 seconds between disk flushes */
+ __le32 write_behind; /* 60 number of outstanding write-behind writes */
__u8 pad[256 - 64]; /* set to zero */
} bitmap_super_t;
*/
struct mdp_superblock_1 {
/* constant array information - 128 bytes */
- __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */
- __u32 major_version; /* 1 */
- __u32 feature_map; /* bit 0 set if 'bitmap_offset' is meaningful */
- __u32 pad0; /* always set to 0 when writing */
+ __le32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */
+ __le32 major_version; /* 1 */
+ __le32 feature_map; /* bit 0 set if 'bitmap_offset' is meaningful */
+ __le32 pad0; /* always set to 0 when writing */
__u8 set_uuid[16]; /* user-space generated. */
char set_name[32]; /* set and interpreted by user-space */
- __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
- __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */
- __u32 layout; /* only for raid5 and raid10 currently */
- __u64 size; /* used size of component devices, in 512byte sectors */
+ __le64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
+ __le32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */
+ __le32 layout; /* only for raid5 and raid10 currently */
+ __le64 size; /* used size of component devices, in 512byte sectors */
- __u32 chunksize; /* in 512byte sectors */
- __u32 raid_disks;
- __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts
+ __le32 chunksize; /* in 512byte sectors */
+ __le32 raid_disks;
+ __le32 bitmap_offset; /* sectors after start of superblock that bitmap starts
* NOTE: signed, so bitmap can be before superblock
* only meaningful of feature_map[0] is set.
*/
/* These are only valid with feature bit '4' */
- __u32 new_level; /* new level we are reshaping to */
- __u64 reshape_position; /* next address in array-space for reshape */
- __u32 delta_disks; /* change in number of raid_disks */
- __u32 new_layout; /* new layout */
- __u32 new_chunk; /* new chunk size (bytes) */
+ __le32 new_level; /* new level we are reshaping to */
+ __le64 reshape_position; /* next address in array-space for reshape */
+ __le32 delta_disks; /* change in number of raid_disks */
+ __le32 new_layout; /* new layout */
+ __le32 new_chunk; /* new chunk size (bytes) */
__u8 pad1[128-124]; /* set to 0 when written */
/* constant this-device information - 64 bytes */
- __u64 data_offset; /* sector start of data, often 0 */
- __u64 data_size; /* sectors in this device that can be used for data */
- __u64 super_offset; /* sector start of this superblock */
- __u64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
- __u32 dev_number; /* permanent identifier of this device - not role in raid */
- __u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */
+ __le64 data_offset; /* sector start of data, often 0 */
+ __le64 data_size; /* sectors in this device that can be used for data */
+ __le64 super_offset; /* sector start of this superblock */
+ __le64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
+ __le32 dev_number; /* permanent identifier of this device - not role in raid */
+ __le32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */
__u8 device_uuid[16]; /* user-space setable, ignored by kernel */
__u8 devflags; /* per-device flags. Only one defined...*/
#define WriteMostly1 1 /* mask for writemostly flag in above */
__u8 pad2[64-57]; /* set to 0 when writing */
/* array state information - 64 bytes */
- __u64 utime; /* 40 bits second, 24 btes microseconds */
- __u64 events; /* incremented when superblock updated */
- __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */
- __u32 sb_csum; /* checksum upto devs[max_dev] */
- __u32 max_dev; /* size of devs[] array to consider */
+ __le64 utime; /* 40 bits second, 24 btes microseconds */
+ __le64 events; /* incremented when superblock updated */
+ __le64 resync_offset; /* data before this offset (from data_offset) known to be in sync */
+ __le32 sb_csum; /* checksum upto devs[max_dev] */
+ __le32 max_dev; /* size of devs[] array to consider */
__u8 pad3[64-32]; /* set to 0 when writing */
/* device state information. Indexed by dev_number.
* into the 'roles' value. If a device is spare or faulty, then it doesn't
* have a meaningful role.
*/
- __u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
+ __le16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
};
/* feature_map bits */
* Initialize unwind support.
*/
extern void unwind_init(void);
+extern void unwind_setup(void);
#ifdef CONFIG_MODULES
struct unwind_frame_info {};
static inline void unwind_init(void) {}
+static inline void unwind_setup(void) {}
#ifdef CONFIG_MODULES
{
fl->uli_u.dnports.sport = scp->addrloc;
fl->uli_u.dnports.dport = scp->addrrem;
- fl->uli_u.dnports.objnum = scp->addr.sdn_objnum;
- if (fl->uli_u.dnports.objnum == 0) {
- fl->uli_u.dnports.objnamel = (__u8)dn_ntohs(scp->addr.sdn_objnamel);
- memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16);
- }
}
extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu);
struct {
__le16 sport;
__le16 dport;
- __u8 objnum;
- __u8 objnamel; /* Not 16 bits since max val is 16 */
- __u8 objname[16]; /* Not zero terminated */
} dnports;
__be32 spi;
/**
* sk_filter_release: Release a socket filter
- * @sk: socket
- * @fp: filter to remove
+ * @rcu: rcu_head that contains the sk_filter info to remove
*
* Remove a filter from a socket and release its resources.
*/
/* control data */
int id; /* CID */
- struct list_head item; /* maintains list of conns */
int c_stage; /* connection state */
/*
* Preallocated buffer for pdus that have data but do not
* - mgmtpool, *
* - r2tpool */
int state; /* session state */
- struct list_head item;
int age; /* counts session re-opens */
- struct list_head connections; /* list of connections */
int cmds_max; /* size of cmds array */
struct iscsi_cmd_task **cmds; /* Original Cmds arr */
struct iscsi_queue cmdpool; /* PDU's pool */
#define PERSISTENT_RESERVE_IN 0x5e
#define PERSISTENT_RESERVE_OUT 0x5f
#define REPORT_LUNS 0xa0
+#define MAINTENANCE_IN 0xa3
#define MOVE_MEDIUM 0xa5
#define EXCHANGE_MEDIUM 0xa6
#define READ_12 0xa8
#define SERVICE_ACTION_IN 0x9e
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
+/* values for maintenance in */
+#define MI_REPORT_TARGET_PGS 0x0a
/* Values for T10/04-262r7 */
#define ATA_16 0x85 /* 16-byte pass-thru */
#define SCSI_IOCTL_GET_PCI 0x5387
/* Pull a u32 out of a SCSI message (using BE SCSI conventions) */
-static inline u32 scsi_to_u32(u8 *ptr)
+static inline __u32 scsi_to_u32(__u8 *ptr)
{
return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
}
struct scsi_transport_template;
struct iscsi_transport;
struct Scsi_Host;
-struct mempool_zone;
struct iscsi_cls_conn;
struct iscsi_conn;
struct iscsi_cmd_task;
int active; /* must be accessed with the connlock */
struct device dev; /* sysfs transport/container device */
- struct mempool_zone *z_error;
- struct mempool_zone *z_pdu;
- struct list_head freequeue;
};
#define iscsi_dev_to_conn(_dev) \
/* include/version.h. Generated by alsa/ksync script. */
#define CONFIG_SND_VERSION "1.0.13"
-#define CONFIG_SND_DATE " (Fri Oct 06 18:28:19 2006 UTC)"
+#define CONFIG_SND_DATE " (Sun Oct 22 08:56:16 2006 UTC)"
printk(KERN_NOTICE);
printk(linux_banner);
setup_arch(&command_line);
+ unwind_setup();
setup_per_cpu_areas();
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
#include <linux/unwind.h>
#include <linux/module.h>
-#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/sort.h>
#include <linux/stop_machine.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
extern char __start_unwind[], __end_unwind[];
+extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
#define MAX_STACK_DEPTH 8
} core, init;
const void *address;
unsigned long size;
+ const unsigned char *header;
+ unsigned long hdrsz;
struct unwind_table *link;
const char *name;
} root_table;
return table;
}
+static unsigned long read_pointer(const u8 **pLoc,
+ const void *end,
+ signed ptrType);
+
static void init_unwind_table(struct unwind_table *table,
const char *name,
const void *core_start,
const void *init_start,
unsigned long init_size,
const void *table_start,
- unsigned long table_size)
+ unsigned long table_size,
+ const u8 *header_start,
+ unsigned long header_size)
{
+ const u8 *ptr = header_start + 4;
+ const u8 *end = header_start + header_size;
+
table->core.pc = (unsigned long)core_start;
table->core.range = core_size;
table->init.pc = (unsigned long)init_start;
table->init.range = init_size;
table->address = table_start;
table->size = table_size;
+ /* See if the linker provided table looks valid. */
+ if (header_size <= 4
+ || header_start[0] != 1
+ || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
+ || header_start[2] == DW_EH_PE_omit
+ || read_pointer(&ptr, end, header_start[2]) <= 0
+ || header_start[3] == DW_EH_PE_omit)
+ header_start = NULL;
+ table->hdrsz = header_size;
+ smp_wmb();
+ table->header = header_start;
table->link = NULL;
table->name = name;
}
init_unwind_table(&root_table, "kernel",
_text, _end - _text,
NULL, 0,
- __start_unwind, __end_unwind - __start_unwind);
+ __start_unwind, __end_unwind - __start_unwind,
+ __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
+}
+
+static const u32 bad_cie, not_fde;
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
+static signed fde_pointer_type(const u32 *cie);
+
+struct eh_frame_hdr_table_entry {
+ unsigned long start, fde;
+};
+
+static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
+{
+ const struct eh_frame_hdr_table_entry *e1 = p1;
+ const struct eh_frame_hdr_table_entry *e2 = p2;
+
+ return (e1->start > e2->start) - (e1->start < e2->start);
+}
+
+static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
+{
+ struct eh_frame_hdr_table_entry *e1 = p1;
+ struct eh_frame_hdr_table_entry *e2 = p2;
+ unsigned long v;
+
+ v = e1->start;
+ e1->start = e2->start;
+ e2->start = v;
+ v = e1->fde;
+ e1->fde = e2->fde;
+ e2->fde = v;
+}
+
+static void __init setup_unwind_table(struct unwind_table *table,
+ void *(*alloc)(unsigned long))
+{
+ const u8 *ptr;
+ unsigned long tableSize = table->size, hdrSize;
+ unsigned n;
+ const u32 *fde;
+ struct {
+ u8 version;
+ u8 eh_frame_ptr_enc;
+ u8 fde_count_enc;
+ u8 table_enc;
+ unsigned long eh_frame_ptr;
+ unsigned int fde_count;
+ struct eh_frame_hdr_table_entry table[];
+ } __attribute__((__packed__)) *header;
+
+ if (table->header)
+ return;
+
+ if (table->hdrsz)
+ printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
+ table->name);
+
+ if (tableSize & (sizeof(*fde) - 1))
+ return;
+
+ for (fde = table->address, n = 0;
+ tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
+ tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+ const u32 *cie = cie_for_fde(fde, table);
+ signed ptrType;
+
+ if (cie == ¬_fde)
+ continue;
+ if (cie == NULL
+ || cie == &bad_cie
+ || (ptrType = fde_pointer_type(cie)) < 0)
+ return;
+ ptr = (const u8 *)(fde + 2);
+ if (!read_pointer(&ptr,
+ (const u8 *)(fde + 1) + *fde,
+ ptrType))
+ return;
+ ++n;
+ }
+
+ if (tableSize || !n)
+ return;
+
+ hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
+ + 2 * n * sizeof(unsigned long);
+ header = alloc(hdrSize);
+ if (!header)
+ return;
+ header->version = 1;
+ header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
+ header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4;
+ header->table_enc = DW_EH_PE_abs|DW_EH_PE_native;
+ put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
+ BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
+ % __alignof(typeof(header->fde_count)));
+ header->fde_count = n;
+
+ BUILD_BUG_ON(offsetof(typeof(*header), table)
+ % __alignof(typeof(*header->table)));
+ for (fde = table->address, tableSize = table->size, n = 0;
+ tableSize;
+ tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+ const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
+
+ if (!fde[1])
+ continue; /* this is a CIE */
+ ptr = (const u8 *)(fde + 2);
+ header->table[n].start = read_pointer(&ptr,
+ (const u8 *)(fde + 1) + *fde,
+ fde_pointer_type(cie));
+ header->table[n].fde = (unsigned long)fde;
+ ++n;
+ }
+ WARN_ON(n != header->fde_count);
+
+ sort(header->table,
+ n,
+ sizeof(*header->table),
+ cmp_eh_frame_hdr_table_entries,
+ swap_eh_frame_hdr_table_entries);
+
+ table->hdrsz = hdrSize;
+ smp_wmb();
+ table->header = (const void *)header;
+}
+
+static void *__init balloc(unsigned long sz)
+{
+ return __alloc_bootmem_nopanic(sz,
+ sizeof(unsigned int),
+ __pa(MAX_DMA_ADDRESS));
+}
+
+void __init unwind_setup(void)
+{
+ setup_unwind_table(&root_table, balloc);
}
#ifdef CONFIG_MODULES
init_unwind_table(table, module->name,
module->module_core, module->core_size,
module->module_init, module->init_size,
- table_start, table_size);
+ table_start, table_size,
+ NULL, 0);
if (last_table)
last_table->link = table;
return value;
}
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
+{
+ const u32 *cie;
+
+ if (!*fde || (*fde & (sizeof(*fde) - 1)))
+ return &bad_cie;
+ if (!fde[1])
+ return ¬_fde; /* this is a CIE */
+ if ((fde[1] & (sizeof(*fde) - 1))
+ || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
+ return NULL; /* this is not a valid FDE */
+ cie = fde + 1 - fde[1] / sizeof(*fde);
+ if (*cie <= sizeof(*cie) + 4
+ || *cie >= fde[1] - sizeof(*fde)
+ || (*cie & (sizeof(*cie) - 1))
+ || cie[1])
+ return NULL; /* this is not a (valid) CIE */
+ return cie;
+}
+
static unsigned long read_pointer(const u8 **pLoc,
const void *end,
signed ptrType)
unsigned i;
signed ptrType = -1;
uleb128_t retAddrReg = 0;
- struct unwind_table *table;
+ const struct unwind_table *table;
struct unwind_state state;
if (UNW_PC(frame) == 0)
return -EINVAL;
if ((table = find_table(pc)) != NULL
&& !(table->size & (sizeof(*fde) - 1))) {
- unsigned long tableSize = table->size;
-
- for (fde = table->address;
- tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
- tableSize -= sizeof(*fde) + *fde,
- fde += 1 + *fde / sizeof(*fde)) {
- if (!*fde || (*fde & (sizeof(*fde) - 1)))
- break;
- if (!fde[1])
- continue; /* this is a CIE */
- if ((fde[1] & (sizeof(*fde) - 1))
- || fde[1] > (unsigned long)(fde + 1)
- - (unsigned long)table->address)
- continue; /* this is not a valid FDE */
- cie = fde + 1 - fde[1] / sizeof(*fde);
- if (*cie <= sizeof(*cie) + 4
- || *cie >= fde[1] - sizeof(*fde)
- || (*cie & (sizeof(*cie) - 1))
- || cie[1]
- || (ptrType = fde_pointer_type(cie)) < 0) {
- cie = NULL; /* this is not a (valid) CIE */
- continue;
+ const u8 *hdr = table->header;
+ unsigned long tableSize;
+
+ smp_rmb();
+ if (hdr && hdr[0] == 1) {
+ switch(hdr[3] & DW_EH_PE_FORM) {
+ case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
+ case DW_EH_PE_data2: tableSize = 2; break;
+ case DW_EH_PE_data4: tableSize = 4; break;
+ case DW_EH_PE_data8: tableSize = 8; break;
+ default: tableSize = 0; break;
+ }
+ ptr = hdr + 4;
+ end = hdr + table->hdrsz;
+ if (tableSize
+ && read_pointer(&ptr, end, hdr[1])
+ == (unsigned long)table->address
+ && (i = read_pointer(&ptr, end, hdr[2])) > 0
+ && i == (end - ptr) / (2 * tableSize)
+ && !((end - ptr) % (2 * tableSize))) {
+ do {
+ const u8 *cur = ptr + (i / 2) * (2 * tableSize);
+
+ startLoc = read_pointer(&cur,
+ cur + tableSize,
+ hdr[3]);
+ if (pc < startLoc)
+ i /= 2;
+ else {
+ ptr = cur - tableSize;
+ i = (i + 1) / 2;
+ }
+ } while (startLoc && i > 1);
+ if (i == 1
+ && (startLoc = read_pointer(&ptr,
+ ptr + tableSize,
+ hdr[3])) != 0
+ && pc >= startLoc)
+ fde = (void *)read_pointer(&ptr,
+ ptr + tableSize,
+ hdr[3]);
}
+ }
+
+ if (fde != NULL) {
+ cie = cie_for_fde(fde, table);
ptr = (const u8 *)(fde + 2);
- startLoc = read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType);
- endLoc = startLoc
- + read_pointer(&ptr,
- (const u8 *)(fde + 1) + *fde,
- ptrType & DW_EH_PE_indirect
- ? ptrType
- : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
- if (pc >= startLoc && pc < endLoc)
- break;
- cie = NULL;
+ if(cie != NULL
+ && cie != &bad_cie
+ && cie != ¬_fde
+ && (ptrType = fde_pointer_type(cie)) >= 0
+ && read_pointer(&ptr,
+ (const u8 *)(fde + 1) + *fde,
+ ptrType) == startLoc) {
+ if (!(ptrType & DW_EH_PE_indirect))
+ ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+ endLoc = startLoc
+ + read_pointer(&ptr,
+ (const u8 *)(fde + 1) + *fde,
+ ptrType);
+ if(pc >= endLoc)
+ fde = NULL;
+ } else
+ fde = NULL;
+ }
+ if (fde == NULL) {
+ for (fde = table->address, tableSize = table->size;
+ cie = NULL, tableSize > sizeof(*fde)
+ && tableSize - sizeof(*fde) >= *fde;
+ tableSize -= sizeof(*fde) + *fde,
+ fde += 1 + *fde / sizeof(*fde)) {
+ cie = cie_for_fde(fde, table);
+ if (cie == &bad_cie) {
+ cie = NULL;
+ break;
+ }
+ if (cie == NULL
+ || cie == ¬_fde
+ || (ptrType = fde_pointer_type(cie)) < 0)
+ continue;
+ ptr = (const u8 *)(fde + 2);
+ startLoc = read_pointer(&ptr,
+ (const u8 *)(fde + 1) + *fde,
+ ptrType);
+ if (!startLoc)
+ continue;
+ if (!(ptrType & DW_EH_PE_indirect))
+ ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+ endLoc = startLoc
+ + read_pointer(&ptr,
+ (const u8 *)(fde + 1) + *fde,
+ ptrType);
+ if (pc >= startLoc && pc < endLoc)
+ break;
+ }
}
}
if (cie != NULL) {
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
if (!early_pfn_valid(pfn))
continue;
+ if (!early_pfn_in_nid(pfn, nid))
+ continue;
page = pfn_to_page(pfn);
set_page_links(page, zone, nid, pfn);
init_page_count(page);
struct zone **z;
void *obj = NULL;
- for (z = zonelist->zones; *z && !obj; z++)
+ for (z = zonelist->zones; *z && !obj; z++) {
+ int nid = zone_to_nid(*z);
+
if (zone_idx(*z) <= ZONE_NORMAL &&
- cpuset_zone_allowed(*z, flags))
+ cpuset_zone_allowed(*z, flags) &&
+ cache->nodelists[nid])
obj = __cache_alloc_node(cache,
- flags | __GFP_THISNODE,
- zone_to_nid(*z));
+ flags | __GFP_THISNODE, nid);
+ }
return obj;
}
int atm_register_sysfs(struct atm_dev *adev)
{
struct class_device *cdev = &adev->class_dev;
- int i, err;
+ int i, j, err;
cdev->class = &atm_class;
class_set_devdata(cdev, adev);
if (err < 0)
return err;
- for (i = 0; atm_attrs[i]; i++)
- class_device_create_file(cdev, atm_attrs[i]);
+ for (i = 0; atm_attrs[i]; i++) {
+ err = class_device_create_file(cdev, atm_attrs[i]);
+ if (err)
+ goto err_out;
+ }
return 0;
+
+err_out:
+ for (j = 0; j < i; j++)
+ class_device_remove_file(cdev, atm_attrs[j]);
+ class_device_del(cdev);
+ return err;
}
void atm_unregister_sysfs(struct atm_dev *adev)
config IP_DCCP
tristate "The DCCP Protocol (EXPERIMENTAL)"
---help---
- Datagram Congestion Control Protocol
+ Datagram Congestion Control Protocol (RFC 4340)
- From draft-ietf-dccp-spec-11 <http://www.icir.org/kohler/dcp/draft-ietf-dccp-spec-11.txt>.
+ From http://www.ietf.org/rfc/rfc4340.txt:
The Datagram Congestion Control Protocol (DCCP) is a transport
protocol that implements bidirectional, unicast connections of
congestion-controlled, unreliable datagrams. It should be suitable
for use by applications such as streaming media, Internet telephony,
- and on-line games
+ and on-line games.
To compile this protocol support as a module, choose M here: the
module will be called dccp.
memcpy(to, from, len);
/*
- * From draft-ietf-dccp-spec-11.txt:
+ * From RFC 4340, A.2:
*
* For each acknowledgement it sends, the HC-Receiver will add an
* acknowledgement record. ack_seqno will equal the HC-Receiver
}
/*
- * Implements the draft-ietf-dccp-spec-11.txt Appendix A
+ * Implements the RFC 4340, Appendix A
*/
int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
const u64 ackno, const u8 state)
* We may well decide to do buffer compression, etc, but for now lets
* just drop.
*
- * From Appendix A:
+ * From Appendix A.1.1 (`New Packets'):
*
* Of course, the circular buffer may overflow, either when the
* HC-Sender is sending data at a very high rate, when the
/*
* A.1.2. Old Packets
*
- * When a packet with Sequence Number S arrives, and
- * S <= buf_ackno, the HC-Receiver will scan the table
- * for the byte corresponding to S. (Indexing structures
+ * When a packet with Sequence Number S <= buf_ackno
+ * arrives, the HC-Receiver will scan the table for
+ * the byte corresponding to S. (Indexing structures
* could reduce the complexity of this scan.)
*/
u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
/** struct dccp_ackvec - ack vector
*
- * This data structure is the one defined in the DCCP draft
- * Appendix A.
+ * This data structure is the one defined in RFC 4340, Appendix A.
*
* @dccpav_buf_head - circular buffer head
* @dccpav_buf_tail - circular buffer tail
for lost packets, would prefer CCID 2 to CCID 3. On-line games may
also prefer CCID 2.
- CCID 2 is further described in:
- http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid2-10.txt
+ CCID 2 is further described in RFC 4341,
+ http://www.ietf.org/rfc/rfc4341.txt
- This text was extracted from:
- http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt
+ This text was extracted from RFC 4340 (sec. 10.1),
+ http://www.ietf.org/rfc/rfc4340.txt
If in doubt, say M.
suitable than CCID 2 for applications such streaming media where a
relatively smooth sending rate is of importance.
- CCID 3 is further described in:
-
- http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid3-11.txt.
+ CCID 3 is further described in RFC 4342,
+ http://www.ietf.org/rfc/rfc4342.txt
The TFRC congestion control algorithms were initially described in
RFC 3448.
- This text was extracted from:
- http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt
+ This text was extracted from RFC 4340 (sec. 10.2),
+ http://www.ietf.org/rfc/rfc4340.txt
If in doubt, say M.
*/
/*
- * This implementation should follow: draft-ietf-dccp-ccid2-10.txt
+ * This implementation should follow RFC 4341
*
* BUGS:
* - sequence number wrapping
packet->dccphtx_seqno = dp->dccps_gss;
/*
* Check if win_count have changed
- * Algorithm in "8.1. Window Counter Valuer" in
- * draft-ietf-dccp-ccid3-11.txt
+ * Algorithm in "8.1. Window Counter Value" in RFC 4342.
*/
quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
if (likely(hctx->ccid3hctx_rtt > 8))
#define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT
* state, about 60 seconds */
-/* draft-ietf-dccp-spec-11.txt initial RTO value */
+/* RFC 1122, 4.2.3.1 initial RTO value */
#define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ))
/* Maximal interval between probes for local resources. */
dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
DCCP_PKT_SYNCACK);
/*
- * From the draft:
+ * From RFC 4340, sec. 5.7
*
* As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets
* MAY have non-zero-length application data areas, whose
- * contents * receivers MUST ignore.
+ * contents receivers MUST ignore.
*/
goto discard;
}
dccp_sync_mss(sk, mtu);
/*
- * From: draft-ietf-dccp-spec-11.txt
+ * From RFC 4340, sec. 14.1:
*
* DCCP-Sync packets are the best choice for upward
* probing, since DCCP-Sync probes do not risk application
dccp_hdr(skb)->dccph_sport);
}
+static struct request_sock_ops dccp_request_sock_ops;
+
int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct inet_request_sock *ireq;
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
goto drop;
- req = reqsk_alloc(sk->sk_prot->rsk_prot);
+ req = reqsk_alloc(&dccp_request_sock_ops);
if (req == NULL)
goto drop;
dccp_hdr_reset(skb)->dccph_reset_code =
DCCP_SKB_CB(rxskb)->dccpd_reset_code;
- /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+ /* See "8.3.1. Abnormal Termination" in RFC 4340 */
seqno = 0;
if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
dccp_hdr_reset(skb)->dccph_reset_code =
DCCP_SKB_CB(rxskb)->dccpd_reset_code;
- /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+ /* See "8.3.1. Abnormal Termination" in RFC 4340 */
seqno = 0;
if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
{
- struct inet_request_sock *ireq;
struct dccp_sock dp;
struct request_sock *req;
struct dccp_request_sock *dreq;
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
goto drop;
- req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot);
+ req = inet6_reqsk_alloc(&dccp6_request_sock_ops);
if (req == NULL)
goto drop;
goto drop_and_free;
ireq6 = inet6_rsk(req);
- ireq = inet_rsk(req);
ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
req->rcv_wnd = dccp_feat_default_sequence_window;
if (sk->sk_state == DCCP_OPEN) { /* Fast path */
if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
goto reset;
+ if (opt_skb) {
+ /* This is where we would goto ipv6_pktoptions. */
+ __kfree_skb(opt_skb);
+ }
return 0;
}
if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
goto reset;
+ if (opt_skb) {
+ /* This is where we would goto ipv6_pktoptions. */
+ __kfree_skb(opt_skb);
+ }
return 0;
reset:
elapsed_time);
break;
/*
- * From draft-ietf-dccp-spec-11.txt:
+ * From RFC 4340, sec. 10.3:
*
* Option numbers 128 through 191 are for
* options sent from the HC-Sender to the
depends on IEEE80211
select CRYPTO
select CRYPTO_ARC4
+ select CRYPTO_ECB
select CRC32
---help---
Include software based cipher suites in support of IEEE
depends on IEEE80211 && NET_RADIO
select CRYPTO
select CRYPTO_MICHAEL_MIC
+ select CRYPTO_ECB
select CRC32
---help---
Include software based cipher suites in support of IEEE 802.11i
{
struct arphdr *rarp;
unsigned char *rarp_ptr;
- unsigned long sip, tip;
+ u32 sip, tip;
unsigned char *sha, *tha; /* s for "source", t for "target" */
struct ic_device *d;
static struct fib6_table fib6_main_tbl = {
.tb6_id = RT6_TABLE_MAIN,
- .tb6_lock = RW_LOCK_UNLOCKED,
.tb6_root = {
.leaf = &ip6_null_entry,
.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
{
unsigned int h;
+ /*
+ * Initialize table lock at a single place to give lockdep a key,
+ * tables aren't visible prior to being linked to the list.
+ */
+ rwlock_init(&tb->tb6_lock);
+
h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1);
/*
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
static struct fib6_table fib6_local_tbl = {
.tb6_id = RT6_TABLE_LOCAL,
- .tb6_lock = RW_LOCK_UNLOCKED,
.tb6_root = {
.leaf = &ip6_null_entry,
.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
table = kzalloc(sizeof(*table), GFP_ATOMIC);
if (table != NULL) {
table->tb6_id = id;
- table->tb6_lock = RW_LOCK_UNLOCKED;
table->tb6_root.leaf = &ip6_null_entry;
table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
}
const char *outdev,
const struct ip6t_ip6 *ip6info,
unsigned int *protoff,
- int *fragoff)
+ int *fragoff, int *hotdrop)
{
size_t i;
unsigned long ret;
unsigned short _frag_off;
protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
- if (protohdr < 0)
+ if (protohdr < 0) {
+ if (_frag_off == 0)
+ *hotdrop = 1;
return 0;
-
+ }
*fragoff = _frag_off;
dprintf("Packet protocol %hi ?= %s%hi.\n",
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6,
- &protoff, &offset)) {
+ &protoff, &offset, &hotdrop)) {
struct ip6t_entry_target *t;
if (IP6T_MATCH_ITERATE(e, do_match,
* If target header is found, its offset is set in *offset and return protocol
* number. Otherwise, return -1.
*
+ * If the first fragment doesn't contain the final protocol header or
+ * NEXTHDR_NONE it is considered invalid.
+ *
* Note that non-1st fragment is special case that "the protocol number
* of last header" is "next header" field in Fragment header. In this case,
* *offset is meaningless and fragment offset is stored in *fragoff if fragoff
if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
if (target < 0)
break;
- return -1;
+ return -ENOENT;
}
hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
if (hp == NULL)
- return -1;
+ return -EBADMSG;
if (nexthdr == NEXTHDR_FRAGMENT) {
unsigned short _frag_off, *fp;
fp = skb_header_pointer(skb,
sizeof(_frag_off),
&_frag_off);
if (fp == NULL)
- return -1;
+ return -EBADMSG;
_frag_off = ntohs(*fp) & ~0x7;
if (_frag_off) {
*fragoff = _frag_off;
return hp->nexthdr;
}
- return -1;
+ return -ENOENT;
}
hdrlen = 8;
} else if (nexthdr == NEXTHDR_AUTH)
const struct ip6t_ah *ahinfo = matchinfo;
unsigned int ptr;
unsigned int hdrlen = 0;
+ int err;
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0)
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
+ if (err < 0) {
+ if (err != -ENOENT)
+ *hotdrop = 1;
return 0;
+ }
ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
if (ah == NULL) {
struct frag_hdr _frag, *fh;
const struct ip6t_frag *fraginfo = matchinfo;
unsigned int ptr;
+ int err;
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
+ if (err < 0) {
+ if (err != -ENOENT)
+ *hotdrop = 1;
return 0;
+ }
fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
if (fh == NULL) {
u8 _opttype, *tp = NULL;
u8 _optlen, *lp = NULL;
unsigned int optlen;
+ int err;
- if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0)
+ err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
+ if (err < 0) {
+ if (err != -ENOENT)
+ *hotdrop = 1;
return 0;
+ }
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
if (oh == NULL) {
unsigned int hdrlen = 0;
unsigned int ret = 0;
struct in6_addr *ap, _addr;
+ int err;
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
+ if (err < 0) {
+ if (err != -ENOENT)
+ *hotdrop = 1;
return 0;
+ }
rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
if (rh == NULL) {
return NET_XMIT_BYPASS;
}
+ skb_orphan(skb);
+
/*
* If we need to duplicate packet, then re-insert at top of the
* qdisc tree, since parent queuer expects that only one
x->id.proto, family);
}
+static void xfrm_hash_grow_check(int have_hash_collision)
+{
+ if (have_hash_collision &&
+ (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
+ xfrm_state_num > xfrm_state_hmask)
+ schedule_work(&xfrm_hash_work);
+}
+
struct xfrm_state *
xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
struct flowi *fl, struct xfrm_tmpl *tmpl,
x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
add_timer(&x->timer);
+ xfrm_state_num++;
+ xfrm_hash_grow_check(x->bydst.next != NULL);
} else {
x->km.state = XFRM_STATE_DEAD;
xfrm_state_put(x);
return x;
}
-static void xfrm_hash_grow_check(int have_hash_collision)
-{
- if (have_hash_collision &&
- (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
- xfrm_state_num > xfrm_state_hmask)
- schedule_work(&xfrm_hash_work);
-}
-
static void __xfrm_state_insert(struct xfrm_state *x)
{
unsigned int h;
".fixup",
".smp_locks",
".plt", /* seen on ARCH=um build on x86_64. Harmless */
+ "__ftr_fixup", /* powerpc cpu feature fixup */
+ "__fw_ftr_fixup", /* powerpc firmware feature fixup */
NULL
};
/* Start of section names */
}
switch (info->type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- private_size = sizeof(char);
- if (info->count > 128)
- return -EINVAL;
- break;
case SNDRV_CTL_ELEM_TYPE_INTEGER:
private_size = sizeof(long);
if (info->count > 128)
len = buffer->len - buffer->size;
va_start(args, fmt);
for (;;) {
- res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
+ va_list ap;
+ va_copy(ap, args);
+ res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap);
+ va_end(ap);
if (res < len)
break;
err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
config SND_ADLIB
tristate "AdLib FM card"
+ depends on SND
select SND_OPL3_LIB
help
Say Y here to include support for AdLib FM cards.
struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
int err;
+ if (!cfg)
+ return -ENOMEM;
acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
if (acard->dev == NULL) {
kfree(cfg);
struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
int err;
+ if (!cfg)
+ return -ENOMEM;
acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
if (acard->cap == NULL) {
kfree(cfg);
struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
int err;
+ if (!cfg)
+ return -ENOMEM;
iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
if (iwcard->dev == NULL) {
kfree(cfg);
struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
int err;
+ if (!cfg)
+ return -ENOMEM;
chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
if (chip->dev == NULL) {
kfree(cfg);
#include <asm/cpu/dac.h>
#include <asm/cpu/timer.h>
#include <asm/machvec.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
#include <asm/hd64461.h>
#define MODNAME "sh_dac_audio"
ac97->power_up &= ~(1 << (reg>>1));
else
ac97->power_up |= 1 << (reg>>1);
- if (power_save)
- update_power_regs(ac97);
+ update_power_regs(ac97);
}
#endif
return err;
}
}
- if (! power_save)
- return 0;
-
- if (! powerup && ac97->power_workq)
+ if (power_save && !powerup && ac97->power_workq)
/* adjust power-down bits after two seconds delay
* (for avoiding loud click noises for many (OSS) apps
* that open/close frequently)
outl(0xffffffff, ALI_REG(chip, ALI_STOP));
spin_unlock_irq(&chip->reg_lock);
+
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
if (! im)
return 0;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "ali5451: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+ pci_set_master(pci);
spin_lock_irq(&chip->reg_lock);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct snd_als300 *chip = card->private_data;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "als300: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_als300_init(chip);
snd_pcm_suspend_all(chip->pcm);
snd_sbmixer_suspend(chip);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card_als4000 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "als4000: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_als4000_configure(chip);
snd_atiixp_aclink_down(chip);
snd_atiixp_chip_stop(chip);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct atiixp *chip = card->private_data;
int i;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "atiixp: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_atiixp_aclink_reset(chip);
snd_atiixp_aclink_down(chip);
snd_atiixp_chip_stop(chip);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct atiixp_modem *chip = card->private_data;
int i;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "atiixp-modem: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_atiixp_aclink_reset(chip);
for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_azf3328 *chip = card->private_data;
int reg;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "azt3328: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
/* disable ints */
snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct cmipci *cm = card->private_data;
int i;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "cmipci: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
/* reset / initialize to a sane state */
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
unsigned int i;
u32 ulCLK;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "cs4281: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
/* disable CLKRUN */
chip->active_ctrl(chip, -chip->amplifier);
chip->amplifier = amp_saved; /* restore the status */
+
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_cs46xx *chip = card->private_data;
int amp_saved;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "cs46xx: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
+
amp_saved = chip->amplifier;
chip->amplifier = 0;
chip->active_ctrl(chip, 1); /* force to on */
snd_ac97_suspend(cs5535au->ac97);
/* save important regs, then disable aclink in hw */
snd_cs5535audio_stop_hardware(cs5535au);
+
pci_disable_device(pci);
pci_save_state(pci);
-
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
int timeout;
int i;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
/* set LNK_WRM_RST to reset AC link */
snd_emu10k1_done(emu);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct snd_emu10k1 *emu = card->private_data;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "emu10k1: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
-
+
snd_emu10k1_resume_init(emu);
snd_emu10k1_efx_resume(emu);
snd_ac97_resume(emu->ac97);
udelay(100);
snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
#endif
- pci_set_power_state(pci, PCI_D3hot);
+
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct ensoniq *ensoniq = card->private_data;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR DRIVER_NAME ": pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_ensoniq_chip_init(ensoniq);
*d = snd_es1938_reg_read(chip, *s);
outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
- if (chip->irq >= 0)
+ if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
+ chip->irq = -1;
+ }
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct es1938 *chip = card->private_data;
unsigned char *s, *d;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
- request_irq(pci->irq, snd_es1938_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "ES1938", chip);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "es1938: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+
+ if (request_irq(pci->irq, snd_es1938_interrupt,
+ IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) {
+ printk(KERN_ERR "es1938: unable to grab IRQ %d, "
+ "disabling device\n", pci->irq);
+ snd_card_disconnect(card);
+ return -EIO;
+ }
chip->irq = pci->irq;
snd_es1938_chip_init(chip);
snd_es1938_free_gameport(chip);
- if (chip->irq >= 0)
+ if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
+ }
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
spin_lock_init(&chip->mixer_lock);
chip->card = card;
chip->pci = pci;
+ chip->irq = -1;
if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
kfree(chip);
pci_disable_device(pci);
#define ESM_MODE_PLAY 0
#define ESM_MODE_CAPTURE 1
-/* acpi states */
-enum {
- ACPI_D0=0,
- ACPI_D1,
- ACPI_D2,
- ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ ( 1 << 15)
-#define ACPI_24MHZ ( 1 << 14)
-#define ACPI_978 ( 1 << 13)
-#define ACPI_SPDIF ( 1 << 12)
-#define ACPI_GLUE ( 1 << 11)
-#define ACPI__10 ( 1 << 10) /* reserved */
-#define ACPI_PCIINT ( 1 << 9)
-#define ACPI_HV ( 1 << 8) /* hardware volume */
-#define ACPI_GPIO ( 1 << 7)
-#define ACPI_ASSP ( 1 << 6)
-#define ACPI_SB ( 1 << 5) /* sb emul */
-#define ACPI_FM ( 1 << 4) /* fm emul */
-#define ACPI_RB ( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI ( 1 << 2)
-#define ACPI_GP ( 1 << 1) /* game port */
-#define ACPI_WP ( 1 << 0) /* wave processor */
-
-#define ACPI_ALL (0xffff)
-#define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
- ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE (ACPI__10)
-
-/* these masks indicate which units we care about at
- which states */
-static u16 acpi_state_mask[] = {
- [ACPI_D0] = ACPI_ALL,
- [ACPI_D1] = ACPI_SLEEP,
- [ACPI_D2] = ACPI_SLEEP,
- [ACPI_D3] = ACPI_NONE
-};
-
/* APU use in the driver */
enum snd_enum_apu_type {
udelay(10);
}
-/*
- * power management
- */
-static void snd_es1968_set_acpi(struct es1968 *chip, int state)
-{
- u16 active_mask = acpi_state_mask[state];
-
- pci_set_power_state(chip->pci, state);
- /* make sure the units we care about are on
- XXX we might want to do this before state flipping? */
- pci_write_config_word(chip->pci, 0x54, ~ active_mask);
- pci_write_config_word(chip->pci, 0x56, ~ active_mask);
-}
-
-
/*
* initialize maestro chip
*/
* IRQs.
*/
- /* do config work at full power */
- snd_es1968_set_acpi(chip, ACPI_D0);
-
/* Config Reg A */
pci_read_config_word(pci, ESM_CONFIG_A, &w);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
snd_es1968_bob_stop(chip);
- snd_es1968_set_acpi(chip, ACPI_D3);
+
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
return 0;
/* restore all our config */
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "es1968: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
+
snd_es1968_chip_init(chip);
/* need to restore the base pointers.. */
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
snd_es1968_free_gameport(chip);
- snd_es1968_set_acpi(chip, ACPI_D3);
chip->master_switch = NULL;
chip->master_volume = NULL;
pci_release_regions(chip->pci);
chip->saved_regs[i] = inw(chip->port + saved_regs[i]);
/* FIXME: tea575x suspend */
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct fm801 *chip = card->private_data;
int i;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "fm801: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_fm801_chip_init(chip, 1);
"{ATI, SB450},"
"{ATI, SB600},"
"{ATI, RS600},"
+ "{ATI, RS690},"
"{VIA, VT8251},"
"{VIA, VT8237A},"
"{SiS, SIS966},"
unsigned int initialized :1;
unsigned int single_cmd :1;
unsigned int polling_mode :1;
+ unsigned int msi :1;
};
/* driver types */
*/
#define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0)
+static int azx_acquire_irq(struct azx *chip, int do_disconnect);
/*
* Interface for HD codec
schedule_timeout_interruptible(1);
} while (time_after_eq(timeout, jiffies));
+ if (chip->msi) {
+ snd_printk(KERN_WARNING "hda_intel: No response from codec, "
+ "disabling MSI...\n");
+ free_irq(chip->irq, chip);
+ chip->irq = -1;
+ pci_disable_msi(chip->pci);
+ chip->msi = 0;
+ if (azx_acquire_irq(chip, 1) < 0)
+ return -1;
+ goto again;
+ }
+
if (!chip->polling_mode) {
snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
"switching to polling mode...\n");
return 0;
}
+static int azx_acquire_irq(struct azx *chip, int do_disconnect)
+{
+ if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ "HDA Intel", chip)) {
+ printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
+ "disabling device\n", chip->pci->irq);
+ if (do_disconnect)
+ snd_card_disconnect(chip->card);
+ return -1;
+ }
+ chip->irq = chip->pci->irq;
+ return 0;
+}
+
#ifdef CONFIG_PM
/*
snd_pcm_suspend_all(chip->pcm[i]);
snd_hda_suspend(chip->bus, state);
azx_free_cmd_io(chip);
- if (chip->irq >= 0)
+ if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
- if (!disable_msi)
+ chip->irq = -1;
+ }
+ if (chip->msi)
pci_disable_msi(chip->pci);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct azx *chip = card->private_data;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
- if (!disable_msi)
- pci_enable_msi(pci);
- /* FIXME: need proper error handling */
- request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
- "HDA Intel", chip);
- chip->irq = pci->irq;
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "hda-intel: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
+ if (chip->msi)
+ if (pci_enable_msi(pci) < 0)
+ chip->msi = 0;
+ if (azx_acquire_irq(chip, 1) < 0)
+ return -EIO;
azx_init_chip(chip);
snd_hda_resume(chip->bus);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
/* disable position buffer */
azx_writel(chip, DPLBASE, 0);
azx_writel(chip, DPUBASE, 0);
-
- synchronize_irq(chip->irq);
}
if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
free_irq(chip->irq, (void*)chip);
- if (!disable_msi)
- pci_disable_msi(chip->pci);
}
+ if (chip->msi)
+ pci_disable_msi(chip->pci);
if (chip->remap_addr)
iounmap(chip->remap_addr);
chip->pci = pci;
chip->irq = -1;
chip->driver_type = driver_type;
+ chip->msi = !disable_msi;
chip->position_fix = position_fix;
chip->single_cmd = single_cmd;
goto errout;
}
- if (!disable_msi)
- pci_enable_msi(pci);
+ if (chip->msi)
+ if (pci_enable_msi(pci) < 0)
+ chip->msi = 0;
- if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
- "HDA Intel", (void*)chip)) {
- snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
+ if (azx_acquire_irq(chip, 0) < 0) {
err = -EBUSY;
goto errout;
}
- chip->irq = pci->irq;
pci_set_master(pci);
synchronize_irq(chip->irq);
{ 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
{ 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
{ 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
+ { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
.config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1263,
+ .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
*/
struct hda_codec_preset snd_hda_preset_atihdmi[] = {
{ .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
+ { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi },
{} /* terminator */
};
/* SPDIF for stream index #1 */
if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
codec->num_pcms = 2;
- info++;
+ info = spec->pcm_rec + 1;
info->name = spec->stream_name_digital;
if (spec->multiout.dig_out_nid &&
spec->stream_digital_playback) {
if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
spec->adc_nids) {
codec->num_pcms = 3;
- info++;
+ info = spec->pcm_rec + 2;
info->name = spec->stream_name_analog;
/* No playback stream for second PCM */
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
.name = "Tyan Thunder K8WE",
.type = AC97_TUNE_HP_ONLY
},
+ {
+ .subvendor = 0x10f7,
+ .subdevice = 0x834c,
+ .name = "Panasonic CF-R4",
+ .type = AC97_TUNE_HP_ONLY,
+ },
{
.subvendor = 0x110a,
.subdevice = 0x0056,
if (chip->device_type == DEVICE_INTEL_ICH4)
chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
- if (chip->irq >= 0)
+ if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
+ chip->irq = -1;
+ }
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct intel8x0 *chip = card->private_data;
int i;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "intel8x0: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
- request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
- card->shortname, chip);
+ if (request_irq(pci->irq, snd_intel8x0_interrupt,
+ IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+ printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
+ "disabling device\n", pci->irq);
+ snd_card_disconnect(card);
+ return -EIO;
+ }
chip->irq = pci->irq;
synchronize_irq(chip->irq);
snd_intel8x0_chip_init(chip, 0);
for (i = 0; i < chip->pcm_devs; i++)
snd_pcm_suspend_all(chip->pcm[i]);
snd_ac97_suspend(chip->ac97);
- if (chip->irq >= 0)
+ if (chip->irq >= 0) {
+ synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
+ chip->irq = -1;
+ }
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct intel8x0m *chip = card->private_data;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "intel8x0m: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
- request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
- card->shortname, chip);
+ if (request_irq(pci->irq, snd_intel8x0_interrupt,
+ IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+ printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
+ "disabling device\n", pci->irq);
+ snd_card_disconnect(card);
+ return -EIO;
+ }
chip->irq = pci->irq;
snd_intel8x0_chip_init(chip, 0);
snd_ac97_resume(chip->ac97);
chip->suspend_mem[index++] =
snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i);
- /* power down apci registers */
- snd_m3_outw(chip, 0xffff, 0x54);
- snd_m3_outw(chip, 0xffff, 0x56);
-
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
if (chip->suspend_mem == NULL)
return 0;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "maestor3: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
/* first lets just bring everything back. .*/
chip->coeffs_current = 0;
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
/* Perform a full reset on the hardware */
chip->in_resume = 1;
+
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "nm256: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+ pci_set_master(pci);
+
snd_nm256_init_chip(chip);
/* restore ac97 */
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_ac97_suspend(chip->ac97);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct snd_riptide *chip = card->private_data;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "riptide: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_riptide_initialize(chip);
snd_ac97_resume(chip->ac97);
snd_ac97_suspend(trident->ac97);
snd_ac97_suspend(trident->ac97_sec);
- switch (trident->device) {
- case TRIDENT_DEVICE_ID_DX:
- case TRIDENT_DEVICE_ID_NX:
- break; /* TODO */
- case TRIDENT_DEVICE_ID_SI7018:
- break;
- }
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_card *card = pci_get_drvdata(pci);
struct snd_trident *trident = card->private_data;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
- pci_set_master(pci); /* to be sure */
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "trident: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+ pci_set_master(pci);
switch (trident->device) {
case TRIDENT_DEVICE_ID_DX:
chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
}
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct via82xx *chip = card->private_data;
int i;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "via82xx: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
+ pci_set_master(pci);
snd_via82xx_chip_init(chip);
snd_via82xx_channel_reset(chip, &chip->devs[i]);
synchronize_irq(chip->irq);
snd_ac97_suspend(chip->ac97);
- pci_set_power_state(pci, PCI_D3hot);
+
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct via82xx_modem *chip = card->private_data;
int i;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "via82xx-modem: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_via82xx_chip_init(chip);
int err;
err = snd_vx_suspend(&vx->core, state);
- pci_set_power_state(pci, PCI_D3hot);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return err;
}
struct snd_card *card = pci_get_drvdata(pci);
struct snd_vx222 *vx = card->private_data;
- pci_restore_state(pci);
- pci_enable_device(pci);
pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "vx222: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
return snd_vx_resume(&vx->core);
}
snd_ymfpci_disable_dsp(chip);
pci_disable_device(pci);
pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
struct snd_ymfpci *chip = card->private_data;
unsigned int i;
+ pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
- pci_enable_device(pci);
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "ymfpci: pci_enable_device failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
pci_set_master(pci);
snd_ymfpci_aclink_reset(pci);
snd_ymfpci_codec_ready(chip, 0);