Commit 76dd2761 authored by Linus Torvalds's avatar Linus Torvalds

Merge home.transmeta.com:/home/torvalds/v2.5/x86-64

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 1e215a63 1a19232d
......@@ -435,6 +435,14 @@ CONFIG_X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
CONFIG_NR_CPUS
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 32 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
CONFIG_PREEMPT
This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to
......@@ -487,10 +495,6 @@ CONFIG_CHECKING
Enables some internal consistency checks for kernel debugging.
You should normally say N.
CONFIG_SIMNOW
Disable some time consuming optional things for slow CPU simulators.
Say N unless you're running on a slow simulator like Simics or SimNow.
CONFIG_EARLY_PRINTK
Write kernel log output directly into the VGA buffer. This is useful
for kernel debugging when your machine crashes very early before
......@@ -499,13 +503,26 @@ CONFIG_EARLY_PRINTK
klogd/syslogd or the X server.You should normally N here, unless
you want to debug such a crash.
CONFIG_X86_MCE_NONFATAL
Enabling this feature starts a timer that triggers every 5 seconds which
will look at the machine check registers to see if anything happened.
Non-fatal problems automatically get corrected (but still logged).
Disable this if you don't want to see these messages.
Seeing the messages this option prints out may be indicative of dying hardware,
or out-of-spec (ie, overclocked) hardware.
This option only does something on hardware with Intel P6 style MCE.
(Pentium Pro and above, AMD Athlon/Duron)
CONFIG_KALLSYMS
Say Y here to let the kernel print out symbolic crash information and
symbolic stack backtraces. This increases the size of the kernel
somewhat, as all symbols have to be loaded into the kernel image.
CONFIG_INIT_DEBUG
Fill __init and __initdata at the end of boot. This is only for debugging.
CONFIG_IA32_EMULATION
Include code to run 32bit programs under an 64bit kernel. You should likely
turn this on, unless you're 100% sure that you don't have any 32bit programs
left.
CONFIG_GART_IOMMU
Support the K8 IOMMU. Needed to run systems with more than 4GB of memory
properly with 32bit devices. You should probably turn this on.
The iommu can be turned off at runtime with the iommu=off parameter.
CONFIG_DUMMY_IOMMU
Don't use IOMMU code. This will cause problems when you have more than 4GB
of memory and any 32bit devices. Don't turn on unless you know what you
are doing.
......@@ -33,7 +33,7 @@ IA32_CPP := $(CROSS_COMPILE)gcc -m32 -E
export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP
LD=$(CROSS_COMPILE)ld -m elf_x86_64
LDFLAGS := -m elf_x86_64
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux := -e stext
......@@ -47,52 +47,39 @@ CFLAGS += -finline-limit=2000
HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
SUBDIRS += arch/x86_64/kernel arch/x86_64/mm arch/x86_64/lib
CORE_FILES := arch/x86_64/kernel/kernel.o $(CORE_FILES)
CORE_FILES += arch/x86_64/mm/mm.o
LIBS := $(TOPDIR)/arch/x86_64/lib/lib.a $(LIBS)
ifdef CONFIG_IA32_EMULATION
SUBDIRS += arch/x86_64/ia32
CORE_FILES += arch/x86_64/ia32/ia32.o
endif
ifdef CONFIG_PCI
SUBDIRS += arch/x86_64/pci
DRIVERS += arch/x86_64/pci/pci.o
endif
CORE_FILES += $(core-y)
libs-y += arch/x86_64/lib/
core-y += arch/x86_64/kernel/ arch/x86_64/mm/
core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/
drivers-$(CONFIG_PCI) += arch/x86_64/pci/
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
makeboot = $(call descend,arch/x86_64/boot,$(1))
.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
clean archclean archmrproper
bzImage: vmlinux
@$(MAKEBOOT) bzImage
BOOTIMAGE=arch/x86_64/boot/bzImage
zImage zlilo zdisk: BOOTIMAGE=arch/x86_64/boot/zImage
bzImage-padded: vmlinux
@$(MAKEBOOT) bzImage-padded
zImage bzImage: vmlinux
+@$(call makeboot,$(BOOTIMAGE))
tmp:
@$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
compressed: zImage
bzlilo: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
zlilo bzlilo: vmlinux
+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
bzdisk: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zdisk
zdisk bzdisk: vmlinux
+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage install
+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
archclean:
@$(MAKEBOOT) clean
+@$(call makeboot,clean)
archmrproper:
prepare: include/asm-$(ARCH)/offset.h
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
......
......@@ -190,7 +190,7 @@ static void puts(const char *s)
outb_p(0xff & (pos >> 1), vidport+1);
}
void* memset(void* s, int c, size_t n)
void* memset(void* s, int c, unsigned n)
{
int i;
char *ss = (char*)s;
......@@ -199,14 +199,13 @@ void* memset(void* s, int c, size_t n)
return s;
}
void* memcpy(void* __dest, __const void* __src,
size_t __n)
void* memcpy(void* dest, const void* src, unsigned n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
char *d = (char *)dest, *s = (char *)src;
for (i=0;i<__n;i++) d[i] = s[i];
return __dest;
for (i=0;i<n;i++) d[i] = s[i];
return dest;
}
/* ===========================================================================
......
......@@ -21,6 +21,7 @@ define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
define_bool CONFIG_X86_CMPXCHG y
define_bool CONFIG_EARLY_PRINTK y
define_bool CONFIG_GENERIC_ISA_DMA y
source init/Config.in
......@@ -54,11 +55,17 @@ if [ "$CONFIG_SMP" = "n" ]; then
fi
if [ "$CONFIG_SMP" = "y" ]; then
define_bool CONFIG_HAVE_DEC_LOCK y
# actually 64 maximum, but you need to fix the APIC code first
# to use clustered mode or whatever your big iron needs
int 'Maximum number of CPUs (2-8)' CONFIG_NR_CPUS 8
fi
bool 'IOMMU support' CONFIG_GART_IOMMU
if [ "$CONFIG_GART_IOMMU" != "y" ]; then
define_bool CONFIG_DUMMY_IOMMU y
fi
define_bool CONFIG_X86_MCE y
bool 'Check for non-fatal machine check errors' CONFIG_X86_MCE_NONFATAL $CONFIG_X86_MCE
endmenu
......@@ -108,22 +115,20 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
bool 'IA32 Emulation' CONFIG_IA32_EMULATION
endmenu
source drivers/mtd/Config.in
source drivers/parport/Config.in
#source drivers/pnp/Config.in
source drivers/block/Config.in
source drivers/md/Config.in
mainmenu_option next_comment
comment 'ATA/ATAPI/MFM/RLL support'
tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE
tristate 'ATA/ATAPI/MFM/RLL device support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
......@@ -133,15 +138,19 @@ fi
endmenu
mainmenu_option next_comment
comment 'SCSI support'
comment 'SCSI device support'
tristate 'SCSI support' CONFIG_SCSI
tristate 'SCSI device support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in
fi
endmenu
source drivers/md/Config.in
source drivers/telephony/Config.in
source drivers/message/fusion/Config.in
source drivers/ieee1394/Config.in
......@@ -172,8 +181,6 @@ source net/irda/Config.in
source drivers/isdn/Config.in
source drivers/telephony/Config.in
# no support for non IDE/SCSI cdroms as they were all ISA only
#
......@@ -224,6 +231,8 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Additional run-time checks' CONFIG_CHECKING
bool ' Debug __init statements' CONFIG_INIT_DEBUG
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Load all symbols for debugging/kksymoops' CONFIG_KALLSYMS
fi
endmenu
......
#
# Automatically generated by make menuconfig: don't edit
# Automatically generated make config: don't edit
#
CONFIG_X86_64=y
CONFIG_X86=y
......@@ -10,6 +10,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_ISA_DMA=y
#
# Code maturity level options
......@@ -47,11 +48,12 @@ CONFIG_X86_CPUID=y
# CONFIG_EISA is not set
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_MTRR=y
CONFIG_SMP=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_NONFATAL is not set
CONFIG_NR_CPUS=8
CONFIG_GART_IOMMU=y
CONFIG_X86_MCE=y
#
# Power management options
......@@ -61,7 +63,25 @@ CONFIG_NR_CPUS=8
#
# ACPI Support
#
# CONFIG_ACPI is not set
CONFIG_ACPI=y
# CONFIG_ACPI_HT_ONLY is not set
CONFIG_ACPI_BOOT=y
# CONFIG_ACPI_SLEEP is not set
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_TOSHIBA=y
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_BOOT=y
CONFIG_ACPI_BUS=y
CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
#
# Bus options (PCI etc.)
......@@ -106,81 +126,21 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
CONFIG_LBD=y
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_BLK_DEV_LVM is not set
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_NETLINK_DEV=y
# CONFIG_NETFILTER is not set
CONFIG_FILTER=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
#
# Appletalk devices
#
# CONFIG_DEV_APPLETALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_LLC is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# QoS and/or fair queueing
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_NET_SCHED is not set
#
# Telephony Support
#
# CONFIG_PHONE is not set
# CONFIG_PHONE_IXJ is not set
# CONFIG_PHONE_IXJ_PCMCIA is not set
CONFIG_IDE=y
#
# ATA/IDE/MFM/RLL support
# IDE, ATA and ATAPI Block devices
#
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
#
# ATA and ATAPI Block devices
# Please see Documentation/ide.txt for help/info on IDE drives
#
CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
......@@ -188,27 +148,35 @@ CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_IDEDISK_STROKE is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
#
# IDE chipset support/bugfixes
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_IDEDMA_PCI_AUTO is not set
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_AEC6280_BURST is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
CONFIG_BLK_DEV_AMD74XX=y
# CONFIG_AMD74XX_OVERRIDE is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
......@@ -216,94 +184,111 @@ CONFIG_BLK_DEV_AMD74XX=y
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_NFORCE is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_PDC202XX_BURST is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_SL82C105 is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_IDEDMA_AUTO=y
# CONFIG_IDEDMA_IVB is not set
CONFIG_ATAPI=y
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_ATARAID is not set
# CONFIG_BLK_DEV_ATARAID_PDC is not set
# CONFIG_BLK_DEV_ATARAID_HPT is not set
#
# SCSI support
#
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_REPORT_LUNS is not set
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
#
# SCSI low-level drivers
#
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_DMA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_NCR53C8XX is not set
# CONFIG_SCSI_SYM53C8XX is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_DMA_NONPCI is not set
CONFIG_BLK_DEV_IDE_MODES=y
#
# SCSI device support
#
# CONFIG_SCSI is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_BLK_DEV_LVM is not set
#
# Telephony Support
#
# CONFIG_PHONE is not set
# CONFIG_PHONE_IXJ is not set
# CONFIG_PHONE_IXJ_PCMCIA is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
# CONFIG_FUSION_BOOT is not set
# CONFIG_FUSION_ISENSE is not set
# CONFIG_FUSION_CTL is not set
# CONFIG_FUSION_LAN is not set
#
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
#
# CONFIG_IEEE1394 is not set
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_NETLINK_DEV=y
# CONFIG_NETFILTER is not set
CONFIG_FILTER=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_IPV6 is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DEV_APPLETALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE 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
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# Network device support
#
......@@ -339,6 +324,11 @@ CONFIG_VORTEX=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_PCI is not set
......@@ -350,6 +340,7 @@ CONFIG_VORTEX=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000_NAPI is not set
# CONFIG_MYRI_SBUS is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
......@@ -380,11 +371,6 @@ CONFIG_TIGON3=y
#
# CONFIG_WAN is not set
#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
#
# Amateur Radio support
#
......@@ -403,31 +389,106 @@ CONFIG_TIGON3=y
#
# Input device support
#
# CONFIG_INPUT is not set
# CONFIG_INPUT_KEYBDEV is not set
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT=y
#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input I/O drivers
#
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_INPUT_EMU10K1 is not set
# CONFIG_GAMEPORT_PCIGAME is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
# CONFIG_GAMEPORT_VORTEX is not set
# CONFIG_GAMEPORT_FM801 is not set
# CONFIG_GAMEPORT_CS461x is not set
# CONFIG_SERIO is not set
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
CONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not set
# CONFIG_JOYSTICK_A3D is not set
# CONFIG_JOYSTICK_ADI is not set
# CONFIG_JOYSTICK_COBRA is not set
# CONFIG_JOYSTICK_GF2K is not set
# CONFIG_JOYSTICK_GRIP is not set
# CONFIG_JOYSTICK_GRIP_MP is not set
# CONFIG_JOYSTICK_GUILLEMOT is not set
# CONFIG_JOYSTICK_INTERACT is not set
# CONFIG_JOYSTICK_SIDEWINDER is not set
# CONFIG_JOYSTICK_TMDC is not set
# CONFIG_JOYSTICK_IFORCE is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
# CONFIG_JOYSTICK_SPACEORB is not set
# CONFIG_JOYSTICK_SPACEBALL is not set
# CONFIG_JOYSTICK_STINGER is not set
# CONFIG_JOYSTICK_TWIDDLER is not set
# CONFIG_JOYSTICK_DB9 is not set
# CONFIG_JOYSTICK_GAMECON is not set
# CONFIG_JOYSTICK_TURBOGRAFX is not set
# CONFIG_INPUT_JOYDUMP is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_INPUT_MISC is not set
# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_UINPUT is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_EXTENDED is not set
CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_CS is not set
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SERIAL_8250_MANY_PORTS is not set
# CONFIG_SERIAL_8250_SHARE_IRQ is not set
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
......@@ -440,10 +501,6 @@ CONFIG_UNIX98_PTY_COUNT=256
# Mice
#
# CONFIG_BUSMOUSE is not set
CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
# CONFIG_QIC02_TAPE is not set
#
......@@ -451,6 +508,7 @@ CONFIG_PSMOUSE=y
#
# CONFIG_WATCHDOG is not set
# CONFIG_INTEL_RNG is not set
# CONFIG_AMD_RNG is not set
# CONFIG_NVRAM is not set
CONFIG_RTC=y
# CONFIG_DTLK is not set
......@@ -462,9 +520,18 @@ CONFIG_RTC=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
CONFIG_AGP=y
# CONFIG_AGP_INTEL is not set
# CONFIG_AGP_I810 is not set
# CONFIG_AGP_VIA is not set
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_ALI is not set
# CONFIG_AGP_SWORKS is not set
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
# CONFIG_SCx200_GPIO is not set
CONFIG_RAW_DRIVER=y
#
# Misc devices
......@@ -504,7 +571,7 @@ CONFIG_JBD=y
# CONFIG_CRAMFS is not set
CONFIG_TMPFS=y
CONFIG_RAMFS=y
# CONFIG_ISO9660_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_ZISOFS is not set
# CONFIG_JFS_FS is not set
......@@ -530,6 +597,9 @@ CONFIG_EXT2_FS=y
# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_XFS_FS is not set
# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
#
# Network File Systems
......@@ -537,14 +607,18 @@ CONFIG_EXT2_FS=y
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
CONFIG_NFS_V3=y
# CONFIG_NFS_V4 is not set
# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=y
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V4 is not set
CONFIG_NFSD_TCP=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
# CONFIG_CIFS is not set
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
......@@ -555,6 +629,7 @@ CONFIG_EXPORTFS=y
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
# CONFIG_AFS_FS is not set
# CONFIG_ZISOFS_FS is not set
#
......@@ -599,8 +674,15 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_CHECKING is not set
CONFIG_CHECKING=y
# CONFIG_INIT_DEBUG is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_KALLSYMS is not set
#
# Security options
#
CONFIG_SECURITY_CAPABILITIES=y
#
# Library routines
......
......@@ -25,7 +25,7 @@ struct elf_phdr;
#define IA32_EMULATOR 1
#define IA32_PAGE_OFFSET 0xE0000000
#define IA32_PAGE_OFFSET 0xffff0000
#define IA32_STACK_TOP IA32_PAGE_OFFSET
#define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000)
......@@ -216,13 +216,15 @@ static void elf32_init(struct pt_regs *regs)
extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address);
int ia32_setup_arg_pages(struct linux_binprm *bprm)
int setup_arg_pages(struct linux_binprm *bprm)
{
unsigned long stack_base;
struct vm_area_struct *mpnt;
struct mm_struct *mm = current->mm;
int i;
stack_base = IA32_STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
stack_base = IA32_STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
mm->arg_start = bprm->p + stack_base;
bprm->p += stack_base;
if (bprm->loader)
......@@ -233,9 +235,14 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm)
if (!mpnt)
return -ENOMEM;
down_write(&current->mm->mmap_sem);
if (!vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) {
kmem_cache_free(vm_area_cachep, mpnt);
return -ENOMEM;
}
down_write(&mm->mmap_sem);
{
mpnt->vm_mm = current->mm;
mpnt->vm_mm = mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
mpnt->vm_end = IA32_STACK_TOP;
mpnt->vm_page_prot = PAGE_COPY;
......@@ -243,24 +250,25 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm)
mpnt->vm_ops = NULL;
mpnt->vm_pgoff = 0;
mpnt->vm_file = NULL;
INIT_LIST_HEAD(&mpnt->shared);
mpnt->vm_private_data = (void *) 0;
insert_vm_struct(current->mm, mpnt);
current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
insert_vm_struct(mm, mpnt);
mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
}
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
struct page *page = bprm->page[i];
if (page) {
bprm->page[i] = NULL;
current->mm->rss++;
put_dirty_page(current,page,stack_base);
}
stack_base += PAGE_SIZE;
}
up_write(&current->mm->mmap_sem);
up_write(&mm->mmap_sem);
return 0;
}
static unsigned long
elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
{
......
/* $Id: ia32_ioctl.c,v 1.11 2002/04/18 14:36:37 ak Exp $
/* $Id: ia32_ioctl.c,v 1.25 2002/10/11 07:17:06 ak Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
......@@ -21,6 +21,7 @@
#include <linux/hdreg.h>
#include <linux/raid/md.h>
#include <linux/kd.h>
#include <linux/dirent.h>
#include <linux/route.h>
#include <linux/in6.h>
#include <linux/ipv6_route.h>
......@@ -55,7 +56,9 @@
#include <linux/module.h>
#include <linux/serial.h>
#include <linux/reiserfs_fs.h>
#include <linux/if_tun.h>
#include <linux/dirent.h>
#include <linux/ctype.h>
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
/* Ugh. This header really is not clean */
#define min min
......@@ -74,8 +77,14 @@
#include <asm/ia32.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_bonding.h>
#include <linux/watchdog.h>
#include <asm/module.h>
#include <asm/ioctl32.h>
#include <linux/soundcard.h>
#include <linux/lp.h>
#include <linux/atm.h>
#include <linux/atmarp.h>
......@@ -88,6 +97,19 @@
#include <linux/atm_tcp.h>
#include <linux/sonet.h>
#include <linux/atm_suni.h>
#include <linux/mtd/mtd.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/nbd.h>
#include <linux/random.h>
#include <linux/filter.h>
#include <asm/mtrr.h>
#define A(__x) ((void *)(unsigned long)(__x))
#define AA(__x) A(__x)
......@@ -114,7 +136,6 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
}
#if 0
static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs = get_fs();
......@@ -130,7 +151,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EFAULT;
return err;
}
#endif
static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
......@@ -443,6 +463,7 @@ struct ifconf32 {
__kernel_caddr_t32 ifcbuf;
};
#ifdef CONFIG_NET
static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct net_device *dev;
......@@ -458,10 +479,12 @@ static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
strncpy(ifr32.ifr_name, dev->name, sizeof(ifr32.ifr_name)-1);
ifr32.ifr_name[sizeof(ifr32.ifr_name)-1] = 0;
dev_put(dev);
err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
return (err ? -EFAULT : 0);
}
#endif
static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
{
......@@ -558,9 +581,25 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
}
switch (ethcmd) {
case ETHTOOL_GDRVINFO: len = sizeof(struct ethtool_drvinfo); break;
case ETHTOOL_GMSGLVL:
case ETHTOOL_SMSGLVL:
case ETHTOOL_GLINK:
case ETHTOOL_NWAY_RST: len = sizeof(struct ethtool_value); break;
case ETHTOOL_GREGS: {
struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
/* darned variable size arguments */
if (get_user(len, (u32 *)&regaddr->len)) {
err = -EFAULT;
goto out;
}
len += sizeof(struct ethtool_regs);
break;
}
case ETHTOOL_GSET:
case ETHTOOL_SSET:
default: len = sizeof(struct ethtool_cmd); break;
case ETHTOOL_SSET: len = sizeof(struct ethtool_cmd); break;
default:
err = -EOPNOTSUPP;
goto out;
}
if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
......@@ -586,6 +625,91 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
}
static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
{
struct ifreq ifr;
mm_segment_t old_fs;
int err, len;
u32 data;
if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
return -EFAULT;
ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
if (!ifr.ifr_data)
return -EAGAIN;
switch (cmd) {
case SIOCBONDENSLAVE:
case SIOCBONDRELEASE:
case SIOCBONDSETHWADDR:
case SIOCBONDCHANGEACTIVE:
len = IFNAMSIZ * sizeof(char);
break;
case SIOCBONDSLAVEINFOQUERY:
len = sizeof(struct ifslave);
break;
case SIOCBONDINFOQUERY:
len = sizeof(struct ifbond);
break;
default:
err = -EINVAL;
goto out;
};
__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
if (copy_from_user(ifr.ifr_data, (char *)A(data), len)) {
err = -EFAULT;
goto out;
}
old_fs = get_fs();
set_fs (KERNEL_DS);
err = sys_ioctl (fd, cmd, (unsigned long)&ifr);
set_fs (old_fs);
if (!err) {
len = copy_to_user((char *)A(data), ifr.ifr_data, len);
if (len)
err = -EFAULT;
}
out:
free_page((unsigned long)ifr.ifr_data);
return err;
}
static __inline__ void *alloc_user_space(long len)
{
struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs);
return (void *)regs->rsp - len;
}
static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ifreq *u_ifreq64;
struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg;
char tmp_buf[IFNAMSIZ];
void *data64;
u32 data32;
if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
IFNAMSIZ))
return -EFAULT;
if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
return -EFAULT;
data64 = (void *) A(data32);
u_ifreq64 = alloc_user_space(sizeof(*u_ifreq64));
/* Don't check these user accesses, just let that get trapped
* in the ioctl handler instead.
*/
copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
}
static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ifreq ifr;
......@@ -604,15 +728,6 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
if (err)
return -EFAULT;
break;
case SIOCGPPPSTATS:
case SIOCGPPPCSTATS:
case SIOCGPPPVER:
if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
return -EFAULT;
ifr.ifr_data = (__kernel_caddr_t)get_zeroed_page(GFP_KERNEL);
if (!ifr.ifr_data)
return -EAGAIN;
break;
default:
if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
return -EFAULT;
......@@ -638,27 +753,6 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
return -EFAULT;
break;
case SIOCGPPPSTATS:
case SIOCGPPPCSTATS:
case SIOCGPPPVER:
{
u32 data;
int len;
__get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
if(cmd == SIOCGPPPVER)
len = strlen((char *)ifr.ifr_data) + 1;
else if(cmd == SIOCGPPPCSTATS)
len = sizeof(struct ppp_comp_stats);
else
len = sizeof(struct ppp_stats);
len = copy_to_user((char *)A(data), ifr.ifr_data, len);
free_page((unsigned long)ifr.ifr_data);
if(len)
return -EFAULT;
break;
}
case SIOCGIFMAP:
err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
......@@ -671,14 +765,6 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
err = -EFAULT;
break;
}
} else {
switch (cmd) {
case SIOCGPPPSTATS:
case SIOCGPPPCSTATS:
case SIOCGPPPVER:
free_page((unsigned long)ifr.ifr_data);
break;
}
}
return err;
}
......@@ -792,14 +878,6 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
return err ? -EFAULT : 0;
}
struct fbcmap32 {
int index; /* first element (0 origin) */
int count;
u32 red;
u32 green;
u32 blue;
};
struct fb_fix_screeninfo32 {
char id[16];
__kernel_caddr_t32 smem_start;
......@@ -883,7 +961,7 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
break;
default:
do {
static int count = 0;
static int count;
if (++count <= 20)
printk("%s: Unknown fb ioctl cmd fd(%d) "
"cmd(%08x) arg(%08lx)\n",
......@@ -1262,6 +1340,269 @@ out: if (karg) kfree(karg);
return err;
}
typedef struct sg_io_hdr32 {
s32 interface_id; /* [i] 'S' for SCSI generic (required) */
s32 dxfer_direction; /* [i] data transfer direction */
u8 cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
u8 mx_sb_len; /* [i] max length to write to sbp */
u16 iovec_count; /* [i] 0 implies no scatter gather */
u32 dxfer_len; /* [i] byte count of data transfer */
u32 dxferp; /* [i], [*io] points to data transfer memory
or scatter gather list */
u32 cmdp; /* [i], [*i] points to command to perform */
u32 sbp; /* [i], [*o] points to sense_buffer memory */
u32 timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
u32 flags; /* [i] 0 -> default, see SG_FLAG... */
s32 pack_id; /* [i->o] unused internally (normally) */
u32 usr_ptr; /* [i->o] unused internally */
u8 status; /* [o] scsi status */
u8 masked_status; /* [o] shifted, masked scsi status */
u8 msg_status; /* [o] messaging level data (optional) */
u8 sb_len_wr; /* [o] byte count actually written to sbp */
u16 host_status; /* [o] errors from host adapter */
u16 driver_status; /* [o] errors from software driver */
s32 resid; /* [o] dxfer_len - actual_transferred */
u32 duration; /* [o] time taken by cmd (unit: millisec) */
u32 info; /* [o] auxiliary information */
} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
typedef struct sg_iovec32 {
u32 iov_base;
u32 iov_len;
} sg_iovec32_t;
static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
{
sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
sg_iovec_t *kiov;
int i;
sgp->dxferp = kmalloc(sgp->iovec_count *
sizeof(sg_iovec_t), GFP_KERNEL);
if (!sgp->dxferp)
return -ENOMEM;
memset(sgp->dxferp, 0,
sgp->iovec_count * sizeof(sg_iovec_t));
kiov = (sg_iovec_t *) sgp->dxferp;
for (i = 0; i < sgp->iovec_count; i++) {
u32 iov_base32;
if (__get_user(iov_base32, &uiov->iov_base) ||
__get_user(kiov->iov_len, &uiov->iov_len))
return -EFAULT;
kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
if (!kiov->iov_base)
return -ENOMEM;
if (copy_from_user(kiov->iov_base,
(void *) A(iov_base32),
kiov->iov_len))
return -EFAULT;
uiov++;
kiov++;
}
return 0;
}
static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
{
sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
int i;
for (i = 0; i < sgp->iovec_count; i++) {
u32 iov_base32;
if (__get_user(iov_base32, &uiov->iov_base))
return -EFAULT;
if (copy_to_user((void *) A(iov_base32),
kiov->iov_base,
kiov->iov_len))
return -EFAULT;
uiov++;
kiov++;
}
return 0;
}
static void free_sg_iovec(sg_io_hdr_t *sgp)
{
sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
int i;
for (i = 0; i < sgp->iovec_count; i++) {
if (kiov->iov_base) {
kfree(kiov->iov_base);
kiov->iov_base = NULL;
}
kiov++;
}
kfree(sgp->dxferp);
sgp->dxferp = NULL;
}
static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
sg_io_hdr32_t *sg_io32;
sg_io_hdr_t sg_io64;
u32 dxferp32, cmdp32, sbp32;
mm_segment_t old_fs;
int err = 0;
sg_io32 = (sg_io_hdr32_t *)arg;
err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
err |= __get_user(sg_io64.flags, &sg_io32->flags);
err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
sg_io64.dxferp = NULL;
sg_io64.cmdp = NULL;
sg_io64.sbp = NULL;
err |= __get_user(cmdp32, &sg_io32->cmdp);
sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
if (!sg_io64.cmdp) {
err = -ENOMEM;
goto out;
}
if (copy_from_user(sg_io64.cmdp,
(void *) A(cmdp32),
sg_io64.cmd_len)) {
err = -EFAULT;
goto out;
}
err |= __get_user(sbp32, &sg_io32->sbp);
sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);
if (!sg_io64.sbp) {
err = -ENOMEM;
goto out;
}
if (copy_from_user(sg_io64.sbp,
(void *) A(sbp32),
sg_io64.mx_sb_len)) {
err = -EFAULT;
goto out;
}
err |= __get_user(dxferp32, &sg_io32->dxferp);
if (sg_io64.iovec_count) {
int ret;
if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
err = ret;
goto out;
}
} else {
sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
if (!sg_io64.dxferp) {
err = -ENOMEM;
goto out;
}
if (copy_from_user(sg_io64.dxferp,
(void *) A(dxferp32),
sg_io64.dxfer_len)) {
err = -EFAULT;
goto out;
}
}
/* Unused internally, do not even bother to copy it over. */
sg_io64.usr_ptr = NULL;
if (err)
return -EFAULT;
old_fs = get_fs();
set_fs (KERNEL_DS);
err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
set_fs (old_fs);
if (err < 0)
goto out;
err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
err |= __put_user(sg_io64.status, &sg_io32->status);
err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
err |= __put_user(sg_io64.resid, &sg_io32->resid);
err |= __put_user(sg_io64.duration, &sg_io32->duration);
err |= __put_user(sg_io64.info, &sg_io32->info);
err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
if (sg_io64.dxferp) {
if (sg_io64.iovec_count)
err |= copy_back_sg_iovec(&sg_io64, dxferp32);
else
err |= copy_to_user((void *)A(dxferp32),
sg_io64.dxferp,
sg_io64.dxfer_len);
}
if (err)
err = -EFAULT;
out:
if (sg_io64.cmdp)
kfree(sg_io64.cmdp);
if (sg_io64.sbp)
kfree(sg_io64.sbp);
if (sg_io64.dxferp) {
if (sg_io64.iovec_count) {
free_sg_iovec(&sg_io64);
} else {
kfree(sg_io64.dxferp);
}
}
return err;
}
struct sock_fprog32 {
__u16 len;
__u32 filter;
};
#define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct sock_fprog32 *u_fprog32 = (struct sock_fprog32 *) arg;
struct sock_fprog *u_fprog64 = alloc_user_space(sizeof(struct sock_fprog));
void *fptr64;
u32 fptr32;
u16 flen;
if (get_user(flen, &u_fprog32->len) ||
get_user(fptr32, &u_fprog32->filter))
return -EFAULT;
fptr64 = (void *) A(fptr32);
if (put_user(flen, &u_fprog64->len) ||
put_user(fptr64, &u_fprog64->filter))
return -EFAULT;
if (cmd == PPPIOCSPASS32)
cmd = PPPIOCSPASS;
else
cmd = PPPIOCSACTIVE;
return sys_ioctl(fd, cmd, (unsigned long) u_fprog64);
}
struct ppp_option_data32 {
__kernel_caddr_t32 ptr;
__u32 length;
......@@ -1308,7 +1649,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
break;
default:
do {
static int count = 0;
static int count;
if (++count <= 20)
printk("ppp_ioctl: Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
......@@ -1418,7 +1759,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
break;
default:
do {
static int count = 0;
static int count;
if (++count <= 20)
printk("mt_ioctl: Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
......@@ -1536,7 +1877,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
break;
default:
do {
static int count = 0;
static int count;
if (++count <= 20)
printk("cdrom_ioctl: Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
......@@ -1623,7 +1964,7 @@ static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
}
break;
default: {
static int count = 0;
static int count;
if (++count <= 20)
printk("%s: Unknown loop ioctl cmd, fd(%d) "
"cmd(%08x) arg(%08lx)\n",
......@@ -1652,9 +1993,9 @@ static int vt_check(struct file *file)
/*
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
* to be the owner of the tty, or super-user.
*/
if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
if (current->tty == tty || capable(CAP_SYS_ADMIN))
return 1;
return 0;
}
......@@ -2024,6 +2365,7 @@ typedef struct {
u32 pv[ABS_MAX_PV + 1];
u32 lv[ABS_MAX_LV + 1];
uint8_t vg_uuid[UUID_LEN+1]; /* volume group UUID */
uint8_t dummy1[200];
} vg32_t;
typedef struct {
......@@ -2138,7 +2480,8 @@ static lv_t *get_lv_t(u32 p, int *errp)
lv_block_exception32_t *lbe32;
lv_block_exception_t *lbe;
lv32_t *ul = (lv32_t *)A(p);
lv_t *l = (lv_t *)kmalloc(sizeof(lv_t), GFP_KERNEL);
lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
if (!l) {
*errp = -ENOMEM;
return NULL;
......@@ -2173,7 +2516,6 @@ static lv_t *get_lv_t(u32 p, int *errp)
err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
}
}
}
......@@ -2211,7 +2553,7 @@ static int copy_lv_t(u32 ptr, lv_t *l)
static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
vg_t *v;
vg_t *v = NULL;
union {
lv_req_t lv_req;
le_remap_req_t le_remap;
......@@ -2229,17 +2571,22 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
switch (cmd) {
case VG_STATUS:
v = kmalloc(sizeof(vg_t), GFP_KERNEL);
if (!v) return -ENOMEM;
if (!v)
return -ENOMEM;
karg = v;
break;
case VG_CREATE_OLD:
case VG_CREATE:
v = kmalloc(sizeof(vg_t), GFP_KERNEL);
if (!v) return -ENOMEM;
if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc) ||
__get_user(v->proc, &((vg32_t *)arg)->proc)) {
if (!v)
return -ENOMEM;
if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
kfree(v);
return -EFAULT;
}
/* 'proc' field is unused, just NULL it out. */
v->proc = NULL;
if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
kfree(v);
return -EFAULT;
......@@ -2251,94 +2598,117 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EPERM;
for (i = 0; i < v->pv_max; i++) {
err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
if (err) break;
if (err)
break;
if (ptr) {
v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
if (!v->pv[i]) {
err = -ENOMEM;
break;
}
err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
err = copy_from_user(v->pv[i], (void *)A(ptr),
sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) {
err = -EFAULT;
break;
}
err = copy_from_user(v->pv[i]->pv_uuid, ((pv32_t *)A(ptr))->pv_uuid, UUID_LEN+1);
err = copy_from_user(v->pv[i]->pv_uuid,
((pv32_t *)A(ptr))->pv_uuid,
UUID_LEN+1);
if (err) {
err = -EFAULT;
break;
}
v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
v->pv[i]->pe = NULL;
v->pv[i]->bd = NULL;
}
}
if (!err) {
for (i = 0; i < v->lv_max; i++) {
err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
if (err) break;
if (err)
break;
if (ptr) {
v->lv[i] = get_lv_t(ptr, &err);
if (err) break;
if (err)
break;
}
}
}
break;
case LV_CREATE:
case LV_EXTEND:
case LV_REDUCE:
case LV_REMOVE:
case LV_RENAME:
case LV_STATUS_BYNAME:
err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
if (err) return -EFAULT;
err = copy_from_user(&u.pv_status, (void*)arg, sizeof(u.pv_status.pv_name));
if (err)
return -EFAULT;
if (cmd != LV_REMOVE) {
err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
if (err) return err;
if (err)
return err;
u.lv_req.lv = get_lv_t(ptr, &err);
} else
u.lv_req.lv = NULL;
break;
case LV_STATUS_BYINDEX:
err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index);
err = get_user(u.lv_byindex.lv_index,
&((lv_status_byindex_req32_t *)arg)->lv_index);
err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
if (err) return err;
if (err)
return err;
u.lv_byindex.lv = get_lv_t(ptr, &err);
break;
case LV_STATUS_BYDEV:
err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
if (err)
return err;
u.lv_bydev.lv = get_lv_t(ptr, &err);
if (err) return err;
u.lv_bydev.lv = &p;
p.pe = NULL; p.inode = NULL;
break;
case VG_EXTEND:
err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) return -EFAULT;
if (err)
return -EFAULT;
err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
if (err) return -EFAULT;
p.pe = NULL; p.inode = NULL;
if (err)
return -EFAULT;
p.pe = NULL;
p.bd = NULL;
karg = &p;
break;
case PV_CHANGE:
case PV_STATUS:
err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
if (err) return -EFAULT;
err = copy_from_user(&u.pv_status, (void*)arg, sizeof(u.lv_req.lv_name));
if (err)
return -EFAULT;
err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
if (err) return err;
if (err)
return err;
u.pv_status.pv = &p;
if (cmd == PV_CHANGE) {
err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) return -EFAULT;
p.pe = NULL; p.inode = NULL;
err = copy_from_user(&p, (void *)A(ptr),
sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err)
return -EFAULT;
p.pe = NULL;
p.bd = NULL;
}
break;
}
};
old_fs = get_fs(); set_fs (KERNEL_DS);
err = sys_ioctl (fd, cmd, (unsigned long)karg);
set_fs (old_fs);
switch (cmd) {
case VG_STATUS:
if (!err) {
......@@ -2351,42 +2721,60 @@ static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
}
kfree(v);
break;
case VG_CREATE_OLD:
case VG_CREATE:
for (i = 0; i < v->pv_max; i++)
if (v->pv[i]) kfree(v->pv[i]);
for (i = 0; i < v->lv_max; i++)
if (v->lv[i]) put_lv_t(v->lv[i]);
for (i = 0; i < v->pv_max; i++) {
if (v->pv[i])
kfree(v->pv[i]);
}
for (i = 0; i < v->lv_max; i++) {
if (v->lv[i])
put_lv_t(v->lv[i]);
}
kfree(v);
break;
case LV_STATUS_BYNAME:
if (!err && u.lv_req.lv) err = copy_lv_t(ptr, u.lv_req.lv);
if (!err && u.lv_req.lv)
err = copy_lv_t(ptr, u.lv_req.lv);
/* Fall through */
case LV_CREATE:
case LV_EXTEND:
case LV_REDUCE:
if (u.lv_req.lv) put_lv_t(u.lv_req.lv);
if (u.lv_req.lv)
put_lv_t(u.lv_req.lv);
break;
case LV_STATUS_BYINDEX:
if (u.lv_byindex.lv) {
if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv);
if (!err)
err = copy_lv_t(ptr, u.lv_byindex.lv);
put_lv_t(u.lv_byindex.lv);
}
break;
case PV_STATUS:
if (!err) {
err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) return -EFAULT;
err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
if (err) return -EFAULT;
}
break;
case LV_STATUS_BYDEV:
if (!err) {
if (!err) err = copy_lv_t(ptr, u.lv_bydev.lv);
if (u.lv_bydev.lv) {
if (!err)
err = copy_lv_t(ptr, u.lv_bydev.lv);
put_lv_t(u.lv_byindex.lv);
}
break;
case PV_STATUS:
if (!err) {
err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err)
return -EFAULT;
err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
if (err)
return -EFAULT;
}
break;
};
return err;
}
#endif
......@@ -2976,7 +3364,11 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioc
return err;
}
/* SuSE extension */
static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
}
#ifndef TIOCGDEV
#define TIOCGDEV _IOR('T',0x32, unsigned int)
#endif
......@@ -3088,6 +3480,15 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, void *ptr)
}
#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)
static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
{
if (cmd == REISERFS_IOC_UNPACK32)
cmd = REISERFS_IOC_UNPACK;
return sys_ioctl(fd,cmd,ptr);
}
struct dirent32 {
unsigned int d_ino;
__kernel_off_t32 d_off;
......@@ -3125,32 +3526,6 @@ static int vfat_ioctl32(unsigned fd, unsigned cmd, void *ptr)
return ret;
}
#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int)
static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
{
if (cmd == REISERFS_IOC_UNPACK32)
cmd = REISERFS_IOC_UNPACK;
return sys_ioctl(fd,cmd,ptr);
}
#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
static int autofs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr)
{
int ret;
unsigned long val;
mm_segment_t oldfs = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, AUTOFS_IOC_SETTIMEOUT32, (unsigned long)&val);
set_fs(oldfs);
if (!ret)
ret = put_user(val, (int *) ptr);
return ret;
}
#define RTC_IRQP_READ32 _IOR('p', 0x0b, unsigned int) /* Read IRQ rate */
#define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int) /* Set IRQ rate */
#define RTC_EPOCH_READ32 _IOR('p', 0x0d, unsigned) /* Read epoch */
......@@ -3190,6 +3565,572 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
return sys_ioctl(fd,cmd,arg);
}
/* Fix sizeof(sizeof()) breakage */
#define BLKELVGET_32 _IOR(0x12,106,int)
#define BLKELVSET_32 _IOW(0x12,107,int)
#define BLKBSZGET_32 _IOR(0x12,112,int)
#define BLKBSZSET_32 _IOW(0x12,113,int)
#define BLKGETSIZE64_32 _IOR(0x12,114,int)
static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return sys_ioctl(fd, BLKELVGET, arg);
}
static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return sys_ioctl(fd, BLKELVSET, arg);
}
static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return sys_ioctl(fd, BLKBSZGET, arg);
}
static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return sys_ioctl(fd, BLKBSZSET, arg);
}
static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
unsigned long arg)
{
return sys_ioctl(fd, BLKGETSIZE64, arg);
}
struct usbdevfs_ctrltransfer32 {
__u8 bRequestType;
__u8 bRequest;
__u16 wValue;
__u16 wIndex;
__u16 wLength;
__u32 timeout; /* in milliseconds */
__u32 data;
};
#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct usbdevfs_ctrltransfer kctrl;
struct usbdevfs_ctrltransfer32 *uctrl;
mm_segment_t old_fs;
__u32 udata;
void *uptr, *kptr;
int err;
uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
if (copy_from_user(&kctrl, uctrl,
(sizeof(struct usbdevfs_ctrltransfer) -
sizeof(void *))))
return -EFAULT;
if (get_user(udata, &uctrl->data))
return -EFAULT;
uptr = (void *) A(udata);
/* In usbdevice_fs, it limits the control buffer to a page,
* for simplicity so do we.
*/
if (!uptr || kctrl.wLength > PAGE_SIZE)
return -EINVAL;
kptr = (void *)__get_free_page(GFP_KERNEL);
if ((kctrl.bRequestType & 0x80) == 0) {
err = -EFAULT;
if (copy_from_user(kptr, uptr, kctrl.wLength))
goto out;
}
kctrl.data = kptr;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
set_fs(old_fs);
if (err >= 0 &&
((kctrl.bRequestType & 0x80) != 0)) {
if (copy_to_user(uptr, kptr, kctrl.wLength))
err = -EFAULT;
}
out:
free_page((unsigned long) kptr);
return err;
}
struct usbdevfs_bulktransfer32 {
unsigned int ep;
unsigned int len;
unsigned int timeout; /* in milliseconds */
__u32 data;
};
#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct usbdevfs_bulktransfer kbulk;
struct usbdevfs_bulktransfer32 *ubulk;
mm_segment_t old_fs;
__u32 udata;
void *uptr, *kptr;
int err;
ubulk = (struct usbdevfs_bulktransfer32 *) arg;
if (get_user(kbulk.ep, &ubulk->ep) ||
get_user(kbulk.len, &ubulk->len) ||
get_user(kbulk.timeout, &ubulk->timeout) ||
get_user(udata, &ubulk->data))
return -EFAULT;
uptr = (void *) A(udata);
/* In usbdevice_fs, it limits the control buffer to a page,
* for simplicity so do we.
*/
if (!uptr || kbulk.len > PAGE_SIZE)
return -EINVAL;
kptr = (void *) __get_free_page(GFP_KERNEL);
if ((kbulk.ep & 0x80) == 0) {
err = -EFAULT;
if (copy_from_user(kptr, uptr, kbulk.len))
goto out;
}
kbulk.data = kptr;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
set_fs(old_fs);
if (err >= 0 &&
((kbulk.ep & 0x80) != 0)) {
if (copy_to_user(uptr, kptr, kbulk.len))
err = -EFAULT;
}
out:
free_page((unsigned long) kptr);
return err;
}
/* This needs more work before we can enable it. Unfortunately
* because of the fancy asynchronous way URB status/error is written
* back to userspace, we'll need to fiddle with USB devio internals
* and/or reimplement entirely the frontend of it ourselves. -DaveM
*
* The issue is:
*
* When an URB is submitted via usbdevicefs it is put onto an
* asynchronous queue. When the URB completes, it may be reaped
* via another ioctl. During this reaping the status is written
* back to userspace along with the length of the transfer.
*
* We must translate into 64-bit kernel types so we pass in a kernel
* space copy of the usbdevfs_urb structure. This would mean that we
* must do something to deal with the async entry reaping. First we
* have to deal somehow with this transitory memory we've allocated.
* This is problematic since there are many call sites from which the
* async entries can be destroyed (and thus when we'd need to free up
* this kernel memory). One of which is the close() op of usbdevicefs.
* To handle that we'd need to make our own file_operations struct which
* overrides usbdevicefs's release op with our own which runs usbdevicefs's
* real release op then frees up the kernel memory.
*
* But how to keep track of these kernel buffers? We'd need to either
* keep track of them in some table _or_ know about usbdevicefs internals
* (ie. the exact layout of it's file private, which is actually defined
* in linux/usbdevice_fs.h, the layout of the async queues are private to
* devio.c)
*
* There is one possible other solution I considered, also involving knowledge
* of usbdevicefs internals:
*
* After an URB is submitted, we "fix up" the address back to the user
* space one. This would work if the status/length fields written back
* by the async URB completion lines up perfectly in the 32-bit type with
* the 64-bit kernel type. Unfortunately, it does not because the iso
* frame descriptors, at the end of the struct, can be written back.
*
* I think we'll just need to simply duplicate the devio URB engine here.
*/
#if 0
struct usbdevfs_urb32 {
__u8 type;
__u8 endpoint;
__s32 status;
__u32 flags;
__u32 buffer;
__s32 buffer_length;
__s32 actual_length;
__s32 start_frame;
__s32 number_of_packets;
__s32 error_count;
__u32 signr;
__u32 usercontext; /* unused */
struct usbdevfs_iso_packet_desc iso_frame_desc[0];
};
#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
static int get_urb32(struct usbdevfs_urb *kurb,
struct usbdevfs_urb32 *uurb)
{
if (get_user(kurb->type, &uurb->type) ||
__get_user(kurb->endpoint, &uurb->endpoint) ||
__get_user(kurb->status, &uurb->status) ||
__get_user(kurb->flags, &uurb->flags) ||
__get_user(kurb->buffer_length, &uurb->buffer_length) ||
__get_user(kurb->actual_length, &uurb->actual_length) ||
__get_user(kurb->start_frame, &uurb->start_frame) ||
__get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
__get_user(kurb->error_count, &uurb->error_count) ||
__get_user(kurb->signr, &uurb->signr))
return -EFAULT;
kurb->usercontext = 0; /* unused currently */
return 0;
}
/* Just put back the values which usbdevfs actually changes. */
static int put_urb32(struct usbdevfs_urb *kurb,
struct usbdevfs_urb32 *uurb)
{
if (put_user(kurb->status, &uurb->status) ||
__put_user(kurb->actual_length, &uurb->actual_length) ||
__put_user(kurb->error_count, &uurb->error_count))
return -EFAULT;
if (kurb->number_of_packets != 0) {
int i;
for (i = 0; i < kurb->number_of_packets; i++) {
if (__put_user(kurb->iso_frame_desc[i].actual_length,
&uurb->iso_frame_desc[i].actual_length) ||
__put_user(kurb->iso_frame_desc[i].status,
&uurb->iso_frame_desc[i].status))
return -EFAULT;
}
}
return 0;
}
static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
struct usbdevfs_urb32 *uurb)
{
unsigned int totlen;
int i;
if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
kurb->number_of_packets = 0;
return 0;
}
if (kurb->number_of_packets < 1 ||
kurb->number_of_packets > 128)
return -EINVAL;
if (copy_from_user(&kurb->iso_frame_desc[0],
&uurb->iso_frame_desc[0],
sizeof(struct usbdevfs_iso_packet_desc) *
kurb->number_of_packets))
return -EFAULT;
totlen = 0;
for (i = 0; i < kurb->number_of_packets; i++) {
unsigned int this_len;
this_len = kurb->iso_frame_desc[i].length;
if (this_len > 1023)
return -EINVAL;
totlen += this_len;
}
if (totlen > 32768)
return -EINVAL;
kurb->buffer_length = totlen;
return 0;
}
static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct usbdevfs_urb *kurb;
struct usbdevfs_urb32 *uurb;
mm_segment_t old_fs;
__u32 udata;
void *uptr, *kptr;
unsigned int buflen;
int err;
uurb = (struct usbdevfs_urb32 *) arg;
err = -ENOMEM;
kurb = kmalloc(sizeof(struct usbdevfs_urb) +
(sizeof(struct usbdevfs_iso_packet_desc) * 128),
GFP_KERNEL);
if (!kurb)
goto out;
err = -EFAULT;
if (get_urb32(kurb, uurb))
goto out;
err = get_urb32_isoframes(kurb, uurb);
if (err)
goto out;
err = -EFAULT;
if (__get_user(udata, &uurb->buffer))
goto out;
uptr = (void *) A(udata);
err = -ENOMEM;
buflen = kurb->buffer_length;
kptr = kmalloc(buflen, GFP_KERNEL);
if (!kptr)
goto out;
kurb->buffer = kptr;
err = -EFAULT;
if (copy_from_user(kptr, uptr, buflen))
goto out_kptr;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
set_fs(old_fs);
if (err >= 0) {
/* RED-PEN Shit, this doesn't work for async URBs :-( XXX */
if (put_urb32(kurb, uurb)) {
err = -EFAULT;
} else if ((kurb->endpoint & USB_DIR_IN) != 0) {
if (copy_to_user(uptr, kptr, buflen))
err = -EFAULT;
}
}
out_kptr:
kfree(kptr);
out:
kfree(kurb);
return err;
}
#endif
#define USBDEVFS_REAPURB32 _IOW('U', 12, u32)
#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32)
static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs;
void *kptr;
int err;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_ioctl(fd,
(cmd == USBDEVFS_REAPURB32 ?
USBDEVFS_REAPURB :
USBDEVFS_REAPURBNDELAY),
(unsigned long) &kptr);
set_fs(old_fs);
if (err >= 0 &&
put_user(((u32)(long)kptr), (u32 *) A(arg)))
err = -EFAULT;
return err;
}
struct usbdevfs_disconnectsignal32 {
unsigned int signr;
u32 context;
};
#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct usbdevfs_disconnectsignal kdis;
struct usbdevfs_disconnectsignal32 *udis;
mm_segment_t old_fs;
u32 uctx;
int err;
udis = (struct usbdevfs_disconnectsignal32 *) arg;
if (get_user(kdis.signr, &udis->signr) ||
__get_user(uctx, &udis->context))
return -EFAULT;
kdis.context = (void *) (long)uctx;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
set_fs(old_fs);
return err;
}
struct mtd_oob_buf32 {
u32 start;
u32 length;
u32 ptr; /* unsigned char* */
};
#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs = get_fs();
struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg;
struct mtd_oob_buf karg;
u32 tmp;
char *ptr;
int ret;
if (get_user(karg.start, &uarg->start) ||
get_user(karg.length, &uarg->length) ||
get_user(tmp, &uarg->ptr))
return -EFAULT;
ptr = (char *)A(tmp);
if (0 >= karg.length)
return -EINVAL;
karg.ptr = kmalloc(karg.length, GFP_KERNEL);
if (NULL == karg.ptr)
return -ENOMEM;
if (copy_from_user(karg.ptr, ptr, karg.length)) {
kfree(karg.ptr);
return -EFAULT;
}
set_fs(KERNEL_DS);
if (MEMREADOOB32 == cmd)
ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
else if (MEMWRITEOOB32 == cmd)
ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
else
ret = -EINVAL;
set_fs(old_fs);
if (0 == ret && cmd == MEMREADOOB32) {
ret = copy_to_user(ptr, karg.ptr, karg.length);
ret |= put_user(karg.start, &uarg->start);
ret |= put_user(karg.length, &uarg->length);
}
kfree(karg.ptr);
return ((0 == ret) ? 0 : -EFAULT);
}
/* /proc/mtrr ioctls */
struct mtrr_sentry32
{
unsigned int base; /* Base address */
unsigned int size; /* Size of region */
unsigned int type; /* Type of region */
};
struct mtrr_gentry32
{
unsigned int regnum; /* Register number */
unsigned int base; /* Base address */
unsigned int size; /* Size of region */
unsigned int type; /* Type of region */
};
#define MTRR_IOCTL_BASE 'M'
#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
#define MTRRIOC32_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct mtrr_gentry g;
struct mtrr_sentry s;
int get = 0, err = 0;
struct mtrr_gentry32 *g32 = (struct mtrr_gentry32 *)arg;
mm_segment_t oldfs = get_fs();
switch (cmd) {
#define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break
#define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break
SET(ADD);
SET(SET);
SET(DEL);
GET(GET);
SET(KILL);
SET(ADD_PAGE);
SET(SET_PAGE);
SET(DEL_PAGE);
GET(GET_PAGE);
SET(KILL_PAGE);
}
if (get) {
err = get_user(g.regnum, &g32->regnum);
err |= get_user(g.base, &g32->base);
err |= get_user(g.size, &g32->size);
err |= get_user(g.type, &g32->type);
arg = (unsigned long)&g;
} else {
struct mtrr_sentry32 *s32 = (struct mtrr_sentry32 *)arg;
err = get_user(s.base, &s32->base);
err |= get_user(s.size, &s32->size);
err |= get_user(s.type, &s32->type);
arg = (unsigned long)&s;
}
if (err) return err;
set_fs(KERNEL_DS);
err = sys_ioctl(fd, cmd, arg);
set_fs(oldfs);
if (!err && get) {
err = put_user(g.base, &g32->base);
err |= put_user(g.size, &g32->size);
err |= put_user(g.regnum, &g32->regnum);
err |= put_user(g.type, &g32->type);
}
return err;
}
struct ioctl_trans {
unsigned long cmd;
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
......@@ -3220,7 +4161,6 @@ COMPATIBLE_IOCTL(TCSETS)
COMPATIBLE_IOCTL(TCSETSW)
COMPATIBLE_IOCTL(TCSETSF)
COMPATIBLE_IOCTL(TIOCLINUX)
HANDLE_IOCTL(TIOCGDEV, tiocgdev)
/* Little t */
COMPATIBLE_IOCTL(TIOCGETD)
COMPATIBLE_IOCTL(TIOCSETD)
......@@ -3245,6 +4185,7 @@ COMPATIBLE_IOCTL(TIOCSCTTY)
COMPATIBLE_IOCTL(TIOCGPTN)
COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCSERGETLSR)
/* Big F */
COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
......@@ -3269,12 +4210,14 @@ COMPATIBLE_IOCTL(FIGETBSZ)
*/
COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
COMPATIBLE_IOCTL(HDIO_SET_DMA)
COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
COMPATIBLE_IOCTL(HDIO_SET_32BIT)
COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
COMPATIBLE_IOCTL(HDIO_SET_NICE)
/* 0x02 -- Floppy ioctls */
COMPATIBLE_IOCTL(FDMSGON)
......@@ -3302,7 +4245,6 @@ COMPATIBLE_IOCTL(BLKRASET)
COMPATIBLE_IOCTL(BLKFRASET)
COMPATIBLE_IOCTL(BLKSECTSET)
COMPATIBLE_IOCTL(BLKSSZGET)
/* RAID */
COMPATIBLE_IOCTL(RAID_VERSION)
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
......@@ -3323,7 +4265,6 @@ COMPATIBLE_IOCTL(START_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY)
COMPATIBLE_IOCTL(STOP_ARRAY_RO)
COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
/* Big K */
COMPATIBLE_IOCTL(PIO_FONT)
COMPATIBLE_IOCTL(GIO_FONT)
......@@ -3345,6 +4286,7 @@ COMPATIBLE_IOCTL(KDGKBSENT)
COMPATIBLE_IOCTL(KDSKBSENT)
COMPATIBLE_IOCTL(KDGKBDIACR)
COMPATIBLE_IOCTL(KDSKBDIACR)
COMPATIBLE_IOCTL(KDKBDREP)
COMPATIBLE_IOCTL(KDGKBLED)
COMPATIBLE_IOCTL(KDSKBLED)
COMPATIBLE_IOCTL(KDGETLED)
......@@ -3364,6 +4306,14 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE)
COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE)
COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
/* Big T */
COMPATIBLE_IOCTL(TUNSETNOCSUM)
COMPATIBLE_IOCTL(TUNSETDEBUG)
COMPATIBLE_IOCTL(TUNSETIFF)
COMPATIBLE_IOCTL(TUNSETPERSIST)
COMPATIBLE_IOCTL(TUNSETOWNER)
/* Big V */
COMPATIBLE_IOCTL(VT_SETMODE)
COMPATIBLE_IOCTL(VT_GETMODE)
......@@ -3377,7 +4327,8 @@ COMPATIBLE_IOCTL(VT_RESIZE)
COMPATIBLE_IOCTL(VT_RESIZEX)
COMPATIBLE_IOCTL(VT_LOCKSWITCH)
COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
/* Little v, the video4linux ioctls */
/* Little v */
/* Little v, the video4linux ioctls (conflict?) */
COMPATIBLE_IOCTL(VIDIOCGCAP)
COMPATIBLE_IOCTL(VIDIOCGCHAN)
COMPATIBLE_IOCTL(VIDIOCSCHAN)
......@@ -3417,10 +4368,6 @@ COMPATIBLE_IOCTL(RTC_RD_TIME)
COMPATIBLE_IOCTL(RTC_SET_TIME)
COMPATIBLE_IOCTL(RTC_WKALM_SET)
COMPATIBLE_IOCTL(RTC_WKALM_RD)
HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_SET32,rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
/* Little m */
COMPATIBLE_IOCTL(MTIOCTOP)
/* Socket level stuff */
......@@ -3442,6 +4389,11 @@ COMPATIBLE_IOCTL(SIOCGRARP)
COMPATIBLE_IOCTL(SIOCDRARP)
COMPATIBLE_IOCTL(SIOCADDDLCI)
COMPATIBLE_IOCTL(SIOCDELDLCI)
COMPATIBLE_IOCTL(SIOCGMIIPHY)
COMPATIBLE_IOCTL(SIOCGMIIREG)
COMPATIBLE_IOCTL(SIOCSMIIREG)
COMPATIBLE_IOCTL(SIOCGIFVLAN)
COMPATIBLE_IOCTL(SIOCSIFVLAN)
/* SG stuff */
COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
......@@ -3463,7 +4415,6 @@ COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
COMPATIBLE_IOCTL(SG_SCSI_RESET)
COMPATIBLE_IOCTL(SG_IO)
COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
......@@ -3481,10 +4432,14 @@ COMPATIBLE_IOCTL(PPPIOCSMAXCID)
COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
/* PPPIOCSCOMPRESS is translated */
COMPATIBLE_IOCTL(PPPIOCGNPMODE)
COMPATIBLE_IOCTL(PPPIOCSNPMODE)
COMPATIBLE_IOCTL(PPPIOCGDEBUG)
COMPATIBLE_IOCTL(PPPIOCSDEBUG)
/* PPPIOCSPASS is translated */
/* PPPIOCSACTIVE is translated */
/* PPPIOCGIDLE is translated */
COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
COMPATIBLE_IOCTL(PPPIOCATTACH)
COMPATIBLE_IOCTL(PPPIOCDETACH)
......@@ -3494,8 +4449,10 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN)
COMPATIBLE_IOCTL(PPPIOCATTCHAN)
COMPATIBLE_IOCTL(PPPIOCGCHAN)
/* PPPOX */
COMPATIBLE_IOCTL(PPPOEIOCSFWD);
COMPATIBLE_IOCTL(PPPOEIOCDFWD);
COMPATIBLE_IOCTL(PPPOEIOCSFWD)
COMPATIBLE_IOCTL(PPPOEIOCDFWD)
/* LP */
COMPATIBLE_IOCTL(LPGETSTATUS)
/* CDROM stuff */
COMPATIBLE_IOCTL(CDROMPAUSE)
COMPATIBLE_IOCTL(CDROMRESUME)
......@@ -3527,9 +4484,15 @@ COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
COMPATIBLE_IOCTL(CDROM_LOCKDOOR)
COMPATIBLE_IOCTL(CDROM_DEBUG)
COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
/* DVD ioctls */
COMPATIBLE_IOCTL(DVD_READ_STRUCT)
COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
COMPATIBLE_IOCTL(DVD_AUTH)
/* Big L */
COMPATIBLE_IOCTL(LOOP_SET_FD)
COMPATIBLE_IOCTL(LOOP_CLR_FD)
/* Big A */
/* sparc only */
/* Big Q for sound/OSS */
COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
......@@ -3688,7 +4651,6 @@ COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, autofs_ioctl32);
/* DEVFS */
COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
......@@ -3755,15 +4717,68 @@ COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
#endif /* DRM */
HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32);
HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32);
HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32);
/* serial driver */
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl);
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl);
/* elevator */
COMPATIBLE_IOCTL(BLKELVGET)
COMPATIBLE_IOCTL(BLKELVSET)
#ifdef CONFIG_AUTOFS_FS
COMPATIBLE_IOCTL(AUTOFS_IOC_READY)
COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL)
COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
COMPATIBLE_IOCTL(AUTOFS_IOC_SETTIMEOUT)
COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
#endif
#ifdef CONFIG_RTC
COMPATIBLE_IOCTL(RTC_AIE_ON)
COMPATIBLE_IOCTL(RTC_AIE_OFF)
COMPATIBLE_IOCTL(RTC_UIE_ON)
COMPATIBLE_IOCTL(RTC_UIE_OFF)
COMPATIBLE_IOCTL(RTC_PIE_ON)
COMPATIBLE_IOCTL(RTC_PIE_OFF)
COMPATIBLE_IOCTL(RTC_WIE_ON)
COMPATIBLE_IOCTL(RTC_WIE_OFF)
COMPATIBLE_IOCTL(RTC_ALM_SET)
COMPATIBLE_IOCTL(RTC_ALM_READ)
COMPATIBLE_IOCTL(RTC_RD_TIME)
COMPATIBLE_IOCTL(RTC_SET_TIME)
COMPATIBLE_IOCTL(RTC_WKALM_SET)
COMPATIBLE_IOCTL(RTC_WKALM_RD)
#endif
/* Big W */
/* WIOC_GETSUPPORT not yet implemented -E */
COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
COMPATIBLE_IOCTL(WDIOC_GETTEMP)
COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
#if 0 /* sparc only ? */
COMPATIBLE_IOCTL(WIOCSTART)
COMPATIBLE_IOCTL(WIOCSTOP)
COMPATIBLE_IOCTL(WIOCGSTAT)
#endif
/* Big R */
COMPATIBLE_IOCTL(RNDGETENTCNT)
COMPATIBLE_IOCTL(RNDADDTOENTCNT)
COMPATIBLE_IOCTL(RNDGETPOOL)
COMPATIBLE_IOCTL(RNDADDENTROPY)
COMPATIBLE_IOCTL(RNDZAPENTCNT)
COMPATIBLE_IOCTL(RNDCLEARPOOL)
/* Bluetooth ioctls */
COMPATIBLE_IOCTL(HCIDEVUP)
COMPATIBLE_IOCTL(HCIDEVDOWN)
COMPATIBLE_IOCTL(HCIDEVRESET)
COMPATIBLE_IOCTL(HCIDEVRESTAT)
COMPATIBLE_IOCTL(HCIGETDEVLIST)
COMPATIBLE_IOCTL(HCIGETDEVINFO)
COMPATIBLE_IOCTL(HCIGETCONNLIST)
COMPATIBLE_IOCTL(HCIGETCONNINFO)
COMPATIBLE_IOCTL(HCISETRAW)
COMPATIBLE_IOCTL(HCISETSCAN)
COMPATIBLE_IOCTL(HCISETAUTH)
COMPATIBLE_IOCTL(HCISETENCRYPT)
COMPATIBLE_IOCTL(HCISETPTYPE)
COMPATIBLE_IOCTL(HCISETLINKPOL)
COMPATIBLE_IOCTL(HCISETLINKMODE)
COMPATIBLE_IOCTL(HCISETACLMTU)
COMPATIBLE_IOCTL(HCISETSCOMTU)
COMPATIBLE_IOCTL(HCIINQUIRY)
/* Misc. */
COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
......@@ -3771,8 +4786,46 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
COMPATIBLE_IOCTL(0x4B50); /* KDGHWCLK - not in the kernel, but don't complain */
COMPATIBLE_IOCTL(0x4B51); /* KDSHWCLK - not in the kernel, but don't complain */
/* USB */
COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
COMPATIBLE_IOCTL(USBDEVFS_RESET)
COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
/* MTD */
COMPATIBLE_IOCTL(MEMGETINFO)
COMPATIBLE_IOCTL(MEMERASE)
COMPATIBLE_IOCTL(MEMLOCK)
COMPATIBLE_IOCTL(MEMUNLOCK)
COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
COMPATIBLE_IOCTL(MEMGETREGIONINFO)
/* NBD */
COMPATIBLE_IOCTL(NBD_SET_SOCK)
COMPATIBLE_IOCTL(NBD_SET_BLKSIZE)
COMPATIBLE_IOCTL(NBD_SET_SIZE)
COMPATIBLE_IOCTL(NBD_DO_IT)
COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
COMPATIBLE_IOCTL(NBD_DISCONNECT)
/* And these ioctls need translation */
HANDLE_IOCTL(TIOCGDEV, tiocgdev)
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
#ifdef CONFIG_NET
HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
#endif
HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc)
......@@ -3799,26 +4852,42 @@ HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc)
HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc)
HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl)
HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl)
HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl)
HANDLE_IOCTL(SIOCBONDSETHWADDR, bond_ioctl)
HANDLE_IOCTL(SIOCBONDSLAVEINFOQUERY, bond_ioctl)
HANDLE_IOCTL(SIOCBONDINFOQUERY, bond_ioctl)
HANDLE_IOCTL(SIOCBONDCHANGEACTIVE, bond_ioctl)
HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
/* realtime device */
HANDLE_IOCTL(RTC_IRQP_READ, rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32)
HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
/* Raw devices */
HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
HANDLE_IOCTL(SIOCRTMSG, ret_einval)
HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo)
HANDLE_IOCTL(BLKRAGET, w_long)
HANDLE_IOCTL(BLKGETSIZE, w_long)
HANDLE_IOCTL(0x1260, broken_blkgetsize)
HANDLE_IOCTL(BLKFRAGET, w_long)
HANDLE_IOCTL(BLKSECTGET, w_long)
HANDLE_IOCTL(FBIOGET_FSCREENINFO, fb_ioctl_trans)
HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
HANDLE_IOCTL(FBIOGETCMAP, fb_ioctl_trans)
HANDLE_IOCTL(FBIOPUTCMAP, fb_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
......@@ -3834,8 +4903,11 @@ HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans)
HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans)
HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans)
HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans)
HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans)
......@@ -3849,6 +4921,8 @@ HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans)
HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
HANDLE_IOCTL(LOOP_SET_STATUS, loop_status)
HANDLE_IOCTL(LOOP_GET_STATUS, loop_status)
#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int)
HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout)
HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl)
HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl)
HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl)
......@@ -3907,18 +4981,48 @@ HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl)
HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl)
HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
HANDLE_IOCTL(VG_CREATE_OLD, do_lvm_ioctl)
HANDLE_IOCTL(LV_STATUS_BYDEV, do_lvm_ioctl)
#endif /* LVM */
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
#endif /* DRM */
/* VFAT */
HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
/* take care of sizeof(sizeof()) breakage */
/* elevator */
HANDLE_IOCTL(BLKELVGET_32, do_blkelvget)
HANDLE_IOCTL(BLKELVSET_32, do_blkelvset)
/* block stuff */
HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64)
/* mtrr */
HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
IOCTL_TABLE_END
#define IOCTL_HASHSIZE 256
......@@ -3926,6 +5030,8 @@ struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
extern struct ioctl_trans ioctl_start[], ioctl_end[];
extern struct ioctl_trans ioctl_start[], ioctl_end[];
static inline unsigned long ioctl32_hash(unsigned long cmd)
{
return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
......@@ -4022,7 +5128,7 @@ static inline int builtin_ioctl(struct ioctl_trans *t)
/* Problem:
This function cannot unregister duplicate ioctls, because they are not
unique.
When they happen we need to extend the prototype to pass handler too. */
When they happen we need to extend the prototype to pass the handler too. */
int unregister_ioctl32_conversion(unsigned int cmd)
{
......@@ -4096,13 +5202,35 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
if (t) {
handler = t->handler;
error = handler(fd, cmd, arg, filp);
} else if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
error = siocdevprivate_ioctl(fd, cmd, arg);
} else {
static int count = 0;
if (++count <= 50)
printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) "
"cmd(%08x) arg(%08x)\n",
static int count;
if (++count <= 50) {
char buf[10];
char *path = (char *)__get_free_page(GFP_KERNEL), *fn = "?";
/* find the name of the device. */
if (path) {
struct file *f = fget(fd);
if (f) {
fn = d_path(f->f_dentry, f->f_vfsmnt,
path, PAGE_SIZE);
fput(f);
}
}
sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
if (!isprint(buf[1]))
sprintf(buf, "%02x", buf[1]);
printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
"cmd(%08x){%s} arg(%08x) on %s\n",
current->comm, current->pid,
(int)fd, (unsigned int)cmd, (unsigned int)arg);
(int)fd, (unsigned int)cmd, buf, (unsigned int)arg,
fn);
if (path)
free_page((unsigned long)path);
}
error = -EINVAL;
}
out:
......@@ -4110,3 +5238,4 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
out2:
return error;
}
......@@ -7,7 +7,7 @@
* 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
* 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
*
* $Id: ia32_signal.c,v 1.17 2002/03/21 14:16:32 ak Exp $
* $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $
*/
#include <linux/sched.h>
......@@ -39,6 +39,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
void signal_fault(struct pt_regs *regs, void *frame, char *where);
static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
{
......@@ -163,32 +164,38 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsign
regs->r ## x = reg; \
}
#define RELOAD_SEG(seg) \
#define RELOAD_SEG(seg,mask) \
{ unsigned int cur; \
unsigned short pre; \
err |= __get_user(pre, &sc->seg); \
asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
pre |= mask; \
if (pre != cur) loadsegment(seg,pre); }
/* Reload fs and gs if they have changed in the signal handler. */
/* Reload fs and gs if they have changed in the signal handler.
This does not handle long fs/gs base changes in the handler, but
does not clobber them at least in the normal case. */
{
unsigned short gs;
unsigned gs, oldgs;
err |= __get_user(gs, &sc->gs);
gs |= 3;
asm("movl %%gs,%0" : "=r" (oldgs));
if (gs != oldgs)
load_gs_index(gs);
}
RELOAD_SEG(fs);
RELOAD_SEG(ds);
RELOAD_SEG(es);
RELOAD_SEG(fs,3);
RELOAD_SEG(ds,3);
RELOAD_SEG(es,3);
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
COPY(dx); COPY(cx); COPY(ip);
/* Don't touch extended registers */
err |= __get_user(regs->cs, &sc->cs);
regs->cs |= 2;
regs->cs |= 3;
err |= __get_user(regs->ss, &sc->ss);
regs->ss |= 2;
regs->ss |= 3;
{
unsigned int tmpflags;
......@@ -284,7 +291,7 @@ asmlinkage int sys32_rt_sigreturn(struct pt_regs regs)
return eax;
badframe:
signal_fault(&regs, frame, "32bit rt sigreturn");
signal_fault(&regs,frame,"32bit rt sigreturn");
return 0;
}
......@@ -377,8 +384,9 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
{
struct exec_domain *ed = current_thread_info()->exec_domain;
err |= __put_user((ed && ed->signal_invmap && sig < 32
err |= __put_user((ed
&& ed->signal_invmap
&& sig < 32
? ed->signal_invmap[sig]
: sig),
&frame->sig);
......@@ -435,7 +443,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
signal_fault(regs,frame,"32bit signal setup");
signal_fault(regs,frame,"32bit signal deliver");
}
void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -449,9 +457,12 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
{
struct exec_domain *ed = current_thread_info()->exec_domain;
err |= __put_user((ed && ed->signal_invmap && sig < 32
err |= __put_user((ed
&& ed->signal_invmap
&& sig < 32
? ed->signal_invmap[sig]
: sig),
&frame->sig);
......
......@@ -27,7 +27,7 @@
*/
ENTRY(ia32_cstar_target)
movq $-ENOSYS,%rax
sysret
sysretl
/*
* Emulated IA32 system calls via int 0x80.
......@@ -77,6 +77,7 @@ ia32_tracesys:
jmp ia32_do_syscall
ia32_badsys:
movq $0,ORIG_RAX-ARGOFFSET(%rsp)
movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
jmp int_ret_from_sys_call
......@@ -84,6 +85,10 @@ ni_syscall:
movq %rax,%rdi
jmp sys32_ni_syscall
quiet_ni_syscall:
movq $-ENOSYS,%rax
ret
.macro PTREGSCALL label, func
.globl \label
\label:
......@@ -229,7 +234,7 @@ ia32_sys_call_table:
.quad stub32_iopl /* 110 */
.quad sys_vhangup
.quad ni_syscall /* old "idle" system call */
.quad ni_syscall /* vm86old */
.quad sys32_vm86_warning /* vm86old */
.quad sys32_wait4
.quad sys_swapoff /* 115 */
.quad sys32_sysinfo
......@@ -238,7 +243,7 @@ ia32_sys_call_table:
.quad stub32_sigreturn
.quad stub32_clone /* 120 */
.quad sys_setdomainname
.quad sys32_newuname
.quad sys_uname
.quad sys_modify_ldt
.quad sys32_adjtimex
.quad sys32_mprotect /* 125 */
......@@ -282,8 +287,8 @@ ia32_sys_call_table:
.quad sys_mremap
.quad sys_setresuid16
.quad sys_getresuid16 /* 165 */
.quad ni_syscall /* vm86 */
.quad ni_syscall /* query_module */
.quad sys32_vm86_warning /* vm86 */
.quad quiet_ni_syscall /* query_module */
.quad sys_poll
.quad sys32_nfsservctl
.quad sys_setresgid16 /* 170 */
......@@ -368,7 +373,7 @@ ia32_sys_call_table:
.quad sys_io_cancel
.quad sys_ni_syscall /* 250 alloc_huge_pages */
.quad sys_ni_syscall /* free_huge_pages */
.quad sys_ni_syscall /* exit_group */
.quad sys_exit_group /* exit_group */
ia32_syscall_end:
.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
.quad ni_syscall
......
......@@ -264,6 +264,9 @@ semctl32 (int first, int second, int third, void *uptr)
if (err2)
err = -EFAULT;
break;
default:
err = -EINVAL;
break;
}
return err;
}
......@@ -284,7 +287,7 @@ do_sys32_msgsnd (int first, int second, int third, void *uptr)
if (!p)
return -ENOMEM;
err = get_user(p->mtype, &up->mtype);
err |= copy_from_user(p->mtext, &up->mtext, second);
err |= (copy_from_user(p->mtext, &up->mtext, second) ? -EFAULT : 0);
if (err)
goto out;
old_fs = get_fs();
......
......@@ -35,7 +35,6 @@
#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/binfmts.h>
#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/slab.h>
......@@ -56,6 +55,7 @@
#include <linux/stat.h>
#include <linux/ipc.h>
#include <linux/rwsem.h>
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/aio_abi.h>
#include <asm/mman.h>
......@@ -264,8 +264,11 @@ sys32_mmap(struct mmap_arg_struct *arg)
if (!file)
return -EBADF;
}
#if 0 /* reenable when noexec works */
if (a.prot & PROT_READ)
a.prot |= PROT_EXEC;
#endif
a.flags |= MAP_32BIT;
......@@ -275,8 +278,8 @@ sys32_mmap(struct mmap_arg_struct *arg)
if (file)
fput(file);
/* Should not happen */
if (retval >= 0xFFFFFFFF && (long)retval > 0) {
/* Cannot wrap */
if (retval+a.len >= 0xFFFFFFFF && (long)retval > 0) {
do_munmap(mm, retval, a.len);
retval = -ENOMEM;
}
......@@ -964,22 +967,24 @@ sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
struct iovec *
get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
static struct iovec *
get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type, int *errp)
{
int i;
u32 buf, len;
struct iovec *ivp, *iov;
unsigned long totlen;
/* Get the "struct iovec" from user memory */
if (!count)
return 0;
if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
return(struct iovec *)0;
if (count > UIO_MAXIOV)
return(struct iovec *)0;
if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
return(struct iovec *)0;
if (count > UIO_FASTIOV) {
*errp = -ENOMEM;
iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
if (!iov)
return((struct iovec *)0);
......@@ -987,24 +992,33 @@ get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
iov = iov_buf;
ivp = iov;
totlen = 0;
for (i = 0; i < count; i++) {
if (__get_user(len, &iov32->iov_len) ||
__get_user(buf, &iov32->iov_base)) {
if (iov != iov_buf)
kfree(iov);
return((struct iovec *)0);
}
if (verify_area(type, (void *)A(buf), len)) {
if (iov != iov_buf)
kfree(iov);
return((struct iovec *)0);
}
*errp = __get_user(len, &iov32->iov_len) |
__get_user(buf, &iov32->iov_base);
if (*errp)
goto error;
*errp = verify_area(type, (void *)A(buf), len);
if (*errp)
goto error;
/* SuS checks: */
*errp = -EINVAL;
if ((int)len < 0)
goto error;
if ((totlen += len) >= 0x7fffffff)
goto error;
ivp->iov_base = (void *)A(buf);
ivp->iov_len = (__kernel_size_t)len;
iov32++;
ivp++;
}
*errp = 0;
return(iov);
error:
if (iov != iov_buf)
kfree(iov);
return NULL;
}
asmlinkage long
......@@ -1015,8 +1029,8 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count)
int ret;
mm_segment_t old_fs = get_fs();
if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0)
return -EFAULT;
if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE, &ret)) == NULL)
return ret;
set_fs(KERNEL_DS);
ret = sys_readv(fd, iov, count);
set_fs(old_fs);
......@@ -1033,8 +1047,8 @@ sys32_writev(int fd, struct iovec32 *vector, u32 count)
int ret;
mm_segment_t old_fs = get_fs();
if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0)
return -EFAULT;
if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ, &ret)) == NULL)
return ret;
set_fs(KERNEL_DS);
ret = sys_writev(fd, iov, count);
set_fs(old_fs);
......@@ -1121,7 +1135,7 @@ sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
/*
* sys_time() can be implemented in user-level using
* sys_gettimeofday(). IA64 did this but i386 Linux did not
* sys_gettimeofday(). x86-64 did this but i386 Linux did not
* so we have to implement this system call here.
*/
asmlinkage long sys32_time(int * tloc)
......@@ -1288,6 +1302,39 @@ static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
}
extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
switch (cmd) {
case F_GETLK:
case F_SETLK:
case F_SETLKW:
{
struct flock f;
mm_segment_t old_fs;
long ret;
if (get_flock(&f, (struct flock32 *)arg))
return -EFAULT;
old_fs = get_fs(); set_fs (KERNEL_DS);
ret = sys_fcntl(fd, cmd, (unsigned long)&f);
set_fs (old_fs);
if (ret) return ret;
if (put_flock(&f, (struct flock32 *)arg))
return -EFAULT;
return 0;
}
case F_GETLK64:
case F_SETLK64:
case F_SETLKW64:
return sys32_fcntl64(fd,cmd,arg);
default:
return sys_fcntl(fd, cmd, (unsigned long)arg);
}
}
static inline int get_flock64(struct ia32_flock64 *fl32, struct flock *fl64)
{
......@@ -1319,40 +1366,34 @@ asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long a
{
struct flock fl64;
mm_segment_t oldfs = get_fs();
int ret = 0, origcmd;
unsigned long origarg;
int ret = 0;
int oldcmd = cmd;
unsigned long oldarg = arg;
origcmd = cmd;
origarg = arg;
switch (cmd) {
case F_GETLK:
case F_SETLK:
case F_SETLKW:
ret = get_flock(&fl64, (struct flock32 *)arg);
arg = (unsigned long) &fl64;
set_fs(KERNEL_DS);
break;
case F_GETLK64:
cmd = F_GETLK;
goto cnv64;
goto cnv;
case F_SETLK64:
cmd = F_SETLK;
goto cnv64;
goto cnv;
case F_SETLKW64:
cmd = F_SETLKW;
cnv64:
cnv:
ret = get_flock64((struct ia32_flock64 *)arg, &fl64);
arg = (unsigned long)&fl64;
set_fs(KERNEL_DS);
break;
case F_GETLK:
case F_SETLK:
case F_SETLKW:
return sys32_fcntl(fd,cmd,arg);
}
if (!ret)
ret = sys_fcntl(fd, cmd, arg);
set_fs(oldfs);
if (origcmd == F_GETLK && !ret)
ret = put_flock(&fl64, (struct flock32 *)origarg);
else if (cmd == F_GETLK && !ret)
ret = put_flock64((struct ia32_flock64 *)origarg, &fl64);
if (oldcmd == F_GETLK64 && !ret)
ret = put_flock64((struct ia32_flock64 *)oldarg, &fl64);
return ret;
}
......@@ -1804,19 +1845,6 @@ sys32_sysctl(struct sysctl_ia32 *args32)
#endif
}
extern asmlinkage long sys_newuname(struct new_utsname * name);
asmlinkage long
sys32_newuname(struct new_utsname * name)
{
int ret = sys_newuname(name);
if (current->personality == PER_LINUX32 && !ret) {
ret = copy_to_user(name->machine, "i686\0\0", 6);
}
return ret;
}
extern asmlinkage ssize_t sys_pread64(unsigned int fd, char * buf,
size_t count, loff_t pos);
......@@ -1825,7 +1853,8 @@ extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char * buf,
typedef __kernel_ssize_t32 ssize_t32;
/* warning. next two assume LE */
/* warning: next two assume little endian */
asmlinkage ssize_t32
sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,
u32 poslo, u32 poshi)
......@@ -1849,7 +1878,8 @@ asmlinkage long
sys32_personality(unsigned long personality)
{
int ret;
if (current->personality == PER_LINUX32 && personality == PER_LINUX)
if (personality(current->personality) == PER_LINUX32 &&
personality == PER_LINUX)
personality = PER_LINUX32;
ret = sys_personality(personality);
if (ret == PER_LINUX32)
......@@ -1956,42 +1986,39 @@ sys32_adjtimex(struct timex32 *utp)
return ret;
}
/* common code for old and new mmaps */
static inline long do_mmap2(
unsigned long addr, unsigned long len,
asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct mm_struct *mm = current->mm;
unsigned long error;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
return -EBADF;
}
down_write(&current->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(&current->mm->mmap_sem);
/* later add PROT_EXEC for PROT_READ here */
down_write(&mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags|MAP_32BIT, pgoff);
up_write(&mm->mmap_sem);
/* cannot wrap */
if (error+len >= 0xFFFFFFFF && (long)error >= 0) {
do_munmap(mm, error, len);
error = -ENOMEM;
}
if (file)
fput(file);
out:
return error;
}
asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
return do_mmap2(addr, len, prot, flags, fd, pgoff);
}
asmlinkage int sys32_olduname(struct oldold_utsname * name)
asmlinkage long sys32_olduname(struct oldold_utsname * name)
{
int error;
......@@ -2581,6 +2608,19 @@ long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
return ret;
}
int sys32_vm86_warning(void)
{
static long warn_time = -(60*HZ);
if (time_before(warn_time + 60*HZ,jiffies)) {
printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n",
current->comm);
warn_time = jiffies;
}
return -ENOSYS ;
}
struct exec_domain ia32_exec_domain = {
.name = "linux/x86",
.pers_low = PER_LINUX32,
......
......@@ -9,7 +9,7 @@ export-objs := mtrr.o x8664_ksyms.o pci-gart.o
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
setup64.o bluesmoke.o bootflag.o e820.o reboot.o
setup64.o bluesmoke.o bootflag.o e820.o reboot.o profile.o
obj-$(CONFIG_MTRR) += mtrr.o
obj-$(CONFIG_X86_MSR) += msr.o
......
......@@ -897,17 +897,9 @@ int setup_profiling_timer(unsigned int multiplier)
inline void smp_local_timer_interrupt(struct pt_regs *regs)
{
int user = user_mode(regs);
int cpu = smp_processor_id();
/*
* The profiling function is SMP safe. (nothing can mess
* around with "current", and the profiling counters are
* updated with atomic operations). This is especially
* useful with a profiling multiplier != 1
*/
if (!user)
x86_do_profile(regs->rip);
x86_do_profile(regs);
if (--prof_counter[cpu] <= 0) {
/*
......@@ -925,7 +917,7 @@ inline void smp_local_timer_interrupt(struct pt_regs *regs)
}
#ifdef CONFIG_SMP
update_process_times(user);
update_process_times(user_mode(regs));
#endif
}
......@@ -951,8 +943,6 @@ inline void smp_local_timer_interrupt(struct pt_regs *regs)
*/
void smp_apic_timer_interrupt(struct pt_regs *regs)
{
int cpu = smp_processor_id();
/*
* the NMI deadlock-detector uses this.
*/
......@@ -1084,11 +1074,13 @@ int __init APIC_init_uniprocessor (void)
static __init int setup_disableapic(char *str)
{
disable_apic = 1;
return 0;
}
static __init int setup_noapictimer(char *str)
{
disable_apic_timer = 1;
return 0;
}
__setup("disableapic", setup_disableapic);
......
......@@ -785,7 +785,7 @@ void __init mp_register_ioapic (
mp_ioapic_routing[idx].irq_end = irq_base +
io_apic_get_redir_entries(idx);
printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
mp_ioapic_routing[idx].irq_start,
......
......@@ -646,7 +646,7 @@ int mtrr_add_page (u64 base, u32 size, unsigned int type, char increment)
}
if (base & (size_or_mask>>PAGE_SHIFT)) {
printk (KERN_WARNING "mtrr: base(%lx) exceeds the MTRR width(%lx)\n",
printk (KERN_WARNING "mtrr: base(%Lx) exceeds the MTRR width(%Lx)\n",
(unsigned long) base,
(unsigned long) (size_or_mask>>PAGE_SHIFT));
return -EINVAL;
......
......@@ -23,6 +23,7 @@
#include <asm/smp.h>
#include <asm/mtrr.h>
#include <asm/mpspec.h>
#include <asm/nmi.h>
unsigned int nmi_watchdog = NMI_LOCAL_APIC;
static unsigned int nmi_hz = HZ;
......@@ -137,6 +138,18 @@ static int nmi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
return 0;
}
struct pm_dev * set_nmi_pm_callback(pm_callback callback)
{
apic_pm_unregister(nmi_pmdev);
return apic_pm_register(PM_SYS_DEV, 0, callback);
}
void unset_nmi_pm_callback(struct pm_dev * dev)
{
apic_pm_unregister(dev);
nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback);
}
static void nmi_pm_init(void)
{
if (!nmi_pmdev)
......@@ -178,7 +191,7 @@ static void __pminit setup_k7_watchdog(void)
| K7_NMI_EVENT;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
printk(KERN_INFO "watchdog: setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
printk(KERN_INFO "watchdog: setting K7_PERFCTR0 to %08x\n", -(cpu_khz/nmi_hz*1000));
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= K7_EVNTSEL_ENABLE;
......@@ -275,3 +288,30 @@ void nmi_watchdog_tick (struct pt_regs * regs)
if (nmi_perfctr_msr)
wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
}
static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
{
return 0;
}
static nmi_callback_t nmi_callback = dummy_nmi_callback;
asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
{
int cpu = smp_processor_id();
add_pda(__nmi_count,1);
if (!nmi_callback(regs, cpu))
default_do_nmi(regs);
}
void set_nmi_callback(nmi_callback_t callback)
{
nmi_callback = callback;
}
void unset_nmi_callback(void)
{
nmi_callback = dummy_nmi_callback;
}
......@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
#include <linux/module.h>
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/config.h>
......
/*
* linux/arch/i386/kernel/profile.c
*
* (C) 2002 John Levon <levon@movementarian.org>
*
*/
#include <linux/profile.h>
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <linux/irq.h>
#include <asm/hw_irq.h>
static struct notifier_block * profile_listeners;
static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
int register_profile_notifier(struct notifier_block * nb)
{
int err;
write_lock_irq(&profile_lock);
err = notifier_chain_register(&profile_listeners, nb);
write_unlock_irq(&profile_lock);
return err;
}
int unregister_profile_notifier(struct notifier_block * nb)
{
int err;
write_lock_irq(&profile_lock);
err = notifier_chain_unregister(&profile_listeners, nb);
write_unlock_irq(&profile_lock);
return err;
}
void x86_profile_hook(struct pt_regs * regs)
{
/* we would not even need this lock if
* we had a global cli() on register/unregister
*/
read_lock(&profile_lock);
notifier_call_chain(&profile_listeners, 0, regs);
read_unlock(&profile_lock);
}
......@@ -8,6 +8,7 @@
#include <asm/io.h>
#include <asm/kdebug.h>
#include <asm/delay.h>
#include <asm/hw_irq.h>
/*
......
......@@ -234,7 +234,6 @@ static void __init contig_initmem_init(void)
void __init setup_arch(char **cmdline_p)
{
unsigned long bootmap_size, low_mem_size;
int i;
ROOT_DEV = ORIG_ROOT_DEV;
......@@ -284,14 +283,8 @@ void __init setup_arch(char **cmdline_p)
contig_initmem_init();
/*
* Reserve the bootmem bitmap itself as well. We do this in two
* steps (first step was init_bootmem()) because this catches
* the (very unlikely) case of us accidentally initializing the
* bootmem allocator with an invalid RAM area.
*/
reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
/* reserve kernel */
reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) - HIGH_MEMORY);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
......
......@@ -559,11 +559,10 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
printk("Do you have a strange power saving mode enabled?\n");
}
asmlinkage void do_nmi(struct pt_regs * regs)
asmlinkage void default_do_nmi(struct pt_regs * regs)
{
unsigned char reason = inb(0x61);
add_pda(__nmi_count,1);
if (!(reason & 0xc0)) {
#if CONFIG_X86_LOCAL_APIC
/*
......
#
# Makefile for the linux i386-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o
obj-y := init.o fault.o ioremap.o extable.o modutil.o
export-objs := pageattr.o
obj-y := init.o fault.o ioremap.o extable.o modutil.o pageattr.o
include $(TOPDIR)/Rules.make
......@@ -32,18 +32,14 @@
extern void die(const char *,struct pt_regs *,long);
extern spinlock_t console_lock, timerlist_lock;
extern spinlock_t console_lock;
void bust_spinlocks(int yes)
{
spin_lock_init(&timerlist_lock);
int loglevel_save = console_loglevel;
if (yes) {
oops_in_progress = 1;
#ifdef CONFIG_SMP
global_irq_lock = 0; /* Many serial drivers do __global_cli() */
#endif
} else {
int loglevel_save = console_loglevel;
#ifdef CONFIG_VT
unblank_screen();
#endif
......@@ -108,6 +104,18 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
int write;
siginfo_t info;
#ifdef CONFIG_CHECKING
{
unsigned long gs;
struct x8664_pda *pda = cpu_pda + stack_smp_processor_id();
rdmsrl(MSR_GS_BASE, gs);
if (gs != (unsigned long)pda) {
wrmsrl(MSR_GS_BASE, pda);
printk("page_fault: wrong gs %lx expected %p\n", gs, pda);
}
}
#endif
/* get the address */
__asm__("movq %%cr2,%0":"=r" (address));
......@@ -129,7 +137,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
if (in_interrupt() || !mm)
if (in_atomic() || !mm)
goto no_context;
again:
......@@ -223,7 +231,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
/* Are we prepared to handle this kernel fault? */
if ((fixup = search_exception_table(regs->rip)) != 0) {
regs->rip = fixup;
if (exception_trace)
if (0 && exception_trace)
printk(KERN_ERR
"%s: fixed kernel exception at %lx address %lx err:%ld\n",
current->comm, regs->rip, address, error_code);
......
......@@ -37,6 +37,8 @@
#include <asm/tlb.h>
#include <asm/mmu_context.h>
unsigned long start_pfn, end_pfn;
mmu_gather_t mmu_gathers[NR_CPUS];
/*
......@@ -49,19 +51,24 @@ void show_mem(void)
{
int i, total = 0, reserved = 0;
int shared = 0, cached = 0;
pg_data_t *pgdat;
struct page *page;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = max_mapnr;
while (i-- > 0) {
for_each_pgdat(pgdat) {
for (i = 0; i < pgdat->node_size; ++i) {
page = pgdat->node_mem_map + i;
total++;
if (PageReserved(mem_map+i))
if (PageReserved(page))
reserved++;
else if (PageSwapCache(mem_map+i))
else if (PageSwapCache(page))
cached++;
else if (page_count(mem_map+i))
shared += page_count(mem_map+i) - 1;
else if (page_count(page))
shared += page_count(page) - 1;
}
}
printk("%d pages of RAM\n", total);
printk("%d reserved pages\n",reserved);
......@@ -264,16 +271,15 @@ void __init paging_init(void)
{
{
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
unsigned int max_dma, low;
unsigned int max_dma;
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
if (low < max_dma)
zones_size[ZONE_DMA] = low;
if (end_pfn < max_dma)
zones_size[ZONE_DMA] = end_pfn;
else {
zones_size[ZONE_DMA] = max_dma;
zones_size[ZONE_NORMAL] = low - max_dma;
zones_size[ZONE_NORMAL] = end_pfn - max_dma;
}
free_area_init(zones_size);
}
......@@ -308,11 +314,15 @@ void __init mem_init(void)
int codesize, reservedpages, datasize, initsize;
int tmp;
printk("mem_init\n");
if (!mem_map)
BUG();
max_mapnr = num_physpages = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
max_low_pfn = end_pfn;
max_pfn = end_pfn;
max_mapnr = num_physpages = end_pfn;
high_memory = (void *) __va(end_pfn * PAGE_SIZE);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
......@@ -323,7 +333,7 @@ void __init mem_init(void)
after_bootmem = 1;
reservedpages = 0;
for (tmp = 0; tmp < max_low_pfn; tmp++)
for (tmp = 0; tmp < end_pfn; tmp++)
/*
* Only count reserved RAM pages
*/
......
......@@ -10,6 +10,7 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
......@@ -157,14 +158,72 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
return NULL;
addr = area->addr;
if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
vfree(addr);
vunmap(addr);
return NULL;
}
return (void *) (offset + (char *)addr);
}
/**
* ioremap_nocache - map bus memory into CPU space
* @offset: bus address of the memory
* @size: size of the resource to map
*
* ioremap_nocache performs a platform specific sequence of operations to
* make bus memory CPU accessible via the readb/readw/readl/writeb/
* writew/writel functions and the other mmio helpers. The returned
* address is not guaranteed to be usable directly as a virtual
* address.
*
* This version of ioremap ensures that the memory is marked uncachable
* on the CPU as well as honouring existing caching rules from things like
* the PCI bus. Note that there are other caches and buffers on many
* busses. In particular driver authors should read up on PCI writes
*
* It's useful if some control registers are in such an area and
* write combining or read caching is not desirable:
*
* Must be freed with iounmap.
*/
void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
{
void *p = __ioremap(phys_addr, size, _PAGE_PCD);
if (!p)
return p;
if (phys_addr + size < virt_to_phys(high_memory)) {
struct page *ppage = virt_to_page(__va(phys_addr));
unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
BUG_ON(phys_addr+size > (unsigned long)high_memory);
BUG_ON(phys_addr + size < phys_addr);
if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) {
iounmap(p);
p = NULL;
}
}
return p;
}
void iounmap(void *addr)
{
if (addr > high_memory)
vfree((void *) (PAGE_MASK & (unsigned long) addr));
struct vm_struct *p;
if (addr <= high_memory)
return;
p = remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
if (!p) {
printk("__iounmap: bad address %p\n", addr);
return;
}
unmap_vm_area(p);
if (p->flags && p->phys_addr < virt_to_phys(high_memory)) {
change_page_attr(virt_to_page(__va(p->phys_addr)),
p->size >> PAGE_SHIFT,
PAGE_KERNEL);
}
kfree(p);
}
......@@ -13,12 +13,15 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
static struct vm_struct * modvmlist = NULL;
void module_unmap (void * addr)
{
struct vm_struct **p, *tmp;
int i;
if (!addr)
return;
......@@ -29,21 +32,33 @@ void module_unmap (void * addr)
for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
kfree(tmp);
return;
goto found;
}
}
printk("Trying to unmap nonexistent module vm area (%p)\n", addr);
return;
found:
unmap_vm_area(tmp);
for (i = 0; i < tmp->nr_pages; i++) {
if (unlikely(!tmp->pages[i]))
BUG();
__free_page(tmp->pages[i]);
}
kfree(tmp->pages);
kfree(tmp);
}
void * module_map (unsigned long size)
{
void * addr;
struct vm_struct **p, *tmp, *area;
struct page **pages;
void * addr;
unsigned int nr_pages, array_size, i;
size = PAGE_ALIGN(size);
if (!size || size > MODULES_LEN) return NULL;
if (!size || size > MODULES_LEN)
return NULL;
addr = (void *) MODULES_VADDR;
for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
......@@ -51,18 +66,53 @@ void * module_map (unsigned long size)
break;
addr = (void *) (tmp->size + (unsigned long) tmp->addr);
}
if ((unsigned long) addr + size >= MODULES_END) return NULL;
if ((unsigned long) addr + size >= MODULES_END)
return NULL;
area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
if (!area) return NULL;
if (!area)
return NULL;
area->size = size + PAGE_SIZE;
area->addr = addr;
area->next = *p;
area->pages = NULL;
area->nr_pages = 0;
area->phys_addr = 0;
*p = area;
if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL, PAGE_KERNEL)) {
module_unmap(addr);
return NULL;
nr_pages = size >> PAGE_SHIFT;
array_size = (nr_pages * sizeof(struct page *));
area->nr_pages = nr_pages;
area->pages = pages = kmalloc(array_size, GFP_KERNEL);
if (!area->pages)
goto fail;
memset(area->pages, 0, array_size);
for (i = 0; i < area->nr_pages; i++) {
area->pages[i] = alloc_page(GFP_KERNEL);
if (unlikely(!area->pages[i]))
goto fail;
}
if (map_vm_area(area, PAGE_KERNEL, &pages)) {
unmap_vm_area(area);
goto fail;
}
return addr;
return area->addr;
fail:
if (area->pages) {
for (i = 0; i < area->nr_pages; i++) {
if (area->pages[i])
__free_page(area->pages[i]);
}
kfree(area->pages);
}
kfree(area);
return NULL;
}
/*
* Copyright 2002 Andi Kleen, SuSE Labs.
* Thanks to Ben LaHaise for precious feedback.
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/io.h>
static inline pte_t *lookup_address(unsigned long address)
{
pgd_t *pgd = pgd_offset_k(address);
pmd_t *pmd;
pte_t *pte;
if (!pgd || !pgd_present(*pgd))
return NULL;
pmd = pmd_offset(pgd, address);
if (!pmd_present(*pmd))
return NULL;
if (pmd_large(*pmd))
return (pte_t *)pmd;
pte = pte_offset_kernel(pmd, address);
if (pte && !pte_present(*pte))
pte = NULL;
return pte;
}
static struct page *split_large_page(unsigned long address, pgprot_t prot)
{
int i;
unsigned long addr;
struct page *base = alloc_pages(GFP_KERNEL, 0);
pte_t *pbase;
if (!base)
return NULL;
address = __pa(address);
addr = address & LARGE_PAGE_MASK;
pbase = (pte_t *)page_address(base);
for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
pbase[i] = pfn_pte(addr >> PAGE_SHIFT,
addr == address ? prot : PAGE_KERNEL);
}
return base;
}
static void flush_kernel_map(void *address)
{
if (address && cpu_has_clflush) {
/* is this worth it? */
int i;
for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
asm volatile("clflush %0" :: "m" (address + i));
} else
asm volatile("wbinvd":::"memory");
__flush_tlb_one(address);
}
/*
* No more special protections in this 2/4MB area - revert to a
* large page again.
*/
static inline void revert_page(struct page *kpte_page, unsigned long address)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t large_pte;
pgd = pgd_offset_k(address);
if (!pgd) BUG();
pmd = pmd_offset(pgd, address);
if (!pmd) BUG();
if ((pmd_val(*pmd) & _PAGE_GLOBAL) == 0) BUG();
large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE);
set_pte((pte_t *)pmd, large_pte);
}
static int
__change_page_attr(unsigned long address, struct page *page, pgprot_t prot,
struct page **oldpage)
{
pte_t *kpte;
struct page *kpte_page;
unsigned kpte_flags;
kpte = lookup_address(address);
if (!kpte) return 0;
kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
kpte_flags = pte_val(*kpte);
if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
if ((kpte_flags & _PAGE_PSE) == 0) {
pte_t old = *kpte;
pte_t standard = mk_pte(page, PAGE_KERNEL);
set_pte(kpte, mk_pte(page, prot));
if (pte_same(old,standard))
atomic_inc(&kpte_page->count);
} else {
struct page *split = split_large_page(address, prot);
if (!split)
return -ENOMEM;
set_pte(kpte,mk_pte(split, PAGE_KERNEL));
}
} else if ((kpte_flags & _PAGE_PSE) == 0) {
set_pte(kpte, mk_pte(page, PAGE_KERNEL));
atomic_dec(&kpte_page->count);
}
if (atomic_read(&kpte_page->count) == 1) {
*oldpage = kpte_page;
revert_page(kpte_page, address);
}
return 0;
}
static inline void flush_map(unsigned long address)
{
#ifdef CONFIG_SMP
smp_call_function(flush_kernel_map, (void *)address, 1, 1);
#endif
flush_kernel_map((void *)address);
}
struct deferred_page {
struct deferred_page *next;
struct page *fpage;
unsigned long address;
};
static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
static inline void save_page(unsigned long address, struct page *fpage)
{
struct deferred_page *df;
df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL);
if (!df) {
flush_map(address);
__free_page(fpage);
} else {
df->next = df_list;
df->fpage = fpage;
df->address = address;
df_list = df;
}
}
/*
* Change the page attributes of an page in the linear mapping.
*
* This should be used when a page is mapped with a different caching policy
* than write-back somewhere - some CPUs do not like it when mappings with
* different caching policies exist. This changes the page attributes of the
* in kernel linear mapping too.
*
* The caller needs to ensure that there are no conflicting mappings elsewhere.
* This function only deals with the kernel linear map.
*
* Caller must call global_flush_tlb() after this.
*/
int change_page_attr(struct page *page, int numpages, pgprot_t prot)
{
int err = 0;
struct page *fpage, *fpage2;
int i;
down_write(&init_mm.mmap_sem);
for (i = 0; i < numpages; i++, page++) {
unsigned long address = (unsigned long)page_address(page);
fpage = NULL;
err = __change_page_attr(address, page, prot, &fpage);
/* Handle kernel mapping too which aliases part of the lowmem */
if (!err && page_to_phys(page) < KERNEL_TEXT_SIZE) {
unsigned long addr2 = __START_KERNEL_map + page_to_phys(page);
fpage2 = NULL;
err = __change_page_attr(addr2, page, prot, &fpage2);
if (fpage2)
save_page(addr2, fpage2);
}
if (fpage)
save_page(address, fpage);
}
up_write(&init_mm.mmap_sem);
return err;
}
void global_flush_tlb(void)
{
struct deferred_page *df, *next_df;
down_read(&init_mm.mmap_sem);
df = xchg(&df_list, NULL);
up_read(&init_mm.mmap_sem);
flush_map((df && !df->next) ? df->address : 0);
for (; df; df = next_df) {
next_df = df->next;
if (df->fpage)
__free_page(df->fpage);
kfree(df);
}
}
EXPORT_SYMBOL(change_page_attr);
EXPORT_SYMBOL(global_flush_tlb);
......@@ -20,6 +20,10 @@
#include <linux/config.h>
#include <asm/atomic.h>
#include <asm/irq.h>
#include <linux/profile.h>
#include <linux/smp.h>
struct hw_interrupt_type;
#endif
/*
......@@ -126,20 +130,23 @@ __asm__( \
"push $" #nr "-256 ; " \
"jmp common_interrupt");
extern unsigned long prof_cpu_mask;
extern unsigned int * prof_buffer;
extern unsigned long prof_len;
extern unsigned long prof_shift;
/*
* x86 profiling function, SMP safe. We might want to do this in
* assembly totally?
*/
static inline void x86_do_profile (unsigned long rip)
static inline void x86_do_profile (struct pt_regs *regs)
{
unsigned long rip;
extern unsigned long prof_cpu_mask;
extern char _stext;
#ifdef CONFIG_PROFILING
extern void x86_profile_hook(struct pt_regs *);
x86_profile_hook(regs);
#endif
if (user_mode(regs))
return;
if (!prof_buffer)
return;
rip = regs->rip;
/*
* Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
* (default is all CPUs.)
......@@ -159,6 +166,11 @@ static inline void x86_do_profile (unsigned long rip)
atomic_inc((atomic_t *)&prof_buffer[rip]);
}
struct notifier_block;
int register_profile_notifier(struct notifier_block * nb);
int unregister_profile_notifier(struct notifier_block * nb);
#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
if (IO_APIC_IRQ(i))
......
......@@ -235,11 +235,6 @@ struct iovec32 {
};
#ifdef __KERNEL__
struct iovec *get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type);
#endif
#endif /* !CONFIG_IA32_SUPPORT */
#endif
......@@ -5,7 +5,7 @@
*/
/*
* This file contains the i386 architecture specific IDE code.
* This file contains the x86_64 architecture specific IDE code.
*/
#ifndef __ASMx86_64_IDE_H
......
......@@ -148,9 +148,18 @@ extern int io_apic_get_redir_entries (int ioapic);
extern int io_apic_set_pci_routing (int ioapic, int pin, int irq);
#endif
#ifdef CONFIG_ACPI_BOOT
extern int io_apic_get_unique_id (int ioapic, int apic_id);
extern int io_apic_get_version (int ioapic);
extern int io_apic_get_redir_entries (int ioapic);
extern int io_apic_set_pci_routing (int ioapic, int pin, int irq);
#endif
#else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0
#endif
void enable_NMI_through_LVT0 (void * dummy);
#endif
#include <linux/ioctl32.h>
#ifndef __x86_64_IPC_H__
#define __x86_64_IPC_H__
#ifndef __x8664_IPC_H__
#define __x8664_IPC_H__
/* dummy */
......
#ifndef __i386_IPCBUF_H__
#define __i386_IPCBUF_H__
#ifndef __x86_64_IPCBUF_H__
#define __x86_64_IPCBUF_H__
/*
* The ipc64_perm structure for i386 architecture.
* The ipc64_perm structure for x86_64 architecture.
* Note extra padding because this structure is passed back and forth
* between kernel and user space.
*
......@@ -26,4 +26,4 @@ struct ipc64_perm
unsigned long __unused2;
};
#endif /* __i386_IPCBUF_H__ */
#endif /* __x86_64_IPCBUF_H__ */
/* $Id: namei.h,v 1.2 2001/07/04 09:08:13 ak Exp $
* linux/include/asm-i386/namei.h
*
* Included from linux/fs/namei.c
*/
#ifndef __X8664_NAMEI_H
#define __X8664_NAMEI_H
......
/*
* linux/include/asm-i386/nmi.h
*/
#ifndef ASM_NMI_H
#define ASM_NMI_H
#include <linux/pm.h>
struct pt_regs;
typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
/**
* set_nmi_callback
*
* Set a handler for an NMI. Only one handler may be
* set. Return 1 if the NMI was handled.
*/
void set_nmi_callback(nmi_callback_t callback);
/**
* unset_nmi_callback
*
* Remove the handler previously set.
*/
void unset_nmi_callback(void);
#ifdef CONFIG_PM
/** Replace the PM callback routine for NMI. */
struct pm_dev * set_nmi_pm_callback(pm_callback callback);
/** Unset the PM callback routine back to the default. */
void unset_nmi_pm_callback(struct pm_dev * dev);
#else
static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
{
return 0;
}
static inline void unset_nmi_pm_callback(struct pm_dev * dev)
{
}
#endif /* CONFIG_PM */
#endif /* ASM_NMI_H */
......@@ -2,7 +2,7 @@
#define _ASMx86_64_PARAM_H
#ifdef __KERNEL__
# define HZ 100 /* Internal kernel timer frequency */
# define HZ 1000 /* Internal kernel timer frequency */
# define USER_HZ 100 /* .. some user interfaces are in "ticks */
#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
#endif
......
......@@ -42,6 +42,7 @@ extern void exception_table_check(void);
extern void acpi_boot_init(char *);
int iommu_setup(char *opt);
#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
#define round_down(x,y) ((x) & ~((y)-1))
......
......@@ -9,6 +9,8 @@
#define __local_bh_enable() \
do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
void do_softirq(void);
#define local_bh_enable() \
do { \
__local_bh_enable(); \
......
......@@ -482,8 +482,10 @@ __SYSCALL(__NR_io_submit, sys_io_submit)
__SYSCALL(__NR_io_cancel, sys_io_cancel)
#define __NR_get_thread_area 211
__SYSCALL(__NR_get_thread_area, sys_get_thread_area)
#define __NR_lookup_dcookie 212
__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
#define __NR_syscall_max __NR_get_thread_area
#define __NR_syscall_max __NR_lookup_dcookie
#ifndef __NO_STUBS
/* user-visible error numbers are in the range -1 - -4095 */
......@@ -503,7 +505,6 @@ do { \
#define __syscall "syscall"
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
type name(void) \
{ \
......
#ifndef IOCTL32_H
#define IOCTL32_H 1
struct file;
int sys_ioctl(unsigned int, unsigned int, unsigned long);
/*
* Register an 32bit ioctl translation handler for ioctl cmd.
*
* handler == NULL: use 64bit ioctl handler.
* arguments to handler: fd: file descriptor
* cmd: ioctl command.
* arg: ioctl argument
* struct file *file: file descriptor pointer.
*/
extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
extern int unregister_ioctl32_conversion(unsigned int cmd);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment