CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
#
# General setup
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HOTPLUG=y
# CONFIG_IKCONFIG is not set
CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
#
# Processor type and features
#
-# CONFIG_X86_PC is not set
+CONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
-CONFIG_X86_CYCLONE_TIMER=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
CONFIG_X86_HIGH_ENTRY=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=32
-CONFIG_SCHED_SMT=y
+# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
-CONFIG_X86_LOCAL_APIC=y
-CONFIG_X86_IO_APIC=y
+# CONFIG_X86_UP_APIC is not set
CONFIG_X86_TSC=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_NONFATAL is not set
-CONFIG_X86_MCE_P4THERMAL=y
CONFIG_TOSHIBA=m
CONFIG_I8K=m
CONFIG_MICROCODE=m
#
CONFIG_EDD=m
# CONFIG_NOHIGHMEM is not set
-# CONFIG_HIGHMEM4G is not set
-CONFIG_HIGHMEM64G=y
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
CONFIG_HIGHMEM=y
-CONFIG_X86_PAE=y
-# CONFIG_NUMA is not set
CONFIG_HIGHPTE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
# CONFIG_EFI is not set
-# CONFIG_IRQBALANCE is not set
-CONFIG_HAVE_DEC_LOCK=y
CONFIG_REGPARM=y
#
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
-CONFIG_PCI_USE_VECTOR=y
CONFIG_PCI_LEGACY_PROC=y
# CONFIG_PCI_NAMES is not set
CONFIG_ISA=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
CONFIG_HOTPLUG_PCI_COMPAQ=m
# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-CONFIG_HOTPLUG_PCI_IBM=m
# CONFIG_HOTPLUG_PCI_ACPI is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
CONFIG_HOTPLUG_PCI_PCIE=m
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
#
# Device Drivers
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
CONFIG_BLK_DEV_IDECS=m
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDETAPE=m
# SCSI low-level drivers
#
CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
# CONFIG_SCSI_7000FASST is not set
CONFIG_SCSI_ACARD=m
CONFIG_SCSI_AHA152X=m
CONFIG_SCSI_SATA_VITESSE=m
CONFIG_SCSI_BUSLOGIC=m
# CONFIG_SCSI_OMIT_FLASHPOINT 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_MD_MULTIPATH=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
#
# Fusion MPT device support
#
# Old SIR device drivers
#
+CONFIG_IRPORT_SIR=m
#
# Old Serial dongle support
#
+# CONFIG_DONGLE_OLD is not set
#
# FIR device drivers
CONFIG_ULTRA=m
CONFIG_SMC9194=m
CONFIG_NET_VENDOR_RACAL=y
+# CONFIG_NI5010 is not set
CONFIG_NI52=m
CONFIG_NI65=m
CONFIG_WINBOND_840=m
CONFIG_DM9102=m
CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_PCMCIA_XIRTULIP is not set
# CONFIG_AT1700 is not set
CONFIG_DEPCA=m
CONFIG_HP100=m
CONFIG_TLAN=m
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
CONFIG_NET_POCKET=y
CONFIG_ATP=m
CONFIG_DE600=m
CONFIG_DE620=m
#
-# Gigabit Ethernet (1000/10000 Mbit)
+# Ethernet (1000 Mbit)
#
-CONFIG_NET_GIGE=y
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_DL2K=m
CONFIG_R8169=m
CONFIG_SK98LIN=m
CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
CONFIG_IXGB=m
CONFIG_IXGB_NAPI=y
CONFIG_S2IO=m
#
# ISDN feature submodules
#
+CONFIG_ISDN_DRV_LOOP=m
#
# ISDN4Linux hardware drivers
CONFIG_ISDN_DRV_SC=m
CONFIG_ISDN_DRV_ACT2000=m
CONFIG_ISDN_DRV_TPAM=m
+CONFIG_HYSDN=m
+CONFIG_HYSDN_CAPI=y
#
# CAPI subsystem
# Active AVM cards
#
CONFIG_CAPI_AVM=y
+CONFIG_ISDN_DRV_AVMB1_B1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCI=m
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+CONFIG_ISDN_DRV_AVMB1_T1ISA=m
+CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
+CONFIG_ISDN_DRV_AVMB1_AVM_CS=m
+CONFIG_ISDN_DRV_AVMB1_T1PCI=m
+CONFIG_ISDN_DRV_AVMB1_C4=m
#
# Active Eicon DIVA Server cards
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
CONFIG_ROCKETPORT=m
# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
CONFIG_SYNCLINK=m
CONFIG_SYNCLINKMP=m
CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
CONFIG_STALDRV=y
+# CONFIG_STALLION is not set
+# CONFIG_ISTALLION is not set
#
# Serial drivers
#
# Ftape, the floppy tape device driver
#
+# CONFIG_FTAPE is not set
CONFIG_AGP=y
CONFIG_AGP_ALI=y
CONFIG_AGP_ATI=y
CONFIG_SYNCLINK_CS=m
CONFIG_MWAVE=m
# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
CONFIG_HANGCHECK_TIMER=m
#
CONFIG_I2C_ALI15X3=m
CONFIG_I2C_AMD756=m
CONFIG_I2C_AMD8111=m
+# CONFIG_I2C_ELEKTOR is not set
CONFIG_I2C_I801=m
CONFIG_I2C_I810=m
CONFIG_I2C_ISA=m
CONFIG_VIDEO_ZORAN_DC30=m
CONFIG_VIDEO_ZORAN_LML33=m
CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_MEYE=m
CONFIG_VIDEO_SAA7134=m
CONFIG_VIDEO_MXB=m
CONFIG_VIDEO_DPC=m
#
# Digital Video Broadcasting Devices
#
-# CONFIG_DVB is not set
+CONFIG_DVB=y
+CONFIG_DVB_CORE=m
+
+#
+# Supported Frontend Modules
+#
+CONFIG_DVB_TWINHAN_DST=m
+CONFIG_DVB_STV0299=m
+# CONFIG_DVB_SP887X is not set
+# CONFIG_DVB_ALPS_TDLB7 is not set
+CONFIG_DVB_ALPS_TDMB7=m
+CONFIG_DVB_ATMEL_AT76C651=m
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_GRUNDIG_29504_491=m
+CONFIG_DVB_GRUNDIG_29504_401=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_VES1X93=m
+# CONFIG_DVB_TDA1004X is not set
+CONFIG_DVB_NXT6000=m
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_SKYSTAR=m
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
CONFIG_VIDEO_SAA7146=m
CONFIG_VIDEO_SAA7146_VV=m
CONFIG_VIDEO_VIDEOBUF=m
CONFIG_FB_HGA=m
CONFIG_FB_HGA_ACCEL=y
CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
CONFIG_FB_MATROX=m
CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
CONFIG_SUN_PARTITION=y
#
# Profiling support
#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_PROFILING is not set
#
# Kernel hacking
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_FRAME_POINTER is not set
-CONFIG_X86_FIND_SMP_CONFIG=y
-CONFIG_X86_MPPARSE=y
#
# Security options
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
-CONFIG_X86_SMP=y
-CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
-CONFIG_X86_TRAMPOLINE=y
-CONFIG_X86_STD_RESOURCES=y
CONFIG_PC=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_GENERIC_ISA_DMA=y
-CONFIG_SMP=y
+# CONFIG_SMP is not set
# CONFIG_HOTPLUG_CPU is not set
CONFIG_SCHED_SMT=y
+# CONFIG_HPET is not set
#
# Code maturity level options
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_IKCONFIG is not set
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
+CONFIG_BINFMT_MISC=y
#
# Device Drivers
# SCSI low-level drivers
#
CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
# CONFIG_SCSI_7000FASST is not set
CONFIG_SCSI_ACARD=m
CONFIG_SCSI_AHA152X=m
CONFIG_MD_RAID6=m
CONFIG_MD_MULTIPATH=m
CONFIG_BLK_DEV_DM=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
CONFIG_DM_CRYPT=m
#
CONFIG_DEPCA=m
CONFIG_HP100=m
# CONFIG_NET_ISA is not set
-# CONFIG_EWRK3 is not set
+CONFIG_EWRK3=m
CONFIG_E2100=m
CONFIG_EEXPRESS=m
CONFIG_EEXPRESS_PRO=m
CONFIG_TLAN=m
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_VELOCITY=m
CONFIG_NET_POCKET=y
CONFIG_ATP=m
CONFIG_DE600=m
#
# Digital Video Broadcasting Devices
#
-# CONFIG_DVB is not set
+CONFIG_DVB=y
CONFIG_DVB_CORE=m
#
CONFIG_VIDEO_SELECT=y
CONFIG_FB_HGA=m
CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
CONFIG_FB_I810=m
CONFIG_FB_I810_GTF=y
CONFIG_FB_MATROX=m
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_RW_DETECT=y
#
# USB Human Interface Devices (HID)
#
# Profiling support
#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_PROFILING is not set
+# CONFIG_OPROFILE is not set
#
# Tux
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
# CONFIG_SECURITY_SELINUX_MLS is not set
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
#
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_PC=y
-# CONFIG_X86_PC is not set
+CONFIG_X86_PC=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
-CONFIG_NR_CPUS=32
+CONFIG_NR_CPUS=8
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_TSC=y
CONFIG_EDD=m
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
-CONFIG_HIGHMEM64G=y
# CONFIG_HIGHMEM64G is not set
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
CONFIG_IBM_ASM=m
CONFIG_M686=y
# CONFIG_NOHIGHMEM is not set
-CONFIG_HIGHMEM64G=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_COMPAQ=m
-CONFIG_HOTPLUG_PCI_IBM=m
+# CONFIG_SMP is not set
+CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
-# CONFIG_EWRK3 is not set
-CONFIG_NR_CPUS=32
-# CONFIG_X86_PC is not set
-CONFIG_X86_GENERICARCH=y
+# CONFIG_PROFILING is not set
+# CONFIG_OPROFILE is not set
D: sonypi, meye drivers, mct_u232 usb serial hacks
S: Paris, France
+N: Matt Porter
+E: mporter@kernel.crashing.org
+D: Motorola PowerPC PReP support
+D: cPCI PowerPC support
+D: Embedded PowerPC 4xx/6xx/7xx/74xx support
+S: Chandler, Arizona 85249
+S: USA
+
N: Frederic Potter
E: fpotter@cirpack.com
D: Some PCI kernel support
S: USA
N: Marcelo W. Tosatti
-E: marcelo@conectiva.com.br
-W: http://bazar.conectiva.com.br/~marcelo/
-D: Miscellaneous kernel hacker (mostly VM/MM work)
-S: Conectiva S.A.
-S: R. Tocantins, 89 - Cristo Rei
-S: 80050-430 - Curitiba - Paraná
+E: marcelo.tosatti@cyclades.com
+D: Miscellaneous kernel hacker
+D: v2.4 kernel maintainer
+D: Current pc300/cyclades maintainer
+S: Cyclades Corporation
+S: Av Cristovao Colombo, 462. Floresta.
+S: Porto Alegre
S: Brazil
N: Stefan Traby
Kernel Memory Layout on ARM Linux
Russell King <rmk@arm.linux.org.uk>
- April 27, 2003 (2.5.68)
+ May 21, 2004 (2.6.6)
This document describes the virtual memory layout which the Linux
kernel uses for ARM processors. It indicates which regions are
CPU supports vector relocation (control
register V bit.)
-ffe00000 fffeffff Free for platform use, not recommended.
+ffc00000 fffeffff DMA memory mapping region. Memory returned
+ by the dma_alloc_xxx functions will be
+ dynamically mapped here.
-ffc00000 ffdfffff 2MB consistent memory mapping.
- Memory returned by the consistent_alloc
- low level function will be dynamically
- mapped here.
+ff000000 ffbfffff Reserved for future expansion of DMA
+ mapping region.
-ff000000 ffbfffff Free for platform use, not recommended.
+VMALLOC_END feffffff Free for platform use, recommended.
-VMALLOC_END ff000000 Free for platform use, recommended.
-
-VMALLOC_START VMALLOC_END vmalloc() / ioremap() space.
+VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will
be dynamically placed in this region.
VMALLOC_START may be based upon the value
of the high_memory variable.
-PAGE_OFFSET high_memory Kernel direct-mapped RAM region.
+PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region.
This maps the platforms RAM, and typically
maps all platform RAM in a 1:1 relationship.
-TASK_SIZE PAGE_OFFSET Kernel module space
+TASK_SIZE PAGE_OFFSET-1 Kernel module space
Kernel modules inserted via insmod are
placed here using dynamic mappings.
-00001000 TASK_SIZE User space mappings
+00001000 TASK_SIZE-1 User space mappings
Per-thread mappings are placed here via
the mmap() system call.
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
To actually register a new binary type, you have to set up a string looking like
-:name:type:offset:magic:mask:interpreter: (where you can choose the ':' upon
+:name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' upon
your needs) and echo it to /proc/sys/fs/binfmt_misc/register.
Here is what the fields mean:
- 'name' is an identifier string. A new /proc file will be created with this
The mask is anded with the byte sequence of the file.
- 'interpreter' is the program that should be invoked with the binary as first
argument (specify the full path)
+ - 'flags' is an optional field that controls several aspects of the invocation
+ of the interpreter. It is a string of capital letters, each controls a certain
+ aspect. The following flags are supported -
+ 'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite the
+ original argv[0] with the full path to the binary. When this flag is
+ included, binfmt_misc will add an argument to the argument vector for
+ this purpose, thus preserving the original argv[0].
+ 'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path
+ of the binary to the interpreter as an argument. When this flag is
+ included, binfmt_misc will open the file for reading and pass its
+ descriptor as an argument, instead of the full path, thus allowing
+ the interpreter to execute non-readable binaries. This feature should
+ be used with care - the interpreter has to be trusted not to emit
+ the contents of the non-readable binary.
+ 'C' - credentials. Currently, the behavior of binfmt_misc is to calculate
+ the credentials and security token of the new process according to
+ the interpreter. When this flag is included, these attributes are
+ calculated according to the binary. It also implies the 'O' flag.
+ This feature should be used with care as the interpreter
+ will run with root permissions when a setuid binary owned by root
+ is run with binfmt_misc.
+
There are some restrictions:
- the whole register string may not exceed 255 characters
write a wrapper script for it. See Documentation/java.txt for an
example.
-Your interpreter should NOT look in the PATH for the filename; the
-kernel passes it the full filename to use. Using the PATH can cause
-unexpected behaviour and be a security hazard.
+Your interpreter should NOT look in the PATH for the filename; the kernel
+passes it the full filename (or the file descriptor) to use. Using $PATH can
+cause unexpected behaviour and can be a security hazard.
There is a web page about binfmt_misc at
1/(32.141E-6 s) = 31.113E3 Hz
A full screen counts 480 (yres) lines, but we have to consider the vertical
-retrace too (e.g. 49 `pixels'). So a full screen will take
+retrace too (e.g. 49 `lines'). So a full screen will take
(480+49)*32.141E-6 s = 17.002E-3 s
all of the ancestors of that filesystem object are also in the dcache.
As normal access is by filename this prefix is created naturally and
maintained easily (by each object maintaining a reference count on
-it's parent).
+its parent).
However when objects are included into the dcache by interpreting a
filehandle fragment, there is no automatic creation of a path prefix
2/ The dcache must be prepared for a newly found (via ->lookup) directory
to already have a (non-connected) dentry, and must be able to move
that dentry into place (based on the parent and name in the
- ->lookup). This is particuarly needed for directories as
+ ->lookup). This is particularly needed for directories as
it is a dcache invariant that directories only have one dentry.
To implement these features, the dcache has:
-a/ A dentry flag DCACHE_DISCONNECTED which is set on
- and dentry that might not be part of the proper prefix.
+a/ A dentry flag DCACHE_DISCONNECTED which is set on
+ any dentry that might not be part of the proper prefix.
This is set when anonymous dentries are created, and cleared when a
- dentry is noticed to be a child on a dentry which is in the proper
+ dentry is noticed to be a child of a dentry which is in the proper
prefix.
b/ A per-superblock list "s_anon" of dentries which are the roots of
get_name. When given a parent dentry and a child dentry, this
should find a name in the directory identified by the parent
dentry, which leads to the object identified by the child dentry.
- If no get_name function is supplied, a default implementation
- which used vfs_readdir to find potential names, and matches inode
- numbers to find the correct match.
+ If no get_name function is supplied, a default implementation is
+ provided which uses vfs_readdir to find potential names, and
+ matches inode numbers to find the correct match.
get_parent. When given a dentry for a directory, this should return
a dentry for the parent. Quite possibly the parent dentry will
->lookup("..") is *not* used as a default as it can leave ".."
entries in the dcache which are too messy to work with.
- get_dentry. When given a opaque datum, this should find the
+ get_dentry. When given an opaque datum, this should find the
implied object and create a dentry for it (possibly with
d_alloc_anon).
The opaque datum is whatever is passed down by the decode_fh
fragment.
decode_fh passes two datums through find_exported_dentry. One that
should be used to identify the target object, and one that can be
- used to identify the objects parent, should that be necessary.
+ used to identify the object's parent, should that be necessary.
The default get_dentry function assumes that the datum contains an
inode number and a generation number, and it attempts to get the
inode using "iget" and check it's validity by matching the
passed them to find_exported_dentry.
-A filehandle fragment consists of an array of 1 or more 4byte words.
-Together with a one byte "type".
+A filehandle fragment consists of an array of 1 or more 4byte words,
+together with a one byte "type".
The decode_fh routine should not depend on the stated size that is
passed to it. This size may be larger than the original filehandle
generated by encode_fh, in which case it will have been padded with
If the filesystem is not called for "sync" and it determines that it
would need to block against in-progress I/O to be able to start new I/O
-against the page the filesystem shoud redirty the page (usually with
-__set_page_dirty_nobuffers()), then unlock the page and return zero.
+against the page the filesystem should redirty the page with
+redirty_page_for_writepage(), then unlock the page and return zero.
This may also be done to avoid internal deadlocks, but rarely.
If the filesytem is called for sync then it must wait on any
in-progress I/O and then start new I/O.
The filesystem should unlock the page synchronously, before returning
-to the caller. If the page has write I/O underway against it,
-writepage() should run SetPageWriteback() against the page prior to
-unlocking it. The write I/O completion handler should run
-end_page_writeback() against the page.
-
-That is: after 2.5.12, pages which are under writeout are *not* locked.
+to the caller.
+
+Unless the filesystem is going to redirty_page_for_writepage(), unlock the page
+and return zero, writepage *must* run set_page_writeback() against the page,
+followed by unlocking it. Once set_page_writeback() has been run against the
+page, write I/O can be submitted and the write I/O completion handler must run
+end_page_writeback() once the I/O is complete. If no I/O is submitted, the
+filesystem must run end_page_writeback() against the page before returning from
+writepage.
+
+That is: after 2.5.12, pages which are under writeout are *not* locked. Note,
+if the filesystem needs the page to be locked during writeout, that is ok, too,
+the page is allowed to be unlocked at any point in time between the calls to
+set_page_writeback() and end_page_writeback().
+
+Note, failure to run either redirty_page_for_writepage() or the combination of
+set_page_writeback()/end_page_writeback() on a page submitted to writepage
+will leave the page itself marked clean but it will be tagged as dirty in the
+radix tree. This incoherency can lead to all sorts of hard-to-debug problems
+in the filesystem like having dirty inodes at umount and losing written data.
->sync_page() locking rules are not well-defined - usually it is called
with lock on page, but that is not guaranteed. Considering the currently
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
+2.1.14:
+ - Fix an NFSd caused deadlock reported by several users.
+2.1.13:
+ - Implement writing of inodes (access time updates are not implemented
+ yet so mounting with -o noatime,nodiratime is enforced).
+ - Enable writing out of resident files so you can now overwrite any
+ uncompressed, unencrypted, nonsparse file as long as you do not
+ change the file size.
+ - Add housekeeping of ntfs system files so that ntfsfix no longer needs
+ to be run after writing to an NTFS volume.
+ NOTE: This still leaves quota tracking and user space journalling on
+ the side but they should not cause data corruption. In the worst
+ case the charged quotas will be out of date ($Quota) and some
+ userspace applications might get confused due to the out of date
+ userspace journal ($UsnJrnl).
2.1.12:
- Fix the second fix to the decompression engine from the 2.1.9 release
and some further internals cleanups.
devices Available devices (block and character)
dma Used DMS channels
filesystems Supported filesystems
- driver Various drivers grouped here, currently rtc (2.4)
+ driver Various drivers grouped here, currently rtc (2.4) and hpet (2.6)
execdomains Execdomains, related to security (2.4)
fb Frame Buffer devices (2.4)
fs File system parameters, currently nfs/exports (2.4)
Writing to this file results in a flush of the routing cache.
-gc_elastic, gc_interval, gc_min_interval, gc_tresh, gc_timeout
+gc_elasticity, gc_interval, gc_min_interval, gc_tresh, gc_timeout,
+gc_thresh, gc_thresh1, gc_thresh2, gc_thresh3
--------------------------------------------------------------
Values to control the frequency and behavior of the garbage collection
allowing ide-floppy, ide-tape, and ide-cdrom|writers
to use ide-scsi emulation on a device specific option.
+ "hdx=stroke" : Should you have a system w/ an AWARD Bios and your
+ drives are larger than 32GB and it will not boot,
+ one is required to perform a few OEM operations first.
+ The option is called "stroke" because it allows one
+ to "soft clip" the drive to work around a barrier
+ limit.
+
"idebus=xx" : inform IDE driver of VESA/PCI bus speed in MHz,
where "xx" is between 20 and 66 inclusive,
used when tuning chipset PIO modes.
<mailto:michael.klein@puffin.lb.shuttle.de>
0xDD 00-3F ZFCP device driver see drivers/s390/scsi/
<mailto:aherrman@de.ibm.com>
+0xF3 00-3F video/sisfb.h sisfb (in development)
+ <mailto:thomas@winischhofer.net>
psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports
per second.
psmouse.resetafter=
- [HW,MOUSE] Try to reset Synaptics Touchpad after so many
- bad packets (0 = never).
+ [HW,MOUSE] Try to reset the device after so many bad packets
+ (0 = never).
psmouse.resolution=
[HW,MOUSE] Set desired mouse resolution, in dpi.
psmouse.smartscroll=
- information on the 3Com EtherLink Plus (3c505) driver.
6pack.txt
- info on the 6pack protocol, an alternative to KISS for AX.25
-8139too.txt
- - info on the 8139too driver for RTL-8139 based network cards.
Configurable
- info on some of the configurable network parameters
DLINK.txt
Disable Path MTU Discovery.
default FALSE
+min_pmtu - INTEGER
+ default 562 - minimum discovered Path MTU
+
+mtu_expires - INTEGER
+ Time, in seconds, that cached PMTU information is kept.
+
+min_adv_mss - INTEGER
+ The advertised MSS depends on the first hop route MTU, but will
+ never be lower than this setting.
+
IP Fragmentation:
ipfrag_high_thresh - INTEGER
conections.
Default: 7
+
+tcp_frto - BOOLEAN
+ Enables F-RTO, an enhanced recovery algorithm for TCP retransmission
+ timeouts. It is particularly beneficial in wireless environments
+ where packet loss is typically due to random radio interference
+ rather than intermediate router congestion.
+
+somaxconn - INTEGER
+ Limit of socket listen() backlog, known in userspace as SOMAXCONN.
+ Defaults to 128. See also tcp_max_syn_backlog for additional tuning
+ for TCP sockets.
+
+IP Variables:
+
ip_local_port_range - 2 INTEGERS
Defines the local port range that is used by TCP and UDP to
choose the local port. The first number is the first, the
The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface}
+app_solicit - INTEGER
+ The maximum number of probes to send to the user space ARP daemon
+ via netlink before dropping back to multicast probes (see
+ mcast_solicit). Defaults to 0.
+
+disable_policy - BOOLEAN
+ Disable IPSEC policy (SPD) for this interface
+
+disable_xfrm - BOOLEAN
+ Disable IPSEC encryption on this interface, whatever the policy
+
+
+
tag - INTEGER
Allows you to write a number, which can be used as required.
Default value is 0.
disabled if local forwarding is enabled.
autoconf - BOOLEAN
- Configure link-local addresses using L2 hardware addresses.
+ Autoconfigure addresses using Prefix Information in Router
+ Advertisements.
- Default: TRUE
+ Functional default: enabled if accept_ra is enabled.
+ disabled if accept_ra is disabled.
dad_transmits - INTEGER
The amount of Duplicate Address Detection probes to send.
Default: 1
+UNDOCUMENTED:
+
+dev_weight FIXME
+discovery_slots FIXME
+discovery_timeout FIXME
+fast_poll_increase FIXME
+ip6_queue_maxlen FIXME
+lap_keepalive_time FIXME
+lo_cong FIXME
+max_baud_rate FIXME
+max_dgram_qlen FIXME
+max_noreply_time FIXME
+max_tx_data_size FIXME
+max_tx_window FIXME
+min_tx_turn_time FIXME
+mod_cong FIXME
+no_cong FIXME
+no_cong_thresh FIXME
+slot_timeout FIXME
+warn_noreply_time FIXME
+
$Id: ip-sysctl.txt,v 1.20 2001/12/13 09:00:18 davem Exp $
-
-DaveM:
-
-If you agree with it I will send two small patches to modify
-kernel's configure help.
-
- Ulisses
-
--------------------------------------------------------------------------------
+ ABSTRACT
--------------------------------------------------------------------------------
Jesse Brandeburg, for fixing my grammathical/spelling errors
->>> EOF
--
-To unsubscribe from this list: send the line "unsubscribe linux-net" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
\ No newline at end of file
L: linux-net@vger.kernel.org
S: Maintained
+3W-XXXX ATA-RAID CONTROLLER DRIVER
+P: Adam Radford
+M: linuxraid@amcc.com
+L: linux-scsi@vger.kernel.org
+W: http://www.amcc.com
+S: Supported
+
+3W-9XXX SATA-RAID CONTROLLER DRIVER
+P: Adam Radford
+M: linuxraid@amcc.com
+L: linux-scsi@vger.kernel.org
+W: http://www.amcc.com
+S: Supported
+
53C700 AND 53C700-66 SCSI DRIVER
P: James E.J. Bottomley
M: James.Bottomley@HansenPartnership.com
IA64 (Itanium) PLATFORM
P: David Mosberger-Tang
M: davidm@hpl.hp.com
-L: linux-ia64@linuxia64.org
-W: http://www.linuxia64.org/
+L: linux-ia64@vger.kernel.org
+W: http://www.ia64-linux.org/
S: Maintained
SN-IA64 (Itanium) SUB-PLATFORM
P: Jesse Barnes
M: jbarnes@sgi.com
L: linux-altix@sgi.com
-L: linux-ia64@linuxia64.org
+L: linux-ia64@vger.kernel.org
W: http://www.sgi.com/altix
S: Maintained
L: linuxppc-dev@lists.linuxppc.org
S: Maintained
+LINUX FOR POWERPC EMBEDDED PPC4XX
+P: Matt Porter
+M: mporter@kernel.crashing.org
+W: http://www.penguinppc.org/
+L: linuxppc-embedded@lists.linuxppc.org
+S: Maintained
+
LLC (802.2)
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
NCP FILESYSTEM
P: Petr Vandrovec
M: vandrove@vc.cvut.cz
-P: Volker Lendecke
-M: vl@kki.org
L: linware@sh.cvut.cz
S: Maintained
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 6
+SUBLEVEL = 7
EXTRAVERSION = -prep
NAME=Zonked Quokka
buildcheck:
$(PERL) scripts/reference_discarded.pl
+ $(PERL) scripts/reference_init.pl
endif #ifeq ($(config-targets),1)
endif #ifeq ($(mixed-targets),1)
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
initrd_end,
phys_to_virt(PFN_PHYS(max_low_pfn)));
} else {
- nid = NODE_DATA(kvaddr_to_nid(initrd_start));
- reserve_bootmem_node(nid,
+ nid = kvaddr_to_nid(initrd_start);
+ reserve_bootmem_node(NODE_DATA(nid),
virt_to_phys((void *)initrd_start),
INITRD_SIZE);
}
# Select various configuration options depending on the machine type
config DISCONTIGMEM
bool
- depends on ARCH_EDB7211 || ARCH_SA1100 || ARCH_LH7A40X
+ depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_SROMLL)
default y
help
- Say Y to upport efficient handling of discontiguous physical memory,
+ Say Y to support efficient handling of discontiguous physical memory,
for architectures which are either NUMA (Non-Uniform Memory Access)
or have huge holes in the physical address space for other reasons.
See <file:Documentation/vm/numa> for more.
If you do not feel you need a faster FP emulation you should better
choose NWFPE.
+config VFP
+ bool "VFP-format floating point maths"
+ help
+ Say Y to include VFP support code in the kernel. This is needed
+ if your hardware includes a VFP unit.
+
+ Please see <file:Documentation/arm/VFP/release-notes.txt> for
+ release notes and additional status information.
+
+ Say N if your target does not have VFP hardware.
+
source "fs/Kconfig.binfmt"
source "drivers/base/Kconfig"
config ALIGNMENT_TRAP
bool
depends on CPU_32
- default y
+ default y if !ARCH_EBSA110
help
ARM processors can not fetch/store information which is not
naturally aligned on the bus, i.e., a 4 byte fetch must start at an
endif
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
+core-$(CONFIG_VFP) += arch/arm/vfp/
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
.macro writeb, rb
strb \rb, [r3, #0]
.endm
+#elif defined(CONFIG_ARCH_OMAP)
+ .macro loadsp, rb
+ mov \rb, #0xff000000 @ physical base address
+ add \rb, \rb, #0x00fb0000
+#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
+ add \rb, \rb, #0x00000800
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+ add \rb, \rb, #0x00009000
+#endif
+ .endm
+ .macro writeb, rb
+ strb \rb, [r3]
+ .endm
#else
#error no serial architecture defined
#endif
# Automatically generated make config: don't edit
#
CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
+CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_STANDALONE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
#
# Loadable module support
#
CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
#
# System Type
#
-# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_ADIFCC is not set
# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
CONFIG_ARCH_EBSA110=y
-# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_CAMELOT is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-
-#
-# CLPS711X/EP721X Implementations
+# Processor Type
#
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
+CONFIG_CPU_SA110=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_CACHE_V4WB=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WB=y
#
-# Processor Type
+# Processor Features
#
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM1020 is not set
-CONFIG_CPU_SA110=y
-# CONFIG_CPU_SA1100 is not set
-# CONFIG_DISCONTIGMEM is not set
#
# General setup
#
-# CONFIG_PCI is not set
CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-CONFIG_HOTPLUG=y
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
#
# PCMCIA/CardBus support
#
CONFIG_PCMCIA=m
-CONFIG_I82365=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_I82365=m
# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSCTL=y
+CONFIG_PCMCIA_PROBE=y
+
+#
+# At least one math emulation must be selected
+#
CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
CONFIG_FPE_FASTFPE=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=y
# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
# CONFIG_PM is not set
+# CONFIG_PREEMPT is not set
# CONFIG_ARTHUR is not set
CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
CONFIG_LEDS=y
#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_CML1=y
CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_PC_PCMCIA is not set
# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_SUNBPP is not set
# CONFIG_PARPORT_OTHER is not set
CONFIG_PARPORT_1284=y
#
-# Plug and Play configuration
+# Plug and Play support
#
# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
#
# Block devices
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_RAM=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_BLK_DEV_LVM is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_FILTER is not set
CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_RTNETLINK=y
-CONFIG_NETLINK=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_FWMARK=y
CONFIG_IP_ROUTE_NAT=y
# CONFIG_IP_ROUTE_MULTIPATH is not set
# CONFIG_IP_ROUTE_TOS is not set
CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_ROUTE_LARGE_TABLES is not set
CONFIG_IP_PNP=y
# CONFIG_IP_PNP_DHCP is not set
CONFIG_IP_PNP_BOOTP=y
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
-CONFIG_INET_ECN=y
CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_TUNNEL is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
#
-# IP: Netfilter Configuration
+# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=y
CONFIG_IP_NF_FTP=y
CONFIG_IP_NF_IRC=y
+# CONFIG_IP_NF_TFTP is not set
+# CONFIG_IP_NF_AMANDA is not set
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_LIMIT=y
-# CONFIG_IP_NF_MATCH_MAC is not set
+CONFIG_IP_NF_MATCH_IPRANGE=y
+CONFIG_IP_NF_MATCH_MAC=y
+CONFIG_IP_NF_MATCH_PKTTYPE=y
CONFIG_IP_NF_MATCH_MARK=y
CONFIG_IP_NF_MATCH_MULTIPORT=y
CONFIG_IP_NF_MATCH_TOS=y
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
+CONFIG_IP_NF_MATCH_RECENT=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_DSCP=y
+CONFIG_IP_NF_MATCH_AH_ESP=y
+CONFIG_IP_NF_MATCH_LENGTH=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_MATCH_TCPMSS=y
+CONFIG_IP_NF_MATCH_HELPER=y
CONFIG_IP_NF_MATCH_STATE=y
-CONFIG_IP_NF_MATCH_UNCLEAN=y
+CONFIG_IP_NF_MATCH_CONNTRACK=y
# CONFIG_IP_NF_MATCH_OWNER is not set
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_SAME=y
+# CONFIG_IP_NF_NAT_LOCAL is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
CONFIG_IP_NF_NAT_IRC=y
CONFIG_IP_NF_NAT_FTP=y
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_TARGET_TOS=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_DSCP=y
CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_CLASSIFY=y
CONFIG_IP_NF_TARGET_LOG=y
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-CONFIG_IPV6=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=y
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_RAW is not set
#
-# IPv6: Netfilter Configuration
+# IPv6: Netfilter Configuration
#
+# CONFIG_IP6_NF_QUEUE is not set
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_LIMIT=y
+CONFIG_IP6_NF_MATCH_MAC=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_MULTIPORT=y
+# CONFIG_IP6_NF_MATCH_OWNER is not set
CONFIG_IP6_NF_MATCH_MARK=y
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+CONFIG_IP6_NF_MATCH_AHESP=y
+CONFIG_IP6_NF_MATCH_LENGTH=y
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
CONFIG_IP6_NF_FILTER=y
+# CONFIG_IP6_NF_TARGET_LOG is not set
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_TARGET_MARK=y
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
+# CONFIG_IP6_NF_RAW is not set
#
-#
+# SCTP Configuration (EXPERIMENTAL)
#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
-# CONFIG_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_SCHED is not set
#
-# Network device support
+# Network testing
#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-# CONFIG_NET_SB1000 is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
CONFIG_ARM_AM79C961A=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
#
# Ethernet (1000 Mbit)
#
-# CONFIG_ACENIC is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
#
-# Wireless LAN (non-hamradio)
+# Ethernet (10000 Mbit)
#
-# CONFIG_NET_RADIO is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
#
-# Wan interfaces
+# Wireless LAN (non-hamradio)
#
-# CONFIG_WAN is not set
+# CONFIG_NET_RADIO is not set
#
# PCMCIA network device support
# CONFIG_PCMCIA_NMCLAN is not set
# CONFIG_PCMCIA_SMC91C92 is not set
# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
+# CONFIG_PCMCIA_AXNET is not set
#
-# Amateur Radio support
+# Wan interfaces
#
-# CONFIG_HAMRADIO is not set
+# CONFIG_WAN is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
-# IrDA (infrared) support
+# SCSI device support
#
-# CONFIG_IRDA is not set
+# CONFIG_SCSI is not set
#
-# ATA/IDE/MFM/RLL support
+# Fusion MPT device support
#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
#
-# SCSI support
+# IEEE 1394 (FireWire) support
#
-# CONFIG_SCSI is not set
+# CONFIG_IEEE1394 is not set
#
# I2O device support
#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
#
# ISDN subsystem
# CONFIG_ISDN is not set
#
-# Input core support
+# Input device support
#
# CONFIG_INPUT is not set
#
-# Character devices
+# Userland interfaces
#
-# CONFIG_VT is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_EXTENDED=y
-# CONFIG_SERIAL_MANY_PORTS is not set
-# CONFIG_SERIAL_SHARE_IRQ is not set
-# CONFIG_SERIAL_DETECT_IRQ is not set
-# CONFIG_SERIAL_MULTIPORT is not set
-# CONFIG_HUB6 is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
#
-# I2C support
+# Input I/O drivers
#
-# CONFIG_I2C is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
#
-# Mice
+# Input Device Drivers
#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
#
-# Joysticks
+# Character devices
#
-# CONFIG_JOYSTICK is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
#
-# Input core support is needed for joysticks
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
# CONFIG_QIC02_TAPE is not set
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
#
# Watchdog Cards
#
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
CONFIG_SOFT_WATCHDOG=y
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
+
+#
+# ISA-based Watchdog Cards
+#
# CONFIG_PCWATCHDOG is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_60XX_WDT is not set
# CONFIG_MIXCOMWD is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_INTEL_RNG is not set
+# CONFIG_WDT is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
#
# PCMCIA character devices
#
-# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
#
# File systems
#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_ROMFS_FS is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_FAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-CONFIG_MINIX_FS=y
# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_EXT2_FS is not set
# CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
#
# Network File Systems
#
-# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-CONFIG_ROOT_NFS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
+CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
#
# Partition Types
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_NEC98_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-# CONFIG_SMB_NLS is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
# CONFIG_NLS is not set
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Misc devices
+#
+
#
# USB support
#
-# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
#
# Kernel hacking
#
CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_INFO is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_DEBUG_KERNEL is not set
+
+#
+# Security options
+#
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
#
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
#
# System Type
#
# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_ANAKIN is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_CAMELOT is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
CONFIG_ARCH_LH7A40X=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
#
# CLPS711X/EP721X Implementations
#
#
-# Intel PXA250/210 Implementations
+# Intel IXP4xx Implementation Options
+#
+
+#
+# IXP4xx Platforms
+#
+
+#
+# IXP4xx Options
+#
+
+#
+# Intel PXA2xx Implementations
#
#
# SA11x0 Implementations
#
+#
+# TI OMAP Implementations
+#
+
+#
+# OMAP Core Type
+#
+
+#
+# OMAP Board Type
+#
+
+#
+# OMAP Feature Selections
+#
+
+#
+# S3C2410 Implementations
+#
+
#
# LH7A40X Implementations
#
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
# CONFIG_NETFILTER is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
-CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
#
# Ethernet (10000 Mbit)
#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
#
-# Wireless LAN (non-hamradio)
+# Token Ring devices
#
-# CONFIG_NET_RADIO is not set
#
-# Token Ring devices
+# Wireless LAN (non-hamradio)
#
-# CONFIG_SHAPER is not set
+# CONFIG_NET_RADIO is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# ATA/ATAPI/MFM/RLL support
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
+CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
# CONFIG_BLK_DEV_HD is not set
#
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
CONFIG_LOCKD_V4=y
# CONFIG_EXPORTFS is not set
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_GSS is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
#
# Misc devices
#
# Library routines
#
CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
#
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_HOTPLUG is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
CONFIG_FUTEX=y
# CONFIG_EPOLL is not set
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
#
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_CAMELOT is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_SHARK is not set
CONFIG_ARCH_LH7A40X=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE_PB is not set
#
# CLPS711X/EP721X Implementations
#
#
-# Intel PXA250/210 Implementations
+# Intel IXP4xx Implementation Options
+#
+
+#
+# IXP4xx Platforms
+#
+
+#
+# IXP4xx Options
+#
+
+#
+# Intel PXA2xx Implementations
#
#
# TI OMAP Implementations
#
+#
+# OMAP Core Type
+#
+
+#
+# OMAP Board Type
+#
+
#
# OMAP Feature Selections
#
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
# CONFIG_NETFILTER is not set
#
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
#
# Ethernet (10000 Mbit)
#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
#
-# Wireless LAN (non-hamradio)
+# Token Ring devices
#
-# CONFIG_NET_RADIO is not set
#
-# Token Ring devices
+# Wireless LAN (non-hamradio)
#
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
+# CONFIG_NET_RADIO is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# ATA/ATAPI/MFM/RLL support
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
+CONFIG_IDE_ARM=y
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# SCSI low-level drivers
#
# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_DEBUG is not set
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_TEST is not set
#
# Library routines
#
CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
- ldr \rx, =0x80000700 @ physical base address
+ mov \rx, #0x00000700 @ offset from base
+ orreq \rx, \rx, #0x80000000 @ physical base
orrne \rx, \rx, #0xf8000000 @ virtual base
.endm
#include <asm/thread_info.h>
#include <asm/glue.h>
#include <asm/ptrace.h>
+#include <asm/vfpmacros.h>
#include "entry-header.S"
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \base, =IO_ADDRESS(OMAP_IH1_BASE)
- ldr \irqnr, [\base, #IRQ_ITR]
- ldr \tmp, [\base, #IRQ_MIR]
+ ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
+ ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET]
mov \irqstat, #0xffffffff
bic \tmp, \irqstat, \tmp
tst \irqnr, \tmp
beq 1510f
- ldr \irqnr, [\base, #IRQ_SIR_FIQ]
+ ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
cmp \irqnr, #0
- ldreq \irqnr, [\base, #IRQ_SIR_IRQ]
+ ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
cmpeq \irqnr, #INT_IH2_IRQ
ldreq \base, =IO_ADDRESS(OMAP_IH2_BASE)
- ldreq \irqnr, [\base, #IRQ_SIR_IRQ]
+ ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
addeqs \irqnr, \irqnr, #32
1510:
.endm
mov pc, lr @ CP#7
mov pc, lr @ CP#8
mov pc, lr @ CP#9
+#ifdef CONFIG_VFP
+ b do_vfp @ CP#10 (VFP)
+ b do_vfp @ CP#11 (VFP)
+#else
mov pc, lr @ CP#10 (VFP)
mov pc, lr @ CP#11 (VFP)
+#endif
mov pc, lr @ CP#12
mov pc, lr @ CP#13
mov pc, lr @ CP#14 (Debug)
ldr r3, [r2, #TI_CPU_DOMAIN]!
stmia ip, {r4 - sl, fp, sp, lr} @ Store most regs on stack
mcr p15, 0, r3, c3, c0, 0 @ Set domain register
+#ifdef CONFIG_VFP
+ @ Always disable VFP so we can lazily save/restore the old
+ @ state. This occurs in the context of the previous thread.
+ VFPFMRX r4, FPEXC
+ bic r4, r4, #FPEXC_ENABLE
+ VFPFMXR FPEXC, r4
+#endif
ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
__INIT
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
memset(thread->used_cp, 0, sizeof(thread->used_cp));
memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
fp_init(&thread->fpstate);
+#if defined(CONFIG_VFP)
+ vfp_flush_thread(&thread->vfpstate);
+#endif
}
void release_thread(struct task_struct *dead_task)
{
+#if defined(CONFIG_VFP)
+ vfp_release_thread(&dead_task->thread_info->vfpstate);
+#endif
}
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
+ goto badframe;
+
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
+ stack_t stack;
int err = 0;
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
__put_user_error(&frame->uc, &frame->puc, err);
err |= copy_siginfo_to_user(&frame->info, info);
- /* Clear all the bits of the ucontext we don't use. */
- err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+ __put_user_error(0, &frame->uc.uc_flags, err);
+ __put_user_error(NULL, &frame->uc.uc_link, err);
+
+ memset(&stack, 0, sizeof(stack));
+ stack.ss_sp = (void *)current->sas_ss_sp;
+ stack.ss_flags = sas_ss_flags(regs->ARM_sp);
+ stack.ss_size = current->sas_ss_size;
+ err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack));
err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/
regs, set->sig[0]);
lib-$(CONFIG_ARCH_CLPS7500) += io-acorn.o
lib-$(CONFIG_ARCH_L7200) += io-acorn.o
lib-$(CONFIG_ARCH_SHARK) += io-shark.o
-lib-$(CONFIG_ARCH_CLPS711X) += io-acorn.o
$(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S
$(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S
.text
.align
- .equ diff_pcio_base, PCIO_BASE - IO_BASE
-
- .macro outw2 rd
- mov r8, \rd, lsl #16
- orr r8, r8, r8, lsr #16
- str r8, [r3, r0, lsl #2]
- mov r8, \rd, lsr #16
- orr r8, r8, r8, lsl #16
- str r8, [r3, r0, lsl #2]
- .endm
-
- .macro inw2 rd, mask, temp
- ldr \rd, [r0]
- and \rd, \rd, \mask
- ldr \temp, [r0]
- orr \rd, \rd, \temp, lsl #16
- .endm
-
- .macro addr rd
- tst \rd, #0x80000000
- mov \rd, \rd, lsl #2
- add \rd, \rd, #IO_BASE
- addeq \rd, \rd, #diff_pcio_base
- .endm
-
.iosl_warning:
.ascii "<4>insl/outsl not implemented, called from %08lX\0"
.align
+if ARCH_CLPS711X
menu "CLPS711X/EP721X Implementations"
config ARCH_AUTCPU12
bool "AUTCPU12"
- depends on ARCH_CLPS711X
help
Say Y if you intend to run the kernel on the autronix autcpu12
board. This board is based on a Cirrus Logic CS89712.
config ARCH_CDB89712
bool "CDB89712"
- depends on ARCH_CLPS711X
help
This is an evaluation board from Cirrus for the CS89712 processor.
The board includes 2 serial ports, Ethernet, IRDA, and expansion
config ARCH_CEIVA
bool "CEIVA"
- depends on ARCH_CLPS711X
help
Say Y here if you intend to run this kernel on the Ceiva/Polaroid
PhotoMax Digital Picture Frame.
config ARCH_CLEP7312
bool "CLEP7312"
- depends on ARCH_CLPS711X
config ARCH_EDB7211
bool "EDB7211"
- depends on ARCH_CLPS711X
help
Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
evaluation board.
config ARCH_P720T
bool "P720T"
- depends on ARCH_CLPS711X
help
Say Y here if you intend to run this kernel on the ARM Prospector
720T.
config ARCH_FORTUNET
bool "FORTUNET"
- depends on ARCH_CLPS711X
# XXX Maybe these should indicate register compatibility
# instead of being mutually exclusive.
endmenu
+endif
u32 ret, a = __isamem_convert_addr(addr);
if ((int)addr & 1)
- ret = __raw_getl(a);
+ ret = __raw_readl(a);
else
- ret = __raw_getb(a);
+ ret = __raw_readb(a);
return ret;
}
if ((int)addr & 1)
BUG();
- return __raw_getw(a);
+ return __raw_readw(a);
}
u32 __readl(void *addr)
if ((int)addr & 3)
BUG();
- ret = __raw_getw(a);
- ret |= __raw_getw(a + 4) << 16;
+ ret = __raw_readw(a);
+ ret |= __raw_readw(a + 4) << 16;
return ret;
}
u32 a = __isamem_convert_addr(addr);
if ((int)addr & 1)
- __raw_putl(val, a);
+ __raw_writel(val, a);
else
- __raw_putb(val, a);
+ __raw_writeb(val, a);
}
void __writew(u16 val, void *addr)
if ((int)addr & 1)
BUG();
- __raw_putw(val, a);
+ __raw_writew(val, a);
}
void __writel(u32 val, void *addr)
if ((int)addr & 3)
BUG();
- __raw_putw(val, a);
- __raw_putw(val >> 16, a + 4);
+ __raw_writew(val, a);
+ __raw_writew(val >> 16, a + 4);
}
EXPORT_SYMBOL(__writeb);
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- ret = __raw_getb(ISAIO_BASE + (port << 2));
+ ret = __raw_readb(ISAIO_BASE + (port << 2));
else {
u32 a = ISAIO_BASE + ((port & ~1) << 1);
* Shame nothing else does
*/
if (port & 1)
- ret = __raw_getl(a);
+ ret = __raw_readl(a);
else
- ret = __raw_getb(a);
+ ret = __raw_readb(a);
}
return ret;
}
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- ret = __raw_getw(ISAIO_BASE + (port << 2));
+ ret = __raw_readw(ISAIO_BASE + (port << 2));
else {
u32 a = ISAIO_BASE + ((port & ~1) << 1);
if (port & 1)
BUG();
- ret = __raw_getw(a);
+ ret = __raw_readw(a);
}
return ret;
}
* The SuperIO registers use sane addressing techniques...
*/
if (SUPERIO_PORT(port))
- __raw_putb(val, ISAIO_BASE + (port << 2));
+ __raw_writeb(val, ISAIO_BASE + (port << 2));
else {
u32 a = ISAIO_BASE + ((port & ~1) << 1);
* Shame nothing else does
*/
if (port & 1)
- __raw_putl(val, a);
+ __raw_writel(val, a);
else
- __raw_putb(val, a);
+ __raw_writeb(val, a);
}
}
BUG();
}
- __raw_putw(val, ISAIO_BASE + off);
+ __raw_writew(val, ISAIO_BASE + off);
}
void __outl(u32 val, int port)
+if ARCH_CAMELOT
menu "Epxa10db"
comment "PLD hotswap support"
- depends on ARCH_CAMELOT
config PLD
bool
- depends on ARCH_CAMELOT
default y
config PLD_HOTSWAP
bool "Support for PLD device hotplugging (experimental)"
- depends on ARCH_CAMELOT && EXPERIMENTAL
+ depends on EXPERIMENTAL
help
This enables support for the dynamic loading and configuration of
compatible drivers when the contents of the PLD are changed. This
endmenu
+endif
+if ARCH_FOOTBRIDGE
menu "Footbridge Implementations"
config ARCH_CATS
bool "CATS"
- depends on ARCH_FOOTBRIDGE
help
Say Y here if you intend to run this kernel on the CATS.
config ARCH_PERSONAL_SERVER
bool "Compaq Personal Server"
- depends on ARCH_FOOTBRIDGE
---help---
Say Y here if you intend to run this kernel on the Compaq
Personal Server.
config ARCH_EBSA285_ADDIN
bool "EBSA285 (addin mode)"
- depends on ARCH_FOOTBRIDGE
help
Say Y here if you intend to run this kernel on the EBSA285 card
in addin mode.
config ARCH_EBSA285_HOST
bool "EBSA285 (host mode)"
- depends on ARCH_FOOTBRIDGE
help
Say Y here if you intend to run this kernel on the EBSA285 card
in host ("central function") mode.
config ARCH_NETWINDER
bool "NetWinder"
- depends on ARCH_FOOTBRIDGE
help
Say Y here if you intend to run this kernel on the Rebel.COM
NetWinder. Information about this machine can be found at:
endmenu
+endif
+if ARCH_INTEGRATOR
+
menu "Integrator Options"
- depends on ARCH_INTEGRATOR
config ARCH_INTEGRATOR_AP
bool "Support Integrator/AP and Integrator/PP2 platforms"
module will be called impd1.
endmenu
+
+endif
# Object file lists.
-obj-y := core.o lm.o time.o
+obj-y := clock.o core.o lm.o time.o
obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
#include <asm/arch/impd1.h>
#include <asm/sizes.h>
+#include "clock.h"
+
static int module_id;
module_param_named(lmid, module_id, int, 0444);
MODULE_PARM_DESC(lmid, "logic module stack position");
struct impd1_module {
- void *base;
+ void *base;
+ struct clk vcos[2];
};
static const struct icst525_params impd1_vco_params = {
.rd_max = 120,
};
-void impd1_set_vco(struct device *dev, int vconr, unsigned long period)
+static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
{
- struct impd1_module *impd1 = dev_get_drvdata(dev);
- struct icst525_vco vco;
+ struct impd1_module *impd1 = clk->data;
+ int vconr = clk - impd1->vcos;
u32 val;
- vco = icst525_ps_to_vco(&impd1_vco_params, period);
-
- pr_debug("Guessed VCO reg params: S=%d R=%d V=%d\n",
- vco.s, vco.r, vco.v);
-
val = vco.v | (vco.r << 9) | (vco.s << 16);
writel(0xa05f, impd1->base + IMPD1_LOCK);
switch (vconr) {
- case 1:
+ case 0:
writel(val, impd1->base + IMPD1_OSC1);
break;
- case 2:
+ case 1:
writel(val, impd1->base + IMPD1_OSC2);
break;
}
#endif
}
-EXPORT_SYMBOL(impd1_set_vco);
-
void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
{
struct impd1_module *impd1 = dev_get_drvdata(dev);
}
};
+static const char *impd1_vconames[2] = {
+ "CLCDCLK",
+ "AUXVCO2",
+};
+
static int impd1_probe(struct lm_device *dev)
{
struct impd1_module *impd1;
printk("IM-PD1 found at 0x%08lx\n", dev->resource.start);
+ for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
+ impd1->vcos[i].owner = THIS_MODULE,
+ impd1->vcos[i].name = impd1_vconames[i],
+ impd1->vcos[i].params = &impd1_vco_params,
+ impd1->vcos[i].data = impd1,
+ impd1->vcos[i].setvco = impd1_setvco;
+
+ clk_register(&impd1->vcos[i]);
+ }
+
for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
struct impd1_device *idev = impd1_devs + i;
struct amba_device *d;
{
struct impd1_module *impd1 = lm_get_drvdata(dev);
struct list_head *l, *n;
+ int i;
list_for_each_safe(l, n, &dev->dev.children) {
struct device *d = list_to_dev(l);
device_unregister(d);
}
+ for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++)
+ clk_unregister(&impd1->vcos[i]);
+
lm_set_drvdata(dev, NULL);
iounmap(impd1->base);
#include <asm/mach-types.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_kmi.h>
+#include <asm/hardware/icst525.h>
#include <asm/arch/lm.h>
#include <asm/mach/mmc.h>
#include <asm/mach/map.h>
+#include "clock.h"
+
#define INTCP_PA_MMC_BASE 0x1c000000
#define INTCP_PA_AACI_BASE 0x1d000000
#define INTCP_PA_FLASH_BASE 0x24000000
#define INTCP_FLASH_SIZE SZ_32M
+#define INTCP_PA_CLCD_BASE 0xc0000000
+
#define INTCP_VA_CIC_BASE 0xf1000040
#define INTCP_VA_PIC_BASE 0xf1400000
#define INTCP_VA_SIC_BASE 0xfca00000
pic_unmask_irq(IRQ_CP_CPPLDINT);
}
+/*
+ * Clock handling
+ */
+#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c)
+
+static const struct icst525_params cp_auxvco_params = {
+ .ref = 24000,
+ .vco_max = 320000,
+ .vd_min = 8,
+ .vd_max = 263,
+ .rd_min = 3,
+ .rd_max = 65,
+};
+
+static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco)
+{
+ u32 val;
+
+ val = readl(CM_AUXOSC) & ~0x7ffff;
+ val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+ writel(0xa05f, CM_LOCK);
+ writel(val, CM_AUXOSC);
+ writel(0, CM_LOCK);
+}
+
+static struct clk cp_clcd_clk = {
+ .name = "CLCDCLK",
+ .params = &cp_auxvco_params,
+ .setvco = cp_auxvco_set,
+};
+
+static struct clk cp_mmci_clk = {
+ .name = "MCLK",
+ .rate = 33000000,
+};
+
/*
* Flash handling.
*/
.periphid = 0,
};
+static struct amba_device clcd_device = {
+ .dev = {
+ .bus_id = "mb:c0",
+ .coherent_dma_mask = ~0,
+ },
+ .res = {
+ .start = INTCP_PA_CLCD_BASE,
+ .end = INTCP_PA_CLCD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .dma_mask = ~0,
+ .irq = { IRQ_CP_CLCDCINT, NO_IRQ },
+ .periphid = 0,
+};
+
static struct amba_device *amba_devs[] __initdata = {
&mmc_device,
&aaci_device,
+ &clcd_device,
};
static void __init intcp_init(void)
{
int i;
+ clk_register(&cp_clcd_clk);
+ clk_register(&cp_mmci_clk);
+
platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+if ARCH_IOP3XX
menu "IOP3xx Implementation Options"
choice
prompt "IOP3xx System Type"
default ARCH_IQ80310
- depends on ARCH_IOP3XX
config ARCH_IQ80310
bool "IQ80310"
config IOP3XX_AAU
bool "Support Intel IOP3xx Application Accelerator Unit (EXPERIMENTAL)"
- depends on ARCH_IOP3XX && EXPERIMENTAL
+ depends on EXPERIMENTAL
config IOP3XX_DMA
bool "Support Intel IOP3xx DMA (EXPERIMENTAL)"
- depends on ARCH_IOP3XX && EXPERIMENTAL
+ depends on EXPERIMENTAL
config IOP3XX_MU
bool "Support Intel IOP3xx Messaging Unit (EXPERIMENTAL)"
- depends on ARCH_IOP3XX && EXPERIMENTAL
+ depends on EXPERIMENTAL
config IOP3XX_PMON
bool "Support Intel IOP3xx Performance Monitor (EXPERIMENTAL)"
- depends on ARCH_IOP3XX && EXPERIMENTAL
+ depends on EXPERIMENTAL
endmenu
+endif
+if ARCH_IXP4XX
config ARCH_SUPPORTS_BIG_ENDIAN
bool
- depends on ARCH_IXP4XX
default y
menu "Intel IXP4xx Implementation Options"
config ARCH_AVILA
bool "Avila"
- depends on ARCH_IXP4XX
help
Say 'Y' here if you want your kernel to support the Gateworks
Avila Network Platform. For more information on this platform,
config ARCH_ADI_COYOTE
bool "Coyote"
- depends on ARCH_IXP4XX
help
Say 'Y' here if you want your kernel to support the ADI
Engineering Coyote Gateway Reference Platform. For more
config ARCH_IXDP425
bool "IXDP425"
- depends on ARCH_IXP4XX
help
Say 'Y' here if you want your kernel to support Intel's
IXDP425 Development Platform (Also known as Richfield).
config ARCH_PRPMC1100
bool "PrPMC1100"
- depends on ARCH_IXP4XX
help
Say 'Y' here if you want your kernel to support the Motorola
PrPCM1100 Processor Mezanine Module. For more information on
config IXP4XX_INDIRECT_PCI
bool "Use indirect PCI memory access"
- depends on ARCH_IXP4XX
help
IXP4xx provides two methods of accessing PCI memory space:
what you need, leave this option unselected.
endmenu
+
+endif
+if ARCH_LH7A40X
menu "LH7A40X Implementations"
config MACH_KEV7A400
bool "KEV7A400"
- depends on ARCH_LH7A40X
select ARCH_LH7A400
help
Say Y here if you are using the Sharp KEV7A400 development
config MACH_LPD7A400
bool "LPD7A400 Card Engine"
- depends on ARCH_LH7A40X
select ARCH_LH7A400
- select IDE_POLL
+# select IDE_POLL
help
Say Y here if you are using Logic Product Development's
LPD7A400 CardEngine. For the time being, the LPD7A400 and
config MACH_LPD7A404
bool "LPD7A404 Card Engine"
- depends on ARCH_LH7A40X
select ARCH_LH7A404
- select IDE_POLL
+# select IDE_POLL
help
Say Y here if you are using Logic Product Development's
LPD7A404 CardEngine. For the time being, the LPD7A400 and
config ARCH_LH7A404
bool
+config LH7A40X_CONTIGMEM
+ bool "Disable NUMA Support"
+ depends on ARCH_LH7A40X
+ help
+ Say Y here if your bootloader sets the SROMLL bit(s) in
+ the SDRAM controller, organizing memory as a contiguous
+ array. This option will disable CONFIG_DISCONTIGMEM and
+ force the kernel to manage all memory in one node.
+
+ Setting this option incorrectly may prevent the kernel from
+ booting. It is OK to leave it N.
+
+ For more information, consult
+ <file:Documentation/arm/Sharp-LH/SDRAM>.
+
+config LH7A40X_ONE_BANK_PER_NODE
+ bool "Optimize NUMA Node Tables for Size"
+ depends on ARCH_LH7A40X && !LH7A40X_CONTIGMEM
+ help
+ Say Y here to produce compact memory node tables. By
+ default pairs of adjacent physical RAM banks are managed
+ together in a single node, incurring some wasted overhead
+ in the node tables, however also maintaining compatibility
+ with systems where physical memory is truly contiguous.
+
+ Setting this option incorrectly may prevent the kernel from
+ booting. It is OK to leave it N.
+
+ For more information, consult
+ <file:Documentation/arm/Sharp-LH/SDRAM>.
+
endmenu
+
+endif
static void __init lpd7a40x_init (void)
{
- CPLD_CONTROL = 0x0; /* Enable LAN (Disable LCD) */
+ CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */
+ CPLD_CONTROL &= ~(0
+ | (1<<1) /* Disable LCD */
+ | (1<<0) /* Enable WLAN */
+ );
+
platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs));
}
int pinCPLD = (cpld_version == 0x28) ? 7 : 3;
#if defined CONFIG_MACH_LPD7A404
- cpld_version = 0x34; /* Override, for now */
+ cpld_version = 0x34; /* Coerce LPD7A404 to RevB */
#endif
/* First, configure user controlled GPIOF interrupts */
/* Then, configure CPLD interrupt */
- CPLD_INTERRUPTS = 0x0c; /* Disable all CPLD interrupts */
+ CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */
GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */
GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */
GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */
+if ARCH_OMAP
menu "TI OMAP Implementations"
comment "OMAP Core Type"
config ARCH_OMAP730
- depends on ARCH_OMAP
bool "OMAP730 Based System"
select CPU_ARM926T
config ARCH_OMAP1510
- depends on ARCH_OMAP
default y
bool "OMAP1510 Based System"
select CPU_ARM925T
select CPU_DCACHE_WRITETHROUGH
config ARCH_OMAP1610
- depends on ARCH_OMAP
bool "OMAP1610 Based System"
select CPU_ARM926T
config ARCH_OMAP5912
- depends on ARCH_OMAP
bool "OMAP5912 Based System"
select CPU_ARM926T
#config OMAP_BOOT_TAG
# bool "OMAP bootloader information passing"
-# depends on ARCH_OMAP
# default n
# help
# Say Y, if you have a bootloader which passes information
config OMAP_MUX
bool "OMAP multiplexing support"
- depends on ARCH_OMAP
default y
help
Pin multiplexing support for OMAP boards. If your bootloader
choice
prompt "Low-level debug console UART"
- depends on ARCH_OMAP
default OMAP_LL_DEBUG_UART1
config OMAP_LL_DEBUG_UART1
Enable 30MHz clock for OMAP CPU. If unsure, say N.
endmenu
+
+endif
#include <linux/device.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
omap_map_io();
}
-MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610")
+MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710")
MAINTAINER("Tony Lindgren <tony@atomide.com>")
BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
BOOT_PARAMS(0x10000100)
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/delay.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
/* Only FPGA needs to be mapped here. All others are done with ioremap */
static struct map_desc innovator1510_io_desc[] __initdata = {
-{ OMAP1510P1_FPGA_BASE, OMAP1510P1_FPGA_START, OMAP1510P1_FPGA_SIZE,
+{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
MT_DEVICE },
};
static struct resource innovator1510_smc91x_resources[] = {
[0] = {
- .start = OMAP1510P1_FPGA_ETHR_START, /* Physical */
- .end = OMAP1510P1_FPGA_ETHR_START + 16,
+ .start = OMAP1510_FPGA_ETHR_START, /* Physical */
+ .end = OMAP1510_FPGA_ETHR_START + 16,
.flags = IORESOURCE_MEM,
},
[1] = {
#ifdef CONFIG_ARCH_OMAP1510
if (cpu_is_omap1510()) {
iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
+ udelay(10); /* Delay needed for FPGA */
/* Dump the Innovator FPGA rev early - useful info for support. */
printk("Innovator FPGA Rev %d.%d Board Rev %d\n",
- fpga_read(OMAP1510P1_FPGA_REV_HIGH),
- fpga_read(OMAP1510P1_FPGA_REV_LOW),
- fpga_read(OMAP1510P1_FPGA_BOARD_REV));
+ fpga_read(OMAP1510_FPGA_REV_HIGH),
+ fpga_read(OMAP1510_FPGA_REV_LOW),
+ fpga_read(OMAP1510_FPGA_BOARD_REV));
}
#endif
#ifdef CONFIG_ARCH_OMAP1610
#include <linux/device.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
*
* Modified from board-generic.c
*
+ * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
+ * Updated for 2.6 by Kevin Hilman <kjh@hilman.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
#include <linux/device.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
}
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
- MAINTAINER("Kevin Hilman <k-hilman@ti.com>")
+ MAINTAINER("Kevin Hilman <kjh@hilman.org>")
BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
BOOT_PARAMS(0x10000100)
MAPIO(omap_perseus2_map_io)
#include <linux/spinlock.h>
#include <asm/hardware.h>
+#include <asm/mach-types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
}
}
-module_init(omap_bus_init);
+postcore_initcall(omap_bus_init);
module_exit(omap_bus_exit);
MODULE_DESCRIPTION("Virtual bus for OMAP");
}, {
.name = "ck_gen1",
.flags = CK_RATEF | CK_IDLEF,
- .rate_reg = CK_DPLL1,
+ .rate_reg = DPLL_CTL,
.idle_reg = ARM_IDLECT1,
.idle_shift = IDLDPLL_ARM,
.parent = OMAP_CLKIN,
omap_writew(0x1000, ARM_SYSST);
#if defined(CONFIG_OMAP_ARM_30MHZ)
omap_writew(0x1555, ARM_CKCTL);
- omap_writew(0x2290, DPLL_CTL_REG);
+ omap_writew(0x2290, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_60MHZ)
omap_writew(0x1005, ARM_CKCTL);
- omap_writew(0x2290, DPLL_CTL_REG);
+ omap_writew(0x2290, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_96MHZ)
omap_writew(0x1005, ARM_CKCTL);
- omap_writew(0x2410, DPLL_CTL_REG);
+ omap_writew(0x2410, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_120MHZ)
omap_writew(0x110a, ARM_CKCTL);
- omap_writew(0x2510, DPLL_CTL_REG);
+ omap_writew(0x2510, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_168MHZ)
omap_writew(0x110f, ARM_CKCTL);
- omap_writew(0x2710, DPLL_CTL_REG);
+ omap_writew(0x2710, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
omap_writew(0x250E, ARM_CKCTL);
- omap_writew(0x2710, DPLL_CTL_REG);
+ omap_writew(0x2710, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912))
omap_writew(0x150f, ARM_CKCTL);
if (crystal_type == 2) {
source_clock = 13; /* MHz */
- omap_writew(0x2510, DPLL_CTL_REG);
+ omap_writew(0x2510, DPLL_CTL);
} else
- omap_writew(0x2810, DPLL_CTL_REG);
+ omap_writew(0x2810, DPLL_CTL);
#elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
omap_writew(0x250E, ARM_CKCTL);
- omap_writew(0x2790, DPLL_CTL_REG);
+ omap_writew(0x2790, DPLL_CTL);
#else
#error "OMAP MHZ not set, please run make xconfig"
#endif
#ifdef CONFIG_MACH_OMAP_PERSEUS2
/* Select slicer output as OMAP input clock */
- omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL_REG) & ~0x1, OMAP730_PCC_UPLD_CTRL_REG);
+ omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
#endif
/* Turn off some other junk the bootloader might have turned on */
#include <asm/arch/board.h>
#include <asm/io.h>
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP revision check
+ *
+ * Since we use the cpu_is_omapnnnn() macros, there's a chance that a board
+ * switches to an updated core. We want to print out the OMAP revision early.
+ *
+ * We use the system_serial registers for the revision information so we
+ * can see it in /proc/cpuinfo.
+ *
+ * If the OMAP detection gets more complicated, we may want to expand this
+ * to store the OMAP version and replace the current cpu_is_omapnnnn() macros.
+ *
+ * ----------------------------------------------------------------------------
+ */
+static void __init omap_check_revision(void)
+{
+ system_serial_high = omap_readl(OMAP_ID_BASE);
+ system_serial_low = OMAP_ID_REG;
+ system_rev = (OMAP_ID_REG >> ID_SHIFT) & ID_MASK;
+
+ printk("OMAP revision: %d.%d (0x%08x) id: 0x%08x detected as OMAP-",
+ (system_serial_high >> 20) & 0xf,
+ (system_serial_high >> 16) & 0xf,
+ system_serial_high, system_serial_low);
+
+ switch (system_rev) {
+ case OMAP_ID_730:
+ printk("730\n");
+ system_rev = 0x730;
+ break;
+ case OMAP_ID_1510:
+ printk("1510\n");
+ system_rev = 0x1510;
+ break;
+ case OMAP_ID_1610:
+ printk("1610\n");
+ system_rev = 0x1610;
+ break;
+ case OMAP_ID_1710:
+ printk("1710\n");
+ system_rev = 0x1710;
+ break;
+ case OMAP_ID_5912:
+ printk("5912/1611B\n");
+ system_rev = 0x5912;
+ break;
+ default:
+ printk("unknown, please add support!\n");
+ }
+}
+
/*
* ----------------------------------------------------------------------------
* OMAP I/O mapping
static struct map_desc omap5912_io_desc[] __initdata = {
{ OMAP5912_DSP_BASE, OMAP5912_DSP_START, OMAP5912_DSP_SIZE, MT_DEVICE },
{ OMAP5912_DSPREG_BASE, OMAP5912_DSPREG_START, OMAP5912_DSPREG_SIZE, MT_DEVICE },
- { OMAP5912_SRAM_BASE, OMAP5912_SRAM_START, OMAP5912_SRAM_SIZE, MT_DEVICE }
+/*
+ * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
+ * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
+ * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
+ * can be used.
+ */
+ { OMAP5912_SRAM_BASE, OMAP5912_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE }
};
#endif
/* We have to initialize the IO space mapping before we can run
* cpu_is_omapxxx() macros. */
iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+ omap_check_revision();
#ifdef CONFIG_ARCH_OMAP730
if (cpu_is_omap730()) {
/* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
* on a Posted Write in the TIPB Bridge".
*/
- omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL_REG);
- omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL_REG);
+ omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
+ omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
/* Must init clocks early to assure that timer interrupt works
*/
{
u16 w;
- w = omap_readw(OMAP_DMA_CSDP_REG(lch));
+ w = omap_readw(OMAP_DMA_CSDP(lch));
w &= ~0x03;
w |= data_type;
- omap_writew(w, OMAP_DMA_CSDP_REG(lch));
+ omap_writew(w, OMAP_DMA_CSDP(lch));
- w = omap_readw(OMAP_DMA_CCR_REG(lch));
+ w = omap_readw(OMAP_DMA_CCR(lch));
w &= ~(1 << 5);
if (sync_mode == OMAP_DMA_SYNC_FRAME)
w |= 1 << 5;
- omap_writew(w, OMAP_DMA_CCR_REG(lch));
+ omap_writew(w, OMAP_DMA_CCR(lch));
- w = omap_readw(OMAP_DMA_CCR2_REG(lch));
+ w = omap_readw(OMAP_DMA_CCR2(lch));
w &= ~(1 << 2);
if (sync_mode == OMAP_DMA_SYNC_BLOCK)
w |= 1 << 2;
- omap_writew(w, OMAP_DMA_CCR2_REG(lch));
+ omap_writew(w, OMAP_DMA_CCR2(lch));
- omap_writew(elem_count, OMAP_DMA_CEN_REG(lch));
- omap_writew(frame_count, OMAP_DMA_CFN_REG(lch));
+ omap_writew(elem_count, OMAP_DMA_CEN(lch));
+ omap_writew(frame_count, OMAP_DMA_CFN(lch));
}
+void omap_set_dma_constant_fill(int lch, u32 color)
+{
+ u16 w;
+
+#ifdef CONFIG_DEBUG_KERNEL
+ if (omap_dma_in_1510_mode) {
+ printk(KERN_ERR "OMAP DMA constant fill not available in 1510 mode.");
+ BUG();
+ return;
+ }
+#endif
+ w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+ w |= 0x01;
+ omap_writew(w, OMAP_DMA_CCR2(lch));
+
+ omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
+ omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+
+ w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
+ w |= 1; /* Channel type G */
+ omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
+}
+
+void omap_set_dma_transparent_copy(int lch, u32 color)
+{
+ u16 w;
+
+#ifdef CONFIG_DEBUG_KERNEL
+ if (omap_dma_in_1510_mode) {
+ printk(KERN_ERR "OMAP DMA transparent copy not available in 1510 mode.");
+ BUG();
+ }
+#endif
+ w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+ w |= 0x02;
+ omap_writew(w, OMAP_DMA_CCR2(lch));
+
+ omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
+ omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+
+ w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
+ w |= 1; /* Channel type G */
+ omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
+}
void omap_set_dma_src_params(int lch, int src_port, int src_amode,
unsigned long src_start)
{
u16 w;
- w = omap_readw(OMAP_DMA_CSDP_REG(lch));
+ w = omap_readw(OMAP_DMA_CSDP(lch));
w &= ~(0x1f << 2);
w |= src_port << 2;
- omap_writew(w, OMAP_DMA_CSDP_REG(lch));
+ omap_writew(w, OMAP_DMA_CSDP(lch));
- w = omap_readw(OMAP_DMA_CCR_REG(lch));
+ w = omap_readw(OMAP_DMA_CCR(lch));
w &= ~(0x03 << 12);
w |= src_amode << 12;
- omap_writew(w, OMAP_DMA_CCR_REG(lch));
+ omap_writew(w, OMAP_DMA_CCR(lch));
+
+ omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
+ omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
+}
+
+void omap_set_dma_src_index(int lch, int eidx, int fidx)
+{
+ omap_writew(eidx, OMAP_DMA_CSEI(lch));
+ omap_writew(fidx, OMAP_DMA_CSFI(lch));
+}
+
+void omap_set_dma_src_data_pack(int lch, int enable)
+{
+ u16 w;
+
+ w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
+ w |= enable ? (1 << 6) : 0;
+ omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_src_burst_mode(int lch, int burst_mode)
+{
+ u16 w;
- omap_writew(src_start >> 16, OMAP_DMA_CSSA_U_REG(lch));
- omap_writew(src_start, OMAP_DMA_CSSA_L_REG(lch));
+ w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
+ switch (burst_mode) {
+ case OMAP_DMA_DATA_BURST_4:
+ w |= (0x01 << 7);
+ break;
+ case OMAP_DMA_DATA_BURST_8:
+ w |= (0x03 << 7);
+ break;
+ default:
+ printk(KERN_ERR "Invalid DMA burst mode\n");
+ BUG();
+ return;
+ }
+ omap_writew(w, OMAP_DMA_CSDP(lch));
}
void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
{
u16 w;
- w = omap_readw(OMAP_DMA_CSDP_REG(lch));
+ w = omap_readw(OMAP_DMA_CSDP(lch));
w &= ~(0x1f << 9);
w |= dest_port << 9;
- omap_writew(w, OMAP_DMA_CSDP_REG(lch));
+ omap_writew(w, OMAP_DMA_CSDP(lch));
- w = omap_readw(OMAP_DMA_CCR_REG(lch));
+ w = omap_readw(OMAP_DMA_CCR(lch));
w &= ~(0x03 << 14);
w |= dest_amode << 14;
- omap_writew(w, OMAP_DMA_CCR_REG(lch));
+ omap_writew(w, OMAP_DMA_CCR(lch));
+
+ omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
+ omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
+}
+
+void omap_set_dma_dest_index(int lch, int eidx, int fidx)
+{
+ omap_writew(eidx, OMAP_DMA_CDEI(lch));
+ omap_writew(fidx, OMAP_DMA_CDFI(lch));
+}
+
+void omap_set_dma_dest_data_pack(int lch, int enable)
+{
+ u16 w;
- omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U_REG(lch));
- omap_writew(dest_start, OMAP_DMA_CDSA_L_REG(lch));
+ w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
+ w |= enable ? (1 << 13) : 0;
+ omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_dest_burst_mode(int lch, int burst_mode)
+{
+ u16 w;
+
+ w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
+ switch (burst_mode) {
+ case OMAP_DMA_DATA_BURST_4:
+ w |= (0x01 << 14);
+ break;
+ case OMAP_DMA_DATA_BURST_8:
+ w |= (0x03 << 14);
+ break;
+ default:
+ printk(KERN_ERR "Invalid DMA burst mode\n");
+ BUG();
+ return;
+ }
+ omap_writew(w, OMAP_DMA_CSDP(lch));
}
void omap_start_dma(int lch)
/* Enable the queue, if needed so. */
if (next_lch != -1) {
/* Clear the STOP_LNK bits */
- w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(lch));
+ w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
w &= ~(1 << 14);
- omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(lch));
- w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(next_lch));
+ omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+ w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
w &= ~(1 << 14);
- omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(next_lch));
+ omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
/* And set the ENABLE_LNK bits */
omap_writew(next_lch | (1 << 15),
- OMAP_DMA_CLNK_CTRL_REG(lch));
+ OMAP_DMA_CLNK_CTRL(lch));
/* The loop case */
if (dma_chan[next_lch].next_lch == lch)
omap_writew(lch | (1 << 15),
- OMAP_DMA_CLNK_CTRL_REG(next_lch));
+ OMAP_DMA_CLNK_CTRL(next_lch));
/* Read CSR to make sure it's cleared. */
- w = omap_readw(OMAP_DMA_CSR_REG(next_lch));
+ w = omap_readw(OMAP_DMA_CSR(next_lch));
/* Enable some nice interrupts. */
omap_writew(dma_chan[next_lch].enabled_irqs,
- OMAP_DMA_CICR_REG(next_lch));
+ OMAP_DMA_CICR(next_lch));
dma_chan[next_lch].flags |= OMAP_DMA_ACTIVE;
}
}
/* Read CSR to make sure it's cleared. */
- w = omap_readw(OMAP_DMA_CSR_REG(lch));
+ w = omap_readw(OMAP_DMA_CSR(lch));
/* Enable some nice interrupts. */
- omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR_REG(lch));
+ omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
- w = omap_readw(OMAP_DMA_CCR_REG(lch));
+ w = omap_readw(OMAP_DMA_CCR(lch));
w |= OMAP_DMA_CCR_EN;
- omap_writew(w, OMAP_DMA_CCR_REG(lch));
+ omap_writew(w, OMAP_DMA_CCR(lch));
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
int next_lch;
/* Disable all interrupts on the channel */
- omap_writew(0, OMAP_DMA_CICR_REG(lch));
+ omap_writew(0, OMAP_DMA_CICR(lch));
if (omap_dma_in_1510_mode()) {
- w = omap_readw(OMAP_DMA_CCR_REG(lch));
+ w = omap_readw(OMAP_DMA_CCR(lch));
w &= ~OMAP_DMA_CCR_EN;
- omap_writew(w, OMAP_DMA_CCR_REG(lch));
+ omap_writew(w, OMAP_DMA_CCR(lch));
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
return;
}
* According to thw HW spec, enabling the STOP_LNK bit
* resets the CCR_EN bit at the same time.
*/
- w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(lch));
+ w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
w |= (1 << 14);
- w = omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(lch));
+ w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
if (next_lch != -1) {
- omap_writew(0, OMAP_DMA_CICR_REG(next_lch));
- w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(next_lch));
+ omap_writew(0, OMAP_DMA_CICR(next_lch));
+ w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch));
w |= (1 << 14);
- w = omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(next_lch));
+ w = omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch));
dma_chan[next_lch].flags &= ~OMAP_DMA_ACTIVE;
}
}
csr = dma_chan[ch].saved_csr;
dma_chan[ch].saved_csr = 0;
} else
- csr = omap_readw(OMAP_DMA_CSR_REG(ch));
+ csr = omap_readw(OMAP_DMA_CSR(ch));
if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
dma_chan[ch + 6].saved_csr = csr >> 7;
csr &= 0x7f;
}
/* Disable the 1510 compatibility mode and set the sync device
* id. */
- omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR_REG(free_ch));
+ omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
} else {
- omap_writew(dev_id, OMAP_DMA_CCR_REG(free_ch));
+ omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
}
*dma_ch_out = free_ch;
spin_unlock_irqrestore(&dma_chan_lock, flags);
/* Disable all DMA interrupts for the channel. */
- omap_writew(0, OMAP_DMA_CICR_REG(ch));
+ omap_writew(0, OMAP_DMA_CICR(ch));
/* Make sure the DMA transfer is stopped. */
- omap_writew(0, OMAP_DMA_CCR_REG(ch));
+ omap_writew(0, OMAP_DMA_CCR(ch));
}
int omap_dma_in_1510_mode(void)
enable_1510_mode = 1;
} else if (cpu_is_omap1610() || cpu_is_omap5912()) {
printk(KERN_INFO "OMAP DMA hardware version %d\n",
- omap_readw(OMAP_DMA_HW_ID_REG));
+ omap_readw(OMAP_DMA_HW_ID));
printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
- (omap_readw(OMAP_DMA_CAPS_0_U_REG) << 16) | omap_readw(OMAP_DMA_CAPS_0_L_REG),
- (omap_readw(OMAP_DMA_CAPS_1_U_REG) << 16) | omap_readw(OMAP_DMA_CAPS_1_L_REG),
- omap_readw(OMAP_DMA_CAPS_2_REG), omap_readw(OMAP_DMA_CAPS_3_REG),
- omap_readw(OMAP_DMA_CAPS_4_REG));
+ (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
+ (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
+ omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
+ omap_readw(OMAP_DMA_CAPS_4));
if (!enable_1510_mode) {
u16 w;
/* Disable OMAP 3.0/3.1 compatibility mode. */
- w = omap_readw(OMAP_DMA_GSCR_REG);
+ w = omap_readw(OMAP_DMA_GSCR);
w |= 1 << 3;
- omap_writew(w, OMAP_DMA_GSCR_REG);
+ omap_writew(w, OMAP_DMA_GSCR);
dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
} else
dma_chan_count = 9;
EXPORT_SYMBOL(omap_free_dma);
EXPORT_SYMBOL(omap_start_dma);
EXPORT_SYMBOL(omap_stop_dma);
+
EXPORT_SYMBOL(omap_set_dma_transfer_params);
+EXPORT_SYMBOL(omap_set_dma_constant_fill);
+EXPORT_SYMBOL(omap_set_dma_transparent_copy);
+
EXPORT_SYMBOL(omap_set_dma_src_params);
+EXPORT_SYMBOL(omap_set_dma_src_index);
+EXPORT_SYMBOL(omap_set_dma_src_data_pack);
+EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
+
EXPORT_SYMBOL(omap_set_dma_dest_params);
+EXPORT_SYMBOL(omap_set_dma_dest_index);
+EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
+EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
+
EXPORT_SYMBOL(omap_dma_link_lch);
EXPORT_SYMBOL(omap_dma_unlink_lch);
irq -= IH_FPGA_BASE;
if (irq < 8)
- __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_LO)
- & ~(1 << irq)), OMAP1510P1_FPGA_IMR_LO);
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
+ & ~(1 << irq)), OMAP1510_FPGA_IMR_LO);
else if (irq < 16)
- __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_HI)
- & ~(1 << (irq - 8))), OMAP1510P1_FPGA_IMR_HI);
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+ & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
else
__raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
& ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
static inline u32 get_fpga_unmasked_irqs(void)
{
return
- ((__raw_readb(OMAP1510P1_FPGA_ISR_LO) &
- __raw_readb(OMAP1510P1_FPGA_IMR_LO))) |
- ((__raw_readb(OMAP1510P1_FPGA_ISR_HI) &
- __raw_readb(OMAP1510P1_FPGA_IMR_HI)) << 8) |
+ ((__raw_readb(OMAP1510_FPGA_ISR_LO) &
+ __raw_readb(OMAP1510_FPGA_IMR_LO))) |
+ ((__raw_readb(OMAP1510_FPGA_ISR_HI) &
+ __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) |
((__raw_readb(INNOVATOR_FPGA_ISR2) &
__raw_readb(INNOVATOR_FPGA_IMR2)) << 16);
}
irq -= IH_FPGA_BASE;
if (irq < 8)
- __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_LO) | (1 << irq)),
- OMAP1510P1_FPGA_IMR_LO);
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
+ OMAP1510_FPGA_IMR_LO);
else if (irq < 16)
- __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_HI)
- | (1 << (irq - 8))), OMAP1510P1_FPGA_IMR_HI);
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+ | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
else
__raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
| (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
{
int i;
- __raw_writeb(0, OMAP1510P1_FPGA_IMR_LO);
- __raw_writeb(0, OMAP1510P1_FPGA_IMR_HI);
+ __raw_writeb(0, OMAP1510_FPGA_IMR_LO);
+ __raw_writeb(0, OMAP1510_FPGA_IMR_HI);
__raw_writeb(0, INNOVATOR_FPGA_IMR2);
for (i = IH_FPGA_BASE; i < (IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
#include <asm/irq.h>
#include <asm/arch/irqs.h>
#include <asm/arch/gpio.h>
-#include <asm/arch/pm.h>
#include <asm/mach/irq.h>
#include <asm/io.h>
#define OMAP730_GPIO_INT_MASK 0x10
#define OMAP730_GPIO_INT_STATUS 0x14
-#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff)
+#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff)
struct gpio_bank {
u32 base;
reg += OMAP730_GPIO_DIR_CONTROL;
break;
}
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (is_input)
l |= 1 << gpio;
else
l &= ~(1 << gpio);
- omap_writel(l, reg);
+ __raw_writel(l, reg);
}
void omap_set_gpio_direction(int gpio, int is_input)
switch (bank->method) {
case METHOD_MPUIO:
- reg += OMAP_MPUIO_OUTPUT_REG;
- l = omap_readl(reg);
+ reg += OMAP_MPUIO_OUTPUT;
+ l = __raw_readl(reg);
if (enable)
l |= 1 << gpio;
else
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DATA_OUTPUT;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (enable)
l |= 1 << gpio;
else
break;
case METHOD_GPIO_730:
reg += OMAP730_GPIO_DATA_OUTPUT;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (enable)
l |= 1 << gpio;
else
BUG();
return;
}
- omap_writel(l, reg);
+ __raw_writel(l, reg);
}
void omap_set_gpio_dataout(int gpio, int enable)
BUG();
return -1;
}
- return (omap_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+ return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
}
static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
switch (bank->method) {
case METHOD_MPUIO:
- reg += OMAP_MPUIO_GPIO_INT_EDGE_REG;
- l = omap_readl(reg);
+ reg += OMAP_MPUIO_GPIO_INT_EDGE;
+ l = __raw_readl(reg);
if (edge == OMAP_GPIO_RISING_EDGE)
l |= 1 << gpio;
else
l &= ~(1 << gpio);
- omap_writel(l, reg);
+ __raw_writel(l, reg);
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_CONTROL;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (edge == OMAP_GPIO_RISING_EDGE)
l |= 1 << gpio;
else
l &= ~(1 << gpio);
- omap_writel(l, reg);
+ __raw_writel(l, reg);
break;
case METHOD_GPIO_1610:
edge &= 0x03;
else
reg += OMAP1610_GPIO_EDGE_CTRL1;
gpio &= 0x07;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
l &= ~(3 << (gpio << 1));
l |= edge << (gpio << 1);
- omap_writel(l, reg);
+ __raw_writel(l, reg);
break;
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_CONTROL;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (edge == OMAP_GPIO_RISING_EDGE)
l |= 1 << gpio;
else
l &= ~(1 << gpio);
- omap_writel(l, reg);
+ __raw_writel(l, reg);
break;
default:
BUG();
switch (bank->method) {
case METHOD_MPUIO:
- l = omap_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE_REG);
+ l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
return (l & (1 << gpio)) ?
OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
case METHOD_GPIO_1510:
- l = omap_readl(reg + OMAP1510_GPIO_INT_CONTROL);
+ l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
return (l & (1 << gpio)) ?
OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_EDGE_CTRL2;
else
reg += OMAP1610_GPIO_EDGE_CTRL1;
- return (omap_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
+ return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
case METHOD_GPIO_730:
- l = omap_readl(reg + OMAP730_GPIO_INT_CONTROL);
+ l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
return (l & (1 << gpio)) ?
OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
default:
BUG();
return;
}
- omap_writel(1 << get_gpio_index(gpio), reg);
+ __raw_writel(1 << get_gpio_index(gpio), reg);
}
static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
switch (bank->method) {
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_MASKIT;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (enable)
l &= ~(1 << gpio);
else
break;
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_MASK;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (enable)
l &= ~(1 << gpio);
else
break;
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_MASK;
- l = omap_readl(reg);
+ l = __raw_readl(reg);
if (enable)
l &= ~(1 << gpio);
else
BUG();
return;
}
- omap_writel(l, reg);
+ __raw_writel(l, reg);
}
int omap_request_gpio(int gpio)
/* Claim the pin for the ARM */
reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
- omap_writel(omap_readl(reg) | (1 << get_gpio_index(gpio)), reg);
+ __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
}
#endif
spin_unlock(&bank->lock);
isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
#endif
for (;;) {
- u32 isr = omap_readl(isr_reg);
+ u32 isr = __raw_readl(isr_reg);
unsigned int gpio_irq;
if (!isr)
#ifdef CONFIG_ARCH_OMAP1510
if (bank->method == METHOD_GPIO_1510)
- omap_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS);
+ __raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS);
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610)
- omap_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1);
+ __raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1);
#endif
#ifdef CONFIG_ARCH_OMAP730
if (bank->method == METHOD_GPIO_730)
- omap_writel(1 << (gpio & 0x1f), bank->base + OMAP730_GPIO_INT_STATUS);
+ __raw_writel(1 << (gpio & 0x1f), bank->base + OMAP730_GPIO_INT_STATUS);
#endif
}
bank = &gpio_bank[i];
bank->reserved_map = 0;
+ bank->base = IO_ADDRESS(bank->base);
spin_lock_init(&bank->lock);
if (bank->method == METHOD_MPUIO) {
omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
}
#ifdef CONFIG_ARCH_OMAP1510
if (bank->method == METHOD_GPIO_1510) {
- omap_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
- omap_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
+ __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
+ __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
}
#endif
#if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)
if (bank->method == METHOD_GPIO_1610) {
- omap_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
- omap_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
+ __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
+ __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
}
#endif
#ifdef CONFIG_ARCH_OMAP730
if (bank->method == METHOD_GPIO_730) {
- omap_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
- omap_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
+ __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
+ __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
gpio_count = 32; /* 730 has 32-bit GPIOs */
}
}
/* Enable system clock for GPIO module.
- * The CAM_CLK_CTRL_REG *is* really the right place. */
+ * The CAM_CLK_CTRL *is* really the right place. */
if (cpu_is_omap1610())
- omap_writel(omap_readl(ULPD_CAM_CLK_CTRL_REG) | 0x04, ULPD_CAM_CLK_CTRL_REG);
+ omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
return 0;
}
return 0;
}
-EXPORT_SYMBOL(omap_gpio_init);
EXPORT_SYMBOL(omap_request_gpio);
EXPORT_SYMBOL(omap_free_gpio);
+EXPORT_SYMBOL(omap_set_gpio_direction);
+EXPORT_SYMBOL(omap_set_gpio_dataout);
+EXPORT_SYMBOL(omap_get_gpio_datain);
+EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
arch_initcall(omap_gpio_init);
static void omap_ack_irq(unsigned int irq)
{
if (irq > 31)
- omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG);
+ omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
- omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG);
+ omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
}
static void omap_mask_irq(unsigned int irq)
int bank = IRQ_BANK(irq);
u32 l;
- l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR);
+ l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
l |= 1 << IRQ_BIT(irq);
- omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR);
+ omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
}
static void omap_unmask_irq(unsigned int irq)
int bank = IRQ_BANK(irq);
u32 l;
- l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR);
+ l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
l &= ~(1 << IRQ_BIT(irq));
- omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR);
+ omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
}
static void omap_mask_ack_irq(unsigned int irq)
/* FIQ is only available on bank 0 interrupts */
fiq = bank ? 0 : (fiq & 0x1);
val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
- offset = IRQ_ILR0 + IRQ_BIT(irq) * 0x4;
+ offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
irq_bank_writel(val, bank, offset);
}
/* Mask and clear all interrupts */
for (i = 0; i < irq_bank_count; i++) {
- irq_bank_writel(~0x0, i, IRQ_MIR);
- irq_bank_writel(0x0, i, IRQ_ITR);
+ irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
+ irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
}
/* Clear any pending interrupts */
- irq_bank_writel(0x03, 0, IRQ_CONTROL_REG);
- irq_bank_writel(0x03, 1, IRQ_CONTROL_REG);
+ irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
+ irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
/* Install the interrupt handlers for each bank */
for (i = 0; i < irq_bank_count; i++) {
val &= ~0xff;
omap_writel(val, OCPI_SEC);
- val = omap_readl(OCPI_SEC);
- val |= 0;
- omap_writel(val, OCPI_SEC);
-
- val = omap_readl(OCPI_SINT0);
- val |= 0;
- omap_writel(val, OCPI_SINT1);
-
return 0;
}
EXPORT_SYMBOL(ocpi_enable);
+if ARCH_PXA
menu "Intel PXA2xx Implementations"
choice
prompt "Select target board"
- depends on ARCH_PXA
config ARCH_LUBBOCK
bool "Intel DBPXA250 Development Platform"
help
Select code specific to PXA27x variants
+endif
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/arch/idp.h>
+
#include "generic.h"
#ifndef PXA_IDP_REV02
#include <asm/leds.h>
#include <asm/system.h>
+#include <asm/arch/idp.h>
+
#include "leds.h"
#define LED_STATE_ENABLED 1
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
+#include <asm/arch/lubbock.h>
#include "leds.h"
#include <asm/leds.h>
#include <asm/system.h>
+#include <asm/arch/mainstone.h>
+
#include "leds.h"
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/arch/lubbock.h>
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
#include <asm/hardware/sa1111.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/arch/mainstone.h>
+
#include "generic.h"
#include <asm/hardware.h>
#include <asm/memory.h>
#include <asm/system.h>
+#include <asm/arch/lubbock.h>
/*
+if ARCH_S3C2410
+
menu "S3C2410 Implementations"
config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
- depends on ARCH_S3C2410
help
Say Y here if you are using the Simtec Electronics EB2410ITX
development board (also known as BAST)
config ARCH_H1940
bool "IPAQ H1940"
- depends on ARCH_S3C2410
help
Say Y here if you are using the HP IPAQ H1940
<http://www.handhelds.org/projects/h1940.html>.
config ARCH_SMDK2410
bool "SMDK2410/A9M2410"
- depends on ARCH_S3C2410
help
Say Y here if you are using the SMDK2410 or the derived module A9M2410
<http://www.fsforth.de>
config MACH_VR1000
bool "Simtec VR1000"
- depends on ARCH_S3C2410
help
Say Y here if you are using the Simtec VR1000 board.
endmenu
+
+endif
+if ARCH_SA1100
menu "SA11x0 Implementations"
config SA1100_ASSABET
bool "Assabet"
- depends on ARCH_SA1100
help
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
Microprocessor Development Board (also known as the Assabet).
config SA1100_ADSBITSY
bool "ADS Bitsy"
- depends on ARCH_SA1100
help
Say Y here if you are using Applied Data Systems Intel(R)
StrongARM(R) 1110 based Bitsy, 3 x 5 inches in size, Compaq - IPAQ -
config SA1100_BRUTUS
bool "Brutus"
- depends on ARCH_SA1100
help
Say Y here if you are using the Intel(R) StrongARM(R) SA-1100
Microprocessor Development Board (also known as the Brutus).
config SA1100_CERF
bool "CerfBoard"
- depends on ARCH_SA1100
help
The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
More information is available at:
config SA1100_H3100
bool "Compaq iPAQ H3100"
- depends on ARCH_SA1100
help
Say Y here if you intend to run this kernel on the Compaq iPAQ
H3100 handheld computer. Information about this machine and the
config SA1100_H3600
bool "Compaq iPAQ H3600/H3700"
- depends on ARCH_SA1100
help
Say Y here if you intend to run this kernel on the Compaq iPAQ
H3600 handheld computer. Information about this machine and the
config SA1100_H3800
bool "Compaq iPAQ H3800"
- depends on ARCH_SA1100
help
Say Y here if you intend to run this kernel on the Compaq iPAQ H3800
series handheld computer. Information about this machine and the
#dep_bool ' Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
config SA1100_EXTENEX1
bool "Extenex HandHeld Theater (Squashtail)"
- depends on ARCH_SA1100
config SA1100_EXTENEX1_16MB
bool "Support 16 MB of DRAM (not just 8)"
config SA1100_FLEXANET
bool "FlexaNet"
- depends on ARCH_SA1100
help
Say Y here if you intend to run this kernel on the FlexaNet
handheld instruments. Information about this machine can be
config SA1100_FREEBIRD
bool "FreeBird-v1.1"
- depends on ARCH_SA1100
help
Support the FreeBird board used in Coventive embedded products. See
Documentation/arm/SA1100/Freebird for more.
config SA1100_GRAPHICSCLIENT
bool "GraphicsClient Plus"
- depends on ARCH_SA1100
help
Say Y here if you are using an Applied Data Systems Intel(R)
StrongARM(R) SA-1100 based Graphics Client SBC. See
config SA1100_GRAPHICSMASTER
bool "GraphicsMaster"
- depends on ARCH_SA1100
help
Say Y here if you are using an Applied Data Systems Intel(R)
StrongARM(R) SA-1100 based Graphics Master SBC with SA-1111
config SA1100_BADGE4
bool "HP Labs BadgePAD 4"
- depends on ARCH_SA1100
help
Say Y here if you want to build a kernel for the HP Laboratories
BadgePAD 4.
config SA1100_JORNADA720
bool "HP Jornada 720"
- depends on ARCH_SA1100
help
Say Y here if you want to build a kernel for the HP Jornada 720
handheld computer. See <http://www.hp.com/jornada/products/720>
config SA1100_HACKKIT
bool "HackKit Core CPU Board"
- depends on ARCH_SA1100
help
Say Y here to support the HackKit Core CPU Board
<http://hackkit.eletztrick.de>;
config SA1100_HUW_WEBPANEL
bool "HuW WebPanel"
- depends on ARCH_SA1100
help
Say Y here to support the HuW Webpanel produced by Hoeft & Wessel
AG. English-language website is at
config SA1100_ITSY
bool "Itsy"
- depends on ARCH_SA1100
help
Say Y here if you are using the Compaq Itsy experimental pocket
computer. See <http://research.compaq.com/wrl/projects/itsy/> for
config SA1100_LART
bool "LART"
- depends on ARCH_SA1100
help
Say Y here if you are using the Linux Advanced Radio Terminal
(also known as the LART). See <http://www.lart.tudelft.nl/> for
config SA1100_NANOENGINE
bool "nanoEngine"
- depends on ARCH_SA1100
help
The nanoEngine is a StrongARM 1110-based single board computer
from Bright Star Engineering. More information is available at:
config SA1100_OMNIMETER
bool "OmniMeter"
- depends on ARCH_SA1100
help
Say Y here if you are using the inhand electronics OmniMeter. See
<http://www.inhandelectronics.com/omnimeter.asp> for details.
config SA1100_PANGOLIN
bool "Pangolin"
- depends on ARCH_SA1100
help
Pangolin is a StrongARM 1110-based evaluation platform produced
by Dialogue Technology. It has EISA slots for ease of configuration
config SA1100_PLEB
bool "PLEB"
- depends on ARCH_SA1100
help
Say Y here if you are using a Portable Linux Embedded Board
(also known as PLEB). See <http://www.cse.unsw.edu.au/~pleb/>
config SA1100_PT_SYSTEM3
bool "PT System 3"
- depends on ARCH_SA1100
help
Say Y here if you intend to build a kernel suitable to run on
a Pruftechnik Digital Board. For more information see
config SA1100_SHANNON
bool "Shannon"
- depends on ARCH_SA1100
help
The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
limited edition webphone produced by Philips. The Shannon is a SA1100
config SA1100_SHERMAN
bool "Sherman"
- depends on ARCH_SA1100
help
Say Y here to support the Blazie Engineering `Sherman' StrongARM
1110-based SBC, used primarily in assistance products for the
config SA1100_SIMPAD
bool "Simpad"
- depends on ARCH_SA1100
help
The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
config SA1100_PFS168
bool "Tulsa"
- depends on ARCH_SA1100
help
The Radisys Corp. PFS-168 (aka Tulsa) is an Intel® StrongArm® SA-1110 based
computer which includes the SA-1111 Microprocessor Companion Chip and other
config SA1100_VICTOR
bool "Victor"
- depends on ARCH_SA1100
help
Say Y here if you are using a Visu Aide Intel(R) StrongARM(R)
SA-1100 based Victor Digital Talking Book Reader. See
config SA1100_XP860
bool "XP860"
- depends on ARCH_SA1100
help
:: Config help missing ::
:: 06 August 2002 ::
config SA1100_YOPY
bool "Yopy"
- depends on ARCH_SA1100
help
Say Y here to support the Yopy PDA. Product information at
<http://www.yopy.com/>. See Documentation/arm/SA1100/Yopy
config SA1100_STORK
bool "Stork"
- depends on ARCH_SA1100
help
Say Y here if you intend to run this kernel on the Stork
handheld computer.
#config SA1100_TRIZEPS
# bool "Trizeps"
-# depends on ARCH_SA1100
# help
# :: write me ::
config SA1100_SSP
tristate "Generic PIO SSP"
- depends on ARCH_SA1100
help
Say Y here to enable support for the generic PIO SSP driver.
This isn't for audio support, but for attached sensors and
config SA1100_USB
tristate "SA1100 USB function support"
- depends on ARCH_SA1100
config SA1100_USB_NETLINK
tristate "Support for SA11x0 USB network link function"
endmenu
+endif
}
static struct cpufreq_driver sa1100_driver = {
- .flags = (CPUFREQ_PANIC_OUTOFSYNC |
- CPUFREQ_PANIC_RESUME_OUTOFSYNC),
+ .flags = CPUFREQ_STICKY |
+ CPUFREQ_PANIC_OUTOFSYNC |
+ CPUFREQ_PANIC_RESUME_OUTOFSYNC,
.verify = sa11x0_verify_speed,
.target = sa1100_target,
.get = sa11x0_getspeed,
}
static struct cpufreq_driver sa1110_driver = {
- .flags = (CPUFREQ_PANIC_OUTOFSYNC |
- CPUFREQ_PANIC_RESUME_OUTOFSYNC),
+ .flags = CPUFREQ_STICKY |
+ CPUFREQ_PANIC_OUTOFSYNC |
+ CPUFREQ_PANIC_RESUME_OUTOFSYNC,
.verify = sa11x0_verify_speed,
.target = sa1110_target,
.get = sa11x0_getspeed,
# Makefile for the linux kernel.
#
-obj-y := core.o
+obj-y := core.o clock.o
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
return 0;
}
-void __flush_dcache_page(struct page *page)
+static void __flush_dcache_page(struct page *page)
{
struct address_space *mapping = page_mapping(page);
struct mm_struct *mm = current->active_mm;
flush_dcache_mmap_unlock(mapping);
}
+void flush_dcache_page(struct page *page)
+{
+ struct address_space *mapping = page_mapping(page);
+
+ if (mapping && !mapping_mapped(mapping))
+ set_bit(PG_dcache_dirty, &page->flags);
+ else
+ __flush_dcache_page(page);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
static void
make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
{
if (pmd_none(*pmd_k))
goto bad_area;
- set_pmd(pmd, *pmd_k);
+ copy_pmd(pmd, pmd_k);
return 0;
bad_area:
*/
cache_type = read_cpuid(CPUID_CACHETYPE);
if (cache_type != read_cpuid(CPUID_ID)) {
- aliasing = (cache_type | cache_type >> 12) & (1 << 9);
+ aliasing = (cache_type | cache_type >> 12) & (1 << 11);
if (aliasing)
do_align = filp || flags & MAP_SHARED;
}
#include <asm/proc-fns.h>
#include <asm/tlbflush.h>
-EXPORT_SYMBOL(__flush_dcache_page);
-
#ifndef MULTI_CPU
EXPORT_SYMBOL(cpu_dcache_clean_area);
EXPORT_SYMBOL(cpu_set_pte);
EXPORT_SYMBOL_NOVERS(__cpuc_flush_user_all);
EXPORT_SYMBOL_NOVERS(__cpuc_flush_user_range);
EXPORT_SYMBOL_NOVERS(__cpuc_coherent_kern_range);
-EXPORT_SYMBOL_NOVERS(__cpuc_flush_dcache_page);
#else
EXPORT_SYMBOL(cpu_cache);
#endif
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
-# Last update: Thu Apr 29 19:06:33 2004
+# Last update: Fri May 28 13:17:46 2004
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
smdk5500 MACH_SMDK5500 SMDK5500 499
signalsync MACH_SIGNALSYNC SIGNALSYNC 500
nbc MACH_NBC NBC 501
-er4525 MACH_ER4525 ER4525 502
+kodiak MACH_KODIAK KODIAK 502
netbookpro MACH_NETBOOKPRO NETBOOKPRO 503
hw90200 MACH_HW90200 HW90200 504
condor MACH_CONDOR CONDOR 505
tidsc25 MACH_TIDSC25 TIDSC25 523
akcpmxl MACH_AKCPMXL AKCPMXL 524
av3xx MACH_AV3XX AV3XX 525
+avila MACH_AVILA AVILA 526
+pxa_mpm10 MACH_PXA_MPM10 PXA_MPM10 527
+pxa_kyanite MACH_PXA_KYANITE PXA_KYANITE 528
+sgold MACH_SGOLD SGOLD 529
+oscar MACH_OSCAR OSCAR 530
+epxa4usb2 MACH_EPXA4USB2 EPXA4USB2 531
+xsengine MACH_XSENGINE XSENGINE 532
+ip600 MACH_IP600 IP600 533
+mcan2 MACH_MCAN2 MCAN2 534
+ddi_blueridge MACH_DDI_BLUERIDGE DDI_BLUERIDGE 535
+skyminder MACH_SKYMINDER SKYMINDER 536
+lpd79520 MACH_LPD79520 LPD79520 537
+edb9302 MACH_EDB9302 EDB9302 538
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
static int
e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
- struct net_local *np = (struct net_local *)dev->priv;
+ struct mii_ioctl_data *data = if_mii(ifr);
+ struct net_local *np = netdev_priv(dev);
spin_lock(&np->lock); /* Preempt protection */
switch (cmd) {
#include <linux/fs.h>
#include <linux/user.h>
#include <linux/elfcore.h>
+#include <linux/mqueue.h>
//#define DEBUG
config CONFIG_SH_STANDARD_BIOS
bool "Use gdb protocol serial console"
- depends on (!H8300H_SIM && H8S_SIM)
+ depends on (!H8300H_SIM && !H8S_SIM)
help
serial console output using GDB protocol.
Require eCos/RedBoot
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
case PTRACE_PEEKUSR: {
unsigned long tmp;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
+ if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
ret = -EIO;
+ break ;
+ }
- tmp = 0; /* Default return condition */
+ ret = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
+
if (addr < H8300_REGS_NO)
tmp = h8300_get_reg(child, addr);
else {
- ret = -EIO;
- break ;
+ switch(addr) {
+ case 49:
+ tmp = child->mm->start_code;
+ break ;
+ case 50:
+ tmp = child->mm->start_data;
+ break ;
+ case 51:
+ tmp = child->mm->end_code;
+ break ;
+ case 52:
+ tmp = child->mm->end_data;
+ break ;
+ default:
+ ret = -EIO;
+ }
}
- ret = put_user(tmp,(unsigned long *) data);
+ if (!ret)
+ ret = put_user(tmp,(unsigned long *) data);
break ;
}
mov.l @(LER0-LER1:16,sp),er1 /* restore ER0 */
mov.l er1,@er0
mov.w @(LEXR-LER1:16,sp),r1 /* restore EXR */
+ mov.b r1l,r1h
mov.w r1,@(8:16,er0)
mov.w @(LCCR-LER1:16,sp),r1 /* restore the RET addr */
mov.b r1l,r1h
jsr @SYMBOL_NAME(syscall_trace)
bra SYMBOL_NAME(ret_from_exception):8
-
SYMBOL_NAME_LABEL(ret_from_fork)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
static const int h8300_register_offset[] = {
PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4),
PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0),
- PT_REG(ccr), PT_REG(pc), PT_REG(exr)
+ PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr)
};
/* read register */
config X86_NUMAQ
bool "NUMAQ (IBM/Sequent)"
+ select DISCONTIGMEM
+ select NUMA
help
This option is used for getting Linux to run on a (IBM/Sequent) NUMA
multiquad box. This changes the way that processors are bootstrapped,
Choose N to continue using the legacy 8254 timer.
config HPET_EMULATE_RTC
- def_bool HPET_TIMER && RTC=y
+ bool "Provide RTC interrupt"
+ depends on HPET_TIMER && RTC=y
config SMP
bool "Symmetric multi-processing support"
config X86_MCE
bool "Machine Check Exception"
+ depends on !X86_VOYAGER
---help---
Machine Check Exception support allows the processor to notify the
kernel if it detects a problem (e.g. overheating, component failure).
This option is only useful on systems that have EFI firmware
and will result in a kernel image that is ~8k larger. In addition,
you must use the latest ELILO loader available at
- <ftp://ftp.hpl.hp.com/pub/linux-ia64/> in order to take advantage of
+ <http://elilo.sourceforge.net> in order to take advantage of
kernel initialization using EFI information (neither GRUB nor LILO know
anything about EFI). However, even with this option, the resultant
kernel should continue to boot on existing non-EFI platforms.
depends on X86_SMP || (X86_VOYAGER && SMP)
default y
-# std_resources is overridden for pc9800, but that's not
-# a currently selectable arch choice
-config X86_STD_RESOURCES
- bool
- default y
-
config PC
bool
depends on X86 && !EMBEDDED
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
CONFIG_LOG_BUF_SHIFT=15
CONFIG_HOTPLUG=y
# CONFIG_IKCONFIG is not set
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
#
# CONFIG_HPET_EMULATE_RTC is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=8
+CONFIG_SCHED_SMT=y
CONFIG_PREEMPT=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
#
# Generic Driver Options
#
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
#
# Memory Technology Devices (MTD)
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE 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_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_REPORT_LUNS=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+CONFIG_SCSI_DPT_I2O=m
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_SATA_SVW is not set
CONFIG_SCSI_ATA_PIIX=y
# CONFIG_SCSI_SATA_PROMISE is not set
+CONFIG_SCSI_SATA_SX4=m
# CONFIG_SCSI_SATA_SIL is not set
+CONFIG_SCSI_SATA_SIS=m
# CONFIG_SCSI_SATA_VIA is not set
# CONFIG_SCSI_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
+CONFIG_SCSI_IPR=m
+# CONFIG_SCSI_IPR_TRACE is not set
+# CONFIG_SCSI_IPR_DUMP is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_NET_SB1000 is not set
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
#
# Ethernet (10 or 100Mbit)
#
# CONFIG_8139TOO_TUNE_TWISTER is not set
# CONFIG_8139TOO_8129 is not set
# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_8139_RXBUF_IDX=2
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
+# Wireless LAN (non-hamradio)
#
-# CONFIG_IRDA is not set
+# CONFIG_NET_RADIO is not set
#
-# Bluetooth support
+# Wan interfaces
#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# ISDN subsystem
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_AMD64 is not set
CONFIG_AGP_INTEL=y
+CONFIG_AGP_INTEL_MCH=m
# CONFIG_AGP_NVIDIA is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_SWORKS is not set
#
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+CONFIG_USB_EGALAX=m
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_PHIDGETSERVO=m
# CONFIG_USB_TEST is not set
#
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_FRAME_POINTER is not set
+CONFIG_4KSTACKS=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y
# Library routines
#
CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
CONFIG_X86_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
+CONFIG_X86_STD_RESOURCES=y
CONFIG_PC=y
obj-$(CONFIG_HPET_TIMER) += time_hpet.o
obj-$(CONFIG_EFI) += efi.o efi_stub.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_X86_STD_RESOURCES) += std_resources.o
EXTRA_AFLAGS := -traditional -m32
#include <linux/acpi.h>
#include <linux/efi.h>
#include <linux/irq.h>
-#include <asm/pgalloc.h>
+#include <linux/module.h>
+
+#include <asm/pgtable.h>
#include <asm/io_apic.h>
#include <asm/apic.h>
#include <asm/io.h>
return 0;
}
+unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
+{
+ unsigned int irq;
+
+#ifdef CONFIG_PCI
+ /*
+ * Make sure all (legacy) PCI IRQs are set as level-triggered.
+ */
+ if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
+ static u16 irq_mask;
+ extern void eisa_set_level_irq(unsigned int irq);
+
+ if (edge_level == ACPI_LEVEL_SENSITIVE) {
+ if ((gsi < 16) && !((1 << gsi) & irq_mask)) {
+ Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi);
+ irq_mask |= (1 << gsi);
+ eisa_set_level_irq(gsi);
+ }
+ }
+ }
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+ if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
+ mp_register_gsi(gsi, edge_level, active_high_low);
+ }
+#endif
+ acpi_gsi_to_irq(gsi, &irq);
+ return irq;
+}
+EXPORT_SYMBOL(acpi_register_gsi);
+
static unsigned long __init
acpi_scan_rsdp (
unsigned long start,
#include <asm/smp.h>
#include <asm/mtrr.h>
#include <asm/mpspec.h>
-#include <asm/pgalloc.h>
#include <asm/desc.h>
#include <asm/arch_hooks.h>
#include <asm/hpet.h>
apic_write_around(APIC_LVT0, v);
}
+int get_physical_broadcast(void)
+{
+ unsigned int lvr, version;
+ lvr = apic_read(APIC_LVR);
+ version = GET_APIC_VERSION(lvr);
+ if (version >= 0x14)
+ return 0xff;
+ else
+ return 0xf;
+}
+
int get_maxlvt(void)
{
unsigned int v, ver, maxlvt;
static int __init elanfreq_setup(char *str)
{
max_freq = simple_strtoul(str, &str, 0);
+ printk(KERN_WARNING "You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n");
return 1;
}
__setup("elanfreq=", elanfreq_setup);
}
-MODULE_PARM (max_freq, "i");
+module_param (max_freq, int, 0444);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
static int pci_busclk = 0;
-MODULE_PARM(pci_busclk, "i");
+module_param (pci_busclk, int, 0444);
/* maximum duration for which the cpu may be suspended
* (32us * MAX_DURATION). If no parameter is given, this defaults
* is suspended -- processing power is just 0.39% of what it used to be,
* though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
static int max_duration = 255;
-MODULE_PARM(max_duration, "i");
+module_param (max_duration, int, 0444);
/* For the default policy, we want at least some processing power
* - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
static unsigned int numscales=16, numvscales;
static unsigned int fsb;
static int minvid, maxvid;
+static unsigned int minmult, maxmult;
static int can_scale_voltage;
static int vrmrev;
/* Module parameters */
static int dont_scale_voltage;
static int debug;
-static int debug;
-static void dprintk(const char *msg, ...)
+static void dprintk(const char *fmt, ...)
{
- if (debug == 1)
- printk(msg);
+ char s[256];
+ va_list args;
+
+ if (debug == 0)
+ return;
+
+ va_start(args, fmt);
+ vsprintf(s, fmt, args);
+ printk(s);
+ va_end(args);
}
static struct cpufreq_frequency_table *longhaul_table;
-static unsigned int calc_speed (int mult, int fsb)
+static unsigned int calc_speed(int mult, int fsb)
{
int khz;
khz = (mult/10)*fsb;
}
-static int longhaul_get_cpu_mult (void)
+static int longhaul_get_cpu_mult(void)
{
unsigned long invalue=0,lo, hi;
rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;
- if (longhaul_version==2) {
- if (lo & (1<<27))
- invalue+=16;
- }
- if (longhaul_version==4) {
+ if (longhaul_version==2 || longhaul_version==3) {
if (lo & (1<<27))
invalue+=16;
}
* Sets a new clock ratio, and -if applicable- a new Front Side Bus
*/
-static void longhaul_setstate (unsigned int clock_ratio_index)
+static void longhaul_setstate(unsigned int clock_ratio_index)
{
int speed, mult;
struct cpufreq_freqs freqs;
longhaul.bits.RevisionKey = 3;
wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
break;
- case 4:
+ case 3:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
#define ROUNDING 0xf
-static int _guess (int guess, int maxmult)
+static int _guess(int guess)
{
int target;
}
-static int guess_fsb(int maxmult)
+static int guess_fsb(void)
{
int speed = (cpu_khz/1000);
int i;
speed &= ~ROUNDING;
for (i=0; i<3; i++) {
- if (_guess(speeds[i],maxmult) == speed)
+ if (_guess(speeds[i]) == speed)
return speeds[i];
}
return 0;
}
-static int __init longhaul_get_ranges (void)
+static int __init longhaul_get_ranges(void)
{
struct cpuinfo_x86 *c = cpu_data;
- unsigned long invalue,invalue2;
- unsigned int minmult=0, maxmult=0;
+ unsigned long invalue;
unsigned int multipliers[32]= {
50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
unsigned int j, k = 0;
union msr_longhaul longhaul;
unsigned long lo, hi;
- unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
+ unsigned int eblcr_fsb_table_v1[] = { 66, 133, 100, -1 };
+ unsigned int eblcr_fsb_table_v2[] = { 133, 100, -1, 66 };
switch (longhaul_version) {
case 1:
rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
invalue = (lo & (1<<18|1<<19)) >>18;
if (c->x86_model==6)
- fsb = eblcr_fsb_table[invalue];
+ fsb = eblcr_fsb_table_v1[invalue];
else
- fsb = guess_fsb(maxmult);
+ fsb = guess_fsb();
break;
case 2:
else
minmult = multipliers[invalue];
- switch (longhaul.bits.MaxMHzFSB) {
- case 0x0: fsb=133;
- break;
- case 0x1: fsb=100;
- break;
- case 0x2: printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
- return -EINVAL;
- case 0x3: fsb=66;
- break;
- }
+ fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
break;
- case 4:
+ case 3:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
- //TODO: Nehemiah may have borken MaxMHzBR.
- // need to extrapolate from FSB.
-
- invalue2 = longhaul.bits.MinMHzBR;
- invalue = longhaul.bits.MaxMHzBR;
- if (longhaul.bits.MaxMHzBR4)
- invalue += 16;
- maxmult=multipliers[invalue];
-
- maxmult=longhaul_get_cpu_mult();
-
- printk(KERN_INFO PFX " invalue: %ld maxmult: %d \n", invalue, maxmult);
- printk(KERN_INFO PFX " invalue2: %ld \n", invalue2);
-
+ /*
+ * TODO: This code works, but raises a lot of questions.
+ * - Some Nehemiah's seem to have broken Min/MaxMHzBR's.
+ * We get around this by using a hardcoded multiplier of 5.0x
+ * for the minimimum speed, and the speed we booted up at for the max.
+ * This is done in longhaul_get_cpu_mult() by reading the EBLCR register.
+ * - According to some VIA documentation EBLCR is only
+ * in pre-Nehemiah C3s. How this still works is a mystery.
+ * We're possibly using something undocumented and unsupported,
+ * But it works, so we don't grumble.
+ */
minmult=50;
+ maxmult=longhaul_get_cpu_mult();
- switch (longhaul.bits.MaxMHzFSB) {
- case 0x0: fsb=133;
- break;
- case 0x1: fsb=100;
- break;
- case 0x2: printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
- return -EINVAL;
- case 0x3: fsb=66;
- break;
- }
-
+ fsb = eblcr_fsb_table_v2[longhaul.bits.MaxMHzFSB];
break;
}
dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n",
minmult/10, minmult%10, maxmult/10, maxmult%10);
+
+ if (fsb == -1) {
+ printk (KERN_INFO PFX "Invalid (reserved) FSB!\n");
+ return -EINVAL;
+ }
+
highest_speed = calc_speed (maxmult, fsb);
lowest_speed = calc_speed (minmult,fsb);
dprintk (KERN_INFO PFX "FSB: %dMHz Lowestspeed=%dMHz Highestspeed=%dMHz\n",
}
-static int longhaul_target (struct cpufreq_policy *policy,
+static int longhaul_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
return (calc_speed (longhaul_get_cpu_mult(), fsb));
}
-static int __init longhaul_cpu_init (struct cpufreq_policy *policy)
+static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = cpu_data;
char *cpuname=NULL;
break;
case 9:
- longhaul_version=4;
+ longhaul_version=3;
numscales=32;
switch (c->x86_mask) {
case 0 ... 1:
.attr = longhaul_attr,
};
-static int __init longhaul_init (void)
+static int __init longhaul_init(void)
{
struct cpuinfo_x86 *c = cpu_data;
return -ENODEV;
}
-static void __exit longhaul_exit (void)
+static void __exit longhaul_exit(void)
{
+ int i=0;
+ unsigned int new_clock_ratio;
+
+ while (clock_ratio[i] != maxmult)
+ i++;
+
+ new_clock_ratio = longhaul_table[i].index & 0xFF;
+ longhaul_setstate(new_clock_ratio);
+
cpufreq_unregister_driver(&longhaul_driver);
kfree(longhaul_table);
}
#include <linux/smp.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
+#include <linux/cpumask.h>
#include <asm/processor.h>
#include <asm/msr.h>
#endif
/* notifiers */
- for_each_cpu(i) {
- if (cpu_isset(i, affected_cpu_map)) {
- freqs.cpu = i;
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- }
+ for_each_cpu_mask(i, affected_cpu_map) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
}
/* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
* Developer's Manual, Volume 3
*/
- for_each_cpu(i) {
- if (cpu_isset(i, affected_cpu_map)) {
- cpumask_t this_cpu = cpumask_of_cpu(i);
+ for_each_cpu_mask(i, affected_cpu_map) {
+ cpumask_t this_cpu = cpumask_of_cpu(i);
- set_cpus_allowed(current, this_cpu);
- BUG_ON(smp_processor_id() != i);
+ set_cpus_allowed(current, this_cpu);
+ BUG_ON(smp_processor_id() != i);
- cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
- }
+ cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
}
set_cpus_allowed(current, cpus_allowed);
/* notifiers */
- for_each_cpu(i) {
- if (cpu_isset(i, affected_cpu_map)) {
- freqs.cpu = i;
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- }
+ for_each_cpu_mask(i, affected_cpu_map) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
return 0;
#include <asm/io.h>
#include <asm/system.h>
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
u8 numpstates;
};
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
union powernow_acpi_control_t {
struct {
unsigned long fid:5,
}
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
struct acpi_processor_performance *acpi_processor_perf;
static void __exit powernow_exit (void)
{
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
if (acpi_processor_perf) {
acpi_processor_unregister_performance(acpi_processor_perf, 0);
kfree(acpi_processor_perf);
continue;
}
- /* verify only 1 entry from the lo frequency table */
- if ((fid < HI_FID_TABLE_BOTTOM) && (cntlofreq++)) {
- printk(KERN_ERR PFX "Too many lo freq table entries\n");
- goto err_out_mem;
+ if (fid < HI_FID_TABLE_BOTTOM) {
+ if (cntlofreq) {
+ /* if both entries are the same, ignore this
+ * one...
+ */
+ if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
+ (powernow_table[i].index != powernow_table[cntlofreq].index)) {
+ printk(KERN_ERR PFX "Too many lo freq table entries\n");
+ goto err_out_mem;
+ }
+
+ dprintk(KERN_INFO PFX "double low frequency table entry, ignoring it.\n");
+ powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ continue;
+ } else
+ cntlofreq = i;
}
if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
- goto sched_out;
+ goto err_out;
}
- /* from this point, do not exit without restoring preempt and cpu */
- preempt_disable();
-
if (pending_bit_stuck()) {
printk(KERN_ERR PFX "failing targ, change pending bit set\n");
goto err_out;
ret = 0;
err_out:
- preempt_enable_no_resched();
-sched_out:
set_cpus_allowed(current, oldmask);
schedule();
return -ENODEV;
}
-static int __exit powernowk8_cpu_exit (struct cpufreq_policy *pol)
+static int powernowk8_cpu_exit (struct cpufreq_policy *pol)
{
struct powernow_k8_data *data = powernow_data[pol->cpu];
.verify = powernowk8_verify,
.target = powernowk8_target,
.init = powernowk8_cpu_init,
- .exit = powernowk8_cpu_exit,
+ .exit = __devexit_p(powernowk8_cpu_exit),
.get = powernowk8_get,
.name = "powernow-k8",
.owner = THIS_MODULE,
}
/* driver entry point for term */
-static void __exit powernowk8_exit(void)
+static void powernowk8_exit(void)
{
dprintk(KERN_INFO PFX "exit\n");
/**
* speedstep_set_state - set the SpeedStep state
* @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- * @notify: whether to call cpufreq_notify_transition for CPU speed changes
*
* Tries to change the SpeedStep state.
*/
-static void speedstep_set_state (unsigned int state, unsigned int notify)
+static void speedstep_set_state (unsigned int state)
{
u32 pmbase;
u8 pm2_blk;
u8 value;
unsigned long flags;
- struct cpufreq_freqs freqs;
if (!speedstep_chipset_dev || (state > 0x1))
return;
- freqs.old = speedstep_get_processor_frequency(speedstep_processor);
- freqs.new = speedstep_freqs[state].frequency;
- freqs.cpu = 0; /* speedstep.c is UP only driver */
-
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01))
printk (KERN_ERR "cpufreq: change failed - I/O error\n");
}
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
return;
}
unsigned int relation)
{
unsigned int newstate = 0;
+ struct cpufreq_freqs freqs;
+ cpumask_t cpus_allowed, affected_cpu_map;
+ int i;
if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
return -EINVAL;
- speedstep_set_state(newstate, 1);
+ /* no transition necessary */
+ if (freqs.old == freqs.new)
+ return 0;
+
+ freqs.old = speedstep_get_processor_frequency(speedstep_processor);
+ freqs.new = speedstep_freqs[newstate].frequency;
+ freqs.cpu = policy->cpu;
+
+ cpus_allowed = current->cpus_allowed;
+
+ /* only run on CPU to be set, or on its sibling */
+#ifdef CONFIG_SMP
+ affected_cpu_map = cpu_sibling_map[policy->cpu];
+#else
+ affected_cpu_map = cpumask_of_cpu(policy->cpu);
+#endif
+
+ for_each_cpu_mask(i, affected_cpu_map) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+
+ /* switch to physical CPU where state is to be changed */
+ set_cpus_allowed(current, affected_cpu_map);
+
+ speedstep_set_state(newstate);
+
+ /* allow to be run on all CPUs */
+ set_cpus_allowed(current, cpus_allowed);
+
+ for_each_cpu_mask(i, affected_cpu_map) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
return 0;
}
{
int result = 0;
unsigned int speed;
+ cpumask_t cpus_allowed,affected_cpu_map;
+
/* capability check */
- if (policy->cpu != 0)
+ if (policy->cpu != 0) /* FIXME: better support for SMT in cpufreq core. Up until then, it's better to register only one CPU */
return -ENODEV;
+ /* only run on CPU to be set, or on its sibling */
+ cpus_allowed = current->cpus_allowed;
+#ifdef CONFIG_SMP
+ affected_cpu_map = cpu_sibling_map[policy->cpu];
+#else
+ affected_cpu_map = cpumask_of_cpu(policy->cpu);
+#endif
+ set_cpus_allowed(current, affected_cpu_map);
+
/* detect low and high frequency */
result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
&speedstep_set_state);
- if (result)
+ if (result) {
+ set_cpus_allowed(current, cpus_allowed);
return result;
+ }
/* get current speed setting */
speed = speedstep_get_processor_frequency(speedstep_processor);
+ set_cpus_allowed(current, cpus_allowed);
if (!speed)
return -EIO;
* specific.
* M-P4-Ms may have either ebx=0xe or 0xf [see above]
* M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
- * So, how to distinguish all those processors with
- * ebx=0xf? I don't know. Sort them out, and wait
- * for someone to complain.
+ * also, M-P4M HTs have ebx=0x8, too
+ * For now, they are distinguished by the model_id string
*/
- if (ebx == 0x0e)
+ if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL))
return SPEEDSTEP_PROCESSOR_P4M;
break;
default:
unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed,
unsigned int *high_speed,
- void (*set_state) (unsigned int state,
- unsigned int notify)
- )
+ void (*set_state) (unsigned int state))
{
unsigned int prev_speed;
unsigned int ret = 0;
local_irq_save(flags);
/* switch to low state */
- set_state(SPEEDSTEP_LOW, 0);
+ set_state(SPEEDSTEP_LOW);
*low_speed = speedstep_get_processor_frequency(processor);
if (!*low_speed) {
ret = -EIO;
}
/* switch to high state */
- set_state(SPEEDSTEP_HIGH, 0);
+ set_state(SPEEDSTEP_HIGH);
*high_speed = speedstep_get_processor_frequency(processor);
if (!*high_speed) {
ret = -EIO;
/* switch to previous state, if necessary */
if (*high_speed != prev_speed)
- set_state(SPEEDSTEP_LOW, 0);
+ set_state(SPEEDSTEP_LOW);
out:
local_irq_restore(flags);
extern unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed,
unsigned int *high_speed,
- void (*set_state) (unsigned int state, unsigned int notify));
+ void (*set_state) (unsigned int state));
: "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0)
);
- return state;
+ return (state & 1);
}
/**
* speedstep_set_state - set the SpeedStep state
* @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- * @notify: whether to call cpufreq_notify_transition
*
*/
-static void speedstep_set_state (unsigned int state, unsigned int notify)
+static void speedstep_set_state (unsigned int state)
{
- unsigned int old_state, result = 0, command, new_state;
+ unsigned int result = 0, command, new_state;
unsigned long flags;
- struct cpufreq_freqs freqs;
unsigned int function=SET_SPEEDSTEP_STATE;
unsigned int retry = 0;
if (state > 0x1)
return;
- old_state = speedstep_get_state();
- freqs.old = speedstep_freqs[old_state].frequency;
- freqs.new = speedstep_freqs[state].frequency;
- freqs.cpu = 0; /* speedstep.c is UP only driver */
-
- if (old_state == state)
- return;
-
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
/* Disable IRQs */
local_irq_save(flags);
printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result);
}
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
return;
}
unsigned int target_freq, unsigned int relation)
{
unsigned int newstate = 0;
+ struct cpufreq_freqs freqs;
if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
return -EINVAL;
- speedstep_set_state(newstate, 1);
+ freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
+ freqs.new = speedstep_freqs[newstate].frequency;
+ freqs.cpu = 0; /* speedstep.c is UP only driver */
+
+ if (freqs.old == freqs.new)
+ return 0;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ speedstep_set_state(newstate);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
}
#ifdef CONFIG_ACPI_PCI
static __init int disable_acpi_irq(struct dmi_blacklist *d)
-{
- printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", d->ident);
- acpi_noirq_set();
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
+ d->ident);
+ acpi_noirq_set();
+ }
return 0;
}
static __init int disable_acpi_pci(struct dmi_blacklist *d)
-{
- printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);
- acpi_disable_pci();
+{
+ if (!acpi_force) {
+ printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
+ d->ident);
+ acpi_disable_pci();
+ }
return 0;
}
#endif
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/desc.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#define EFI_DEBUG 0
#include <asm/mmx.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/nmi.h>
#include <asm/ist.h>
* be shot.
*/
-/*
- * =PC9800NOTE= In NEC PC-9800, we use irq8 instead of irq13!
- */
static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
{
extern void math_error(void *);
-#ifndef CONFIG_X86_PC9800
outb(0,0xF0);
-#endif
if (ignore_fpu_irq || !boot_cpu_data.hard_math)
return IRQ_NONE;
math_error((void *)regs->eip);
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include "io_ports.h"
-#undef APIC_LOCKUP_DEBUG
-
-#define APIC_LOCKUP_DEBUG
-
static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
/*
}
}
-/* mask = 1 */
-static void __mask_IO_APIC_irq (unsigned int irq)
+static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable)
{
- int pin;
struct irq_pin_list *entry = irq_2_pin + irq;
+ unsigned int pin, reg;
for (;;) {
- unsigned int reg;
pin = entry->pin;
if (pin == -1)
break;
reg = io_apic_read(entry->apic, 0x10 + pin*2);
- io_apic_modify(entry->apic, 0x10 + pin*2, reg |= 0x00010000);
+ reg &= ~disable;
+ reg |= enable;
+ io_apic_modify(entry->apic, 0x10 + pin*2, reg);
if (!entry->next)
break;
entry = irq_2_pin + entry->next;
}
- io_apic_sync(entry->apic);
+}
+
+/* mask = 1 */
+static void __mask_IO_APIC_irq (unsigned int irq)
+{
+ __modify_IO_APIC_irq(irq, 0x00010000, 0);
}
/* mask = 0 */
static void __unmask_IO_APIC_irq (unsigned int irq)
{
- int pin;
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- for (;;) {
- unsigned int reg;
- pin = entry->pin;
- if (pin == -1)
- break;
- reg = io_apic_read(entry->apic, 0x10 + pin*2);
- io_apic_modify(entry->apic, 0x10 + pin*2, reg &= 0xfffeffff);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
+ __modify_IO_APIC_irq(irq, 0, 0x00010000);
}
/* mask = 1, trigger = 0 */
static void __mask_and_edge_IO_APIC_irq (unsigned int irq)
{
- int pin;
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- for (;;) {
- unsigned int reg;
- pin = entry->pin;
- if (pin == -1)
- break;
- reg = io_apic_read(entry->apic, 0x10 + pin*2);
- reg = (reg & 0xffff7fff) | 0x00010000;
- io_apic_modify(entry->apic, 0x10 + pin*2, reg);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
+ __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000);
}
/* mask = 0, trigger = 1 */
static void __unmask_and_level_IO_APIC_irq (unsigned int irq)
{
- int pin;
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- for (;;) {
- unsigned int reg;
- pin = entry->pin;
- if (pin == -1)
- break;
- reg = io_apic_read(entry->apic, 0x10 + pin*2);
- reg = (reg & 0xfffeffff) | 0x00008000;
- io_apic_modify(entry->apic, 0x10 + pin*2, reg);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
+ __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000);
}
static void mask_IO_APIC_irq (unsigned int irq)
printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID);
printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type);
printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS);
- if (reg_00.bits.ID >= APIC_BROADCAST_ID)
+ if (reg_00.bits.ID >= get_physical_broadcast())
UNEXPECTED_IO_APIC();
if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2)
UNEXPECTED_IO_APIC();
old_id = mp_ioapics[apic].mpc_apicid;
- if (mp_ioapics[apic].mpc_apicid >= APIC_BROADCAST_ID) {
+ if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid);
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
mp_ioapics[apic].mpc_apicid)) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
apic, mp_ioapics[apic].mpc_apicid);
- for (i = 0; i < APIC_BROADCAST_ID; i++)
+ for (i = 0; i < get_physical_broadcast(); i++)
if (!physid_isset(i, phys_id_present_map))
break;
- if (i >= APIC_BROADCAST_ID)
+ if (i >= get_physical_broadcast())
panic("Max APIC ID exceeded!\n");
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
i);
ack_APIC_irq();
if (!(v & (1 << (i & 0x1f)))) {
-#ifdef APIC_LOCKUP_DEBUG
- struct irq_pin_list *entry;
-#endif
-
#ifdef APIC_MISMATCH_DEBUG
atomic_inc(&irq_mis_count);
#endif
spin_lock(&ioapic_lock);
__mask_and_edge_IO_APIC_irq(irq);
-#ifdef APIC_LOCKUP_DEBUG
- for (entry = irq_2_pin + irq;;) {
- unsigned int reg;
-
- if (entry->pin == -1)
- break;
- reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2);
- if (reg & 0x00004000)
- printk(KERN_CRIT "Aieee!!! Remote IRR"
- " still set after unlock!\n");
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
-#endif
__unmask_and_level_IO_APIC_irq(irq);
spin_unlock(&ioapic_lock);
}
#ifdef CONFIG_ACPI_BOOT
-#define IO_APIC_MAX_ID APIC_BROADCAST_ID
-
int __init io_apic_get_unique_id (int ioapic, int apic_id)
{
union IO_APIC_reg_00 reg_00;
reg_00.raw = io_apic_read(ioapic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags);
- if (apic_id >= IO_APIC_MAX_ID) {
+ if (apic_id >= get_physical_broadcast()) {
printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
"%d\n", ioapic, apic_id, reg_00.bits.ID);
apic_id = reg_00.bits.ID;
*/
if (check_apicid_used(apic_id_map, apic_id)) {
- for (i = 0; i < IO_APIC_MAX_ID; i++) {
+ for (i = 0; i < get_physical_broadcast(); i++) {
if (!check_apicid_used(apic_id_map, i))
break;
}
- if (i == IO_APIC_MAX_ID)
+ if (i == get_physical_broadcast())
panic("Max apic_id exceeded!\n");
printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/delay.h>
#include <asm/desc.h>
#include <asm/irq.h>
irq, action_ret);
} else {
printk(KERN_ERR "irq %d: nobody cared! (screaming interrupt?)\n", irq);
+ printk(KERN_ERR "irq %d: Please try booting with acpi=off and report a bug\n", irq);
}
dump_stack();
printk(KERN_ERR "handlers:\n");
#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
+#include <linux/bitops.h>
#include <asm/smp.h>
#include <asm/acpi.h>
#include <asm/mtrr.h>
#include <asm/mpspec.h>
-#include <asm/pgalloc.h>
#include <asm/io_apic.h>
#include <mach_apic.h>
static int mpc_record;
static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
+#ifdef CONFIG_X86_NUMAQ
+static int MP_valid_apicid(int apicid, int version)
+{
+ return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf;
+}
+#else
+static int MP_valid_apicid(int apicid, int version)
+{
+ if (version >= 0x14)
+ return apicid < 0xff;
+ else
+ return apicid < 0xf;
+}
+#endif
+
void __init MP_processor_info (struct mpc_config_processor *m)
{
int ver, apicid;
return;
}
num_processors++;
+ ver = m->mpc_apicver;
- if (MAX_APICS - m->mpc_apicid <= 0) {
+ if (!MP_valid_apicid(apicid, ver)) {
printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
m->mpc_apicid, MAX_APICS);
--num_processors;
return;
}
- ver = m->mpc_apicver;
tmp = apicid_to_cpu_present(apicid);
physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp);
MP_processor_info(&processor);
}
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER)
+#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT))
#define MP_ISA_BUS 0
#define MP_MAX_IOAPIC_PIN 127
} mp_ioapic_routing[MAX_IO_APICS];
-static int __init mp_find_ioapic (
+static int mp_find_ioapic (
int gsi)
{
int i = 0;
for (idx = 0; idx < mp_irq_entries; idx++)
if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+ (mp_irqs[idx].mpc_dstapic == ioapic) &&
(mp_irqs[idx].mpc_srcbusirq == i ||
mp_irqs[idx].mpc_dstirq == i))
break;
}
}
-extern FADT_DESCRIPTOR acpi_fadt;
-
-#ifdef CONFIG_ACPI_PCI
-
int (*platform_rename_gsi)(int ioapic, int gsi);
-void __init mp_parse_prt (void)
+void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
{
- struct list_head *node = NULL;
- struct acpi_prt_entry *entry = NULL;
int ioapic = -1;
int ioapic_pin = 0;
- int gsi = 0;
int idx, bit = 0;
- int edge_level = 0;
- int active_high_low = 0;
- /*
- * Parsing through the PCI Interrupt Routing Table (PRT) and program
- * routing for all entries.
- */
- list_for_each(node, &acpi_prt.entries) {
- entry = list_entry(node, struct acpi_prt_entry, node);
-
- /* Need to get gsi for dynamic entry */
- if (entry->link.handle) {
- gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
- if (!gsi)
- continue;
- }
- else {
- /* Hardwired GSI. Assume PCI standard settings */
- gsi = entry->link.index;
- edge_level = 1;
- active_high_low = 1;
- }
+#ifdef CONFIG_ACPI_BUS
+ /* Don't set up the ACPI SCI because it's already set up */
+ if (acpi_fadt.sci_int == gsi)
+ return;
+#endif
- /* Don't set up the ACPI SCI because it's already set up */
- if (acpi_fadt.sci_int == gsi) {
- /* we still need to set entry's irq */
- acpi_gsi_to_irq(gsi, &entry->irq);
- continue;
- }
-
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- continue;
- ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
-
- if (platform_rename_gsi)
- gsi = platform_rename_gsi(ioapic, gsi);
-
- /*
- * Avoid pin reprogramming. PRTs typically include entries
- * with redundant pin->gsi mappings (but unique PCI devices);
- * we only only program the IOAPIC on the first.
- */
- bit = ioapic_pin % 32;
- idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
- if (idx > 3) {
- printk(KERN_ERR "Invalid reference to IOAPIC pin "
- "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
- ioapic_pin);
- continue;
- }
- if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
- Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
- mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
- acpi_gsi_to_irq(gsi, &entry->irq);
- continue;
- }
+ ioapic = mp_find_ioapic(gsi);
+ if (ioapic < 0) {
+ printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
+ return;
+ }
- mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+ ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
- if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) {
- acpi_gsi_to_irq(gsi, &entry->irq);
- }
- printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s %s\n",
- entry->id.segment, entry->id.bus,
- entry->id.device, ('A' + entry->pin),
- mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
- entry->irq, edge_level ? "level" : "edge",
- active_high_low ? "low" : "high");
+ if (platform_rename_gsi)
+ gsi = platform_rename_gsi(ioapic, gsi);
+
+ /*
+ * Avoid pin reprogramming. PRTs typically include entries
+ * with redundant pin->gsi mappings (but unique PCI devices);
+ * we only program the IOAPIC on the first.
+ */
+ bit = ioapic_pin % 32;
+ idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
+ if (idx > 3) {
+ printk(KERN_ERR "Invalid reference to IOAPIC pin "
+ "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
+ ioapic_pin);
+ return;
+ }
+ if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+ Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
+ mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+ return;
}
- print_IO_APIC();
+ mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
- return;
+ io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
+ edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
+ active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
}
-#endif /*CONFIG_ACPI_PCI*/
-#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/
+#endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/
#endif /*CONFIG_ACPI_BOOT*/
if (!strncmp(str, "poll", 4)) {
printk("using polling idle threads.\n");
pm_idle = poll_idle;
-#ifdef CONFIG_SMP
+#ifdef CONFIG_X86_SMP
if (smp_num_siblings > 1)
printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
#endif
#include <asm/sections.h>
#include <asm/io_apic.h>
#include <asm/ist.h>
-#include <asm/std_resources.h>
+#include <asm/io.h>
#include "setup_arch_pre.h"
/* This value is set up by the early boot code to point to the value
unsigned char __initdata boot_params[PARAM_SIZE];
-static struct resource code_resource = { "Kernel code", 0x100000, 0 };
-static struct resource data_resource = { "Kernel data", 0, 0 };
+static struct resource data_resource = {
+ .name = "Kernel data",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource code_resource = {
+ .name = "Kernel code",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource system_rom_resource = {
+ .name = "System ROM",
+ .start = 0xf0000,
+ .end = 0xfffff,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource extension_rom_resource = {
+ .name = "Extension ROM",
+ .start = 0xe0000,
+ .end = 0xeffff,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource adapter_rom_resources[] = { {
+ .name = "Adapter ROM",
+ .start = 0xc8000,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+ .name = "Adapter ROM",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+ .name = "Adapter ROM",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+ .name = "Adapter ROM",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+ .name = "Adapter ROM",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+ .name = "Adapter ROM",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+} };
+
+#define ADAPTER_ROM_RESOURCES \
+ (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
+
+static struct resource video_rom_resource = {
+ .name = "Video ROM",
+ .start = 0xc0000,
+ .end = 0xc7fff,
+ .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource video_ram_resource = {
+ .name = "Video RAM area",
+ .start = 0xa0000,
+ .end = 0xbffff,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource standard_io_resources[] = { {
+ .name = "dma1",
+ .start = 0x0000,
+ .end = 0x001f,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "pic1",
+ .start = 0x0020,
+ .end = 0x0021,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "timer",
+ .start = 0x0040,
+ .end = 0x005f,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "keyboard",
+ .start = 0x0060,
+ .end = 0x006f,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "dma page reg",
+ .start = 0x0080,
+ .end = 0x008f,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "pic2",
+ .start = 0x00a0,
+ .end = 0x00a1,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "dma2",
+ .start = 0x00c0,
+ .end = 0x00df,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+}, {
+ .name = "fpu",
+ .start = 0x00f0,
+ .end = 0x00ff,
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO
+} };
+
+#define STANDARD_IO_RESOURCES \
+ (sizeof standard_io_resources / sizeof standard_io_resources[0])
+
+#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
+
+static int __init romchecksum(unsigned char *rom, unsigned long length)
+{
+ unsigned char *p, sum = 0;
+
+ for (p = rom; p < rom + length; p++)
+ sum += *p;
+ return sum == 0;
+}
+
+static void __init probe_roms(void)
+{
+ unsigned long start, length, upper;
+ unsigned char *rom;
+ int i;
+
+ /* video rom */
+ upper = adapter_rom_resources[0].start;
+ for (start = video_rom_resource.start; start < upper; start += 2048) {
+ rom = isa_bus_to_virt(start);
+ if (!romsignature(rom))
+ continue;
+
+ video_rom_resource.start = start;
+
+ /* 0 < length <= 0x7f * 512, historically */
+ length = rom[2] * 512;
+
+ /* if checksum okay, trust length byte */
+ if (length && romchecksum(rom, length))
+ video_rom_resource.end = start + length - 1;
+
+ request_resource(&iomem_resource, &video_rom_resource);
+ break;
+ }
+
+ start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
+ if (start < upper)
+ start = upper;
+
+ /* system rom */
+ request_resource(&iomem_resource, &system_rom_resource);
+ upper = system_rom_resource.start;
+
+ /* check for extension rom (ignore length byte!) */
+ rom = isa_bus_to_virt(extension_rom_resource.start);
+ if (romsignature(rom)) {
+ length = extension_rom_resource.end - extension_rom_resource.start + 1;
+ if (romchecksum(rom, length)) {
+ request_resource(&iomem_resource, &extension_rom_resource);
+ upper = extension_rom_resource.start;
+ }
+ }
+
+ /* check for adapter roms on 2k boundaries */
+ for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) {
+ rom = isa_bus_to_virt(start);
+ if (!romsignature(rom))
+ continue;
+
+ /* 0 < length <= 0x7f * 512, historically */
+ length = rom[2] * 512;
+
+ /* but accept any length that fits if checksum okay */
+ if (!length || start + length > upper || !romchecksum(rom, length))
+ continue;
+
+ adapter_rom_resources[i].start = start;
+ adapter_rom_resources[i].end = start + length - 1;
+ request_resource(&iomem_resource, &adapter_rom_resources[i]);
+
+ start = adapter_rom_resources[i++].end & ~2047UL;
+ }
+}
static void __init limit_regions(unsigned long long size)
{
static void __init register_memory(unsigned long max_low_pfn)
{
unsigned long low_mem_size;
+ int i;
if (efi_enabled)
efi_initialize_iomem_resources(&code_resource, &data_resource);
legacy_init_iomem_resources(&code_resource, &data_resource);
/* EFI systems may still have VGA */
- request_graphics_resource();
+ request_resource(&iomem_resource, &video_ram_resource);
/* request I/O space for devices used on all i[345]86 PCs */
- request_standard_io_resources();
+ for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ request_resource(&ioport_resource, &standard_io_resources[i]);
/* Tell the PCI layer not to allocate too close to the RAM area.. */
low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
}
asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
+sys_rt_sigsuspend(struct pt_regs regs)
{
- struct pt_regs * regs = (struct pt_regs *) &unewset;
sigset_t saveset, newset;
/* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
+ if (regs.ecx != sizeof(sigset_t))
return -EINVAL;
- if (copy_from_user(&newset, unewset, sizeof(newset)))
+ if (copy_from_user(&newset, (sigset_t __user *)regs.ebx, sizeof(newset)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- regs->eax = -EINTR;
+ regs.eax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(regs, &saveset))
+ if (do_signal(®s, &saveset))
return -EINTR;
}
}
}
asmlinkage int
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
+sys_sigaltstack(struct pt_regs regs)
{
- struct pt_regs *regs = (struct pt_regs *) &uss;
- return do_sigaltstack(uss, uoss, regs->esp);
+ const stack_t __user *uss = (const stack_t __user *)regs.ebx;
+ stack_t __user *uoss = (stack_t __user *)regs.ecx;
+ return do_sigaltstack(uss, uoss, regs.esp);
}
#include <linux/interrupt.h>
#include <asm/mtrr.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <mach_ipi.h>
#include <mach_apic.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/desc.h>
#include <asm/arch_hooks.h>
#include <linux/config.h>
#include <asm/hpet.h>
+#include <linux/hpet.h>
unsigned long hpet_period; /* fsecs / HPET clock */
unsigned long hpet_tick; /* hpet clks count per tick */
hpet_writel(cfg, HPET_CFG);
use_hpet = 1;
+
+#ifdef CONFIG_HPET
+ {
+ struct hpet_data hd;
+ unsigned int ntimer;
+
+ memset(&hd, 0, sizeof (hd));
+
+ ntimer = hpet_readl(HPET_ID);
+ ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
+ ntimer++;
+
+ /*
+ * Register with driver.
+ * Timer0 and Timer1 is used by platform.
+ */
+ hd.hd_address = hpet_virt_address;
+ hd.hd_nirqs = ntimer;
+ hd.hd_flags = HPET_DATA_PLATFORM;
+#ifndef CONFIG_HPET_EMULATE_RTC
+ hd.hd_state = 0x1;
+#else
+ hd.hd_state = 0x3;
+#endif
+ hd.hd_irq[0] = HPET_LEGACY_8254;
+ hd.hd_irq[1] = HPET_LEGACY_RTC;
+ if (ntimer > 2) {
+ struct hpet *hpet;
+ struct hpet_timer *timer;
+ int i;
+
+ hpet = (struct hpet *) hpet_virt_address;
+
+ for (i = 2, timer = &hpet->hpet_timers[2]; i < ntimer;
+ timer++, i++)
+ hd.hd_irq[i] = (timer->hpet_config &
+ Tn_INT_ROUTE_CNF_MASK) >>
+ Tn_INT_ROUTE_CNF_SHIFT;
+
+ }
+
+ hpet_alloc(&hd);
+ }
+#endif
+
#ifdef CONFIG_X86_LOCAL_APIC
wait_timer_tick = wait_hpet_tick;
#endif
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/fixmap.h>
+#include "io_ports.h"
extern spinlock_t i8253_lock;
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
+
+ /*
+ * VIA686a test code... reset the latch if count > max + 1
+ * from timer_pit.c - cjb
+ */
+ if (count > LATCH) {
+ outb_p(0x34, PIT_MODE);
+ outb_p(LATCH & 0xff, PIT_CH0);
+ outb(LATCH >> 8, PIT_CH0);
+ count = LATCH - 1;
+ }
spin_unlock(&i8253_lock);
/* lost tick compensation */
#include <asm/io.h>
#include <asm/arch_hooks.h>
+#include <linux/timex.h>
+#include "mach_timer.h"
+
+/* Number of PMTMR ticks expected during calibration run */
+#define PMTMR_TICKS_PER_SEC 3579545
+#define PMTMR_EXPECTED_RATE \
+ ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
+
/* The I/O port the PMTMR resides at.
* The location is detected during setup_arch(),
return v2 & ACPI_PM_MASK;
}
+
+/*
+ * Some boards have the PMTMR running way too fast. We check
+ * the PMTMR rate against PIT channel 2 to catch these cases.
+ */
+static int verify_pmtmr_rate(void)
+{
+ u32 value1, value2;
+ unsigned long count, delta;
+
+ mach_prepare_counter();
+ value1 = read_pmtmr();
+ mach_countup(&count);
+ value2 = read_pmtmr();
+ delta = (value2 - value1) & ACPI_PM_MASK;
+
+ /* Check that the PMTMR delta is within 5% of what we expect */
+ if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
+ delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
+ printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE);
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int init_pmtmr(char* override)
{
u32 value1, value2;
return -ENODEV;
pm_good:
+ if (verify_pmtmr_rate() != 0)
+ return -ENODEV;
+
init_cpu_khz();
return 0;
}
#include <asm/nmi.h>
#include <asm/smp.h>
-#include <asm/pgalloc.h>
#include <asm/arch_hooks.h>
#include <linux/irq.h>
break;
printk(" =======================\n");
}
- printk("\n");
}
void show_stack(struct task_struct *task, unsigned long *esp)
file = "<bad filename>";
printk("------------[ cut here ]------------\n");
- printk("kernel BUG at %s:%d!\n", file, line);
+ printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
no_bug:
return;
spin_lock_irq(&die_lock);
bust_spinlocks(1);
handle_BUG(regs);
- printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+ printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
#ifdef CONFIG_PREEMPT
printk("PREEMPT ");
nl = 1;
#include <linux/ptrace.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/io.h>
#include <asm/tlbflush.h>
#include <asm/irq.h>
static int do_vm86_irq_handling(int subfunction, int irqnumber);
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
-asmlinkage int sys_vm86old(struct vm86_struct __user * v86)
+asmlinkage int sys_vm86old(struct pt_regs regs)
{
+ struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.ebx;
struct kernel_vm86_struct info; /* declare this _on top_,
* this avoids wasting of stack space.
* This remains on the stack until we
if (tmp)
goto out;
memset(&info.vm86plus, 0, (int)&info.regs32 - (int)&info.vm86plus);
- info.regs32 = (struct pt_regs *) &v86;
+ info.regs32 = ®s;
tsk->thread.vm86_info = v86;
do_sys_vm86(&info, tsk);
ret = 0; /* we never return here */
}
-asmlinkage int sys_vm86(unsigned long subfunction, struct vm86plus_struct __user * v86)
+asmlinkage int sys_vm86(struct pt_regs regs)
{
struct kernel_vm86_struct info; /* declare this _on top_,
* this avoids wasting of stack space.
*/
struct task_struct *tsk;
int tmp, ret;
+ struct vm86plus_struct __user *v86;
tsk = current;
- switch (subfunction) {
+ switch (regs.ebx) {
case VM86_REQUEST_IRQ:
case VM86_FREE_IRQ:
case VM86_GET_IRQ_BITS:
case VM86_GET_AND_RESET_IRQ:
- ret = do_vm86_irq_handling(subfunction,(int)v86);
+ ret = do_vm86_irq_handling(regs.ebx, (int)regs.ecx);
goto out;
case VM86_PLUS_INSTALL_CHECK:
/* NOTE: on old vm86 stuff this will return the error
ret = -EPERM;
if (tsk->thread.saved_esp0)
goto out;
+ v86 = (struct vm86plus_struct __user *)regs.ecx;
tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1);
tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2,
(long)&info.regs32 - (long)&info.regs.VM86_REGS_PART2);
ret = -EFAULT;
if (tmp)
goto out;
- info.regs32 = (struct pt_regs *) &subfunction;
+ info.regs32 = ®s;
info.vm86plus.is_vm86pus = 1;
tsk->thread.vm86_info = (struct vm86_struct __user *)v86;
do_sys_vm86(&info, tsk);
* in userspace is always better than an Oops anyway.) [KD]
*/
static void do_int(struct kernel_vm86_regs *regs, int i,
- unsigned char * ssp, unsigned short sp)
+ unsigned char __user * ssp, unsigned short sp)
{
- unsigned long *intr_ptr, segoffs;
+ unsigned long __user *intr_ptr;
+ unsigned long segoffs;
if (regs->cs == BIOSSEG)
goto cannot_handle;
goto cannot_handle;
if (i==0x21 && is_revectored(AH(regs),&KVM86->int21_revectored))
goto cannot_handle;
- intr_ptr = (unsigned long *) (i << 2);
+ intr_ptr = (unsigned long __user *) (i << 2);
if (get_user(segoffs, intr_ptr))
goto cannot_handle;
if ((segoffs >> 16) == BIOSSEG)
if (VMPI.is_vm86pus) {
if ( (trapno==3) || (trapno==1) )
return_to_32bit(regs, VM86_TRAP + (trapno << 8));
- do_int(regs, trapno, (unsigned char *) (regs->ss << 4), SP(regs));
+ do_int(regs, trapno, (unsigned char __user *) (regs->ss << 4), SP(regs));
return 0;
}
if (trapno !=1)
void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
{
- unsigned char *csp, *ssp, opcode;
+ unsigned char opcode;
+ unsigned char __user *csp;
+ unsigned char __user *ssp;
unsigned short ip, sp;
int data32, pref_done;
return_to_32bit(regs, VM86_PICRETURN); \
return; } while (0)
- csp = (unsigned char *) (regs->cs << 4);
- ssp = (unsigned char *) (regs->ss << 4);
+ csp = (unsigned char __user *) (regs->cs << 4);
+ ssp = (unsigned char __user *) (regs->ss << 4);
sp = SP(regs);
ip = IP(regs);
#
-lib-y = checksum.o delay.o \
- usercopy.o getuser.o \
- memcpy.o strstr.o
+lib-y = checksum.o delay.o usercopy.o getuser.o memcpy.o strstr.o \
+ bitops.o
lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
inline void __const_udelay(unsigned long xloops)
{
int d0;
+ xloops *= 4;
__asm__("mull %0"
:"=d" (xloops), "=&a" (d0)
- :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy));
- __delay(xloops * HZ);
+ :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy * (HZ/4)));
+ __delay(++xloops);
}
void __udelay(unsigned long usecs)
{
- __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
+ __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
}
void __ndelay(unsigned long nsecs)
struct mip_reg *host_reg;
int mip_port;
unsigned long mip_addr, host_addr;
-extern int (*platform_rename_gsi)();
static int __init
es7000_rename_gsi(int ioapic, int gsi)
}
if (success < 2) {
- printk("\nNo ES7000 found.\n");
es7000_plat = 0;
} else {
printk("\nEnabling ES7000 specific features...\n");
boot_cpu_logical_apicid = logical_apicid;
}
- if (m->mpc_apicid > MAX_APICS) {
+ ver = m->mpc_apicver;
+ if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
m->mpc_apicid, MAX_APICS);
return;
}
- ver = m->mpc_apicver;
apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
#include <linux/pci_ids.h>
#include <asm/io.h>
-#include <asm/pgalloc.h>
#include <asm/arch_hooks.h>
#include <asm/apic.h>
#include "cobalt.h"
#include <linux/reboot.h>
#include <linux/sysrq.h>
#include <asm/io.h>
-#include <asm/pgalloc.h>
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/pm.h>
#include <asm/desc.h>
#include <asm/voyager.h>
#include <asm/vic.h>
-#include <asm/pgalloc.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/desc.h>
#include <asm/voyager.h>
#include <asm/vic.h>
-#include <asm/pgalloc.h>
#include <asm/mtrr.h>
#include <asm/msr.h>
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
- printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
+ printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *) address);
if ( FPU_CS == __USER_CS )
{
while ( 1 )
{
- FPU_get_user(byte1, (u_char *) address);
+ FPU_get_user(byte1, (u_char __user *) address);
if ( (byte1 & 0xf8) == 0xd8 ) break;
printk("[%02x]", byte1);
address++;
}
printk("%02x ", byte1);
- FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+ FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
if (FPU_modrm >= 0300)
printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
#define MAX_PRINTED_BYTES 20
for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
{
- FPU_get_user(byte1, (u_char *) address);
+ FPU_get_user(byte1, (u_char __user *) address);
if ( (byte1 & 0xf8) == 0xd8 )
{
printk(" %02x", byte1);
printk(" [more..]\n");
else
{
- FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+ FPU_get_user(FPU_modrm, 1 + (u_char __user *) address);
if (FPU_modrm >= 0300)
printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
#include "status_w.h"
-void fadd__()
+void fadd__(void)
{
/* fadd st,st(i) */
int i = FPU_rm;
}
-void fmul__()
+void fmul__(void)
{
/* fmul st,st(i) */
int i = FPU_rm;
-void fsub__()
+void fsub__(void)
{
/* fsub st,st(i) */
clear_C1();
}
-void fsubr_()
+void fsubr_(void)
{
/* fsubr st,st(i) */
clear_C1();
}
-void fdiv__()
+void fdiv__(void)
{
/* fdiv st,st(i) */
clear_C1();
}
-void fdivr_()
+void fdivr_(void)
{
/* fdivr st,st(i) */
clear_C1();
-void fadd_i()
+void fadd_i(void)
{
/* fadd st(i),st */
int i = FPU_rm;
}
-void fmul_i()
+void fmul_i(void)
{
/* fmul st(i),st */
clear_C1();
}
-void fsubri()
+void fsubri(void)
{
/* fsubr st(i),st */
clear_C1();
}
-void fsub_i()
+void fsub_i(void)
{
/* fsub st(i),st */
clear_C1();
}
-void fdivri()
+void fdivri(void)
{
/* fdivr st(i),st */
clear_C1();
}
-void fdiv_i()
+void fdiv_i(void)
{
/* fdiv st(i),st */
clear_C1();
-void faddp_()
+void faddp_(void)
{
/* faddp st(i),st */
int i = FPU_rm;
}
-void fmulp_()
+void fmulp_(void)
{
/* fmulp st(i),st */
clear_C1();
-void fsubrp()
+void fsubrp(void)
{
/* fsubrp st(i),st */
clear_C1();
}
-void fsubp_()
+void fsubp_(void)
{
/* fsubp st(i),st */
clear_C1();
}
-void fdivrp()
+void fdivrp(void)
{
/* fdivrp st(i),st */
clear_C1();
}
-void fdivp_()
+void fdivp_(void)
{
/* fdivp st(i),st */
clear_C1();
}
/* Needs to be externally visible */
-void finit()
+void finit(void)
{
control_word = 0x037f;
partial_status = 0;
fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
};
-void finit_()
+void finit_(void)
{
(finit_table[FPU_rm])();
}
FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
};
-void fstsw_()
+void fstsw_(void)
{
(fstsw_table[FPU_rm])();
}
FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
};
-void fp_nop()
+void fp_nop(void)
{
(fp_nop_table[FPU_rm])();
}
-void fld_i_()
+void fld_i_(void)
{
FPU_REG *st_new_ptr;
int i;
}
-void fxch_i()
+void fxch_i(void)
{
/* fxch st(i) */
FPU_REG t;
}
-void ffree_()
+void ffree_(void)
{
/* ffree st(i) */
FPU_settagi(FPU_rm, TAG_Empty);
}
-void ffreep()
+void ffreep(void)
{
/* ffree st(i) + pop - unofficial code */
FPU_settagi(FPU_rm, TAG_Empty);
}
-void fst_i_()
+void fst_i_(void)
{
/* fst st(i) */
FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
}
-void fstp_i()
+void fstp_i(void)
{
/* fstp st(i) */
FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
u_char emulating=0;
#endif /* RE_ENTRANT_CHECKING */
-static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
overrides *override);
asmlinkage void math_emulate(long arg)
FPU_REG loaded_data;
FPU_REG *st0_ptr;
u_char loaded_tag, st0_tag;
- void *data_address;
+ void __user *data_address;
struct address data_sel_off;
struct address entry_sel_off;
unsigned long code_base = 0;
math_abort(FPU_info, SIGILL);
}
- if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) )
+ code_descriptor = LDT_DESCRIPTOR(FPU_CS);
+ if ( SEG_D_SIZE(code_descriptor) )
{
/* The above test may be wrong, the book is not clear */
/* Segmented 32 bit protected mode */
if (current->ptrace & PT_PTRACED)
FPU_lookahead = 0;
- if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP,
+ if ( !valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
&addr_modes.override) )
{
RE_ENTRANT_CHECK_OFF;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- FPU_get_user(FPU_modrm, (u_char *) FPU_EIP);
+ FPU_get_user(FPU_modrm, (u_char __user *) FPU_EIP);
RE_ENTRANT_CHECK_ON;
FPU_EIP++;
switch ( (byte1 >> 1) & 3 )
{
case 0:
- unmasked = FPU_load_single((float *)data_address,
+ unmasked = FPU_load_single((float __user *)data_address,
&loaded_data);
loaded_tag = unmasked & 0xff;
unmasked &= ~0xff;
break;
case 1:
- loaded_tag = FPU_load_int32((long *)data_address, &loaded_data);
+ loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
break;
case 2:
- unmasked = FPU_load_double((double *)data_address,
+ unmasked = FPU_load_double((double __user *)data_address,
&loaded_data);
loaded_tag = unmasked & 0xff;
unmasked &= ~0xff;
break;
case 3:
default: /* Used here to suppress gcc warnings. */
- loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+ loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
break;
}
if (FPU_lookahead && !need_resched())
{
FPU_ORIG_EIP = FPU_EIP - code_base;
- if ( valid_prefix(&byte1, (u_char **)&FPU_EIP,
+ if ( valid_prefix(&byte1, (u_char __user **)&FPU_EIP,
&addr_modes.override) )
goto do_another_FPU_instruction;
}
all prefix bytes, further changes are needed in the emulator code
which accesses user address space. Access to separate segments is
important for msdos emulation. */
-static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+static int valid_prefix(u_char *Byte, u_char __user **fpu_eip,
overrides *override)
{
u_char byte;
- u_char *ip = *fpu_eip;
+ u_char __user *ip = *fpu_eip;
*override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */
#define sstatus_word() \
((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
-int restore_i387_soft(void *s387, struct _fpstate *buf)
+int restore_i387_soft(void *s387, struct _fpstate __user *buf)
{
- u_char *d = (u_char *)buf;
+ u_char __user *d = (u_char __user *)buf;
int offset, other, i, tags, regnr, tag, newtop;
RE_ENTRANT_CHECK_OFF;
}
-int save_i387_soft(void *s387, struct _fpstate * buf)
+int save_i387_soft(void *s387, struct _fpstate __user * buf)
{
- u_char *d = (u_char *)buf;
+ u_char __user *d = (u_char __user *)buf;
int offset = (S387->ftop & 7) * 10, other = 80 - offset;
RE_ENTRANT_CHECK_OFF;
ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
};
-void FPU_etc()
+void FPU_etc(void)
{
(fp_etc_table[FPU_rm])(&st(0), FPU_gettag0());
}
extern void FPU_triga(void);
extern void FPU_trigb(void);
/* get_address.c */
-extern void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
+extern void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
struct address *addr, fpu_addr_modes addr_modes);
-extern void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
+extern void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
struct address *addr, fpu_addr_modes addr_modes);
/* load_store.c */
extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
- void *data_address);
+ void __user *data_address);
/* poly_2xm1.c */
extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result);
/* poly_atan.c */
/* reg_constant.c */
extern void fconst(void);
/* reg_ld_str.c */
-extern int FPU_load_extended(long double *s, int stnr);
-extern int FPU_load_double(double *dfloat, FPU_REG *loaded_data);
-extern int FPU_load_single(float *single, FPU_REG *loaded_data);
-extern int FPU_load_int64(long long *_s);
-extern int FPU_load_int32(long *_s, FPU_REG *loaded_data);
-extern int FPU_load_int16(short *_s, FPU_REG *loaded_data);
-extern int FPU_load_bcd(u_char *s);
+extern int FPU_load_extended(long double __user *s, int stnr);
+extern int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data);
+extern int FPU_load_single(float __user *single, FPU_REG *loaded_data);
+extern int FPU_load_int64(long long __user *_s);
+extern int FPU_load_int32(long __user *_s, FPU_REG *loaded_data);
+extern int FPU_load_int16(short __user *_s, FPU_REG *loaded_data);
+extern int FPU_load_bcd(u_char __user *s);
extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
- long double *d);
-extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat);
-extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single);
-extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d);
-extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d);
-extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d);
-extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d);
+ long double __user *d);
+extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat);
+extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single);
+extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d);
+extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d);
+extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d);
+extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d);
extern int FPU_round_to_int(FPU_REG *r, u_char tag);
-extern u_char *fldenv(fpu_addr_modes addr_modes, u_char *s);
-extern void frstor(fpu_addr_modes addr_modes, u_char *data_address);
-extern u_char *fstenv(fpu_addr_modes addr_modes, u_char *d);
-extern void fsave(fpu_addr_modes addr_modes, u_char *data_address);
+extern u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s);
+extern void frstor(fpu_addr_modes addr_modes, u_char __user *data_address);
+extern u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d);
+extern void fsave(fpu_addr_modes addr_modes, u_char __user *data_address);
extern int FPU_tagof(FPU_REG *ptr);
/* reg_mul.c */
extern int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w);
/* A simpler test than verify_area() can probably be done for
FPU_code_verify_area() because the only possible error is to step
past the upper boundary of a legal code area. */
-#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z)
+#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void __user *)FPU_EIP,z)
#endif
#define FPU_get_user(x,y) get_user((x),(y))
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- FPU_get_user(base, (u_char *) (*fpu_eip)); /* The SIB byte */
+ FPU_get_user(base, (u_char __user *) (*fpu_eip)); /* The SIB byte */
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
ss = base >> 6;
long displacement;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- FPU_get_user(displacement, (signed char *) (*fpu_eip));
+ FPU_get_user(displacement, (signed char __user *) (*fpu_eip));
offset += displacement;
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
long displacement;
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- FPU_get_user(displacement, (long *) (*fpu_eip));
+ FPU_get_user(displacement, (long __user *) (*fpu_eip));
offset += displacement;
RE_ENTRANT_CHECK_ON;
(*fpu_eip) += 4;
*/
-void *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
+void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
struct address *addr,
fpu_addr_modes addr_modes)
{
/* Special case: disp32 */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- FPU_get_user(address, (unsigned long *) (*fpu_eip));
+ FPU_get_user(address, (unsigned long __user *) (*fpu_eip));
(*fpu_eip) += 4;
RE_ENTRANT_CHECK_ON;
addr->offset = address;
- return (void *) address;
+ return (void __user *) address;
}
else
{
address = *cpu_reg_ptr; /* Just return the contents
of the cpu register */
addr->offset = address;
- return (void *) address;
+ return (void __user *) address;
}
case 1:
/* 8 bit signed displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- FPU_get_user(address, (signed char *) (*fpu_eip));
+ FPU_get_user(address, (signed char __user *) (*fpu_eip));
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
break;
/* 32 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(4);
- FPU_get_user(address, (long *) (*fpu_eip));
+ FPU_get_user(address, (long __user *) (*fpu_eip));
(*fpu_eip) += 4;
RE_ENTRANT_CHECK_ON;
break;
EXCEPTION(EX_INTERNAL|0x133);
}
- return (void *)address;
+ return (void __user *)address;
}
-void *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
+void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
struct address *addr,
fpu_addr_modes addr_modes)
{
/* Special case: disp16 */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(2);
- FPU_get_user(address, (unsigned short *) (*fpu_eip));
+ FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
(*fpu_eip) += 2;
RE_ENTRANT_CHECK_ON;
goto add_segment;
/* 8 bit signed displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(1);
- FPU_get_user(address, (signed char *) (*fpu_eip));
+ FPU_get_user(address, (signed char __user *) (*fpu_eip));
RE_ENTRANT_CHECK_ON;
(*fpu_eip)++;
break;
/* 16 bit displacement */
RE_ENTRANT_CHECK_OFF;
FPU_code_verify_area(2);
- FPU_get_user(address, (unsigned short *) (*fpu_eip));
+ FPU_get_user(address, (unsigned short __user *) (*fpu_eip));
(*fpu_eip) += 2;
RE_ENTRANT_CHECK_ON;
break;
EXCEPTION(EX_INTERNAL|0x131);
}
- return (void *)address ;
+ return (void __user *)address ;
}
};
int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
- void *data_address)
+ void __user *data_address)
{
FPU_REG loaded_data;
FPU_REG *st0_ptr;
{
case 000: /* fld m32real */
clear_C1();
- loaded_tag = FPU_load_single((float *)data_address, &loaded_data);
+ loaded_tag = FPU_load_single((float __user *)data_address, &loaded_data);
if ( (loaded_tag == TAG_Special)
&& isNaN(&loaded_data)
&& (real_1op_NaN(&loaded_data) < 0) )
break;
case 001: /* fild m32int */
clear_C1();
- loaded_tag = FPU_load_int32((long *)data_address, &loaded_data);
+ loaded_tag = FPU_load_int32((long __user *)data_address, &loaded_data);
FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
case 002: /* fld m64real */
clear_C1();
- loaded_tag = FPU_load_double((double *)data_address, &loaded_data);
+ loaded_tag = FPU_load_double((double __user *)data_address, &loaded_data);
if ( (loaded_tag == TAG_Special)
&& isNaN(&loaded_data)
&& (real_1op_NaN(&loaded_data) < 0) )
break;
case 003: /* fild m16int */
clear_C1();
- loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+ loaded_tag = FPU_load_int16((short __user *)data_address, &loaded_data);
FPU_copy_to_reg0(&loaded_data, loaded_tag);
break;
case 010: /* fst m32real */
clear_C1();
- FPU_store_single(st0_ptr, st0_tag, (float *)data_address);
+ FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address);
break;
case 011: /* fist m32int */
clear_C1();
- FPU_store_int32(st0_ptr, st0_tag, (long *)data_address);
+ FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address);
break;
case 012: /* fst m64real */
clear_C1();
- FPU_store_double(st0_ptr, st0_tag, (double *)data_address);
+ FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address);
break;
case 013: /* fist m16int */
clear_C1();
- FPU_store_int16(st0_ptr, st0_tag, (short *)data_address);
+ FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address);
break;
case 014: /* fstp m32real */
clear_C1();
- if ( FPU_store_single(st0_ptr, st0_tag, (float *)data_address) )
+ if ( FPU_store_single(st0_ptr, st0_tag, (float __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 015: /* fistp m32int */
clear_C1();
- if ( FPU_store_int32(st0_ptr, st0_tag, (long *)data_address) )
+ if ( FPU_store_int32(st0_ptr, st0_tag, (long __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 016: /* fstp m64real */
clear_C1();
- if ( FPU_store_double(st0_ptr, st0_tag, (double *)data_address) )
+ if ( FPU_store_double(st0_ptr, st0_tag, (double __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 017: /* fistp m16int */
clear_C1();
- if ( FPU_store_int16(st0_ptr, st0_tag, (short *)data_address) )
+ if ( FPU_store_int16(st0_ptr, st0_tag, (short __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 020: /* fldenv m14/28byte */
- fldenv(addr_modes, (u_char *)data_address);
+ fldenv(addr_modes, (u_char __user *)data_address);
/* Ensure that the values just loaded are not changed by
fix-up operations. */
return 1;
case 022: /* frstor m94/108byte */
- frstor(addr_modes, (u_char *)data_address);
+ frstor(addr_modes, (u_char __user *)data_address);
/* Ensure that the values just loaded are not changed by
fix-up operations. */
return 1;
case 023: /* fbld m80dec */
clear_C1();
- loaded_tag = FPU_load_bcd((u_char *)data_address);
+ loaded_tag = FPU_load_bcd((u_char __user *)data_address);
FPU_settag0(loaded_tag);
break;
case 024: /* fldcw */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, data_address, 2);
- FPU_get_user(control_word, (unsigned short *) data_address);
+ FPU_get_user(control_word, (unsigned short __user *) data_address);
RE_ENTRANT_CHECK_ON;
if ( partial_status & ~control_word & CW_Exceptions )
partial_status |= (SW_Summary | SW_Backward);
return 1;
case 025: /* fld m80real */
clear_C1();
- loaded_tag = FPU_load_extended((long double *)data_address, 0);
+ loaded_tag = FPU_load_extended((long double __user *)data_address, 0);
FPU_settag0(loaded_tag);
break;
case 027: /* fild m64int */
clear_C1();
- loaded_tag = FPU_load_int64((long long *)data_address);
+ loaded_tag = FPU_load_int64((long long __user *)data_address);
FPU_settag0(loaded_tag);
break;
case 030: /* fstenv m14/28byte */
- fstenv(addr_modes, (u_char *)data_address);
+ fstenv(addr_modes, (u_char __user *)data_address);
return 1;
case 032: /* fsave */
- fsave(addr_modes, (u_char *)data_address);
+ fsave(addr_modes, (u_char __user *)data_address);
return 1;
case 033: /* fbstp m80dec */
clear_C1();
- if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char *)data_address) )
+ if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 034: /* fstcw m16int */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
- FPU_put_user(control_word, (unsigned short *) data_address);
+ FPU_put_user(control_word, (unsigned short __user *) data_address);
RE_ENTRANT_CHECK_ON;
return 1;
case 035: /* fstp m80real */
clear_C1();
- if ( FPU_store_extended(st0_ptr, st0_tag, (long double *)data_address) )
+ if ( FPU_store_extended(st0_ptr, st0_tag, (long double __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 036: /* fstsw m2byte */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,data_address,2);
- FPU_put_user(status_word(),(unsigned short *) data_address);
+ FPU_put_user(status_word(),(unsigned short __user *) data_address);
RE_ENTRANT_CHECK_ON;
return 1;
case 037: /* fistp m64int */
clear_C1();
- if ( FPU_store_int64(st0_ptr, st0_tag, (long long *)data_address) )
+ if ( FPU_store_int64(st0_ptr, st0_tag, (long long __user *)data_address) )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
/*---------------------------------------------------------------------------*/
-void fcom_st()
+void fcom_st(void)
{
/* fcom st(i) */
compare_st_st(FPU_rm);
}
-void fcompst()
+void fcompst(void)
{
/* fcomp st(i) */
if ( !compare_st_st(FPU_rm) )
}
-void fcompp()
+void fcompp(void)
{
/* fcompp */
if (FPU_rm != 1)
}
-void fucom_()
+void fucom_(void)
{
/* fucom st(i) */
compare_u_st_st(FPU_rm);
}
-void fucomp()
+void fucomp(void)
{
/* fucomp st(i) */
if ( !compare_u_st_st(FPU_rm) )
}
-void fucompp()
+void fucompp(void)
{
/* fucompp */
if (FPU_rm == 1)
/* Get a long double from user memory */
-int FPU_load_extended(long double *s, int stnr)
+int FPU_load_extended(long double __user *s, int stnr)
{
FPU_REG *sti_ptr = &st(stnr);
/* Get a double from user memory */
-int FPU_load_double(double *dfloat, FPU_REG *loaded_data)
+int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data)
{
int exp, tag, negative;
unsigned m64, l64;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, dfloat, 8);
- FPU_get_user(m64, 1 + (unsigned long *) dfloat);
- FPU_get_user(l64, (unsigned long *) dfloat);
+ FPU_get_user(m64, 1 + (unsigned long __user *) dfloat);
+ FPU_get_user(l64, (unsigned long __user *) dfloat);
RE_ENTRANT_CHECK_ON;
negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
/* Get a float from user memory */
-int FPU_load_single(float *single, FPU_REG *loaded_data)
+int FPU_load_single(float __user *single, FPU_REG *loaded_data)
{
unsigned m32;
int exp, tag, negative;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, single, 4);
- FPU_get_user(m32, (unsigned long *) single);
+ FPU_get_user(m32, (unsigned long __user *) single);
RE_ENTRANT_CHECK_ON;
negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
/* Get a long long from user memory */
-int FPU_load_int64(long long *_s)
+int FPU_load_int64(long long __user *_s)
{
long long s;
int sign;
/* Get a long from user memory */
-int FPU_load_int32(long *_s, FPU_REG *loaded_data)
+int FPU_load_int32(long __user *_s, FPU_REG *loaded_data)
{
long s;
int negative;
/* Get a short from user memory */
-int FPU_load_int16(short *_s, FPU_REG *loaded_data)
+int FPU_load_int16(short __user *_s, FPU_REG *loaded_data)
{
int s, negative;
/* Get a packed bcd array from user memory */
-int FPU_load_bcd(u_char *s)
+int FPU_load_bcd(u_char __user *s)
{
FPU_REG *st0_ptr = &st(0);
int pos;
{
l *= 10;
RE_ENTRANT_CHECK_OFF;
- FPU_get_user(bcd, (u_char *) s+pos);
+ FPU_get_user(bcd, s+pos);
RE_ENTRANT_CHECK_ON;
l += bcd >> 4;
l *= 10;
}
RE_ENTRANT_CHECK_OFF;
- FPU_get_user(sign, (u_char *) s+9);
+ FPU_get_user(sign, s+9);
sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
RE_ENTRANT_CHECK_ON;
/*===========================================================================*/
/* Put a long double into user memory */
-int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
+int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double __user *d)
{
/*
The only exception raised by an attempt to store to an
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE, d, 10);
- FPU_put_user(st0_ptr->sigl, (unsigned long *) d);
- FPU_put_user(st0_ptr->sigh, (unsigned long *) ((u_char *)d + 4));
- FPU_put_user(exponent16(st0_ptr), (unsigned short *) ((u_char *)d + 8));
+ FPU_put_user(st0_ptr->sigl, (unsigned long __user *) d);
+ FPU_put_user(st0_ptr->sigh, (unsigned long __user *) ((u_char __user *)d + 4));
+ FPU_put_user(exponent16(st0_ptr), (unsigned short __user *) ((u_char __user *)d + 8));
RE_ENTRANT_CHECK_ON;
return 1;
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
- FPU_put_user(0, (unsigned long *) d);
- FPU_put_user(0xc0000000, 1 + (unsigned long *) d);
- FPU_put_user(0xffff, 4 + (short *) d);
+ FPU_put_user(0, (unsigned long __user *) d);
+ FPU_put_user(0xc0000000, 1 + (unsigned long __user *) d);
+ FPU_put_user(0xffff, 4 + (short __user *) d);
RE_ENTRANT_CHECK_ON;
return 1;
}
/* Put a double into user memory */
-int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
+int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat)
{
unsigned long l[2];
unsigned long increment = 0; /* avoid gcc warnings */
/* The masked response */
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
- FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
- FPU_put_user(0, (unsigned long *) dfloat);
- FPU_put_user(0xfff80000, 1 + (unsigned long *) dfloat);
+ FPU_verify_area(VERIFY_WRITE,dfloat,8);
+ FPU_put_user(0, (unsigned long __user *) dfloat);
+ FPU_put_user(0xfff80000, 1 + (unsigned long __user *) dfloat);
RE_ENTRANT_CHECK_ON;
return 1;
}
l[1] |= 0x80000000;
RE_ENTRANT_CHECK_OFF;
- FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
- FPU_put_user(l[0], (unsigned long *)dfloat);
- FPU_put_user(l[1], 1 + (unsigned long *)dfloat);
+ FPU_verify_area(VERIFY_WRITE,dfloat,8);
+ FPU_put_user(l[0], (unsigned long __user *)dfloat);
+ FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
RE_ENTRANT_CHECK_ON;
return 1;
/* Put a float into user memory */
-int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
+int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single)
{
long templ = 0;
unsigned long increment = 0; /* avoid gcc warnings */
/* The masked response */
/* Put out the QNaN indefinite */
RE_ENTRANT_CHECK_OFF;
- FPU_verify_area(VERIFY_WRITE,(void *)single,4);
- FPU_put_user(0xffc00000, (unsigned long *) single);
+ FPU_verify_area(VERIFY_WRITE,single,4);
+ FPU_put_user(0xffc00000, (unsigned long __user *) single);
RE_ENTRANT_CHECK_ON;
return 1;
}
templ |= 0x80000000;
RE_ENTRANT_CHECK_OFF;
- FPU_verify_area(VERIFY_WRITE,(void *)single,4);
- FPU_put_user(templ,(unsigned long *) single);
+ FPU_verify_area(VERIFY_WRITE,single,4);
+ FPU_put_user(templ,(unsigned long __user *) single);
RE_ENTRANT_CHECK_ON;
return 1;
/* Put a long long into user memory */
-int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long *d)
+int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d)
{
FPU_REG t;
long long tll;
}
RE_ENTRANT_CHECK_OFF;
- FPU_verify_area(VERIFY_WRITE,(void *)d,8);
+ FPU_verify_area(VERIFY_WRITE,d,8);
copy_to_user(d, &tll, 8);
RE_ENTRANT_CHECK_ON;
/* Put a long into user memory */
-int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long *d)
+int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d)
{
FPU_REG t;
int precision_loss;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,4);
- FPU_put_user(t.sigl, (unsigned long *) d);
+ FPU_put_user(t.sigl, (unsigned long __user *) d);
RE_ENTRANT_CHECK_ON;
return 1;
/* Put a short into user memory */
-int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short *d)
+int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d)
{
FPU_REG t;
int precision_loss;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,2);
- FPU_put_user((short)t.sigl,(short *) d);
+ FPU_put_user((short)t.sigl, d);
RE_ENTRANT_CHECK_ON;
return 1;
/* Put a packed bcd array into user memory */
-int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d)
+int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
{
FPU_REG t;
unsigned long long ll;
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,10);
for ( i = 0; i < 7; i++)
- FPU_put_user(0, (u_char *) d+i); /* These bytes "undefined" */
- FPU_put_user(0xc0, (u_char *) d+7); /* This byte "undefined" */
- FPU_put_user(0xff, (u_char *) d+8);
- FPU_put_user(0xff, (u_char *) d+9);
+ FPU_put_user(0, d+i); /* These bytes "undefined" */
+ FPU_put_user(0xc0, d+7); /* This byte "undefined" */
+ FPU_put_user(0xff, d+8);
+ FPU_put_user(0xff, d+9);
RE_ENTRANT_CHECK_ON;
return 1;
}
b = FPU_div_small(&ll, 10);
b |= (FPU_div_small(&ll, 10)) << 4;
RE_ENTRANT_CHECK_OFF;
- FPU_put_user(b,(u_char *) d+i);
+ FPU_put_user(b, d+i);
RE_ENTRANT_CHECK_ON;
}
RE_ENTRANT_CHECK_OFF;
- FPU_put_user(sign,(u_char *) d+9);
+ FPU_put_user(sign, d+9);
RE_ENTRANT_CHECK_ON;
return 1;
/*===========================================================================*/
-u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
+u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s)
{
unsigned short tag_word = 0;
u_char tag;
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 0x0e);
- FPU_get_user(control_word, (unsigned short *) s);
- FPU_get_user(partial_status, (unsigned short *) (s+2));
- FPU_get_user(tag_word, (unsigned short *) (s+4));
- FPU_get_user(instruction_address.offset, (unsigned short *) (s+6));
- FPU_get_user(instruction_address.selector, (unsigned short *) (s+8));
- FPU_get_user(operand_address.offset, (unsigned short *) (s+0x0a));
- FPU_get_user(operand_address.selector, (unsigned short *) (s+0x0c));
+ FPU_get_user(control_word, (unsigned short __user *) s);
+ FPU_get_user(partial_status, (unsigned short __user *) (s+2));
+ FPU_get_user(tag_word, (unsigned short __user *) (s+4));
+ FPU_get_user(instruction_address.offset, (unsigned short __user *) (s+6));
+ FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+8));
+ FPU_get_user(operand_address.offset, (unsigned short __user *) (s+0x0a));
+ FPU_get_user(operand_address.selector, (unsigned short __user *) (s+0x0c));
RE_ENTRANT_CHECK_ON;
s += 0x0e;
if ( addr_modes.default_mode == VM86 )
{
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_READ, s, 0x1c);
- FPU_get_user(control_word, (unsigned short *) s);
- FPU_get_user(partial_status, (unsigned short *) (s+4));
- FPU_get_user(tag_word, (unsigned short *) (s+8));
- FPU_get_user(instruction_address.offset, (unsigned long *) (s+0x0c));
- FPU_get_user(instruction_address.selector, (unsigned short *) (s+0x10));
- FPU_get_user(instruction_address.opcode, (unsigned short *) (s+0x12));
- FPU_get_user(operand_address.offset, (unsigned long *) (s+0x14));
- FPU_get_user(operand_address.selector, (unsigned long *) (s+0x18));
+ FPU_get_user(control_word, (unsigned short __user *) s);
+ FPU_get_user(partial_status, (unsigned short __user *) (s+4));
+ FPU_get_user(tag_word, (unsigned short __user *) (s+8));
+ FPU_get_user(instruction_address.offset, (unsigned long __user *) (s+0x0c));
+ FPU_get_user(instruction_address.selector, (unsigned short __user *) (s+0x10));
+ FPU_get_user(instruction_address.opcode, (unsigned short __user *) (s+0x12));
+ FPU_get_user(operand_address.offset, (unsigned long __user *) (s+0x14));
+ FPU_get_user(operand_address.selector, (unsigned long __user *) (s+0x18));
RE_ENTRANT_CHECK_ON;
s += 0x1c;
}
}
-void frstor(fpu_addr_modes addr_modes, u_char *data_address)
+void frstor(fpu_addr_modes addr_modes, u_char __user *data_address)
{
int i, regnr;
- u_char *s = fldenv(addr_modes, data_address);
+ u_char __user *s = fldenv(addr_modes, data_address);
int offset = (top & 7) * 10, other = 80 - offset;
/* Copy all registers in stack order. */
}
-u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
+u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d)
{
if ( (addr_modes.default_mode == VM86) ||
((addr_modes.default_mode == PM16)
RE_ENTRANT_CHECK_OFF;
FPU_verify_area(VERIFY_WRITE,d,14);
#ifdef PECULIAR_486
- FPU_put_user(control_word & ~0xe080, (unsigned long *) d);
+ FPU_put_user(control_word & ~0xe080, (unsigned long __user *) d);
#else
- FPU_put_user(control_word, (unsigned short *) d);
+ FPU_put_user(control_word, (unsigned short __user *) d);
#endif /* PECULIAR_486 */
- FPU_put_user(status_word(), (unsigned short *) (d+2));
- FPU_put_user(fpu_tag_word, (unsigned short *) (d+4));
- FPU_put_user(instruction_address.offset, (unsigned short *) (d+6));
- FPU_put_user(operand_address.offset, (unsigned short *) (d+0x0a));
+ FPU_put_user(status_word(), (unsigned short __user *) (d+2));
+ FPU_put_user(fpu_tag_word, (unsigned short __user *) (d+4));
+ FPU_put_user(instruction_address.offset, (unsigned short __user *) (d+6));
+ FPU_put_user(operand_address.offset, (unsigned short __user *) (d+0x0a));
if ( addr_modes.default_mode == VM86 )
{
FPU_put_user((instruction_address.offset & 0xf0000) >> 4,
- (unsigned short *) (d+8));
+ (unsigned short __user *) (d+8));
FPU_put_user((operand_address.offset & 0xf0000) >> 4,
- (unsigned short *) (d+0x0c));
+ (unsigned short __user *) (d+0x0c));
}
else
{
- FPU_put_user(instruction_address.selector, (unsigned short *) (d+8));
- FPU_put_user(operand_address.selector, (unsigned short *) (d+0x0c));
+ FPU_put_user(instruction_address.selector, (unsigned short __user *) (d+8));
+ FPU_put_user(operand_address.selector, (unsigned short __user *) (d+0x0c));
}
RE_ENTRANT_CHECK_ON;
d += 0x0e;
}
-void fsave(fpu_addr_modes addr_modes, u_char *data_address)
+void fsave(fpu_addr_modes addr_modes, u_char __user *data_address)
{
- u_char *d;
+ u_char __user *d;
int offset = (top & 7) * 10, other = 80 - offset;
d = fstenv(addr_modes, data_address);
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/hardirq.h>
#include <asm/desc.h>
#include <asm/tlbflush.h>
else
printk(KERN_ALERT "Unable to handle kernel paging request");
printk(" at virtual address %08lx\n",address);
- printk(" printing eip:\n");
+ printk(KERN_ALERT " printing eip:\n");
printk("%08lx\n", regs->eip);
asm("movl %%cr3,%0":"=r" (page));
page = ((unsigned long *) __va(page))[address >> 22];
#include <linux/err.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
-#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
ret = -ENOMEM;
goto out;
}
- if (!pte_none(*pte))
- continue;
+
+ if (!pte_none(*pte)) {
+ pmd_t *pmd = (pmd_t *) pte;
+
+ page = pmd_page(*pmd);
+ pmd_clear(pmd);
+ dec_page_state(nr_page_table_pages);
+ page_cache_release(page);
+ }
idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
#include <asm/e820.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/io.h>
-#include <asm/pgalloc.h>
#include <asm/fixmap.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/hw_irq.h>
#include "pci.h"
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
static int __init pci_acpi_init(void)
{
+ struct pci_dev *dev = NULL;
+
if (pcibios_scanned)
return 0;
- if (!acpi_noirq) {
- if (!acpi_pci_irq_init()) {
- printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
- pcibios_scanned++;
- pcibios_enable_irq = acpi_pci_irq_enable;
- } else
- printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
+ if (acpi_noirq)
+ return 0;
- }
+ printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+ acpi_irq_penalty_init();
+ pcibios_scanned++;
+ pcibios_enable_irq = acpi_pci_irq_enable;
+
+ /*
+ * PCI IRQ routing is set up by pci_enable_device(), but we
+ * also do it here in case there are still broken drivers that
+ * don't use pci_enable_device().
+ */
+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ acpi_pci_irq_enable(dev);
+
+#ifdef CONFIG_X86_IO_APIC
+ if (acpi_ioapic)
+ print_IO_APIC();
+#endif
return 0;
}
fixed_val = rev < 0xC1 ? 0x1F01FF01 : 0x9F01FF01;
pci_read_config_dword(dev, 0x6c, &val);
- if (val != fixed_val) {
+
+ /*
+ * Apply fixup only if C1 Halt Disconnect is enabled
+ * (bit28) because it is not supported on some boards.
+ */
+ if ((val & (1 << 28)) && val != fixed_val) {
printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n");
pci_write_config_dword(dev, 0x6c, fixed_val);
}
endchoice
-config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
- depends on SMP && HOTPLUG && EXPERIMENTAL
- default n
- ---help---
- Say Y here to experiment with turning CPUs off and on. CPUs
- can be controlled through /sys/devices/system/cpu/cpu#.
- Say N if you want to disable cpu hotplug.
-
choice
prompt "Processor type"
default ITANIUM
than 64 will cause the use of a CPU mask array, causing a small
performance hit.
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ depends on SMP && HOTPLUG && EXPERIMENTAL
+ default n
+ ---help---
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu/cpu#.
+ Say N if you want to disable CPU hotplug.
+
config PREEMPT
bool "Preemptible Kernel"
help
return ia32_do_mmap(filep, (addr & IA32_PAGE_MASK), eppnt->p_filesz + pgoff, prot, type,
eppnt->p_offset - pgoff);
}
+
+#define cpu_uses_ia32el() (local_cpu_data->family > 0x1f)
+
+static int __init check_elf32_binfmt(void)
+{
+ if (cpu_uses_ia32el()) {
+ printk("Please use IA-32 EL for executing IA-32 binaries\n");
+ return unregister_binfmt(&elf_format);
+ }
+ return 0;
+}
+
+module_init(check_elf32_binfmt)
data8 sys_setfsuid /* 16-bit version */
data8 sys_setfsgid /* 16-bit version */
data8 sys_llseek /* 140 */
- data8 sys32_getdents
+ data8 compat_sys_getdents
data8 compat_sys_select
data8 sys_flock
data8 sys32_msync
data8 sys_pivot_root
data8 sys_mincore
data8 sys_madvise
- data8 sys_getdents64 /* 220 */
+ data8 compat_sys_getdents64 /* 220 */
data8 compat_sys_fcntl64
data8 sys_ni_syscall /* reserved for TUX */
data8 sys_ni_syscall /* reserved for Security */
#endif /* CONFIG_ACPI_NUMA */
unsigned int
-acpi_register_gsi (u32 gsi, int polarity, int trigger)
+acpi_register_gsi (u32 gsi, int edge_level, int active_high_low)
{
- return acpi_register_irq(gsi, polarity, trigger);
+ if (has_8259 && gsi < 16)
+ return isa_irq_to_vector(gsi);
+
+ return iosapic_register_intr(gsi,
+ (active_high_low == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+ (edge_level == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
}
EXPORT_SYMBOL(acpi_register_gsi);
if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
acpi_legacy_devices = 1;
- acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
+ acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
return 0;
}
return 0;
}
-int
-acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
-{
- if (has_8259 && gsi < 16)
- return isa_irq_to_vector(gsi);
-
- return iosapic_register_intr(gsi,
- (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
- (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
-}
-EXPORT_SYMBOL(acpi_register_irq);
-
#endif /* CONFIG_ACPI_BOOT */
* Jonathan Nicklin <nicklin@missioncriticallinux.com>
* Patrick O'Rourke <orourke@missioncriticallinux.com>
* 11/07/2000
- /
+ */
/*
* Global (preserved) predicate usage on syscall entry/exit path:
*
adds r17=-1024,r15
movl r14=sys_call_table
;;
+ rsm psr.i
shladd r18=r17,3,r14
;;
ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point
* to synthesize.
*/
# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
- | IA64_PSR_BN)
+ | IA64_PSR_BN | IA64_PSR_I)
invala
movl r8=PSR_ONE_BITS
cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)?
;;
(p6) ld8 r18=[r18]
- mov r29=psr // read psr (12 cyc load latency)
+ mov r21=ar.fpsr
add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
;;
(p6) mov b7=r18
(p6) tbit.z p8,p0=r18,0
(p8) br.dptk.many b7
+(p6) rsm psr.i
mov r27=ar.rsc
- mov r21=ar.fpsr
mov r26=ar.pfs
+ ;;
+ mov r29=psr // read psr (12 cyc load latency)
/*
* brl.cond doesn't work as intended because the linker would convert this branch
* into a branch to a PLT. Perhaps there will be a way to avoid this with some
br.ret.sptk.many rp
END(ia64_delay_loop)
+/*
+ * Return a CPU-local timestamp in nano-seconds. This timestamp is
+ * NOT synchronized across CPUs its return value must never be
+ * compared against the values returned on another CPU. The usage in
+ * kernel/sched.c ensures that.
+ *
+ * The return-value of sched_clock() is NOT supposed to wrap-around.
+ * If it did, it would cause some scheduling hiccups (at the worst).
+ * Fortunately, with a 64-bit cycle-counter ticking at 100GHz, even
+ * that would happen only once every 5+ years.
+ *
+ * The code below basically calculates:
+ *
+ * (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT
+ *
+ * except that the multiplication and the shift are done with 128-bit
+ * intermediate precision so that we can produce a full 64-bit result.
+ */
+GLOBAL_ENTRY(sched_clock)
+ addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
+ mov.m r9=ar.itc // fetch cycle-counter (35 cyc)
+ ;;
+ ldf8 f8=[r8]
+ ;;
+ setf.sig f9=r9 // certain to stall, so issue it _after_ ldf8...
+ ;;
+ xmpy.lu f10=f9,f8 // calculate low 64 bits of 128-bit product (4 cyc)
+ xmpy.hu f11=f9,f8 // calculate high 64 bits of 128-bit product
+ ;;
+ getf.sig r8=f10 // (5 cyc)
+ getf.sig r9=f11
+ ;;
+ shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
+ br.ret.sptk.many rp
+END(sched_clock)
+
GLOBAL_ENTRY(start_kernel_thread)
.prologue
.save rp, r0 // this is the end of the call-chain
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#endif
static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
-cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
+extern cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
index = find_iosapic(gsi);
if (index < 0) {
- printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi);
+ printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi);
return;
}
}
}
+static unsigned int
+get_target_cpu (void)
+{
+#ifdef CONFIG_SMP
+ static int cpu = -1;
+
+ /*
+ * If the platform supports redirection via XTP, let it
+ * distribute interrupts.
+ */
+ if (smp_int_redirect & SMP_IRQ_REDIRECTION)
+ return hard_smp_processor_id();
+
+ /*
+ * Some interrupts (ACPI SCI, for instance) are registered
+ * before the BSP is marked as online.
+ */
+ if (!cpu_online(smp_processor_id()))
+ return hard_smp_processor_id();
+
+ /*
+ * Otherwise, round-robin interrupt vectors across all the
+ * processors. (It'd be nice if we could be smarter in the
+ * case of NUMA.)
+ */
+ do {
+ if (++cpu >= NR_CPUS)
+ cpu = 0;
+ } while (!cpu_online(cpu));
+
+ return cpu_physical_id(cpu);
+#else
+ return hard_smp_processor_id();
+#endif
+}
+
/*
* ACPI can describe IOSAPIC interrupts via static tables and namespace
* methods. This provides an interface to register those interrupts and
unsigned long polarity, unsigned long trigger)
{
int vector;
- unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
+ unsigned int dest;
+ unsigned long flags;
- vector = gsi_to_vector(gsi);
- if (vector < 0)
- vector = assign_irq_vector(AUTO_ASSIGN);
+ /*
+ * If this GSI has already been registered (i.e., it's a
+ * shared interrupt, or we lost a race to register it),
+ * don't touch the RTE.
+ */
+ spin_lock_irqsave(&iosapic_lock, flags);
+ {
+ vector = gsi_to_vector(gsi);
+ if (vector > 0) {
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+ return vector;
+ }
- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
- polarity, trigger);
+ vector = assign_irq_vector(AUTO_ASSIGN);
+ dest = get_target_cpu();
+ register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+ polarity, trigger);
+ }
+ spin_unlock_irqrestore(&iosapic_lock, flags);
- printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
- gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
- (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
+ printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
+ gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+ (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+ cpu_logical_id(dest), dest, vector);
- /* program the IOSAPIC routing table */
- set_rte(vector, dest, 0);
+ set_rte(vector, dest, 1);
return vector;
}
int iosapic_vector, u16 eid, u16 id,
unsigned long polarity, unsigned long trigger)
{
+ static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
unsigned char delivery;
- int vector;
+ int vector, mask = 0;
unsigned int dest = ((id << 8) | eid) & 0xffff;
switch (int_type) {
case ACPI_INTERRUPT_CPEI:
vector = IA64_CPE_VECTOR;
delivery = IOSAPIC_LOWEST_PRIORITY;
+ mask = 1;
break;
default:
- printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n");
+ printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type);
return -1;
}
- register_intr(gsi, vector, delivery, polarity,
- trigger);
+ register_intr(gsi, vector, delivery, polarity, trigger);
- printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
- int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
- (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
+ printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
+ int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
+ int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
+ (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+ cpu_logical_id(dest), dest, vector);
- /* program the IOSAPIC routing table */
- set_rte(vector, dest, 0);
+ set_rte(vector, dest, mask);
return vector;
}
unsigned long trigger)
{
int vector;
- unsigned int dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
+ unsigned int dest = hard_smp_processor_id();
vector = isa_irq_to_vector(isa_irq);
register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
- DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
- isa_irq, gsi, polarity == IOSAPIC_POL_HIGH ? "high" : "low",
- trigger == IOSAPIC_EDGE ? "edge" : "level", dest, vector);
+ DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
+ isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
+ polarity == IOSAPIC_POL_HIGH ? "high" : "low",
+ cpu_logical_id(dest), dest, vector);
- /* program the IOSAPIC routing table */
- set_rte(vector, dest, 0);
+ set_rte(vector, dest, 1);
}
void __init
iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
}
}
-
-void
-iosapic_enable_intr (unsigned int vector)
-{
- unsigned int dest;
- irq_desc_t *desc;
-
- /*
- * In the case of a shared interrupt, do not re-route the vector, and
- * especially do not mask a running interrupt (startup will not get
- * called for a shared interrupt).
- */
- desc = irq_descp(vector);
- if (desc->action)
- return;
-
-#ifdef CONFIG_SMP
- /*
- * For platforms that do not support interrupt redirect via the XTP interface, we
- * can round-robin the PCI device interrupts to the processors
- */
- if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
- static int cpu_index = -1;
-
- do
- if (++cpu_index >= NR_CPUS)
- cpu_index = 0;
- while (!cpu_online(cpu_index));
-
- dest = cpu_physical_id(cpu_index) & 0xffff;
- } else {
- /*
- * Direct the interrupt vector to the current cpu, platform redirection
- * will distribute them.
- */
- dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
- }
-#else
- /* direct the interrupt vector to the running cpu id */
- dest = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff;
-#endif
- set_rte(vector, dest, 1);
-
- printk(KERN_INFO "IOSAPIC: vector %d -> CPU 0x%04x, enabled\n",
- vector, dest);
-}
-
-#ifdef CONFIG_ACPI_PCI
-
-void __init
-iosapic_parse_prt (void)
-{
- struct acpi_prt_entry *entry;
- struct list_head *node;
- unsigned int gsi;
- int vector;
- char pci_id[16];
- struct hw_interrupt_type *irq_type = &irq_type_iosapic_level;
- irq_desc_t *idesc;
-
- list_for_each(node, &acpi_prt.entries) {
- entry = list_entry(node, struct acpi_prt_entry, node);
-
- /* We're only interested in static (non-link) entries. */
- if (entry->link.handle)
- continue;
-
- gsi = entry->link.index;
-
- vector = gsi_to_vector(gsi);
- if (vector < 0) {
- if (find_iosapic(gsi) < 0)
- continue;
-
- /* allocate a vector for this interrupt line */
- if (pcat_compat && (gsi < 16))
- vector = isa_irq_to_vector(gsi);
- else
- /* new GSI; allocate a vector for it */
- vector = assign_irq_vector(AUTO_ASSIGN);
-
- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
- IOSAPIC_LEVEL);
- }
- entry->irq = vector;
- snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
- entry->id.segment, entry->id.bus, entry->id.device, 'A' + entry->pin);
-
- /*
- * If vector was previously initialized to a different
- * handler, re-initialize.
- */
- idesc = irq_descp(vector);
- if (idesc->handler != irq_type)
- register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
- IOSAPIC_LEVEL);
-
- }
-}
-
-#endif /* CONFIG_ACPI */
#include <asm/delay.h>
#include <asm/irq.h>
-extern cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
/*
* Linux has a controller-independent x86 interrupt architecture.
}
};
+/*
+ * This is updated when the user sets irq affinity via /proc
+ */
+cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
+
#ifdef CONFIG_IA64_GENERIC
irq_desc_t * __ia64_irq_desc (unsigned int irq)
{
setup_serial_hcdp(efi.hcdp);
}
#endif
- /*
- * Without HCDP, we won't discover any serial ports until the serial driver looks
- * in the ACPI namespace. If ACPI claims there are some legacy devices, register
- * the legacy COM ports so serial console works earlier. This is slightly dangerous
- * because we don't *really* know whether there's anything there, but we hope that
- * all new boxes will implement HCDP.
- */
- {
- extern unsigned char acpi_legacy_devices;
- if (!efi.hcdp && acpi_legacy_devices)
- setup_serial_legacy();
- }
+ if (!efi.hcdp)
+ setup_serial_legacy();
#endif
#ifdef CONFIG_VT
ia32_cpu_init();
#endif
+ /* Clear ITC to eliminiate sched_clock() overflows in human time. */
+ ia64_set_itc(0);
+
/* disable all local interrupt sources: */
ia64_set_itv(1 << 16);
ia64_set_lrr0(1 << 16);
{
long i, delta, adj, adjust_latency = 0, done = 0;
unsigned long flags, rt, master_time_stamp, bound;
- extern void ia64_cpu_local_tick (void);
#if DEBUG_ITC_SYNC
struct {
long rt; /* roundtrip time */
#else
# error Fixme: Dunno how to build CPU-to-node map.
#endif
- cpu_to_node_map[cpu] = node;
+ cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
if (node >= 0)
cpu_set(cpu, node_to_cpu_mask[node]);
}
#endif
-unsigned long long
-sched_clock (void)
-{
- unsigned long offset = ia64_get_itc();
-
- return (offset * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
-}
-
static void
itc_reset (void)
{
.data : AT(ADDR(.data) - LOAD_OFFSET)
{ *(.data) *(.data1) *(.gnu.linkonce.d*) CONSTRUCTORS }
- . = ALIGN(16);
- __gp = . + 0x200000; /* gp must be 16-byte aligned for exc. table */
-
+ . = ALIGN(16); /* gp must be 16-byte aligned for exc. table */
.got : AT(ADDR(.got) - LOAD_OFFSET)
{ *(.got.plt) *(.got) }
+ __gp = ADDR(.got) + 0x200000;
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \
- checksum.o clear_page.o csum_partial_copy.o copy_page.o \
+ bitop.o checksum.o clear_page.o csum_partial_copy.o copy_page.o \
clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
flush.o ip_fast_csum.o do_csum.o \
memset.o strlen.o swiotlb.o
static int __init
pci_acpi_init (void)
{
- if (!acpi_pci_irq_init())
- printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
- else
- printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
+ struct pci_dev *dev = NULL;
+
+ printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+
+ /*
+ * PCI IRQ routing is set up by pci_enable_device(), but we
+ * also do it here in case there are still broken drivers that
+ * don't use pci_enable_device().
+ */
+ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+ acpi_pci_irq_enable(dev);
+
return 0;
}
struct pci_controller *controller = PCI_CONTROLLER(dev);
struct pci_window *window;
int i, j;
+ int limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ? \
+ PCI_ROM_RESOURCE : PCI_NUM_RESOURCES;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ for (i = 0; i < limit; i++) {
if (!dev->resource[i].start)
continue;
{
while ((((volatile unsigned long) (*pda->pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) !=
SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
- udelay(1);
+ cpu_relax();
}
EXPORT_SYMBOL(sn_mmiob);
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/types.h>
piomap->bp_kvaddr + offset, len, valp);
}
+static uint64_t
+pcibr_disable_mst_timeout(pcibr_soft_t pcibr_soft)
+{
+ uint64_t old_enable;
+ uint64_t new_enable;
+ uint64_t intr_bits;
+
+ intr_bits = PIC_ISR_PCI_MST_TIMEOUT
+ | PIC_ISR_PCIX_MTOUT | PIC_ISR_PCIX_SPLIT_EMSG;
+ old_enable = pcireg_intr_enable_get(pcibr_soft);
+ pcireg_intr_enable_bit_clr(pcibr_soft, intr_bits);
+ new_enable = pcireg_intr_enable_get(pcibr_soft);
+
+ if (old_enable == new_enable) {
+ return 0; /* was already disabled */
+ } else {
+ return 1;
+ }
+}
+
+static int
+pcibr_enable_mst_timeout(pcibr_soft_t pcibr_soft)
+{
+ uint64_t old_enable;
+ uint64_t new_enable;
+ uint64_t intr_bits;
+
+ intr_bits = PIC_ISR_PCI_MST_TIMEOUT
+ | PIC_ISR_PCIX_MTOUT | PIC_ISR_PCIX_SPLIT_EMSG;
+ old_enable = pcireg_intr_enable_get(pcibr_soft);
+ pcireg_intr_enable_bit_set(pcibr_soft, intr_bits);
+ new_enable = pcireg_intr_enable_get(pcibr_soft);
+
+ if (old_enable == new_enable) {
+ return 0; /* was alread enabled */
+ } else {
+ return 1;
+ }
+}
+
/*
* pcibr_probe_slot: read a config space word
* while trapping any errors; return zero if
int len,
void *valp)
{
- int rv;
+ int rv, changed;
/*
* Sanity checks ...
return -1; /* invalid alignment */
}
+ changed = pcibr_disable_mst_timeout(pcibr_soft);
+
rv = snia_badaddr_val((void *)addr, len, valp);
/* Clear the int_view register incase it was set */
pcireg_intr_reset_set(pcibr_soft, BRIDGE_IRR_MULTI_CLR);
+ if (changed) {
+ pcibr_enable_mst_timeout(pcibr_soft);
+ }
return (rv ? 1 : 0); /* return 1 for snia_badaddr_val error, 0 if ok */
}
-
void
pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot)
{
#include <linux/a.out.h>
#include <linux/reboot.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <linux/sched.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/thread_info.h>
#include <asm/uaccess.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV)
#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER)
+#ifdef CONFIG_SBC82xx
+/* rx is clk9, tx is clk10
+ */
+#define PC_F1RXCLK ((uint)0x00000100)
+#define PC_F1TXCLK ((uint)0x00000200)
+#define CMX1_CLK_ROUTE ((uint)0x25000000)
+#define CMX1_CLK_MASK ((uint)0xff000000)
+#else
/* CLK12 is receive, CLK11 is transmit. These are board specific.
*/
#define PC_F1RXCLK ((uint)0x00000800)
#define PC_F1TXCLK ((uint)0x00000400)
#define CMX1_CLK_ROUTE ((uint)0x3e000000)
#define CMX1_CLK_MASK ((uint)0xff000000)
+#endif /* !CONFIG_SBC82xx */
/* I/O Pin assignment for FCC2. I don't yet know the best way to do this,
* but there is little variation among the choices.
ushort skb_cur;
ushort skb_dirty;
+ atomic_t n_pkts; /* Number of packets in tx ring */
+
/* CPM dual port RAM relative addresses.
*/
cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
{
struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv;
volatile cbd_t *bdp;
+ int idx;
if (!cep->link) {
/* Link is down or autonegotiation is in progress. */
bdp->cbd_datlen = skb->len;
bdp->cbd_bufaddr = __pa(skb->data);
+ spin_lock_irq(&cep->lock);
+
/* Save skb pointer. */
- cep->tx_skbuff[cep->skb_cur] = skb;
+ idx = cep->skb_cur & TX_RING_MOD_MASK;
+ if (cep->tx_skbuff[idx]) {
+ /* This should never happen (any more).
+ Leave the sanity check in for now... */
+ printk(KERN_ERR "EEP. cep->tx_skbuff[%d] is %p not NULL in %s\n",
+ idx, cep->tx_skbuff[idx], __func__);
+ printk(KERN_ERR "Expect to lose %d bytes of sock space",
+ cep->tx_skbuff[idx]->truesize);
+ }
+ cep->tx_skbuff[idx] = skb;
cep->stats.tx_bytes += skb->len;
- cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+ cep->skb_cur++;
- spin_lock_irq(&cep->lock);
+ atomic_inc(&cep->n_pkts);
/* Send it on its way. Tell CPM its ready, interrupt when done,
* its the last BD of the frame, and to put the CRC on the end.
else
bdp++;
- if (bdp->cbd_sc & BD_ENET_TX_READY) {
- netif_stop_queue(dev);
+
+ /* If the tx_ring is full, stop the queue */
+ if (atomic_read(&cep->n_pkts) >= (TX_RING_SIZE-1)) {
+ if (!netif_queue_stopped(dev)) {
+ netif_stop_queue(dev);
cep->tx_full = 1;
+ }
}
cep->cur_tx = (cbd_t *)bdp;
volatile cbd_t *bdp;
ushort int_events;
int must_restart;
+ int idx;
cep = (struct fcc_enet_private *)dev->priv;
cep->stats.collisions++;
/* Free the sk buffer associated with this last transmit. */
- dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]);
- cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+ idx = cep->skb_dirty & TX_RING_MOD_MASK;
+ dev_kfree_skb_irq(cep->tx_skbuff[idx]);
+ cep->tx_skbuff[idx] = NULL;
+ cep->skb_dirty++;
+
+ atomic_dec(&cep->n_pkts);
/* Update pointer to next buffer descriptor to be transmitted. */
if (bdp->cbd_sc & BD_ENET_TX_WRAP)
*/
eap = (unsigned char *)&(ep->fen_paddrh);
for (i=5; i>=0; i--) {
+#ifdef CONFIG_SBC82xx
+ if (i == 5) {
+ /* bd->bi_enetaddr holds the SCC0 address; the FCC
+ devices count up from there */
+ dev->dev_addr[i] = bd->bi_enetaddr[i] & ~3;
+ dev->dev_addr[i] += 1 + fip->fc_fccnum;
+ *eap++ = dev->dev_addr[i];
+ }
+#else
if (i == 3) {
dev->dev_addr[i] = bd->bi_enetaddr[i];
dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum));
*eap++ = dev->dev_addr[i];
}
+#endif
else {
*eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
}
while (cp->cp_cpcr & CPM_CR_FLG);
cep->skb_cur = cep->skb_dirty = 0;
+ atomic_set(&cep->n_pkts, 0);
}
/* Let 'er rip.
#ifndef CONFIG_SCC1_ENET
{ 0, 0, PROFF_SCC1, SIU_INT_SCC1, 0, SCC_NUM_BASE}, /* SCC1 ttyS2 */
#endif
-#ifndef CONFIG_SCC2_ENET
+#if !defined(CONFIG_SBC82xx) && !defined(CONFIG_SCC2_ENET)
{ 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE + 1}, /* SCC2 ttyS3 */
#endif
};
if (break_pressed && info->line == sercons.index) {
if (ch != 0 && time_before(jiffies,
break_pressed + HZ*5)) {
- handle_sysrq(ch, regs, NULL, NULL);
+ handle_sysrq(ch, regs, NULL);
break_pressed = 0;
goto ignore_char;
} else
config 8xx
bool "8xx"
+config E500
+ bool "e500"
+
endchoice
+config BOOKE
+ bool
+ depends on E500
+ default y
+
+config FSL_BOOKE
+ bool
+ depends on E500
+ default y
+
config PTE_64BIT
bool
depends on 44x
If in doubt, say Y here.
+config SPE
+ bool "SPE Support"
+ depends on E500
+ ---help---
+ This option enables kernel support for the Signal Processing
+ Extensions (SPE) to the PowerPC processor. The kernel currently
+ supports saving and restoring SPE registers, and turning on the
+ 'spe enable' bit so user processes can execute SPE instructions.
+
+ This option is only usefully if you have a processor that supports
+ SPE (e500, otherwise known as 85xx series), but does not have any
+ affect on a non-spe cpu (it does, however add code to the kernel).
+
+ If in doubt, say Y here.
+
config TAU
bool "Thermal Management Support"
depends on 6xx && !8260
config MATH_EMULATION
bool "Math emulation"
- depends on 4xx || 8xx
+ depends on 4xx || 8xx || E500
---help---
Some PowerPC chips designed for embedded applications do not have
a floating-point unit and therefore do not implement the
If in doubt, say Y here.
source arch/ppc/platforms/4xx/Kconfig
+source arch/ppc/platforms/85xx/Kconfig
config PPC64BRIDGE
bool
<http://www.windriver.com/>, but the EST8260 cannot be found on it
and has probably been discontinued or rebadged.
+config SBC82xx
+ bool "SBC82xx"
+ ---help---
+ SBC PowerQUICC II, single-board computer with MPC82xx CPU
+ Manufacturer: Wind River Systems, Inc.
+ Date of Release: May 2003
+ End of Life: -
+ URL: <http://www.windriver.com/>
+
config SBS8260
bool "SBS8260"
config 8260
bool "MPC8260 CPM Support" if WILLOW
depends on 6xx
- default y if TQM8260 || RPXSUPER || EST8260 || SBS8260
+ default y if TQM8260 || RPXSUPER || EST8260 || SBS8260 || SBC82xx
help
The MPC8260 CPM (Communications Processor Module) is a typical
embedded CPU made by Motorola. Selecting this option means that
bool
config PCI
- bool "PCI support" if 40x || 8260
- default y if !40x && !8260 && !8xx && !APUS
+ bool "PCI support" if 40x || 8260 || 85xx
+ default y if !40x && !8260 && !8xx && !APUS && !85xx
default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS
default PCI_QSPAN if !4xx && !8260 && 8xx
help
config PPC_OCP
bool
- depends on IBM_OCP
+ depends on IBM_OCP || FSL_OCP
default y
endmenu
CPPFLAGS += -Iarch/$(ARCH)
AFLAGS += -Iarch/$(ARCH)
cflags-y += -Iarch/$(ARCH) -msoft-float -pipe \
- -ffixed-r2 -Wno-uninitialized -mmultiple -mstring
+ -ffixed-r2 -Wno-uninitialized -mmultiple
CPP = $(CC) -E $(CFLAGS)
+ifndef CONFIG_E500
+cflags-y += -mstring
+endif
+
cflags-$(CONFIG_4xx) += -Wa,-m405
+cflags-$(CONFIG_E500) += -Wa,-me500
cflags-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge
CFLAGS += $(cflags-y)
-
head-y := arch/ppc/kernel/head.o
head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o
head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
+head-$(CONFIG_E500) := arch/ppc/kernel/head_e500.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/
+core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/
core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
core-$(CONFIG_XMON) += arch/ppc/xmon/
core-$(CONFIG_APUS) += arch/ppc/amiga/
ifdef CONFIG_6xx
# Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later
-NEW_AS := $(shell echo dssall | $(AS) -o /dev/null >/dev/null 2>&1 ; echo $$?)
+NEW_AS := $(shell echo dssall | $(AS) -many -o /dev/null >/dev/null 2>&1 ; echo $$?)
GOODVER := 2.12.1
else
NEW_AS := 0
ifneq ($(NEW_AS),0)
checkbin:
- @echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build'
+ @echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '
@echo 'correctly with old versions of binutils.'
@echo '*** Please upgrade your binutils to ${GOODVER} or newer'
@false
#include <linux/types.h>
#include <linux/config.h>
#include <linux/string.h>
+#include <asm/reg.h>
#ifdef CONFIG_8xx
#include <asm/mpc8xx.h>
#endif
#ifdef CONFIG_8260
/* Compute 8260 clock values if the rom doesn't provide them.
- * We can't compute the internal core frequency (I don't know how to
- * do that).
*/
+static unsigned char bus2core_8260[] = {
+/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2,
+ 6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2,
+};
+
static void
clk_8260(bd_t *bd)
{
uint scmr, vco_out, clkin;
- uint plldf, pllmf, busdf, brgdf, cpmdf;
+ uint plldf, pllmf, corecnf;
volatile immap_t *ip;
ip = (immap_t *)IMAP_ADDR;
*/
plldf = (scmr >> 12) & 1;
pllmf = scmr & 0xfff;
- cpmdf = (scmr >> 16) & 0x0f;
- busdf = (scmr >> 20) & 0x0f;
+ corecnf = (scmr >> 24) &0x1f;
/* This is arithmetic from the 8260 manual.
*/
bd->bi_vco = vco_out; /* Save for later */
bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */
+ bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2;
/* Set Baud rate divisor. The power up default is divide by 16,
* but we set it again here in case it was changed.
ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */
bd->bi_brgfreq = vco_out / 16;
}
+
+static unsigned char bus2core_8280[] = {
+/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2,
+ 6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2,
+};
+
+static void
+clk_8280(bd_t *bd)
+{
+ uint scmr, main_clk, clkin;
+ uint pllmf, corecnf;
+ volatile immap_t *ip;
+
+ ip = (immap_t *)IMAP_ADDR;
+ scmr = ip->im_clkrst.car_scmr;
+
+ /* The clkin is always bus frequency.
+ */
+ clkin = bd->bi_busfreq;
+
+ /* Collect the bits from the scmr.
+ */
+ pllmf = scmr & 0xf;
+ corecnf = (scmr >> 24) & 0x1f;
+
+ /* This is arithmetic from the 8280 manual.
+ */
+ main_clk = clkin * (pllmf + 1);
+
+ bd->bi_cpmfreq = main_clk / 2; /* CPM Freq, in MHz */
+ bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2;
+
+ /* Set Baud rate divisor. The power up default is divide by 16,
+ * but we set it again here in case it was changed.
+ */
+ ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1;
+ bd->bi_brgfreq = main_clk / 16;
+}
#endif
+#ifdef CONFIG_SBC82xx
+void
+embed_config(bd_t **bdp)
+{
+ u_char *cp;
+ int i;
+ bd_t *bd;
+ unsigned long pvr;
+
+ bd = *bdp;
+
+ bd = &bdinfo;
+ *bdp = bd;
+ bd->bi_baudrate = 9600;
+ bd->bi_memsize = 256 * 1024 * 1024; /* just a guess */
+
+ cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1;
+ memcpy(bd->bi_enetaddr, cp, 6);
+
+ /* can busfreq be calculated? */
+ pvr = mfspr(PVR);
+ if ((pvr & 0xffff0000) == 0x80820000) {
+ bd->bi_busfreq = 100000000;
+ clk_8280(bd);
+ } else {
+ bd->bi_busfreq = 66000000;
+ clk_8260(bd);
+ }
+
+}
+#endif /* SBC82xx */
+
#if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260)
void
embed_config(bd_t **bdp)
ifdef CONFIG_4xx
EXTRA_AFLAGS := -Wa,-m405
endif
+ifdef CONFIG_E500
+EXTRA_AFLAGS := -Wa,-me500
+endif
extra-$(CONFIG_PPC_STD_MMU) := head.o
extra-$(CONFIG_40x) := head_4xx.o
extra-$(CONFIG_44x) := head_44x.o
+extra-$(CONFIG_E500) := head_e500.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
unsigned char flags;
};
-#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE)
#define OPCD(inst) (((inst) & 0xFC000000) >> 26)
#define RS(inst) (((inst) & 0x03E00000) >> 21)
#define RA(inst) (((inst) & 0x001F0000) >> 16)
fix_alignment(struct pt_regs *regs)
{
int instr, nb, flags;
-#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE)
int opcode, f1, f2, f3;
#endif
int i, t;
CHECK_FULL_REGS(regs);
-#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
- /* The 4xx-family processors have no DSISR register,
+#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) || defined(CONFIG_BOOKE)
+ /* The 4xx-family & Book-E processors have no DSISR register,
* so we emulate it.
* The POWER4 has a DSISR register but doesn't set it on
* an alignment fault. -- paulus
flags = aligninfo[instr].flags;
- /* For the 4xx-family processors, the 'dar' field of the
+ /* For the 4xx-family & Book-E processors, the 'dar' field of the
* pt_regs structure is overloaded and is really from the DEAR.
*/
DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
DEFINE(PT_PTRACED, PT_PTRACED);
#endif
DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
+ DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
+ DEFINE(THREAD_SPEFSCR, offsetof(struct thread_struct, spefscr));
+ DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
+#endif /* CONFIG_SPE */
/* Interrupt register frame */
DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
- !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4))
+ !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
+ !defined(CONFIG_BOOKE))
/* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well...
32, 32,
__setup_cpu_603
},
+ { /* 8280 is a G2_LE (603e core, plus some) */
+ 0x7fff0000, 0x00820000, "8280",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_CAN_NAP | CPU_FTR_HAS_HIGH_BATS,
+ COMMON_PPC,
+ 32, 32,
+ __setup_cpu_603
+ },
{ /* default match, we assume split I/D cache & TB (non-601)... */
0x00000000, 0x00000000, "(generic PPC)",
CPU_FTR_COMMON |
0, /*__setup_cpu_440 */
},
#endif /* CONFIG_44x */
+#ifdef CONFIG_E500
+ { /* e500 */
+ 0xffff0000, 0x80200000, "e500",
+ /* xxx - galak: add CPU_FTR_CAN_DOZE */
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 32, 32,
+ 0, /*__setup_cpu_e500 */
+ },
+#endif
#if !CLASSIC_PPC
{ /* default match */
0x00000000, 0x00000000, "(generic PPC)",
#undef SHOW_SYSCALLS_TASK
/*
- * MSR_KERNEL is > 0x10000 on 4xx since it include MSR_CE.
+ * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
*/
#if MSR_KERNEL >= 0x10000
#define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l
#endif
#ifdef CONFIG_BOOKE
-#define COR r8
+#define COR r8 /* Critical Offset Register (COR) */
#define BOOKE_LOAD_COR lis COR,crit_save@ha
#define BOOKE_REST_COR mfspr COR,SPRG2
#define BOOKE_SAVE_COR mtspr SPRG2,COR
andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
bne- syscall_exit_work
syscall_exit_cont:
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
/* If the process has its own DBCR0 value, load it up */
lwz r0,PTRACE(r2)
andi. r0,r0,PT_PTRACED
- bnel- load_4xx_dbcr0
+ bnel- load_dbcr0
#endif
stwcx. r0,0,r1 /* to clear the reservation */
lwz r4,_LINK(r1)
stw r12,THREAD+THREAD_VRSAVE(r2)
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif /* CONFIG_ALTIVEC */
- and. r0,r0,r11 /* FP or altivec enabled? */
+#ifdef CONFIG_SPE
+ oris r0,r0,MSR_SPE@h /* Disable SPE */
+ mfspr r12,SPRN_SPEFSCR /* save spefscr register value */
+ stw r12,THREAD+THREAD_SPEFSCR(r2)
+#endif /* CONFIG_SPE */
+ and. r0,r0,r11 /* FP or altivec or SPE enabled? */
beq+ 1f
andc r11,r11,r0
MTMSRD(r11)
mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ lwz r0,THREAD+THREAD_SPEFSCR(r2)
+ mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */
+#endif /* CONFIG_SPE */
lwz r0,_CCR(r1)
mtcrf 0xFF,r0
bne do_work
restore_user:
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
/* Check whether this process has its own DBCR0 value */
lwz r0,PTRACE(r2)
andi. r0,r0,PT_PTRACED
- bnel- load_4xx_dbcr0
+ bnel- load_dbcr0
#endif
#ifdef CONFIG_PREEMPT
PPC405_ERR77(0,r1)
stwcx. r0,0,r1 /* to clear the reservation */
-#ifndef CONFIG_4xx
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
lwz r9,_MSR(r1)
andi. r10,r9,MSR_RI /* check if this exception occurred */
beql nonrecoverable /* at a bad place (MSR:RI = 0) */
SYNC
RFI
-#else /* CONFIG_4xx */
+#else /* !(CONFIG_4xx || CONFIG_BOOKE) */
/*
- * This is a bit different on 4xx because 4xx doesn't have
+ * This is a bit different on 4xx/Book-E because it doesn't have
* the RI bit in the MSR.
* The TLB miss handler checks if we have interrupted
* the exception exit path and restarts it if so
* give the wrong answer).
* We have to restore various SPRs that may have been in use at the
* time of the critical interrupt.
+ *
+ * Note that SPRG6 is used for machine check on CONFIG_BOOKE parts and
+ * thus not saved in the critical handler
*/
.globl ret_from_crit_exc
ret_from_crit_exc:
* Load the DBCR0 value for a task that is being ptraced,
* having first saved away the global DBCR0.
*/
-load_4xx_dbcr0:
+load_dbcr0:
mfmsr r0 /* first disable debug exceptions */
rlwinm r0,r0,0,~MSR_DE
mtmsr r0
blr
.comm global_dbcr0,8
-#endif /* CONFIG_4xx */
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
do_work: /* r10 contains MSR_KERNEL here */
andi. r0,r9,_TIF_NEED_RESCHED
void disable_irq(unsigned int irq)
{
+ irq_desc_t *desc = irq_desc + irq;
disable_irq_nosync(irq);
- synchronize_irq(irq);
+ if (desc->action)
+ synchronize_irq(irq);
}
/**
static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
- cpumask_t *mask = (cpumask_t *)data, full_count = count, err;
+ int err;
+ int full_count = count;
+ cpumask_t *mask = (cpumask_t *)data;
cpumask_t new_value;
err = cpumask_parse(buffer, count, new_value);
ble 1b
isync
-#else /* !(CONFIG_40x || CONFIG_44x) */
+#elif defined(CONFIG_FSL_BOOKE)
+ /* Invalidate all entries in TLB0 */
+ li r3, 0x04
+ tlbivax 0,3
+ /* Invalidate all entries in TLB1 */
+ li r3, 0x0c
+ tlbivax 0,3
+ /* Invalidate all entries in TLB2 */
+ li r3, 0x14
+ tlbivax 0,3
+ /* Invalidate all entries in TLB3 */
+ li r3, 0x1c
+ tlbivax 0,3
+ msync
+#ifdef CONFIG_SMP
+ tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
#if defined(CONFIG_SMP)
rlwinm r8,r1,0,0,18
lwz r8,TI_CPU(r8)
tlbwe r3, r3, PPC44x_TLB_PAGEID
isync
10:
-#else /* !(CONFIG_40x || CONFIG_44x) */
+#elif defined(CONFIG_FSL_BOOKE)
+ rlwinm r4, r3, 0, 0, 19
+ ori r5, r4, 0x08 /* TLBSEL = 1 */
+ ori r6, r4, 0x10 /* TLBSEL = 2 */
+ ori r7, r4, 0x18 /* TLBSEL = 3 */
+ tlbivax 0, r4
+ tlbivax 0, r5
+ tlbivax 0, r6
+ tlbivax 0, r7
+ msync
+#if defined(CONFIG_SMP)
+ tlbsync
+#endif /* CONFIG_SMP */
+#else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */
#if defined(CONFIG_SMP)
rlwinm r8,r1,0,0,18
lwz r8,TI_CPU(r8)
lis r3, KERNELBASE@h
iccci 0,r3
#endif
+#elif CONFIG_FSL_BOOKE
+ mfspr r3,SPRN_L1CSR1
+ ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
+ mtspr SPRN_L1CSR1,r3
#else
mfspr r3,PVR
rlwinm r3,r3,16,16,31
* and exceptions as if the cpu had performed the load or store.
*/
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_E500)
_GLOBAL(cvt_fd)
lfs 0,0(r3)
stfd 0,0(r4)
struct resource *res = dev->resource + i;
if (!res->flags)
continue;
- if (!res->start || res->end == 0xffffffff) {
+ if (res->end == 0xffffffff) {
DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
pci_name(dev), i, res->start, res->end);
res->end -= res->start;
return -1;
}
res = bus->resource[i];
+ if (res == NULL)
+ return -1;
pr = NULL;
for (j = 0; j < 4; j++) {
struct resource *r = parent->resource[j];
return;
bus_range = (int *) get_property(node, "bus-range", &len);
if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s\n",
- node->full_name);
- return;
- }
- pci_to_OF_bus_map[pci_bus] = bus_range[0];
+ printk(KERN_WARNING "Can't get bus-range for %s, "
+ "assuming it starts at 0\n", node->full_name);
+ pci_to_OF_bus_map[pci_bus] = 0;
+ } else
+ pci_to_OF_bus_map[pci_bus] = bus_range[0];
for (node=node->child; node != 0;node = node->sibling) {
struct pci_dev* dev;
u16 w;
struct resource res;
+ if (bus->resource[0] == NULL)
+ return;
res = *(bus->resource[0]);
DBG("Remapping Bus %d, bridge: %s\n", bus->number, bridge->slot_name);
int has_vga = 0;
for (parent_io=0; parent_io<4; parent_io++)
- if (bus->resource[parent_io]->flags & IORESOURCE_IO)
+ if (bus->resource[parent_io]
+ && bus->resource[parent_io]->flags & IORESOURCE_IO)
break;
if (parent_io >= 4)
return;
{
unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0;
int n = 0;
-#ifdef CONFIG_PPC_STD_MMU
+#if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE)
unsigned int kptes = 0, uptes = 0;
PTE *ptr;
#endif /* CONFIG_PPC_STD_MMU */
goto return_string;
}
+#ifndef CONFIG_PPC64BRIDGE
for (ptr = Hash; ptr < Hash_end; ptr++) {
unsigned int mctx, vsid;
else
uptes++;
}
+#endif
n += sprintf( buffer + n,
"PTE Hash Table Information\n"
"Buckets\t\t: %lu\n"
"Address\t\t: %08lx\n"
"Entries\t\t: %lu\n"
+#ifndef CONFIG_PPC64BRIDGE
"User ptes\t: %u\n"
"Kernel ptes\t: %u\n"
- "Percent full\t: %lu%%\n",
- (unsigned long)(Hash_size>>10),
+ "Percent full\t: %lu%%\n"
+#endif
+ , (unsigned long)(Hash_size>>10),
(Hash_size/(sizeof(PTE)*8)),
(unsigned long)Hash,
- Hash_size/sizeof(PTE),
- uptes,
+ Hash_size/sizeof(PTE)
+#ifndef CONFIG_PPC64BRIDGE
+ , uptes,
kptes,
((kptes+uptes)*100) / (Hash_size/sizeof(PTE))
+#endif
);
n += sprintf( buffer + n,
EXPORT_SYMBOL(last_task_used_altivec);
EXPORT_SYMBOL(giveup_altivec);
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+EXPORT_SYMBOL(last_task_used_spe);
+EXPORT_SYMBOL(giveup_spe);
+#endif /* CONFIG_SPE */
#ifdef CONFIG_SMP
-#ifdef CONFIG_DEBUG_SPINLOCK
-EXPORT_SYMBOL(_raw_spin_lock);
-EXPORT_SYMBOL(_raw_spin_unlock);
-EXPORT_SYMBOL(_raw_spin_trylock);
-EXPORT_SYMBOL(_raw_read_lock);
-EXPORT_SYMBOL(_raw_read_unlock);
-EXPORT_SYMBOL(_raw_write_lock);
-EXPORT_SYMBOL(_raw_write_unlock);
-#endif
EXPORT_SYMBOL(smp_call_function);
EXPORT_SYMBOL(smp_hw_index);
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(cpm_install_handler);
EXPORT_SYMBOL(cpm_free_handler);
#endif /* CONFIG_8xx */
-#if defined(CONFIG_8xx) || defined(CONFIG_40x)
+#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx)
EXPORT_SYMBOL(__res);
#endif
#if defined(CONFIG_8xx)
#include <linux/init_task.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/mqueue.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
struct task_struct *last_task_used_math = NULL;
struct task_struct *last_task_used_altivec = NULL;
+struct task_struct *last_task_used_spe = NULL;
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
void
enable_kernel_altivec(void)
{
- WARN_ON(current_thread_info()->preempt_count == 0 && !irqs_disabled());
+ WARN_ON(preemptible());
#ifdef CONFIG_SMP
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
EXPORT_SYMBOL(enable_kernel_altivec);
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+int
+dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
+{
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+ /* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
+ memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35);
+ return 1;
+}
+
+void
+enable_kernel_spe(void)
+{
+ WARN_ON(preemptible());
+
+#ifdef CONFIG_SMP
+ if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
+ giveup_spe(current);
+ else
+ giveup_spe(NULL); /* just enable SPE for kernel - force */
+#else
+ giveup_spe(last_task_used_spe);
+#endif /* __SMP __ */
+}
+EXPORT_SYMBOL(enable_kernel_spe);
+#endif /* CONFIG_SPE */
+
void
enable_kernel_fp(void)
{
- WARN_ON(current_thread_info()->preempt_count == 0 && !irqs_disabled());
+ WARN_ON(preemptible());
#ifdef CONFIG_SMP
if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
giveup_altivec(prev);
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /*
+ * If the previous thread used spe in the last quantum
+ * (thus changing spe regs) then save them.
+ *
+ * On SMP we always save/restore spe regs just to avoid the
+ * complexity of changing processors.
+ */
+ if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
+ giveup_spe(prev);
+#endif /* CONFIG_SPE */
#endif /* CONFIG_SMP */
/* Avoid the trap. On smp this this never happens since
*/
if (new->thread.regs && last_task_used_altivec == new)
new->thread.regs->msr |= MSR_VEC;
+#ifdef CONFIG_SPE
+ /* Avoid the trap. On smp this this never happens since
+ * we don't set last_task_used_spe
+ */
+ if (new->thread.regs && last_task_used_spe == new)
+ new->thread.regs->msr |= MSR_SPE;
+#endif /* CONFIG_SPE */
new_thread = &new->thread;
old_thread = ¤t->thread;
last = _switch(old_thread, new_thread);
if (regs->msr & MSR_VEC)
giveup_altivec(current);
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+#endif /* CONFIG_SPE */
preempt_enable();
}
current->thread.vrsave = 0;
current->thread.used_vr = 0;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ memset(current->thread.evr, 0, sizeof(current->thread.evr));
+ current->thread.acc = 0;
+ current->thread.spefscr = 0;
+ current->thread.used_spe = 0;
+#endif /* CONFIG_SPE */
}
+#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
+ | PR_FP_EXC_RES | PR_FP_EXC_INV)
+
int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
{
struct pt_regs *regs = tsk->thread.regs;
- if (val > PR_FP_EXC_PRECISE)
+ /* This is a bit hairy. If we are an SPE enabled processor
+ * (have embedded fp) we store the IEEE exception enable flags in
+ * fpexc_mode. fpexc_mode is also used for setting FP exception
+ * mode (asyn, precise, disabled) for 'Classic' FP. */
+ if (val & PR_FP_EXC_SW_ENABLE) {
+#ifdef CONFIG_SPE
+ tsk->thread.fpexc_mode = val &
+ (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
+#else
return -EINVAL;
- tsk->thread.fpexc_mode = __pack_fe01(val);
- if (regs != NULL && (regs->msr & MSR_FP) != 0)
- regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
- | tsk->thread.fpexc_mode;
+#endif
+ } else {
+ /* on a CONFIG_SPE this does not hurt us. The bits that
+ * __pack_fe01 use do not overlap with bits used for
+ * PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits
+ * on CONFIG_SPE implementations are reserved so writing to
+ * them does not change anything */
+ if (val > PR_FP_EXC_PRECISE)
+ return -EINVAL;
+ tsk->thread.fpexc_mode = __pack_fe01(val);
+ if (regs != NULL && (regs->msr & MSR_FP) != 0)
+ regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
+ | tsk->thread.fpexc_mode;
+ }
return 0;
}
{
unsigned int val;
- val = __unpack_fe01(tsk->thread.fpexc_mode);
+ if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
+#ifdef CONFIG_SPE
+ val = tsk->thread.fpexc_mode;
+#else
+ return -EINVAL;
+#endif
+ else
+ val = __unpack_fe01(tsk->thread.fpexc_mode);
return put_user(val, (unsigned int *) adr);
}
if (regs->msr & MSR_VEC)
giveup_altivec(current);
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (regs->msr & MSR_SPE)
+ giveup_spe(current);
+#endif /* CONFIG_SPE */
preempt_enable();
error = do_execve(filename, (char __user *__user *) a1,
(char __user *__user *) a2, regs);
/*
* Set of msr bits that gdb can change on behalf of a process.
*/
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
#define MSR_DEBUGCHANGE 0
#else
#define MSR_DEBUGCHANGE (MSR_SE | MSR_BE)
}
#endif
+#ifdef CONFIG_SPE
+
+/*
+ * For get_evrregs/set_evrregs functions 'data' has the following layout:
+ *
+ * struct {
+ * u32 evr[32];
+ * u64 acc;
+ * u32 spefscr;
+ * }
+ */
+
+/*
+ * Get contents of SPE register state in task TASK.
+ */
+static inline int get_evrregs(unsigned long *data, struct task_struct *task)
+{
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 35 * sizeof(unsigned long)))
+ return -EFAULT;
+
+ /* copy SPEFSCR */
+ if (__put_user(task->thread.spefscr, &data[34]))
+ return -EFAULT;
+
+ /* copy SPE registers EVR[0] .. EVR[31] */
+ for (i = 0; i < 32; i++, data++)
+ if (__put_user(task->thread.evr[i], data))
+ return -EFAULT;
+
+ /* copy ACC */
+ if (__put_user64(task->thread.acc, (unsigned long long *)data))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * Write contents of SPE register state into task TASK.
+ */
+static inline int set_evrregs(struct task_struct *task, unsigned long *data)
+{
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 35 * sizeof(unsigned long)))
+ return -EFAULT;
+
+ /* copy SPEFSCR */
+ if (__get_user(task->thread.spefscr, &data[34]))
+ return -EFAULT;
+
+ /* copy SPE registers EVR[0] .. EVR[31] */
+ for (i = 0; i < 32; i++, data++)
+ if (__get_user(task->thread.evr[i], data))
+ return -EFAULT;
+ /* copy ACC */
+ if (__get_user64(task->thread.acc, (unsigned long long*)data))
+ return -EFAULT;
+
+ return 0;
+}
+#endif /* CONFIG_SPE */
+
static inline void
set_single_step(struct task_struct *task)
{
struct pt_regs *regs = task->thread.regs;
if (regs != NULL) {
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
/* MSR.DE should already be set */
#else
struct pt_regs *regs = task->thread.regs;
if (regs != NULL) {
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
task->thread.dbcr0 = 0;
#else
regs->msr &= ~MSR_SE;
ret = set_vrregs(child, (unsigned long *)data);
break;
#endif
+#ifdef CONFIG_SPE
+ case PTRACE_GETEVRREGS:
+ /* Get the child spe register state. */
+ if (child->thread.regs->msr & MSR_SPE)
+ giveup_spe(child);
+ ret = get_evrregs((unsigned long *)data, child);
+ break;
+
+ case PTRACE_SETEVRREGS:
+ /* Set the child spe register state. */
+ /* this is to clear the MSR_SPE bit to force a reload
+ * of register state from memory */
+ if (child->thread.regs->msr & MSR_SPE)
+ giveup_spe(child);
+ ret = set_evrregs(child, (unsigned long *)data);
+ break;
+#endif
default:
ret = ptrace_request(child, request, addr, data);
/*
* Save the current user registers on the user stack.
- * We only save the altivec registers if the process has used
- * altivec instructions at some point.
+ * We only save the altivec/spe registers if the process has used
+ * altivec/spe instructions at some point.
*/
static int
save_user_regs(struct pt_regs *regs, struct mcontext *frame, int sigret)
#ifdef CONFIG_ALTIVEC
if (current->thread.used_vr && (regs->msr & MSR_VEC))
giveup_altivec(current);
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ if (current->thread.used_spe && (regs->msr & MSR_SPE))
+ giveup_spe(current);
#endif /* CONFIG_ALTIVEC */
preempt_enable();
return 1;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* save spe registers */
+ if (current->thread.used_spe) {
+ if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32)))
+ return 1;
+ /* set MSR_SPE in the saved MSR value to indicate that
+ frame->mc_vregs contains valid data */
+ if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR]))
+ return 1;
+ }
+ /* else assert((regs->msr & MSR_SPE) == 0) */
+
+ /* We always copy to/from spefscr */
+ if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG))
+ return 1;
+#endif /* CONFIG_SPE */
+
if (sigret) {
/* Set up the sigreturn trampoline: li r0,sigret; sc */
if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig)
{
unsigned long save_r2;
-#ifdef CONFIG_ALTIVEC
+#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
unsigned long msr;
#endif
return 1;
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ /* force the process to reload the spe registers from
+ current->thread when it next does spe instructions */
+ regs->msr &= ~MSR_SPE;
+ if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
+ /* restore spe registers from the stack */
+ if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
+ sizeof(sr->mc_vregs)))
+ return 1;
+ } else if (current->thread.used_spe)
+ memset(¤t->thread.evr, 0, ELF_NEVRREG * sizeof(u32));
+
+ /* Always get SPEFSCR back */
+ if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG))
+ return 1;
+#endif /* CONFIG_SPE */
+
return 0;
}
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/prctl.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
/* On 4xx, the reason for the machine check or program exception
is in the ESR. */
#define get_reason(regs) ((regs)->dsisr)
+#ifndef CONFIG_E500
+#define get_mc_reason(regs) ((regs)->dsisr)
+#else
+#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
+#endif
#define REASON_FP 0
#define REASON_ILLEGAL ESR_PIL
#define REASON_PRIVILEGED ESR_PPR
/* On non-4xx, the reason for the machine check or program
exception is in the MSR. */
#define get_reason(regs) ((regs)->msr)
+#define get_mc_reason(regs) ((regs)->msr)
#define REASON_FP 0x100000
#define REASON_ILLEGAL 0x80000
#define REASON_PRIVILEGED 0x40000
void
MachineCheckException(struct pt_regs *regs)
{
- unsigned long reason = get_reason(regs);
+ unsigned long reason = get_mc_reason(regs);
if (user_mode(regs)) {
regs->msr |= MSR_RI;
/* Clear MCSR */
mtspr(SPRN_MCSR, mcsr);
}
-#else /* !CONFIG_4xx */
+#elif defined (CONFIG_E500)
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from MCSR=%lx): ", reason);
+
+ if (reason & MCSR_MCP)
+ printk("Machine Check Signal\n");
+ if (reason & MCSR_ICPERR)
+ printk("Instruction Cache Parity Error\n");
+ if (reason & MCSR_DCP_PERR)
+ printk("Data Cache Push Parity Error\n");
+ if (reason & MCSR_DCPERR)
+ printk("Data Cache Parity Error\n");
+ if (reason & MCSR_GL_CI)
+ printk("Guarded Load or Cache-Inhibited stwcx.\n");
+ if (reason & MCSR_BUS_IAERR)
+ printk("Bus - Instruction Address Error\n");
+ if (reason & MCSR_BUS_RAERR)
+ printk("Bus - Read Address Error\n");
+ if (reason & MCSR_BUS_WAERR)
+ printk("Bus - Write Address Error\n");
+ if (reason & MCSR_BUS_IBERR)
+ printk("Bus - Instruction Data Error\n");
+ if (reason & MCSR_BUS_RBERR)
+ printk("Bus - Read Data Bus Error\n");
+ if (reason & MCSR_BUS_WBERR)
+ printk("Bus - Read Data Bus Error\n");
+ if (reason & MCSR_BUS_IPERR)
+ printk("Bus - Instruction Parity Error\n");
+ if (reason & MCSR_BUS_RPERR)
+ printk("Bus - Read Parity Error\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 */
printk("Machine check in kernel mode.\n");
printk("Caused by (from SRR1=%lx): ", reason);
switch (reason & 0x601F0000) {
}
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_FSL_BOOKE
+void CacheLockingException(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code)
+{
+ /* We treat cache locking instructions from the user
+ * as priv ops, in the future we could try to do
+ * something smarter
+ */
+ if (error_code & (ESR_DLK|ESR_ILK))
+ _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
+ return;
+}
+#endif /* CONFIG_FSL_BOOKE */
+
+#ifdef CONFIG_SPE
+void
+SPEFloatingPointException(struct pt_regs *regs)
+{
+ unsigned long spefscr;
+ int fpexc_mode;
+ int code = 0;
+
+ spefscr = current->thread.spefscr;
+ fpexc_mode = current->thread.fpexc_mode;
+
+ /* Hardware does not neccessarily set sticky
+ * underflow/overflow/invalid flags */
+ if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
+ code = FPE_FLTOVF;
+ spefscr |= SPEFSCR_FOVFS;
+ }
+ else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) {
+ code = FPE_FLTUND;
+ spefscr |= SPEFSCR_FUNFS;
+ }
+ else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV))
+ code = FPE_FLTDIV;
+ else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) {
+ code = FPE_FLTINV;
+ spefscr |= SPEFSCR_FINVS;
+ }
+ else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES))
+ code = FPE_FLTRES;
+
+ current->thread.spefscr = spefscr;
+
+ _exception(SIGFPE, regs, code, regs->nip);
+ return;
+}
+#endif
void __init trap_init(void)
{
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/module.h>
#include <asm/ppc_asm.h>
#include <asm/smp.h>
* since they may inhibit forward progress by other CPUs in getting
* a lock.
*/
-unsigned long __spin_trylock(volatile unsigned long *lock)
+static inline unsigned long __spin_trylock(volatile unsigned long *lock)
{
unsigned long ret;
lock->owner_pc = (unsigned long)__builtin_return_address(0);
lock->owner_cpu = cpu;
}
+EXPORT_SYMBOL(_raw_spin_lock);
int _raw_spin_trylock(spinlock_t *lock)
{
lock->owner_pc = (unsigned long)__builtin_return_address(0);
return 1;
}
+EXPORT_SYMBOL(_raw_spin_trylock);
void _raw_spin_unlock(spinlock_t *lp)
{
wmb();
lp->lock = 0;
}
+EXPORT_SYMBOL(_raw_spin_unlock);
/*
}
wmb();
}
+EXPORT_SYMBOL(_raw_read_lock);
void _raw_read_unlock(rwlock_t *rw)
{
wmb();
atomic_dec((atomic_t *) &(rw)->lock);
}
+EXPORT_SYMBOL(_raw_read_unlock);
void _raw_write_lock(rwlock_t *rw)
{
}
wmb();
}
+EXPORT_SYMBOL(_raw_write_lock);
+
+int _raw_write_trylock(rwlock_t *rw)
+{
+ if (test_and_set_bit(31, &(rw)->lock)) /* someone has a write lock */
+ return 0;
+
+ if ((rw)->lock & ~(1<<31)) { /* someone has a read lock */
+ /* clear our write lock and wait for reads to go away */
+ clear_bit(31,&(rw)->lock);
+ return 0;
+ }
+ wmb();
+ return 1;
+}
+EXPORT_SYMBOL(_raw_write_trylock);
void _raw_write_unlock(rwlock_t *rw)
{
wmb();
clear_bit(31,&(rw)->lock);
}
+EXPORT_SYMBOL(_raw_write_unlock);
#endif
obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o
obj-$(CONFIG_40x) += 4xx_mmu.o
obj-$(CONFIG_44x) += 44x_mmu.o
+obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o
struct mm_struct *mm = current->mm;
siginfo_t info;
int code = SEGV_MAPERR;
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
int is_write = error_code & ESR_DST;
#else
int is_write = 0;
error_code &= 0x48200000;
else
is_write = error_code & 0x02000000;
-#endif /* CONFIG_4xx */
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_fault_handler && TRAP(regs) == 0x300) {
debugger_fault_handler(regs);
return 0;
}
-#if !defined(CONFIG_4xx)
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
if (error_code & 0x00400000) {
/* DABR match */
if (debugger_dabr_match(regs))
return 0;
}
-#endif /* !CONFIG_4xx */
+#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
#endif /* CONFIG_XMON || CONFIG_KGDB */
if (in_atomic() || mm == NULL)
if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
-#if defined(CONFIG_4xx)
- /* an exec - 4xx allows for per-page execute permission */
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ /* an exec - 4xx/Book-E allows for per-page execute permission */
} else if (TRAP(regs) == 0x400) {
pte_t *ptep;
goto bad_area;
#endif
- /* Since 4xx supports per-page execute permission,
+ /* Since 4xx/Book-E supports per-page execute permission,
* we lazily flush dcache to icache. */
ptep = NULL;
if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
if (__max_memory && total_memory > __max_memory)
total_memory = __max_memory;
total_lowmem = total_memory;
+#ifdef CONFIG_FSL_BOOKE
+ /* Freescale Book-E parts expect lowmem to be mapped by fixed TLB
+ * entries, so we need to adjust lowmem to match the amount we can map
+ * in the fixed entries */
+ adjust_total_lowmem();
+#endif /* CONFIG_FSL_BOOKE */
if (total_lowmem > __max_low_memory) {
total_lowmem = __max_low_memory;
#ifndef CONFIG_HIGHMEM
extern void setbat(int index, unsigned long virt, unsigned long phys,
unsigned int size, int flags);
extern void reserve_phys_mem(unsigned long start, unsigned long size);
+extern void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned int size, int flags, unsigned int pid);
+extern void invalidate_tlbcam_entry(int index);
extern int __map_without_bats;
extern unsigned long ioremap_base;
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void);
+#elif defined(CONFIG_FSL_BOOKE)
+#define flush_HPTE(X, va, pg) _tlbie(va)
+extern void MMU_init_hw(void);
+extern unsigned long mmu_mapin_ram(void);
+extern void adjust_total_lowmem(void);
+
#else
/* anything except 4xx or 8xx */
extern void MMU_init_hw(void);
#define HAVE_BATS 1
#endif
+#if defined(CONFIG_FSL_BOOKE)
+#define HAVE_TLBCAM 1
+#endif
+
extern char etext[], _stext[];
#ifdef CONFIG_SMP
#define p_mapped_by_bats(x) (0UL)
#endif /* HAVE_BATS */
+#ifdef HAVE_TLBCAM
+extern unsigned int tlbcam_index;
+extern unsigned int num_tlbcam_entries;
+extern unsigned long v_mapped_by_tlbcam(unsigned long va);
+extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
+#else /* !HAVE_TLBCAM */
+#define v_mapped_by_tlbcam(x) (0UL)
+#define p_mapped_by_tlbcam(x) (0UL)
+#endif /* HAVE_TLBCAM */
+
#ifdef CONFIG_44x
/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */
#define PGDIR_ORDER 1
if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
goto out;
+ if ((v = p_mapped_by_tlbcam(p)))
+ goto out;
+
if (mem_init_done) {
struct vm_struct *area;
area = get_vm_area(size, VM_IOREMAP);
/* is x a power of 2? */
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
+/* is x a power of 4? */
+#define is_power_of_4(x) ((x) != 0 && (((x) & (x-1)) == 0) && (ffs(x) & 1))
+
/*
* Set up a mapping for a block of I/O.
* virt, phys, size must all be page-aligned.
}
#endif /* HAVE_BATS */
+#ifdef HAVE_TLBCAM
+ /*
+ * Use a CAM for this if possible...
+ */
+ if (tlbcam_index < num_tlbcam_entries && is_power_of_4(size)
+ && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+ settlbcam(tlbcam_index, virt, phys, size, flags, 0);
+ ++tlbcam_index;
+ return;
+ }
+#endif /* HAVE_TLBCAM */
+
/* No BATs available, put it in the page tables. */
for (i = 0; i < size; i += PAGE_SIZE)
map_page(virt + i, phys + i, flags);
flush_hash_pages(mm->context, addr, ptephys, 1);
}
+/*
+ * Called by ptep_set_access_flags, must flush on CPUs for which the
+ * DSI handler can't just "fixup" the TLB on a write fault
+ */
+void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (Hash != 0)
+ return;
+ _tlbie(addr);
+}
+
/*
* Called at the end of a mmu_gather operation to make sure the
* TLB flush is completely done.
obj-$(CONFIG_PRPMC750) += prpmc750.o
obj-$(CONFIG_PRPMC800) += prpmc800.o
obj-$(CONFIG_SANDPOINT) += sandpoint.o
+obj-$(CONFIG_SBC82xx) += sbc82xx.o
obj-$(CONFIG_SPRUCE) += spruce.o
ifeq ($(CONFIG_SMP),y)
ifdef CONFIG_4xx
EXTRA_AFLAGS := -Wa,-m405
endif
+ifdef CONFIG_E500
+EXTRA_AFLAGS := -Wa,-me500
+endif
-CFLAGS_prom_init.o += -mrelocatable-lib
-CFLAGS_btext.o += -mrelocatable-lib
+CFLAGS_prom_init.o += -fPIC
+CFLAGS_btext.o += -fPIC
obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o
obj-$(CONFIG_PPC_OCP) += ocp.o
obj-$(CONFIG_HARRIER) += harrier.o
obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o
obj-$(CONFIG_SANDPOINT) += i8259.o open_pic.o pci_auto.o todc_time.o
+obj-$(CONFIG_SBC82xx) += todc_time.o
obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \
todc_time.o
obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o
endif
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o indirect_pci.o
+obj-$(CONFIG_40x) += dcr.o
+obj-$(CONFIG_BOOKE) += dcr.o
+obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o
+ifeq ($(CONFIG_85xx),y)
+obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
+endif
#include "open_pic_defs.h"
-#ifdef CONFIG_PRPMC800
+#if defined(CONFIG_PRPMC800) || defined(CONFIG_85xx)
#define OPENPIC_BIG_ENDIAN
#endif
config PREEMPT
bool "Preemptible Kernel"
- depends on BROKEN
help
This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to
HAS_BIARCH := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;)
ifeq ($(HAS_BIARCH),y)
-AS := $(AS) -64
+AS := $(AS) -a64
LD := $(LD) -m elf64ppc
CC := $(CC) -m64
endif
#include <asm/cache.h>
#include <asm/cputable.h>
-void disable_kernel_fp(void); /* asm function from head.S */
-
struct aligninfo {
unsigned char len;
unsigned char flags;
}
/* Force the fprs into the save area so we can reference them */
- if ((flags & F) && (regs->msr & MSR_FP))
- giveup_fpu(current);
+ if (flags & F) {
+ if (!user_mode(regs))
+ return 0;
+ flush_fp_to_thread(current);
+ }
/* If we are loading, get the data from user space */
if (flags & LD) {
if (flags & F) {
if (nb == 4) {
/* Doing stfs, have to convert to single */
+ preempt_disable();
enable_kernel_fp();
cvt_df(¤t->thread.fpr[reg], (float *)&data.v[4], ¤t->thread.fpscr);
disable_kernel_fp();
+ preempt_enable();
}
else
data.dd = current->thread.fpr[reg];
if (flags & F) {
if (nb == 4) {
/* Doing lfs, have to convert to double */
+ preempt_disable();
enable_kernel_fp();
cvt_fd((float *)&data.v[4], ¤t->thread.fpr[reg], ¤t->thread.fpscr);
disable_kernel_fp();
+ preempt_enable();
}
else
current->thread.fpr[reg] = data.dd;
DEFINE(THREAD_SHIFT, THREAD_SHIFT);
DEFINE(THREAD_SIZE, THREAD_SIZE);
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
/* task_struct->thread */
DEFINE(THREAD, offsetof(struct task_struct, thread));
DEFINE(PACALPPACA, offsetof(struct paca_struct, xLpPaca));
DEFINE(LPPACA, offsetof(struct paca_struct, xLpPaca));
DEFINE(PACAREGSAV, offsetof(struct paca_struct, xRegSav));
- DEFINE(PACAEXC, offsetof(struct paca_struct, exception_stack));
+ DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
+ DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
+ DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
+ DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
DEFINE(PACAGUARD, offsetof(struct paca_struct, guard));
DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
+ DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
+ DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
+ DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
+ DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
DEFINE(GPR20, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[20]));
DEFINE(GPR21, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[21]));
DEFINE(GPR22, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[22]));
DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
- DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
+ DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
/* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
#define DO_SOFT_DISABLE
#endif
-#undef SHOW_SYSCALLS
-#undef SHOW_SYSCALLS_TASK
-
-#ifdef SHOW_SYSCALLS_TASK
- .data
-show_syscalls_task:
- .long -1
-#endif
-
+/*
+ * System calls.
+ */
.section ".toc","aw"
.SYS_CALL_TABLE:
.tc .sys_call_table[TC],.sys_call_table
.SYS_CALL_TABLE32:
.tc .sys_call_table32[TC],.sys_call_table32
+/* This value is used to mark exception frames on the stack. */
+exception_marker:
+ .tc ID_72656773_68657265[TC],0x7265677368657265
+
.section ".text"
- .align 3
+ .align 7
-/*
- * Handle a system call.
- */
-_GLOBAL(DoSyscall)
+#undef SHOW_SYSCALLS
+
+ .globl SystemCall_common
+SystemCall_common:
+ andi. r10,r12,MSR_PR
+ mr r10,r1
+ addi r1,r1,-INT_FRAME_SIZE
+ beq- 1f
+ ld r1,PACAKSAVE(r13)
+1: std r10,0(r1)
+ std r11,_NIP(r1)
+ std r12,_MSR(r1)
+ std r0,GPR0(r1)
+ std r10,GPR1(r1)
+ std r2,GPR2(r1)
+ std r3,GPR3(r1)
+ std r4,GPR4(r1)
+ std r5,GPR5(r1)
+ std r6,GPR6(r1)
+ std r7,GPR7(r1)
+ std r8,GPR8(r1)
+ li r11,0
+ std r11,GPR9(r1)
+ std r11,GPR10(r1)
+ std r11,GPR11(r1)
+ std r11,GPR12(r1)
+ std r9,GPR13(r1)
+ crclr so
+ mfcr r9
+ mflr r10
+ li r11,0xc01
+ std r9,_CCR(r1)
+ std r10,_LINK(r1)
+ std r11,_TRAP(r1)
+ mfxer r9
+ mfctr r10
+ std r9,_XER(r1)
+ std r10,_CTR(r1)
std r3,ORIG_GPR3(r1)
- ld r11,_CCR(r1) /* Clear SO bit in CR */
- lis r10,0x1000
- andc r11,r11,r10
- std r11,_CCR(r1)
+ ld r2,PACATOC(r13)
+ addi r9,r1,STACK_FRAME_OVERHEAD
+ ld r11,exception_marker@toc(r2)
+ std r11,-16(r9) /* "regshere" marker */
+#ifdef CONFIG_PPC_ISERIES
+ /* Hack for handling interrupts when soft-enabling on iSeries */
+ cmpdi cr1,r0,0x5555 /* syscall 0x5555 */
+ andi. r10,r12,MSR_PR /* from kernel */
+ crand 4*cr0+eq,4*cr1+eq,4*cr0+eq
+ beq HardwareInterrupt_entry
+ lbz r10,PACAPROCENABLED(r13)
+ std r10,SOFTE(r1)
+#endif
+ mfmsr r11
+ ori r11,r11,MSR_EE
+ mtmsrd r11,1
+
#ifdef SHOW_SYSCALLS
-#ifdef SHOW_SYSCALLS_TASK
- LOADBASE(r31,show_syscalls_task)
- ld r31,show_syscalls_task@l(r31)
- ld r10,PACACURRENT(r13)
- cmp 0,r10,r31
- bne 1f
+ bl .do_show_syscall
+ REST_GPR(0,r1)
+ REST_4GPRS(3,r1)
+ REST_2GPRS(7,r1)
+ addi r9,r1,STACK_FRAME_OVERHEAD
#endif
- LOADADDR(r3,7f)
- ld r4,GPR0(r1)
- ld r5,GPR3(r1)
- ld r6,GPR4(r1)
- ld r7,GPR5(r1)
- ld r8,GPR6(r1)
- ld r9,GPR7(r1)
- bl .printk
- LOADADDR(r3,77f)
- ld r4,GPR8(r1)
- ld r5,GPR9(r1)
- ld r6, PACACURRENT(r13)
- bl .printk
- ld r0,GPR0(r1)
- ld r3,GPR3(r1)
- ld r4,GPR4(r1)
- ld r5,GPR5(r1)
- ld r6,GPR6(r1)
- ld r7,GPR7(r1)
- ld r8,GPR8(r1)
-1:
-#endif /* SHOW_SYSCALLS */
- clrrdi r10,r1,THREAD_SHIFT
- ld r10,TI_FLAGS(r10)
+ clrrdi r11,r1,THREAD_SHIFT
+ li r12,0
+ ld r10,TI_FLAGS(r11)
+ stb r12,TI_SC_NOERR(r11)
andi. r11,r10,_TIF_SYSCALL_T_OR_A
- bne- 50f
+ bne- syscall_dotrace
+syscall_dotrace_cont:
cmpli 0,r0,NR_syscalls
- bge- 66f
+ bge- syscall_enosys
+
+system_call: /* label this so stack traces look sane */
/*
* Need to vector to 32 Bit or default sys_call_table here,
* based on caller's run-mode / personality.
*/
- andi. r11,r10,_TIF_32BIT
+ ld r11,.SYS_CALL_TABLE@toc(2)
+ andi. r10,r10,_TIF_32BIT
beq- 15f
- ld r10,.SYS_CALL_TABLE32@toc(2)
-/*
- * We now zero extend all six arguments (r3 - r8), the compatibility
- * layer assumes this.
- */
+ ld r11,.SYS_CALL_TABLE32@toc(2)
clrldi r3,r3,32
clrldi r4,r4,32
clrldi r5,r5,32
clrldi r6,r6,32
clrldi r7,r7,32
clrldi r8,r8,32
- b 17f
15:
- ld r10,.SYS_CALL_TABLE@toc(2)
-17: slwi r0,r0,3
- ldx r10,r10,r0 /* Fetch system call handler [ptr] */
+ slwi r0,r0,3
+ ldx r10,r11,r0 /* Fetch system call handler [ptr] */
mtlr r10
- addi r9,r1,STACK_FRAME_OVERHEAD
blrl /* Call handler */
-_GLOBAL(ret_from_syscall_1)
- std r3,RESULT(r1) /* Save result */
+
+syscall_exit:
#ifdef SHOW_SYSCALLS
-#ifdef SHOW_SYSCALLS_TASK
- ld r10, PACACURRENT(13)
- cmp 0,r10,r31
- bne 91f
-#endif
- mr r4,r3
- LOADADDR(r3,79f)
- bl .printk
- ld r3,RESULT(r1)
-91:
+ std r3,GPR3(r1)
+ bl .do_show_syscall_exit
+ ld r3,GPR3(r1)
#endif
+ std r3,RESULT(r1)
+ ld r5,_CCR(r1)
li r10,-_LAST_ERRNO
- cmpld 0,r3,r10
- blt 30f
+ cmpld r3,r10
+ clrrdi r12,r1,THREAD_SHIFT
+ bge- syscall_error
+syscall_error_cont:
+
+ /* check for syscall tracing or audit */
+ ld r9,TI_FLAGS(r12)
+ andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ bne- syscall_exit_trace
+syscall_exit_trace_cont:
+
+ /* disable interrupts so current_thread_info()->flags can't change,
+ and so that we don't get interrupted after loading SRR0/1. */
+ ld r8,_MSR(r1)
+ andi. r10,r8,MSR_RI
+ beq- unrecov_restore
+ mfmsr r10
+ rldicl r10,r10,48,1
+ rotldi r10,r10,16
+ mtmsrd r10,1
+ ld r9,TI_FLAGS(r12)
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+ bne- syscall_exit_work
+ ld r7,_NIP(r1)
+ stdcx. r0,0,r1 /* to clear the reservation */
+ andi. r6,r8,MSR_PR
+ ld r4,_LINK(r1)
+ beq 1f /* only restore r13 if */
+ ld r13,GPR13(r1) /* returning to usermode */
+1: ld r2,GPR2(r1)
+ ld r1,GPR1(r1)
+ li r12,MSR_RI
+ andc r10,r10,r12
+ mtmsrd r10,1 /* clear MSR.RI */
+ mtlr r4
+ mtcr r5
+ mtspr SRR0,r7
+ mtspr SRR1,r8
+ rfid
+
+syscall_enosys:
+ li r3,-ENOSYS
+ std r3,RESULT(r1)
+ clrrdi r12,r1,THREAD_SHIFT
+ ld r5,_CCR(r1)
+
+syscall_error:
+ lbz r11,TI_SC_NOERR(r12)
+ cmpi 0,r11,0
+ bne- syscall_error_cont
neg r3,r3
-22: ld r10,_CCR(r1) /* Set SO bit in CR */
- oris r10,r10,0x1000
- std r10,_CCR(r1)
-30: std r3,GPR3(r1) /* Update return value */
- b .ret_from_except
-66: li r3,ENOSYS
- b 22b
+ oris r5,r5,0x1000 /* Set SO bit in CR */
+ std r5,_CCR(r1)
+ b syscall_error_cont
/* Traced system call support */
-50: addi r3,r1,STACK_FRAME_OVERHEAD
+syscall_dotrace:
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_syscall_trace_enter
ld r0,GPR0(r1) /* Restore original registers */
ld r3,GPR3(r1)
ld r6,GPR6(r1)
ld r7,GPR7(r1)
ld r8,GPR8(r1)
- /* XXX check this - Anton */
- ld r9,GPR9(r1)
- cmpli 0,r0,NR_syscalls
- bge- 66f
-/*
- * Need to vector to 32 Bit or default sys_call_table here,
- * based on caller's run-mode / personality.
- */
+ addi r9,r1,STACK_FRAME_OVERHEAD
clrrdi r10,r1,THREAD_SHIFT
ld r10,TI_FLAGS(r10)
- andi. r11,r10,_TIF_32BIT
- beq- 55f
- ld r10,.SYS_CALL_TABLE32@toc(2)
+ b syscall_dotrace_cont
+
+syscall_exit_trace:
+ std r3,GPR3(r1)
+ bl .save_nvgprs
+ bl .do_syscall_trace_leave
+ REST_NVGPRS(r1)
+ ld r3,GPR3(r1)
+ ld r5,_CCR(r1)
+ clrrdi r12,r1,THREAD_SHIFT
+ b syscall_exit_trace_cont
+
+/* Stuff to do on exit from a system call. */
+syscall_exit_work:
+ std r3,GPR3(r1)
+ std r5,_CCR(r1)
+ b .ret_from_except_lite
+
+/* Save non-volatile GPRs, if not already saved. */
+_GLOBAL(save_nvgprs)
+ ld r11,_TRAP(r1)
+ andi. r0,r11,1
+ beqlr-
+ SAVE_NVGPRS(r1)
+ clrrdi r0,r11,1
+ std r0,_TRAP(r1)
+ blr
+
/*
- * We now zero extend all six arguments (r3 - r8), the compatibility
- * layer assumes this.
+ * The sigsuspend and rt_sigsuspend system calls can call do_signal
+ * and thus put the process into the stopped state where we might
+ * want to examine its user state with ptrace. Therefore we need
+ * to save all the nonvolatile registers (r14 - r31) before calling
+ * the C code. Similarly, fork, vfork and clone need the full
+ * register state on the stack so that it can be copied to the child.
*/
- clrldi r3,r3,32
- clrldi r4,r4,32
- clrldi r5,r5,32
- clrldi r6,r6,32
- clrldi r7,r7,32
- clrldi r8,r8,32
- b 57f
-55:
- ld r10,.SYS_CALL_TABLE@toc(2)
-57:
- slwi r0,r0,3
- ldx r10,r10,r0 /* Fetch system call handler [ptr] */
- mtlr r10
- addi r9,r1,STACK_FRAME_OVERHEAD
- blrl /* Call handler */
-_GLOBAL(ret_from_syscall_2)
- std r3,RESULT(r1) /* Save result */
- li r10,-_LAST_ERRNO
- cmpld 0,r3,r10
- blt 60f
- neg r3,r3
-57: ld r10,_CCR(r1) /* Set SO bit in CR */
- oris r10,r10,0x1000
- std r10,_CCR(r1)
-60: std r3,GPR3(r1) /* Update return value */
- bl .do_syscall_trace_leave
- b .ret_from_except
-66: li r3,ENOSYS
- b 57b
-#ifdef SHOW_SYSCALLS
-7: .string "syscall %d(%x, %x, %x, %x, %x, "
-77: .string "%x, %x), current=%p\n"
-79: .string " -> %x\n"
- .align 2,0
-#endif
+_GLOBAL(ppc32_sigsuspend)
+ bl .save_nvgprs
+ bl .sys32_sigsuspend
+ b syscall_exit
+
+_GLOBAL(ppc64_rt_sigsuspend)
+ bl .save_nvgprs
+ bl .sys_rt_sigsuspend
+ b syscall_exit
+
+_GLOBAL(ppc32_rt_sigsuspend)
+ bl .save_nvgprs
+ bl .sys32_rt_sigsuspend
+ b syscall_exit
+
+_GLOBAL(ppc_fork)
+ bl .save_nvgprs
+ bl .sys_fork
+ b syscall_exit
+
+_GLOBAL(ppc_vfork)
+ bl .save_nvgprs
+ bl .sys_vfork
+ b syscall_exit
+
+_GLOBAL(ppc_clone)
+ bl .save_nvgprs
+ bl .sys_clone
+ b syscall_exit
-
_GLOBAL(ppc32_swapcontext)
+ bl .save_nvgprs
bl .sys32_swapcontext
b 80f
_GLOBAL(ppc64_swapcontext)
+ bl .save_nvgprs
bl .sys_swapcontext
b 80f
_GLOBAL(ppc64_rt_sigreturn)
bl .sys_rt_sigreturn
-80: clrrdi r4,r1,THREAD_SHIFT
+80: cmpdi 0,r3,0
+ blt syscall_exit
+ clrrdi r4,r1,THREAD_SHIFT
ld r4,TI_FLAGS(r4)
andi. r4,r4,_TIF_SYSCALL_T_OR_A
- bne- 81f
- cmpi 0,r3,0
- bge .ret_from_except
- b .ret_from_syscall_1
-81: cmpi 0,r3,0
- blt .ret_from_syscall_2
+ beq+ 81f
bl .do_syscall_trace_leave
- b .ret_from_except
+81: b .ret_from_except
+
+_GLOBAL(ret_from_fork)
+ bl .schedule_tail
+ REST_NVGPRS(r1)
+ li r3,0
+ b syscall_exit
/*
* This routine switches between two different tasks. The process
* The code which creates the new task context is in 'copy_thread'
* in arch/ppc64/kernel/process.c
*/
+ .align 7
_GLOBAL(_switch)
mflr r0
std r0,16(r1)
2:
END_FTR_SECTION_IFSET(CPU_FTR_SLB)
clrrdi r7,r8,THREAD_SHIFT /* base of new stack */
- addi r7,r7,THREAD_SIZE-INT_FRAME_SIZE
+ /* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
+ because we don't need to leave the 288-byte ABI gap at the
+ top of the kernel stack. */
+ addi r7,r7,THREAD_SIZE-SWITCH_FRAME_SIZE
mr r1,r8 /* start using new stack pointer */
std r7,PACAKSAVE(r13)
addi r1,r1,SWITCH_FRAME_SIZE
blr
-_GLOBAL(ret_from_fork)
- bl .schedule_tail
- clrrdi r4,r1,THREAD_SHIFT
- ld r4,TI_FLAGS(r4)
- andi. r4,r4,_TIF_SYSCALL_T_OR_A
- beq+ .ret_from_except
- bl .do_syscall_trace_leave
- b .ret_from_except
-
+ .align 7
_GLOBAL(ret_from_except)
+ ld r11,_TRAP(r1)
+ andi. r0,r11,1
+ bne .ret_from_except_lite
+ REST_NVGPRS(r1)
+
+_GLOBAL(ret_from_except_lite)
/*
* Disable interrupts so that current_thread_info()->flags
* can't change between when we test it and when we return
* from the interrupt.
*/
mfmsr r10 /* Get current interrupt state */
- li r4,0
- ori r4,r4,MSR_EE
- andc r9,r10,r4 /* clear MSR_EE */
+ rldicl r9,r10,48,1 /* clear MSR_EE */
+ rotldi r9,r9,16
mtmsrd r9,1 /* Update machine state */
+#ifdef CONFIG_PREEMPT
+ clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */
+ li r0,_TIF_NEED_RESCHED /* bits to check */
+ ld r3,_MSR(r1)
+ ld r4,TI_FLAGS(r9)
+ /* Move MSR_PR bit in r3 to _TIF_SIGPENDING position in r0 */
+ rlwimi r0,r3,32+TIF_SIGPENDING-MSR_PR_LG,_TIF_SIGPENDING
+ and. r0,r4,r0 /* check NEED_RESCHED and maybe SIGPENDING */
+ bne do_work
+
+#else /* !CONFIG_PREEMPT */
ld r3,_MSR(r1) /* Returning to user mode? */
andi. r3,r3,MSR_PR
beq restore /* if not, just restore regs and return */
/* Check current_thread_info()->flags */
- clrrdi r3,r1,THREAD_SHIFT
- ld r3,TI_FLAGS(r3)
- andi. r0,r3,_TIF_USER_WORK_MASK
+ clrrdi r9,r1,THREAD_SHIFT
+ ld r4,TI_FLAGS(r9)
+ andi. r0,r4,_TIF_USER_WORK_MASK
bne do_work
-
- addi r0,r1,INT_FRAME_SIZE /* size of frame */
- ld r4,PACACURRENT(r13)
- std r0,THREAD+KSP(r4) /* save kernel stack pointer */
-
- /*
- * r13 is our per cpu area, only restore it if we are returning to
- * userspace
- */
- REST_GPR(13,r1)
+#endif
restore:
#ifdef CONFIG_PPC_ISERIES
ld r5,SOFTE(r1)
- mfspr r4,SPRG3 /* get paca address */
cmpdi 0,r5,0
beq 4f
/* Check for pending interrupts (iSeries) */
- /* this is CHECKANYINT except that we already have the paca address */
- ld r3,PACALPPACA+LPPACAANYINT(r4)
+ ld r3,PACALPPACA+LPPACAANYINT(r13)
cmpdi r3,0
beq+ 4f /* skip do_IRQ if no interrupts */
- mfspr r13,SPRG3 /* get paca pointer back */
li r3,0
stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */
mtmsrd r10 /* hard-enable again */
bl .do_IRQ
b .ret_from_except /* loop back and handle more */
-4: stb r5,PACAPROCENABLED(r4)
+4: stb r5,PACAPROCENABLED(r13)
#endif
ld r3,_MSR(r1)
- andi. r3,r3,MSR_RI
+ andi. r0,r3,MSR_RI
beq- unrecov_restore
+ andi. r0,r3,MSR_PR
+
+ /*
+ * r13 is our per cpu area, only restore it if we are returning to
+ * userspace
+ */
+ beq 1f
+ REST_GPR(13, r1)
+1:
ld r3,_CTR(r1)
ld r0,_LINK(r1)
mtctr r3
mtspr XER,r3
REST_8GPRS(5, r1)
- REST_10GPRS(14, r1)
- REST_8GPRS(24, r1)
stdcx. r0,0,r1 /* to clear the reservation */
ld r1,GPR1(r1)
rfid
+ b .
-/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
+/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
do_work:
+#ifdef CONFIG_PREEMPT
+ andi. r0,r3,MSR_PR /* Returning to user mode? */
+ bne user_work
+ /* Check that preempt_count() == 0 and interrupts are enabled */
+ lwz r8,TI_PREEMPT(r9)
+ cmpwi cr1,r8,0
+#ifdef CONFIG_PPC_ISERIES
+ ld r0,SOFTE(r1)
+ cmpdi r0,0
+#else
+ andi. r0,r3,MSR_EE
+#endif
+ crandc eq,cr1*4+eq,eq
+ bne restore
+ /* here we are preempting the current task */
+1: lis r0,PREEMPT_ACTIVE@h
+ stw r0,TI_PREEMPT(r9)
+#ifdef CONFIG_PPC_ISERIES
+ li r0,1
+ stb r0,PACAPROCENABLED(r13)
+#endif
+ mtmsrd r10,1 /* reenable interrupts */
+ bl .schedule
+ mfmsr r10
+ clrrdi r9,r1,THREAD_SHIFT
+ rldicl r10,r10,48,1 /* disable interrupts again */
+ li r0,0
+ rotldi r10,r10,16
+ mtmsrd r10,1
+ ld r4,TI_FLAGS(r9)
+ andi. r0,r4,_TIF_NEED_RESCHED
+ bne 1b
+ stw r0,TI_PREEMPT(r9)
+ b restore
+
+user_work:
+#endif
/* Enable interrupts */
mtmsrd r10,1
- andi. r0,r3,_TIF_NEED_RESCHED
+ andi. r0,r4,_TIF_NEED_RESCHED
beq 1f
bl .schedule
- b .ret_from_except
+ b .ret_from_except_lite
-1: andi. r0,r3,_TIF_SIGPENDING
- beq .ret_from_except
+1: bl .save_nvgprs
li r3,0
addi r4,r1,STACK_FRAME_OVERHEAD
bl .do_signal
b .ret_from_except
unrecov_restore:
- mfspr r13,SPRG3
addi r3,r1,STACK_FRAME_OVERHEAD
bl .unrecoverable_exception
b unrecov_restore
mflr r0
std r0,16(r1)
stdu r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */
-
+
/* Because RTAS is running in 32b mode, it clobbers the high order half
* of all registers that it saves. We therefore save those registers
* RTAS might touch to the stack. (r0, r3-r13 are caller saved)
#define DO_SOFT_DISABLE
#endif
-/* copy saved SOFTE bit or EE bit from saved MSR depending
- * if we are doing soft-disable or not
- */
-#ifdef DO_SOFT_DISABLE
-#define DO_COPY_EE() ld r20,SOFTE(r1)
-#else
-#define DO_COPY_EE() rldicl r20,r23,49,63
-#endif
-
/*
* hcall interface to pSeries LPAR
*/
#endif
#endif
+/* This value is used to mark exception frames on the stack. */
+ .section ".toc","aw"
+exception_marker:
+ .tc ID_72656773_68657265[TC],0x7265677368657265
+ .text
+
/*
* The following macros define the code that appears as
* the prologue to each of the exception handlers. They
* are split into two parts to allow a single kernel binary
- * to be used for pSeries, and iSeries.
+ * to be used for pSeries and iSeries.
+ * LOL. One day... - paulus
*/
/*
* This is the start of the interrupt handlers for pSeries
* This code runs with relocation off.
*/
-#define EX_SRR0 0
-#define EX_SRR1 8
-#define EX_R20 16
-#define EX_R21 24
-#define EX_R22 32
-#define EX_R23 40
+#define EX_R9 0
+#define EX_R10 8
+#define EX_R11 16
+#define EX_R12 24
+#define EX_R13 32
+#define EX_SRR0 40
#define EX_DAR 48
#define EX_DSISR 56
#define EX_CCR 60
-#define EX_TRAP 60
-
-#define EXCEPTION_PROLOG_PSERIES(n,label) \
- mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \
- mtspr SPRG1,r21; /* save r21 */ \
- mfspr r20,SPRG3; /* get paca virt addr */ \
- ld r21,PACAEXCSP(r20); /* get exception stack ptr */ \
- addi r21,r21,EXC_FRAME_SIZE; /* make exception frame */ \
- std r22,EX_R22(r21); /* Save r22 in exc. frame */ \
- li r22,n; /* Save the ex # in exc. frame*/ \
- stw r22,EX_TRAP(r21); /* */ \
- std r23,EX_R23(r21); /* Save r23 in exc. frame */ \
- mfspr r22,SRR0; /* EA of interrupted instr */ \
- std r22,EX_SRR0(r21); /* Save SRR0 in exc. frame */ \
- mfspr r23,SRR1; /* machine state at interrupt */ \
- std r23,EX_SRR1(r21); /* Save SRR1 in exc. frame */ \
- \
- mfspr r23,DAR; /* Save DAR in exc. frame */ \
- std r23,EX_DAR(r21); \
- mfspr r23,DSISR; /* Save DSISR in exc. frame */ \
- stw r23,EX_DSISR(r21); \
- mfspr r23,SPRG2; /* Save r20 in exc. frame */ \
- std r23,EX_R20(r21); \
- \
- clrrdi r22,r20,60; /* Get 0xc part of the vaddr */ \
- ori r22,r22,(label)@l; /* add in the vaddr offset */ \
- /* assumes *_common < 16b */ \
- mfmsr r23; \
- rotldi r23,r23,4; \
- ori r23,r23,0x32B; /* Set IR, DR, RI, SF, ISF, HV*/ \
- rotldi r23,r23,60; /* for generic handlers */ \
- mtspr SRR0,r22; \
- mtspr SRR1,r23; \
- mfcr r23; /* save CR in r23 */ \
+
+#define EXCEPTION_PROLOG_PSERIES(area, label) \
+ mfspr r13,SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9; \
+ clrrdi r12,r13,32; /* get high part of &label */ \
+ mfmsr r10; \
+ mfspr r11,SRR0; /* save SRR0 */ \
+ ori r12,r12,(label)@l; /* virt addr of handler */ \
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
+ mtspr SRR0,r12; \
+ mfspr r12,SRR1; /* and SRR1 */ \
+ mtspr SRR1,r10; \
rfid
/*
* This is the start of the interrupt handlers for iSeries
* This code runs with relocation on.
*/
-#define EXCEPTION_PROLOG_ISERIES(n) \
- mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \
- mtspr SPRG1,r21; /* save r21 */ \
- mfspr r20,SPRG3; /* get paca */ \
- ld r21,PACAEXCSP(r20); /* get exception stack ptr */ \
- addi r21,r21,EXC_FRAME_SIZE; /* make exception frame */ \
- std r22,EX_R22(r21); /* save r22 on exception frame */ \
- li r22,n; /* Save the ex # in exc. frame */ \
- stw r22,EX_TRAP(r21); /* */ \
- std r23,EX_R23(r21); /* Save r23 in exc. frame */ \
- ld r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */ \
- std r22,EX_SRR0(r21); /* save SRR0 in exc. frame */ \
- ld r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */ \
- std r23,EX_SRR1(r21); /* save SRR1 in exc. frame */ \
- \
- mfspr r23,DAR; /* Save DAR in exc. frame */ \
- std r23,EX_DAR(r21); \
- mfspr r23,DSISR; /* Save DSISR in exc. frame */ \
- stw r23,EX_DSISR(r21); \
- mfspr r23,SPRG2; /* Save r20 in exc. frame */ \
- std r23,EX_R20(r21); \
- \
- mfmsr r22; /* set MSR.RI */ \
- ori r22,r22,MSR_RI; \
- mtmsrd r22,1; \
- mfcr r23; /* save CR in r23 */
+#define EXCEPTION_PROLOG_ISERIES_1(area) \
+ mfspr r13,SPRG3; /* get paca address into r13 */ \
+ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
+ std r10,area+EX_R10(r13); \
+ std r11,area+EX_R11(r13); \
+ std r12,area+EX_R12(r13); \
+ mfspr r9,SPRG1; \
+ std r9,area+EX_R13(r13); \
+ mfcr r9
+
+#define EXCEPTION_PROLOG_ISERIES_2 \
+ mfmsr r10; \
+ ld r11,LPPACA+LPPACASRR0(r13); \
+ ld r12,LPPACA+LPPACASRR1(r13); \
+ ori r10,r10,MSR_RI; \
+ mtmsrd r10,1
/*
* The common exception prolog is used for all except a few exceptions
* to take another exception from the point where we first touch the
* kernel stack onwards.
*
- * On entry r20 points to the paca and r21 points to the exception
- * frame on entry, r23 contains the saved CR, and relocation is on.
- */
-#define EXCEPTION_PROLOG_COMMON \
- mfspr r22,SPRG1; /* Save r21 in exc. frame */ \
- std r22,EX_R21(r21); \
- std r21,PACAEXCSP(r20); /* update exception stack ptr */ \
- ld r22,EX_SRR1(r21); /* Get SRR1 from exc. frame */ \
- andi. r22,r22,MSR_PR; /* Set CR for later branch */ \
- mr r22,r1; /* Save r1 */ \
- subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
- beq- 1f; \
- ld r1,PACAKSAVE(r20); /* kernel stack to use */ \
-1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
- bge cr1,bad_stack; /* abort if it is */ \
- std r22,GPR1(r1); /* save r1 in stackframe */ \
- std r22,0(r1); /* make stack chain pointer */ \
- std r23,_CCR(r1); /* save CR in stackframe */ \
- ld r22,EX_R20(r21); /* move r20 to stackframe */ \
- std r22,GPR20(r1); \
- ld r23,EX_R21(r21); /* move r21 to stackframe */ \
- std r23,GPR21(r1); \
- ld r22,EX_R22(r21); /* move r22 to stackframe */ \
- std r22,GPR22(r1); \
- ld r23,EX_R23(r21); /* move r23 to stackframe */ \
- std r23,GPR23(r1); \
- mflr r22; /* save LR in stackframe */ \
- std r22,_LINK(r1); \
- mfctr r23; /* save CTR in stackframe */ \
- std r23,_CTR(r1); \
- mfspr r22,XER; /* save XER in stackframe */ \
- std r22,_XER(r1); \
- ld r23,EX_DAR(r21); /* move DAR to stackframe */ \
- std r23,_DAR(r1); \
- lwz r22,EX_DSISR(r21); /* move DSISR to stackframe */ \
- std r22,_DSISR(r1); \
- lbz r22,PACAPROCENABLED(r20); \
- std r22,SOFTE(r1); \
- ld r22,EX_SRR0(r21); /* get SRR0 from exc. frame */ \
- ld r23,EX_SRR1(r21); /* get SRR1 from exc. frame */ \
- addi r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame */ \
- std r21,PACAEXCSP(r20); \
- SAVE_GPR(0, r1); /* save r0 in stackframe */ \
- SAVE_8GPRS(2, r1); /* save r2 - r13 in stackframe */ \
- SAVE_4GPRS(10, r1); \
- ld r2,PACATOC(r20); \
- mr r13,r20
-
-/*
- * Note: code which follows this uses cr0.eq (set if from kernel),
- * r1, r22 (SRR0), and r23 (SRR1).
+ * On entry r13 points to the paca, r9-r13 are saved in the paca,
+ * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
+ * SRR1, and relocation is on.
*/
+#define EXCEPTION_PROLOG_COMMON(n, area) \
+ andi. r10,r12,MSR_PR; /* See if coming from user */ \
+ mr r10,r1; /* Save r1 */ \
+ subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
+ beq- 1f; \
+ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
+1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
+ bge- cr1,bad_stack; /* abort if it is */ \
+ std r9,_CCR(r1); /* save CR in stackframe */ \
+ std r11,_NIP(r1); /* save SRR0 in stackframe */ \
+ std r12,_MSR(r1); /* save SRR1 in stackframe */ \
+ std r10,0(r1); /* make stack chain pointer */ \
+ std r0,GPR0(r1); /* save r0 in stackframe */ \
+ std r10,GPR1(r1); /* save r1 in stackframe */ \
+ std r2,GPR2(r1); /* save r2 in stackframe */ \
+ SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
+ SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
+ ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \
+ ld r10,area+EX_R10(r13); \
+ std r9,GPR9(r1); \
+ std r10,GPR10(r1); \
+ ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \
+ ld r10,area+EX_R12(r13); \
+ ld r11,area+EX_R13(r13); \
+ std r9,GPR11(r1); \
+ std r10,GPR12(r1); \
+ std r11,GPR13(r1); \
+ ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
+ mflr r9; /* save LR in stackframe */ \
+ std r9,_LINK(r1); \
+ mfctr r10; /* save CTR in stackframe */ \
+ std r10,_CTR(r1); \
+ mfspr r11,XER; /* save XER in stackframe */ \
+ std r11,_XER(r1); \
+ li r9,(n)+1; \
+ std r9,_TRAP(r1); /* set trap number */ \
+ li r10,0; \
+ ld r11,exception_marker@toc(r2); \
+ std r10,RESULT(r1); /* clear regs->result */ \
+ std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */
/*
* Exception vectors.
*/
-#define STD_EXCEPTION_PSERIES(n, label ) \
- . = n; \
- .globl label##_Pseries; \
-label##_Pseries: \
- EXCEPTION_PROLOG_PSERIES( n, label##_common )
-
-#define STD_EXCEPTION_ISERIES( n, label ) \
- .globl label##_Iseries; \
-label##_Iseries: \
- EXCEPTION_PROLOG_ISERIES( n ); \
+#define STD_EXCEPTION_PSERIES(n, label ) \
+ . = n; \
+ .globl label##_Pseries; \
+label##_Pseries: \
+ mtspr SPRG1,r13; /* save r13 */ \
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+#define STD_EXCEPTION_ISERIES(n, label, area) \
+ .globl label##_Iseries; \
+label##_Iseries: \
+ mtspr SPRG1,r13; /* save r13 */ \
+ EXCEPTION_PROLOG_ISERIES_1(area); \
+ EXCEPTION_PROLOG_ISERIES_2; \
b label##_common
-#define MASKABLE_EXCEPTION_ISERIES( n, label ) \
- .globl label##_Iseries; \
-label##_Iseries: \
- EXCEPTION_PROLOG_ISERIES( n ); \
- lbz r22,PACAPROFENABLED(r20); \
- cmpi 0,r22,0; \
- bne- label##_Iseries_profile; \
-label##_Iseries_prof_ret: \
- lbz r22,PACAPROCENABLED(r20); \
- cmpi 0,r22,0; \
- beq- label##_Iseries_masked; \
- b label##_common; \
-label##_Iseries_profile: \
- std r24,48(r21); \
- std r25,56(r21); \
- mflr r24; \
- bl do_profile; \
- mtlr r24; \
- ld r24,48(r21); \
- ld r25,56(r21); \
+#define MASKABLE_EXCEPTION_ISERIES( n, label ) \
+ .globl label##_Iseries; \
+label##_Iseries: \
+ mtspr SPRG1,r13; /* save r13 */ \
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
+ lbz r10,PACAPROFENABLED(r13); \
+ cmpwi r10,0; \
+ bne- label##_Iseries_profile; \
+label##_Iseries_prof_ret: \
+ lbz r10,PACAPROCENABLED(r13); \
+ cmpwi 0,r10,0; \
+ beq- label##_Iseries_masked; \
+ EXCEPTION_PROLOG_ISERIES_2; \
+ b label##_common; \
+label##_Iseries_profile: \
+ ld r12,LPPACA+LPPACASRR1(r13); \
+ andi. r12,r12,MSR_PR; /* Test if in kernel */ \
+ bne label##_Iseries_prof_ret; \
+ ld r11,LPPACA+LPPACASRR0(r13); \
+ ld r12,PACAPROFSTEXT(r13); /* _stext */ \
+ subf r11,r12,r11; /* offset into kernel */ \
+ lwz r12,PACAPROFSHIFT(r13); \
+ srd r11,r11,r12; \
+ lwz r12,PACAPROFLEN(r13); /* profile table length - 1 */ \
+ cmpd r11,r12; /* off end? */ \
+ ble 1f; \
+ mr r11,r12; /* force into last entry */ \
+1: sldi r11,r11,2; /* convert to offset */ \
+ ld r12,PACAPROFBUFFER(r13);/* profile buffer */ \
+ add r12,r12,r11; \
+2: lwarx r11,0,r12; /* atomically increment */ \
+ addi r11,r11,1; \
+ stwcx. r11,0,r12; \
+ bne- 2b; \
b label##_Iseries_prof_ret
+#ifdef DO_SOFT_DISABLE
+#define DISABLE_INTS \
+ lbz r10,PACAPROCENABLED(r13); \
+ li r11,0; \
+ std r10,SOFTE(r1); \
+ mfmsr r10; \
+ stb r11,PACAPROCENABLED(r13); \
+ ori r10,r10,MSR_EE; \
+ mtmsrd r10,1
+
+#define ENABLE_INTS \
+ lbz r10,PACAPROCENABLED(r13); \
+ mfmsr r11; \
+ std r10,SOFTE(r1); \
+ ori r11,r11,MSR_EE; \
+ mtmsrd r11,1
+
+#else /* hard enable/disable interrupts */
+#define DISABLE_INTS
+
+#define ENABLE_INTS \
+ ld r12,_MSR(r1); \
+ mfmsr r11; \
+ rlwimi r11,r12,0,MSR_EE; \
+ mtmsrd r11,1
+
+#endif
+
#define STD_EXCEPTION_COMMON( trap, label, hdlr ) \
- .globl label##_common; \
-label##_common: \
- EXCEPTION_PROLOG_COMMON; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- li r20,0; \
- li r6,trap; \
- bl .save_remaining_regs; \
- bl hdlr; \
+ .align 7; \
+ .globl label##_common; \
+label##_common: \
+ EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
+ DISABLE_INTS; \
+ bl .save_nvgprs; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ bl hdlr; \
b .ret_from_except
+#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
+ .align 7; \
+ .globl label##_common; \
+label##_common: \
+ EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
+ DISABLE_INTS; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ bl hdlr; \
+ b .ret_from_except_lite
+
/*
* Start of pSeries system interrupt routines
*/
__start_interrupts:
STD_EXCEPTION_PSERIES( 0x100, SystemReset )
- STD_EXCEPTION_PSERIES( 0x200, MachineCheck )
- STD_EXCEPTION_PSERIES( 0x300, DataAccess )
- STD_EXCEPTION_PSERIES( 0x380, DataAccessSLB )
+
+ . = 0x200
+ .globl MachineCheck_Pseries
+_MachineCheckPseries:
+ mtspr SPRG1,r13 /* save r13 */
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
+
+ . = 0x300
+ .globl DataAccess_Pseries
+DataAccess_Pseries:
+ mtspr SPRG1,r13
+BEGIN_FTR_SECTION
+ mtspr SPRG2,r12
+ mfspr r13,DAR
+ mfspr r12,DSISR
+ srdi r13,r13,60
+ rlwimi r13,r12,16,0x20
+ mfcr r12
+ cmpwi r13,0x2c
+ beq .do_stab_bolted_Pseries
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccess_common)
+
+ . = 0x380
+ .globl DataAccessSLB_Pseries
+DataAccessSLB_Pseries:
+ mtspr SPRG1,r13
+ mtspr SPRG2,r12
+ mfspr r13,DAR
+ mfcr r12
+ srdi r13,r13,60
+ cmpdi r13,0xc
+ beq .do_slb_bolted_Pseries
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccessSLB_common)
+
STD_EXCEPTION_PSERIES( 0x400, InstructionAccess )
STD_EXCEPTION_PSERIES( 0x480, InstructionAccessSLB )
STD_EXCEPTION_PSERIES( 0x500, HardwareInterrupt )
STD_EXCEPTION_PSERIES( 0x900, Decrementer )
STD_EXCEPTION_PSERIES( 0xa00, Trap_0a )
STD_EXCEPTION_PSERIES( 0xb00, Trap_0b )
- STD_EXCEPTION_PSERIES( 0xc00, SystemCall )
+
+ . = 0xc00
+ .globl SystemCall_Pseries
+SystemCall_Pseries:
+ mr r9,r13
+ mfmsr r10
+ mfspr r13,SPRG3
+ mfspr r11,SRR0
+ clrrdi r12,r13,32
+ oris r12,r12,SystemCall_common@h
+ ori r12,r12,SystemCall_common@l
+ mtspr SRR0,r12
+ ori r10,r10,MSR_IR|MSR_DR|MSR_RI
+ mfspr r12,SRR1
+ mtspr SRR1,r10
+ rfid
+
STD_EXCEPTION_PSERIES( 0xd00, SingleStep )
STD_EXCEPTION_PSERIES( 0xe00, Trap_0e )
* trickery is thus necessary
*/
. = 0xf00
- b .PerformanceMonitor_Pseries
- . = 0xf20
- b .AltivecUnavailable_Pseries
+ b PerformanceMonitor_Pseries
+
+ STD_EXCEPTION_PSERIES(0xf20, AltivecUnavailable)
STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
STD_EXCEPTION_PSERIES( 0x1700, AltivecAssist )
- /* Here are the "moved" performance monitor and
- * altivec unavailable exceptions
- */
- . = 0x3000
- .globl PerformanceMonitor_Pseries;
-.PerformanceMonitor_Pseries:
- EXCEPTION_PROLOG_PSERIES(0xf00, PerformanceMonitor_common)
+ /* moved from 0xf00 */
+ STD_EXCEPTION_PSERIES(0x3000, PerformanceMonitor)
. = 0x3100
- .globl AltivecUnavailable_Pseries;
-.AltivecUnavailable_Pseries:
- EXCEPTION_PROLOG_PSERIES(0xf20, AltivecUnavailable_common)
+_GLOBAL(do_stab_bolted_Pseries)
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+ EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+
+_GLOBAL(do_slb_bolted_Pseries)
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+ EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_slb_bolted)
/* Space for the naca. Architected to be located at real address
/*** ISeries-LPAR interrupt handlers ***/
- STD_EXCEPTION_ISERIES( 0x200, MachineCheck )
- STD_EXCEPTION_ISERIES( 0x300, DataAccess )
- STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB )
- STD_EXCEPTION_ISERIES( 0x400, InstructionAccess )
- STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB )
- MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt )
- STD_EXCEPTION_ISERIES( 0x600, Alignment )
- STD_EXCEPTION_ISERIES( 0x700, ProgramCheck )
- STD_EXCEPTION_ISERIES( 0x800, FPUnavailable )
- MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer )
- STD_EXCEPTION_ISERIES( 0xa00, Trap_0a )
- STD_EXCEPTION_ISERIES( 0xb00, Trap_0b )
- STD_EXCEPTION_ISERIES( 0xc00, SystemCall )
- STD_EXCEPTION_ISERIES( 0xd00, SingleStep )
- STD_EXCEPTION_ISERIES( 0xe00, Trap_0e )
- STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor )
+ STD_EXCEPTION_ISERIES(0x200, MachineCheck, PACA_EXMC)
+
+ .globl DataAccess_Iseries
+DataAccess_Iseries:
+ mtspr SPRG1,r13
+BEGIN_FTR_SECTION
+ mtspr SPRG2,r12
+ mfspr r13,DAR
+ mfspr r12,DSISR
+ srdi r13,r13,60
+ rlwimi r13,r12,16,0x20
+ mfcr r12
+ cmpwi r13,0x2c
+ beq .do_stab_bolted_Iseries
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+ EXCEPTION_PROLOG_ISERIES_2
+ b DataAccess_common
+
+.do_stab_bolted_Iseries:
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ EXCEPTION_PROLOG_ISERIES_2
+ b .do_stab_bolted
+
+ .globl DataAccessSLB_Iseries
+DataAccessSLB_Iseries:
+ mtspr SPRG1,r13 /* save r13 */
+ mtspr SPRG2,r12
+ mfspr r13,DAR
+ mfcr r12
+ srdi r13,r13,60
+ cmpdi r13,0xc
+ beq .do_slb_bolted_Iseries
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+ EXCEPTION_PROLOG_ISERIES_2
+ b DataAccessSLB_common
+
+.do_slb_bolted_Iseries:
+ mtcrf 0x80,r12
+ mfspr r12,SPRG2
+ EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
+ EXCEPTION_PROLOG_ISERIES_2
+ b .do_slb_bolted
+
+ STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x480, InstructionAccessSLB, PACA_EXGEN)
+ MASKABLE_EXCEPTION_ISERIES(0x500, HardwareInterrupt)
+ STD_EXCEPTION_ISERIES(0x600, Alignment, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x700, ProgramCheck, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0x800, FPUnavailable, PACA_EXGEN)
+ MASKABLE_EXCEPTION_ISERIES(0x900, Decrementer)
+ STD_EXCEPTION_ISERIES(0xa00, Trap_0a, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES(0xb00, Trap_0b, PACA_EXGEN)
+
+ .globl SystemCall_Iseries
+SystemCall_Iseries:
+ mr r9,r13
+ mfspr r13,SPRG3
+ EXCEPTION_PROLOG_ISERIES_2
+ b SystemCall_common
+
+ STD_EXCEPTION_ISERIES( 0xd00, SingleStep, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES( 0xe00, Trap_0e, PACA_EXGEN)
+ STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor, PACA_EXGEN)
.globl SystemReset_Iseries
SystemReset_Iseries:
mfspr r13,SPRG3 /* Get paca address */
- mfmsr r24
- ori r24,r24,MSR_RI
- mtmsrd r24 /* RI on */
lhz r24,PACAPACAINDEX(r13) /* Get processor # */
- cmpi 0,r24,0 /* Are we processor 0? */
+ cmpwi 0,r24,0 /* Are we processor 0? */
beq .__start_initialization_iSeries /* Start up the first processor */
mfspr r4,CTRLF
li r5,RUNLATCH /* Turn off the run light */
addi r1,r3,THREAD_SIZE
subi r1,r1,STACK_FRAME_OVERHEAD
- cmpi 0,r23,0
+ cmpwi 0,r23,0
beq iseries_secondary_smp_loop /* Loop until told to go */
#ifdef SECONDARY_PROCESSORS
bne .__secondary_start /* Loop until told to go */
b 1b /* If SMP not configured, secondaries
* loop forever */
- .globl HardwareInterrupt_Iseries_masked
-HardwareInterrupt_Iseries_masked:
- b maskable_exception_exit
-
.globl Decrementer_Iseries_masked
Decrementer_Iseries_masked:
- li r22,1
- stb r22,PACALPPACA+LPPACADECRINT(r20)
- lwz r22,PACADEFAULTDECR(r20)
- mtspr DEC,r22
-maskable_exception_exit:
- mtcrf 0xff,r23 /* Restore regs and free exception frame */
- ld r22,EX_SRR0(r21)
- ld r23,EX_SRR1(r21)
- mtspr SRR0,r22
- mtspr SRR1,r23
- ld r22,EX_R22(r21)
- ld r23,EX_R23(r21)
- mfspr r21,SPRG1
- mfspr r20,SPRG2
+ li r11,1
+ stb r11,PACALPPACA+LPPACADECRINT(r13)
+ lwz r12,PACADEFAULTDECR(r13)
+ mtspr DEC,r12
+ /* fall through */
+
+ .globl HardwareInterrupt_Iseries_masked
+HardwareInterrupt_Iseries_masked:
+ mtcrf 0x80,r9 /* Restore regs */
+ ld r11,LPPACA+LPPACASRR0(r13)
+ ld r12,LPPACA+LPPACASRR1(r13)
+ mtspr SRR0,r11
+ mtspr SRR1,r12
+ ld r9,PACA_EXGEN+EX_R9(r13)
+ ld r10,PACA_EXGEN+EX_R10(r13)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
rfid
#endif
+
/*
* Data area reserved for FWNMI option.
*/
. = 0x8000
.globl SystemReset_FWNMI
SystemReset_FWNMI:
- EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common)
+ mtspr SPRG1,r13 /* save r13 */
+ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, SystemReset_common)
.globl MachineCheck_FWNMI
MachineCheck_FWNMI:
- EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)
+ mtspr SPRG1,r13 /* save r13 */
+ EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
/*
* Space for the initial segment table
/*** Common interrupt handlers ***/
STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
- STD_EXCEPTION_COMMON( 0x200, MachineCheck, .MachineCheckException )
- STD_EXCEPTION_COMMON( 0x900, Decrementer, .timer_interrupt )
+
+ /*
+ * Machine check is different because we use a different
+ * save area: PACA_EXMC instead of PACA_EXGEN.
+ */
+ .align 7
+ .globl MachineCheck_common
+MachineCheck_common:
+ EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
+ DISABLE_INTS
+ bl .save_nvgprs
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .MachineCheckException
+ b .ret_from_except
+
+ STD_EXCEPTION_COMMON_LITE(0x900, Decrementer, .timer_interrupt)
STD_EXCEPTION_COMMON( 0xa00, Trap_0a, .UnknownException )
STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException )
STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException )
#endif
/*
- * Here the exception frame is filled out and we have detected that
- * the kernel stack pointer is bad. R23 contains the saved CR, r20
- * points to the paca, r21 points to the exception frame, and r22
- * contains the (bad) kernel stack pointer.
+ * Here we have detected that the kernel stack pointer is bad.
+ * R9 contains the saved CR, r13 points to the paca,
+ * r10 contains the (bad) kernel stack pointer,
+ * r11 and r12 contain the saved SRR0 and SRR1.
* We switch to using the paca guard page as an emergency stack,
- * save the registers on there, and call kernel_bad_stack(),
- * which panics.
+ * save the registers there, and call kernel_bad_stack(), which panics.
*/
bad_stack:
- addi r1,r20,8192-64-INT_FRAME_SIZE
- std r22,GPR1(r1)
- std r23,_CCR(r1)
- ld r22,EX_R20(r21)
- std r22,GPR20(r1)
- ld r23,EX_R21(r21)
- std r23,GPR21(r1)
- ld r22,EX_R22(r21)
- std r22,GPR22(r1)
- ld r23,EX_R23(r21)
- std r23,GPR23(r1)
- ld r23,EX_DAR(r21)
- std r23,_DAR(r1)
- lwz r22,EX_DSISR(r21)
- std r22,_DSISR(r1)
- lwz r23,EX_TRAP(r21)
- std r23,TRAP(r1)
- ld r22,EX_SRR0(r21)
- ld r23,EX_SRR1(r21)
- std r22,_NIP(r1)
- std r23,_MSR(r1)
- addi r21,r21,-EXC_FRAME_SIZE
- std r21,PACAEXCSP(r20)
- mflr r22
- std r22,_LINK(r1)
- mfctr r23
- std r23,_CTR(r1)
- mfspr r22,XER
- std r22,_XER(r1)
+ addi r1,r13,8192-64-INT_FRAME_SIZE
+ std r9,_CCR(r1)
+ std r10,GPR1(r1)
+ std r11,_NIP(r1)
+ std r12,_MSR(r1)
+ mfspr r11,DAR
+ mfspr r12,DSISR
+ std r11,_DAR(r1)
+ std r12,_DSISR(r1)
+ mflr r10
+ mfctr r11
+ mfxer r12
+ std r10,_LINK(r1)
+ std r11,_CTR(r1)
+ std r12,_XER(r1)
SAVE_GPR(0, r1)
- SAVE_10GPRS(2, r1)
- SAVE_8GPRS(12, r1)
- SAVE_8GPRS(24, r1)
- addi r21,r1,INT_FRAME_SIZE
- std r21,0(r1)
- li r22,0
- std r22,0(r21)
- ld r2,PACATOC(r20)
- mr r13,r20
+ SAVE_GPR(2,r1)
+ SAVE_4GPRS(3,r1)
+ SAVE_2GPRS(7,r1)
+ SAVE_10GPRS(12,r1)
+ SAVE_10GPRS(22,r1)
+ addi r11,r1,INT_FRAME_SIZE
+ std r11,0(r1)
+ li r12,0
+ std r12,0(r11)
+ ld r2,PACATOC(r13)
1: addi r3,r1,STACK_FRAME_OVERHEAD
bl .kernel_bad_stack
b 1b
/*
- * Return from an exception which is handled without calling
- * save_remaining_regs. The caller is assumed to have done
- * EXCEPTION_PROLOG_COMMON.
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
*/
fast_exception_return:
- andi. r3,r23,MSR_RI /* check if RI is set */
+ ld r12,_MSR(r1)
+ ld r11,_NIP(r1)
+ andi. r3,r12,MSR_RI /* check if RI is set */
beq- unrecov_fer
ld r3,_CCR(r1)
ld r4,_LINK(r1)
mtcr r3
mtlr r4
mtctr r5
- mtspr XER,r6
+ mtxer r6
REST_GPR(0, r1)
REST_8GPRS(2, r1)
- REST_4GPRS(10, r1)
- mfmsr r20
- li r21, MSR_RI
- andc r20,r20,r21
- mtmsrd r20,1
+ mfmsr r10
+ clrrdi r10,r10,2 /* clear RI (LE is 0 already) */
+ mtmsrd r10,1
- mtspr SRR1,r23
- mtspr SRR0,r22
- REST_4GPRS(20, r1)
+ mtspr SRR1,r12
+ mtspr SRR0,r11
+ REST_4GPRS(10, r1)
ld r1,GPR1(r1)
rfid
unrecov_fer:
- li r6,0x4000
- li r20,0
- bl .save_remaining_regs
+ bl .save_nvgprs
1: addi r3,r1,STACK_FRAME_OVERHEAD
bl .unrecoverable_exception
b 1b
/*
- * Here r20 points to the PACA, r21 to the exception frame,
- * r23 contains the saved CR.
- * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * Here r13 points to the paca, r9 contains the saved CR,
+ * SRR0 and SRR1 are saved in r11 and r12,
+ * r9 - r13 are saved in paca->exgen.
*/
+ .align 7
.globl DataAccess_common
DataAccess_common:
-BEGIN_FTR_SECTION
- mfspr r22,DAR
- srdi r22,r22,60
- cmpi 0,r22,0xc
-
- /* Segment fault on a bolted segment. Go off and map that segment. */
- beq- .do_stab_bolted
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-stab_bolted_user_return:
- EXCEPTION_PROLOG_COMMON
- ld r3,_DSISR(r1)
- andis. r0,r3,0xa450 /* weird error? */
- bne 1f /* if not, try to put a PTE */
- andis. r0,r3,0x0020 /* Is it a page table fault? */
- rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
- ld r3,_DAR(r1) /* into the hash table */
-
-BEGIN_FTR_SECTION
- beq+ 2f /* If so handle it */
- li r4,0x300 /* Trap number */
- bl .do_stab_SI
- b 1f
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-2: li r5,0x300
- bl .do_hash_page_DSI /* Try to handle as hpte fault */
-1:
- ld r4,_DAR(r1)
- ld r5,_DSISR(r1)
- addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- li r6,0x300
- bl .save_remaining_regs
- bl .do_page_fault
- b .ret_from_except
-
+ mfspr r10,DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ mfspr r10,DSISR
+ stw r10,PACA_EXGEN+EX_DSISR(r13)
+ EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ lwz r4,PACA_EXGEN+EX_DSISR(r13)
+ li r5,0x300
+ b .do_hash_page /* Try to handle as hpte fault */
+
+ .align 7
.globl DataAccessSLB_common
DataAccessSLB_common:
- mfspr r22,DAR
- srdi r22,r22,60
- cmpi 0,r22,0xc
-
- /* Segment fault on a bolted segment. Go off and map that segment. */
- beq .do_slb_bolted
-
- EXCEPTION_PROLOG_COMMON
- ld r3,_DAR(r1)
- li r4,0x380 /* Exception vector */
+ mfspr r10,DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ std r3,_DAR(r1)
bl .slb_allocate
- or. r3,r3,r3 /* Check return code */
+ cmpdi r3,0 /* Check return code */
beq fast_exception_return /* Return if we succeeded */
- addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- ld r4,_DAR(r1)
- li r6,0x380
li r5,0
- bl .save_remaining_regs
- bl .do_page_fault
- b .ret_from_except
+ std r5,_DSISR(r1)
+ b .handle_page_fault
+ .align 7
.globl InstructionAccess_common
InstructionAccess_common:
- EXCEPTION_PROLOG_COMMON
-
-BEGIN_FTR_SECTION
- andis. r0,r23,0x0020 /* no ste found? */
- beq+ 2f
- mr r3,r22 /* SRR0 at interrupt */
- li r4,0x400 /* Trap number */
- bl .do_stab_SI
- b 1f
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-2: mr r3,r22
+ EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+ ld r3,_NIP(r1)
+ andis. r4,r12,0x5820
li r5,0x400
- bl .do_hash_page_ISI /* Try to handle as hpte fault */
-1:
- mr r4,r22
- rlwinm r5,r23,0,4,4 /* We only care about PR in error_code */
- addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- li r6,0x400
- bl .save_remaining_regs
- bl .do_page_fault
- b .ret_from_except
+ b .do_hash_page /* Try to handle as hpte fault */
+ .align 7
.globl InstructionAccessSLB_common
InstructionAccessSLB_common:
- EXCEPTION_PROLOG_COMMON
- mr r3,r22 /* SRR0 = NIA */
- li r4,0x480 /* Exception vector */
+ EXCEPTION_PROLOG_COMMON(0x480, PACA_EXGEN)
+ ld r3,_NIP(r1) /* SRR0 = NIA */
bl .slb_allocate
or. r3,r3,r3 /* Check return code */
beq+ fast_exception_return /* Return if we succeeded */
- addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- mr r4,r22 /* SRR0 = NIA */
- li r6,0x480
+ ld r4,_NIP(r1)
li r5,0
- bl .save_remaining_regs
- bl .do_page_fault
- b .ret_from_except
+ std r4,_DAR(r1)
+ std r5,_DSISR(r1)
+ b .handle_page_fault
+ .align 7
.globl HardwareInterrupt_common
+ .globl HardwareInterrupt_entry
HardwareInterrupt_common:
- EXCEPTION_PROLOG_COMMON
+ EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
HardwareInterrupt_entry:
+ DISABLE_INTS
addi r3,r1,STACK_FRAME_OVERHEAD
- li r20,0
- li r6,0x500
- bl .save_remaining_regs
bl .do_IRQ
- b .ret_from_except
+ b .ret_from_except_lite
+ .align 7
.globl Alignment_common
Alignment_common:
- EXCEPTION_PROLOG_COMMON
+ mfspr r10,DAR
+ std r10,PACA_EXGEN+EX_DAR(r13)
+ mfspr r10,DSISR
+ stw r10,PACA_EXGEN+EX_DSISR(r13)
+ EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+ ld r3,PACA_EXGEN+EX_DAR(r13)
+ lwz r4,PACA_EXGEN+EX_DSISR(r13)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+ bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- li r6,0x600
- bl .save_remaining_regs
+ ENABLE_INTS
bl .AlignmentException
b .ret_from_except
+ .align 7
.globl ProgramCheck_common
ProgramCheck_common:
- EXCEPTION_PROLOG_COMMON
+ EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+ bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- li r6,0x700
- bl .save_remaining_regs
+ ENABLE_INTS
bl .ProgramCheckException
b .ret_from_except
+ .align 7
.globl FPUnavailable_common
FPUnavailable_common:
- EXCEPTION_PROLOG_COMMON
+ EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
bne .load_up_fpu /* if from user, just load it up */
+ bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- li r6,0x800
- bl .save_remaining_regs
+ ENABLE_INTS
bl .KernelFPUnavailableException
BUG_OPCODE
+ .align 7
.globl AltivecUnavailable_common
AltivecUnavailable_common:
- EXCEPTION_PROLOG_COMMON
+ EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
#ifdef CONFIG_ALTIVEC
- bne .load_up_altivec /* if from user, just load it up */
+ bne .load_up_altivec /* if from user, just load it up */
#endif
+ bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
- DO_COPY_EE()
- li r6,0xf20
- bl .save_remaining_regs
-#ifdef CONFIG_ALTIVEC
- bl .KernelAltivecUnavailableException
-#else
- bl .UnknownException
-#endif
- BUG_OPCODE
+ ENABLE_INTS
+ bl .AltivecUnavailableException
+ b .ret_from_except
- .globl SystemCall_common
-SystemCall_common:
- EXCEPTION_PROLOG_COMMON
-#ifdef CONFIG_PPC_ISERIES
- cmpi 0,r0,0x5555 /* Special syscall to handle pending */
- bne+ 1f /* interrupts */
- andi. r6,r23,MSR_PR /* Only allowed from kernel */
- beq+ HardwareInterrupt_entry
-1:
-#endif
- DO_COPY_EE()
- li r6,0xC00
- bl .save_remaining_regs
- bl .DoSyscall
- b .ret_from_except
+/*
+ * Hash table stuff
+ */
+ .align 7
+_GLOBAL(do_hash_page)
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+
+ andis. r0,r4,0xa450 /* weird error? */
+ bne- .handle_page_fault /* if not, try to insert a HPTE */
+BEGIN_FTR_SECTION
+ andis. r0,r4,0x0020 /* Is it a segment table fault? */
+ bne- .do_ste_alloc /* If so handle it */
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-_GLOBAL(do_hash_page_ISI)
- li r4,0
-_GLOBAL(do_hash_page_DSI)
/*
* We need to set the _PAGE_USER bit if MSR_PR is set or if we are
* accessing a userspace segment (even from the kernel). We assume
* kernel addresses always have the high bit set.
*/
- rotldi r0,r3,15 /* Move high bit into MSR_PR position */
- orc r0,r23,r0
- rlwimi r4,r0,32-13,30,30 /* Insert into _PAGE_USER */
+ rlwinm r4,r4,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
+ rotldi r0,r3,15 /* Move high bit into MSR_PR posn */
+ orc r0,r12,r0 /* MSR_PR | ~high_bit */
+ rlwimi r4,r0,32-13,30,30 /* becomes _PAGE_USER access bit */
ori r4,r4,1 /* add _PAGE_PRESENT */
- mflr r21 /* Save LR in r21 */
-
-#ifdef DO_SOFT_DISABLE
/*
- * We hard enable here (but first soft disable) so that the hash_page
- * code can spin on the hash_table_lock with problem on a shared
- * processor.
+ * On iSeries, we soft-disable interrupts here, then
+ * hard-enable interrupts so that the hash_page code can spin on
+ * the hash_table_lock without problems on a shared processor.
*/
- li r0,0
- stb r0,PACAPROCENABLED(r20) /* Soft Disabled */
-
- mfmsr r0
- ori r0,r0,MSR_EE+MSR_RI
- mtmsrd r0 /* Hard Enable, RI on */
-#endif
+ DISABLE_INTS
/*
* r3 contains the faulting address
*
* at return r3 = 0 for success
*/
-
bl .hash_page /* build HPTE if possible */
+ cmpdi r3,0 /* see if hash_page succeeded */
#ifdef DO_SOFT_DISABLE
/*
- * Now go back to hard disabled.
+ * If we had interrupts soft-enabled at the point where the
+ * DSI/ISI occurred, and an interrupt came in during hash_page,
+ * handle it now.
+ * We jump to ret_from_except_lite rather than fast_exception_return
+ * because ret_from_except_lite will check for and handle pending
+ * interrupts if necessary.
*/
- mfmsr r0
- li r4,0
- ori r4,r4,MSR_EE+MSR_RI
- andc r0,r0,r4
- mtmsrd r0 /* Hard Disable, RI off */
-
- ld r0,SOFTE(r1)
- cmpdi 0,r0,0 /* See if we will soft enable in */
- /* save_remaining_regs */
- beq 5f
- CHECKANYINT(r4,r5)
- bne- HardwareInterrupt_entry /* Convert this DSI into an External */
- /* to process interrupts which occurred */
- /* during hash_page */
-5:
- stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable status */
+ beq .ret_from_except_lite
+ /*
+ * hash_page couldn't handle it, set soft interrupt enable back
+ * to what it was before the trap. Note that .local_irq_restore
+ * handles any interrupts pending at this point.
+ */
+ ld r3,SOFTE(r1)
+ bl .local_irq_restore
+ b 11f
+#else
+ beq+ fast_exception_return /* Return from exception on success */
+ /* fall through */
#endif
- or. r3,r3,r3 /* Check return code */
- beq fast_exception_return /* Return from exception on success */
- mtlr r21 /* restore LR */
- blr /* Return to DSI or ISI on failure */
+/* Here we have a page fault that hash_page can't handle. */
+_GLOBAL(handle_page_fault)
+ ENABLE_INTS
+11: ld r4,_DAR(r1)
+ ld r5,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .do_page_fault
+ cmpdi r3,0
+ beq+ .ret_from_except_lite
+ bl .save_nvgprs
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+ bl .bad_page_fault
+ b .ret_from_except
+
+ /* here we have a segment miss */
+_GLOBAL(do_ste_alloc)
+ bl .ste_allocate /* try to insert stab entry */
+ cmpdi r3,0
+ beq+ fast_exception_return
+ b .handle_page_fault
/*
- * r20 points to the PACA, r21 to the exception frame,
- * r23 contains the saved CR.
- * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
* We assume we aren't going to take any exceptions during this procedure.
+ * We assume (DAR >> 60) == 0xc.
*/
+ .align 7
_GLOBAL(do_stab_bolted)
- stw r23,EX_CCR(r21) /* save CR in exc. frame */
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
- mfspr r22,DSISR
- andis. r22,r22,0x0020
- beq- stab_bolted_user_return
+ /* Hash to the primary group */
+ ld r10,PACASTABVIRT(r13)
+ mfspr r11,DAR
+ srdi r11,r11,28
+ rldimi r10,r11,7,52 /* r10 = first ste of the group */
+ /* Calculate VSID */
/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
- mfspr r21,DAR
- rldicl r20,r21,36,51
- sldi r20,r20,15
- srdi r21,r21,60
- or r20,r20,r21
+ rldic r11,r11,15,36
+ ori r11,r11,0xc
/* VSID_RANDOMIZER */
- li r21,9
- sldi r21,r21,32
- oris r21,r21,58231
- ori r21,r21,39831
-
- mulld r20,r20,r21
- clrldi r20,r20,28 /* r20 = vsid */
+ li r9,9
+ sldi r9,r9,32
+ oris r9,r9,58231
+ ori r9,r9,39831
- mfsprg r21,3
- ld r21,PACASTABVIRT(r21)
-
- /* Hash to the primary group */
- mfspr r22,DAR
- rldicl r22,r22,36,59
- rldicr r22,r22,7,56
- or r21,r21,r22 /* r21 = first ste of the group */
+ mulld r9,r11,r9
+ rldic r9,r9,12,16 /* r9 = vsid << 12 */
/* Search the primary group for a free entry */
- li r22,0
-1:
- ld r23,0(r21) /* Test valid bit of the current ste */
- rldicl r23,r23,57,63
- cmpwi r23,0
- bne 2f
- li r23,0
- rldimi r23,r20,12,0 /* Insert the new vsid value */
- std r23,8(r21) /* Put new entry back into the stab */
- eieio /* Order vsid update */
- li r23,0
- mfspr r20,DAR /* Get the new esid */
- rldicl r20,r20,36,28 /* Permits a full 36b of ESID */
- rldimi r23,r20,28,0 /* Insert the new esid value */
- ori r23,r23,144 /* Turn on valid and kp */
- std r23,0(r21) /* Put new entry back into the stab */
- sync /* Order the update */
- b 3f
-2:
- addi r22,r22,1
- addi r21,r21,16
- cmpldi r22,7
- ble 1b
+1: ld r11,0(r10) /* Test valid bit of the current ste */
+ andi. r11,r11,0x80
+ beq 2f
+ addi r10,r10,16
+ andi. r11,r10,0x70
+ bne 1b
/* Stick for only searching the primary group for now. */
/* At least for now, we use a very simple random castout scheme */
/* Use the TB as a random number ; OR in 1 to avoid entry 0 */
- mftb r22
- andi. r22,r22,7
- ori r22,r22,1
- sldi r22,r22,4
+ mftb r11
+ rldic r11,r11,4,57 /* r11 = (r11 << 4) & 0x70 */
+ ori r11,r11,0x10
- /* r21 currently points to and ste one past the group of interest */
+ /* r10 currently points to an ste one past the group of interest */
/* make it point to the randomly selected entry */
- subi r21,r21,128
- or r21,r21,r22 /* r21 is the entry to invalidate */
+ subi r10,r10,128
+ or r10,r10,r11 /* r10 is the entry to invalidate */
isync /* mark the entry invalid */
- ld r23,0(r21)
- li r22,-129
- and r23,r23,r22
- std r23,0(r21)
+ ld r11,0(r10)
+ rldicl r11,r11,56,1 /* clear the valid bit */
+ rotldi r11,r11,8
+ std r11,0(r10)
sync
- li r23,0
- rldimi r23,r20,12,0
- std r23,8(r21)
+ clrrdi r11,r11,28 /* Get the esid part of the ste */
+ slbie r11
+
+2: std r9,8(r10) /* Store the vsid part of the ste */
eieio
- ld r22,0(r21) /* Get the esid part of the ste */
- li r23,0
- mfspr r20,DAR /* Get the new esid */
- rldicl r20,r20,36,28 /* Permits a full 32b of ESID */
- rldimi r23,r20,28,0 /* Insert the new esid value */
- ori r23,r23,144 /* Turn on valid and kp */
- std r23,0(r21) /* Put new entry back into the stab */
-
- rldicl r22,r22,36,28
- rldicr r22,r22,28,35
- slbie r22
+ mfspr r11,DAR /* Get the new esid */
+ clrrdi r11,r11,28 /* Permits a full 32b of ESID */
+ ori r11,r11,0x90 /* Turn on valid and kp */
+ std r11,0(r10) /* Put new entry back into the stab */
+
sync
-3:
/* All done -- return from exception. */
- mfsprg r20,3 /* Load the PACA pointer */
- ld r21,PACAEXCSP(r20) /* Get the exception frame pointer */
- addi r21,r21,EXC_FRAME_SIZE
- lwz r23,EX_CCR(r21) /* get saved CR */
-
- ld r22,EX_SRR1(r21)
- andi. r22,r22,MSR_RI
- beq- unrecov_stab
-
- /* note that this is almost identical to maskable_exception_exit */
- mtcr r23 /* restore CR */
-
- mfmsr r22
- li r23, MSR_RI
- andc r22,r22,r23
- mtmsrd r22,1
-
- ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */
- ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */
- mtspr SRR0,r22
- mtspr SRR1,r23
- ld r22,EX_R22(r21) /* restore r22 and r23 */
- ld r23,EX_R23(r21)
- mfspr r20,SPRG2
- mfspr r21,SPRG1
- rfid
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+ ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
-unrecov_stab:
- EXCEPTION_PROLOG_COMMON
- li r6,0x4100
- li r20,0
- bl .save_remaining_regs
-1: addi r3,r1,STACK_FRAME_OVERHEAD
- bl .unrecoverable_exception
- b 1b
+ andi. r10,r12,MSR_RI
+ beq- unrecov_slb
+
+ mtcrf 0x80,r9 /* restore CR */
+
+ mfmsr r10
+ clrrdi r10,r10,2
+ mtmsrd r10,1
+
+ mtspr SRR0,r11
+ mtspr SRR1,r12
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
+ rfid
/*
- * r20 points to the PACA, r21 to the exception frame,
- * r23 contains the saved CR.
- * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
* We assume we aren't going to take any exceptions during this procedure.
*/
/* XXX note fix masking in get_kernel_vsid to match */
_GLOBAL(do_slb_bolted)
- stw r23,EX_CCR(r21) /* save CR in exc. frame */
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
/*
* We take the next entry, round robin. Previously we tried
* we dont have any LRU information to help us choose a slot.
*/
- /* r20 = paca */
-1: ld r22,PACASTABRR(r20)
- addi r21,r22,1
- cmpdi r21,SLB_NUM_ENTRIES
+ /* r13 = paca */
+1: ld r10,PACASTABRR(r13)
+ addi r9,r10,1
+ cmpdi r9,SLB_NUM_ENTRIES
blt+ 2f
- li r21,2 /* dont touch slot 0 or 1 */
-2: std r21,PACASTABRR(r20)
+ li r9,2 /* dont touch slot 0 or 1 */
+2: std r9,PACASTABRR(r13)
- /* r20 = paca, r22 = entry */
+ /* r13 = paca, r10 = entry */
/*
* Never cast out the segment for our kernel stack. Since we
* which gets invalidated due to a tlbie from another cpu at a
* non recoverable point (after setting srr0/1) - Anton
*/
- slbmfee r21,r22
- srdi r21,r21,27
+ slbmfee r9,r10
+ srdi r9,r9,27
/*
* Use paca->ksave as the value of the kernel stack pointer,
* because this is valid at all times.
* switch (between updating r1 and updating paca->ksave),
* we check against both r1 and paca->ksave.
*/
- srdi r23,r1,27
- ori r23,r23,1
- cmpd r23,r21
+ srdi r11,r1,27
+ ori r11,r11,1
+ cmpd r11,r9
beq- 1b
- ld r23,PACAKSAVE(r20)
- srdi r23,r23,27
- ori r23,r23,1
- cmpd r23,r21
+ ld r11,PACAKSAVE(r13)
+ srdi r11,r11,27
+ ori r11,r11,1
+ cmpd r11,r9
beq- 1b
- /* r20 = paca, r22 = entry */
+ /* r13 = paca, r10 = entry */
/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
- mfspr r21,DAR
- rldicl r23,r21,36,51
- sldi r23,r23,15
- srdi r21,r21,60
- or r23,r23,r21
+ mfspr r9,DAR
+ rldicl r11,r9,36,51
+ sldi r11,r11,15
+ srdi r9,r9,60
+ or r11,r11,r9
/* VSID_RANDOMIZER */
- li r21,9
- sldi r21,r21,32
- oris r21,r21,58231
- ori r21,r21,39831
+ li r9,9
+ sldi r9,r9,32
+ oris r9,r9,58231
+ ori r9,r9,39831
/* vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK */
- mulld r23,r23,r21
- clrldi r23,r23,28
+ mulld r11,r11,r9
+ clrldi r11,r11,28
- /* r20 = paca, r22 = entry, r23 = vsid */
+ /* r13 = paca, r10 = entry, r11 = vsid */
/* Put together slb word1 */
- sldi r23,r23,12
+ sldi r11,r11,12
BEGIN_FTR_SECTION
/* set kp and c bits */
- ori r23,r23,0x480
+ ori r11,r11,0x480
END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
BEGIN_FTR_SECTION
/* set kp, l and c bits */
- ori r23,r23,0x580
+ ori r11,r11,0x580
END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
- /* r20 = paca, r22 = entry, r23 = slb word1 */
+ /* r13 = paca, r10 = entry, r11 = slb word1 */
/* Put together slb word0 */
- mfspr r21,DAR
- rldicr r21,r21,0,35 /* get the new esid */
- oris r21,r21,2048 /* set valid bit */
- rldimi r21,r22,0,52 /* insert entry */
+ mfspr r9,DAR
+ clrrdi r9,r9,28 /* get the new esid */
+ oris r9,r9,0x800 /* set valid bit */
+ rldimi r9,r10,0,52 /* insert entry */
- /* r20 = paca, r21 = slb word0, r23 = slb word1 */
+ /* r13 = paca, r9 = slb word0, r11 = slb word1 */
/*
* No need for an isync before or after this slbmte. The exception
* we enter with and the rfid we exit with are context synchronizing .
*/
- slbmte r23,r21
+ slbmte r11,r9
/* All done -- return from exception. */
- ld r21,PACAEXCSP(r20) /* Get the exception frame pointer */
- addi r21,r21,EXC_FRAME_SIZE
- lwz r23,EX_CCR(r21) /* get saved CR */
- /* note that this is almost identical to maskable_exception_exit */
+ lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
+ ld r11,PACA_EXSLB+EX_SRR0(r13) /* get saved SRR0 */
- ld r22,EX_SRR1(r21)
- andi. r22,r22,MSR_RI
- beq- unrecov_stab
+ andi. r10,r12,MSR_RI /* check for unrecoverable exception */
+ beq- unrecov_slb
/*
* Until everyone updates binutils hardwire the POWER4 optimised
#if 0
.machine push
.machine "power4"
- mtcrf 0x80,r23
+ mtcrf 0x80,r9
.machine pop
#else
- .long 0x7ef80120
+ .long 0x7d380120
#endif
- mfmsr r22
- li r23, MSR_RI
- andc r22,r22,r23
- mtmsrd r22,1
-
- ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */
- ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */
- mtspr SRR0,r22
- mtspr SRR1,r23
- ld r22,EX_R22(r21) /* restore r22 and r23 */
- ld r23,EX_R23(r21)
- ld r20,EX_R20(r21)
- mfspr r21,SPRG1
+ mfmsr r10
+ clrrdi r10,r10,2
+ mtmsrd r10,1
+
+ mtspr SRR0,r11
+ mtspr SRR1,r12
+ ld r9,PACA_EXSLB+EX_R9(r13)
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ ld r11,PACA_EXSLB+EX_R11(r13)
+ ld r12,PACA_EXSLB+EX_R12(r13)
+ ld r13,PACA_EXSLB+EX_R13(r13)
rfid
-_GLOBAL(do_stab_SI)
- mflr r21 /* Save LR in r21 */
-
- /*
- * r3 contains the faulting address
- * r4 contains the required access permissions
- *
- * at return r3 = 0 for success
- */
-
- bl .ste_allocate /* build STE if possible */
- or. r3,r3,r3 /* Check return code */
- beq fast_exception_return /* Return from exception on success */
- mtlr r21 /* restore LR */
- blr /* Return to DSI or ISI on failure */
-
-/*
- * This code finishes saving the registers to the exception frame.
- * Address translation is already on.
- */
-_GLOBAL(save_remaining_regs)
- /*
- * Save the rest of the registers into the pt_regs structure
- */
- std r22,_NIP(r1)
- std r23,_MSR(r1)
- std r6,TRAP(r1)
- ld r6,GPR6(r1)
- SAVE_2GPRS(14, r1)
- SAVE_4GPRS(16, r1)
- SAVE_8GPRS(24, r1)
-
- /* Set the marker value "regshere" just before the reg values */
- SET_REG_TO_CONST(r22, 0x7265677368657265)
- std r22,STACK_FRAME_OVERHEAD-16(r1)
-
- /*
- * Clear the RESULT field
- */
- li r22,0
- std r22,RESULT(r1)
-
- /*
- * Test if from user state; result will be tested later
- */
- andi. r23,r23,MSR_PR /* Set CR for later branch */
-
- /*
- * Indicate that r1 contains the kernel stack and
- * get the Kernel TOC pointer from the paca
- */
- ld r2,PACATOC(r13) /* Get Kernel TOC pointer */
-
- /*
- * If from user state, update THREAD.regs
- */
- beq 2f /* Modify THREAD.regs if from user */
- addi r23,r1,STACK_FRAME_OVERHEAD
- ld r22, PACACURRENT(r13)
- std r23,THREAD+PT_REGS(r22)
-2:
- SET_REG_TO_CONST(r22, MSR_KERNEL)
-
-#ifdef DO_SOFT_DISABLE
- stb r20,PACAPROCENABLED(r13) /* possibly soft enable */
- ori r22,r22,MSR_EE /* always hard enable */
-#else
- rldimi r22,r20,15,48 /* Insert desired EE value */
-#endif
-
- mtmsrd r22,1
- blr
-
-/*
- * Kernel profiling with soft disable on iSeries
- */
-do_profile:
- ld r22,8(r21) /* Get SRR1 */
- andi. r22,r22,MSR_PR /* Test if in kernel */
- bnelr /* return if not in kernel */
- ld r22,0(r21) /* Get SRR0 */
- ld r25,PACAPROFSTEXT(r20) /* _stext */
- subf r22,r25,r22 /* offset into kernel */
- lwz r25,PACAPROFSHIFT(r20)
- srd r22,r22,r25
- lwz r25,PACAPROFLEN(r20) /* length of profile table (-1) */
- cmp 0,r22,r25 /* off end? */
- ble 1f
- mr r22,r25 /* force into last entry */
-1: sldi r22,r22,2 /* convert to offset into buffer */
- ld r25,PACAPROFBUFFER(r20) /* profile buffer */
- add r25,r25,r22
-2: lwarx r22,0,r25 /* atomically increment */
- addi r22,r22,1
- stwcx. r22,0,r25
- bne- 2b
- blr
+unrecov_slb:
+ EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+ DISABLE_INTS
+ bl .save_nvgprs
+1: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl .unrecoverable_exception
+ b 1b
/*
addi r1,r1,0x1000
subi r1,r1,STACK_FRAME_OVERHEAD
- cmpi 0,r23,0
+ cmpwi 0,r23,0
#ifdef CONFIG_SMP
#ifdef SECONDARY_PROCESSORS
bne .__secondary_start
*
*/
#ifndef CONFIG_SMP
- LOADBASE(r3,last_task_used_math)
- ld r4,last_task_used_math@l(r3)
- cmpi 0,r4,0
+ ld r3,last_task_used_math@got(r2)
+ ld r4,0(r3)
+ cmpdi 0,r4,0
beq 1f
/* Save FP state to last_task_used_math's THREAD struct */
addi r4,r4,THREAD
/* Disable FP for last_task_used_math */
ld r5,PT_REGS(r4)
ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r20,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r20
+ li r6,MSR_FP|MSR_FE0|MSR_FE1
+ andc r4,r4,r6
std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#endif /* CONFIG_SMP */
ld r4,PACACURRENT(r13)
addi r5,r4,THREAD /* Get THREAD */
ld r4,THREAD_FPEXC_MODE(r5)
- ori r23,r23,MSR_FP
- or r23,r23,r4
+ ori r12,r12,MSR_FP
+ or r12,r12,r4
+ std r12,_MSR(r1)
lfd fr0,THREAD_FPSCR(r5)
mtfsf 0xff,fr0
REST_32FPRS(0, r5)
#ifndef CONFIG_SMP
/* Update last_task_used_math to 'current' */
subi r4,r5,THREAD /* Back to 'current' */
- std r4,last_task_used_math@l(r3)
+ std r4,0(r3)
#endif /* CONFIG_SMP */
/* restore registers and return */
b fast_exception_return
ori r5,r5,MSR_FP
mtmsrd r5 /* enable use of fpu now */
isync
- cmpi 0,r3,0
+ cmpdi 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
ld r5,PT_REGS(r3)
- cmpi 0,r5,0
+ cmpdi 0,r5,0
SAVE_32FPRS(0, r3)
mffs fr0
stfd fr0,THREAD_FPSCR(r3)
1:
#ifndef CONFIG_SMP
li r5,0
- LOADBASE(r4,last_task_used_math)
- std r5,last_task_used_math@l(r4)
+ ld r4,last_task_used_math@got(r2)
+ std r5,0(r4)
#endif /* CONFIG_SMP */
blr
* avoid saving all of the VREGs here...
*/
#ifndef CONFIG_SMP
- LOADBASE(r3,last_task_used_altivec)
- ld r4,last_task_used_altivec@l(r3)
- cmpi 0,r4,0
+ ld r3,last_task_used_altivec@got(r2)
+ ld r4,0(r3)
+ cmpdi 0,r4,0
beq 1f
/* Save VMX state to last_task_used_altivec's THREAD struct */
addi r4,r4,THREAD
/* Disable VMX for last_task_used_altivec */
ld r5,PT_REGS(r4)
ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r20,MSR_VEC@h
- andc r4,r4,r20
+ lis r6,MSR_VEC@h
+ andc r4,r4,r6
std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1:
#endif /* CONFIG_SMP */
* all 1's
*/
mfspr r4,SPRN_VRSAVE
- cmpi 0,r4,0
+ cmpdi 0,r4,0
bne+ 1f
li r4,-1
mtspr SPRN_VRSAVE,r4
/* enable use of VMX after return */
ld r4,PACACURRENT(r13)
addi r5,r4,THREAD /* Get THREAD */
- oris r23,r23,MSR_VEC@h
+ oris r12,r12,MSR_VEC@h
+ std r12,_MSR(r1)
li r4,1
li r10,THREAD_VSCR
stw r4,THREAD_USED_VR(r5)
#ifndef CONFIG_SMP
/* Update last_task_used_math to 'current' */
subi r4,r5,THREAD /* Back to 'current' */
- std r4,last_task_used_altivec@l(r3)
+ std r4,0(r3)
#endif /* CONFIG_SMP */
/* restore registers and return */
b fast_exception_return
oris r5,r5,MSR_VEC@h
mtmsrd r5 /* enable use of VMX now */
isync
- cmpi 0,r3,0
+ cmpdi 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
ld r5,PT_REGS(r3)
- cmpi 0,r5,0
+ cmpdi 0,r5,0
SAVE_32VRS(0,r4,r3)
mfvscr vr0
li r4,THREAD_VSCR
1:
#ifndef CONFIG_SMP
li r5,0
- LOADBASE(r4,last_task_used_altivec)
- std r5,last_task_used_altivec@l(r4)
+ ld r4,last_task_used_altivec@got(r2)
+ std r5,0(r4)
#endif /* CONFIG_SMP */
blr
LOADADDR(r3,current_set)
sldi r28,r24,3 /* get current_set[cpu#] */
ldx r1,r3,r28
- addi r1,r1,THREAD_SIZE
- subi r1,r1,STACK_FRAME_OVERHEAD
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ li r0,0
+ std r0,0(r1)
std r1,PACAKSAVE(r13)
ld r3,PACASTABREAL(r13) /* get raddr of segment table */
#endif
/*
- * This subroutine clobbers r11, r12 and the LR
+ * This subroutine clobbers r11 and r12
*/
_GLOBAL(enable_64b_mode)
mfmsr r11 /* grab the current MSR */
std r4,PACACURRENT(r13)
std r2,PACATOC(r13)
- li r5,0
std r1,PACAKSAVE(r13)
/* Restore the parms passed in from the bootloader. */
HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
HvLpDma_Direction_RemoteToLocal);
- p = q = cmd_line + 255;
- while (p > cmd_line) {
- if ((*p == 0) || (*p == ' ') || (*p == '\n'))
- --p;
- else
+ p = cmd_line;
+ q = cmd_line + 255;
+ while( p < q ) {
+ if (!*p || *p == '\n')
break;
+ ++p;
}
- if (p < q)
- *(p + 1) = 0;
+ *p = 0;
if (strstr(cmd_line, "dprofile=")) {
for (q = cmd_line; (p = strstr(q, "dprofile=")) != 0; ) {
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
static struct fs_struct init_fs = INIT_FS;
{
int len = count;
char *p;
-
+
+ if (off) {
+ *eof = 1;
+ return 0;
+ }
+
len = mf_getCmdLine(page, &len, (u64)data);
- p = page + len - 1;
- while (p > page) {
- if ((*p == 0) || (*p == ' '))
- --p;
- else
+ p = page;
+ while (len < (count - 1)) {
+ if (!*p || *p == '\n')
break;
+ p++;
+ len++;
}
- if (*p != '\n') {
- ++p;
- *p = '\n';
- }
- ++p;
+ *p = '\n';
+ p++;
*p = 0;
- len = p - page;
-
- len -= off;
- if (len < count) {
- *eof = 1;
- if (len <= 0)
- return 0;
- } else
- len = count;
- *start = page + off;
- return len;
+
+ return p - page;
}
#if 0
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
- cmpi 0,r3,0
+ cmpdi 0,r3,0
stb r3,PACAPROCENABLED(r13)
beqlr
/* Check pending interrupts */
/* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables) */
- CHECKANYINT(r4,r5)
+ ld r4,PACALPPACA+LPPACAANYINT(r13)
+ cmpdi r4,0
beqlr
- /*
+ /*
* Handle pending interrupts in interrupt context
*/
li r0,0x5555
_GLOBAL(sys_call_table32)
.llong .sys_restart_syscall /* 0 */
.llong .sys_exit
- .llong .sys_fork
+ .llong .ppc_fork
.llong .sys_read
.llong .sys_write
.llong .sys32_open /* 5 */
.llong .sys32_ssetmask
.llong .sys_setreuid /* 70 */
.llong .sys_setregid
- .llong .sys32_sigsuspend
+ .llong .ppc32_sigsuspend
.llong .compat_sys_sigpending
.llong .sys32_sethostname
.llong .compat_sys_setrlimit /* 75 */
.llong .sys32_ipc
.llong .sys_fsync
.llong .ppc32_sigreturn
- .llong .sys_clone /* 120 */
+ .llong .ppc_clone /* 120 */
.llong .sys32_setdomainname
.llong .ppc64_newuname
.llong .sys_ni_syscall /* old modify_ldt syscall */
.llong .sys32_rt_sigpending /* 175 */
.llong .sys32_rt_sigtimedwait
.llong .sys32_rt_sigqueueinfo
- .llong .sys32_rt_sigsuspend
+ .llong .ppc32_rt_sigsuspend
.llong .sys32_pread64
.llong .sys32_pwrite64 /* 180 */
.llong .sys_chown
.llong .sys32_sendfile
.llong .sys_ni_syscall /* reserved for streams1 */
.llong .sys_ni_syscall /* reserved for streams2 */
- .llong .sys_vfork
+ .llong .ppc_vfork
.llong .compat_sys_getrlimit /* 190 */
.llong .sys32_readahead
.llong .sys32_mmap2
_GLOBAL(sys_call_table)
.llong .sys_restart_syscall /* 0 */
.llong .sys_exit
- .llong .sys_fork
+ .llong .ppc_fork
.llong .sys_read
.llong .sys_write
.llong .sys_open /* 5 */
.llong .sys_ipc
.llong .sys_fsync
.llong .sys_ni_syscall
- .llong .sys_clone /* 120 */
+ .llong .ppc_clone /* 120 */
.llong .sys_setdomainname
.llong .ppc64_newuname
.llong .sys_ni_syscall /* old modify_ldt syscall */
.llong .sys_rt_sigpending /* 175 */
.llong .sys_rt_sigtimedwait
.llong .sys_rt_sigqueueinfo
- .llong .sys_rt_sigsuspend
+ .llong .ppc64_rt_sigsuspend
.llong .sys_pread64
.llong .sys_pwrite64 /* 180 */
.llong .sys_chown
.llong .sys_sendfile64
.llong .sys_ni_syscall /* reserved for streams1 */
.llong .sys_ni_syscall /* reserved for streams2 */
- .llong .sys_vfork
+ .llong .ppc_vfork
.llong .sys_getrlimit /* 190 */
.llong .sys_readahead
.llong .sys_ni_syscall /* 32bit only mmap2 */
.xDesc = 0xd397d9e2, /* "LpRS" */ \
.xSize = sizeof(struct ItLpRegSave) \
}, \
- .exception_sp = \
- (&paca[number].exception_stack[0]) - EXC_FRAME_SIZE, \
}
struct paca_struct paca[] __page_aligned = {
PMAC_TYPE_POWERMAC_G5, g5_features,
0,
},
+ { "RackMac3,1", "XServe G5",
+ PMAC_TYPE_POWERMAC_G5, g5_features,
+ 0,
+ },
};
/*
.page_table_lock = SPIN_LOCK_UNLOCKED,
};
+/*
+ * Make sure the floating-point register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_fp_to_thread(struct task_struct *tsk)
+{
+ if (tsk->thread.regs) {
+ /*
+ * We need to disable preemption here because if we didn't,
+ * another process could get scheduled after the regs->msr
+ * test but before we have finished saving the FP registers
+ * to the thread_struct. That process could take over the
+ * FPU, and then when we get scheduled again we would store
+ * bogus values for the remaining FP registers.
+ */
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_FP) {
+#ifdef CONFIG_SMP
+ /*
+ * This should only ever be called for current or
+ * for a stopped child process. Since we save away
+ * the FP register state on context switch on SMP,
+ * there is something wrong if a stopped child appears
+ * to still have its FP state in the CPU registers.
+ */
+ BUG_ON(tsk != current);
+#endif
+ giveup_fpu(current);
+ }
+ preempt_enable();
+ }
+}
+
void enable_kernel_fp(void)
{
+ WARN_ON(preemptible());
+
#ifdef CONFIG_SMP
if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
giveup_fpu(current);
int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
{
- struct pt_regs *regs = tsk->thread.regs;
-
- if (!regs)
+ if (!tsk->thread.regs)
return 0;
- if (tsk == current && (regs->msr & MSR_FP))
- giveup_fpu(current);
+ flush_fp_to_thread(current);
memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
void enable_kernel_altivec(void)
{
+ WARN_ON(preemptible());
+
#ifdef CONFIG_SMP
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
giveup_altivec(current);
}
EXPORT_SYMBOL(enable_kernel_altivec);
+/*
+ * Make sure the VMX/Altivec register state in the
+ * the thread_struct is up to date for task tsk.
+ */
+void flush_altivec_to_thread(struct task_struct *tsk)
+{
+#ifdef CONFIG_ALTIVEC
+ if (tsk->thread.regs) {
+ preempt_disable();
+ if (tsk->thread.regs->msr & MSR_VEC) {
+#ifdef CONFIG_SMP
+ BUG_ON(tsk != current);
+#endif
+ giveup_altivec(current);
+ }
+ preempt_enable();
+ }
+#endif
+}
+
int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
{
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
+ flush_altivec_to_thread(current);
memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs));
return 1;
}
void show_regs(struct pt_regs * regs)
{
int i;
+ unsigned long trap;
printk("NIP: %016lX XER: %016lX LR: %016lX\n",
regs->nip, regs->xer, regs->link);
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
regs->msr&MSR_IR ? 1 : 0,
regs->msr&MSR_DR ? 1 : 0);
- if (regs->trap == 0x300 || regs->trap == 0x380 || regs->trap == 0x600)
+ trap = TRAP(regs);
+ if (trap == 0x300 || trap == 0x380 || trap == 0x600)
printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
printk("TASK: %p[%d] '%s' THREAD: %p",
current, current->pid, current->comm, current->thread_info);
}
printk("%016lX ", regs->gpr[i]);
+ if (i == 13 && !FULL_REGS(regs))
+ break;
}
printk("\n");
/*
*/
void prepare_to_copy(struct task_struct *tsk)
{
- struct pt_regs *regs = tsk->thread.regs;
-
- if (regs == NULL)
- return;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
+ flush_fp_to_thread(current);
+ flush_altivec_to_thread(current);
}
/*
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
+ flush_fp_to_thread(current);
+ flush_altivec_to_thread(current);
error = do_execve(filename, (char __user * __user *) a1,
(char __user * __user *) a2, regs);
if (index < PT_FPR0) {
tmp = get_reg(child, (int)index);
} else {
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
}
ret = put_user(tmp,(unsigned long __user *) data);
if (index < PT_FPR0) {
ret = put_reg(child, index, data);
} else {
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
ret = 0;
}
unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
unsigned long __user *tmp = (unsigned long __user *)addr;
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
for (i = 0; i < 32; i++) {
ret = put_user(*reg, tmp);
unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
unsigned long __user *tmp = (unsigned long __user *)addr;
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
for (i = 0; i < 32; i++) {
ret = get_user(*reg, tmp);
if (index < PT_FPR0) {
tmp = get_reg(child, index);
} else {
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
/*
* the user space code considers the floating point
* to be an array of unsigned int (32 bits) - the
break;
if (numReg >= PT_FPR0) {
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
tmp = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
} else { /* register within PT_REGS struct */
tmp = get_reg(child, numReg);
if (index < PT_FPR0) {
ret = put_reg(child, index, data);
} else {
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
/*
* the user space code considers the floating point
* to be an array of unsigned int (32 bits) - the
|| ((numReg > PT_CCR) && (numReg < PT_FPR0)))
break;
if (numReg >= PT_FPR0) {
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
}
if (numReg == PT_MSR)
data = (data & MSR_DEBUGCHANGE)
unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
unsigned int __user *tmp = (unsigned int __user *)addr;
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
for (i = 0; i < 32; i++) {
ret = put_user(*reg, tmp);
unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
unsigned int __user *tmp = (unsigned int __user *)addr;
- if (child->thread.regs->msr & MSR_FP)
- giveup_fpu(child);
+ flush_fp_to_thread(child);
for (i = 0; i < 32; i++) {
ret = get_user(*reg, tmp);
void
call_rtas_display_status(char c)
{
- struct rtas_args *args = &(get_paca()->xRtas);
+ struct rtas_args *args;
unsigned long s;
spin_lock_irqsave(&rtas.lock, s);
+ args = &(get_paca()->xRtas);
args->token = 10;
args->nargs = 1;
va_list list;
int i, logit = 0;
unsigned long s;
- struct rtas_args *rtas_args = &(get_paca()->xRtas);
+ struct rtas_args *rtas_args;
long ret;
PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n");
/* Gotta do something different here, use global lock for now... */
spin_lock_irqsave(&rtas.lock, s);
+ rtas_args = &(get_paca()->xRtas);
rtas_args->token = token;
rtas_args->nargs = nargs;
#endif
long err = 0;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
+ flush_fp_to_thread(current);
/* Make sure signal doesn't get spurrious FP exceptions */
current->thread.fpscr = 0;
err |= __put_user(v_regs, &sc->v_regs);
/* save altivec registers */
- if (current->thread.used_vr) {
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
+ if (current->thread.used_vr) {
+ flush_altivec_to_thread(current);
/* Copy 33 vec registers (vr0..31 and vscr) to the stack */
err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128));
/* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
struct k_sigaction *ka = ¤t->sighand->action[signr-1];
/* Whee! Actually deliver the signal. */
- if (regs->trap == 0x0C00)
+ if (TRAP(regs) == 0x0C00)
syscall_restart(regs, ka);
handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
- if (regs->trap == 0x0C00) { /* System Call! */
+ if (TRAP(regs) == 0x0C00) { /* System Call! */
if ((int)regs->result == -ERESTARTNOHAND ||
(int)regs->result == -ERESTARTSYS ||
(int)regs->result == -ERESTARTNOINTR) {
{
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
int i, err = 0;
-
- /* Make sure floating point registers are stored in regs */
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-
+
+ /* Make sure floating point registers are stored in regs */
+ flush_fp_to_thread(current);
+
/* save general and floating-point registers */
for (i = 0; i <= PT_RESULT; i ++)
err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]);
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
+ flush_altivec_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
ELF_NVRREG32 * sizeof(vector128)))
return 1;
ka = (signr == 0)? NULL: ¤t->sighand->action[signr-1];
- if (regs->trap == 0x0C00 /* System Call! */
+ if (TRAP(regs) == 0x0C00 /* System Call! */
&& regs->ccr & 0x10000000 /* error signalled */
&& ((ret = regs->gpr[3]) == ERESTARTSYS
|| ret == ERESTARTNOHAND || ret == ERESTARTNOINTR
}
/* Fixup atomic count: it exited inside IRQ handler. */
- ((struct task_struct *)paca[lcpu].xCurrent)->thread_info->preempt_count
- = 0;
+ paca[lcpu].xCurrent->thread_info->preempt_count = 0;
/* Fixup SLB round-robin so next segment (kernel) goes in segment 0 */
paca[lcpu].xStab_data.next_round_robin = 0;
init_idle(p, cpu);
unhash_process(p);
- paca[cpu].xCurrent = (u64)p;
+ paca[cpu].xCurrent = p;
current_set[cpu] = p->thread_info;
}
/* cpu_possible is set up in prom.c */
cpu_set(boot_cpuid, cpu_online_map);
- paca[boot_cpuid].xCurrent = (u64)current;
+ paca[boot_cpuid].xCurrent = current;
current_set[boot_cpuid] = current->thread_info;
}
* use this value that I found through experimentation.
* -- Cort
*/
- for (c = 5000; c && !cpu_callin_map[cpu]; c--)
- udelay(100);
+ if (system_state == SYSTEM_BOOTING)
+ for (c = 5000; c && !cpu_callin_map[cpu]; c--)
+ udelay(100);
+#ifdef CONFIG_HOTPLUG_CPU
+ else
+ /*
+ * CPUs can take much longer to come up in the
+ * hotplug case. Wait five seconds.
+ */
+ for (c = 25; c && !cpu_callin_map[cpu]; c--) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/5);
+ }
+#endif
if (!cpu_callin_map[cpu]) {
printk("Processor %u is stuck.\n", cpu);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
-#ifdef CONFIG_ALTIVEC
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */
+ flush_fp_to_thread(current);
+ flush_altivec_to_thread(current);
error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
return secs;
}
+void do_show_syscall(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7, unsigned long r8,
+ struct pt_regs *regs)
+{
+ printk("syscall %ld(%lx, %lx, %lx, %lx, %lx, %lx) regs=%p current=%p"
+ " cpu=%d\n", regs->gpr[0], r3, r4, r5, r6, r7, r8, regs,
+ current, smp_processor_id());
+}
+
+void do_show_syscall_exit(unsigned long r3)
+{
+ printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id());
+}
+
/* Only exists on P-series. */
cond_syscall(ppc_rtas);
#ifdef CONFIG_NUMA
parent = &node_devices[cpu_to_node(cpu)];
#endif
+ /*
+ * For now, we just see if the system supports making
+ * the RTAS calls for CPU hotplug. But, there may be a
+ * more comprehensive way to do this for an individual
+ * CPU. For instance, the boot cpu might never be valid
+ * for hotplugging.
+ */
+ if (systemcfg->platform != PLATFORM_PSERIES_LPAR)
+ c->no_control = 1;
+
register_cpu(c, cpu, parent);
register_cpu_pmc(&c->sysdev);
siginfo_t info;
unsigned long fpscr;
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
+ flush_fp_to_thread(current);
fpscr = current->thread.fpscr;
die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
}
-void KernelAltivecUnavailableException(struct pt_regs *regs)
+void AltivecUnavailableException(struct pt_regs *regs)
{
+#ifndef CONFIG_ALTIVEC
+ if (user_mode(regs)) {
+ /* A user program has executed an altivec instruction,
+ but this kernel doesn't support altivec. */
+ siginfo_t info;
+
+ memset(&info, 0, sizeof(info));
+ info.si_signo = SIGILL;
+ info.si_code = ILL_ILLOPC;
+ info.si_addr = (void *) regs->nip;
+ _exception(SIGILL, &info, regs);
+ return;
+ }
+#endif
printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
"%lx at %lx\n", regs->trap, regs->nip);
die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
_exception(SIGTRAP, &info, regs);
}
+/*
+ * After we have successfully emulated an instruction, we have to
+ * check if the instruction was being single-stepped, and if so,
+ * pretend we got a single-step exception. This was pointed out
+ * by Kumar Gala. -- paulus
+ */
+static inline void emulate_single_step(struct pt_regs *regs)
+{
+ if (regs->msr & MSR_SE)
+ SingleStepException(regs);
+}
+
static void dummy_perf(struct pt_regs *regs)
{
}
fixed = fix_alignment(regs);
if (fixed == 1) {
- if (!user_mode(regs))
- PPCDBG(PPCDBG_ALIGNFIXUP, "fix alignment at %lx\n",
- regs->nip);
regs->nip += 4; /* skip over emulated instruction */
+ emulate_single_step(regs);
return;
}
void
AltivecAssistException(struct pt_regs *regs)
{
- if (regs->msr & MSR_VEC)
- giveup_altivec(current);
+ flush_altivec_to_thread(current);
/* XXX quick hack for now: set the non-Java bit in the VSCR */
current->thread.vscr.u[3] |= 0x10000;
}
extern struct subsystem devices_subsys; /* needed for vio_find_name() */
-struct iommu_table *vio_build_iommu_table(struct vio_dev *dev);
+static struct iommu_table *vio_build_iommu_table(struct vio_dev *);
+static const struct vio_device_id *vio_match_device(
+ const struct vio_device_id *, const struct vio_dev *);
#ifdef CONFIG_PPC_PSERIES
static int vio_num_address_cells;
* system is in its list of supported devices. Returns the matching
* vio_device_id structure or NULL if there is no match.
*/
-const struct vio_device_id * vio_match_device(const struct vio_device_id *ids,
+static const struct vio_device_id * vio_match_device(const struct vio_device_id *ids,
const struct vio_dev *dev)
{
DBGENTER();
#ifdef CONFIG_PPC_PSERIES
while (ids->type) {
- if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) &&
- device_is_compatible((struct device_node*)dev->archdata, ids->compat))
+ if ((strncmp(((struct device_node *)dev->dev.platform_data)->type, ids->type, strlen(ids->type)) == 0) &&
+ device_is_compatible(dev->dev.platform_data, ids->compat))
return ids;
ids++;
}
DBGENTER();
/* XXX free TCE table */
- of_node_put(viodev->archdata);
+ of_node_put(viodev->dev.platform_data);
kfree(viodev);
}
static ssize_t viodev_show_devspec(struct device *dev, char *buf)
{
- struct vio_dev *viodev = to_vio_dev(dev);
- struct device_node *of_node = viodev->archdata;
+ struct device_node *of_node = dev->platform_data;
return sprintf(buf, "%s\n", of_node->full_name);
}
static ssize_t viodev_show_name(struct device *dev, char *buf)
{
- struct vio_dev *viodev = to_vio_dev(dev);
- struct device_node *of_node = viodev->archdata;
+ struct device_node *of_node = dev->platform_data;
return sprintf(buf, "%s\n", of_node->name);
}
* @of_node: The OF node for this device.
*
* Creates and initializes a vio_dev structure from the data in
- * of_node (archdata) and adds it to the list of virtual devices.
+ * of_node (dev.platform_data) and adds it to the list of virtual devices.
* Returns a pointer to the created vio_dev or NULL if node has
* NULL device_type or compatible fields.
*/
}
memset(viodev, 0, sizeof(struct vio_dev));
- viodev->archdata = (void *)of_node_get(of_node);
+ viodev->dev.platform_data = of_node_get(of_node);
viodev->unit_address = *unit_address;
viodev->iommu_table = vio_build_iommu_table(viodev);
*/
const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
{
- return get_property((struct device_node *)vdev->archdata, (char*)which, length);
+ return get_property(vdev->dev.platform_data, (char*)which, length);
}
EXPORT_SYMBOL(vio_get_attribute);
* Returns a pointer to the built tce tree, or NULL if it can't
* find property.
*/
-struct iommu_table * vio_build_iommu_table(struct vio_dev *dev)
+static struct iommu_table * vio_build_iommu_table(struct vio_dev *dev)
{
unsigned int *dma_window;
struct iommu_table *newTceTable;
unsigned long size;
int dma_window_property_size;
- dma_window = (unsigned int *) get_property((struct device_node *)dev->archdata, "ibm,my-dma-window", &dma_window_property_size);
+ dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
if(!dma_window) {
return NULL;
}
{
char *buf;
u16 vlanMap;
- int vlanIndex;
dma_addr_t handle;
HvLpEvent_Rc hvrc;
DECLARE_MUTEX_LOCKED(Semaphore);
down(&Semaphore);
vlanMap = HvLpConfig_getVirtualLanIndexMap();
- vlanIndex = 0;
- while (vlanMap != 0){
- if (vlanMap & 0x8000)
- vlanIndex++;;
- vlanMap = vlanMap << 1;
- }
buf[PAGE_SIZE-1] = '\0';
seq_printf(m, "%s", buf);
-
- seq_printf(m, "AVAILABLE_VETH=%d\n", vlanIndex );
+ seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
e2a(xItExtVpdPanel.mfgID[2]),
e2a(xItExtVpdPanel.mfgID[3]),
* - DSISR for a non-SLB data access fault,
* - SRR1 & 0x08000000 for a non-SLB instruction access fault
* - 0 any SLB fault.
+ * The return value is 0 if the fault was handled, or the signal
+ * number if this is a kernel fault that can't be handled here.
*/
-void do_page_fault(struct pt_regs *regs, unsigned long address,
- unsigned long error_code)
+int do_page_fault(struct pt_regs *regs, unsigned long address,
+ unsigned long error_code)
{
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
siginfo_t info;
unsigned long code = SEGV_MAPERR;
unsigned long is_write = error_code & 0x02000000;
+ unsigned long trap = TRAP(regs);
- if (regs->trap == 0x300 || regs->trap == 0x380) {
+ if (trap == 0x300 || trap == 0x380) {
if (debugger_fault_handler(regs))
- return;
+ return 0;
}
/* On a kernel SLB miss we can only check for a valid exception entry */
- if (!user_mode(regs) && (regs->trap == 0x380)) {
- bad_page_fault(regs, address, SIGSEGV);
- return;
- }
+ if (!user_mode(regs) && (trap == 0x380 || address >= TASK_SIZE))
+ return SIGSEGV;
if (error_code & 0x00400000) {
if (debugger_dabr_match(regs))
- return;
+ return 0;
}
if (in_atomic() || mm == NULL) {
- bad_page_fault(regs, address, SIGSEGV);
- return;
+ if (!user_mode(regs))
+ return SIGSEGV;
+ /* in_atomic() in user mode is really bad,
+ as is current->mm == NULL. */
+ printk(KERN_EMERG "Page fault in user mode with"
+ "in_atomic() = %d mm = %p\n", in_atomic(), mm);
+ printk(KERN_EMERG "NIP = %lx MSR = %lx\n",
+ regs->nip, regs->msr);
+ die("Weird page fault", regs, SIGSEGV);
}
+
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
}
up_read(&mm->mmap_sem);
- return;
+ return 0;
bad_area:
up_read(&mm->mmap_sem);
info.si_code = code;
info.si_addr = (void *) address;
force_sig_info(SIGSEGV, &info, current);
- return;
+ return 0;
}
- bad_page_fault(regs, address, SIGSEGV);
- return;
+ return SIGSEGV;
/*
* We ran out of memory, or some other thing happened to us that made
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
do_exit(SIGKILL);
- bad_page_fault(regs, address, SIGKILL);
- return;
+ return SIGKILL;
do_sigbus:
up_read(&mm->mmap_sem);
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_ADRERR;
- info.si_addr = (void *)address;
- force_sig_info (SIGBUS, &info, current);
- if (!user_mode(regs))
- bad_page_fault(regs, address, SIGBUS);
+ if (user_mode(regs)) {
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void *)address;
+ force_sig_info(SIGBUS, &info, current);
+ return 0;
+ }
+ return SIGBUS;
}
/*
struct mm_struct *mm;
pte_t *ptep;
int ret;
+ int cpu;
int user_region = 0;
int local = 0;
cpumask_t tmp;
if (pgdir == NULL)
return 1;
- tmp = cpumask_of_cpu(smp_processor_id());
+ cpu = get_cpu();
+ tmp = cpumask_of_cpu(cpu);
if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
local = 1;
ret = hash_huge_page(mm, access, ea, vsid, local);
else {
ptep = find_linux_pte(pgdir, ea);
- if (ptep == NULL)
+ if (ptep == NULL) {
+ put_cpu();
return 1;
+ }
ret = __hash_page(ea, access, vsid, ptep, trap, local);
}
-
+ put_cpu();
return ret;
}
unsigned long addr;
hugepte_t *ptep;
struct page *page;
+ int cpu;
int local = 0;
cpumask_t tmp;
BUG_ON((end % HPAGE_SIZE) != 0);
/* XXX are there races with checking cpu_vm_mask? - Anton */
- tmp = cpumask_of_cpu(smp_processor_id());
+ cpu = get_cpu();
+ tmp = cpumask_of_cpu(cpu);
if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
local = 1;
put_page(page);
}
+ put_cpu();
mm->rss -= (end - start) >> PAGE_SHIFT;
}
void *pgdir;
pte_t *ptep;
int local = 0;
+ int cpu;
cpumask_t tmp;
/* handle i-cache coherency */
vsid = get_vsid(vma->vm_mm->context.id, ea);
- tmp = cpumask_of_cpu(smp_processor_id());
+ cpu = get_cpu();
+ tmp = cpumask_of_cpu(cpu);
if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp))
local = 1;
__hash_page(ea, pte_val(pte) & (_PAGE_USER|_PAGE_RW), vsid, ptep,
0x300, local);
+ put_cpu();
}
void * reserve_phb_iospace(unsigned long size)
DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
unsigned long pte_freelist_forced_free;
+void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage)
+{
+ /* This is safe as we are holding page_table_lock */
+ cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
+ struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
+
+ if (atomic_read(&tlb->mm->mm_users) < 2 ||
+ cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
+ pte_free(ptepage);
+ return;
+ }
+
+ if (*batchp == NULL) {
+ *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
+ if (*batchp == NULL) {
+ pte_free_now(ptepage);
+ return;
+ }
+ (*batchp)->index = 0;
+ }
+ (*batchp)->pages[(*batchp)->index++] = ptepage;
+ if ((*batchp)->index == PTE_FREELIST_SIZE) {
+ pte_free_submit(*batchp);
+ *batchp = NULL;
+ }
+}
+
/*
* Update the MMU hash table to correspond with a change to
* a Linux PTE. If wrprot is true, it is permissible to
void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
{
int i;
- cpumask_t tmp = cpumask_of_cpu(smp_processor_id());
+ int cpu;
+ cpumask_t tmp;
int local = 0;
BUG_ON(in_interrupt());
+ cpu = get_cpu();
i = batch->index;
+ tmp = cpumask_of_cpu(cpu);
if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
local = 1;
else
flush_hash_range(batch->context, i, local);
batch->index = 0;
+ put_cpu();
}
#ifdef CONFIG_SMP
static int xmon_gate;
#endif /* CONFIG_SMP */
-#define TRAP(regs) ((regs)->trap)
-#define FULL_REGS(regs) 1
-
static unsigned long in_xmon = 0;
static unsigned long adrs;
*/
static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata";
static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp);
+ void __user *buffer, size_t *lenp);
static int appldata_interval_handler(ctl_table *ctl, int write,
- struct file *filp, void *buffer,
+ struct file *filp,
+ void __user *buffer,
size_t *lenp);
static struct ctl_table_header *appldata_sysctl_header;
* wrapper function for mod_virt_timer(), because smp_call_function_on()
* accepts only one parameter.
*/
-static void appldata_mod_vtimer_wrap(struct appldata_mod_vtimer_args *args) {
+static void appldata_mod_vtimer_wrap(void *p) {
+ struct appldata_mod_vtimer_args *args = p;
mod_virt_timer(args->timer, args->expires);
}
*/
static int
appldata_timer_handler(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
int len, i;
char buf[2];
*/
static int
appldata_interval_handler(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
int len, i, interval;
char buf[16];
appldata_mod_vtimer_args.expires =
per_cpu_interval;
smp_call_function_on(
- (void *) appldata_mod_vtimer_wrap,
+ appldata_mod_vtimer_wrap,
&appldata_mod_vtimer_args,
0, 1, i);
}
*/
static int
appldata_generic_handler(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
struct appldata_ops *ops = NULL, *tmp_ops;
int rc, len, found;
CONFIG_IKCONFIG_PROC=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_REPORT_LUNS is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
# SCSI low-level drivers
#
# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_MII is not set
#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
+# Gigabit Ethernet (1000/10000 Mbit)
#
#
DEFINE(__TI_cpu, offsetof(struct thread_info, cpu),);
DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count),);
BLANK();
+ DEFINE(__PT_ARGS, offsetof(struct pt_regs, args),);
DEFINE(__PT_PSW, offsetof(struct pt_regs, psw),);
DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs),);
DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2),);
asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
-int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
+int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
{
int err;
}
asmlinkage int
-sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigsetsize)
+sys32_rt_sigsuspend(struct pt_regs * regs, compat_sigset_t __user *unewset,
+ size_t sigsetsize)
{
sigset_t saveset, newset;
compat_sigset_t set32;
if (do_signal(regs, &saveset))
return -EINTR;
}
-}
+}
asmlinkage long
-sys32_sigaction(int sig, const struct old_sigaction32 *act,
- struct old_sigaction32 *oact)
+sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
+ struct old_sigaction32 __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
int
do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact);
-asmlinkage long
-sys32_rt_sigaction(int sig, const struct sigaction32 *act,
- struct sigaction32 *oact, size_t sigsetsize)
+asmlinkage long
+sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
+ struct sigaction32 __user *oact, size_t sigsetsize)
{
struct k_sigaction new_ka, old_ka;
int ret;
}
asmlinkage long
-sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs)
+sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss,
+ struct pt_regs *regs)
{
stack_t kss, koss;
int ret, err = 0;
}
set_fs (KERNEL_DS);
- ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, regs->gprs[15]);
+ ret = do_sigaltstack((stack_t __user *) (uss ? &kss : NULL),
+ (stack_t __user *) (uoss ? &koss : NULL),
+ regs->gprs[15]);
set_fs (old_fs);
if (!ret && uoss) {
return ret;
}
-static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
+static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
{
_s390_regs_common32 regs32;
int err, i;
sizeof(_s390_fp_regs32));
}
-static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
+static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
{
_s390_regs_common32 regs32;
int err, i;
asmlinkage long sys32_sigreturn(struct pt_regs *regs)
{
- sigframe32 *frame = (sigframe32 *)regs->gprs[15];
+ sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
sigset_t set;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
badframe:
force_sig(SIGSEGV, current);
return 0;
-}
+}
asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
{
- rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15];
+ rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
sigset_t set;
stack_t st;
__u32 ss_sp;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- set_fs (KERNEL_DS);
- do_sigaltstack(&st, NULL, regs->gprs[15]);
+ set_fs (KERNEL_DS);
+ do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]);
set_fs (old_fs);
return regs->gprs[2];
/*
* Determine which stack to use..
*/
-static inline void *
+static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
unsigned long sp;
sp = (unsigned long) ka->sa.sa_restorer;
}
- return (void *)((sp - frame_size) & -8ul);
+ return (void __user *)((sp - frame_size) & -8ul);
}
static inline int map_signal(int sig)
static void setup_frame32(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs)
{
- sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+ sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
goto give_sigsegv;
} else {
regs->gprs[14] = (__u64) frame->retcode;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
- (u16 *)(frame->retcode)))
+ (u16 __user *)(frame->retcode)))
goto give_sigsegv;
}
/* Set up backchain. */
- if (__put_user(regs->gprs[15], (unsigned int *) frame))
+ if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
goto give_sigsegv;
/* Set up registers for signal handler */
sigset_t *set, struct pt_regs * regs)
{
int err = 0;
- rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+ rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
goto give_sigsegv;
} else {
regs->gprs[14] = (__u64) frame->retcode;
err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
- (u16 *)(frame->retcode));
+ (u16 __user *)(frame->retcode));
}
/* Set up backchain. */
- if (__put_user(regs->gprs[15], (unsigned int *) frame))
+ if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
goto give_sigsegv;
/* Set up registers for signal handler */
lgfr %r4,%r4 # int
llgtr %r5,%r5 # struct compat_timespec *
llgtr %r6,%r6 # u32 *
+ lgf %r0,164(%r15) # int
+ stg %r0,160(%r15)
jg compat_sys_futex # branch to system call
.globl sys32_setxattr_wrapper
/* internal function prototyes */
static int debug_init(void);
-static ssize_t debug_output(struct file *file, char *user_buf,
+static ssize_t debug_output(struct file *file, char __user *user_buf,
size_t user_len, loff_t * offset);
-static ssize_t debug_input(struct file *file, const char *user_buf,
+static ssize_t debug_input(struct file *file, const char __user *user_buf,
size_t user_len, loff_t * offset);
static int debug_open(struct inode *inode, struct file *file);
static int debug_close(struct inode *inode, struct file *file);
static int debug_prolog_level_fn(debug_info_t * id,
struct debug_view *view, char *out_buf);
static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
- struct file *file, const char *user_buf,
+ struct file *file, const char __user *user_buf,
size_t user_buf_size, loff_t * offset);
static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
- struct file *file, const char *user_buf,
+ struct file *file, const char __user *user_buf,
size_t user_buf_size, loff_t * offset);
static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
char *out_buf, const char *in_buf);
* - copies formated debug entries to the user buffer
*/
-static ssize_t debug_output(struct file *file, /* file descriptor */
- char *user_buf, /* user buffer */
- size_t len, /* length of buffer */
- loff_t *offset /* offset in the file */ )
+static ssize_t debug_output(struct file *file, /* file descriptor */
+ char __user *user_buf, /* user buffer */
+ size_t len, /* length of buffer */
+ loff_t *offset) /* offset in the file */
{
size_t count = 0;
size_t entry_offset, size = 0;
*/
static ssize_t debug_input(struct file *file,
- const char *user_buf, size_t length,
+ const char __user *user_buf, size_t length,
loff_t *offset)
{
int rc = 0;
*/
static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
- struct file *file, const char *user_buf,
+ struct file *file, const char __user *user_buf,
size_t in_buf_size, loff_t * offset)
{
char input_buf[1];
/*
* view function: flushes debug areas
*/
-
+
static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
- struct file *file, const char *user_buf,
+ struct file *file, const char __user *user_buf,
size_t in_buf_size, loff_t * offset)
{
char input_buf[1];
* Stack layout for the system_call stack entry.
* The first few entries are identical to the user_regs_struct.
*/
-SP_PTREGS = STACK_FRAME_OVERHEAD
+SP_PTREGS = STACK_FRAME_OVERHEAD
+SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS
SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW
SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS
SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4
SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+ _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
#define BASED(name) name-system_call(%r13)
lh %r7,0x8a # get svc number from lowcore
sysc_enter:
GET_THREAD_INFO # load pointer to task_struct to R9
+sysc_do_svc:
sla %r7,2 # *4 and test for svc 0
- bnz BASED(sysc_do_restart) # svc number > 0
+ bnz BASED(sysc_nr_ok) # svc number > 0
# svc 0: system call number in %r1
cl %r1,BASED(.Lnr_syscalls)
- bnl BASED(sysc_do_restart)
+ bnl BASED(sysc_nr_ok)
lr %r7,%r1 # copy svc number to %r7
sla %r7,2 # *4
+sysc_nr_ok:
+ mvc SP_ARGS(4,%r15),SP_R7(%r15)
sysc_do_restart:
tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
bz BASED(sysc_leave) # there is no work to do
#
# One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
#
sysc_work:
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
bo BASED(sysc_sigpending)
tm __TI_flags+3(%r9),_TIF_RESTART_SVC
bo BASED(sysc_restart)
+ tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
+ bo BASED(sysc_singlestep)
b BASED(sysc_leave)
#
lm %r2,%r6,SP_R2(%r15) # load svc arguments
b BASED(sysc_do_restart) # restart svc
+#
+# _TIF_SINGLE_STEP is set, call do_debugger_trap
+#
+sysc_singlestep:
+ ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+ mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ l %r1,BASED(.Lhandle_per) # load adr. of per handler
+ la %r14,BASED(sysc_return) # load adr. of system return
+ br %r1 # branch to do_debugger_trap
+
__critical_end:
#
#
pgm_svcper:
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
- lh %r7,0x8a # get svc number from lowcore
- GET_THREAD_INFO # load pointer to task_struct to R9
+ lh %r7,0x8a # get svc number from lowcore
+ GET_THREAD_INFO # load pointer to task_struct to R9
l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
- stosm 24(%r15),0x03 # reenable interrupts
- sla %r7,2 # *4 and test for svc 0
- bnz BASED(pgm_svcstd) # svc number > 0 ?
- # svc 0: system call number in %r1
- cl %r1,BASED(.Lnr_syscalls)
- bnl BASED(pgm_svcstd)
- lr %r7,%r1 # copy svc number to %r7
- sla %r7,2 # *4
-pgm_svcstd:
- tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
- l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
- bnz BASED(pgm_tracesys)
- basr %r14,%r8 # call sys_xxxx
- st %r2,SP_R2(%r15) # store return value (change R2 on stack)
- # ATTENTION: check sys_execve_glue before
- # changing anything here !!
-
-pgm_svcret:
- tm __TI_flags+3(%r9),_TIF_SIGPENDING
- bno BASED(pgm_svcper_nosig)
- la %r2,SP_PTREGS(%r15) # load pt_regs
- sr %r3,%r3 # clear *oldset
- l %r1,BASED(.Ldo_signal)
- basr %r14,%r1 # call do_signal
-
-pgm_svcper_nosig:
- mvi SP_TRAP+3(%r15),0x28 # set trap indication to pgm check
- la %r2,SP_PTREGS(15) # address of register-save area
- l %r1,BASED(.Lhandle_per) # load adr. of per handler
- la %r14,BASED(sysc_return) # load adr. of system return
- br %r1 # branch to do_debugger_trap
-#
-# call trace before and after sys_call
-#
-pgm_tracesys:
- l %r1,BASED(.Ltrace)
- la %r2,SP_PTREGS(%r15) # load pt_regs
- la %r3,0
- srl %r7,2
- st %r7,SP_R2(%r15)
- basr %r14,%r1
- clc SP_R2(4,%r15),BASED(.Lnr_syscalls)
- bnl BASED(pgm_svc_nogo)
- l %r7,SP_R2(%r15) # strace changed the syscall
- sll %r7,2
- l %r8,sys_call_table-system_call(%r7,%r13)
-pgm_svc_go:
- lm %r3,%r6,SP_R3(%r15)
- l %r2,SP_ORIG_R2(%r15)
- basr %r14,%r8 # call sys_xxx
- st %r2,SP_R2(%r15) # store return value
-pgm_svc_nogo:
- tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
- bz BASED(pgm_svcret)
- l %r1,BASED(.Ltrace)
- la %r2,SP_PTREGS(%r15) # load pt_regs
- la %r3,1
- la %r14,BASED(pgm_svcret)
- br %r1
+ oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ stosm 24(%r15),0x03 # reenable interrupts
+ b BASED(sysc_do_svc)
/*
* IO interrupt handler routine
* Stack layout for the system_call stack entry.
* The first few entries are identical to the user_regs_struct.
*/
-SP_PTREGS = STACK_FRAME_OVERHEAD
+SP_PTREGS = STACK_FRAME_OVERHEAD
+SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS
SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW
SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS
SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8
SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC)
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+ _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
/*
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
sysc_enter:
GET_THREAD_INFO # load pointer to task_struct to R9
+sysc_do_svc:
slag %r7,%r7,2 # *4 and test for svc 0
- jnz sysc_do_restart
+ jnz sysc_nr_ok
# svc 0: system call number in %r1
lghi %r0,NR_syscalls
clr %r1,%r0
- jnl sysc_do_restart
+ jnl sysc_nr_ok
lgfr %r7,%r1 # clear high word in r1
slag %r7,%r7,2 # svc 0: system call number in %r1
+sysc_nr_ok:
+ mvc SP_ARGS(8,%r15),SP_R7(%r15)
sysc_do_restart:
larl %r10,sys_call_table
#ifdef CONFIG_S390_SUPPORT
jz sysc_leave # there is no work to do
#
# One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
#
sysc_work:
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
jo sysc_sigpending
tm __TI_flags+7(%r9),_TIF_RESTART_SVC
jo sysc_restart
+ tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
+ jo sysc_singlestep
j sysc_leave
#
lmg %r2,%r6,SP_R2(%r15) # load svc arguments
j sysc_do_restart # restart svc
+#
+# _TIF_SINGLE_STEP is set, call do_debugger_trap
+#
+sysc_singlestep:
+ ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+ mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
+ la %r2,SP_PTREGS(%r15) # address of register-save area
+ larl %r14,sysc_return # load adr. of system return
+ jg do_debugger_trap # branch to do_debugger_trap
+
+
__critical_end:
#
#
pgm_svcper:
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
- llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
- GET_THREAD_INFO # load pointer to task_struct to R9
+ llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
+ GET_THREAD_INFO # load pointer to task_struct to R9
lg %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
- stosm 48(%r15),0x03 # reenable interrupts
- slag %r7,%r7,2 # *4 and test for svc 0
- jnz pgm_svcstd
- # svc 0: system call number in %r1
- lghi %r0,NR_syscalls
- clr %r1,%r0
- slag %r7,%r1,2
-pgm_svcstd:
- larl %r10,sys_call_table
-#ifdef CONFIG_S390_SUPPORT
- tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ?
- jo pgm_svcper_noemu
- larl %r10,sys_call_table_emu # use 31 bit emulation system calls
-pgm_svcper_noemu:
-#endif
- tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
- lgf %r8,0(%r7,%r10) # load address of system call routine
- jnz pgm_tracesys
- basr %r14,%r8 # call sys_xxxx
- stg %r2,SP_R2(%r15) # store return value (change R2 on stack)
- # ATTENTION: check sys_execve_glue before
- # changing anything here !!
-
-pgm_svcret:
- tm __TI_flags+7(%r9),_TIF_SIGPENDING
- jno pgm_svcper_nosig
- la %r2,SP_PTREGS(%r15) # load pt_regs
- sgr %r3,%r3 # clear *oldset
- brasl %r14,do_signal
-
-pgm_svcper_nosig:
- lhi %r0,__LC_PGM_OLD_PSW # set trap indication back to pgm_chk
- st %r0,SP_TRAP(%r15)
- la %r2,SP_PTREGS(15) # address of register-save area
- larl %r14,sysc_return # load adr. of system return
- jg do_debugger_trap
-#
-# call trace before and after sys_call
-#
-pgm_tracesys:
- la %r2,SP_PTREGS(%r15) # load pt_regs
- la %r3,0
- srlg %r7,%r7,2
- stg %r7,SP_R2(%r15)
- brasl %r14,syscall_trace
- lghi %r0,NR_syscalls
- clg %r0,SP_R2(%r15)
- jnh pgm_svc_nogo
- lg %r7,SP_R2(%r15)
- sllg %r7,%r7,2 # strace wants to change the syscall
- lgf %r8,0(%r7,%r10)
-pgm_svc_go:
- lmg %r3,%r6,SP_R3(%r15)
- lg %r2,SP_ORIG_R2(%r15)
- basr %r14,%r8 # call sys_xxx
- stg %r2,SP_R2(%r15) # store return value
-pgm_svc_nogo:
- tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
- jz pgm_svcret
- la %r2,SP_PTREGS(%r15) # load pt_regs
- la %r3,1
- larl %r14,pgm_svcret # return point is sysc_return
- jg syscall_trace
+ oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+ stosm 48(%r15),0x03 # reenable interrupts
+ j sysc_do_svc
/*
* IO interrupt handler routine
mvcle %r2,%r4,0 # clear mem
jo .-4 # branch back, if not finish
+ l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
+.Lservicecall:
+ stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
+
+ stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
+ la %r1,0x200 # set bit 22
+ o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
+ st %r1,.Lcr-.LPG1(%r13)
+ lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
+
+ mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
+ la %r1, .Lsclph-.LPG1(%r13)
+ a %r1,__LC_EXT_NEW_PSW+4 # set handler
+ st %r1,__LC_EXT_NEW_PSW+4
+
+ la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
+ la %r1, .Lsccb-PARMAREA(%r4) # our sccb
+ .insn rre,0xb2200000,%r2,%r1 # service call
+ ipm %r1
+ srl %r1,28 # get cc code
+ xr %r3, %r3
+ chi %r1,3
+ be .Lfchunk-.LPG1(%r13) # leave
+ chi %r1,2
+ be .Lservicecall-.LPG1(%r13)
+ lpsw .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+ lh %r1,.Lsccbr-PARMAREA(%r4)
+ chi %r1,0x10 # 0x0010 is the sucess code
+ je .Lprocsccb # let's process the sccb
+ chi %r1,0x1f0
+ bne .Lfchunk-.LPG1(%r13) # unhandled error code
+ c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced
+ bne .Lfchunk-.LPG1(%r13) # if no, give up
+ l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
+ b .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+ lh %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+ chi %r1,0x00
+ jne .Lscnd
+ l %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+.Lscnd:
+ xr %r3,%r3 # same logic
+ ic %r3,.Lscpa1-PARMAREA(%r4)
+ chi %r3,0x00
+ jne .Lcompmem
+ l %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+ mr %r2,%r1 # mem in MB on 128-bit
+ l %r1,.Lonemb-.LPG1(%r13)
+ mr %r2,%r1 # mem size in bytes in %r3
+ b .Lfchunk-.LPG1(%r13)
+
+.Lpmask:
+ .byte 0
+.align 8
+.Lpcext:.long 0x00080000,0x80000000
+.Lcr:
+ .long 0x00 # place holder for cr0
+.Lwaitsclp:
+ .long 0x020A0000
+ .long .Lsclph
+.Lrcp:
+ .int 0x00120001 # Read SCP forced code
+.Lrcp2:
+ .int 0x00020001 # Read SCP code
+.Lonemb:
+ .int 0x100000
+.Lfchunk:
+
#
# find memory chunks.
#
+ lr %r9,%r3 # end of mem
mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
la %r1,1 # test in increments of 128KB
sll %r1,17
slr %r4,%r4 # set start of chunk to zero
slr %r5,%r5 # set end of chunk to zero
slr %r6,%r6 # set access code to zero
+ la %r10, MEMORY_CHUNKS # number of chunks
.Lloop:
tprot 0(%r5),0 # test protection of first byte
ipm %r7
srl %r7,28
clr %r6,%r7 # compare cc with last access code
be .Lsame-.LPG1(%r13)
- clr %r4,%r5 # chunk size > 0?
- be .Lsize0-.LPG1(%r13)
- st %r4,0(%r3) # store start address of chunk
- lr %r0,%r5
- slr %r0,%r4
- st %r0,4(%r3) # store size of chunk
- st %r6,8(%r3) # store type of chunk
- la %r3,12(%r3)
- lr %r4,%r5 # set start to end
-.Lsize0:
- lr %r6,%r7 # set access code to last cc
+ b .Lchkmem-.LPG1(%r13)
.Lsame:
ar %r5,%r1 # add 128KB to end of chunk
bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
.Lchkmem: # > 2GB or tprot got a program check
clr %r4,%r5 # chunk size > 0?
- be .Ldonemem-.LPG1(%r13)
+ be .Lchkloop-.LPG1(%r13)
st %r4,0(%r3) # store start address of chunk
lr %r0,%r5
slr %r0,%r4
st %r0,4(%r3) # store size of chunk
st %r6,8(%r3) # store type of chunk
+ la %r3,12(%r3)
+ l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
+ st %r5,0(%r4) # store last end to memory size
+ ahi %r10,-1 # update chunk number
+.Lchkloop:
+ lr %r6,%r7 # set access code to last cc
+ # we got an exception or we're starting a new
+ # chunk , we must check if we should
+ # still try to find valid memory (if we detected
+ # the amount of available storage), and if we
+ # have chunks left
+ xr %r0,%r0
+ clr %r0,%r9 # did we detect memory?
+ je .Ldonemem # if not, leave
+ chi %r10,0 # do we have chunks left?
+ je .Ldonemem
+ alr %r5,%r1 # add 128KB to end of chunk
+ lr %r4,%r5 # potential new chunk
+ clr %r5,%r9 # should we go on?
+ jl .Lloop
.Ldonemem:
- l %r1,.Lmemsize-.LPG1(%r13) # address of variable memory_size
- st %r5,0(%r1) # store last end to memory size
-
l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
#
# find out if we are running under VM
.byte "root=/dev/ram0 ro"
.byte 0
.org 0x11000
+.Lsccb:
+ .hword 0x1000 # length, one page
+ .byte 0x00,0x00,0x00
+ .byte 0x80 # variable response bit set
+.Lsccbr:
+ .hword 0x00 # response code
+.Lscpincr1:
+ .hword 0x00
+.Lscpa1:
+ .byte 0x00
+ .fill 89,1,0
+.Lscpa2:
+ .int 0x00
+.Lscpincr2:
+ .quad 0x00
+ .fill 3984,1,0
+ .org 0x12000
.global _pend
_pend:
mvcle %r2,%r4,0 # clear mem
jo .-4 # branch back, if not finish
+ l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
+.Lservicecall:
+ stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
+
+ stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0
+ la %r1,0x200 # set bit 22
+ og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
+ stg %r1,.Lcr-.LPG1(%r13)
+ lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0
+
+ mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw
+ larl %r1,.Lsclph
+ stg %r1,__LC_EXT_NEW_PSW+8 # set handler
+
+ larl %r4,_pstart # %r4 is our index for sccb stuff
+ la %r1,.Lsccb-PARMAREA(%r4) # our sccb
+ .insn rre,0xb2200000,%r2,%r1 # service call
+ ipm %r1
+ srl %r1,28 # get cc code
+ xr %r3,%r3
+ chi %r1,3
+ be .Lfchunk-.LPG1(%r13) # leave
+ chi %r1,2
+ be .Lservicecall-.LPG1(%r13)
+ lpsw .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+ lh %r1,.Lsccbr-PARMAREA(%r4)
+ chi %r1,0x10 # 0x0010 is the sucess code
+ je .Lprocsccb # let's process the sccb
+ chi %r1,0x1f0
+ bne .Lfchunk-.LPG1(%r13) # unhandled error code
+ c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced
+ bne .Lfchunk-.LPG1(%r13) # if no, give up
+ l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP
+ b .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+ lh %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+ chi %r1,0x00
+ jne .Lscnd
+ lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+.Lscnd:
+ xr %r3,%r3 # same logic
+ ic %r3,.Lscpa1-PARMAREA(%r4)
+ chi %r3,0x00
+ jne .Lcompmem
+ l %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+ mlgr %r2,%r1 # mem in MB on 128-bit
+ l %r1,.Lonemb-.LPG1(%r13)
+ mlgr %r2,%r1 # mem size in bytes in %r3
+ b .Lfchunk-.LPG1(%r13)
+
+.Lpmask:
+ .byte 0
+ .align 8
+.Lcr:
+ .quad 0x00 # place holder for cr0
+.Lwaitsclp:
+ .long 0x020A0000
+ .quad .Lsclph
+.Lrcp:
+ .int 0x00120001 # Read SCP forced code
+.Lrcp2:
+ .int 0x00020001 # Read SCP code
+.Lonemb:
+ .int 0x100000
+
+.Lfchunk:
# set program check new psw mask
mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
#
# find memory chunks.
#
+ lgr %r9,%r3 # end of mem
larl %r1,.Lchkmem # set program check address
stg %r1,__LC_PGM_NEW_PSW+8
la %r1,1 # test in increments of 128KB
slgr %r4,%r4 # set start of chunk to zero
slgr %r5,%r5 # set end of chunk to zero
slr %r6,%r6 # set access code to zero
+ la %r10,MEMORY_CHUNKS # number of chunks
.Lloop:
tprot 0(%r5),0 # test protection of first byte
ipm %r7
srl %r7,28
clr %r6,%r7 # compare cc with last access code
je .Lsame
- clgr %r4,%r5 # chunk size > 0?
- je .Lsize0
- stg %r4,0(%r3) # store start address of chunk
- lgr %r0,%r5
- slgr %r0,%r4
- stg %r0,8(%r3) # store size of chunk
- st %r6,20(%r3) # store type of chunk
- la %r3,24(%r3)
- lgr %r4,%r5 # set start to end
- larl %r8,memory_size
- stg %r5,0(%r8) # store memory size
-.Lsize0:
- lr %r6,%r7 # set access code to last cc
+ j .Lchkmem
.Lsame:
algr %r5,%r1 # add 128KB to end of chunk
- brc 12,.Lloop
+ # no need to check here,
+ brc 12,.Lloop # this is the same chunk
.Lchkmem: # > 16EB or tprot got a program check
clgr %r4,%r5 # chunk size > 0?
- je .Ldonemem
+ je .Lchkloop
stg %r4,0(%r3) # store start address of chunk
lgr %r0,%r5
slgr %r0,%r4
stg %r0,8(%r3) # store size of chunk
st %r6,20(%r3) # store type of chunk
la %r3,24(%r3)
- lgr %r4,%r5
larl %r8,memory_size
stg %r5,0(%r8) # store memory size
-#
-# Running native the HSA is located at 2GB and we will get an
-# addressing exception trying to access it. We have to restart
-# the scan at 2GB to find out if the machine has more than 2GB.
-#
+ ahi %r10,-1 # update chunk number
+.Lchkloop:
+ lr %r6,%r7 # set access code to last cc
+ # we got an exception or we're starting a new
+ # chunk , we must check if we should
+ # still try to find valid memory (if we detected
+ # the amount of available storage), and if we
+ # have chunks left
lghi %r4,1
sllg %r4,%r4,31
clgr %r5,%r4
- jhe .Ldonemem
- lgr %r5,%r4
- j .Lloop
+ je .Lhsaskip
+ xr %r0, %r0
+ clgr %r0, %r9 # did we detect memory?
+ je .Ldonemem # if not, leave
+ chi %r10, 0 # do we have chunks left?
+ je .Ldonemem
+.Lhsaskip:
+ algr %r5,%r1 # add 128KB to end of chunk
+ lgr %r4,%r5 # potential new chunk
+ clgr %r5,%r9 # should we go on?
+ jl .Lloop
.Ldonemem:
larl %r12,machine_flags
.byte "root=/dev/ram0 ro"
.byte 0
.org 0x11000
+.Lsccb:
+ .hword 0x1000 # length, one page
+ .byte 0x00,0x00,0x00
+ .byte 0x80 # variable response bit set
+.Lsccbr:
+ .hword 0x00 # response code
+.Lscpincr1:
+ .hword 0x00
+.Lscpa1:
+ .byte 0x00
+ .fill 89,1,0
+.Lscpa2:
+ .int 0x00
+.Lscpincr2:
+ .quad 0x00
+ .fill 3984,1,0
+ .org 0x12000
.global _pend
_pend:
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
*/
#include <linux/config.h>
+#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
{
unsigned long clone_flags;
unsigned long newsp;
- int *parent_tidptr, *child_tidptr;
+ int __user *parent_tidptr, *child_tidptr;
clone_flags = regs.gprs[3];
newsp = regs.orig_gpr2;
- parent_tidptr = (int *) regs.gprs[4];
- child_tidptr = (int *) regs.gprs[5];
+ parent_tidptr = (int __user *) regs.gprs[4];
+ child_tidptr = (int __user *) regs.gprs[5];
if (!newsp)
newsp = regs.gprs[15];
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0,
int error;
char * filename;
- filename = getname((char *) regs.orig_gpr2);
+ filename = getname((char __user *) regs.orig_gpr2);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
- error = do_execve(filename, (char **) regs.gprs[3],
- (char **) regs.gprs[4], ®s);
+ error = do_execve(filename, (char __user * __user *) regs.gprs[3],
+ (char __user * __user *) regs.gprs[4], ®s);
if (error == 0) {
current->ptrace &= ~PT_DTRACE;
current->thread.fp_regs.fpc = 0;
return len;
}
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+static int prof_cpu_mask_write_proc (struct file *file,
+ const char __user *buffer,
unsigned long count, void *data)
{
cpumask_t *mask = (cpumask_t *)data;
/*
* psw and gprs are stored on the stack
*/
- tmp = *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr);
+ tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr);
if (addr == (addr_t) &dummy->regs.psw.mask)
/* Remove per bit from user psw. */
tmp &= ~PSW_MASK_PER;
} else
tmp = 0;
- return put_user(tmp, (addr_t *) data);
+ return put_user(tmp, (addr_t __user *) data);
}
/*
high order bit but older gdb's rely on it */
data |= PSW_ADDR_AMODE;
#endif
- *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr) = data;
+ *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data;
} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
/*
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
return -EIO;
- return put_user(tmp, (unsigned long *) data);
+ return put_user(tmp, (unsigned long __user *) data);
case PTRACE_PEEKUSR:
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR_AREA:
case PTRACE_POKEUSR_AREA:
- if (copy_from_user(&parea, (void *) addr, sizeof(parea)))
+ if (copy_from_user(&parea, (void __user *) addr,
+ sizeof(parea)))
return -EFAULT;
addr = parea.kernel_addr;
data = parea.process_addr;
ret = peek_user(child, addr, data);
else {
addr_t tmp;
- if (get_user (tmp, (addr_t *) data))
+ if (get_user (tmp, (addr_t __user *) data))
return -EFAULT;
ret = poke_user(child, addr, tmp);
}
PSW32_ADDR_AMODE31;
} else {
/* gpr 0-15 */
- tmp = *(__u32 *)((addr_t) __KSTK_PTREGS(child) +
+ tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw +
addr*2 + 4);
}
} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
} else
tmp = 0;
- return put_user(tmp, (__u32 *) data);
+ return put_user(tmp, (__u32 __user *) data);
}
/*
(__u64) tmp & PSW32_ADDR_INSN;
} else {
/* gpr 0-15 */
- *(__u32*)((addr_t) __KSTK_PTREGS(child) + addr*2 + 4) =
- tmp;
+ *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw
+ + addr*2 + 4) = tmp;
}
} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
/*
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
return -EIO;
- return put_user(tmp, (unsigned int *) data);
+ return put_user(tmp, (unsigned int __user *) data);
case PTRACE_PEEKUSR:
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR_AREA:
case PTRACE_POKEUSR_AREA:
- if (copy_from_user(&parea, (void *) addr, sizeof(parea)))
+ if (copy_from_user(&parea, (void __user *) addr,
+ sizeof(parea)))
return -EFAULT;
addr = parea.kernel_addr;
data = parea.process_addr;
ret = peek_user_emu31(child, addr, data);
else {
__u32 tmp;
- if (get_user (tmp, (__u32 *) data))
+ if (get_user (tmp, (__u32 __user *) data))
return -EFAULT;
ret = poke_user_emu31(child, addr, tmp);
}
EXPORT_SYMBOL(__down);
EXPORT_SYMBOL(__down_interruptible);
-/*
- * string functions
- */
-EXPORT_SYMBOL_NOVERS(memcmp);
-EXPORT_SYMBOL_NOVERS(memset);
-EXPORT_SYMBOL_NOVERS(memmove);
-EXPORT_SYMBOL_NOVERS(memscan);
-EXPORT_SYMBOL_NOVERS(strlen);
-EXPORT_SYMBOL_NOVERS(strchr);
-EXPORT_SYMBOL_NOVERS(strcmp);
-EXPORT_SYMBOL_NOVERS(strncat);
-EXPORT_SYMBOL_NOVERS(strncmp);
-EXPORT_SYMBOL_NOVERS(strncpy);
-EXPORT_SYMBOL_NOVERS(strnlen);
-EXPORT_SYMBOL_NOVERS(strrchr);
-EXPORT_SYMBOL_NOVERS(strstr);
-EXPORT_SYMBOL_NOVERS(strpbrk);
-EXPORT_SYMBOL_NOVERS(strcpy);
-
/*
* binfmt_elf loader
*/
unsigned int console_irq = -1;
unsigned long memory_size = 0;
unsigned long machine_flags = 0;
-struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
+struct {
+ unsigned long addr, size, type;
+} memory_chunk[MEMORY_CHUNKS] = { { 0 } };
#define CHUNK_READ_WRITE 0
#define CHUNK_READ_ONLY 1
int cpus_initialized = 0;
}
}
-asmlinkage int
-sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize)
+asmlinkage long
+sys_rt_sigsuspend(struct pt_regs *regs, sigset_t __user *unewset,
+ size_t sigsetsize)
{
sigset_t saveset, newset;
}
}
-asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction *act,
- struct old_sigaction *oact)
+asmlinkage long
+sys_sigaction(int sig, const struct old_sigaction __user *act,
+ struct old_sigaction __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
return ret;
}
-asmlinkage int
-sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs)
+asmlinkage long
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ struct pt_regs *regs)
{
return do_sigaltstack(uss, uoss, regs->gprs[15]);
}
/* Returns non-zero on fault. */
-static int save_sigregs(struct pt_regs *regs, _sigregs *sregs)
+static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
unsigned long old_mask = regs->psw.mask;
int err;
}
/* Returns positive number on error */
-static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
+static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
{
unsigned long old_mask = regs->psw.mask;
int err;
asmlinkage long sys_sigreturn(struct pt_regs *regs)
{
- sigframe *frame = (sigframe *)regs->gprs[15];
+ sigframe __user *frame = (sigframe __user *)regs->gprs[15];
sigset_t set;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
{
- rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
+ rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15];
sigset_t set;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
/*
* Determine which stack to use..
*/
-static inline void *
+static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
unsigned long sp;
sp = (unsigned long) ka->sa.sa_restorer;
}
- return (void *)((sp - frame_size) & -8ul);
+ return (void __user *)((sp - frame_size) & -8ul);
}
static inline int map_signal(int sig)
static void setup_frame(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs)
{
- sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe));
+ sigframe __user *frame;
+
+ frame = get_sigframe(ka, regs, sizeof(sigframe));
if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe)))
goto give_sigsegv;
} else {
regs->gprs[14] = (unsigned long)
frame->retcode | PSW_ADDR_AMODE;
- if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
- (u16 *)(frame->retcode)))
+ if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
+ (u16 __user *)(frame->retcode)))
goto give_sigsegv;
}
/* Set up backchain. */
- if (__put_user(regs->gprs[15], (addr_t *) frame))
+ if (__put_user(regs->gprs[15], (addr_t __user *) frame))
goto give_sigsegv;
/* Set up registers for signal handler */
sigset_t *set, struct pt_regs * regs)
{
int err = 0;
- rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+ rt_sigframe __user *frame;
+
+ frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe)))
goto give_sigsegv;
} else {
regs->gprs[14] = (unsigned long)
frame->retcode | PSW_ADDR_AMODE;
- err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
- (u16 *)(frame->retcode));
+ err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
+ (u16 __user *)(frame->retcode));
}
/* Set up backchain. */
- if (__put_user(regs->gprs[15], (addr_t *) frame))
+ if (__put_user(regs->gprs[15], (addr_t __user *) frame))
goto give_sigsegv;
/* Set up registers for signal handler */
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way Unix traditionally does this, though.
*/
-asmlinkage long sys_pipe(unsigned long * fildes)
+asmlinkage long sys_pipe(unsigned long __user *fildes)
{
int fd[2];
int error;
unsigned long offset;
};
-asmlinkage long sys_mmap2(struct mmap_arg_struct *arg)
+asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg)
{
struct mmap_arg_struct a;
int error = -EFAULT;
return error;
}
-asmlinkage long old_mmap(struct mmap_arg_struct *arg)
+asmlinkage long old_mmap(struct mmap_arg_struct __user *arg)
{
struct mmap_arg_struct a;
long error = -EFAULT;
struct timeval *tvp;
};
-asmlinkage long old_select(struct sel_arg_struct *arg)
+asmlinkage long old_select(struct sel_arg_struct __user *arg)
{
struct sel_arg_struct a;
*
* This is really horribly ugly.
*/
-asmlinkage long sys_ipc (uint call, int first, int second,
- unsigned long third, void *ptr)
+asmlinkage long sys_ipc(uint call, int first, int second,
+ unsigned long third, void __user *ptr)
{
struct ipc_kludge tmp;
int ret;
switch (call) {
case SEMOP:
- return sys_semtimedop (first, (struct sembuf *) ptr, second,
+ return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
NULL);
case SEMTIMEDOP:
- return sys_semtimedop (first, (struct sembuf *) ptr, second,
- (const struct timespec *) third);
+ return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
+ (const struct timespec __user *) third);
case SEMGET:
return sys_semget (first, second, third);
case SEMCTL: {
union semun fourth;
if (!ptr)
return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
+ if (get_user(fourth.__pad, (void __user * __user *) ptr))
return -EFAULT;
return sys_semctl (first, second, third, fourth);
- }
+ }
case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
+ return sys_msgsnd (first, (struct msgbuf __user *) ptr,
second, third);
break;
case MSGRCV:
if (!ptr)
return -EINVAL;
- if (copy_from_user (&tmp, (struct ipc_kludge *) ptr,
+ if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr,
sizeof (struct ipc_kludge)))
return -EFAULT;
return sys_msgrcv (first, tmp.msgp,
case MSGGET:
return sys_msgget ((key_t) first, second);
case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds *) ptr);
-
+ return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+
case SHMAT: {
ulong raddr;
- ret = do_shmat (first, (char *) ptr, second, &raddr);
+ ret = do_shmat (first, (char __user *) ptr, second, &raddr);
if (ret)
return ret;
- return put_user (raddr, (ulong *) third);
+ return put_user (raddr, (ulong __user *) third);
break;
}
- case SHMDT:
- return sys_shmdt ((char *)ptr);
+ case SHMDT:
+ return sys_shmdt ((char __user *)ptr);
case SHMGET:
return sys_shmget (first, second, third);
case SHMCTL:
return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
+ (struct shmid_ds __user *) ptr);
default:
return -ENOSYS;
}
-
+
return -EINVAL;
}
#ifdef CONFIG_ARCH_S390X
-asmlinkage long s390x_newuname(struct new_utsname * name)
+asmlinkage long s390x_newuname(struct new_utsname __user *name)
{
int ret = sys_newuname(name);
};
asmlinkage long
-s390_fadvise64_64(struct fadvise64_64_args *args)
+s390_fadvise64_64(struct fadvise64_64_args __user *args)
{
struct fadvise64_64_args a;
printk("%s Code: ", mode);
for (i = 0; i < 20; i++) {
unsigned char c;
- if (__get_user(c, (char *)(regs->psw.addr + i))) {
+ if (__get_user(c, (char __user *)(regs->psw.addr + i))) {
printk(" Bad PSW.");
break;
}
local_irq_enable();
if (regs->psw.mask & PSW_MASK_PSTATE)
- get_user(*((__u16 *) opcode), location);
+ get_user(*((__u16 *) opcode), (__u16 __user *)location);
else
*((__u16 *)opcode)=*((__u16 *)location);
if (*((__u16 *)opcode)==S390_BREAKPOINT_U16)
EXTRA_AFLAGS := -traditional
-lib-y += delay.o
-lib-$(CONFIG_ARCH_S390_31) += memset.o strcmp.o strcpy.o strncpy.o uaccess.o
-lib-$(CONFIG_ARCH_S390X) += memset64.o strcmp64.o strcpy64.o strncpy64.o uaccess64.o
+lib-y += delay.o string.o
+lib-$(CONFIG_ARCH_S390_31) += uaccess.o
+lib-$(CONFIG_ARCH_S390X) += uaccess64.o
.align 4
.text
.globl __strncpy_from_user_asm
- # %r2 = dst, %r3 = src, %r4 = count
+ # %r2 = count, %r3 = dst, %r4 = src
__strncpy_from_user_asm:
lhi %r0,0
- lhi %r1,1
- lhi %r5,0
-0: mvcp 0(%r1,%r2),0(%r3),%r0
- tm 0(%r2),0xff
- jz 1f
- la %r2,1(%r2)
- la %r3,1(%r3)
- ahi %r5,1
- clr %r5,%r4
- jl 0b
-1: lr %r2,%r5
+ lr %r1,%r4
+ la %r4,0(%r4) # clear high order bit from %r4
+ la %r2,0(%r2,%r4) # %r2 points to first byte after string
+ sacf 256
+0: srst %r2,%r1
+ jo 0b
+ sacf 0
+ lr %r1,%r2
+ jh 1f # \0 found in string ?
+ ahi %r1,1 # include \0 in copy
+1: slr %r1,%r4 # %r1 = copy length (without \0)
+ slr %r2,%r4 # %r2 = return length (including \0)
+2: mvcp 0(%r1,%r3),0(%r4),%r0
+ jnz 3f
br %r14
-2: lhi %r2,-EFAULT
+3: la %r3,256(%r3)
+ la %r4,256(%r4)
+ ahi %r1,-256
+ mvcp 0(%r1,%r3),0(%r4),%r0
+ jnz 3b
br %r14
- .section __ex_table,"a"
- .long 0b,2b
+4: sacf 0
+ lhi %r2,-EFAULT
+ br %r14
+ .section __ex_table,"a"
+ .long 0b,4b
.previous
.align 4
.text
.globl __strnlen_user_asm
- # %r2 = src, %r3 = count
+ # %r2 = count, %r3 = src
__strnlen_user_asm:
lhi %r0,0
- lhi %r1,1
- lhi %r5,0
-0: mvcp 24(%r1,%r15),0(%r2),%r0
- ahi %r5,1
- tm 24(%r15),0xff
- jz 1f
- la %r2,1(%r2)
- clr %r5,%r3
- jl 0b
-1: lr %r2,%r5
+ lr %r1,%r3
+ la %r3,0(%r3) # clear high order bit from %r4
+ la %r2,0(%r2,%r3) # %r2 points to first byte after string
+ sacf 256
+0: srst %r2,%r1
+ jo 0b
+ sacf 0
+ jh 1f # \0 found in string ?
+ ahi %r2,1 # strnlen_user result includes the \0
+1: slr %r2,%r3
br %r14
-2: lhi %r2,-EFAULT
+2: sacf 0
+ lhi %r2,-EFAULT
br %r14
- .section __ex_table,"a"
+ .section __ex_table,"a"
.long 0b,2b
.previous
.align 4
.text
.globl __strncpy_from_user_asm
- # %r2 = dst, %r3 = src, %r4 = count
+ # %r2 = count, %r3 = dst, %r4 = src
__strncpy_from_user_asm:
lghi %r0,0
- lghi %r1,1
- lghi %r5,0
-0: mvcp 0(%r1,%r2),0(%r3),%r0
- tm 0(%r2),0xff
- jz 1f
- la %r2,1(%r2)
- la %r3,1(%r3)
- aghi %r5,1
- clgr %r5,%r4
- jl 0b
-1: lgr %r2,%r5
+ lgr %r1,%r4
+ la %r2,0(%r2,%r4) # %r2 points to first byte after string
+ sacf 256
+0: srst %r2,%r1
+ jo 0b
+ sacf 0
+ lgr %r1,%r2
+ jh 1f # \0 found in string ?
+ aghi %r1,1 # include \0 in copy
+1: slgr %r1,%r4 # %r1 = copy length (without \0)
+ slgr %r2,%r4 # %r2 = return length (including \0)
+2: mvcp 0(%r1,%r3),0(%r4),%r0
+ jnz 3f
br %r14
-2: lghi %r2,-EFAULT
+3: la %r3,256(%r3)
+ la %r4,256(%r4)
+ aghi %r1,-256
+ mvcp 0(%r1,%r3),0(%r4),%r0
+ jnz 3b
br %r14
- .section __ex_table,"a"
- .quad 0b,2b
+4: sacf 0
+ lghi %r2,-EFAULT
+ br %r14
+ .section __ex_table,"a"
+ .quad 0b,4b
.previous
.align 4
.text
.globl __strnlen_user_asm
- # %r2 = src, %r3 = count
+ # %r2 = count, %r3 = src
__strnlen_user_asm:
lghi %r0,0
- lghi %r1,1
- lghi %r5,0
-0: mvcp 24(%r1,%r15),0(%r2),%r0
- aghi %r5,1
- tm 24(%r15),0xff
- jz 1f
- la %r2,1(%r2)
- clgr %r5,%r3
- jl 0b
-1: lgr %r2,%r5
+ lgr %r1,%r3
+ la %r2,0(%r2,%r3) # %r2 points to first byte after string
+ sacf 256
+0: srst %r2,%r1
+ jo 0b
+ sacf 0
+ jh 1f # \0 found in string ?
+ aghi %r2,1 # strnlen_user result includes the \0
+1: slgr %r2,%r3
br %r14
-2: lghi %r2,-EFAULT
+2: sacf 0
+ lghi %r2,-EFAULT
br %r14
- .section __ex_table,"a"
+ .section __ex_table,"a"
.quad 0b,2b
.previous
static spinlock_t dcss_lock = SPIN_LOCK_UNLOCKED;
static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);
-extern struct {unsigned long addr, size, type;} memory_chunk[16];
+extern struct {
+ unsigned long addr, size, type;
+} memory_chunk[MEMORY_CHUNKS];
/*
* Create the 8 bytes, ebcdic VM segment name from
shared segment */
dcss_diag_query(dcss_name, &rwattr, &shattr, &segstart, &segend);
/* does segment collide with main memory? */
- for (i=0; i<16; i++) {
- if (memory_chunk[i].type != 0)
- continue;
- if (memory_chunk[i].addr > segend)
- continue;
- if (memory_chunk[i].addr + memory_chunk[i].size <= segstart)
- continue;
- spin_unlock(&dcss_lock);
- return -ENOENT;
- }
+ for (i=0; i < MEMORY_CHUNKS; i++) {
+ if (memory_chunk[i].type != 0)
+ continue;
+ if (memory_chunk[i].addr > segend)
+ continue;
+ if (memory_chunk[i].addr + memory_chunk[i].size <= segstart)
+ continue;
+ spin_unlock(&dcss_lock);
+ return -ENOENT;
+ }
/* or does it collide with other (loaded) segments? */
list_for_each(l, &dcss_list) {
tmp = list_entry(l, struct dcss_segment, list);
void iounmap(void *addr)
{
if (addr > high_memory)
- return vfree(addr);
+ vfree(addr);
}
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
* in etrap.S which assumes it.
*/
union thread_union init_thread_union
- __attribute__((section (".text")))
+ __attribute__((section (".text,#alloc")))
__attribute__((aligned (THREAD_SIZE)))
= { INIT_THREAD_INFO(init_task) };
return &win->locals[reg - 16];
}
-static inline unsigned long compute_effective_address(struct pt_regs *regs,
- unsigned int insn)
+static unsigned long compute_effective_address(struct pt_regs *regs,
+ unsigned int insn)
{
unsigned int rs1 = (insn >> 14) & 0x1f;
unsigned int rs2 = insn & 0x1f;
}
}
-static inline unsigned long safe_compute_effective_address(struct pt_regs *regs,
- unsigned int insn)
+unsigned long safe_compute_effective_address(struct pt_regs *regs,
+ unsigned int insn)
{
unsigned int rs1 = (insn >> 14) & 0x1f;
unsigned int rs2 = insn & 0x1f;
return 0;
}
+extern unsigned long safe_compute_effective_address(struct pt_regs *,
+ unsigned int);
+
+static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
+{
+ unsigned int insn;
+
+ if (text_fault)
+ return regs->pc;
+
+ if (regs->psr & PSR_PS) {
+ insn = *(unsigned int *) regs->pc;
+ } else {
+ __get_user(insn, (unsigned int *) regs->pc);
+ }
+
+ return safe_compute_effective_address(regs, insn);
+}
+
asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
unsigned long address)
{
info.si_errno = 0;
/* info.si_code set above to make clear whether
this was a SEGV_MAPERR or SEGV_ACCERR fault. */
- info.si_addr = (void *)address;
+ info.si_addr = (void *) compute_si_addr(regs, text_fault);
info.si_trapno = 0;
force_sig_info (SIGSEGV, &info, tsk);
return;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
- info.si_addr = (void *)address;
+ info.si_addr = (void *) compute_si_addr(regs, text_fault);
info.si_trapno = 0;
force_sig_info (SIGBUS, &info, tsk);
if (!from_user)
info.si_errno = 0;
/* info.si_code set above to make clear whether
this was a SEGV_MAPERR or SEGV_ACCERR fault. */
- info.si_addr = (void *)address;
+ info.si_addr = (void *) address;
info.si_trapno = 0;
force_sig_info (SIGSEGV, &info, tsk);
return;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
- info.si_addr = (void *)address;
+ info.si_addr = (void *) address;
info.si_trapno = 0;
force_sig_info (SIGBUS, &info, tsk);
}
static inline void srmmu_pmd_clear(pmd_t *pmdp) {
int i;
- for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++)
+ for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++)
srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0));
}
int i;
ptp = __nocache_pa((unsigned long) ptep) >> 4;
- for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
+ for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
- ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
+ ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
}
}
int i;
ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4); /* watch for overflow */
- for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) {
+ for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) {
srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp);
- ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4);
+ ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4);
}
}
static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) srmmu_pgd_page(*dir) +
- ((address >> SRMMU_PMD_SHIFT_SOFT) & (SRMMU_PTRS_PER_PMD_SOFT - 1));
+ ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
}
/* Find an entry in the third-level page table.. */
pte = __nocache_va((dir->pmdv[0] & SRMMU_PTD_PMASK) << 4);
return (pte_t *) pte +
- ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE_SOFT - 1));
+ ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
}
static unsigned long srmmu_swp_type(swp_entry_t entry)
static pte_t *
srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
{
- return (pte_t *)srmmu_get_nocache(SRMMU_PTE_SZ_SOFT, SRMMU_PTE_SZ_SOFT);
+ return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
}
static struct page *
static void srmmu_free_pte_fast(pte_t *pte)
{
- srmmu_free_nocache((unsigned long)pte, SRMMU_PTE_SZ_SOFT);
+ srmmu_free_nocache((unsigned long)pte, PTE_SIZE);
}
static void srmmu_pte_free(struct page *pte)
BUG();
p = page_to_pfn(pte) << PAGE_SHIFT; /* Physical address */
p = (unsigned long) __nocache_va(p); /* Nocached virtual */
- srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT);
+ srmmu_free_nocache(p, PTE_SIZE);
}
/*
a = 0x20; b = 0x40; c = 0x60;
d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
- start &= SRMMU_PMD_MASK;
+ start &= SRMMU_REAL_PMD_MASK;
while(start < end) {
faddr = (start + (0x10000 - 0x100));
goto inside;
"r" (a), "r" (b), "r" (c), "r" (d),
"r" (e), "r" (f), "r" (g));
} while (faddr != start);
- start += SRMMU_PMD_SIZE;
+ start += SRMMU_REAL_PMD_SIZE;
}
srmmu_set_context(octx);
local_irq_restore(flags);
}
pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
- ptep = (pte_t *)__srmmu_get_nocache(SRMMU_PTE_SZ_SOFT,
- SRMMU_PTE_SZ_SOFT);
+ ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
- memset(__nocache_fix(ptep), 0, SRMMU_PTE_SZ_SOFT);
+ memset(__nocache_fix(ptep), 0, PTE_SIZE);
srmmu_pmd_set(__nocache_fix(pmdp), ptep);
}
- if (start > (0xffffffffUL - SRMMU_PMD_SIZE_SOFT))
+ if (start > (0xffffffffUL - PMD_SIZE))
break;
- start = (start + SRMMU_PMD_SIZE_SOFT) & SRMMU_PMD_MASK_SOFT;
+ start = (start + PMD_SIZE) & PMD_MASK;
}
}
}
pmdp = srmmu_pmd_offset(pgdp, start);
if(srmmu_pmd_none(*pmdp)) {
- ptep = (pte_t *) __srmmu_get_nocache(SRMMU_PTE_SZ_SOFT,
- SRMMU_PTE_SZ_SOFT);
+ ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
+ PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
- memset(ptep, 0, SRMMU_PTE_SZ_SOFT);
+ memset(ptep, 0, PTE_SIZE);
srmmu_pmd_set(pmdp, ptep);
}
- if (start > (0xffffffffUL - SRMMU_PMD_SIZE_SOFT))
+ if (start > (0xffffffffUL - PMD_SIZE))
break;
- start = (start + SRMMU_PMD_SIZE_SOFT) & SRMMU_PMD_MASK_SOFT;
+ start = (start + PMD_SIZE) & PMD_MASK;
}
}
/* A red snapper, see what it really is. */
what = 0;
- if(!(start & ~(SRMMU_PMD_MASK))) {
- if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PMD_SIZE) == prompte)
+ if(!(start & ~(SRMMU_REAL_PMD_MASK))) {
+ if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte)
what = 1;
}
}
pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start);
if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
- ptep = (pte_t *) __srmmu_get_nocache(SRMMU_PTE_SZ_SOFT,
- SRMMU_PTE_SZ_SOFT);
+ ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
+ PTE_SIZE);
if (ptep == NULL)
early_pgtable_allocfail("pte");
- memset(__nocache_fix(ptep), 0, SRMMU_PTE_SZ_SOFT);
+ memset(__nocache_fix(ptep), 0, PTE_SIZE);
srmmu_pmd_set(__nocache_fix(pmdp), ptep);
}
if(what == 1) {
* good hardware PTE piece. Alternatives seem worse.
*/
unsigned int x; /* Index of HW PMD in soft cluster */
- x = (start >> SRMMU_PMD_SHIFT) & 15;
+ x = (start >> PMD_SHIFT) & 15;
*(unsigned long *)__nocache_fix(&pmdp->pmdv[x]) = prompte;
- start += SRMMU_PMD_SIZE;
+ start += SRMMU_REAL_PMD_SIZE;
continue;
}
ptep = srmmu_pte_offset(__nocache_fix(pmdp), start);
extern void ld_mmu_iounit(void);
extern void ___xchg32_sun4md(void);
- BTFIXUPSET_SIMM13(pmd_shift, SRMMU_PMD_SHIFT_SOFT);
- BTFIXUPSET_SETHI(pmd_size, SRMMU_PMD_SIZE_SOFT);
- BTFIXUPSET_SETHI(pmd_mask, SRMMU_PMD_MASK_SOFT);
-
BTFIXUPSET_SIMM13(pgdir_shift, SRMMU_PGDIR_SHIFT);
BTFIXUPSET_SETHI(pgdir_size, SRMMU_PGDIR_SIZE);
BTFIXUPSET_SETHI(pgdir_mask, SRMMU_PGDIR_MASK);
- BTFIXUPSET_SIMM13(ptrs_per_pte, SRMMU_PTRS_PER_PTE_SOFT);
- BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD_SOFT);
+ BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD);
BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD);
BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE));
printk("Loading sun4c MMU routines\n");
/* First the constants */
- BTFIXUPSET_SIMM13(pmd_shift, SUN4C_PMD_SHIFT);
- BTFIXUPSET_SETHI(pmd_size, SUN4C_PMD_SIZE);
- BTFIXUPSET_SETHI(pmd_mask, SUN4C_PMD_MASK);
BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT);
BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE);
BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK);
- BTFIXUPSET_SIMM13(ptrs_per_pte, SUN4C_PTRS_PER_PTE);
BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD);
BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD);
BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE);
#
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDETAPE=m
# CONFIG_BLK_DEV_IDEFLOPPY is not set
CONFIG_SCSI_SATA_VIA=m
CONFIG_SCSI_SATA_VITESSE=m
# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
CONFIG_SCSI_DMX3191D=m
# CONFIG_SCSI_EATA is not set
CONFIG_SCSI_EATA_PIO=m
# CONFIG_VIA_RHINE_MMIO is not set
#
-# Gigabit Ethernet (1000/10000 Mbit)
+# Ethernet (1000 Mbit)
#
-CONFIG_NET_GIGE=y
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_DL2K=m
CONFIG_R8169=m
CONFIG_SK98LIN=m
CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
CONFIG_IXGB=m
CONFIG_IXGB_NAPI=y
CONFIG_S2IO=m
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_KONICAWC is not set
# CONFIG_USB_OV511 is not set
+CONFIG_USB_PWC=m
# CONFIG_USB_SE401 is not set
# CONFIG_USB_STV680 is not set
CONFIG_USB_W9968CF=m
static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset)
{
unsigned long ret;
+ int this_cpu = get_cpu();
- if (mp->portid == smp_processor_id()) {
+ if (mp->portid == this_cpu) {
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=r" (ret)
: "r" (offset), "i" (ASI_MCU_CTRL_REG));
: "r" (mp->regs + offset),
"i" (ASI_PHYS_BYPASS_EC_E));
}
+ put_cpu();
+
return ret;
}
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init_task.h>
+#include <linux/mqueue.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
if (imap == 0UL)
return;
+ preempt_disable();
+
if (tlb_type == cheetah || tlb_type == cheetah_plus) {
unsigned long ver;
* Things like FFB can now be handled via the new IRQ mechanism.
*/
upa_writel(tid | IMAP_VALID, imap);
+
+ preempt_enable();
}
/* This now gets passed true ino's as well. */
static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, cpumask_t mask)
{
u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
+ int this_cpu = get_cpu();
cpus_and(mask, mask, cpu_online_map);
- cpu_clear(smp_processor_id(), mask);
+ cpu_clear(this_cpu, mask);
if (tlb_type == spitfire)
spitfire_xcall_deliver(data0, data1, data2, mask);
else
cheetah_xcall_deliver(data0, data1, data2, mask);
/* NOTE: Caller runs local copy on master. */
+
+ put_cpu();
}
extern unsigned long xcall_sync_tick;
void smp_flush_dcache_page_impl(struct page *page, int cpu)
{
cpumask_t mask = cpumask_of_cpu(cpu);
+ int this_cpu = get_cpu();
#ifdef CONFIG_DEBUG_DCFLUSH
atomic_inc(&dcpage_flushes);
#endif
- if (cpu == smp_processor_id()) {
+ if (cpu == this_cpu) {
__local_flush_dcache_page(page);
} else if (cpu_online(cpu)) {
u64 data0;
atomic_inc(&dcpage_flushes_xcall);
#endif
}
+
+ put_cpu();
}
void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
{
cpumask_t mask = cpu_online_map;
u64 data0;
+ int this_cpu = get_cpu();
- cpu_clear(smp_processor_id(), mask);
+ cpu_clear(this_cpu, mask);
#ifdef CONFIG_DEBUG_DCFLUSH
atomic_inc(&dcpage_flushes);
#endif
flush_self:
__local_flush_dcache_page(page);
+
+ put_cpu();
}
void smp_receive_signal(int cpu)
{
u32 ctx = CTX_HWBITS(mm->context);
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
if (atomic_read(&mm->mm_users) == 1) {
/* See smp_flush_tlb_page for info about this. */
local_flush_and_out:
__flush_tlb_mm(ctx, SECONDARY_CONTEXT);
+
+ put_cpu();
}
}
unsigned long end)
{
u32 ctx = CTX_HWBITS(mm->context);
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
start &= PAGE_MASK;
end = PAGE_ALIGN(end);
local_flush_and_out:
__flush_tlb_range(ctx, start, SECONDARY_CONTEXT,
end, PAGE_SIZE, (end-start));
+
+ put_cpu();
}
void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
{
u32 ctx = CTX_HWBITS(mm->context);
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
page &= PAGE_MASK;
if (mm == current->active_mm &&
local_flush_and_out:
__flush_tlb_page(ctx, page, SECONDARY_CONTEXT);
+
+ put_cpu();
}
}
EXPORT_SYMBOL(___test_and_set_le_bit);
EXPORT_SYMBOL(___test_and_clear_le_bit);
+/* Bit searching */
+EXPORT_SYMBOL(find_next_bit);
+EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(find_next_zero_le_bit);
+
EXPORT_SYMBOL(ivector_table);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
SIGN1(sys32_select, compat_sys_select, %o0)
SIGN1(sys32_mkdir, sys_mkdir, %o1)
-SIGN2(sys32_futex, compat_sys_futex, %o1, %o2)
+SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
SIGN3(sys32_ipc, compat_sys_ipc, %o1, %o2, %o3)
SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
}
/* So stupid... */
-extern long compat_sys_wait4(compat_pid_t, compat_uint_t *, int,
- struct compat_rusage *);
+extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int,
+ struct compat_rusage __user *);
asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru)
{
}
}
-static unsigned long compute_effective_address(struct pt_regs *regs,
- unsigned int insn, unsigned int rd)
+unsigned long compute_effective_address(struct pt_regs *regs,
+ unsigned int insn, unsigned int rd)
{
unsigned int rs1 = (insn >> 14) & 0x1f;
unsigned int rs2 = insn & 0x1f;
VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \
VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \
U3memcpy.o U3copy_from_user.o U3copy_to_user.o \
- U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o splock.o
+ U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o splock.o \
+ find_bit.o
lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
{
unsigned long caller, val;
int stuck = INIT_STUCK;
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
int shown = 0;
GET_CALLER(caller);
lock->owner_cpu = cpu;
current->thread.smp_lock_count++;
current->thread.smp_lock_pc = ((unsigned int)caller);
+
+ put_cpu();
}
int _spin_trylock(spinlock_t *lock)
{
unsigned long val, caller;
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
GET_CALLER(caller);
__asm__ __volatile__("ldstub [%1], %0"
current->thread.smp_lock_count++;
current->thread.smp_lock_pc = ((unsigned int)caller);
}
+
+ put_cpu();
+
return val == 0;
}
{
unsigned long caller, val;
int stuck = INIT_STUCK;
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
int shown = 0;
GET_CALLER(caller);
rw->reader_pc[cpu] = ((unsigned int)caller);
current->thread.smp_lock_count++;
current->thread.smp_lock_pc = ((unsigned int)caller);
+
+ put_cpu();
}
void _do_read_unlock (rwlock_t *rw, char *str)
{
unsigned long caller, val;
int stuck = INIT_STUCK;
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
int shown = 0;
GET_CALLER(caller);
}
goto runlock_again;
}
+
+ put_cpu();
}
void _do_write_lock (rwlock_t *rw, char *str)
{
unsigned long caller, val;
int stuck = INIT_STUCK;
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
int shown = 0;
GET_CALLER(caller);
rw->writer_cpu = cpu;
current->thread.smp_lock_count++;
current->thread.smp_lock_pc = ((unsigned int)caller);
+
+ put_cpu();
}
void _do_write_unlock(rwlock_t *rw)
int _do_write_trylock (rwlock_t *rw, char *str)
{
unsigned long caller, val;
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
GET_CALLER(caller);
: "0" (&(rw->lock))
: "g3", "g5", "g7", "memory");
- if (val)
+ if (val) {
+ put_cpu();
return 0;
+ }
if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) {
/* Readers still around, drop the write
: "r" (&(rw->lock))
: "g3", "g5", "g7", "cc", "memory");
+ put_cpu();
+
return 0;
}
current->thread.smp_lock_count++;
current->thread.smp_lock_pc = ((unsigned int)caller);
+ put_cpu();
+
return 1;
}
#include <linux/types.h>
#include <asm/byteorder.h>
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addcc %4,%5,%1\n\
- add %2,%3,%0\n\
- bcs,a,pn %%xcc, 1f\n\
- add %0, 1, %0\n\
- 1:" \
- : "=r" ((UDItype)(sh)), \
- "=&r" ((UDItype)(sl)) \
- : "r" ((UDItype)(ah)), \
- "r" ((UDItype)(bh)), \
- "r" ((UDItype)(al)), \
- "r" ((UDItype)(bl)) \
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %4,%5,%1\n\t" \
+ "add %2,%3,%0\n\t" \
+ "bcs,a,pn %%xcc, 1f\n\t" \
+ "add %0, 1, %0\n" \
+ "1:" \
+ : "=r" ((UDItype)(sh)), \
+ "=&r" ((UDItype)(sl)) \
+ : "r" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "r" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) \
: "cc")
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subcc %4,%5,%1\n\
- sub %2,%3,%0\n\
- bcs,a,pn %%xcc, 1f\n\
- sub %0, 1, %0\n\
- 1:" \
- : "=r" ((UDItype)(sh)), \
- "=&r" ((UDItype)(sl)) \
- : "r" ((UDItype)(ah)), \
- "r" ((UDItype)(bh)), \
- "r" ((UDItype)(al)), \
- "r" ((UDItype)(bl)) \
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %4,%5,%1\n\t" \
+ "sub %2,%3,%0\n\t" \
+ "bcs,a,pn %%xcc, 1f\n\t" \
+ "sub %0, 1, %0\n" \
+ "1:" \
+ : "=r" ((UDItype)(sh)), \
+ "=&r" ((UDItype)(sl)) \
+ : "r" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "r" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) \
: "cc")
-#define umul_ppmm(wh, wl, u, v) \
- do { \
- UDItype tmp1, tmp2, tmp3, tmp4; \
- __asm__ __volatile__ ( \
- "srl %7,0,%3\n\
- mulx %3,%6,%1\n\
- srlx %6,32,%2\n\
- mulx %2,%3,%4\n\
- sllx %4,32,%5\n\
- srl %6,0,%3\n\
- sub %1,%5,%5\n\
- srlx %5,32,%5\n\
- addcc %4,%5,%4\n\
- srlx %7,32,%5\n\
- mulx %3,%5,%3\n\
- mulx %2,%5,%5\n\
- sethi %%hi(0x80000000),%2\n\
- addcc %4,%3,%4\n\
- srlx %4,32,%4\n\
- add %2,%2,%2\n\
- movcc %%xcc,%%g0,%2\n\
- addcc %5,%4,%5\n\
- sllx %3,32,%3\n\
- add %1,%3,%1\n\
- add %5,%2,%0" \
- : "=r" ((UDItype)(wh)), \
- "=&r" ((UDItype)(wl)), \
- "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
- : "r" ((UDItype)(u)), \
- "r" ((UDItype)(v)) \
- : "cc"); \
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ UDItype tmp1, tmp2, tmp3, tmp4; \
+ __asm__ __volatile__ ( \
+ "srl %7,0,%3\n\t" \
+ "mulx %3,%6,%1\n\t" \
+ "srlx %6,32,%2\n\t" \
+ "mulx %2,%3,%4\n\t" \
+ "sllx %4,32,%5\n\t" \
+ "srl %6,0,%3\n\t" \
+ "sub %1,%5,%5\n\t" \
+ "srlx %5,32,%5\n\t" \
+ "addcc %4,%5,%4\n\t" \
+ "srlx %7,32,%5\n\t" \
+ "mulx %3,%5,%3\n\t" \
+ "mulx %2,%5,%5\n\t" \
+ "sethi %%hi(0x80000000),%2\n\t" \
+ "addcc %4,%3,%4\n\t" \
+ "srlx %4,32,%4\n\t" \
+ "add %2,%2,%2\n\t" \
+ "movcc %%xcc,%%g0,%2\n\t" \
+ "addcc %5,%4,%5\n\t" \
+ "sllx %3,32,%3\n\t" \
+ "add %1,%3,%1\n\t" \
+ "add %5,%2,%0" \
+ : "=r" ((UDItype)(wh)), \
+ "=&r" ((UDItype)(wl)), \
+ "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
+ : "r" ((UDItype)(u)), \
+ "r" ((UDItype)(v)) \
+ : "cc"); \
} while (0)
-#define udiv_qrnnd(q, r, n1, n0, d) \
- do { \
- UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
- __d1 = (d >> 32); \
- __d0 = (USItype)d; \
- \
- __r1 = (n1) % __d1; \
- __q1 = (n1) / __d1; \
- __m = (UWtype) __q1 * __d0; \
- __r1 = (__r1 << 32) | (n0 >> 32); \
- if (__r1 < __m) \
- { \
- __q1--, __r1 += (d); \
- if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \
- if (__r1 < __m) \
- __q1--, __r1 += (d); \
- } \
- __r1 -= __m; \
- \
- __r0 = __r1 % __d1; \
- __q0 = __r1 / __d1; \
- __m = (UWtype) __q0 * __d0; \
- __r0 = (__r0 << 32) | ((USItype)n0); \
- if (__r0 < __m) \
- { \
- __q0--, __r0 += (d); \
- if (__r0 >= (d)) \
- if (__r0 < __m) \
- __q0--, __r0 += (d); \
- } \
- __r0 -= __m; \
- \
- (q) = (UWtype) (__q1 << 32) | __q0; \
- (r) = __r0; \
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ __d1 = (d >> 32); \
+ __d0 = (USItype)d; \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
+ __r1 = (__r1 << 32) | (n0 >> 32); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
+ __r0 = (__r0 << 32) | ((USItype)n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (UWtype) (__q1 << 32) | __q0; \
+ (r) = __r0; \
} while (0)
#define UDIV_NEEDS_NORMALIZATION 1
-#define abort() \
+#define abort() \
return 0
#ifdef __BIG_ENDIAN
return insn;
}
-static void do_fault_siginfo(int code, int sig, unsigned long address)
+extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
+
+static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
+ unsigned int insn, int fault_code)
{
siginfo_t info;
info.si_code = code;
info.si_signo = sig;
info.si_errno = 0;
- info.si_addr = (void *) address;
+ if (fault_code & FAULT_CODE_ITLB)
+ info.si_addr = (void *) regs->tpc;
+ else
+ info.si_addr = (void *)
+ compute_effective_address(regs, insn, 0);
info.si_trapno = 0;
force_sig_info(sig, &info, current);
}
/* The si_code was set to make clear whether
* this was a SEGV_MAPERR or SEGV_ACCERR fault.
*/
- do_fault_siginfo(si_code, SIGSEGV, address);
+ do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code);
return;
}
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
- do_fault_siginfo(BUS_ADRERR, SIGBUS, address);
+ do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code);
/* Kernel mode? Handle exceptions or die */
if (regs->tstate & TSTATE_PRIV)
#define dcache_dirty_cpu(page) \
(((page)->flags >> 24) & (NR_CPUS - 1UL))
-static __inline__ void set_dcache_dirty(struct page *page)
+static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
{
- unsigned long mask = smp_processor_id();
+ unsigned long mask = this_cpu;
unsigned long non_cpu_bits = ~((NR_CPUS - 1UL) << 24UL);
mask = (mask << 24) | (1UL << PG_dcache_dirty);
__asm__ __volatile__("1:\n\t"
(page = pfn_to_page(pfn), page_mapping(page)) &&
((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) {
int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL));
+ int this_cpu = get_cpu();
/* This is just to optimize away some function calls
* in the SMP case.
*/
- if (cpu == smp_processor_id())
+ if (cpu == this_cpu)
flush_dcache_page_impl(page);
else
smp_flush_dcache_page_impl(page, cpu);
clear_dcache_dirty_cpu(page, cpu);
+
+ put_cpu();
}
if (get_thread_fault_code())
__update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
struct address_space *mapping = page_mapping(page);
int dirty = test_bit(PG_dcache_dirty, &page->flags);
int dirty_cpu = dcache_dirty_cpu(page);
+ int this_cpu = get_cpu();
if (mapping && !mapping_mapped(mapping)) {
if (dirty) {
- if (dirty_cpu == smp_processor_id())
- return;
+ if (dirty_cpu == this_cpu)
+ goto out;
smp_flush_dcache_page_impl(page, dirty_cpu);
}
- set_dcache_dirty(page);
+ set_dcache_dirty(page, this_cpu);
} else {
/* We could delay the flush for the !page_mapping
* case too. But that case is for exec env/arg
*/
flush_dcache_page_impl(page);
}
+
+out:
+ put_cpu();
}
/* When shared+writable mmaps of files go away, we lose all dirty
#include "linux/sched.h"
#include "linux/init_task.h"
#include "linux/version.h"
+#include "linux/mqueue.h"
#include "asm/uaccess.h"
#include "asm/pgtable.h"
#include "user_util.h"
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux := -e stext
+CHECK := $(CHECK) -D__x86_64__=1
+
cflags-$(CONFIG_MK8) += $(call check_gcc,-march=k8,)
cflags-$(CONFIG_MPSC) += $(call check_gcc,-march=nocona,)
CFLAGS += $(cflags-y)
CONFIG_IKCONFIG_PROC=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
CONFIG_IDEDMA_AUTO=y
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# Firmware Drivers
#
# CONFIG_EDD is not set
-# CONFIG_SMBIOS is not set
#
# File systems
static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
- struct _fpstate_ia32 *buf)
+ struct _fpstate_ia32 __user *buf)
{
struct _fpxreg *to;
- struct _fpreg *from;
+ struct _fpreg __user *from;
int i;
u32 v;
int err = 0;
-#define G(num,val) err |= __get_user(val, num + (u32 *)buf)
+#define G(num,val) err |= __get_user(val, num + (u32 __user *)buf)
G(0, fxsave->cwd);
G(1, fxsave->swd);
G(2, fxsave->twd);
}
-static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf,
+static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf,
struct i387_fxsave_struct *fxsave,
struct pt_regs *regs,
struct task_struct *tsk)
{
- struct _fpreg *to;
+ struct _fpreg __user *to;
struct _fpxreg *from;
int i;
u16 cs,ds;
cs = regs->cs;
}
-#define P(num,val) err |= __put_user(val, num + (u32 *)buf)
+#define P(num,val) err |= __put_user(val, num + (u32 __user *)buf)
P(0, (u32)fxsave->cwd | 0xffff0000);
P(1, (u32)fxsave->swd | 0xffff0000);
P(2, twd_fxsr_to_i387(fxsave));
return 0;
}
-int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave)
+int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave)
{
clear_fpu(tsk);
if (!fsave) {
}
int save_i387_ia32(struct task_struct *tsk,
- struct _fpstate_ia32 *buf,
+ struct _fpstate_ia32 __user *buf,
struct pt_regs *regs,
int fsave)
{
#ifndef TIOCGDEV
#define TIOCGDEV _IOR('T',0x32, unsigned int)
#endif
-static int tiocgdev(unsigned fd, unsigned cmd, unsigned int *ptr)
+static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr)
{
struct file *file = fget(fd);
ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val);
set_fs(oldfs);
if (!ret)
- ret = put_user(val, (unsigned int*) arg);
+ ret = put_user(val, (unsigned int __user *) arg);
return ret;
case RTC_IRQP_SET32:
ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val);
set_fs(oldfs);
if (!ret)
- ret = put_user(val, (unsigned int*) arg);
+ ret = put_user(val, (unsigned int __user *) arg);
return ret;
case RTC_EPOCH_SET32:
struct mtrr_gentry g;
struct mtrr_sentry s;
int get = 0, err = 0;
- struct mtrr_gentry32 *g32 = (struct mtrr_gentry32 *)arg;
+ struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg;
mm_segment_t oldfs = get_fs();
switch (cmd) {
arg = (unsigned long)&g;
} else {
- struct mtrr_sentry32 *s32 = (struct mtrr_sentry32 *)arg;
+ struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg;
err = get_user(s.base, &s32->base);
err |= get_user(s.size, &s32->size);
err |= get_user(s.type, &s32->type);
#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);
+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from)
{
}
asmlinkage long
-sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr,
- struct pt_regs regs)
+sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
+ stack_ia32_t __user *uoss_ptr,
+ struct pt_regs regs)
{
stack_t uss,uoss;
int ret;
};
static int
-ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
+ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *peax)
{
unsigned int err = 0;
{
u32 tmp;
- struct _fpstate_ia32 * buf;
+ struct _fpstate_ia32 __user * buf;
err |= __get_user(tmp, &sc->fpstate);
- buf = (struct _fpstate_ia32 *) (u64)tmp;
+ buf = compat_ptr(tmp);
if (buf) {
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
asmlinkage long sys32_sigreturn(struct pt_regs regs)
{
- struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
+ struct sigframe __user *frame = (struct sigframe __user *)(regs.rsp-8);
sigset_t set;
unsigned int eax;
asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
{
- struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
+ struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs.rsp - 4);
sigset_t set;
- stack_t st;
unsigned int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
*/
static int
-ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
+ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
struct pt_regs *regs, unsigned int mask)
{
int tmp, err = 0;
tmp = 0;
__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
- err |= __put_user(tmp, (unsigned int *)&sc->gs);
+ err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
__asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
- err |= __put_user(tmp, (unsigned int *)&sc->fs);
+ err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
__asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
- err |= __put_user(tmp, (unsigned int *)&sc->ds);
+ err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
__asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
- err |= __put_user(tmp, (unsigned int *)&sc->es);
+ err |= __put_user(tmp, (unsigned int __user *)&sc->es);
err |= __put_user((u32)regs->rdi, &sc->edi);
err |= __put_user((u32)regs->rsi, &sc->esi);
/*
* Determine which stack to use..
*/
-static void *
+static void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
unsigned long rsp;
rsp = (unsigned long) ka->sa.sa_restorer;
}
- return (void *)((rsp - frame_size) & -8UL);
+ return (void __user *)((rsp - frame_size) & -8UL);
}
void ia32_setup_frame(int sig, struct k_sigaction *ka,
compat_sigset_t *set, struct pt_regs * regs)
{
- struct sigframe *frame;
+ struct sigframe __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
compat_sigset_t *set, struct pt_regs * regs)
{
- struct rt_sigframe *frame;
+ struct rt_sigframe __user *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
.quad sys_mknod
.quad sys_chmod /* 15 */
.quad sys_lchown16
- .quad ni_syscall /* old break syscall holder */
+ .quad quiet_ni_syscall /* old break syscall holder */
.quad sys_stat
.quad sys32_lseek
.quad sys_getpid /* 20 */
.quad sys_fstat /* (old)fstat */
.quad sys_pause
.quad compat_sys_utime /* 30 */
- .quad ni_syscall /* old stty syscall holder */
- .quad ni_syscall /* old gtty syscall holder */
+ .quad quiet_ni_syscall /* old stty syscall holder */
+ .quad quiet_ni_syscall /* old gtty syscall holder */
.quad sys_access
.quad sys_nice
- .quad ni_syscall /* 35 */ /* old ftime syscall holder */
+ .quad quiet_ni_syscall /* 35 */ /* old ftime syscall holder */
.quad sys_sync
.quad sys32_kill
.quad sys_rename
.quad sys_dup
.quad sys32_pipe
.quad compat_sys_times
- .quad ni_syscall /* old prof syscall holder */
+ .quad quiet_ni_syscall /* old prof syscall holder */
.quad sys_brk /* 45 */
.quad sys_setgid16
.quad sys_getgid16
.quad sys_getegid16 /* 50 */
.quad sys_acct
.quad sys_umount /* new_umount */
- .quad ni_syscall /* old lock syscall holder */
+ .quad quiet_ni_syscall /* old lock syscall holder */
.quad compat_sys_ioctl
.quad compat_sys_fcntl64 /* 55 */
- .quad ni_syscall /* old mpx syscall holder */
+ .quad quiet_ni_syscall /* old mpx syscall holder */
.quad sys_setpgid
- .quad ni_syscall /* old ulimit syscall holder */
+ .quad quiet_ni_syscall /* old ulimit syscall holder */
.quad sys32_olduname
.quad sys_umask /* 60 */
.quad sys_chroot
.quad sys_fchown16 /* 95 */
.quad sys_getpriority
.quad sys_setpriority
- .quad ni_syscall /* old profil syscall holder */
+ .quad quiet_ni_syscall /* old profil syscall holder */
.quad compat_sys_statfs
.quad compat_sys_fstatfs /* 100 */
.quad sys_ioperm
.quad sys32_uname
.quad stub32_iopl /* 110 */
.quad sys_vhangup
- .quad ni_syscall /* old "idle" system call */
+ .quad quiet_ni_syscall /* old "idle" system call */
.quad sys32_vm86_warning /* vm86old */
.quad compat_sys_wait4
.quad sys_swapoff /* 115 */
.quad quiet_ni_syscall /* bdflush */
.quad sys_sysfs /* 135 */
.quad sys_personality
- .quad ni_syscall /* for afs_syscall */
+ .quad quiet_ni_syscall /* for afs_syscall */
.quad sys_setfsuid16
.quad sys_setfsgid16
.quad sys_llseek /* 140 */
.quad sys_capset
.quad stub32_sigaltstack
.quad sys32_sendfile
- .quad ni_syscall /* streams1 */
- .quad ni_syscall /* streams2 */
+ .quad quiet_ni_syscall /* streams1 */
+ .quad quiet_ni_syscall /* streams2 */
.quad stub32_vfork /* 190 */
.quad compat_sys_getrlimit
.quad sys32_mmap2
.quad sys_removexattr /* 235 */
.quad sys_lremovexattr
.quad sys_fremovexattr
- .quad sys_tkill /* 238 */
+ .quad sys_tkill
.quad sys_sendfile64
.quad compat_sys_futex /* 240 */
- .quad compat_sys_sched_setaffinity
- .quad compat_sys_sched_getaffinity
+ .quad compat_sys_sched_setaffinity
+ .quad compat_sys_sched_getaffinity
.quad sys32_set_thread_area
.quad sys32_get_thread_area
- .quad sys32_io_setup
+ .quad sys32_io_setup /* 245 */
.quad sys_io_destroy
.quad sys32_io_getevents
.quad sys32_io_submit
.quad sys_io_cancel
- .quad sys_fadvise64
- .quad quiet_ni_syscall /* free_huge_pages */
- .quad sys_exit_group /* exit_group */
+ .quad sys_fadvise64 /* 250 */
+ .quad quiet_ni_syscall /* free_huge_pages */
+ .quad sys_exit_group
.quad sys_lookup_dcookie
.quad sys_epoll_create
- .quad sys_epoll_ctl
+ .quad sys_epoll_ctl /* 255 */
.quad sys_epoll_wait
.quad sys_remap_file_pages
.quad sys_set_tid_address
.quad sys32_timer_create
- .quad compat_timer_settime
+ .quad compat_timer_settime /* 260 */
.quad compat_timer_gettime
.quad sys_timer_getoverrun
.quad sys_timer_delete
.quad compat_clock_settime
- .quad compat_clock_gettime
+ .quad compat_clock_gettime /* 265 */
.quad compat_clock_getres
.quad compat_clock_nanosleep
- .quad compat_statfs64 /* statfs64 */
- .quad compat_fstatfs64 /* fstatfs64 */
- .quad sys_tgkill
+ .quad compat_statfs64
+ .quad compat_fstatfs64
+ .quad sys_tgkill /* 270 */
.quad compat_sys_utimes
.quad sys32_fadvise64_64
- .quad sys_ni_syscall /* sys_vserver */
- .quad sys_ni_syscall /* sys_mbind */
- .quad sys_ni_syscall /* 275 sys_get_mempolicy */
- .quad sys_ni_syscall /* sys_set_mempolicy */
+ .quad quiet_ni_syscall /* sys_vserver */
+ .quad sys_mbind
+ .quad compat_get_mempolicy /* 275 */
+ .quad sys_set_mempolicy
.quad compat_sys_mq_open
.quad sys_mq_unlink
.quad compat_sys_mq_timedsend
.quad compat_sys_mq_timedreceive /* 280 */
.quad compat_sys_mq_notify
.quad compat_sys_mq_getsetattr
+ .quad quiet_ni_syscall /* reserved for kexec */
/* don't forget to change IA32_NR_syscalls */
ia32_syscall_end:
.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
#include <linux/mm.h>
#include <linux/ptrace.h>
#include <asm/ptrace.h>
+#include <asm/compat.h>
#include <asm/uaccess.h>
#include <asm/user32.h>
#include <asm/user.h>
{
struct task_struct *child;
struct pt_regs *childregs;
+ void __user *datap = compat_ptr(data);
int ret;
__u32 val;
if (access_process_vm(child, addr, &val, sizeof(u32), 0)!=sizeof(u32))
ret = -EIO;
else
- ret = put_user(val, (unsigned int *)(u64)data);
+ ret = put_user(val, (unsigned int __user *)datap);
break;
case PTRACE_POKEDATA:
case PTRACE_PEEKUSR:
ret = getreg32(child, addr, &val);
if (ret == 0)
- ret = put_user(val, (__u32 *)(unsigned long) data);
+ ret = put_user(val, (__u32 __user *)datap);
break;
case PTRACE_POKEUSR:
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
- if (!access_ok(VERIFY_WRITE, (unsigned *)(unsigned long)data, 16*4)) {
+ if (!access_ok(VERIFY_WRITE, datap, 16*4)) {
ret = -EIO;
break;
}
ret = 0;
for ( i = 0; i <= 16*4 ; i += sizeof(__u32) ) {
getreg32(child, i, &val);
- ret |= __put_user(val,(u32 *) (unsigned long) data);
- data += sizeof(u32);
+ ret |= __put_user(val,(u32 __user *)datap);
+ datap += sizeof(u32);
}
break;
}
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
unsigned long tmp;
int i;
- if (!access_ok(VERIFY_READ, (unsigned *)(unsigned long)data, 16*4)) {
+ if (!access_ok(VERIFY_READ, datap, 16*4)) {
ret = -EIO;
break;
}
ret = 0;
for ( i = 0; i <= 16*4; i += sizeof(u32) ) {
- ret |= __get_user(tmp, (u32 *) (unsigned long) data);
+ ret |= __get_user(tmp, (u32 __user *)datap);
putreg32(child, i, tmp);
- data += sizeof(u32);
+ datap += sizeof(u32);
}
break;
}
case PTRACE_GETFPREGS:
ret = -EIO;
- if (!access_ok(VERIFY_READ, (void *)(u64)data,
+ if (!access_ok(VERIFY_READ, compat_ptr(data),
sizeof(struct user_i387_struct)))
break;
- save_i387_ia32(child, (void *)(u64)data, childregs, 1);
+ save_i387_ia32(child, datap, childregs, 1);
ret = 0;
break;
case PTRACE_SETFPREGS:
ret = -EIO;
- if (!access_ok(VERIFY_WRITE, (void *)(u64)data,
+ if (!access_ok(VERIFY_WRITE, datap,
sizeof(struct user_i387_struct)))
break;
ret = 0;
/* don't check EFAULT to be bug-to-bug compatible to i386 */
- restore_i387_ia32(child, (void *)(u64)data, 1);
+ restore_i387_ia32(child, datap, 1);
break;
case PTRACE_GETFPXREGS: {
- struct user32_fxsr_struct *u = (void *)(u64)data;
+ struct user32_fxsr_struct __user *u = datap;
init_fpu(child);
ret = -EIO;
if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
break;
}
case PTRACE_SETFPXREGS: {
- struct user32_fxsr_struct *u = (void *)(u64)data;
+ struct user32_fxsr_struct __user *u = datap;
unlazy_fpu(child);
ret = -EIO;
if (!access_ok(VERIFY_READ, u, sizeof(*u)))
#define A(__x) ((unsigned long)(__x))
#define AA(__x) ((unsigned long)(__x))
#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf)
+int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
{
typeof(ubuf->st_uid) uid = 0;
typeof(ubuf->st_gid) gid = 0;
}
asmlinkage long
-sys32_truncate64(char * filename, unsigned long offset_low, unsigned long offset_high)
+sys32_truncate64(char __user * filename, unsigned long offset_low, unsigned long offset_high)
{
return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low);
}
support for 64bit inode numbers. */
static int
-cp_stat64(struct stat64 *ubuf, struct kstat *stat)
+cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
{
typeof(ubuf->st_uid) uid = 0;
typeof(ubuf->st_gid) gid = 0;
}
asmlinkage long
-sys32_stat64(char * filename, struct stat64 *statbuf)
+sys32_stat64(char __user * filename, struct stat64 __user *statbuf)
{
struct kstat stat;
int ret = vfs_stat(filename, &stat);
}
asmlinkage long
-sys32_lstat64(char * filename, struct stat64 *statbuf)
+sys32_lstat64(char __user * filename, struct stat64 __user *statbuf)
{
struct kstat stat;
int ret = vfs_lstat(filename, &stat);
}
asmlinkage long
-sys32_fstat64(unsigned int fd, struct stat64 *statbuf)
+sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf)
{
struct kstat stat;
int ret = vfs_fstat(fd, &stat);
};
asmlinkage long
-sys32_mmap(struct mmap_arg_struct *arg)
+sys32_mmap(struct mmap_arg_struct __user *arg)
{
struct mmap_arg_struct a;
struct file *file = NULL;
}
asmlinkage long
-sys32_pipe(int *fd)
+sys32_pipe(int __user *fd)
{
int retval;
int fds[2];
}
asmlinkage long
-sys32_rt_sigaction(int sig, struct sigaction32 *act,
- struct sigaction32 *oact, unsigned int sigsetsize)
+sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
+ struct sigaction32 __user *oact, unsigned int sigsetsize)
{
struct k_sigaction new_ka, old_ka;
int ret;
}
asmlinkage long
-sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
+sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
}
static inline long
-get_tv32(struct timeval *o, struct compat_timeval *i)
+get_tv32(struct timeval *o, struct compat_timeval __user *i)
{
int err = -EFAULT;
if (access_ok(VERIFY_READ, i, sizeof(*i))) {
}
static inline long
-put_tv32(struct compat_timeval *o, struct timeval *i)
+put_tv32(struct compat_timeval __user *o, struct timeval *i)
{
int err = -EFAULT;
if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
extern struct timezone sys_tz;
asmlinkage long
-sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
if (tv) {
struct timeval ktv;
}
asmlinkage long
-sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
struct timeval ktv;
struct timespec kts;
};
struct getdents32_callback {
- struct linux32_dirent * current_dir;
- struct linux32_dirent * previous;
+ struct linux32_dirent __user * current_dir;
+ struct linux32_dirent __user * previous;
int count;
int error;
};
struct readdir32_callback {
- struct old_linux32_dirent * dirent;
+ struct old_linux32_dirent __user * dirent;
int count;
};
filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
unsigned int d_type)
{
- struct linux32_dirent * dirent;
+ struct linux32_dirent __user * dirent;
struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2, 4);
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
- put_user(d_type, (char *)dirent + reclen - 1);
- dirent = ((void *)dirent) + reclen;
+ put_user(d_type, (char __user *)dirent + reclen - 1);
+ dirent = ((void __user *)dirent) + reclen;
buf->current_dir = dirent;
buf->count -= reclen;
return 0;
}
asmlinkage long
-sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
+sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count)
{
struct file * file;
- struct linux32_dirent * lastdirent;
+ struct linux32_dirent __user * lastdirent;
struct getdents32_callback buf;
int error;
if (!file)
goto out;
- buf.current_dir = (struct linux32_dirent *) dirent;
+ buf.current_dir = (struct linux32_dirent __user *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type)
{
struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
- struct old_linux32_dirent * dirent;
+ struct old_linux32_dirent __user * dirent;
if (buf->count)
return -EINVAL;
}
asmlinkage long
-sys32_oldreaddir (unsigned int fd, void * dirent, unsigned int count)
+sys32_oldreaddir (unsigned int fd, void __user * dirent, unsigned int count)
{
int error;
struct file * file;
};
asmlinkage long
-sys32_old_select(struct sel_arg_struct *arg)
+sys32_old_select(struct sel_arg_struct __user *arg)
{
struct sel_arg_struct a;
* 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)
+asmlinkage long sys32_time(int __user * tloc)
{
int i;
struct timeval tv;
};
asmlinkage long
-sys32_sysinfo(struct sysinfo32 *info)
+sys32_sysinfo(struct sysinfo32 __user *info)
{
struct sysinfo s;
int ret;
}
asmlinkage long
-sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval)
+sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval)
{
struct timespec t;
int ret;
asmlinkage long
-sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
- struct compat_timespec *uts, compat_size_t sigsetsize)
+sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
+ struct compat_timespec __user *uts, compat_size_t sigsetsize)
{
sigset_t s;
compat_sigset_t s32;
}
asmlinkage long
-sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
+sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo)
{
siginfo_t info;
int ret;
asmlinkage long
-sys32_sysctl(struct sysctl_ia32 *args32)
+sys32_sysctl(struct sysctl_ia32 __user *args32)
{
#ifndef CONFIG_SYSCTL
return -ENOSYS;
/* warning: next two assume little endian */
asmlinkage long
-sys32_pread(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
+sys32_pread(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi)
{
return sys_pread64(fd, ubuf, count,
((loff_t)AA(poshi) << 32) | AA(poslo));
}
asmlinkage long
-sys32_pwrite(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi)
+sys32_pwrite(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi)
{
return sys_pwrite64(fd, ubuf, count,
((loff_t)AA(poshi) << 32) | AA(poslo));
}
asmlinkage long
-sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
+sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
{
mm_segment_t old_fs = get_fs();
int ret;
extern int do_adjtimex(struct timex *);
asmlinkage long
-sys32_adjtimex(struct timex32 *utp)
+sys32_adjtimex(struct timex32 __user *utp)
{
struct timex txc;
int ret;
return error;
}
-asmlinkage long sys32_olduname(struct oldold_utsname * name)
+asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
{
int error;
return error;
}
-long sys32_uname(struct old_utsname * name)
+long sys32_uname(struct old_utsname __user * name)
{
int err;
if (!name)
return ret;
}
-asmlinkage long sys32_execve(char *name, compat_uptr_t __user *argv,
+asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs regs)
{
long error;
asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
{
- void *parent_tid = (void *)regs.rdx;
- void *child_tid = (void *)regs.rdi;
+ void __user *parent_tid = (void __user *)regs.rdx;
+ void __user *child_tid = (void __user *)regs.rdi;
if (!newsp)
newsp = regs.rsp;
return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0,
}
-long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
+long sys32_io_setup(unsigned nr_reqs, u32 __user *ctx32p)
{
long ret;
aio_context_t ctx64;
}
asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr,
- compat_uptr_t *iocbpp)
+ compat_uptr_t __user *iocbpp)
{
struct kioctx *ctx;
long ret = 0;
for (i=0; i<nr; i++) {
compat_uptr_t p32;
- struct iocb *user_iocb, tmp;
+ struct iocb __user *user_iocb;
+ struct iocb tmp;
if (unlikely(__get_user(p32, iocbpp + i))) {
ret = -EFAULT;
asmlinkage long sys32_io_getevents(aio_context_t ctx_id,
unsigned long min_nr,
unsigned long nr,
- struct io_event *events,
- struct compat_timespec *timeout)
+ struct io_event __user *events,
+ struct compat_timespec __user *timeout)
{
long ret;
mm_segment_t oldfs;
return ret;
}
-asmlinkage long sys32_open(const char * filename, int flags, int mode)
+asmlinkage long sys32_open(const char __user * filename, int flags, int mode)
{
char * tmp;
int fd, error;
timer_t __user * created_timer_id);
long
-sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
+sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
{
struct sigevent se;
- mm_segment_t oldfs;
- long err;
+ mm_segment_t oldfs;
+ long err;
if (se32) {
memset(&se, 0, sizeof(struct sigevent));
if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
return -EFAULT;
- oldfs = get_fs();
+ oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sys_timer_create(clock, se32 ? &se : NULL, timer_id);
+ err = sys_timer_create(clock, se32 ? &se : NULL, timer_id);
set_fs(oldfs);
return err;
/* Load these always in case some future AMD CPU supports
SYSENTER from compat mode too. */
- wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
- wrmsr(MSR_IA32_SYSENTER_ESP, 0, 0);
- wrmsrl(MSR_IA32_SYSENTER_EIP, ia32_sysenter_target);
+ checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
+ checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL);
+ checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
wrmsrl(MSR_CSTAR, ia32_cstar_target);
}
* Set a given TLS descriptor:
* When you want addresses > 32bit use arch_prctl()
*/
-int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info)
+int do_set_thread_area(struct thread_struct *t, struct user_desc __user *u_info)
{
struct user_desc info;
struct n_desc_struct *desc;
return 0;
}
-asmlinkage long sys32_set_thread_area(struct user_desc *u_info)
+asmlinkage long sys32_set_thread_area(struct user_desc __user *u_info)
{
return do_set_thread_area(¤t->thread, u_info);
}
#define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
#define GET_LONGMODE(desc) (((desc)->b >> 21) & 1)
-int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info)
+int do_get_thread_area(struct thread_struct *t, struct user_desc __user *u_info)
{
struct user_desc info;
struct n_desc_struct *desc;
return 0;
}
-asmlinkage long sys32_get_thread_area(struct user_desc *u_info)
+asmlinkage long sys32_get_thread_area(struct user_desc __user *u_info)
{
return do_get_thread_area(¤t->thread, u_info);
}
int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs)
{
struct n_desc_struct *desc;
- struct user_desc info, *cp;
+ struct user_desc info;
+ struct user_desc __user *cp;
int idx;
- cp = (void *)childregs->rsi;
+ cp = (void __user *)childregs->rsi;
if (copy_from_user(&info, cp, sizeof(info)))
return -EFAULT;
if (LDT_empty(&info))
acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
- printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
}
static int __init acpi_sleep_setup(char *str)
*/
unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;
-extern struct resource code_resource, data_resource, vram_resource;
+extern struct resource code_resource, data_resource;
/* Check for some hardcoded bad areas that early boot is not allowed to touch */
static inline int bad_addr(unsigned long *addrp, unsigned long size)
boot_cpu_data.x86_mask = eax & 0xf;
}
+extern char _end[];
+
void __init x86_64_start_kernel(char * real_mode_data)
{
char *s;
clear_bss();
pda_init(0);
copy_bootdata(real_mode_data);
+#ifdef CONFIG_SMP
+ cpu_set(0, cpu_online_map);
+#endif
/* default console: */
if (!strstr(saved_command_line, "console="))
strcat(saved_command_line, " console=tty0");
if (strstr(saved_command_line, "disableapic"))
disable_apic = 1;
#endif
+ /* You need early console to see that */
+ if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
+ panic("Kernel too big for kernel mapping\n");
+
setup_boot_cpu_data();
start_kernel();
}
* Signal frame handlers.
*/
-int save_i387(struct _fpstate *buf)
+int save_i387(struct _fpstate __user *buf)
{
struct task_struct *tsk = current;
int err = 0;
return 0;
tsk->used_math = 0; /* trigger finit */
if (tsk->thread_info->status & TS_USEDFPU) {
- err = save_i387_checking((struct i387_fxsave_struct *)buf);
+ err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
if (err) return err;
stts();
} else {
* ptrace request handlers.
*/
-int get_fpregs(struct user_i387_struct *buf, struct task_struct *tsk)
+int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *tsk)
{
init_fpu(tsk);
- return __copy_to_user((void *)buf, &tsk->thread.i387.fxsave,
+ return __copy_to_user(buf, &tsk->thread.i387.fxsave,
sizeof(struct user_i387_struct)) ? -EFAULT : 0;
}
-int set_fpregs(struct task_struct *tsk, struct user_i387_struct *buf)
+int set_fpregs(struct task_struct *tsk, struct user_i387_struct __user *buf)
{
if (__copy_from_user(&tsk->thread.i387.fxsave, buf,
sizeof(struct user_i387_struct)))
#include <linux/init.h>
#include <linux/init_task.h>
#include <linux/fs.h>
+#include <linux/mqueue.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
switch (vendor) {
case PCI_VENDOR_ID_VIA:
#ifdef CONFIG_GART_IOMMU
- if (end_pfn >= (0xffffffff>>PAGE_SHIFT) &&
+ if ((end_pfn >= (0xffffffff>>PAGE_SHIFT) ||
+ force_iommu) &&
!iommu_aperture_allowed) {
printk(KERN_INFO
"Looks like a VIA chipset. Disabling IOMMU. Overwrite with \"iommu=allowed\"\n");
return len;
}
-static int irq_affinity_write_proc (struct file *file, const char *buffer,
+static int irq_affinity_write_proc (struct file *file,
+ const char __user *buffer,
unsigned long count, void *data)
{
int irq = (long) data, full_count = count, err;
return len;
}
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+static int prof_cpu_mask_write_proc (struct file *file,
+ const char __user *buffer,
unsigned long count, void *data)
{
unsigned long full_count = count, err;
}
}
-static int read_ldt(void * ptr, unsigned long bytecount)
+static int read_ldt(void __user * ptr, unsigned long bytecount)
{
int err;
unsigned long size;
return bytecount;
}
-static int read_default_ldt(void * ptr, unsigned long bytecount)
+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
{
/* Arbitrary number */
/* x86-64 default LDT is all zeros */
return bytecount;
}
-static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
+static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
{
struct task_struct *me = current;
struct mm_struct * mm = me->mm;
return error;
}
-asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
{
int ret = -ENOSYS;
#define NR_BANKS 5
static int mce_disabled __initdata;
-/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic */
-static int tolerant = 2;
+/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic,
+ 3: never panic or exit (for testing only) */
+static int tolerant = 1;
static int banks;
static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
int i;
oops_begin();
for (i = 0; i < MCE_LOG_LEN; i++) {
- if (mcelog.entry[i].tsc < start)
+ unsigned long tsc = mcelog.entry[i].tsc;
+ if (time_before(tsc, start))
continue;
print_mce(&mcelog.entry[i]);
if (mcelog.entry[i].tsc == backup->tsc)
}
if (backup)
print_mce(backup);
- panic(msg);
+ if (tolerant >= 3)
+ printk("Fake panic: %s\n", msg);
+ else
+ panic(msg);
}
static int mce_available(struct cpuinfo_x86 *c)
void do_machine_check(struct pt_regs * regs, long error_code)
{
- struct mce m;
- int nowayout = 0;
+ struct mce m, panicm;
+ int nowayout = (tolerant < 1);
int kill_it = 0;
u64 mcestart;
int i;
for (i = 0; i < banks; i++) {
if (!bank[i])
continue;
+
+ m.misc = 0;
+ m.addr = 0;
rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status);
if ((m.status & MCI_STATUS_VAL) == 0)
continue;
+ /* Should be implied by the banks check above, but
+ check it anyways */
+ if ((m.status & MCI_STATUS_EN) == 0)
+ continue;
- nowayout |= (tolerant < 1);
- nowayout |= !!(m.status & (MCI_STATUS_OVER|MCI_STATUS_PCC));
+ /* Did this bank cause the exception? */
+ /* Assume that the bank with uncorrectable errors did it,
+ and that there is only a single one. */
+ if (m.status & MCI_STATUS_UC) {
+ panicm = m;
+ } else {
+ m.rip = 0;
+ m.cs = 0;
+ }
+
+ /* In theory _OVER could be a nowayout too, but
+ assume any overflowed errors were no fatal. */
+ nowayout |= !!(m.status & MCI_STATUS_PCC);
kill_it |= !!(m.status & MCI_STATUS_UC);
m.bank = i;
if (nowayout)
mce_panic("Machine check", &m, mcestart);
if (kill_it) {
- int user_space = (m.rip && (m.cs & 3));
+ int user_space = 0;
+
+ if (m.mcgstatus & MCG_STATUS_RIPV)
+ user_space = m.rip && (m.cs & 3);
/* When the machine was in user space and the CPU didn't get
confused it's normally not necessary to panic, unless you
it is best to just halt the machine. */
if ((!user_space && (panic_on_oops || tolerant < 2)) ||
(unsigned)current->pid <= 1)
- mce_panic("Uncorrected machine check", &m, mcestart);
+ mce_panic("Uncorrected machine check", &panicm, mcestart);
/* do_exit takes an awful lot of locks and has as slight risk
of deadlocking. If you don't want that don't set tolerant >= 2 */
- do_exit(SIGBUS);
+ if (tolerant < 3)
+ do_exit(SIGBUS);
}
}
* Periodic polling timer for "silent" machine check errors.
*/
-static int check_interval = 3600; /* one hour */
+static int check_interval = 5 * 60; /* 5 minutes */
static void mcheck_timer(void *data);
static DECLARE_WORK(mcheck_work, mcheck_timer, NULL);
rdtscll(cpu_tsc[smp_processor_id()]);
}
-static ssize_t mce_read(struct file *filp, char *ubuf, size_t usize, loff_t *off)
+static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off)
{
unsigned long cpu_tsc[NR_CPUS];
static DECLARE_MUTEX(mce_read_sem);
unsigned next;
- char *buf = ubuf;
+ char __user *buf = ubuf;
int i, err;
down(&mce_read_sem);
static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, unsigned long arg)
{
+ int __user *p = (int __user *)arg;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
switch (cmd) {
case MCE_GET_RECORD_LEN:
- return put_user(sizeof(struct mce), (int *)arg);
+ return put_user(sizeof(struct mce), p);
case MCE_GET_LOG_LEN:
- return put_user(MCE_LOG_LEN, (int *)arg);
+ return put_user(MCE_LOG_LEN, p);
case MCE_GETCLEAR_FLAGS: {
unsigned flags;
do {
flags = mcelog.flags;
} while (cmpxchg(&mcelog.flags, flags, 0) != flags);
- return put_user(flags, (int *)arg);
+ return put_user(flags, p);
}
default:
return -ENOTTY;
extern void __bad_mpf_size(void);
unsigned int *bp = phys_to_virt(base);
struct intel_mp_floating *mpf;
+ static int printed __initdata;
Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
if (sizeof(*mpf) != 16)
bp += 4;
length -= 16;
}
- printk(KERN_INFO "No mptable found.\n");
+ if (!printed) {
+ printk(KERN_INFO "No mptable found.\n");
+ printed = 1;
+ }
return 0;
}
} mp_ioapic_routing[MAX_IO_APICS];
-static int __init mp_find_ioapic (
+static int mp_find_ioapic (
int gsi)
{
int i = 0;
for (idx = 0; idx < mp_irq_entries; idx++)
if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+ (mp_irqs[idx].mpc_dstapic == ioapic) &&
(mp_irqs[idx].mpc_srcbusirq == i ||
mp_irqs[idx].mpc_dstirq == i))
break;
return;
}
-
-extern FADT_DESCRIPTOR acpi_fadt;
-
-#ifdef CONFIG_ACPI_PCI
-
-void __init mp_parse_prt (void)
+void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
{
- struct list_head *node = NULL;
- struct acpi_prt_entry *entry = NULL;
int ioapic = -1;
int ioapic_pin = 0;
- int gsi = 0;
int idx, bit = 0;
- int edge_level = 0;
- int active_high_low = 0;
- /*
- * Parsing through the PCI Interrupt Routing Table (PRT) and program
- * routing for all static (IOAPIC-direct) entries.
- */
- list_for_each(node, &acpi_prt.entries) {
- entry = list_entry(node, struct acpi_prt_entry, node);
-
- /* Need to get gsi for dynamic entry */
- if (entry->link.handle) {
- gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
- if (!gsi)
- continue;
- } else {
- /* Hardwired GSI. Assume PCI standard settings */
- gsi = entry->link.index;
- edge_level = 1;
- active_high_low = 1;
- }
+ if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
+ return;
- /* Don't set up the ACPI SCI because it's already set up */
- if (acpi_fadt.sci_int == gsi) {
- /* we still need to set up the entry's irq */
- acpi_gsi_to_irq(gsi, &entry->irq);
- continue;
- }
+#ifdef CONFIG_ACPI_BUS
+ /* Don't set up the ACPI SCI because it's already set up */
+ if (acpi_fadt.sci_int == gsi)
+ return;
+#endif
- ioapic = mp_find_ioapic(gsi);
- if (ioapic < 0)
- continue;
- ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
+ ioapic = mp_find_ioapic(gsi);
+ if (ioapic < 0) {
+ printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
+ return;
+ }
- /*
- * Avoid pin reprogramming. PRTs typically include entries
- * with redundant pin->gsi mappings (but unique PCI devices);
- * we only only program the IOAPIC on the first.
- */
- bit = ioapic_pin % 32;
- idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
- if (idx > 3) {
- printk(KERN_ERR "Invalid reference to IOAPIC pin "
- "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
- ioapic_pin);
- continue;
- }
- if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
- Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
- mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
- acpi_gsi_to_irq(gsi, &entry->irq);
- continue;
- }
+ ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
- mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
- if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) {
- acpi_gsi_to_irq(gsi, &entry->irq);
- }
- printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
- entry->id.segment, entry->id.bus,
- entry->id.device, ('A' + entry->pin),
- mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
- entry->irq);
+ /*
+ * Avoid pin reprogramming. PRTs typically include entries
+ * with redundant pin->gsi mappings (but unique PCI devices);
+ * we only program the IOAPIC on the first.
+ */
+ bit = ioapic_pin % 32;
+ idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
+ if (idx > 3) {
+ printk(KERN_ERR "Invalid reference to IOAPIC pin "
+ "%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
+ ioapic_pin);
+ return;
+ }
+ if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+ Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
+ mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+ return;
}
-
- print_IO_APIC();
- return;
-}
+ mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
-#endif /*CONFIG_ACPI_PCI*/
+ io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
+ edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
+ active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+}
#endif /*CONFIG_X86_IO_APIC*/
-
#endif /*CONFIG_ACPI_BOOT*/
return ret;
}
-static ssize_t msr_read(struct file * file, char * buf,
+static ssize_t msr_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
- u32 *tmp = (u32 *)buf;
+ char __user *tmp = buf;
u32 data[2];
size_t rv;
u32 reg = *ppos;
return err;
if ( copy_to_user(tmp,&data,8) )
return -EFAULT;
- tmp += 2;
+ tmp += 8;
}
- return ((char *)tmp) - buf;
+ return tmp - buf;
}
-static ssize_t msr_write(struct file * file, const char * buf,
+static ssize_t msr_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
- const u32 *tmp = (const u32 *)buf;
+ const char __user *tmp = buf;
u32 data[2];
size_t rv;
u32 reg = *ppos;
err = do_wrmsr(cpu, reg, data[0], data[1]);
if ( err )
return err;
- tmp += 2;
+ tmp += 8;
}
- return ((char *)tmp) - buf;
+ return tmp - buf;
}
static int msr_open(struct inode *inode, struct file *file)
int cpu = iminor(file->f_dentry->d_inode);
struct cpuinfo_x86 *c = &(cpu_data)[cpu];
- if (!cpu_online(cpu))
+ if (cpu >= NR_CPUS || !cpu_online(cpu))
return -ENXIO; /* No such CPU */
if ( !cpu_has(c, X86_FEATURE_MSR) )
return -EIO; /* MSR not supported */
* sys_execve() executes a new program.
*/
asmlinkage
-long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
+long sys_execve(char __user *name, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs regs)
{
long error;
char * filename;
return do_fork(SIGCHLD, regs.rsp, ®s, 0, NULL, NULL);
}
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *parent_tid, void *child_tid, struct pt_regs regs)
+asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, struct pt_regs regs)
{
if (!newsp)
newsp = regs.rsp;
rdmsrl(MSR_FS_BASE, base);
} else
base = task->thread.fs;
- ret = put_user(base, (unsigned long *)addr);
+ ret = put_user(base, (unsigned long __user *)addr);
break;
}
case ARCH_GET_GS: {
rdmsrl(MSR_KERNEL_GS_BASE, base);
} else
base = task->thread.gs;
- ret = put_user(base, (unsigned long *)addr);
+ ret = put_user(base, (unsigned long __user *)addr);
break;
}
ret = -EIO;
if (copied != sizeof(tmp))
break;
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp,(unsigned long __user *) data);
break;
}
tmp = 0;
break;
}
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp,(unsigned long __user *) data);
break;
}
don't use it against 64bit processes, use
PTRACE_ARCH_PRCTL instead. */
case PTRACE_SET_THREAD_AREA: {
+ struct user_desc __user *p;
int old;
- get_user(old, &((struct user_desc *)data)->entry_number);
- put_user(addr, &((struct user_desc *)data)->entry_number);
- ret = do_set_thread_area(&child->thread,
- (struct user_desc *)data);
- put_user(old, &((struct user_desc *)data)->entry_number);
+ p = (struct user_desc __user *)data;
+ get_user(old, &p->entry_number);
+ put_user(addr, &p->entry_number);
+ ret = do_set_thread_area(&child->thread, p);
+ put_user(old, &p->entry_number);
break;
case PTRACE_GET_THREAD_AREA:
- get_user(old, &((struct user_desc *)data)->entry_number);
- put_user(addr, &((struct user_desc *)data)->entry_number);
- ret = do_get_thread_area(&child->thread,
- (struct user_desc *)data);
- put_user(old, &((struct user_desc *)data)->entry_number);
+ p = (struct user_desc __user *)data;
+ get_user(old, &p->entry_number);
+ put_user(addr, &p->entry_number);
+ ret = do_get_thread_area(&child->thread, p);
+ put_user(old, &p->entry_number);
break;
}
#endif
break;
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
- if (!access_ok(VERIFY_WRITE, (unsigned *)data, FRAME_SIZE)) {
+ if (!access_ok(VERIFY_WRITE, (unsigned __user *)data, FRAME_SIZE)) {
ret = -EIO;
break;
}
for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
- __put_user(getreg(child, ui),(unsigned long *) data);
+ __put_user(getreg(child, ui),(unsigned long __user *) data);
data += sizeof(long);
}
ret = 0;
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
unsigned long tmp;
- if (!access_ok(VERIFY_READ, (unsigned *)data, FRAME_SIZE)) {
+ if (!access_ok(VERIFY_READ, (unsigned __user *)data, FRAME_SIZE)) {
ret = -EIO;
break;
}
for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) {
- __get_user(tmp, (unsigned long *) data);
+ __get_user(tmp, (unsigned long __user *) data);
putreg(child, ui, tmp);
data += sizeof(long);
}
}
case PTRACE_GETFPREGS: { /* Get the child extended FPU state. */
- if (!access_ok(VERIFY_WRITE, (unsigned *)data,
+ if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
sizeof(struct user_i387_struct))) {
ret = -EIO;
break;
}
- ret = get_fpregs((struct user_i387_struct *)data, child);
+ ret = get_fpregs((struct user_i387_struct __user *)data, child);
break;
}
case PTRACE_SETFPREGS: { /* Set the child extended FPU state. */
- if (!access_ok(VERIFY_READ, (unsigned *)data,
+ if (!access_ok(VERIFY_READ, (unsigned __user *)data,
sizeof(struct user_i387_struct))) {
ret = -EIO;
break;
}
child->used_math = 1;
- ret = set_fpregs(child, (struct user_i387_struct *)data);
+ ret = set_fpregs(child, (struct user_i387_struct __user *)data);
break;
}
#define STANDARD_IO_RESOURCES \
(sizeof standard_io_resources / sizeof standard_io_resources[0])
-struct resource code_resource = { "Kernel code", 0x100000, 0, IORESOURCE_MEM };
-struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_MEM };
-struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY | IORESOURCE_MEM };
+#define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM)
+
+struct resource data_resource = { "Kernel data", 0, 0, IORESOURCE_RAM };
+struct resource code_resource = { "Kernel code", 0, 0, IORESOURCE_RAM };
#define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM)
(sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
static struct resource video_rom_resource = { "Video ROM", 0xc0000, 0xc7fff, IORESOURCE_ROM };
+static struct resource video_ram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_RAM };
#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
-static int __init checksum(unsigned char *rom, unsigned long length)
+static int __init romchecksum(unsigned char *rom, unsigned long length)
{
unsigned char *p, sum = 0;
length = rom[2] * 512;
/* if checksum okay, trust length byte */
- if (length && checksum(rom, length))
+ if (length && romchecksum(rom, length))
video_rom_resource.end = start + length - 1;
request_resource(&iomem_resource, &video_rom_resource);
rom = isa_bus_to_virt(extension_rom_resource.start);
if (romsignature(rom)) {
length = extension_rom_resource.end - extension_rom_resource.start + 1;
- if (checksum(rom, length)) {
+ if (romchecksum(rom, length)) {
request_resource(&iomem_resource, &extension_rom_resource);
upper = extension_rom_resource.start;
}
length = rom[2] * 512;
/* but accept any length that fits if checksum okay */
- if (!length || start + length > upper || !checksum(rom, length))
+ if (!length || start + length > upper || !romchecksum(rom, length))
continue;
adapter_rom_resources[i].start = start;
/* acpi=ht just means: do ACPI MADT parsing
at bootup, but don't enable the full ACPI interpreter */
if (!memcmp(from, "acpi=ht", 7)) {
+ /* if (!acpi_force) */
+ disable_acpi();
acpi_ht = 1;
}
else if (!memcmp(from, "pci=noacpi", 10))
* the bootmem allocator) but before get_smp_config (to allow parsing
* of MADT).
*/
- if (!acpi_disabled)
- acpi_boot_init();
+ acpi_boot_init();
#endif
#ifdef CONFIG_X86_LOCAL_APIC
/*
probe_roms();
e820_reserve_resources();
- request_resource(&iomem_resource, &vram_resource);
+ request_resource(&iomem_resource, &video_ram_resource);
{
unsigned i;
/* request I/O space for devices used on all i[345]86 PCs */
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
- request_resource(&ioport_resource, standard_io_resources+i);
+ request_resource(&ioport_resource, &standard_io_resources[i]);
}
/* Will likely break when you have unassigned resources with more
c->x86_model += ((tfms >> 16) & 0xF) << 4;
}
if (c->x86_capability[0] & (1<<19))
- c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
+ c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
} else {
/* Have CPUID level 0 only - unheard of */
c->x86 = 4;
display_cacheinfo(c);
break;
}
-
+
select_idle_routine(c);
detect_ht(c);
extern struct desc_ptr cpu_gdt_descr[];
struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table };
-char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned;
+char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
unsigned long __supported_pte_mask = ~0UL;
static int do_not_nx __initdata = 0;
pda->irqstackptr += IRQSTACKSIZE-64;
}
-char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ];
+char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ]
+__attribute__((section(".bss.page_aligned")));
void __init syscall_init(void)
{
sigset_t *set, struct pt_regs * regs);
asmlinkage long
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs regs)
{
sigset_t saveset, newset;
current->blocked = newset;
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
saveset, newset, ®s, regs.rip);
#endif
}
asmlinkage long
-sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs regs)
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs regs)
{
return do_sigaltstack(uss, uoss, regs.rsp);
}
};
static int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *prax)
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned long *prax)
{
unsigned int err = 0;
}
{
- struct _fpstate * buf;
+ struct _fpstate __user * buf;
err |= __get_user(buf, &sc->fpstate);
if (buf) {
asmlinkage long sys_rt_sigreturn(struct pt_regs regs)
{
- struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 8);
+ struct rt_sigframe __user *frame;
sigset_t set;
long eax;
+ frame = (struct rt_sigframe __user *)(regs.rsp - 8);
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) {
goto badframe;
}
goto badframe;
}
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax);
#endif
*/
static inline int
-setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
+setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me)
{
int err = 0;
* Determine which stack to use..
*/
-static void *
+static void __user *
get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
{
unsigned long rsp;
rsp = current->sas_ss_sp + current->sas_ss_size;
}
- return (void *)round_down(rsp - size, 16);
+ return (void __user *)round_down(rsp - size, 16);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
{
- struct rt_sigframe *frame;
- struct _fpstate *fp = NULL;
+ struct rt_sigframe __user *frame;
+ struct _fpstate __user *fp = NULL;
int err = 0;
struct task_struct *me = current;
if (me->used_math) {
fp = get_stack(ka, regs, sizeof(struct _fpstate));
- frame = (void *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8;
+ frame = (void __user *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8;
if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) {
goto give_sigsegv;
goto give_sigsegv;
}
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax);
#endif
set_fs(USER_DS);
regs->eflags &= ~TF_MASK;
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
current->comm, current->pid, frame, regs->rip, frame->pretcode);
#endif
{
struct k_sigaction *ka = ¤t->sighand->action[sig-1];
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig,
regs->rip, regs->rsp, regs);
#endif
void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_flags)
{
-#if DEBUG_SIG
+#ifdef DEBUG_SIG
printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n",
thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current));
#endif
do_signal(regs,oldset);
}
-void signal_fault(struct pt_regs *regs, void *frame, char *where)
+void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
{
struct task_struct *me = current;
if (exception_trace)
cpu_set(i, cpu_sibling_map[cpu]);
}
}
- } else {
+ } else {
siblings++;
cpu_set(cpu, cpu_sibling_map[cpu]);
}
- if (siblings != smp_num_siblings)
- printk(KERN_WARNING
- "WARNING: %d siblings found for CPU%d, should be %d\n",
+ if (siblings != smp_num_siblings) {
+ printk(KERN_WARNING
+ "WARNING: %d siblings found for CPU%d, should be %d\n",
siblings, cpu, smp_num_siblings);
+ smp_num_siblings = siblings;
+ }
}
Dprintk("Boot done.\n");
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way Unix traditionally does this, though.
*/
-asmlinkage long sys_pipe(int *fildes)
+asmlinkage long sys_pipe(int __user *fildes)
{
int fd[2];
int error;
}
}
-asmlinkage long sys_uname(struct new_utsname * name)
+asmlinkage long sys_uname(struct new_utsname __user * name)
{
int err;
down_read(&uts_sem);
return err ? -EFAULT : 0;
}
-asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg)
+asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
{
unsigned long raddr;
return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
}
-asmlinkage long sys_time64(long * tloc)
+asmlinkage long sys_time64(long __user * tloc)
{
struct timeval now;
int i;
if (__get_user(tmp, f.filename))
f.filename = "unmapped filename";
printk("----------- [cut here ] --------- [please bite here ] ---------\n");
- printk("Kernel BUG at %.50s:%d\n", f.filename, f.line);
+ printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line);
}
void out_of_line_bug(void)
notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
show_registers(regs);
/* Executive summary in case the oops scrolled away */
- printk("RIP ");
+ printk(KERN_ALERT "RIP ");
printk_address(regs->rip);
printk(" RSP <%016lx>\n", regs->rsp);
}
__bss_start = .; /* BSS */
.bss : {
+ *(.bss.page_aligned)
*(.bss)
}
__bss_end = .;
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }
- . = ALIGN(4096);
- .data.boot_pgt : { *(.data.boot_pgt) }
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.page_aligned) }
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
#endif
EXPORT_SYMBOL(sys_ioctl);
-
-EXPORT_SYMBOL(memcpy_toio);
-EXPORT_SYMBOL(memcpy_fromio);
CFLAGS_csum-partial.o := -funroll-loops
+obj-y := io.o
+
lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
usercopy.o getuser.o putuser.o \
- thunk.o io.o clear_page.o copy_page.o bitstr.o
+ thunk.o clear_page.o copy_page.o bitstr.o
lib-y += memcpy.o memmove.o memset.o copy_user.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
* src and dst are best aligned to 64bits.
*/
unsigned int
-csum_partial_copy_from_user(const char *src, char *dst,
+csum_partial_copy_from_user(const char __user *src, char *dst,
int len, unsigned int isum, int *errp)
{
*errp = 0;
if (unlikely((unsigned long)src & 6)) {
while (((unsigned long)src & 6) && len >= 2) {
__u16 val16;
- *errp = __get_user(val16, (__u16 *)src);
+ *errp = __get_user(val16, (__u16 __user *)src);
if (*errp)
return isum;
*(__u16 *)dst = val16;
len -= 2;
}
}
- isum = csum_partial_copy_generic(src,dst,len,isum,errp,NULL);
+ isum = csum_partial_copy_generic((void *)src,dst,len,isum,errp,NULL);
if (likely(*errp == 0))
return isum;
}
* src and dst are best aligned to 64bits.
*/
unsigned int
-csum_partial_copy_to_user(const char *src, char *dst,
+csum_partial_copy_to_user(const char *src, char __user *dst,
int len, unsigned int isum, int *errp)
{
if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
while (((unsigned long)dst & 6) && len >= 2) {
__u16 val16 = *(__u16 *)src;
isum = add32_with_carry(isum, val16);
- *errp = __put_user(val16, (__u16 *)dst);
+ *errp = __put_user(val16, (__u16 __user *)dst);
if (*errp)
return isum;
src += 2;
}
*errp = 0;
- return csum_partial_copy_generic(src,dst,len,isum,NULL,errp);
+ return csum_partial_copy_generic(src, (void *)dst,len,isum,NULL,errp);
}
EXPORT_SYMBOL(csum_partial_copy_to_user);
#include <asm/io.h>
#include <linux/module.h>
-void *memcpy_toio(void *dst,const void*src,unsigned len)
+void *__memcpy_toio(unsigned long dst,const void*src,unsigned len)
{
- return __inline_memcpy(dst,src,len);
+ return __inline_memcpy((void *) dst,src,len);
}
+EXPORT_SYMBOL(__memcpy_toio);
-void *memcpy_fromio(void *dst,const void*src,unsigned len)
+void *__memcpy_fromio(void *dst,unsigned long src,unsigned len)
{
- return __inline_memcpy(dst,src,len);
+ return __inline_memcpy(dst,(const void *) src,len);
}
+EXPORT_SYMBOL(__memcpy_fromio);
} while (0)
long
-__strncpy_from_user(char *dst, const char *src, long count)
+__strncpy_from_user(char *dst, const char __user *src, long count)
{
long res;
__do_strncpy_from_user(dst, src, count, res);
}
long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
* Zero Userspace
*/
-unsigned long __clear_user(void *addr, unsigned long size)
+unsigned long __clear_user(void __user *addr, unsigned long size)
{
long __d0;
/* no memory constraint because it doesn't change any memory gcc knows
}
-unsigned long clear_user(void *to, unsigned long n)
+unsigned long clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
return __clear_user(to, n);
* Return 0 on exception, a value greater than N if too long
*/
-long strnlen_user(const char *s, long n)
+long strnlen_user(const char __user *s, long n)
{
long res = 0;
char c;
}
}
-long strlen_user(const char *s)
+long strlen_user(const char __user *s)
{
long res = 0;
char c;
}
}
-unsigned long copy_in_user(void *to, const void *from, unsigned len)
+unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
{
if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
- return copy_user_generic(to, from, len);
+ return copy_user_generic((void *)to, (void *)from, len);
}
return len;
}
int unhandled_signal(struct task_struct *tsk, int sig)
{
/* Warn for strace, but not for gdb */
- if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYSGOOD)) == PT_PTRACED)
+ if (!test_ti_thread_flag(tsk->thread_info, TIF_SYSCALL_TRACE) &&
+ (tsk->ptrace & PT_PTRACED))
return 0;
return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
(tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
(address >> 32))
return;
- if (exception_trace && !unhandled_signal(tsk, SIGSEGV)) {
+ if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
printk(KERN_INFO
"%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
tsk->comm, tsk->pid, address, regs->rip,
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
else
printk(KERN_ALERT "Unable to handle kernel paging request");
- printk(" at %016lx RIP: \n",address);
+ printk(" at %016lx RIP: \n" KERN_ALERT,address);
printk_address(regs->rip);
+ printk("\n");
dump_pagetable(address);
__die("Oops", regs, error_code);
/* Executive summary in case the body of the oops scrolled away */
/* Should check here against the e820 map to avoid double free */
#ifdef CONFIG_DISCONTIGMEM
int nid = phys_to_nid(phys);
- if (phys < HIGH_MEMORY && nid)
- panic("reserve of %lx at node %d", phys, nid);
- reserve_bootmem_node(NODE_DATA(nid), phys, len);
+ reserve_bootmem_node(NODE_DATA(nid), phys, len);
#else
reserve_bootmem(phys, len);
#endif
area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
+ area->phys_addr = phys_addr;
addr = area->addr;
if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
vunmap(addr);
start_pfn = node_start_pfn(nodeid);
end_pfn = node_end_pfn(nodeid);
- printk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn);
+ Dprintk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn);
/* All nodes > 0 have a zero length zone DMA */
dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT;
numnodes = 1;
for (i = 0; i < NR_CPUS; i++)
cpu_to_node[i] = 0;
- node_to_cpumask[0] = 1;
+ node_to_cpumask[0] = cpumask_of_cpu(0);
setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
}
return pte;
}
-static struct page *split_large_page(unsigned long address, pgprot_t prot)
+static struct page *split_large_page(unsigned long address, pgprot_t prot,
+ pgprot_t ref_prot)
{
int i;
unsigned long addr;
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);
+ addr == address ? prot : ref_prot);
}
return base;
}
* No more special protections in this 2/4MB area - revert to a
* large page again.
*/
-static void revert_page(struct page *kpte_page, unsigned long address)
+static void revert_page(unsigned long address, pgprot_t ref_prot)
{
pgd_t *pgd;
pmd_t *pmd;
pgd = pgd_offset_k(address);
pmd = pmd_offset(pgd, address);
BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
- large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE);
+ pgprot_val(ref_prot) |= _PAGE_PSE;
+ large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
set_pte((pte_t *)pmd, large_pte);
}
static int
-__change_page_attr(unsigned long address, struct page *page, pgprot_t prot)
+__change_page_attr(unsigned long address, struct page *page, pgprot_t prot,
+ pgprot_t ref_prot)
{
pte_t *kpte;
struct page *kpte_page;
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 (pgprot_val(prot) != pgprot_val(ref_prot)) {
if ((kpte_flags & _PAGE_PSE) == 0) {
pte_t old = *kpte;
- pte_t standard = mk_pte(page, PAGE_KERNEL);
+ pte_t standard = mk_pte(page, ref_prot);
set_pte(kpte, mk_pte(page, prot));
if (pte_same(old,standard))
get_page(kpte_page);
} else {
- struct page *split = split_large_page(address, prot);
+ struct page *split = split_large_page(address, prot, ref_prot);
if (!split)
return -ENOMEM;
get_page(kpte_page);
- set_pte(kpte,mk_pte(split, PAGE_KERNEL));
+ set_pte(kpte,mk_pte(split, ref_prot));
}
} else if ((kpte_flags & _PAGE_PSE) == 0) {
- set_pte(kpte, mk_pte(page, PAGE_KERNEL));
+ set_pte(kpte, mk_pte(page, ref_prot));
__put_page(kpte_page);
}
if (page_count(kpte_page) == 1) {
save_page(address, kpte_page);
- revert_page(kpte_page, address);
+ revert_page(address, ref_prot);
}
return 0;
}
down_write(&init_mm.mmap_sem);
for (i = 0; i < numpages; !err && i++, page++) {
unsigned long address = (unsigned long)page_address(page);
- err = __change_page_attr(address, page, prot);
+ err = __change_page_attr(address, page, prot, PAGE_KERNEL);
if (err)
break;
- /* Handle kernel mapping too which aliases part of the lowmem */
- if (page_to_phys(page) < KERNEL_TEXT_SIZE) {
- unsigned long addr2 = __START_KERNEL_map + page_to_phys(page);
- err = __change_page_attr(addr2, page, prot);
+ /* Handle kernel mapping too which aliases part of the
+ * lowmem */
+ /* Disabled right now. Fixme */
+ if (0 && page_to_phys(page) < KERNEL_TEXT_SIZE) {
+ unsigned long addr2;
+ addr2 = __START_KERNEL_map + page_to_phys(page);
+ err = __change_page_attr(addr2, page, prot,
+ PAGE_KERNEL_EXEC);
}
}
up_write(&init_mm.mmap_sem);
struct scatterlist *sg, unsigned int nsg)
{
unsigned int i;
-
+
for (i = 0; i < nsg; i++) {
- char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
- tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
- p, sg[i].length);
- crypto_kunmap(p, 0);
- crypto_yield(tfm);
+
+ struct page *pg = sg[i].page;
+ unsigned int offset = sg[i].offset;
+ unsigned int l = sg[i].length;
+
+ do {
+ unsigned int bytes_from_page = min(l, ((unsigned int)
+ (PAGE_SIZE)) -
+ offset);
+ char *p = crypto_kmap(pg, 0) + offset;
+
+ tfm->__crt_alg->cra_digest.dia_update
+ (crypto_tfm_ctx(tfm), p,
+ bytes_from_page);
+ crypto_kunmap(p, 0);
+ crypto_yield(tfm);
+ offset = 0;
+ pg++;
+ l -= bytes_from_page;
+ } while (l > 0);
}
}
(TSC) timing source.
So, if you see messages like 'Losing too many ticks!' in the
- kernel logs, and/or you are using a this on a notebook which
+ kernel logs, and/or you are using this on a notebook which
does not yet have an HPET, you should say "Y" here.
endmenu
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/acpi.h>
-#ifdef CONFIG_X86_IO_APIC
-#include <asm/mpspec.h>
-#endif
-#ifdef CONFIG_IOSAPIC
-# include <asm/iosapic.h>
-#endif
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
struct acpi_prt_list acpi_prt;
-#ifdef CONFIG_X86
-extern void eisa_set_level_irq(unsigned int irq);
-#endif
-
/* --------------------------------------------------------------------------
PCI IRQ Routing Table (PRT) Support
PCI Interrupt Routing Support
-------------------------------------------------------------------------- */
-int
-acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
+static int
+acpi_pci_irq_lookup (
+ struct pci_bus *bus,
+ int device,
+ int pin,
+ int *edge_level,
+ int *active_high_low)
{
struct acpi_prt_entry *entry = NULL;
int segment = pci_domain_nr(bus);
int bus_nr = bus->number;
+ int irq;
ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
return_VALUE(0);
}
-
- if (!entry->irq && entry->link.handle) {
- entry->irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, NULL, NULL);
- if (!entry->irq) {
+
+ if (entry->link.handle) {
+ irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low);
+ if (!irq) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
return_VALUE(0);
}
- }
- else if (!entry->irq) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid static routing entry (IRQ 0)\n"));
- return_VALUE(0);
+ } else {
+ irq = entry->link.index;
+ *edge_level = ACPI_LEVEL_SENSITIVE;
+ *active_high_low = ACPI_ACTIVE_LOW;
}
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", entry->irq));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
- return_VALUE(entry->irq);
+ return_VALUE(irq);
}
static int
acpi_pci_irq_derive (
struct pci_dev *dev,
- int pin)
+ int pin,
+ int *edge_level,
+ int *active_high_low)
{
struct pci_dev *bridge = dev;
int irq = 0;
pin = bridge_pin;
}
- irq = acpi_pci_irq_lookup(bridge->bus,
- PCI_SLOT(bridge->devfn), pin);
+ irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
+ pin, edge_level, active_high_low);
}
if (!irq) {
{
int irq = 0;
u8 pin = 0;
+ int edge_level = ACPI_LEVEL_SENSITIVE;
+ int active_high_low = ACPI_ACTIVE_LOW;
ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
* First we check the PCI IRQ routing table (PRT) for an IRQ. PRT
* values override any BIOS-assigned IRQs set during boot.
*/
- irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin);
+ irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, &edge_level, &active_high_low);
/*
* If no PRT entry was found, we'll try to derive an IRQ from the
* device's parent bridge.
*/
if (!irq)
- irq = acpi_pci_irq_derive(dev, pin);
+ irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low);
/*
* No IRQ known to the ACPI subsystem - maybe the BIOS /
* driver reported one, then use it. Exit in any case.
*/
if (!irq) {
- printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), pci_name(dev));
+ printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI",
+ pci_name(dev), ('A' + pin));
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq);
}
}
- dev->irq = irq;
+ dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %s using IRQ %d\n", pci_name(dev), dev->irq));
-
- /*
- * Make sure all (legacy) PCI IRQs are set as level-triggered.
- */
-#ifdef CONFIG_X86
- {
- static u16 irq_mask;
- if ((dev->irq < 16) && !((1 << dev->irq) & irq_mask)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Setting IRQ %d as level-triggered\n", dev->irq));
- irq_mask |= (1 << dev->irq);
- eisa_set_level_irq(dev->irq);
- }
- }
-#endif
-#ifdef CONFIG_IOSAPIC
- if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC)
- iosapic_enable_intr(dev->irq);
-#endif
+ printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u "
+ "(%s, %s) -> IRQ %d\n",
+ pci_name(dev), 'A' + pin, irq,
+ (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
+ (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
+ dev->irq);
return_VALUE(dev->irq);
}
-
-
-int __init
-acpi_pci_irq_init (void)
-{
- struct pci_dev *dev = NULL;
-
- ACPI_FUNCTION_TRACE("acpi_pci_irq_init");
-
- if (!acpi_prt.count) {
- printk(KERN_WARNING PREFIX "ACPI tables contain no PCI IRQ "
- "routing entries\n");
- return_VALUE(-ENODEV);
- }
-
- /* Make sure all link devices have a valid IRQ. */
- if (acpi_pci_link_check()) {
- return_VALUE(-ENODEV);
- }
-
-#ifdef CONFIG_X86_IO_APIC
- /* Program IOAPICs using data from PRT entries. */
- if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
- mp_parse_prt();
-#endif
-#ifdef CONFIG_IOSAPIC
- if (acpi_irq_model == ACPI_IRQ_MODEL_IOSAPIC)
- iosapic_parse_prt();
-#endif
-
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
- acpi_pci_irq_enable(dev);
-
- return_VALUE(0);
-}
struct acpi_resource end;
} resource;
struct acpi_buffer buffer = {sizeof(resource)+1, &resource};
- int i = 0;
- int valid = 0;
ACPI_FUNCTION_TRACE("acpi_pci_link_set");
if (!link || !irq)
return_VALUE(-EINVAL);
- /* We don't check irqs the first time around */
- if (link->irq.setonboot) {
- /* See if we're already at the target IRQ. */
- if (irq == link->irq.active)
- return_VALUE(0);
-
- /* Make sure the target IRQ in the list of possible IRQs. */
- for (i=0; i<link->irq.possible_count; i++) {
- if (irq == link->irq.possible[i])
- valid = 1;
- }
- if (!valid) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq));
- return_VALUE(-EINVAL);
- }
- }
-
memset(&resource, 0, sizeof(resource));
switch(link->irq.resource_type) {
};
int
-acpi_pci_link_check (void)
+acpi_irq_penalty_init(void)
{
struct list_head *node = NULL;
struct acpi_pci_link *link = NULL;
int i = 0;
- ACPI_FUNCTION_TRACE("acpi_pci_link_check");
+ ACPI_FUNCTION_TRACE("acpi_irq_penalty_init");
/*
* Update penalties to facilitate IRQ balancing.
acpi_link.count++;
end:
+ /* disable all links -- to be activated on use */
+ acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+
if (result)
kfree(link);
}
}
+static acpi_status
+get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
+{
+ int *busnr = (int *)data;
+ struct acpi_resource_address64 address;
+
+ if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+ resource->id != ACPI_RSTYPE_ADDRESS32 &&
+ resource->id != ACPI_RSTYPE_ADDRESS64)
+ return AE_OK;
+
+ acpi_resource_to_address64(resource, &address);
+ if ((address.address_length > 0) &&
+ (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+ *busnr = address.min_address_range;
+
+ return AE_OK;
+}
+
+static acpi_status
+try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
+{
+ acpi_status status;
+
+ *busnum = -1;
+ status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum);
+ if (ACPI_FAILURE(status))
+ return status;
+ /* Check if we really get a bus number from _CRS */
+ if (*busnum == -1)
+ return AE_ERROR;
+ return AE_OK;
+}
+
static int
acpi_pci_root_add (
struct acpi_device *device)
/* Some systems have wrong _BBN */
list_for_each_entry(tmp, &acpi_pci_roots, node) {
if ((tmp->id.segment == root->id.segment)
- && (tmp->id.bus == root->id.bus))
+ && (tmp->id.bus == root->id.bus)) {
+ int bus = 0;
+ acpi_status status;
+
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
+
+ status = try_get_root_bridge_busnr(root->handle, &bus);
+ if (ACPI_FAILURE(status))
+ break;
+ if (bus != root->id.bus) {
+ printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus);
+ root->id.bus = bus;
+ }
+ break;
+ }
}
/*
* Device & Function
{
struct acpi_table_ioapic *p =
(struct acpi_table_ioapic*) header;
- printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] global_irq_base[0x%x])\n",
+ printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
p->id, p->address, p->global_irq_base);
}
break;
{
struct acpi_table_iosapic *p =
(struct acpi_table_iosapic*) header;
- printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] global_irq_base[0x%x] address[%p])\n",
- p->id, p->global_irq_base, (void *) (unsigned long) p->address);
+ printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
+ p->id, (void *) (unsigned long) p->address, p->global_irq_base);
}
break;
status = acpi_get_handle(tz->handle, "_SCP", &handle);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
+ status = acpi_get_handle(tz->handle, "_PSV", &handle);
+ if(!ACPI_FAILURE(status)) {
+ tz->cooling_mode = 1;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n",
+ mode?"passive":"active"));
+ return_VALUE(0);
+ }
return_VALUE(-ENODEV);
}
}
/********** basic loader commands and error handling **********/
+// centisecond timeouts - guessing away here
+static unsigned int command_timeouts [] = {
+ [host_memory_test] = 15,
+ [read_adapter_memory] = 2,
+ [write_adapter_memory] = 2,
+ [adapter_start] = 50,
+ [get_version_number] = 10,
+ [interrupt_host] = 1,
+ [flash_erase_sector] = 1,
+ [adap_download_block] = 1,
+ [adap_erase_flash] = 1,
+ [adap_run_in_iram] = 1,
+ [adap_end_download] = 1
+};
+
+
+unsigned int command_successes [] = {
+ [host_memory_test] = COMMAND_PASSED_TEST,
+ [read_adapter_memory] = COMMAND_READ_DATA_OK,
+ [write_adapter_memory] = COMMAND_WRITE_DATA_OK,
+ [adapter_start] = COMMAND_COMPLETE,
+ [get_version_number] = COMMAND_COMPLETE,
+ [interrupt_host] = COMMAND_COMPLETE,
+ [flash_erase_sector] = COMMAND_COMPLETE,
+ [adap_download_block] = COMMAND_COMPLETE,
+ [adap_erase_flash] = COMMAND_COMPLETE,
+ [adap_run_in_iram] = COMMAND_COMPLETE,
+ [adap_end_download] = COMMAND_COMPLETE
+};
+
+static int decode_loader_result (loader_command cmd, u32 result)
+{
+ int res;
+ const char *msg;
+
+ if (result == command_successes[cmd])
+ return 0;
+
+ switch (result) {
+ case BAD_COMMAND:
+ res = -EINVAL;
+ msg = "bad command";
+ break;
+ case COMMAND_IN_PROGRESS:
+ res = -ETIMEDOUT;
+ msg = "command in progress";
+ break;
+ case COMMAND_PASSED_TEST:
+ res = 0;
+ msg = "command passed test";
+ break;
+ case COMMAND_FAILED_TEST:
+ res = -EIO;
+ msg = "command failed test";
+ break;
+ case COMMAND_READ_DATA_OK:
+ res = 0;
+ msg = "command read data ok";
+ break;
+ case COMMAND_READ_BAD_ADDRESS:
+ res = -EINVAL;
+ msg = "command read bad address";
+ break;
+ case COMMAND_WRITE_DATA_OK:
+ res = 0;
+ msg = "command write data ok";
+ break;
+ case COMMAND_WRITE_BAD_ADDRESS:
+ res = -EINVAL;
+ msg = "command write bad address";
+ break;
+ case COMMAND_WRITE_FLASH_FAILURE:
+ res = -EIO;
+ msg = "command write flash failure";
+ break;
+ case COMMAND_COMPLETE:
+ res = 0;
+ msg = "command complete";
+ break;
+ case COMMAND_FLASH_ERASE_FAILURE:
+ res = -EIO;
+ msg = "command flash erase failure";
+ break;
+ case COMMAND_WRITE_BAD_DATA:
+ res = -EINVAL;
+ msg = "command write bad data";
+ break;
+ default:
+ res = -EINVAL;
+ msg = "unknown error";
+ PRINTD (DBG_LOAD|DBG_ERR,
+ "decode_loader_result got %d=%x !",
+ result, result);
+ break;
+ }
+
+ PRINTK (KERN_ERR, "%s", msg);
+ return res;
+}
static int __init do_loader_command (volatile loader_block * lb,
const amb_dev * dev, loader_command cmd) {
- // centisecond timeouts - guessing away here
- unsigned int command_timeouts [] = {
- [host_memory_test] = 15,
- [read_adapter_memory] = 2,
- [write_adapter_memory] = 2,
- [adapter_start] = 50,
- [get_version_number] = 10,
- [interrupt_host] = 1,
- [flash_erase_sector] = 1,
- [adap_download_block] = 1,
- [adap_erase_flash] = 1,
- [adap_run_in_iram] = 1,
- [adap_end_download] = 1
- };
-
- unsigned int command_successes [] = {
- [host_memory_test] = COMMAND_PASSED_TEST,
- [read_adapter_memory] = COMMAND_READ_DATA_OK,
- [write_adapter_memory] = COMMAND_WRITE_DATA_OK,
- [adapter_start] = COMMAND_COMPLETE,
- [get_version_number] = COMMAND_COMPLETE,
- [interrupt_host] = COMMAND_COMPLETE,
- [flash_erase_sector] = COMMAND_COMPLETE,
- [adap_download_block] = COMMAND_COMPLETE,
- [adap_erase_flash] = COMMAND_COMPLETE,
- [adap_run_in_iram] = COMMAND_COMPLETE,
- [adap_end_download] = COMMAND_COMPLETE
- };
-
- int decode_loader_result (loader_command cmd, u32 result) {
- int res;
- const char * msg;
-
- if (result == command_successes[cmd])
- return 0;
-
- switch (result) {
- case BAD_COMMAND:
- res = -EINVAL;
- msg = "bad command";
- break;
- case COMMAND_IN_PROGRESS:
- res = -ETIMEDOUT;
- msg = "command in progress";
- break;
- case COMMAND_PASSED_TEST:
- res = 0;
- msg = "command passed test";
- break;
- case COMMAND_FAILED_TEST:
- res = -EIO;
- msg = "command failed test";
- break;
- case COMMAND_READ_DATA_OK:
- res = 0;
- msg = "command read data ok";
- break;
- case COMMAND_READ_BAD_ADDRESS:
- res = -EINVAL;
- msg = "command read bad address";
- break;
- case COMMAND_WRITE_DATA_OK:
- res = 0;
- msg = "command write data ok";
- break;
- case COMMAND_WRITE_BAD_ADDRESS:
- res = -EINVAL;
- msg = "command write bad address";
- break;
- case COMMAND_WRITE_FLASH_FAILURE:
- res = -EIO;
- msg = "command write flash failure";
- break;
- case COMMAND_COMPLETE:
- res = 0;
- msg = "command complete";
- break;
- case COMMAND_FLASH_ERASE_FAILURE:
- res = -EIO;
- msg = "command flash erase failure";
- break;
- case COMMAND_WRITE_BAD_DATA:
- res = -EINVAL;
- msg = "command write bad data";
- break;
- default:
- res = -EINVAL;
- msg = "unknown error";
- PRINTD (DBG_LOAD|DBG_ERR, "decode_loader_result got %d=%x !",
- result, result);
- break;
- }
-
- PRINTK (KERN_ERR, "%s", msg);
- return res;
- }
unsigned long timeout;
/********** reset card **********/
+static inline void sf (const char * msg)
+{
+ PRINTK (KERN_ERR, "self-test failed: %s", msg);
+}
+
static int amb_reset (amb_dev * dev, int diags) {
u32 word;
// XXX double check byte-order
word = rd_mem (dev, offsetof(amb_mem, mb.loader.result));
if (word & SELF_TEST_FAILURE) {
- void sf (const char * msg) {
- PRINTK (KERN_ERR, "self-test failed: %s", msg);
- }
if (word & GPINT_TST_FAILURE)
sf ("interrupt");
if (word & SUNI_DATA_PATTERN_FAILURE)
}
/********** give adapter parameters **********/
+
+static inline u32 bus_addr(void * addr) {
+ return cpu_to_be32 (virt_to_bus (addr));
+}
static int __init amb_talk (amb_dev * dev) {
adap_talk_block a;
unsigned char pool;
unsigned long timeout;
- u32 x (void * addr) {
- return cpu_to_be32 (virt_to_bus (addr));
- }
-
PRINTD (DBG_FLOW, "amb_talk %p", dev);
- a.command_start = x (dev->cq.ptrs.start);
- a.command_end = x (dev->cq.ptrs.limit);
- a.tx_start = x (dev->txq.in.start);
- a.tx_end = x (dev->txq.in.limit);
- a.txcom_start = x (dev->txq.out.start);
- a.txcom_end = x (dev->txq.out.limit);
+ a.command_start = bus_addr (dev->cq.ptrs.start);
+ a.command_end = bus_addr (dev->cq.ptrs.limit);
+ a.tx_start = bus_addr (dev->txq.in.start);
+ a.tx_end = bus_addr (dev->txq.in.limit);
+ a.txcom_start = bus_addr (dev->txq.out.start);
+ a.txcom_end = bus_addr (dev->txq.out.limit);
for (pool = 0; pool < NUM_RX_POOLS; ++pool) {
// the other "a" items are set up by the adapter
- a.rec_struct[pool].buffer_start = x (dev->rxq[pool].in.start);
- a.rec_struct[pool].buffer_end = x (dev->rxq[pool].in.limit);
- a.rec_struct[pool].rx_start = x (dev->rxq[pool].out.start);
- a.rec_struct[pool].rx_end = x (dev->rxq[pool].out.limit);
+ a.rec_struct[pool].buffer_start = bus_addr (dev->rxq[pool].in.start);
+ a.rec_struct[pool].buffer_end = bus_addr (dev->rxq[pool].in.limit);
+ a.rec_struct[pool].rx_start = bus_addr (dev->rxq[pool].out.start);
+ a.rec_struct[pool].rx_end = bus_addr (dev->rxq[pool].out.limit);
a.rec_struct[pool].buffer_size = cpu_to_be32 (dev->rxq[pool].buffer_size);
}
minor = be32_to_cpu (cmd.args.version.minor);
PRINTK (KERN_INFO, "microcode version is %u.%u", major, minor);
}
-
-// get end station address
-static void __init amb_esi (amb_dev * dev, u8 * esi) {
- u32 lower4;
- u16 upper2;
- command cmd;
- // swap bits within byte to get Ethernet ordering
- u8 bit_swap (u8 byte) {
+// swap bits within byte to get Ethernet ordering
+u8 bit_swap (u8 byte)
+{
const u8 swap[] = {
0x0, 0x8, 0x4, 0xc,
0x2, 0xa, 0x6, 0xe,
0x3, 0xb, 0x7, 0xf
};
return ((swap[byte & 0xf]<<4) | swap[byte>>4]);
- }
+}
+
+// get end station address
+static void __init amb_esi (amb_dev * dev, u8 * esi) {
+ u32 lower4;
+ u16 upper2;
+ command cmd;
cmd.request = cpu_to_be32 (SRB_GET_BIA);
while (command_do (dev, &cmd)) {
return;
}
+
+static void fixup_plx_window (amb_dev *dev, loader_block *lb)
+{
+ // fix up the PLX-mapped window base address to match the block
+ unsigned long blb;
+ u32 mapreg;
+ blb = virt_to_bus(lb);
+ // the kernel stack had better not ever cross a 1Gb boundary!
+ mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10]));
+ mapreg &= ~onegigmask;
+ mapreg |= blb & onegigmask;
+ wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg);
+ return;
+}
-static int __init amb_init (amb_dev * dev) {
+static int __init amb_init (amb_dev * dev)
+{
loader_block lb;
- void fixup_plx_window (void) {
- // fix up the PLX-mapped window base address to match the block
- unsigned long blb;
- u32 mapreg;
- blb = virt_to_bus (&lb);
- // the kernel stack had better not ever cross a 1Gb boundary!
- mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10]));
- mapreg &= ~onegigmask;
- mapreg |= blb & onegigmask;
- wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg);
- return;
- }
-
u32 version;
if (amb_reset (dev, 1)) {
PRINTK (KERN_ERR, "card reset failed!");
} else {
- fixup_plx_window ();
+ fixup_plx_window (dev, &lb);
if (get_loader_version (&lb, dev, &version)) {
PRINTK (KERN_INFO, "failed to get loader version");
} /* amb_reset */
- return -1;
+ return -EINVAL;
}
-static int __init amb_probe (void) {
- struct pci_dev * pci_dev;
- int devs;
-
- void __init do_pci_device (void) {
- amb_dev * dev;
-
- // read resources from PCI configuration space
- u8 irq = pci_dev->irq;
- u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 0));
- u32 iobase = pci_resource_start (pci_dev, 1);
-
- void setup_dev (void) {
+static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev)
+{
unsigned char pool;
memset (dev, 0, sizeof(amb_dev));
// set up known dev items straight away
dev->pci_dev = pci_dev;
- dev->iobase = iobase;
- dev->irq = irq;
- dev->membase = membase;
+ dev->iobase = pci_resource_start (pci_dev, 1);
+ dev->irq = pci_dev->irq;
+ dev->membase = bus_to_virt(pci_resource_start(pci_dev, 0));
// flags (currently only dead)
dev->flags = 0;
spin_lock_init (&dev->txq.lock);
for (pool = 0; pool < NUM_RX_POOLS; ++pool)
spin_lock_init (&dev->rxq[pool].lock);
- }
-
- void setup_pci_dev (void) {
- unsigned char lat;
-
- /* XXX check return value */
- pci_enable_device (pci_dev);
+}
- // enable bus master accesses
- pci_set_master (pci_dev);
-
- // frobnicate latency (upwards, usually)
- pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
- if (pci_lat) {
- PRINTD (DBG_INIT, "%s PCI latency timer from %hu to %hu",
- "changing", lat, pci_lat);
- pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, pci_lat);
- } else if (lat < MIN_PCI_LATENCY) {
- PRINTK (KERN_INFO, "%s PCI latency timer from %hu to %hu",
- "increasing", lat, MIN_PCI_LATENCY);
- pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, MIN_PCI_LATENCY);
- }
- }
-
- PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
- " IO %x, IRQ %u, MEM %p", iobase, irq, membase);
-
- // check IO region
- if (!request_region (iobase, AMB_EXTENT, DEV_LABEL)) {
- PRINTK (KERN_ERR, "IO range already in use!");
- return;
- }
-
- dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
- if (!dev) {
- // perhaps we should be nice: deregister all adapters and abort?
- PRINTK (KERN_ERR, "out of memory!");
- release_region (iobase, AMB_EXTENT);
- return;
- }
-
- setup_dev();
-
- if (amb_init (dev)) {
- PRINTK (KERN_ERR, "adapter initialisation failure");
- } else {
+static int setup_pci_dev(struct pci_dev *pci_dev)
+{
+ unsigned char lat;
+ int ret;
- setup_pci_dev();
+ // enable bus master accesses
+ pci_set_master(pci_dev);
- // grab (but share) IRQ and install handler
- if (request_irq (irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev)) {
- PRINTK (KERN_ERR, "request IRQ failed!");
- // free_irq is at "endif"
- } else {
-
+ ret = pci_enable_device(pci_dev);
+ if (ret < 0)
+ goto out;
+
+ // frobnicate latency (upwards, usually)
+ pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat);
+
+ if (!pci_lat)
+ pci_lat = (lat < MIN_PCI_LATENCY) ? MIN_PCI_LATENCY : lat;
+
+ if (lat != pci_lat) {
+ PRINTK (KERN_INFO, "Changing PCI latency timer from %hu to %hu",
+ lat, pci_lat);
+ pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, pci_lat);
+ }
+out:
+ return ret;
+}
+
+static int __init do_pci_device(struct pci_dev *pci_dev)
+{
+ amb_dev * dev;
+ int err;
+
+ // read resources from PCI configuration space
+ u8 irq = pci_dev->irq;
+ u32 * membase = bus_to_virt (pci_resource_start (pci_dev, 0));
+ u32 iobase = pci_resource_start (pci_dev, 1);
+
+ PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at"
+ " IO %x, IRQ %u, MEM %p", iobase, irq, membase);
+
+ // check IO region
+ err = pci_request_region(pci_dev, 1, DEV_LABEL);
+ if (err < 0) {
+ PRINTK (KERN_ERR, "IO range already in use!");
+ goto out;
+ }
+
+ dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
+ if (!dev) {
+ PRINTK (KERN_ERR, "out of memory!");
+ err = -ENOMEM;
+ goto out_release;
+ }
+
+ setup_dev(dev, pci_dev);
+
+ err = amb_init(dev);
+ if (err < 0) {
+ PRINTK (KERN_ERR, "adapter initialisation failure");
+ goto out_free;
+ }
+
+ err = setup_pci_dev(pci_dev);
+ if (err < 0)
+ goto out_reset;
+
+ // grab (but share) IRQ and install handler
+ err = request_irq(irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev);
+ if (err < 0) {
+ PRINTK (KERN_ERR, "request IRQ failed!");
+ goto out_disable;
+ }
+
dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
if (!dev->atm_dev) {
- PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
- } else {
-
- PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p",
- dev->atm_dev->number, dev, dev->atm_dev);
- dev->atm_dev->dev_data = (void *) dev;
-
- // register our address
- amb_esi (dev, dev->atm_dev->esi);
-
- // 0 bits for vpi, 10 bits for vci
- dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS;
- dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS;
-
- // update count and linked list
- ++devs;
- dev->prev = amb_devs;
- amb_devs = dev;
-
- // enable host interrupts
- interrupts_on (dev);
-
- // success
- return;
-
- // not currently reached
- atm_dev_deregister (dev->atm_dev);
- } /* atm_dev_register */
-
- free_irq (irq, dev);
- } /* request_irq */
-
- amb_reset (dev, 0);
- } /* amb_init */
-
- kfree (dev);
- release_region (iobase, AMB_EXTENT);
- } /* kmalloc, end-of-fn */
+ PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
+ err = -EINVAL;
+ goto out_free_irq;
+ }
+
+ PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p",
+ dev->atm_dev->number, dev, dev->atm_dev);
+ dev->atm_dev->dev_data = (void *) dev;
+
+ // register our address
+ amb_esi (dev, dev->atm_dev->esi);
+
+ // 0 bits for vpi, 10 bits for vci
+ dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS;
+ dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS;
+
+ // update linked list
+ dev->prev = amb_devs;
+ amb_devs = dev;
+
+ // enable host interrupts
+ interrupts_on (dev);
+
+out:
+ return err;
+
+out_free_irq:
+ free_irq(irq, dev);
+out_disable:
+ pci_disable_device(pci_dev);
+out_reset:
+ amb_reset(dev, 0);
+out_free:
+ kfree(dev);
+out_release:
+ pci_release_region(pci_dev, 1);
+ goto out;
+}
+
+static int __init amb_probe (void) {
+ struct pci_dev * pci_dev;
+ int devs;
PRINTD (DBG_FLOW, "amb_probe");
pci_dev = NULL;
while ((pci_dev = pci_find_device
(PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR, pci_dev)
- ))
- do_pci_device();
+ )) {
+ if (do_pci_device(pci_dev) == 0)
+ devs++;
+ }
+
pci_dev = NULL;
while ((pci_dev = pci_find_device
del_timer_sync(&housekeeping);
while (amb_devs) {
+ struct pci_dev *pdev;
+
dev = amb_devs;
+ pdev = dev->pci_dev;
amb_devs = dev->prev;
PRINTD (DBG_INFO|DBG_INIT, "closing %p (atm_dev = %p)", dev, dev->atm_dev);
drain_rx_pools (dev);
interrupts_off (dev);
amb_reset (dev, 0);
+ free_irq (dev->irq, dev);
+ pci_disable_device (pdev);
destroy_queues (dev);
atm_dev_deregister (dev->atm_dev);
- free_irq (dev->irq, dev);
- release_region (dev->iobase, AMB_EXTENT);
kfree (dev);
+ pci_release_region (pdev, 1);
}
return;
}
-static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
struct atm_cirange ci;
struct atm_vcc *vcc;
int i;
if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
- if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT;
+ if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
}
-static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
struct eni_dev *eni_dev = ENI_DEV(dev);
struct eni_multipliers mult;
if (!capable(CAP_NET_ADMIN)) return -EPERM;
- if (copy_from_user(&mult,(void *) arg,
+ if (copy_from_user(&mult, arg,
sizeof(struct eni_multipliers)))
return -EFAULT;
if ((mult.tx && mult.tx <= 100) || (mult.rx &&mult.rx <= 100) ||
if (cmd == ATM_SETCIRANGE) {
struct atm_cirange ci;
- if (copy_from_user(&ci,(void *) arg,sizeof(struct atm_cirange)))
+ if (copy_from_user(&ci, arg,sizeof(struct atm_cirange)))
return -EFAULT;
if ((ci.vpi_bits == 0 || ci.vpi_bits == ATM_CI_MAX) &&
(ci.vci_bits == NR_VCI_LD || ci.vpi_bits == ATM_CI_MAX))
static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen)
+ void __user *optval,int optlen)
{
return -EINVAL;
}
static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen)
+ void __user *optval,int optlen)
{
return -EINVAL;
}
/* Some function placeholders for functions we don't yet support. */
#if 0
-static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
func_enter ();
func_exit ();
static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen)
+ void __user *optval,int optlen)
{
func_enter ();
func_exit ();
static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen)
+ void __user *optval,int optlen)
{
func_enter ();
func_exit ();
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/atm_suni.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/page.h>
opcode.opcode = OPCODE_GET_PROM;
opcode.pad = 0;
- prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data), FORE200E_DMA_FROMDEVICE);
+ prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data), DMA_FROM_DEVICE);
fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
*entry->status = STATUS_FREE;
- fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data), FORE200E_DMA_FROMDEVICE);
+ fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
if (ok == 0) {
printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
/* remove DMA mapping */
fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
- FORE200E_DMA_TODEVICE);
+ DMA_TO_DEVICE);
vc_map = entry->vc_map;
buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
/* Make device DMA transfer visible to CPU. */
- fore200e->bus->dma_sync_for_cpu(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE);
+ fore200e->bus->dma_sync_for_cpu(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, DMA_FROM_DEVICE);
memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length);
/* Now let the device get at it again. */
- fore200e->bus->dma_sync_for_device(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, FORE200E_DMA_FROMDEVICE);
+ fore200e->bus->dma_sync_for_device(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, DMA_FROM_DEVICE);
}
DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
entry->data = tx_copy ? data : NULL;
tpd = entry->tpd;
- tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, data, tx_len, FORE200E_DMA_TODEVICE);
+ tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, data, tx_len, DMA_TO_DEVICE);
tpd->tsd[ 0 ].length = tx_len;
FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
}
stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats,
- sizeof(struct stats), FORE200E_DMA_FROMDEVICE);
+ sizeof(struct stats), DMA_FROM_DEVICE);
FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
*entry->status = STATUS_FREE;
- fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats), FORE200E_DMA_FROMDEVICE);
+ fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
if (ok == 0) {
printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
static int
-fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void* optval, int optlen)
+fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
{
/* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
static int
-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void* optval, int optlen)
+fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
{
/* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
int ok;
u32 oc3_regs_dma_addr;
- oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), FORE200E_DMA_FROMDEVICE);
+ oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
*entry->status = STATUS_FREE;
- fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), FORE200E_DMA_FROMDEVICE);
+ fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
if (ok == 0) {
printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
static int
-fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats* arg)
+fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
{
struct sonet_stats tmp;
static int
-fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void* arg)
+fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
{
struct fore200e* fore200e = FORE200E_DEV(dev);
switch (cmd) {
case SONET_GETSTAT:
- return fore200e_fetch_stats(fore200e, (struct sonet_stats*)arg);
+ return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
case SONET_GETDIAG:
- return put_user(0, (int*)arg) ? -EFAULT : 0;
+ return put_user(0, (int __user *)arg) ? -EFAULT : 0;
case ATM_SETLOOP:
return fore200e_setloop(fore200e, (int)(unsigned long)arg);
case ATM_GETLOOP:
- return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0;
+ return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
case ATM_QUERYLOOP:
- return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int*)arg) ? -EFAULT : 0;
+ return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
}
return -ENOSYS; /* not implemented */
/* allocate the receive buffer body */
if (fore200e_chunk_alloc(fore200e,
&buffer[ i ].data, size, fore200e->bus->buffer_alignment,
- FORE200E_DMA_FROMDEVICE) < 0) {
+ DMA_FROM_DEVICE) < 0) {
while (i > 0)
fore200e_chunk_free(fore200e, &buffer[ --i ].data);
typedef struct host_cmdq_entry {
struct cp_cmdq_entry* cp_entry; /* addr of cp resident cmd queue entry */
- enum status* status; /* addr of host resident status */
+ enum status *status; /* addr of host resident status */
} host_cmdq_entry_t;
typedef struct init_block {
enum opcode opcode; /* initialize command */
- enum status status; /* related status word */
+ enum status status; /* related status word */
u32 receive_threshold; /* not used */
u32 num_connect; /* ATM connections */
u32 cmd_queue_len; /* length of command queue */
int (*proc_read)(struct fore200e*, char*);
} fore200e_bus_t;
-
-#if defined(CONFIG_ATM_FORE200E_SBA)
-# if defined(CONFIG_ATM_FORE200E_PCA)
-# define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL
-# define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE
-# define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE
-# else
-# define FORE200E_DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL
-# define FORE200E_DMA_TODEVICE SBUS_DMA_TODEVICE
-# define FORE200E_DMA_FROMDEVICE SBUS_DMA_FROMDEVICE
-# endif
-#else
-# ifndef CONFIG_ATM_FORE200E_PCA
-# warning compiling the fore200e driver without any hardware support enabled!
-# include <linux/pci.h>
-# endif
-# define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL
-# define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE
-# define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE
-#endif
-
-
/* vc mapping */
typedef struct fore200e_vc_map {
static int he_open(struct atm_vcc *vcc);
static void he_close(struct atm_vcc *vcc);
static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
+static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
static void he_tasklet(unsigned long data);
static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
}
static int
-he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void *arg)
+he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user *arg)
{
unsigned long flags;
struct he_dev *he_dev = HE_DEV(atm_dev);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (copy_from_user(®, (struct he_ioctl_reg *) arg,
- sizeof(struct he_ioctl_reg)))
+ if (copy_from_user(®, arg,
+ sizeof(struct he_ioctl_reg)))
return -EFAULT;
spin_lock_irqsave(&he_dev->global_lock, flags);
}
spin_unlock_irqrestore(&he_dev->global_lock, flags);
if (err == 0)
- if (copy_to_user((struct he_ioctl_reg *) arg, ®,
+ if (copy_to_user(arg, ®,
sizeof(struct he_ioctl_reg)))
return -EFAULT;
break;
// p ranges from 1 to a power of 2
#define CR_MAXPEXP 4
-
+
static int make_rate (const hrz_dev * dev, u32 c, rounding r,
- u16 * bits, unsigned int * actual) {
-
- // note: rounding the rate down means rounding 'p' up
-
- const unsigned long br = test_bit(ultra, &dev->flags) ? BR_ULT : BR_HRZ;
-
- u32 div = CR_MIND;
- u32 pre;
+ u16 * bits, unsigned int * actual)
+{
+ // note: rounding the rate down means rounding 'p' up
+ const unsigned long br = test_bit(ultra, &dev->flags) ? BR_ULT : BR_HRZ;
- // local fn to build the timer bits
- int set_cr (void) {
- // paranoia
- if (div > CR_MAXD || (!pre) || pre > 1<<CR_MAXPEXP) {
- PRINTD (DBG_QOS, "set_cr internal failure: d=%u p=%u",
- div, pre);
- return -EINVAL;
- } else {
- if (bits)
- *bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1);
- if (actual) {
- *actual = (br + (pre<<div) - 1) / (pre<<div);
- PRINTD (DBG_QOS, "actual rate: %u", *actual);
- }
- return 0;
- }
- }
+ u32 div = CR_MIND;
+ u32 pre;
- // br_exp and br_man are used to avoid overflowing (c*maxp*2^d) in
- // the tests below. We could think harder about exact possibilities
- // of failure...
+ // br_exp and br_man are used to avoid overflowing (c*maxp*2^d) in
+ // the tests below. We could think harder about exact possibilities
+ // of failure...
- unsigned long br_man = br;
- unsigned int br_exp = 0;
+ unsigned long br_man = br;
+ unsigned int br_exp = 0;
- PRINTD (DBG_QOS|DBG_FLOW, "make_rate b=%lu, c=%u, %s", br, c,
- (r == round_up) ? "up" : (r == round_down) ? "down" : "nearest");
+ PRINTD (DBG_QOS|DBG_FLOW, "make_rate b=%lu, c=%u, %s", br, c,
+ r == round_up ? "up" : r == round_down ? "down" : "nearest");
- // avoid div by zero
- if (!c) {
- PRINTD (DBG_QOS|DBG_ERR, "zero rate is not allowed!");
- return -EINVAL;
- }
+ // avoid div by zero
+ if (!c) {
+ PRINTD (DBG_QOS|DBG_ERR, "zero rate is not allowed!");
+ return -EINVAL;
+ }
- while (br_exp < CR_MAXPEXP + CR_MIND && (br_man % 2 == 0)) {
- br_man = br_man >> 1;
- ++br_exp;
- }
- // (br >>br_exp) <<br_exp == br and
- // br_exp <= CR_MAXPEXP+CR_MIND
+ while (br_exp < CR_MAXPEXP + CR_MIND && (br_man % 2 == 0)) {
+ br_man = br_man >> 1;
+ ++br_exp;
+ }
+ // (br >>br_exp) <<br_exp == br and
+ // br_exp <= CR_MAXPEXP+CR_MIND
+
+ if (br_man <= (c << (CR_MAXPEXP+CR_MIND-br_exp))) {
+ // Equivalent to: B <= (c << (MAXPEXP+MIND))
+ // take care of rounding
+ switch (r) {
+ case round_down:
+ pre = (br+(c<<div)-1)/(c<<div);
+ // but p must be non-zero
+ if (!pre)
+ pre = 1;
+ break;
+ case round_nearest:
+ pre = (br+(c<<div)/2)/(c<<div);
+ // but p must be non-zero
+ if (!pre)
+ pre = 1;
+ break;
+ default: /* round_up */
+ pre = br/(c<<div);
+ // but p must be non-zero
+ if (!pre)
+ return -EINVAL;
+ }
+ PRINTD (DBG_QOS, "A: p=%u, d=%u", pre, div);
+ goto got_it;
+ }
- if (br_man <= (c << (CR_MAXPEXP+CR_MIND-br_exp))) {
- // Equivalent to: B <= (c << (MAXPEXP+MIND))
- // take care of rounding
- switch (r) {
- case round_down:
- pre = (br+(c<<div)-1)/(c<<div);
- // but p must be non-zero
- if (!pre)
- pre = 1;
- break;
- case round_nearest:
- pre = (br+(c<<div)/2)/(c<<div);
- // but p must be non-zero
- if (!pre)
- pre = 1;
- break;
- case round_up:
- pre = br/(c<<div);
- // but p must be non-zero
- if (!pre)
- return -EINVAL;
- break;
- }
- PRINTD (DBG_QOS, "A: p=%u, d=%u", pre, div);
- return set_cr ();
- }
-
- // at this point we have
- // d == MIND and (c << (MAXPEXP+MIND)) < B
- while (div < CR_MAXD) {
- div++;
- if (br_man <= (c << (CR_MAXPEXP+div-br_exp))) {
- // Equivalent to: B <= (c << (MAXPEXP+d))
- // c << (MAXPEXP+d-1) < B <= c << (MAXPEXP+d)
- // 1 << (MAXPEXP-1) < B/2^d/c <= 1 << MAXPEXP
- // MAXP/2 < B/c2^d <= MAXP
- // take care of rounding
- switch (r) {
- case round_down:
- pre = (br+(c<<div)-1)/(c<<div);
- break;
- case round_nearest:
- pre = (br+(c<<div)/2)/(c<<div);
- break;
- case round_up:
- pre = br/(c<<div);
- break;
- }
- PRINTD (DBG_QOS, "B: p=%u, d=%u", pre, div);
- return set_cr ();
- }
- }
- // at this point we have
- // d == MAXD and (c << (MAXPEXP+MAXD)) < B
- // but we cannot go any higher
- // take care of rounding
- switch (r) {
- case round_down:
- return -EINVAL;
- break;
- case round_nearest:
- break;
- case round_up:
- break;
- }
- pre = 1 << CR_MAXPEXP;
- PRINTD (DBG_QOS, "C: p=%u, d=%u", pre, div);
- return set_cr ();
+ // at this point we have
+ // d == MIND and (c << (MAXPEXP+MIND)) < B
+ while (div < CR_MAXD) {
+ div++;
+ if (br_man <= (c << (CR_MAXPEXP+div-br_exp))) {
+ // Equivalent to: B <= (c << (MAXPEXP+d))
+ // c << (MAXPEXP+d-1) < B <= c << (MAXPEXP+d)
+ // 1 << (MAXPEXP-1) < B/2^d/c <= 1 << MAXPEXP
+ // MAXP/2 < B/c2^d <= MAXP
+ // take care of rounding
+ switch (r) {
+ case round_down:
+ pre = (br+(c<<div)-1)/(c<<div);
+ break;
+ case round_nearest:
+ pre = (br+(c<<div)/2)/(c<<div);
+ break;
+ default: /* round_up */
+ pre = br/(c<<div);
+ }
+ PRINTD (DBG_QOS, "B: p=%u, d=%u", pre, div);
+ goto got_it;
+ }
+ }
+ // at this point we have
+ // d == MAXD and (c << (MAXPEXP+MAXD)) < B
+ // but we cannot go any higher
+ // take care of rounding
+ if (r == round_down)
+ return -EINVAL;
+ pre = 1 << CR_MAXPEXP;
+ PRINTD (DBG_QOS, "C: p=%u, d=%u", pre, div);
+got_it:
+ // paranoia
+ if (div > CR_MAXD || (!pre) || pre > 1<<CR_MAXPEXP) {
+ PRINTD (DBG_QOS, "set_cr internal failure: d=%u p=%u",
+ div, pre);
+ return -EINVAL;
+ } else {
+ if (bits)
+ *bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1);
+ if (actual) {
+ *actual = (br + (pre<<div) - 1) / (pre<<div);
+ PRINTD (DBG_QOS, "actual rate: %u", *actual);
+ }
+ return 0;
+ }
}
static int make_rate_with_tolerance (const hrz_dev * dev, u32 c, rounding r, unsigned int tol,
/********** read the burnt in address **********/
-static u16 __init read_bia (const hrz_dev * dev, u16 addr) {
+static inline void WRITE_IT_WAIT (const hrz_dev *dev, u32 ctrl)
+{
+ wr_regl (dev, CONTROL_0_REG, ctrl);
+ udelay (5);
+}
+static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl)
+{
+ // DI must be valid around rising SK edge
+ WRITE_IT_WAIT(dev, ctrl & ~SEEPROM_SK);
+ WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK);
+}
+
+static u16 __init read_bia (const hrz_dev * dev, u16 addr)
+{
u32 ctrl = rd_regl (dev, CONTROL_0_REG);
- void WRITE_IT_WAIT (void) {
- wr_regl (dev, CONTROL_0_REG, ctrl);
- udelay (5);
- }
-
- void CLOCK_IT (void) {
- // DI must be valid around rising SK edge
- ctrl &= ~SEEPROM_SK;
- WRITE_IT_WAIT();
- ctrl |= SEEPROM_SK;
- WRITE_IT_WAIT();
- }
-
const unsigned int addr_bits = 6;
const unsigned int data_bits = 16;
u16 res;
ctrl &= ~(SEEPROM_CS | SEEPROM_SK | SEEPROM_DI);
- WRITE_IT_WAIT();
+ WRITE_IT_WAIT(dev, ctrl);
// wake Serial EEPROM and send 110 (READ) command
ctrl |= (SEEPROM_CS | SEEPROM_DI);
- CLOCK_IT();
+ CLOCK_IT(dev, ctrl);
ctrl |= SEEPROM_DI;
- CLOCK_IT();
+ CLOCK_IT(dev, ctrl);
ctrl &= ~SEEPROM_DI;
- CLOCK_IT();
+ CLOCK_IT(dev, ctrl);
for (i=0; i<addr_bits; i++) {
if (addr & (1 << (addr_bits-1)))
else
ctrl &= ~SEEPROM_DI;
- CLOCK_IT();
+ CLOCK_IT(dev, ctrl);
addr = addr << 1;
}
for (i=0;i<data_bits;i++) {
res = res >> 1;
- CLOCK_IT();
+ CLOCK_IT(dev, ctrl);
if (rd_regl (dev, CONTROL_0_REG) & SEEPROM_DO)
res |= (1 << (data_bits-1));
}
ctrl &= ~(SEEPROM_SK | SEEPROM_CS);
- WRITE_IT_WAIT();
+ WRITE_IT_WAIT(dev, ctrl);
return res;
}
}
-static int fetch_stats(struct atm_dev *dev,struct idt77105_stats *arg,int zero)
+static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int zero)
{
unsigned long flags;
struct idt77105_stats stats;
}
-static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number);
switch (cmd) {
if (!capable(CAP_NET_ADMIN)) return -EPERM;
/* fall through */
case IDT77105_GETSTAT:
- return fetch_stats(dev,(struct idt77105_stats *) arg,
- cmd == IDT77105_GETSTATZ);
+ return fetch_stats(dev, arg, cmd == IDT77105_GETSTATZ);
case ATM_SETLOOP:
return set_loopback(dev,(int) (long) arg);
case ATM_GETLOOP:
- return put_user(PRIV(dev)->loop_mode,(int *) arg) ?
+ return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-EFAULT : 0;
case ATM_QUERYLOOP:
return put_user(ATM_LM_LOC_ATM | ATM_LM_RMT_ATM,
- (int *) arg) ? -EFAULT : 0;
+ (int __user *) arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
return 0;
}
-static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
+static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
{
IA_CMDBUF ia_cmds;
IADEV *iadev;
int i, board;
- u16 *tmps;
+ u16 __user *tmps;
IF_EVENT(printk(">ia_ioctl\n");)
if (cmd != IA_CMD) {
if (!dev->phy->ioctl) return -EINVAL;
break;
case MEMDUMP_SEGREG:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
- tmps = (u16 *)ia_cmds.buf;
+ tmps = (u16 __user *)ia_cmds.buf;
for(i=0; i<0x80; i+=2, tmps++)
if(put_user((u16)(readl(iadev->seg_reg+i) & 0xffff), tmps)) return -EFAULT;
ia_cmds.status = 0;
break;
case MEMDUMP_REASSREG:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
- tmps = (u16 *)ia_cmds.buf;
+ tmps = (u16 __user *)ia_cmds.buf;
for(i=0; i<0x80; i+=2, tmps++)
if(put_user((u16)(readl(iadev->reass_reg+i) & 0xffff), tmps)) return -EFAULT;
ia_cmds.status = 0;
}
static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
- void *optval, int optlen)
+ void __user *optval, int optlen)
{
IF_EVENT(printk(">ia_getsockopt\n");)
return -EINVAL;
}
static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
- void *optval, int optlen)
+ void __user *optval, int optlen)
{
IF_EVENT(printk(">ia_setsockopt\n");)
return -EINVAL;
int len;
u32 maddr;
int status;
- void *buf;
+ void __user *buf;
} IA_CMDBUF, *PIA_CMDBUF;
/* cmds */
#if 0
/* ioctl operations for card */
/* NOTE: these are all DEBUGGING ONLY currently */
-static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void *arg)
+static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void __user *arg)
{
int result = 0;
struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb);
static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb);
static int ns_proc_read(struct atm_dev *dev, loff_t *pos, char *page);
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
+static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
static void which_list(ns_dev *card, struct sk_buff *skb);
static void ns_poll(unsigned long arg);
static int ns_parse_mac(char *mac, unsigned char *esi);
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)
+static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
{
ns_dev *card;
pool_levels pl;
switch (cmd)
{
case NS_GETPSTAT:
- if (get_user(pl.buftype, &((pool_levels *) arg)->buftype))
+ if (get_user(pl.buftype, &((pool_levels __user *) arg)->buftype))
return -EFAULT;
switch (pl.buftype)
{
return -ENOIOCTLCMD;
}
- if (!copy_to_user((pool_levels *) arg, &pl, sizeof(pl)))
+ if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl)))
return (sizeof(pl));
else
return -EFAULT;
case NS_SETBUFLEV:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (copy_from_user(&pl, (pool_levels *) arg, sizeof(pl)))
+ if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl)))
return -EFAULT;
if (pl.level.min >= pl.level.init || pl.level.init >= pl.level.max)
return -EINVAL;
#undef ADD_LIMITED
-static int fetch_stats(struct atm_dev *dev,struct sonet_stats *arg,int zero)
+static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
{
struct sonet_stats tmp;
int error = 0;
}
-static int change_diag(struct atm_dev *dev,void *arg,int set)
+static int change_diag(struct atm_dev *dev,void __user *arg,int set)
{
int todo;
- if (get_user(todo,(int *) arg)) return -EFAULT;
+ if (get_user(todo,(int __user *)arg)) return -EFAULT;
HANDLE_FLAG(SONET_INS_SBIP,TSOP_DIAG,SUNI_TSOP_DIAG_DBIP8);
HANDLE_FLAG(SONET_INS_LBIP,TLOP_DIAG,SUNI_TLOP_DIAG_DBIP);
HANDLE_FLAG(SONET_INS_PBIP,TPOP_CD,SUNI_TPOP_DIAG_DB3);
HANDLE_FLAG(SONET_INS_PAIS,TPOP_CD,SUNI_TPOP_DIAG_PAIS);
HANDLE_FLAG(SONET_INS_LOS,TSOP_DIAG,SUNI_TSOP_DIAG_DLOS);
HANDLE_FLAG(SONET_INS_HCS,TACP_CS,SUNI_TACP_CS_DHCS);
- return put_user(todo,(int *) arg) ? -EFAULT : 0;
+ return put_user(todo,(int __user *)arg) ? -EFAULT : 0;
}
#undef HANDLE_FLAG
-static int get_diag(struct atm_dev *dev,void *arg)
+static int get_diag(struct atm_dev *dev,void __user *arg)
{
int set;
if (GET(TPOP_CD) & SUNI_TPOP_DIAG_PAIS) set |= SONET_INS_PAIS;
if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DLOS) set |= SONET_INS_LOS;
if (GET(TACP_CS) & SUNI_TACP_CS_DHCS) set |= SONET_INS_HCS;
- return put_user(set,(int *) arg) ? -EFAULT : 0;
+ return put_user(set,(int __user *)arg) ? -EFAULT : 0;
}
}
-static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
switch (cmd) {
case SONET_GETSTATZ:
case SONET_GETSTAT:
- return fetch_stats(dev,(struct sonet_stats *) arg,
- cmd == SONET_GETSTATZ);
+ return fetch_stats(dev, arg, cmd == SONET_GETSTATZ);
case SONET_SETDIAG:
return change_diag(dev,arg,1);
case SONET_CLRDIAG:
if (arg != SONET_FRAME_SONET) return -EINVAL;
return 0;
case SONET_GETFRAMING:
- return put_user(SONET_FRAME_SONET,(int *) arg) ?
+ return put_user(SONET_FRAME_SONET,(int __user *)arg) ?
-EFAULT : 0;
case SONET_GETFRSENSE:
return -EINVAL;
case ATM_SETLOOP:
return set_loopback(dev,(int) (long) arg);
case ATM_GETLOOP:
- return put_user(PRIV(dev)->loop_mode,(int *) arg) ?
+ return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-EFAULT : 0;
case ATM_QUERYLOOP:
return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY,
- (int *) arg) ? -EFAULT : 0;
+ (int __user *) arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
#define GET(reg) dev->ops->phy_get(dev,uPD98402_##reg)
-static int fetch_stats(struct atm_dev *dev,struct sonet_stats *arg,int zero)
+static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
{
struct sonet_stats tmp;
int error = 0;
}
-static int get_sense(struct atm_dev *dev,u8 *arg)
+static int get_sense(struct atm_dev *dev,u8 __user *arg)
{
unsigned long flags;
unsigned char s[3];
}
-static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
switch (cmd) {
case SONET_GETSTATZ:
case SONET_GETSTAT:
- return fetch_stats(dev,(struct sonet_stats *) arg,
- cmd == SONET_GETSTATZ);
+ return fetch_stats(dev,arg, cmd == SONET_GETSTATZ);
case SONET_SETFRAMING:
return set_framing(dev,(int) (long) arg);
case SONET_GETFRAMING:
- return put_user(PRIV(dev)->framing,(int *) arg) ?
+ return put_user(PRIV(dev)->framing,(int __user *)arg) ?
-EFAULT : 0;
case SONET_GETFRSENSE:
return get_sense(dev,arg);
case ATM_SETLOOP:
return set_loopback(dev,(int) (long) arg);
case ATM_GETLOOP:
- return put_user(PRIV(dev)->loop_mode,(int *) arg) ?
+ return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-EFAULT : 0;
case ATM_QUERYLOOP:
return put_user(ATM_LM_LOC_PHY | ATM_LM_LOC_ATM |
- ATM_LM_RMT_PHY,(int *) arg) ? -EFAULT : 0;
+ ATM_LM_RMT_PHY,(int __user *)arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
}
-static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
+static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
struct zatm_dev *zatm_dev;
unsigned long flags;
int pool;
if (get_user(pool,
- &((struct zatm_pool_req *) arg)->pool_num))
+ &((struct zatm_pool_req __user *) arg)->pool_num))
return -EFAULT;
if (pool < 0 || pool > ZATM_LAST_POOL)
return -EINVAL;
}
spin_unlock_irqrestore(&zatm_dev->lock, flags);
return copy_to_user(
- &((struct zatm_pool_req *) arg)->info,
+ &((struct zatm_pool_req __user *) arg)->info,
&info,sizeof(info)) ? -EFAULT : 0;
}
case ZATM_SETPOOL:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (get_user(pool,
- &((struct zatm_pool_req *) arg)->pool_num))
+ &((struct zatm_pool_req __user *) arg)->pool_num))
return -EFAULT;
if (pool < 0 || pool > ZATM_LAST_POOL)
return -EINVAL;
if (copy_from_user(&info,
- &((struct zatm_pool_req *) arg)->info,
+ &((struct zatm_pool_req __user *) arg)->info,
sizeof(info))) return -EFAULT;
if (!info.low_water)
info.low_water = zatm_dev->
static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen)
+ void __user *optval,int optlen)
{
return -EINVAL;
}
static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen)
+ void __user *optval,int optlen)
{
return -EINVAL;
}
/*
* register_cpu - Setup a driverfs device for a CPU.
+ * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to
+ * generate a control file in sysfs for this CPU.
* @num - CPU number to use when creating the device.
*
* Initialize and register the CPU device.
error = sysfs_create_link(&root->sysdev.kobj,
&cpu->sysdev.kobj,
kobject_name(&cpu->sysdev.kobj));
- if (!error)
+ if (!error && !cpu->no_control)
register_cpu_control(cpu);
return error;
}
cpumask_t mask = node_dev->cpumap;
int len;
- /* FIXME - someone should pass us a buffer size (count) or
- * use seq_file or something to avoid buffer overrun risk. */
- len = cpumask_scnprintf(buf, 99 /* XXX FIXME */, mask);
+ /* 2004/06/03: buf currently PAGE_SIZE, need > 1 char per 4 bits. */
+ BUILD_BUG_ON(NR_CPUS/4 > PAGE_SIZE/2);
+
+ len = cpumask_scnprintf(buf, PAGE_SIZE-1, mask);
len += sprintf(buf + len, "\n");
return len;
}
struct gendisk *disk = inode->i_bdev->bd_disk;
DAC960_Controller_T *p = disk->queue->queuedata;
int drive_nr = (long)disk->private_data;
- struct hd_geometry g, *loc = (struct hd_geometry *)arg;
+ struct hd_geometry g;
+ struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;
if (cmd != HDIO_GETGEO || !loc)
return -EINVAL;
DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
*/
-static int DAC960_ProcWriteUserCommand(struct file *file, const char *Buffer,
+static int DAC960_ProcWriteUserCommand(struct file *file,
+ const char __user *Buffer,
unsigned long Count, void *Data)
{
DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
return DAC960_ControllerCount;
case DAC960_IOCTL_GET_CONTROLLER_INFO:
{
- DAC960_ControllerInfo_T *UserSpaceControllerInfo =
- (DAC960_ControllerInfo_T *) Argument;
+ DAC960_ControllerInfo_T __user *UserSpaceControllerInfo =
+ (DAC960_ControllerInfo_T __user *) Argument;
DAC960_ControllerInfo_T ControllerInfo;
DAC960_Controller_T *Controller;
int ControllerNumber;
}
case DAC960_IOCTL_V1_EXECUTE_COMMAND:
{
- DAC960_V1_UserCommand_T *UserSpaceUserCommand =
- (DAC960_V1_UserCommand_T *) Argument;
+ DAC960_V1_UserCommand_T __user *UserSpaceUserCommand =
+ (DAC960_V1_UserCommand_T __user *) Argument;
DAC960_V1_UserCommand_T UserCommand;
DAC960_Controller_T *Controller;
DAC960_Command_T *Command = NULL;
}
case DAC960_IOCTL_V2_EXECUTE_COMMAND:
{
- DAC960_V2_UserCommand_T *UserSpaceUserCommand =
- (DAC960_V2_UserCommand_T *) Argument;
+ DAC960_V2_UserCommand_T __user *UserSpaceUserCommand =
+ (DAC960_V2_UserCommand_T __user *) Argument;
DAC960_V2_UserCommand_T UserCommand;
DAC960_Controller_T *Controller;
DAC960_Command_T *Command = NULL;
}
case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
{
- DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
- (DAC960_V2_GetHealthStatus_T *) Argument;
+ DAC960_V2_GetHealthStatus_T __user *UserSpaceGetHealthStatus =
+ (DAC960_V2_GetHealthStatus_T __user *) Argument;
DAC960_V2_GetHealthStatus_T GetHealthStatus;
DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
DAC960_Controller_T *Controller;
unsigned char ControllerNumber;
DAC960_V1_CommandMailbox_T CommandMailbox;
int DataTransferLength;
- void *DataTransferBuffer;
- DAC960_V1_DCDB_T *DCDB;
+ void __user *DataTransferBuffer;
+ DAC960_V1_DCDB_T __user *DCDB;
}
DAC960_V1_UserCommand_T;
DAC960_V2_CommandMailbox_T CommandMailbox;
int DataTransferLength;
int RequestSenseLength;
- void *DataTransferBuffer;
- void *RequestSenseBuffer;
+ void __user *DataTransferBuffer;
+ void __user *RequestSenseBuffer;
}
DAC960_V2_UserCommand_T;
typedef struct DAC960_V2_GetHealthStatus
{
unsigned char ControllerNumber;
- DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+ DAC960_V2_HealthStatusBuffer_T __user *HealthStatusBuffer;
}
DAC960_V2_GetHealthStatus_T;
config BLK_DEV_FD
tristate "Normal floppy disk support"
- depends on (!X86_PC9800 && !ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN)
+ depends on (!ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN)
---help---
If you want to use the floppy disk drive(s) of your PC under Linux,
say Y. Information about this driver, especially important for IBM
tristate "Atari floppy support"
depends on ATARI
-config BLK_DEV_FD98
- tristate "NEC PC-9800 floppy disk support"
- depends on X86_PC9800
- ---help---
- If you want to use the floppy disk drive(s) of NEC PC-9801/PC-9821,
- say Y.
-
config BLK_DEV_SWIM_IOP
bool "Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)"
depends on MAC && EXPERIMENTAL && BROKEN
static int carm_bdev_ioctl(struct inode *ino, struct file *fil,
unsigned int cmd, unsigned long arg)
{
- void __user *usermem = (void *) arg;
+ void __user *usermem = (void __user *) arg;
struct carm_port *port = ino->i_bdev->bd_disk->private_data;
struct hd_geometry geom;
static void cciss_getgeometry(int cntl_num);
-static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c);
static void start_io( ctlr_info_t *h);
static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
.revalidate_disk= cciss_revalidate,
};
+/*
+ * Enqueuing and dequeuing functions for cmdlists.
+ */
+static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c)
+{
+ if (*Qptr == NULL) {
+ *Qptr = c;
+ c->next = c->prev = c;
+ } else {
+ c->prev = (*Qptr)->prev;
+ c->next = (*Qptr);
+ (*Qptr)->prev->next = c;
+ (*Qptr)->prev = c;
+ }
+}
+
+static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
+ CommandList_struct *c)
+{
+ if (c && c->next != c) {
+ if (*Qptr == c) *Qptr = c->next;
+ c->prev->next = c->next;
+ c->next->prev = c->prev;
+ } else {
+ *Qptr = NULL;
+ }
+ return c;
+}
+#ifdef CONFIG_PROC_FS
+
#include "cciss_scsi.c" /* For SCSI tape support */
/*
#define RAID_UNKNOWN 6
static const char *raid_label[] = {"0","4","1(0+1)","5","5+1","ADG",
"UNKNOWN"};
-#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_cciss;
}
static int
-cciss_proc_write(struct file *file, const char *buffer,
+cciss_proc_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
unsigned char cmd[80];
return 0;
}
+#ifdef CONFIG_COMPAT
+/* for AMD 64 bit kernel compatibility with 32-bit userland ioctls */
+extern long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+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);
+
+static int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg, struct file *file);
+static int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
+ struct file *file);
+
+typedef int (*handler_type) (unsigned int, unsigned int, unsigned long, struct file *);
+
+static struct ioctl32_map {
+ unsigned int cmd;
+ handler_type handler;
+ int registered;
+} cciss_ioctl32_map[] = {
+ { CCISS_GETPCIINFO, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETINTINFO, (handler_type) sys_ioctl, 0 },
+ { CCISS_SETINTINFO, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETNODENAME, (handler_type) sys_ioctl, 0 },
+ { CCISS_SETNODENAME, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETHEARTBEAT, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETBUSTYPES, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETFIRMVER, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETDRIVVER, (handler_type) sys_ioctl, 0 },
+ { CCISS_REVALIDVOLS, (handler_type) sys_ioctl, 0 },
+ { CCISS_PASSTHRU32, cciss_ioctl32_passthru, 0 },
+ { CCISS_DEREGDISK, (handler_type) sys_ioctl, 0 },
+ { CCISS_REGNEWDISK, (handler_type) sys_ioctl, 0 },
+ { CCISS_REGNEWD, (handler_type) sys_ioctl, 0 },
+ { CCISS_RESCANDISK, (handler_type) sys_ioctl, 0 },
+ { CCISS_GETLUNINFO, (handler_type) sys_ioctl, 0 },
+ { CCISS_BIG_PASSTHRU32, cciss_ioctl32_big_passthru, 0 },
+};
+#define NCCISS_IOCTL32_ENTRIES (sizeof(cciss_ioctl32_map) / sizeof(cciss_ioctl32_map[0]))
+static void register_cciss_ioctl32(void)
+{
+ int i, rc;
+
+ for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) {
+ rc = register_ioctl32_conversion(
+ cciss_ioctl32_map[i].cmd,
+ cciss_ioctl32_map[i].handler);
+ if (rc != 0) {
+ printk(KERN_WARNING "cciss: failed to register "
+ "32 bit compatible ioctl 0x%08x\n",
+ cciss_ioctl32_map[i].cmd);
+ cciss_ioctl32_map[i].registered = 0;
+ } else
+ cciss_ioctl32_map[i].registered = 1;
+ }
+}
+static void unregister_cciss_ioctl32(void)
+{
+ int i, rc;
+
+ for (i=0; i < NCCISS_IOCTL32_ENTRIES; i++) {
+ if (!cciss_ioctl32_map[i].registered)
+ continue;
+ rc = unregister_ioctl32_conversion(
+ cciss_ioctl32_map[i].cmd);
+ if (rc == 0) {
+ cciss_ioctl32_map[i].registered = 0;
+ continue;
+ }
+ printk(KERN_WARNING "cciss: failed to unregister "
+ "32 bit compatible ioctl 0x%08x\n",
+ cciss_ioctl32_map[i].cmd);
+ }
+}
+int cciss_ioctl32_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
+ struct file *file)
+{
+ IOCTL32_Command_struct *arg32 =
+ (IOCTL32_Command_struct *) arg;
+ IOCTL_Command_struct arg64;
+ mm_segment_t old_fs;
+ int err;
+ unsigned long cp;
+
+ err = 0;
+ err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info));
+ err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request));
+ err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info));
+ err |= get_user(arg64.buf_size, &arg32->buf_size);
+ err |= get_user(cp, &arg32->buf);
+ arg64.buf = (BYTE *)cp;
+
+ if (err)
+ return -EFAULT;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, CCISS_PASSTHRU, (unsigned long) &arg64);
+ set_fs(old_fs);
+ if (err)
+ return err;
+ err |= copy_to_user(&arg32->error_info, &arg64.error_info, sizeof(&arg32->error_info));
+ if (err)
+ return -EFAULT;
+ return err;
+}
+int cciss_ioctl32_big_passthru(unsigned int fd, unsigned cmd, unsigned long arg,
+ struct file *file)
+{
+ BIG_IOCTL32_Command_struct *arg32 =
+ (BIG_IOCTL32_Command_struct *) arg;
+ BIG_IOCTL_Command_struct arg64;
+ mm_segment_t old_fs;
+ int err;
+ unsigned long cp;
+
+ err = 0;
+ err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, sizeof(arg64.LUN_info));
+ err |= copy_from_user(&arg64.Request, &arg32->Request, sizeof(arg64.Request));
+ err |= copy_from_user(&arg64.error_info, &arg32->error_info, sizeof(arg64.error_info));
+ err |= get_user(arg64.buf_size, &arg32->buf_size);
+ err |= get_user(arg64.malloc_size, &arg32->malloc_size);
+ err |= get_user(cp, &arg32->buf);
+ arg64.buf = (BYTE *)cp;
+
+ if (err)
+ return -EFAULT;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, CCISS_BIG_PASSTHRU, (unsigned long) &arg64);
+ set_fs(old_fs);
+ if (err)
+ return err;
+ err |= copy_to_user(&arg32->error_info, &arg64.error_info, sizeof(&arg32->error_info));
+ if (err)
+ return -EFAULT;
+ return err;
+}
+#else
+static inline void register_cciss_ioctl32(void) {}
+static inline void unregister_cciss_ioctl32(void) {}
+#endif
/*
* ioctl
*/
ctlr_info_t *host = get_host(disk);
drive_info_struct *drv = get_drv(disk);
int ctlr = host->ctlr;
+ void __user *argp = (void __user *)arg;
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
} else
return -ENXIO;
driver_geo.start= get_start_sect(inode->i_bdev);
- if (copy_to_user((void *) arg, &driver_geo,
- sizeof( struct hd_geometry)))
+ if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))
return -EFAULT;
return(0);
}
pciinfo.bus = host->pdev->bus->number;
pciinfo.dev_fn = host->pdev->devfn;
pciinfo.board_id = host->board_id;
- if (copy_to_user((void *) arg, &pciinfo, sizeof( cciss_pci_info_struct )))
+ if (copy_to_user(argp, &pciinfo, sizeof( cciss_pci_info_struct )))
return -EFAULT;
return(0);
}
if (!arg) return -EINVAL;
intinfo.delay = readl(&host->cfgtable->HostWrite.CoalIntDelay);
intinfo.count = readl(&host->cfgtable->HostWrite.CoalIntCount);
- if (copy_to_user((void *) arg, &intinfo, sizeof( cciss_coalint_struct )))
+ if (copy_to_user(argp, &intinfo, sizeof( cciss_coalint_struct )))
return -EFAULT;
return(0);
}
if (!arg) return -EINVAL;
if (!capable(CAP_SYS_ADMIN)) return -EPERM;
- if (copy_from_user(&intinfo, (void *) arg, sizeof( cciss_coalint_struct)))
+ if (copy_from_user(&intinfo, argp, sizeof( cciss_coalint_struct)))
return -EFAULT;
if ( (intinfo.delay == 0 ) && (intinfo.count == 0))
if (!arg) return -EINVAL;
for(i=0;i<16;i++)
NodeName[i] = readb(&host->cfgtable->ServerName[i]);
- if (copy_to_user((void *) arg, NodeName, sizeof( NodeName_type)))
+ if (copy_to_user(argp, NodeName, sizeof( NodeName_type)))
return -EFAULT;
return(0);
}
if (!arg) return -EINVAL;
if (!capable(CAP_SYS_ADMIN)) return -EPERM;
- if (copy_from_user(NodeName, (void *) arg, sizeof( NodeName_type)))
+ if (copy_from_user(NodeName, argp, sizeof( NodeName_type)))
return -EFAULT;
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (!arg) return -EINVAL;
heartbeat = readl(&host->cfgtable->HeartBeat);
- if (copy_to_user((void *) arg, &heartbeat, sizeof( Heartbeat_type)))
+ if (copy_to_user(argp, &heartbeat, sizeof( Heartbeat_type)))
return -EFAULT;
return(0);
}
if (!arg) return -EINVAL;
BusTypes = readl(&host->cfgtable->BusTypes);
- if (copy_to_user((void *) arg, &BusTypes, sizeof( BusTypes_type) ))
+ if (copy_to_user(argp, &BusTypes, sizeof( BusTypes_type) ))
return -EFAULT;
return(0);
}
if (!arg) return -EINVAL;
memcpy(firmware, host->firm_ver, 4);
- if (copy_to_user((void *) arg, firmware, sizeof( FirmwareVer_type)))
+ if (copy_to_user(argp, firmware, sizeof( FirmwareVer_type)))
return -EFAULT;
return(0);
}
if (!arg) return -EINVAL;
- if (copy_to_user((void *) arg, &DriverVer, sizeof( DriverVer_type) ))
+ if (copy_to_user(argp, &DriverVer, sizeof( DriverVer_type) ))
return -EFAULT;
return(0);
}
if (disk->part[i]->nr_sects != 0)
luninfo.num_parts++;
}
- if (copy_to_user((void *) arg, &luninfo,
+ if (copy_to_user(argp, &luninfo,
sizeof(LogvolInfo_struct)))
return -EFAULT;
return(0);
if (!capable(CAP_SYS_RAWIO)) return -EPERM;
- if (copy_from_user(&iocommand, (void *) arg, sizeof( IOCTL_Command_struct) ))
+ if (copy_from_user(&iocommand, argp, sizeof( IOCTL_Command_struct) ))
return -EFAULT;
if((iocommand.buf_size < 1) &&
(iocommand.Request.Type.Direction != XFER_NONE))
/* Copy the error information out */
iocommand.error_info = *(c->err_info);
- if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) )
+ if ( copy_to_user(argp, &iocommand, sizeof( IOCTL_Command_struct) ) )
{
kfree(buff);
cmd_free(host, c, 0);
DECLARE_COMPLETION(wait);
__u32 left;
__u32 sz;
- BYTE *data_ptr;
+ BYTE __user *data_ptr;
if (!arg)
return -EINVAL;
status = -ENOMEM;
goto cleanup1;
}
- if (copy_from_user(ioc, (void *) arg, sizeof(*ioc))) {
+ if (copy_from_user(ioc, argp, sizeof(*ioc))) {
status = -EFAULT;
goto cleanup1;
}
goto cleanup1;
}
left = ioc->buf_size;
- data_ptr = (BYTE *) ioc->buf;
+ data_ptr = ioc->buf;
while (left) {
sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
buff_size[sg_used] = sz;
}
/* Copy the error information out */
ioc->error_info = *(c->err_info);
- if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) {
+ if (copy_to_user(argp, ioc, sizeof(*ioc))) {
cmd_free(host, c, 0);
status = -EFAULT;
goto cleanup1;
}
if (ioc->Request.Type.Direction == XFER_READ) {
/* Copy the data out of the buffer we created */
- BYTE *ptr = (BYTE *) ioc->buf;
+ BYTE __user *ptr = ioc->buf;
for(i=0; i< sg_used; i++) {
if (copy_to_user(ptr, buff[i], buff_size[i])) {
cmd_free(host, c, 0);
return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL);
}
-/*
- * Enqueuing and dequeuing functions for cmdlists.
- */
-static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c)
-{
- if (*Qptr == NULL) {
- *Qptr = c;
- c->next = c->prev = c;
- } else {
- c->prev = (*Qptr)->prev;
- c->next = (*Qptr);
- (*Qptr)->prev->next = c;
- (*Qptr)->prev = c;
- }
-}
-
-static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
- CommandList_struct *c)
-{
- if (c && c->next != c) {
- if (*Qptr == c) *Qptr = c->next;
- c->prev->next = c->next;
- c->next->prev = c->prev;
- } else {
- *Qptr = NULL;
- }
- return c;
-}
-
/*
* Takes jobs of the Q and sends them to the hardware, then puts it on
* the Q to wait for completion.
static int __init init_cciss_module(void)
{
+ register_cciss_ioctl32();
return ( cciss_init());
}
{
int i;
+ unregister_cciss_ioctl32();
pci_unregister_driver(&cciss_pci_driver);
/* double check that all controller entrys have been removed */
for (i=0; i< MAX_CTLR; i++)
physical nor logical disks are presented through the scsi layer. */
#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
+#include <scsi/scsi_host.h>
#include <asm/atomic.h>
#include <linux/timer.h>
#include <linux/completion.h>
unsigned int max_queued;
mempool_t *crq_pool;
+
+ request_queue_t *queue;
+
+ /*
+ * tunables
+ */
+ unsigned int cfq_quantum;
+ unsigned int cfq_queued;
};
struct cfq_queue {
static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq);
static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid);
-static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq);
+static void cfq_dispatch_sort(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+ struct cfq_rq *crq);
/*
* lots of deadline iosched dupes, can be abstracted later...
return;
}
- cfq_del_crq_rb(cfqq, __alias);
- cfq_dispatch_sort(cfqd->dispatch, __alias);
+ cfq_dispatch_sort(cfqd, cfqq, __alias);
goto retry;
}
cfq_remove_request(q, next);
}
-static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq)
+static void
+cfq_dispatch_sort(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+ struct cfq_rq *crq)
{
- struct list_head *entry = head;
+ struct list_head *head = cfqd->dispatch, *entry = head;
struct request *__rq;
+ cfq_del_crq_rb(cfqq, crq);
+ cfq_remove_merge_hints(cfqd->queue, crq);
+
if (!list_empty(head)) {
__rq = list_entry_rq(head->next);
{
struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list));
- cfq_del_crq_rb(cfqq, crq);
- cfq_remove_merge_hints(q, crq);
- cfq_dispatch_sort(cfqd->dispatch, crq);
+ cfq_dispatch_sort(cfqd, cfqq, crq);
}
static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
ret = 1;
}
- if ((queued < cfq_quantum) && good_queues)
+ if ((queued < cfqd->cfq_quantum) && good_queues)
goto restart;
return ret;
cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
if (cfqq) {
- int limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues;
+ int limit = (q->nr_requests - cfqd->cfq_queued) / cfqd->busy_queues;
if (limit < 3)
limit = 3;
{
struct cfq_data *cfqd = q->elevator.elevator_data;
struct cfq_rq *crq = RQ_DATA(rq);
+ struct request_list *rl;
+ int other_rw;
if (crq) {
BUG_ON(q->last_merge == rq);
mempool_free(crq, cfqd->crq_pool);
rq->elevator_private = NULL;
}
+
+ /*
+ * work-around for may_queue "bug": if a read gets issued and refused
+ * to queue because writes ate all the allowed slots and no other
+ * reads are pending for this queue, it could get stuck infinitely
+ * since freed_request() only checks the waitqueue for writes when
+ * freeing them. or vice versa for a single write vs many reads.
+ * so check here whether "the other" data direction might be able
+ * to queue and wake them
+ */
+ rl = &q->rq;
+ other_rw = rq_data_dir(rq) ^ 1;
+ if (rl->count[other_rw] <= q->nr_requests) {
+ smp_mb();
+ if (waitqueue_active(&rl->wait[other_rw]))
+ wake_up(&rl->wait[other_rw]);
+ }
}
static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
cfqd->dispatch = &q->queue_head;
e->elevator_data = cfqd;
+ cfqd->queue = q;
/*
* just set it to some high value, we want anyone to be able to queue
cfqd->max_queued = q->nr_requests;
q->nr_requests = 8192;
+ cfqd->cfq_queued = cfq_queued;
+ cfqd->cfq_quantum = cfq_quantum;
+
return 0;
out_crqpool:
kfree(cfqd->cfq_hash);
subsys_initcall(cfq_slab_setup);
+/*
+ * sysfs parts below -->
+ */
+struct cfq_fs_entry {
+ struct attribute attr;
+ ssize_t (*show)(struct cfq_data *, char *);
+ ssize_t (*store)(struct cfq_data *, const char *, size_t);
+};
+
+static ssize_t
+cfq_var_show(unsigned int var, char *page)
+{
+ return sprintf(page, "%d\n", var);
+}
+
+static ssize_t
+cfq_var_store(unsigned int *var, const char *page, size_t count)
+{
+ char *p = (char *) page;
+
+ *var = simple_strtoul(p, &p, 10);
+ return count;
+}
+
+#define SHOW_FUNCTION(__FUNC, __VAR) \
+static ssize_t __FUNC(struct cfq_data *cfqd, char *page) \
+{ \
+ return cfq_var_show(__VAR, (page)); \
+}
+SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum);
+SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued);
+#undef SHOW_FUNCTION
+
+#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \
+static ssize_t __FUNC(struct cfq_data *cfqd, const char *page, size_t count) \
+{ \
+ int ret = cfq_var_store(__PTR, (page), count); \
+ if (*(__PTR) < (MIN)) \
+ *(__PTR) = (MIN); \
+ else if (*(__PTR) > (MAX)) \
+ *(__PTR) = (MAX); \
+ return ret; \
+}
+STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, INT_MAX);
+STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, INT_MAX);
+#undef STORE_FUNCTION
+
+static struct cfq_fs_entry cfq_quantum_entry = {
+ .attr = {.name = "quantum", .mode = S_IRUGO | S_IWUSR },
+ .show = cfq_quantum_show,
+ .store = cfq_quantum_store,
+};
+static struct cfq_fs_entry cfq_queued_entry = {
+ .attr = {.name = "queued", .mode = S_IRUGO | S_IWUSR },
+ .show = cfq_queued_show,
+ .store = cfq_queued_store,
+};
+
+static struct attribute *default_attrs[] = {
+ &cfq_quantum_entry.attr,
+ &cfq_queued_entry.attr,
+ NULL,
+};
+
+#define to_cfq(atr) container_of((atr), struct cfq_fs_entry, attr)
+
+static ssize_t
+cfq_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+ elevator_t *e = container_of(kobj, elevator_t, kobj);
+ struct cfq_fs_entry *entry = to_cfq(attr);
+
+ if (!entry->show)
+ return 0;
+
+ return entry->show(e->elevator_data, page);
+}
+
+static ssize_t
+cfq_attr_store(struct kobject *kobj, struct attribute *attr,
+ const char *page, size_t length)
+{
+ elevator_t *e = container_of(kobj, elevator_t, kobj);
+ struct cfq_fs_entry *entry = to_cfq(attr);
+
+ if (!entry->store)
+ return -EINVAL;
+
+ return entry->store(e->elevator_data, page, length);
+}
+
+static struct sysfs_ops cfq_sysfs_ops = {
+ .show = cfq_attr_show,
+ .store = cfq_attr_store,
+};
+
+struct kobj_type cfq_ktype = {
+ .sysfs_ops = &cfq_sysfs_ops,
+ .default_attrs = default_attrs,
+};
+
elevator_t iosched_cfq = {
.elevator_name = "cfq",
+ .elevator_ktype = &cfq_ktype,
.elevator_merge_fn = cfq_merge,
.elevator_merged_fn = cfq_merged_request,
.elevator_merge_req_fn = cfq_merged_requests,
ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
int error;
int diskinfo[4];
- struct hd_geometry *geo = (struct hd_geometry *)arg;
- ida_ioctl_t *io = (ida_ioctl_t*)arg;
+ struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
+ ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
ida_ioctl_t *my_io;
switch(cmd) {
return error;
case IDAGETCTLRSIG:
if (!arg) return -EINVAL;
- put_user(host->ctlr_sig, (int*)arg);
+ put_user(host->ctlr_sig, (int __user *)arg);
return 0;
case IDAREVALIDATEVOLS:
if (iminor(inode) != 0)
return revalidate_allvol(host);
case IDADRIVERVERSION:
if (!arg) return -EINVAL;
- put_user(DRIVER_VERSION, (unsigned long*)arg);
+ put_user(DRIVER_VERSION, (unsigned long __user *)arg);
return 0;
case IDAGETPCIINFO:
{
pciinfo.bus = host->pci_dev->bus->number;
pciinfo.dev_fn = host->pci_dev->devfn;
pciinfo.board_id = host->board_id;
- if(copy_to_user((void *) arg, &pciinfo,
+ if(copy_to_user((void __user *) arg, &pciinfo,
sizeof( ida_pci_info_struct)))
return -EFAULT;
return(0);
cmd_free(h, c, 0);
return(error);
}
- if (copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size)) {
+ if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
kfree(p);
cmd_free(h, c, 0);
return -EFAULT;
cmd_free(h, c, 0);
return(error);
}
- if (copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size)) {
+ if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) {
kfree(p);
cmd_free(h, c, 0);
return -EFAULT;
case DIAG_PASS_THRU:
case SENSE_CONTROLLER_PERFORMANCE:
case READ_FLASH_ROM:
- if (copy_to_user((void*)io->sg[0].addr, p, io->sg[0].size)) {
+ if (copy_to_user(io->sg[0].addr, p, io->sg[0].size)) {
kfree(p);
return -EFAULT;
}
rq->q = q;
q->elevator.elevator_add_req_fn(q, rq, where);
+
+ if (blk_queue_plugged(q)) {
+ int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight;
+
+ if (nrq == q->unplug_thresh)
+ __generic_unplug_device(q);
+ }
+
}
void elv_add_request(request_queue_t *q, struct request *rq, int where,
}
disks[dr]->major = FLOPPY_MAJOR;
- disks[dr]->first_minor = TOMINOR(i);
+ disks[dr]->first_minor = TOMINOR(dr);
disks[dr]->fops = &floppy_fops;
sprintf(disks[dr]->disk_name, "fd%d", dr);
/* currently, sg_cnt is assumed to be 1: only the 0th element of sg is used */
struct {
- void *addr;
+ void __user *addr;
size_t size;
} sg[SG_MAX];
int sg_cnt;
/*
* remove the plug and let it rip..
*/
-static inline void __generic_unplug_device(request_queue_t *q)
+inline void __generic_unplug_device(request_queue_t *q)
{
if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
return;
if (elv_next_request(q))
q->request_fn(q);
}
+EXPORT_SYMBOL(__generic_unplug_device);
/**
* generic_unplug_device - fire a request queue
out:
if (freereq)
__blk_put_request(q, freereq);
+ if (bio_sync(bio))
+ __generic_unplug_device(q);
- if (blk_queue_plugged(q)) {
- int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight;
-
- if (nrq == q->unplug_thresh || bio_sync(bio))
- __generic_unplug_device(q);
- }
spin_unlock_irq(q->queue_lock);
return 0;
page->index);
desc->error = -EINVAL;
}
-
+
+ flush_dcache_page(p->page);
+
desc->count = count - size;
desc->written += size;
p->offset += size;
#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0))
#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0))
+static int epatc8;
+
+module_param(epatc8, int, 0);
+MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, "
+ "used in any recent Imation SuperDisk (LS-120) drive.");
+
/* cont = 0 IDE register file
cont = 1 IDE control registers
cont = 2 internal EPAT registers
{ pi->saved_r0 = r0();
pi->saved_r2 = r2();
-#ifdef CONFIG_PARIDE_EPATC8
/* Initialize the chip */
- CPP(0);CPP(0x40);CPP(0xe0);
- w0(0);w2(1);w2(4);
- WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
- WR(0xe,0xf);WR(0xf,4);
- /* WR(0xe,0xa);WR(0xf,4); */
- WR(0xe,0xd);WR(0xf,0);
- /* CPP(0x30); */
+ CPP(0);
+
+ if (epatc8) {
+ CPP(0x40);CPP(0xe0);
+ w0(0);w2(1);w2(4);
+ WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
+ WR(0xe,0xf);WR(0xf,4);
+ /* WR(0xe,0xa);WR(0xf,4); */
+ WR(0xe,0xd);WR(0xf,0);
+ /* CPP(0x30); */
+ }
/* Connect to the chip */
CPP(0xe0);
/* Request EPP */
w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
}
-#else
- CPP(0); CPP(0xe0);
- w0(0); w2(1); w2(4);
- if (pi->mode >= 3) {
- w0(0); w2(1); w2(4); w2(0xc);
- w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4);
+
+ if (!epatc8) {
+ WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
}
- WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
-#endif
}
static void epat_disconnect (PIA *pi)
static int __init epat_init(void)
{
+#ifdef CONFIG_PARIDE_EPATC8
+ epatc8 = 1;
+#endif
return pi_register(&epat)-1;
}
static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
- struct hd_geometry *geo = (struct hd_geometry *) arg;
+ struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
struct hd_geometry g;
sector_t capacity;
static int pg_open(struct inode *inode, struct file *file);
static int pg_release(struct inode *inode, struct file *file);
-static ssize_t pg_read(struct file *filp, char *buf,
+static ssize_t pg_read(struct file *filp, char __user *buf,
size_t count, loff_t * ppos);
-static ssize_t pg_write(struct file *filp, const char *buf,
+static ssize_t pg_write(struct file *filp, const char __user *buf,
size_t count, loff_t * ppos);
static int pg_detect(void);
return 0;
}
-static ssize_t pg_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+static ssize_t pg_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
{
struct pg *dev = filp->private_data;
struct pg_write_hdr hdr;
if (count < hs)
return -EINVAL;
- if (copy_from_user((char *) &hdr, buf, hs))
+ if (copy_from_user(&hdr, buf, hs))
return -EFAULT;
if (hdr.magic != PG_MAGIC)
return count;
}
-static ssize_t pg_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
struct pg *dev = filp->private_data;
struct pg_read_hdr hdr;
hdr.duration = (jiffies - dev->start + HZ / 2) / HZ;
hdr.scsi = dev->status & 0x0f;
- if (copy_to_user(buf, (char *) &hdr, hs))
+ if (copy_to_user(buf, &hdr, hs))
return -EFAULT;
if (copy > 0)
if (copy_to_user(buf + hs, dev->bufptr, copy))
static int pt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static int pt_release(struct inode *inode, struct file *file);
-static ssize_t pt_read(struct file *filp, char *buf,
+static ssize_t pt_read(struct file *filp, char __user *buf,
size_t count, loff_t * ppos);
-static ssize_t pt_write(struct file *filp, const char *buf,
+static ssize_t pt_write(struct file *filp, const char __user *buf,
size_t count, loff_t * ppos);
static int pt_detect(void);
unsigned int cmd, unsigned long arg)
{
struct pt_unit *tape = file->private_data;
+ struct mtop __user *p = (void __user *)arg;
struct mtop mtop;
switch (cmd) {
case MTIOCTOP:
- if (copy_from_user((char *) &mtop, (char *) arg,
- sizeof (struct mtop)))
+ if (copy_from_user(&mtop, p, sizeof(struct mtop)))
return -EFAULT;
switch (mtop.mt_op) {
}
-static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
{
struct pt_unit *tape = filp->private_data;
struct pi_adapter *pi = tape->pi;
}
-static ssize_t pt_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
{
struct pt_unit *tape = filp->private_data;
struct pi_adapter *pi = tape->pi;
struct file *file, u_int cmd, u_long arg)
{
struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data;
- struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
- int err;
+ struct ps2esdi_geometry geom;
if (cmd != HDIO_GETGEO)
return -EINVAL;
- if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
- return (err);
- put_user(p->head, (char *) &geometry->heads);
- put_user(p->sect, (char *) &geometry->sectors);
- put_user(p->cyl, (short *) &geometry->cylinders);
- put_user(get_start_sect(inode->i_bdev), (long *) &geometry->start);
+ memset(&geom, 0, sizeof(geom));
+ geom.heads = p->head;
+ geom.sectors = p->sect;
+ geom.cylinders = p->cyl;
+ geom.start = get_start_sect(inode->i_bdev);
+ if (copy_to_user((void __user *)arg, &geom, sizeof(geom)))
+ return -EFAULT;
return 0;
}
struct buffer_head *head = bh;
do {
- if (!buffer_uptodate(bh))
+ if (!buffer_uptodate(bh)) {
memset(bh->b_data, 0, bh->b_size);
+ /*
+ * akpm: I'm totally undecided about this. The
+ * buffer has just been magically brought "up to
+ * date", but nobody should want to be reading
+ * it anyway, because it hasn't been used for
+ * anything yet. It is still in a "not read
+ * from disk yet" state.
+ *
+ * But non-uptodate buffers against an uptodate
+ * page are against the rules. So do it anyway.
+ */
+ set_buffer_uptodate(bh);
+ }
} while ((bh = bh->b_this_page) != head);
} else {
memset(page_address(page), 0, PAGE_CACHE_SIZE);
geo.start = get_start_sect(i->i_bdev);
geo.cylinders = size / (geo.heads * geo.sectors);
- if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+ if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))
return -EFAULT;
return 0;
}
case HDIO_GETGEO:
{
struct hd_geometry g;
- struct hd_geometry *geometry = (struct hd_geometry *) arg;
+ struct hd_geometry __user *geom= (void __user *)arg;
g.heads = p->heads;
g.sectors = p->sectors;
g.cylinders = p->cylinders;
g.start = get_start_sect(inode->i_bdev);
- return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
+ return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;
}
case HDIO_SET_DMA:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
}
return 0;
case HDIO_GET_DMA:
- return put_user(!nodma, (long *) arg);
+ return put_user(!nodma, (long __user *) arg);
case HDIO_GET_MULTCOUNT:
- return put_user(xd_maxsectors, (long *) arg);
+ return put_user(xd_maxsectors, (long __user *) arg);
default:
return -EINVAL;
}
/*
* We don't provide read/write/poll interface for user space.
*/
-static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr)
{
return 0;
}
-static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char __user *data, size_t count)
{
return 0;
}
}
/* Get packet from user space buffer(already verified) */
-static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char *buf, size_t count)
+static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char __user *buf, size_t count)
{
struct sk_buff *skb;
}
/* Write */
-static ssize_t hci_vhci_chr_write(struct file * file, const char * buf,
+static ssize_t hci_vhci_chr_write(struct file * file, const char __user * buf,
size_t count, loff_t *pos)
{
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
/* Put packet to user space buffer(already verified) */
static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
- struct sk_buff *skb, char *buf, int count)
+ struct sk_buff *skb, char __user *buf,
+ int count)
{
int len = count, total = 0;
- char *ptr = buf;
+ char __user *ptr = buf;
len = min_t(unsigned int, skb->len, len);
if (copy_to_user(ptr, skb->data, len))
}
/* Read */
-static ssize_t hci_vhci_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
+static ssize_t hci_vhci_chr_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
{
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
DECLARE_WAITQUEUE(wait, current);
/* Read the table of contents header, i.e. no. of tracks and start of first
* track
*/
-static int aztGetDiskInfo()
+static int aztGetDiskInfo(void)
{
int limit;
unsigned char test;
struct azt_Toc *tocPtr;
struct cdrom_subchnl subchnl;
struct cdrom_volctrl volctrl;
+ void __user *argp = (void __user *)arg;
#ifdef AZT_DEBUG
printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
#ifdef AZT_DEBUG
printk("aztcd ioctl MULTISESSION\n");
#endif
- if (copy_from_user
- (&ms, (void *) arg,
+ if (copy_from_user(&ms, argp,
sizeof(struct cdrom_multisession)))
return -EFAULT;
if (ms.addr_format == CDROM_MSF) {
else
return -EINVAL;
ms.xa_flag = DiskInfo.xa;
- if (copy_to_user
- ((void *) arg, &ms,
+ if (copy_to_user(argp, &ms,
sizeof(struct cdrom_multisession)))
return -EFAULT;
#ifdef AZT_DEBUG
return 0;
}
case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- if (copy_from_user(&ti, (void *) arg, sizeof ti))
+ if (copy_from_user(&ti, argp, sizeof ti))
return -EFAULT;
if (ti.cdti_trk0 < DiskInfo.first
|| ti.cdti_trk0 > DiskInfo.last
aztAudioStatus = CDROM_AUDIO_NO_STATUS;
}
*/
- if (copy_from_user(&msf, (void *) arg, sizeof msf))
+ if (copy_from_user(&msf, argp, sizeof msf))
return -EFAULT;
/* convert to bcd */
azt_bin2bcd(&msf.cdmsf_min0);
case CDROMREADTOCHDR: /* Read the table of contents header */
tocHdr.cdth_trk0 = DiskInfo.first;
tocHdr.cdth_trk1 = DiskInfo.last;
- if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
+ if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
return -EFAULT;
break;
case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
- if (copy_from_user(&entry, (void *) arg, sizeof entry))
+ if (copy_from_user(&entry, argp, sizeof entry))
return -EFAULT;
if ((!aztTocUpToDate) || aztDiskChanged)
aztUpdateToc();
} else {
return -EINVAL;
}
- if (copy_to_user((void *) arg, &entry, sizeof entry))
+ if (copy_to_user(argp, &entry, sizeof entry))
return -EFAULT;
break;
case CDROMSUBCHNL: /* Get subchannel info */
if (copy_from_user
- (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
+ (&subchnl, argp, sizeof(struct cdrom_subchnl)))
return -EFAULT;
if (aztGetQChannelInfo(&qInfo) < 0) {
#ifdef AZT_DEBUG
subchnl.cdsc_reladdr.msf.frame =
azt_bcd2bin(qInfo.trackTime.frame);
}
- if (copy_to_user
- ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
+ if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
return -EFAULT;
break;
case CDROMVOLCTRL: /* Volume control
* With my Aztech CD268-01A volume control does not work, I can only
turn the channels on (any value !=0) or off (value==0). Maybe it
works better with your drive */
- if (copy_from_user
- (&volctrl, (char *) arg, sizeof(volctrl)))
+ if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
return -EFAULT;
azt_Play.start.min = 0x21;
azt_Play.start.sec = 0x84;
case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
{
- if (copy_from_user(&msf, (void *) arg, sizeof msf))
+ if (copy_from_user(&msf, argp, sizeof msf))
return -EFAULT;
/* convert to bcd */
azt_bin2bcd(&msf.cdmsf_min0);
if (DiskInfo.xa) {
return -1; /*XA Disks can't be read raw */
} else {
- if (sendAztCmd
- (ACMD_PLAY_READ_RAW,
- &azt_Play))
+ if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
return -1;
DTEN_LOW;
- insb(DATA_PORT, buf,
- CD_FRAMESIZE_RAW);
- if (copy_to_user
- ((void *) arg, &buf,
- CD_FRAMESIZE_RAW))
+ insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
+ if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
return -EFAULT;
}
} else
return -1;
DTEN_LOW;
insb(DATA_PORT, buf, CD_FRAMESIZE);
- if (copy_to_user
- ((void *) arg, &buf, CD_FRAMESIZE))
+ if (copy_to_user(argp, &buf, CD_FRAMESIZE))
return -EFAULT;
}
}
break;
case CDROMSEEK: /*seek msf address */
- if (copy_from_user(&msf, (void *) arg, sizeof msf))
+ if (copy_from_user(&msf, argp, sizeof msf))
return -EFAULT;
/* convert to bcd */
azt_bin2bcd(&msf.cdmsf_min0);
unsigned char buffer[16];
int ret;
+ *write = 0;
+
init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
*write = mfd->write;
- if ((ret = cdrom_mrw_probe_pc(cdi)))
+ if ((ret = cdrom_mrw_probe_pc(cdi))) {
+ *write = 0;
return ret;
+ }
return 0;
}
{
struct packet_command cgc;
char buffer[24];
- struct feature_header *fh;
int ret;
init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
return ret;
- fh = (struct feature_header *)&buffer[0];
- if (be32_to_cpu(fh->data_len) >= (sizeof(struct feature_header)+
- sizeof(struct rwrt_feature_desc)))
- memcpy(rfd, &buffer[sizeof(struct feature_header)],
- sizeof (*rfd));
- else
- memset(rfd, 0, sizeof(*rfd));
-
+ memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
return 0;
}
{
struct packet_command cgc;
char buffer[16];
- struct feature_header *fh;
__u16 *feature_code;
int ret;
init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
- cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
- cgc.cmd[3] = CDF_HWDM; /* often 0x0024 */
- cgc.cmd[8] = sizeof(buffer); /* often 0x10 */
+ cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
+ cgc.cmd[3] = CDF_HWDM;
+ cgc.cmd[8] = sizeof(buffer);
cgc.quiet = 1;
if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
return ret;
- fh = (struct feature_header *)&buffer[0];
- ret = 1;
- if (be32_to_cpu(fh->data_len) >= (sizeof(struct feature_header)+8)) {
- feature_code = (__u16 *)&buffer[sizeof(struct feature_header)];
- if (CDF_HWDM == be16_to_cpu(*feature_code))
- ret = 0;
- }
- return ret;
+ feature_code = (__u16 *) &buffer[sizeof(struct feature_header)];
+ if (be16_to_cpu(*feature_code) == CDF_HWDM)
+ return 0;
+
+ return 1;
}
*/
static int cdrom_open_write(struct cdrom_device_info *cdi)
{
+ int mrw, mrw_write, ram_write;
int ret = 1;
+ mrw = 0;
+ if (!cdrom_is_mrw(cdi, &mrw_write))
+ mrw = 1;
+
+ (void) cdrom_is_random_writable(cdi, &ram_write);
+
+ if (mrw)
+ cdi->mask &= ~CDC_MRW;
+ else
+ cdi->mask |= CDC_MRW;
+
+ if (mrw_write)
+ cdi->mask &= ~CDC_MRW_W;
+ else
+ cdi->mask |= CDC_MRW_W;
+
+ if (ram_write)
+ cdi->mask &= ~CDC_RAM;
+ else
+ cdi->mask |= CDC_RAM;
+
if (CDROM_CAN(CDC_MRW_W))
ret = cdrom_mrw_open_write(cdi);
else if (CDROM_CAN(CDC_DVD_RAM))
if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
ret = cdi->ops->open(cdi, 1);
} else {
+ ret = open_for_data(cdi);
+ if (ret)
+ goto err;
if (fp->f_mode & FMODE_WRITE) {
ret = -EROFS;
if (!CDROM_CAN(CDC_RAM))
if (cdrom_open_write(cdi))
goto err;
}
- ret = open_for_data(cdi);
}
if (ret)
retval = -EIO;
goto exit_read_audio;
}
- } else if (copy_to_user((char *)(ra->buf +
+ } else if (copy_to_user(ra->buf +
(CD_FRAMESIZE_RAW
- * cframe)),
- (char *)
- readahead_buffer,
+ * cframe),
+ readahead_buffer,
CD_FRAMESIZE_RAW)) {
retval = -EFAULT;
goto exit_read_audio;
retval = -EIO;
goto exit_read_audio;
}
- } else if (copy_to_user((char *)(ra->buf + (CD_FRAMESIZE_RAW *
- cframe)),
+ } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
(char *)readahead_buffer,
CD_FRAMESIZE_RAW)) {
retval = -EFAULT;
static int scd_dev_ioctl(struct cdrom_device_info *cdi,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
int i;
switch (cmd) {
return -EIO;
}
- if (copy_from_user(&ra, (char *) arg, sizeof(ra)))
+ if (copy_from_user(&ra, argp, sizeof(ra)))
return -EFAULT;
if (ra.nframes == 0) {
}
-static int cdromplaymsf(unsigned long arg)
+static int cdromplaymsf(void __user *arg)
{
int status;
struct cdrom_msf msf;
- if (copy_from_user(&msf, (void *) arg, sizeof msf))
+ if (copy_from_user(&msf, arg, sizeof msf))
return -EFAULT;
bin2bcd(&msf);
}
-static int cdromplaytrkind(unsigned long arg)
+static int cdromplaytrkind(void __user *arg)
{
int status;
struct cdrom_ti ti;
struct cdrom_msf msf;
- if (copy_from_user(&ti, (void *) arg, sizeof ti))
+ if (copy_from_user(&ti, arg, sizeof ti))
return -EFAULT;
if (ti.cdti_trk0 < disk_info.first
}
-static int cdromreadtochdr(unsigned long arg)
+static int cdromreadtochdr(void __user *arg)
{
struct cdrom_tochdr tochdr;
tochdr.cdth_trk0 = disk_info.first;
tochdr.cdth_trk1 = disk_info.last;
- return copy_to_user((void *)arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
+ return copy_to_user(arg, &tochdr, sizeof tochdr) ? -EFAULT : 0;
}
-static int cdromreadtocentry(unsigned long arg)
+static int cdromreadtocentry(void __user *arg)
{
struct cdrom_tocentry entry;
struct cdrom_subchnl *tocptr;
- if (copy_from_user(&entry, (void *) arg, sizeof entry))
+ if (copy_from_user(&entry, arg, sizeof entry))
return -EFAULT;
if (entry.cdte_track == CDROM_LEADOUT)
else if (entry.cdte_format != CDROM_MSF)
return -EINVAL;
- return copy_to_user((void *)arg, &entry, sizeof entry) ? -EFAULT : 0;
+ return copy_to_user(arg, &entry, sizeof entry) ? -EFAULT : 0;
}
-static int cdromvolctrl(unsigned long arg)
+static int cdromvolctrl(void __user *arg)
{
int status;
struct cdrom_volctrl volctrl;
struct cdrom_msf msf;
- if (copy_from_user(&volctrl, (char *) arg, sizeof volctrl))
+ if (copy_from_user(&volctrl, arg, sizeof volctrl))
return -EFAULT;
msf.cdmsf_min0 = 0x10;
}
-static int cdromsubchnl(unsigned long arg)
+static int cdromsubchnl(void __user *arg)
{
int status;
struct cdrom_subchnl subchnl;
- if (copy_from_user(&subchnl, (void *) arg, sizeof subchnl))
+ if (copy_from_user(&subchnl, arg, sizeof subchnl))
return -EFAULT;
if (subchnl.cdsc_format != CDROM_LBA
return -EIO;
}
- if (copy_to_user((void *)arg, &subchnl, sizeof subchnl))
+ if (copy_to_user(arg, &subchnl, sizeof subchnl))
return -EFAULT;
return 0;
}
static struct gendisk *optcd_disk;
-static int cdromread(unsigned long arg, int blocksize, int cmd)
+static int cdromread(void __user *arg, int blocksize, int cmd)
{
int status;
struct cdrom_msf msf;
- if (copy_from_user(&msf, (void *) arg, sizeof msf))
+ if (copy_from_user(&msf, arg, sizeof msf))
return -EFAULT;
bin2bcd(&msf);
fetch_data(optcd_disk->private_data, blocksize);
- if (copy_to_user((void *)arg, optcd_disk->private_data, blocksize))
+ if (copy_to_user(arg, optcd_disk->private_data, blocksize))
return -EFAULT;
return 0;
}
-static int cdromseek(unsigned long arg)
+static int cdromseek(void __user *arg)
{
int status;
struct cdrom_msf msf;
- if (copy_from_user(&msf, (void *)arg, sizeof msf))
+ if (copy_from_user(&msf, arg, sizeof msf))
return -EFAULT;
bin2bcd(&msf);
#ifdef MULTISESSION
-static int cdrommultisession(unsigned long arg)
+static int cdrommultisession(void __user *arg)
{
struct cdrom_multisession ms;
- if (copy_from_user(&ms, (void*) arg, sizeof ms))
+ if (copy_from_user(&ms, arg, sizeof ms))
return -EFAULT;
ms.addr.msf.minute = disk_info.last_session.minute;
ms.xa_flag = disk_info.xa;
- if (copy_to_user((void *)arg, &ms, sizeof(struct cdrom_multisession)))
+ if (copy_to_user(arg, &ms, sizeof(struct cdrom_multisession)))
return -EFAULT;
#if DEBUG_MULTIS
unsigned int cmd, unsigned long arg)
{
int status, err, retval = 0;
+ void __user *argp = (void __user *)arg;
DEBUG((DEBUG_VFS, "starting opt_ioctl"));
switch (cmd) {
case CDROMPAUSE: retval = cdrompause(); break;
case CDROMRESUME: retval = cdromresume(); break;
- case CDROMPLAYMSF: retval = cdromplaymsf(arg); break;
- case CDROMPLAYTRKIND: retval = cdromplaytrkind(arg); break;
- case CDROMREADTOCHDR: retval = cdromreadtochdr(arg); break;
- case CDROMREADTOCENTRY: retval = cdromreadtocentry(arg); break;
+ case CDROMPLAYMSF: retval = cdromplaymsf(argp); break;
+ case CDROMPLAYTRKIND: retval = cdromplaytrkind(argp); break;
+ case CDROMREADTOCHDR: retval = cdromreadtochdr(argp); break;
+ case CDROMREADTOCENTRY: retval = cdromreadtocentry(argp); break;
case CDROMSTOP: err = exec_cmd(COMSTOP);
if (err < 0) {
}
break;
- case CDROMVOLCTRL: retval = cdromvolctrl(arg); break;
- case CDROMSUBCHNL: retval = cdromsubchnl(arg); break;
+ case CDROMVOLCTRL: retval = cdromvolctrl(argp); break;
+ case CDROMSUBCHNL: retval = cdromsubchnl(argp); break;
/* The drive detects the mode and automatically delivers the
correct 2048 bytes, so we don't need these IOCTLs */
break;
#ifdef MULTISESSION
- case CDROMMULTISESSION: retval = cdrommultisession(arg); break;
+ case CDROMMULTISESSION: retval = cdrommultisession(argp); break;
#endif
case CDROM_GET_MCN: retval = -EINVAL; break; /* not implemented */
case CDROMREADRAW:
/* this drive delivers 2340 bytes in raw mode */
- retval = cdromread(arg, CD_FRAMESIZE_RAW1, COMREADRAW);
+ retval = cdromread(argp, CD_FRAMESIZE_RAW1, COMREADRAW);
break;
case CDROMREADCOOKED:
- retval = cdromread(arg, CD_FRAMESIZE, COMREAD);
+ retval = cdromread(argp, CD_FRAMESIZE, COMREAD);
break;
case CDROMREADALL:
- retval = cdromread(arg, CD_FRAMESIZE_RAWER, COMREADALL);
+ retval = cdromread(argp, CD_FRAMESIZE_RAWER, COMREADALL);
break;
- case CDROMSEEK: retval = cdromseek(arg); break;
+ case CDROMSEEK: retval = cdromseek(argp); break;
case CDROMPLAYBLK: retval = -EINVAL; break; /* not implemented */
case CDROMCLOSETRAY: break; /* The action was taken earlier */
default: retval = -EINVAL;
static int sjcd_ioctl(struct inode *ip, struct file *fp,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
#if defined( SJCD_TRACE )
printk("SJCD:ioctl\n");
#endif
- if (ip == NULL)
- return (-EINVAL);
-
sjcd_get_status();
if (!sjcd_status_valid)
return (-EIO);
#if defined( SJCD_TRACE )
printk("SJCD: ioctl: playtrkind\n");
#endif
- if (!copy_from_user(&ti, (void *) arg, sizeof(ti))) {
+ if (!copy_from_user(&ti, argp, sizeof(ti))) {
s = 0;
if (ti.cdti_trk0 < sjcd_first_track_no)
return (-EINVAL);
printk("SJCD: ioctl: playmsf\n");
#endif
if ((s =
- verify_area(VERIFY_READ, (void *) arg,
+ verify_area(VERIFY_READ, argp,
sizeof(sjcd_msf))) == 0) {
if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
sjcd_send_cmd(SCMD_PAUSE);
CDROM_AUDIO_NO_STATUS;
}
- if (copy_from_user(&sjcd_msf, (void *) arg,
+ if (copy_from_user(&sjcd_msf, argp,
sizeof(sjcd_msf)))
return (-EFAULT);
#endif
toc_header.cdth_trk0 = sjcd_first_track_no;
toc_header.cdth_trk1 = sjcd_last_track_no;
- if (copy_to_user((void *)arg, &toc_header,
+ if (copy_to_user(argp, &toc_header,
sizeof(toc_header)))
return -EFAULT;
return 0;
printk("SJCD: ioctl: readtocentry\n");
#endif
if ((s =
- verify_area(VERIFY_WRITE, (void *) arg,
+ verify_area(VERIFY_WRITE, argp,
sizeof(toc_entry))) == 0) {
struct sjcd_hw_disk_info *tp;
- if (copy_from_user(&toc_entry, (void *) arg,
+ if (copy_from_user(&toc_entry, argp,
sizeof(toc_entry)))
return (-EFAULT);
if (toc_entry.cdte_track == CDROM_LEADOUT)
default:
return (-EINVAL);
}
- if (copy_to_user((void *) arg, &toc_entry,
+ if (copy_to_user(argp, &toc_entry,
sizeof(toc_entry)))
s = -EFAULT;
}
printk("SJCD: ioctl: subchnl\n");
#endif
if ((s =
- verify_area(VERIFY_WRITE, (void *) arg,
+ verify_area(VERIFY_WRITE, argp,
sizeof(subchnl))) == 0) {
struct sjcd_hw_qinfo q_info;
- if (copy_from_user(&subchnl, (void *) arg,
+ if (copy_from_user(&subchnl, argp,
sizeof(subchnl)))
return (-EFAULT);
default:
return (-EINVAL);
}
- if (copy_to_user((void *) arg, &subchnl,
+ if (copy_to_user(argp, &subchnl,
sizeof(subchnl)))
s = -EFAULT;
}
printk("SJCD: ioctl: volctrl\n");
#endif
if ((s =
- verify_area(VERIFY_READ, (void *) arg,
+ verify_area(VERIFY_READ, argp,
sizeof(vol_ctrl))) == 0) {
unsigned char dummy[4];
- if (copy_from_user(&vol_ctrl, (void *) arg,
+ if (copy_from_user(&vol_ctrl, argp,
sizeof(vol_ctrl)))
return (-EFAULT);
sjcd_send_4_cmd(SCMD_SET_VOLUME,
#if defined( SJCD_TRACE )
printk("SJCD: ioctl: statistic\n");
#endif
- if (copy_to_user((void *)arg, &statistic,
- sizeof(statistic)))
+ if (copy_to_user(argp, &statistic, sizeof(statistic)))
return -EFAULT;
return 0;
}
* (not BCD), so all the conversions are done.
*/
static int
-sony_get_subchnl_info(long arg)
+sony_get_subchnl_info(void __user *arg)
{
struct cdrom_subchnl schi;
if (!sony_toc_read) {
return -EIO;
}
- if (copy_from_user(&schi, (char *)arg, sizeof schi))
+ if (copy_from_user(&schi, arg, sizeof schi))
return -EFAULT;
switch (sony_audio_status) {
case CDROM_AUDIO_NO_STATUS:
schi.cdsc_audiostatus = sony_audio_status;
- if (copy_to_user((char *)arg, &schi, sizeof schi))
+ if (copy_to_user(arg, &schi, sizeof schi))
return -EFAULT;
return 0;
break;
schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
}
- return copy_to_user((char *)arg, &schi, sizeof schi) ? -EFAULT : 0;
+ return copy_to_user(arg, &schi, sizeof schi) ? -EFAULT : 0;
}
Byte cmd_buff[10], params[10];
int i;
int dsc_status;
+ void __user *argp = (void __user *)arg;
if (check_drive_status() != 0)
return -EIO;
break;
case CDROMPLAYMSF: /* Play starting at the given MSF address. */
- if (copy_from_user(params, (void *)arg, 6))
+ if (copy_from_user(params, argp, 6))
return -EFAULT;
spin_up_drive(status);
set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
case CDROMREADTOCHDR: /* Read the table of contents header */
{
- struct cdrom_tochdr *hdr;
+ struct cdrom_tochdr __user *hdr = argp;
struct cdrom_tochdr loc_hdr;
sony_get_toc();
if (!sony_toc_read)
return -EIO;
- hdr = (struct cdrom_tochdr *)arg;
loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
if (copy_to_user(hdr, &loc_hdr, sizeof *hdr))
case CDROMREADTOCENTRY: /* Read a given table of contents entry */
{
- struct cdrom_tocentry *entry;
+ struct cdrom_tocentry __user *entry = argp;
struct cdrom_tocentry loc_entry;
int track_idx;
Byte *msf_val = NULL;
if (!sony_toc_read) {
return -EIO;
}
- entry = (struct cdrom_tocentry *)arg;
if (copy_from_user(&loc_entry, entry, sizeof loc_entry))
return -EFAULT;
if (!sony_toc_read)
return -EIO;
- if (copy_from_user(&ti, (char *)arg, sizeof ti))
+ if (copy_from_user(&ti, argp, sizeof ti))
return -EFAULT;
if ((ti.cdti_trk0 < sony_toc->first_track_num)
|| (sony_toc->last_track_num < ti.cdti_trk0)
}
case CDROMSUBCHNL: /* Get subchannel info */
- return sony_get_subchnl_info(arg);
+ return sony_get_subchnl_info(argp);
case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
{
struct cdrom_volctrl volctrl;
- if (copy_from_user(&volctrl, (char *)arg,
- sizeof volctrl))
+ if (copy_from_user(&volctrl, argp, sizeof volctrl))
return -EFAULT;
cmd_buff[0] = SONY535_SET_VOLUME;
cmd_buff[1] = volctrl.channel0;
console. This driver allows each pSeries partition to have a console
which is accessed via the HMC.
-config PC9800_OLDLP
- tristate "NEC PC-9800 old-style printer port support"
- depends on X86_PC9800 && !PARPORT
- ---help---
- If you intend to attach a printer to the parallel port of NEC PC-9801
- /PC-9821 with OLD compatibility mode, Say Y.
-
-config PC9800_OLDLP_CONSOLE
- bool "Support for console on line printer"
- depends on PC9800_OLDLP
-
config QIC02_TAPE
tristate "QIC-02 tape support"
help
config RTC
tristate "Enhanced Real Time Clock Support"
- depends on !PPC32 && !PARISC && !IA64 && !X86_PC9800 && !M68K
+ depends on !PPC32 && !PARISC && !IA64 && !M68K
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
bool "EFI Real Time Clock Services"
depends on IA64
-config RTC98
- tristate "NEC PC-9800 Real Time Clock Support"
- depends on X86_PC9800
- default y
- ---help---
- If you say Y here and create a character special file /dev/rtc with
- major number 10 and minor number 135 using mknod ("man mknod"), you
- will get access to the real time clock (or hardware clock) built
-
config H8
bool "Tadpole ANA H8 Support (OBSOLETE)"
depends on OBSOLETE && ALPHA_BOOK1
kernels. Applications should simply open the device (eg /dev/hda1)
with the O_DIRECT flag.
+config HPET
+ bool "HPET - High Precision Event Timer" if (X86 || IA64)
+ default n
+ depends on ACPI
+ help
+ If you say Y here, you will have a device named "/dev/hpet/XX" for
+ each timer supported by the HPET. The timers are
+ non-periodioc and/or periodic.
+
+config HPET_RTC_IRQ
+ bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC
+ default n
+ depends on HPET
+ help
+ If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It
+ is assumed the platform called hpet_alloc with the RTC IRQ values for
+ the HPET timers.
+
+config HPET_NOMMAP
+ bool "HPET - Control mmap capability."
+ default n
+ depends on HPET
+ help
+ If you say Y here, then the mmap interface for the HPET driver returns ENOSYS.
+ Some hardware implementations might not want all the memory in the page the
+ HPET control registers reside to be exposed.
+
config MAX_RAW_DEVS
int "Maximum number of RAW devices to support (1-8192)"
depends on RAW_DRIVER
obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
-obj-$(CONFIG_PC9800_OLDLP) += lp_old98.o
obj-$(CONFIG_DTLK) += dtlk.o
obj-$(CONFIG_R3964) += n_r3964.o
obj-$(CONFIG_APPLICOM) += applicom.o
obj-$(CONFIG_SONYPI) += sonypi.o
obj-$(CONFIG_RTC) += rtc.o
+obj-$(CONFIG_HPET) += hpet.o
obj-$(CONFIG_GEN_RTC) += genrtc.o
obj-$(CONFIG_EFI_RTC) += efirtc.o
ifeq ($(CONFIG_GENERIC_NVRAM),y)
static unsigned int ReadErrorCount; /* number of read error */
static unsigned int DeviceErrorCount; /* number of device error */
-static ssize_t ac_read (struct file *, char *, size_t, loff_t *);
-static ssize_t ac_write (struct file *, const char *, size_t, loff_t *);
+static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *);
+static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *);
static int ac_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static irqreturn_t ac_interrupt(int, void *, struct pt_regs *);
__initcall(applicom_init);
#endif
-static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ac_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
unsigned int NumCard; /* Board number 1 -> 8 */
unsigned int IndexCard; /* Index board number 0 -> 7 */
return 0;
}
-static int do_ac_read(int IndexCard, char *buf,
+static int do_ac_read(int IndexCard, char __user *buf,
struct st_ram_io *st_loc, struct mailbox *mailbox)
{
unsigned long from = (unsigned long)apbs[IndexCard].RamIO + RAM_TO_PC;
return (sizeof(struct st_ram_io) + sizeof(struct mailbox));
}
-static ssize_t ac_read (struct file *filp, char *buf, size_t count, loff_t *ptr)
+static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_t *ptr)
{
unsigned long flags;
unsigned int i;
int ret = 0;
volatile unsigned char byte_reset_it;
struct st_ram_io *adgl;
+ void __user *argp = (void __user *)arg;
/* In general, the device is only openable by root anyway, so we're not
particularly concerned that bogus ioctls can flood the console. */
if (!adgl)
return -ENOMEM;
- if (copy_from_user(adgl, (void *)arg,sizeof(struct st_ram_io))) {
+ if (copy_from_user(adgl, argp, sizeof(struct st_ram_io))) {
kfree(adgl);
return -EFAULT;
}
pmem = apbs[IndexCard].RamIO;
for (i = 0; i < sizeof(struct st_ram_io); i++)
((unsigned char *)adgl)[i]=readb(pmem++);
- if (copy_to_user((void *)arg, adgl, sizeof(struct st_ram_io)))
+ if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
ret = -EFAULT;
break;
case 1:
(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) +
(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2) );
- if (copy_to_user((void *)arg, adgl, sizeof(struct st_ram_io)))
+ if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
ret = -EFAULT;
break;
case 2:
pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC;
adgl->tic_owner_to_pc = readb(pmem++);
adgl->numcard_owner_to_pc = readb(pmem);
- if (copy_to_user((void *)arg, adgl,sizeof(struct st_ram_io)))
+ if (copy_to_user(argp, adgl,sizeof(struct st_ram_io)))
ret = -EFAULT;
break;
case 5:
#include <linux/stat.h>
#include <linux/proc_fs.h>
-#define cy_put_user put_user
-
static void cy_throttle (struct tty_struct *tty);
static void cy_send_xchar (struct tty_struct *tty, char ch);
static int
get_serial_info(struct cyclades_port * info,
- struct serial_struct * retinfo)
+ struct serial_struct __user * retinfo)
{
struct serial_struct tmp;
struct cyclades_card *cinfo = &cy_card[info->card];
static int
set_serial_info(struct cyclades_port * info,
- struct serial_struct * new_info)
+ struct serial_struct __user * new_info)
{
struct serial_struct new_serial;
struct cyclades_port old_info;
* transmit holding register is empty. This functionality
* allows an RS485 driver to be written in user space.
*/
-static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
+static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
{
int card, chip, channel, index;
unsigned char status;
/* Not supported yet */
return -EINVAL;
}
- return cy_put_user(result, (unsigned long *) value);
+ return put_user(result, (unsigned long __user *) value);
}
static int
} /* cy_break */
static int
-get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
+get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon)
{
if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
static int
-get_threshold(struct cyclades_port * info, unsigned long *value)
+get_threshold(struct cyclades_port * info, unsigned long __user *value)
{
unsigned char *base_addr;
int card,channel,chip,index;
+ (cy_chip_offset[chip]<<index));
tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO;
- return cy_put_user(tmp,value);
+ return put_user(tmp,value);
} else {
// Nothing to do!
return 0;
static int
-get_default_threshold(struct cyclades_port * info, unsigned long *value)
+get_default_threshold(struct cyclades_port * info, unsigned long __user *value)
{
- return cy_put_user(info->default_threshold,value);
+ return put_user(info->default_threshold,value);
}/* get_default_threshold */
static int
-get_timeout(struct cyclades_port * info, unsigned long *value)
+get_timeout(struct cyclades_port * info, unsigned long __user *value)
{
unsigned char *base_addr;
int card,channel,chip,index;
+ (cy_chip_offset[chip]<<index));
tmp = cy_readb(base_addr+(CyRTPR<<index));
- return cy_put_user(tmp,value);
+ return put_user(tmp,value);
} else {
// Nothing to do!
return 0;
static int
-get_default_timeout(struct cyclades_port * info, unsigned long *value)
+get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
{
- return cy_put_user(info->default_timeout,value);
+ return put_user(info->default_timeout,value);
}/* get_default_timeout */
/*
{
struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
struct cyclades_icount cprev, cnow; /* kernel counter temps */
- struct serial_icounter_struct *p_cuser; /* user space */
+ struct serial_icounter_struct __user *p_cuser; /* user space */
int ret_val = 0;
unsigned long flags;
+ void __user *argp = (void __user *)arg;
if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
return -ENODEV;
switch (cmd) {
case CYGETMON:
- ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
+ ret_val = get_mon_info(info, argp);
break;
case CYGETTHRESH:
- ret_val = get_threshold(info, (unsigned long *)arg);
+ ret_val = get_threshold(info, argp);
break;
case CYSETTHRESH:
- ret_val = set_threshold(info, (unsigned long)arg);
+ ret_val = set_threshold(info, arg);
break;
case CYGETDEFTHRESH:
- ret_val = get_default_threshold(info, (unsigned long *)arg);
+ ret_val = get_default_threshold(info, argp);
break;
case CYSETDEFTHRESH:
- ret_val = set_default_threshold(info, (unsigned long)arg);
+ ret_val = set_default_threshold(info, arg);
break;
case CYGETTIMEOUT:
- ret_val = get_timeout(info, (unsigned long *)arg);
+ ret_val = get_timeout(info, argp);
break;
case CYSETTIMEOUT:
- ret_val = set_timeout(info, (unsigned long)arg);
+ ret_val = set_timeout(info, arg);
break;
case CYGETDEFTIMEOUT:
- ret_val = get_default_timeout(info, (unsigned long *)arg);
+ ret_val = get_default_timeout(info, argp);
break;
case CYSETDEFTIMEOUT:
- ret_val = set_default_timeout(info, (unsigned long)arg);
+ ret_val = set_default_timeout(info, arg);
break;
case CYSETRFLOW:
info->rflow = (int)arg;
ret_val = info->rtsdtr_inv;
break;
case CYGETCARDINFO:
- if (copy_to_user((void *)arg, (void *)&cy_card[info->card],
+ if (copy_to_user(argp, &cy_card[info->card],
sizeof (struct cyclades_card))) {
ret_val = -EFAULT;
break;
ret_val = info->closing_wait / (HZ/100);
break;
case TIOCGSERIAL:
- ret_val = get_serial_info(info, (struct serial_struct *) arg);
+ ret_val = get_serial_info(info, argp);
break;
case TIOCSSERIAL:
- ret_val = set_serial_info(info, (struct serial_struct *) arg);
+ ret_val = set_serial_info(info, argp);
break;
case TIOCSERGETLSR: /* Get line status register */
- ret_val = get_lsr_info(info, (unsigned int *) arg);
+ ret_val = get_lsr_info(info, argp);
break;
/*
* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
CY_LOCK(info, flags);
cnow = info->icount;
CY_UNLOCK(info, flags);
- p_cuser = (struct serial_icounter_struct *) arg;
+ p_cuser = argp;
ret_val = put_user(cnow.cts, &p_cuser->cts);
if (ret_val) return ret_val;
ret_val = put_user(cnow.dsr, &p_cuser->dsr);
return -EBUSY;
if (!drm_agp->acquire)
return -EINVAL;
- if ( dev->agp->cant_use_aperture )
- return -EINVAL;
if ((retcode = drm_agp->acquire()))
return retcode;
dev->agp->acquired = 1;
snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
+ dev->devname = DRM(alloc)(strlen(dev->name) + dev->unique_len + 2,
+ DRM_MEM_DRIVER);
+ if (dev->devname == NULL)
+ return ENOMEM;
+
+ sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
+
return 0;
}
drm_buf_t *buf;
drm_buf_t *last_buf = NULL;
drm_device_dma_t *dma = dev->dma;
+ int *send_indices = NULL;
+ int *send_sizes = NULL;
+
DECLARE_WAITQUEUE(entry, current);
/* Turn off interrupt handling */
++must_free;
}
+ send_indices = DRM(alloc)(d->send_count * sizeof(*send_indices),
+ DRM_MEM_DRIVER);
+ if (send_indices == NULL)
+ return -ENOMEM;
+ if (copy_from_user(send_indices, d->send_indices,
+ d->send_count * sizeof(*send_indices))) {
+ retcode = -EFAULT;
+ goto cleanup;
+ }
+
+ send_sizes = DRM(alloc)(d->send_count * sizeof(*send_sizes),
+ DRM_MEM_DRIVER);
+ if (send_sizes == NULL)
+ return -ENOMEM;
+ if (copy_from_user(send_sizes, d->send_sizes,
+ d->send_count * sizeof(*send_sizes))) {
+ retcode = -EFAULT;
+ goto cleanup;
+ }
+
for (i = 0; i < d->send_count; i++) {
- idx = d->send_indices[i];
+ idx = send_indices[i];
if (idx < 0 || idx >= dma->buf_count) {
DRM_ERROR("Index %d (of %d max)\n",
- d->send_indices[i], dma->buf_count - 1);
+ send_indices[i], dma->buf_count - 1);
continue;
}
buf = dma->buflist[ idx ];
process closes the /dev/drm? handle, so
it can't also be doing DMA. */
buf->list = DRM_LIST_PRIO;
- buf->used = d->send_sizes[i];
+ buf->used = send_sizes[i];
buf->context = d->context;
buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
address = (unsigned long)buf->address;
if (buf->pending) {
DRM_ERROR("Sending pending buffer:"
" buffer %d, offset %d\n",
- d->send_indices[i], i);
+ send_indices[i], i);
retcode = -EINVAL;
goto cleanup;
}
if (buf->waiting) {
DRM_ERROR("Sending waiting buffer:"
" buffer %d, offset %d\n",
- d->send_indices[i], i);
+ send_indices[i], i);
retcode = -EINVAL;
goto cleanup;
}
gamma_dma_ready(dev);
gamma_free_buffer(dev, last_buf);
}
+ if (send_indices)
+ DRM(free)(send_indices, d->send_count * sizeof(*send_indices),
+ DRM_MEM_DRIVER);
+ if (send_sizes)
+ DRM(free)(send_sizes, d->send_count * sizeof(*send_sizes),
+ DRM_MEM_DRIVER);
if (must_free && !dev->context_flag) {
if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
drm_buf_t *last_buf = NULL;
int retcode = 0;
drm_device_dma_t *dma = dev->dma;
+ int send_index;
+
+ if (get_user(send_index, &d->send_indices[d->send_count-1]))
+ return -EFAULT;
if (d->flags & _DRM_DMA_BLOCK) {
- last_buf = dma->buflist[d->send_indices[d->send_count-1]];
+ last_buf = dma->buflist[send_index];
add_wait_queue(&last_buf->dma_wait, &entry);
}
count = depth->n;
if (count > 4096 || count <= 0)
- return -EMSGSIZE;
+ return DRM_ERR(EMSGSIZE);
if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
return DRM_ERR(EFAULT);
count = depth->n;
if (count > 4096 || count <= 0)
- return -EMSGSIZE;
+ return DRM_ERR(EMSGSIZE);
xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
count = depth->n;
if (count > 4096 || count <= 0)
- return -EMSGSIZE;
+ return DRM_ERR(EMSGSIZE);
if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
return DRM_ERR(EFAULT);
count = depth->n;
if (count > 4096 || count <= 0)
- return -EMSGSIZE;
+ return DRM_ERR(EMSGSIZE);
if ( count > dev_priv->depth_pitch ) {
count = dev_priv->depth_pitch;
#define DRIVER_DATE "20020828"
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 10
+#define DRIVER_MINOR 11
#define DRIVER_PATCHLEVEL 0
/* Interface history:
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
* clients use to tell the DRM where they think the framebuffer is
* located in the card's address space
+ * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
+ * and GL_EXT_blend_[func|equation]_separate on r200
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
#define RADEON_EMIT_PP_TEX_SIZE_0 73
#define RADEON_EMIT_PP_TEX_SIZE_1 74
#define RADEON_EMIT_PP_TEX_SIZE_2 75
-#define RADEON_MAX_STATE_PACKETS 76
+#define R200_EMIT_RB3D_BLENDCOLOR 76
+#define RADEON_MAX_STATE_PACKETS 77
/* Commands understood by cmd_buffer ioctl. More can be added but
#define R200_SE_VTX_FMT_1 0x208c
#define R200_RE_CNTL 0x1c50
+#define R200_RB3D_BLENDCOLOR 0x3218
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
struct mem_block *blocks = DRM_MALLOC(sizeof(*blocks));
if (!blocks)
- return -ENOMEM;
+ return DRM_ERR(ENOMEM);
*heap = DRM_MALLOC(sizeof(**heap));
if (!*heap) {
DRM_FREE( blocks, sizeof(*blocks) );
- return -ENOMEM;
+ return DRM_ERR(ENOMEM);
}
blocks->start = start;
case RADEON_EMIT_PP_TEX_SIZE_0:
case RADEON_EMIT_PP_TEX_SIZE_1:
case RADEON_EMIT_PP_TEX_SIZE_2:
+ case R200_EMIT_RB3D_BLENDCOLOR:
/* These packets don't contain memory offsets */
break;
{ RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0" },
{ RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1" },
{ RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_1" },
+ { R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR" },
};
DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb));
- DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset);
+ DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset);
return retval;
}
if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
retval = DRM_ERR(EINVAL);
- sis_free(fb.free);
+ sis_free((u32)fb.free);
DRM_DEBUG("free fb, offset = %lu\n", fb.free);
MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
-static ssize_t i8k_read(struct file *, char *, size_t, loff_t *);
+static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *);
static int i8k_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
int val;
int speed;
unsigned char buff[16];
+ int __user *argp = (int __user *)arg;
- if (!arg) {
+ if (!argp)
return -EINVAL;
- }
switch (cmd) {
case I8K_BIOS_VERSION:
break;
case I8K_GET_SPEED:
- if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+ if (copy_from_user(&val, argp, sizeof(int))) {
return -EFAULT;
}
val = i8k_get_fan_speed(val);
break;
case I8K_GET_FAN:
- if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+ if (copy_from_user(&val, argp, sizeof(int))) {
return -EFAULT;
}
val = i8k_get_fan_status(val);
if (restricted && !capable(CAP_SYS_ADMIN)) {
return -EPERM;
}
- if (copy_from_user(&val, (int *)arg, sizeof(int))) {
+ if (copy_from_user(&val, argp, sizeof(int))) {
return -EFAULT;
}
- if (copy_from_user(&speed, (int *)arg+1, sizeof(int))) {
+ if (copy_from_user(&speed, argp+1, sizeof(int))) {
return -EFAULT;
}
val = i8k_set_fan(val, speed);
switch (cmd) {
case I8K_BIOS_VERSION:
- if (copy_to_user((int *)arg, &val, 4)) {
+ if (copy_to_user(argp, &val, 4)) {
return -EFAULT;
}
break;
case I8K_MACHINE_ID:
- if (copy_to_user((int *)arg, buff, 16)) {
+ if (copy_to_user(argp, buff, 16)) {
return -EFAULT;
}
break;
default:
- if (copy_to_user((int *)arg, &val, sizeof(int))) {
+ if (copy_to_user(argp, &val, sizeof(int))) {
return -EFAULT;
}
break;
return n;
}
-static ssize_t i8k_read(struct file *f, char *buffer, size_t len, loff_t *fpos)
+static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos)
{
int n;
char info[128];
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
-#define IPMI_BT_VERSION "v31"
+#define IPMI_BT_VERSION "v32"
static int bt_debug = 0x00; /* Production value 0, see following flags */
#include <asm/semaphore.h>
#include <linux/init.h>
-#define IPMI_DEVINTF_VERSION "v31"
+#define IPMI_DEVINTF_VERSION "v32"
struct ipmi_file_private
{
goto out;
}
- if (copy_from_user(&msgdata,
+ if (copy_from_user(msgdata,
req->msg.data,
req->msg.data_len))
{
{
int rv = -EINVAL;
struct ipmi_file_private *priv = file->private_data;
+ void __user *arg = (void __user *)data;
switch (cmd)
{
{
struct ipmi_req req;
- if (copy_from_user(&req, (void *) data, sizeof(req))) {
+ if (copy_from_user(&req, arg, sizeof(req))) {
rv = -EFAULT;
break;
}
{
struct ipmi_req_settime req;
- if (copy_from_user(&req, (void *) data, sizeof(req))) {
+ if (copy_from_user(&req, arg, sizeof(req))) {
rv = -EFAULT;
break;
}
rv = 0;
- if (copy_from_user(&rsp, (void *) data, sizeof(rsp))) {
+ if (copy_from_user(&rsp, arg, sizeof(rsp))) {
rv = -EFAULT;
break;
}
rsp.msg.data_len = 0;
}
- if (copy_to_user((void *) data, &rsp, sizeof(rsp))) {
+ if (copy_to_user(arg, &rsp, sizeof(rsp))) {
rv = -EFAULT;
goto recv_putback_on_err;
}
{
struct ipmi_cmdspec val;
- if (copy_from_user(&val, (void *) data, sizeof(val))) {
+ if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
{
struct ipmi_cmdspec val;
- if (copy_from_user(&val, (void *) data, sizeof(val))) {
+ if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
{
int val;
- if (copy_from_user(&val, (void *) data, sizeof(val))) {
+ if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
{
unsigned int val;
- if (copy_from_user(&val, (void *) data, sizeof(val))) {
+ if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
val = ipmi_get_my_address(priv->user);
- if (copy_to_user((void *) data, &val, sizeof(val))) {
+ if (copy_to_user(arg, &val, sizeof(val))) {
rv = -EFAULT;
break;
}
{
unsigned int val;
- if (copy_from_user(&val, (void *) data, sizeof(val))) {
+ if (copy_from_user(&val, arg, sizeof(val))) {
rv = -EFAULT;
break;
}
val = ipmi_get_my_LUN(priv->user);
- if (copy_to_user((void *) data, &val, sizeof(val))) {
+ if (copy_to_user(arg, &val, sizeof(val))) {
rv = -EFAULT;
break;
}
{
struct ipmi_timing_parms parms;
- if (copy_from_user(&parms, (void *) data, sizeof(parms))) {
+ if (copy_from_user(&parms, arg, sizeof(parms))) {
rv = -EFAULT;
break;
}
parms.retries = priv->default_retries;
parms.retry_time_ms = priv->default_retry_time_ms;
- if (copy_to_user((void *) data, &parms, sizeof(parms))) {
+ if (copy_to_user(arg, &parms, sizeof(parms))) {
rv = -EFAULT;
break;
}
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
-#define IPMI_KCS_VERSION "v31"
+#define IPMI_KCS_VERSION "v32"
/* Set this if you want a printout of why the state machine was hosed
when it gets hosed. */
#include <linux/init.h>
#include <linux/proc_fs.h>
-#define IPMI_MSGHANDLER_VERSION "v31"
+#define IPMI_MSGHANDLER_VERSION "v32"
struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
static int ipmi_init_msghandler(void);
unsigned char protocol;
};
+struct ipmi_proc_entry
+{
+ char *name;
+ struct ipmi_proc_entry *next;
+};
+
#define IPMI_IPMB_NUM_SEQ 64
#define IPMI_MAX_CHANNELS 8
struct ipmi_smi
struct ipmi_smi_handlers *handlers;
void *send_info;
+ /* A list of proc entries for this interface. This does not
+ need a lock, only one thread creates it and only one thread
+ destroys it. */
+ struct ipmi_proc_entry *proc_entries;
+
/* A table of sequence numbers for this interface. We use the
sequence numbers for IPMB messages that go out of the
interface to match them up with their responses. A routine
read_proc_t *read_proc, write_proc_t *write_proc,
void *data, struct module *owner)
{
- struct proc_dir_entry *file;
- int rv = 0;
+ struct proc_dir_entry *file;
+ int rv = 0;
+ struct ipmi_proc_entry *entry;
+
+ /* Create a list element. */
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+ entry->name = kmalloc(strlen(name)+1, GFP_KERNEL);
+ if (!entry->name) {
+ kfree(entry);
+ return -ENOMEM;
+ }
+ strcpy(entry->name, name);
file = create_proc_entry(name, 0, smi->proc_dir);
- if (!file)
+ if (!file) {
+ kfree(entry->name);
+ kfree(entry);
rv = -ENOMEM;
- else {
+ } else {
file->nlink = 1;
file->data = data;
file->read_proc = read_proc;
file->write_proc = write_proc;
file->owner = owner;
+
+ /* Stick it on the list. */
+ entry->next = smi->proc_entries;
+ smi->proc_entries = entry;
}
return rv;
return rv;
}
+static void remove_proc_entries(ipmi_smi_t smi)
+{
+ struct ipmi_proc_entry *entry;
+
+ while (smi->proc_entries) {
+ entry = smi->proc_entries;
+ smi->proc_entries = entry->next;
+
+ remove_proc_entry(entry->name, smi->proc_dir);
+ kfree(entry->name);
+ kfree(entry);
+ }
+ remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
+}
+
static int
send_channel_info_cmd(ipmi_smi_t intf, int chan)
{
/* It's the one we want */
if (msg->rsp[2] != 0) {
/* Got an error from the channel, just go on. */
+
+ if (msg->rsp[2] == IPMI_INVALID_COMMAND_ERR) {
+ /* If the MC does not support this
+ command, that is legal. We just
+ assume it has one IPMB at channel
+ zero. */
+ intf->channels[0].medium
+ = IPMI_CHANNEL_MEDIUM_IPMB;
+ intf->channels[0].protocol
+ = IPMI_CHANNEL_PROTOCOL_IPMB;
+ rv = -ENOSYS;
+
+ intf->curr_channel = IPMI_MAX_CHANNELS;
+ wake_up(&intf->waitq);
+ goto out;
+ }
goto next_channel;
}
if (msg->rsp_size < 6) {
wake_up(&intf->waitq);
printk(KERN_WARNING "ipmi_msghandler: Error sending"
- "channel information: 0x%x\n",
+ "channel information: %d\n",
rv);
}
}
+ out:
+ return;
+}
+
+void ipmi_poll_interface(ipmi_user_t user)
+{
+ ipmi_smi_t intf = user->intf;
+
+ if (intf->handlers->poll)
+ intf->handlers->poll(intf->send_info);
}
int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
if (rv) {
if (new_intf->proc_dir)
- remove_proc_entry(new_intf->proc_dir_name,
- proc_ipmi_root);
+ remove_proc_entries(new_intf);
kfree(new_intf);
}
{
for (i=0; i<MAX_IPMI_INTERFACES; i++) {
if (ipmi_interfaces[i] == intf) {
- remove_proc_entry(intf->proc_dir_name,
- proc_ipmi_root);
+ remove_proc_entries(intf);
spin_lock_irqsave(&interfaces_lock, flags);
ipmi_interfaces[i] = NULL;
clean_up_interface_data(intf);
EXPORT_SYMBOL(ipmi_request_settime);
EXPORT_SYMBOL(ipmi_request_supply_msgs);
EXPORT_SYMBOL(ipmi_request_with_source);
+EXPORT_SYMBOL(ipmi_poll_interface);
EXPORT_SYMBOL(ipmi_register_smi);
EXPORT_SYMBOL(ipmi_unregister_smi);
EXPORT_SYMBOL(ipmi_register_for_cmd);
#include "ipmi_si_sm.h"
#include <linux/init.h>
-#define IPMI_SI_VERSION "v31"
+#define IPMI_SI_VERSION "v32"
/* Measure times between events in the driver. */
#undef DEBUG_TIMING
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}
+static void poll(void *send_info)
+{
+ struct smi_info *smi_info = send_info;
+
+ smi_event_handler(smi_info, 0);
+}
+
static void request_events(void *send_info)
{
struct smi_info *smi_info = send_info;
.owner = THIS_MODULE,
.sender = sender,
.request_events = request_events,
- .set_run_to_completion = set_run_to_completion
+ .set_run_to_completion = set_run_to_completion,
+ .poll = poll,
};
/* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
" has an interrupt. Otherwise, set it to zero or leave"
" it blank.");
-
-#if defined(CONFIG_ACPI_INTERPETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
#define IPMI_MEM_ADDR_SPACE 1
#define IPMI_IO_ADDR_SPACE 2
+
+#if defined(CONFIG_ACPI_INTERPETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
{
int i;
atomic_set(&new_smi->req_events, 0);
new_smi->run_to_completion = 0;
+ new_smi->interrupt_disabled = 0;
+ new_smi->timer_stopped = 0;
+ new_smi->stop_operation = 0;
+
+ /* The ipmi_register_smi() code does some operations to
+ determine the channel information, so we must be ready to
+ handle operations before it is called. This means we have
+ to stop the timer if we get an error after this point. */
+ init_timer(&(new_smi->si_timer));
+ new_smi->si_timer.data = (long) new_smi;
+ new_smi->si_timer.function = smi_timeout;
+ new_smi->last_timeout_jiffies = jiffies;
+ new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
+ add_timer(&(new_smi->si_timer));
+
rv = ipmi_register_smi(&handlers,
new_smi,
new_smi->ipmi_version_major,
printk(KERN_ERR
"ipmi_si: Unable to register device: error %d\n",
rv);
- goto out_err;
+ goto out_err_stop_timer;
}
rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
rv);
- goto out_err;
+ goto out_err_stop_timer;
}
rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
rv);
- goto out_err;
+ goto out_err_stop_timer;
}
start_clear_flags(new_smi);
if (new_smi->irq)
new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
- new_smi->interrupt_disabled = 0;
- new_smi->timer_stopped = 0;
- new_smi->stop_operation = 0;
-
- init_timer(&(new_smi->si_timer));
- new_smi->si_timer.data = (long) new_smi;
- new_smi->si_timer.function = smi_timeout;
- new_smi->last_timeout_jiffies = jiffies;
- new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
- add_timer(&(new_smi->si_timer));
-
*smi = new_smi;
printk(" IPMI %s interface initialized\n", si_type[intf_num]);
return 0;
+ out_err_stop_timer:
+ new_smi->stop_operation = 1;
+
+ /* Wait for the timer to stop. This avoids problems with race
+ conditions removing the timer here. */
+ while (!new_smi->timer_stopped) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
out_err:
if (new_smi->intf)
ipmi_unregister_smi(new_smi->intf);
new_smi->irq_cleanup(new_smi);
+
+ /* Wait until we know that we are out of any interrupt
+ handlers might have been running before we freed the
+ interrupt. */
+ synchronize_kernel();
+
if (new_smi->si_sm) {
if (new_smi->handlers)
new_smi->handlers->cleanup(new_smi->si_sm);
kfree(new_smi->si_sm);
}
new_smi->io_cleanup(new_smi);
+
return rv;
}
#include <linux/ipmi_msgdefs.h> /* for completion codes */
#include "ipmi_si_sm.h"
-#define IPMI_SMIC_VERSION "v31"
+#define IPMI_SMIC_VERSION "v32"
/* smic_debug is a bit-field
* SMIC_DEBUG_ENABLE - turned on for now
#include <asm/apic.h>
#endif
-#define IPMI_WATCHDOG_VERSION "v31"
+#define IPMI_WATCHDOG_VERSION "v32"
/*
* The IPMI command/response information for the watchdog timer.
static int ipmi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
int i;
int val;
switch(cmd) {
case WDIOC_GETSUPPORT:
- i = copy_to_user((void*)arg, &ident, sizeof(ident));
+ i = copy_to_user(argp, &ident, sizeof(ident));
return i ? -EFAULT : 0;
case WDIOC_SETTIMEOUT:
- i = copy_from_user(&val, (void *) arg, sizeof(int));
+ i = copy_from_user(&val, argp, sizeof(int));
if (i)
return -EFAULT;
timeout = val;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
case WDIOC_GETTIMEOUT:
- i = copy_to_user((void *) arg,
- &timeout,
- sizeof(timeout));
+ i = copy_to_user(argp, &timeout, sizeof(timeout));
if (i)
return -EFAULT;
return 0;
case WDIOC_SET_PRETIMEOUT:
- i = copy_from_user(&val, (void *) arg, sizeof(int));
+ i = copy_from_user(&val, argp, sizeof(int));
if (i)
return -EFAULT;
pretimeout = val;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
case WDIOC_GET_PRETIMEOUT:
- i = copy_to_user((void *) arg,
- &pretimeout,
- sizeof(pretimeout));
+ i = copy_to_user(argp, &pretimeout, sizeof(pretimeout));
if (i)
return -EFAULT;
return 0;
return ipmi_heartbeat();
case WDIOC_SETOPTIONS:
- i = copy_from_user(&val, (void *) arg, sizeof(int));
+ i = copy_from_user(&val, argp, sizeof(int));
if (i)
return -EFAULT;
if (val & WDIOS_DISABLECARD)
case WDIOC_GETSTATUS:
val = 0;
- i = copy_to_user((void *) arg, &val, sizeof(val));
+ i = copy_to_user(argp, &val, sizeof(val));
if (i)
return -EFAULT;
return 0;
}
static ssize_t ipmi_write(struct file *file,
- const char *buf,
+ const char __user *buf,
size_t len,
loff_t *ppos)
{
}
static ssize_t ipmi_read(struct file *file,
- char *buf,
+ char __user *buf,
size_t count,
loff_t *ppos)
{
/* On a panic, if we have a panic timeout, make sure that the thing
reboots, even if it hangs during that panic. */
- if (watchdog_user && !panic_event_handled && (panic_timeout > 0)) {
+ if (watchdog_user && !panic_event_handled) {
/* Make sure the panic doesn't hang, and make sure we
do this only once. */
panic_event_handled = 1;
- timeout = panic_timeout + 120;
- if (timeout > 255)
- timeout = 255;
+ timeout = 255;
pretimeout = 0;
ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
panic_halt_ipmi_set_timeout();
i = tty_unregister_driver(stli_serial);
if (i) {
printk("STALLION: failed to un-register tty driver, "
- "errno=%d,%d\n", -i);
+ "errno=%d\n", -i);
restore_flags(flags);
return;
}
/*
* Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
- * This seems a good reason to start with NumLock off. On PC9800 and HIL keyboards
+ * This seems a good reason to start with NumLock off. On HIL keyboards
* of PARISC machines however there is no NumLock key and everyone expects the keypad
* to be used for numbers.
*/
-#if defined(CONFIG_X86_PC9800) || \
- defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
+#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
#define KBD_DEFLEDS (1 << VC_NUMLOCK)
#else
#define KBD_DEFLEDS 0
return error;
}
-static ssize_t lp_write(struct file * file, const char * buf,
+static ssize_t lp_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
#ifdef CONFIG_PARPORT_1284
/* Status readback conforming to ieee1284 */
-static ssize_t lp_read(struct file * file, char * buf,
+static ssize_t lp_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
unsigned int minor=iminor(file->f_dentry->d_inode);
unsigned int minor = iminor(inode);
int status;
int retval = 0;
+ void __user *argp = (void __user *)arg;
#ifdef LP_DEBUG
printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
return -EINVAL;
break;
case LPGETIRQ:
- if (copy_to_user((int *) arg, &LP_IRQ(minor),
+ if (copy_to_user(argp, &LP_IRQ(minor),
sizeof(int)))
return -EFAULT;
break;
status = r_str(minor);
lp_release_parport (&lp_table[minor]);
- if (copy_to_user((int *) arg, &status, sizeof(int)))
+ if (copy_to_user(argp, &status, sizeof(int)))
return -EFAULT;
break;
case LPRESET:
break;
#ifdef LP_STATS
case LPGETSTATS:
- if (copy_to_user((int *) arg, &LP_STAT(minor),
+ if (copy_to_user(argp, &LP_STAT(minor),
sizeof(struct lp_stats)))
return -EFAULT;
if (capable(CAP_SYS_ADMIN))
#endif
case LPGETFLAGS:
status = LP_F(minor);
- if (copy_to_user((int *) arg, &status, sizeof(int)))
+ if (copy_to_user(argp, &status, sizeof(int)))
return -EFAULT;
break;
case LPSETTIMEOUT:
- if (copy_from_user (&par_timeout,
- (struct timeval *) arg,
+ if (copy_from_user (&par_timeout, argp,
sizeof (struct timeval))) {
return -EFAULT;
}
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/pgalloc.h>
#ifdef CONFIG_IA64
# include <linux/efi.h>
}
-int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr)
{
- unsigned short *pusBuffer = pvBuffer;
+ unsigned short __user *pusBuffer = pvBuffer;
unsigned short val;
}
int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
- void *pvBuffer, unsigned uCount,
+ void __user *pvBuffer, unsigned uCount,
unsigned long ulDSPAddr)
{
- unsigned short *pusBuffer = pvBuffer;
+ unsigned short __user *pusBuffer = pvBuffer;
unsigned short val;
}
-int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr)
{
- unsigned short *pusBuffer = pvBuffer;
+ unsigned short __user *pusBuffer = pvBuffer;
PRINTK_5(TRACE_3780I,
}
-int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr)
{
- unsigned short *pusBuffer = pvBuffer;
+ unsigned short __user *pusBuffer = pvBuffer;
PRINTK_5(TRACE_3780I,
"3780i::dsp3780I_ReadIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
}
-int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr)
{
- unsigned short *pusBuffer = pvBuffer;
+ unsigned short __user *pusBuffer = pvBuffer;
PRINTK_5(TRACE_3780I,
"3780i::dsp3780I_WriteIStore entry usDspBaseIO %x, pusBuffer %p, uCount %x, ulDSPAddr %lx\n",
int dsp3780I_DisableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings);
int dsp3780I_Reset(DSP_3780I_CONFIG_SETTINGS * pSettings);
int dsp3780I_Run(DSP_3780I_CONFIG_SETTINGS * pSettings);
-int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr);
int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO,
- void *pvBuffer, unsigned uCount,
+ void __user *pvBuffer, unsigned uCount,
unsigned long ulDSPAddr);
-int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr);
-int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr);
-int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void *pvBuffer,
+int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer,
unsigned uCount, unsigned long ulDSPAddr);
unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
unsigned long ulMsaAddr);
{
unsigned int retval = 0;
pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+ void __user *arg = (void __user *)ioarg;
PRINTK_5(TRACE_MWAVE,
"mwavedd::mwave_ioctl, entry inode %x file %x cmd %x arg %x\n",
" retval %x from tp3780I_QueryAbilities\n",
retval);
if (retval == 0) {
- if( copy_to_user((char *) ioarg,
- (char *) &rAbilities,
+ if( copy_to_user(arg, &rAbilities,
sizeof(MW_ABILITIES)) )
return -EFAULT;
}
case IOCTL_MW_READ_DATA:
case IOCTL_MW_READCLEAR_DATA: {
MW_READWRITE rReadData;
- unsigned short *pusBuffer = 0;
+ unsigned short __user *pusBuffer = 0;
- if( copy_from_user((char *) &rReadData,
- (char *) ioarg,
+ if( copy_from_user(&rReadData, arg,
sizeof(MW_READWRITE)) )
return -EFAULT;
- pusBuffer = (unsigned short *) (rReadData.pBuf);
+ pusBuffer = (unsigned short __user *) (rReadData.pBuf);
PRINTK_4(TRACE_MWAVE,
"mwavedd::mwave_ioctl IOCTL_MW_READ_DATA,"
rReadData.ulDataLength, ioarg, pusBuffer);
retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData,
iocmd,
- (void *) pusBuffer,
+ pusBuffer,
rReadData.ulDataLength,
rReadData.usDspAddress);
}
case IOCTL_MW_READ_INST: {
MW_READWRITE rReadData;
- unsigned short *pusBuffer = 0;
+ unsigned short __user *pusBuffer = 0;
- if( copy_from_user((char *) &rReadData, (char *) ioarg,
+ if( copy_from_user(&rReadData, arg,
sizeof(MW_READWRITE)) )
return -EFAULT;
- pusBuffer = (unsigned short *) (rReadData.pBuf);
+ pusBuffer = (unsigned short __user *) (rReadData.pBuf);
PRINTK_4(TRACE_MWAVE,
"mwavedd::mwave_ioctl IOCTL_MW_READ_INST,"
case IOCTL_MW_WRITE_DATA: {
MW_READWRITE rWriteData;
- unsigned short *pusBuffer = 0;
+ unsigned short __user *pusBuffer = 0;
- if( copy_from_user((char *) &rWriteData,
- (char *) ioarg,
+ if( copy_from_user(&rWriteData, arg,
sizeof(MW_READWRITE)) )
return -EFAULT;
- pusBuffer = (unsigned short *) (rWriteData.pBuf);
+ pusBuffer = (unsigned short __user *) (rWriteData.pBuf);
PRINTK_4(TRACE_MWAVE,
"mwavedd::mwave_ioctl IOCTL_MW_WRITE_DATA,"
case IOCTL_MW_WRITE_INST: {
MW_READWRITE rWriteData;
- unsigned short *pusBuffer = 0;
+ unsigned short __user *pusBuffer = 0;
- if( copy_from_user((char *) &rWriteData,
- (char *) ioarg,
+ if( copy_from_user(&rWriteData, arg,
sizeof(MW_READWRITE)) )
return -EFAULT;
- pusBuffer = (unsigned short *) (rWriteData.pBuf);
+ pusBuffer = (unsigned short __user *)(rWriteData.pBuf);
PRINTK_4(TRACE_MWAVE,
"mwavedd::mwave_ioctl IOCTL_MW_WRITE_INST,"
}
-static ssize_t mwave_read(struct file *file, char *buf, size_t count,
+static ssize_t mwave_read(struct file *file, char __user *buf, size_t count,
loff_t * ppos)
{
PRINTK_5(TRACE_MWAVE,
}
-static ssize_t mwave_write(struct file *file, const char *buf,
+static ssize_t mwave_write(struct file *file, const char __user *buf,
size_t count, loff_t * ppos)
{
PRINTK_5(TRACE_MWAVE,
}
int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
- void *pvBuffer, unsigned int uCount,
+ void __user *pvBuffer, unsigned int uCount,
unsigned long ulDSPAddr)
{
int retval = 0;
int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
- void *pvBuffer, unsigned int uCount,
+ void __user *pvBuffer, unsigned int uCount,
unsigned long ulDSPAddr)
{
int retval = 0;
int tp3780I_QueryAbilities(THINKPAD_BD_DATA * pBDData, MW_ABILITIES * pAbilities);
int tp3780I_Cleanup(THINKPAD_BD_DATA * pBDData);
int tp3780I_ReadWriteDspDStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
- void *pvBuffer, unsigned int uCount,
+ void __user *pvBuffer, unsigned int uCount,
unsigned long ulDSPAddr);
int tp3780I_ReadWriteDspIStore(THINKPAD_BD_DATA * pBDData, unsigned int uOpcode,
- void *pvBuffer, unsigned int uCount,
+ void __user *pvBuffer, unsigned int uCount,
unsigned long ulDSPAddr);
}
static ssize_t
-nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+nvram_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
}
static ssize_t
-nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+nvram_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
/*
* linux/drivers/char/pcmcia/synclink_cs.c
*
- * $Id: synclink_cs.c,v 4.21 2004/03/08 15:29:23 paulkf Exp $
+ * $Id: synclink_cs.c,v 4.22 2004/06/01 20:27:46 paulkf Exp $
*
* Device driver for Microgate SyncLink PC Card
* multiprotocol serial adapter.
static int tiocmget(struct tty_struct *tty, struct file *file);
static int tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
-static int get_stats(MGSLPC_INFO *info, struct mgsl_icount *user_icount);
-static int get_params(MGSLPC_INFO *info, MGSL_PARAMS *user_params);
-static int set_params(MGSLPC_INFO *info, MGSL_PARAMS *new_params);
-static int get_txidle(MGSLPC_INFO *info, int*idle_mode);
+static int get_stats(MGSLPC_INFO *info, struct mgsl_icount __user *user_icount);
+static int get_params(MGSLPC_INFO *info, MGSL_PARAMS __user *user_params);
+static int set_params(MGSLPC_INFO *info, MGSL_PARAMS __user *new_params);
+static int get_txidle(MGSLPC_INFO *info, int __user *idle_mode);
static int set_txidle(MGSLPC_INFO *info, int idle_mode);
static int set_txenable(MGSLPC_INFO *info, int enable);
static int tx_abort(MGSLPC_INFO *info);
static int set_rxenable(MGSLPC_INFO *info, int enable);
-static int wait_events(MGSLPC_INFO *info, int *mask);
+static int wait_events(MGSLPC_INFO *info, int __user *mask);
#define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
MODULE_LICENSE("GPL");
static char *driver_name = "SyncLink PC Card driver";
-static char *driver_version = "$Revision: 4.21 $";
+static char *driver_version = "$Revision: 4.22 $";
static struct tty_driver *serial_driver;
* (gdb) to get the .text address for the add-symbol-file command.
* This allows remote debugging of dynamically loadable modules.
*/
-static void* mgslpc_get_text_ptr(void);
-static void* mgslpc_get_text_ptr() {return mgslpc_get_text_ptr;}
+static void* mgslpc_get_text_ptr(void)
+{
+ return mgslpc_get_text_ptr;
+}
static dev_link_t *mgslpc_attach(void)
{
/* get the current serial statistics
*/
-static int get_stats(MGSLPC_INFO * info, struct mgsl_icount *user_icount)
+static int get_stats(MGSLPC_INFO * info, struct mgsl_icount __user *user_icount)
{
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
/* get the current serial parameters
*/
-static int get_params(MGSLPC_INFO * info, MGSL_PARAMS *user_params)
+static int get_params(MGSLPC_INFO * info, MGSL_PARAMS __user *user_params)
{
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
*
* Returns: 0 if success, otherwise error code
*/
-static int set_params(MGSLPC_INFO * info, MGSL_PARAMS *new_params)
+static int set_params(MGSLPC_INFO * info, MGSL_PARAMS __user *new_params)
{
unsigned long flags;
MGSL_PARAMS tmp_params;
return 0;
}
-static int get_txidle(MGSLPC_INFO * info, int*idle_mode)
+static int get_txidle(MGSLPC_INFO * info, int __user *idle_mode)
{
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
return 0;
}
-static int get_interface(MGSLPC_INFO * info, int*if_mode)
+static int get_interface(MGSLPC_INFO * info, int __user *if_mode)
{
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
* of events triggerred,
* otherwise error code
*/
-static int wait_events(MGSLPC_INFO * info, int * mask_ptr)
+static int wait_events(MGSLPC_INFO * info, int __user *mask_ptr)
{
unsigned long flags;
int s;
{
int error;
struct mgsl_icount cnow; /* kernel counter temps */
- struct serial_icounter_struct *p_cuser; /* user space */
+ struct serial_icounter_struct __user *p_cuser; /* user space */
+ void __user *argp = (void __user *)arg;
unsigned long flags;
switch (cmd) {
case MGSL_IOCGPARAMS:
- return get_params(info,(MGSL_PARAMS *)arg);
+ return get_params(info, argp);
case MGSL_IOCSPARAMS:
- return set_params(info,(MGSL_PARAMS *)arg);
+ return set_params(info, argp);
case MGSL_IOCGTXIDLE:
- return get_txidle(info,(int*)arg);
+ return get_txidle(info, argp);
case MGSL_IOCSTXIDLE:
- return set_txidle(info,(int)arg);
+ return set_txidle(info, (int)arg);
case MGSL_IOCGIF:
- return get_interface(info,(int*)arg);
+ return get_interface(info, argp);
case MGSL_IOCSIF:
return set_interface(info,(int)arg);
case MGSL_IOCTXENABLE:
case MGSL_IOCTXABORT:
return tx_abort(info);
case MGSL_IOCGSTATS:
- return get_stats(info,(struct mgsl_icount*)arg);
+ return get_stats(info, argp);
case MGSL_IOCWAITEVENT:
- return wait_events(info,(int*)arg);
+ return wait_events(info, argp);
case TIOCMIWAIT:
return modem_input_wait(info,(int)arg);
case TIOCGICOUNT:
spin_lock_irqsave(&info->lock,flags);
cnow = info->icount;
spin_unlock_irqrestore(&info->lock,flags);
- p_cuser = (struct serial_icounter_struct *) arg;
+ p_cuser = argp;
PUT_USER(error,cnow.cts, &p_cuser->cts);
if (error) return error;
PUT_USER(error,cnow.dsr, &p_cuser->dsr);
.tiocmset = tiocmset,
};
+static void synclink_cs_cleanup(void)
+{
+ int rc;
+
+ printk("Unloading %s: version %s\n", driver_name, driver_version);
+
+ while(mgslpc_device_list)
+ mgslpc_remove_device(mgslpc_device_list);
+
+ if (serial_driver) {
+ if ((rc = tty_unregister_driver(serial_driver)))
+ printk("%s(%d) failed to unregister tty driver err=%d\n",
+ __FILE__,__LINE__,rc);
+ put_tty_driver(serial_driver);
+ }
+
+ pcmcia_unregister_driver(&mgslpc_driver);
+
+ /* XXX: this really needs to move into generic code.. */
+ while (dev_list != NULL) {
+ if (dev_list->state & DEV_CONFIG)
+ mgslpc_release((u_long)dev_list);
+ mgslpc_detach(dev_list);
+ }
+}
+
static int __init synclink_cs_init(void)
{
- int error;
+ int rc;
if (break_on_load) {
mgslpc_get_text_ptr();
printk("%s %s\n", driver_name, driver_version);
- serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
- if (!serial_driver)
- return -ENOMEM;
+ if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0)
+ return rc;
- error = pcmcia_register_driver(&mgslpc_driver);
- if (error) {
- put_tty_driver(serial_driver);
- return error;
+ serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
+ if (!serial_driver) {
+ rc = -ENOMEM;
+ goto error;
}
/* Initialize the tty_driver structure */
serial_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(serial_driver, &mgslpc_ops);
- if (tty_register_driver(serial_driver) < 0)
+ if ((rc = tty_register_driver(serial_driver)) < 0) {
printk("%s(%d):Couldn't register serial driver\n",
__FILE__,__LINE__);
+ put_tty_driver(serial_driver);
+ serial_driver = NULL;
+ goto error;
+ }
printk("%s %s, tty major#%d\n",
driver_name, driver_version,
serial_driver->major);
return 0;
+
+error:
+ synclink_cs_cleanup();
+ return rc;
}
static void __exit synclink_cs_exit(void)
{
- int rc;
-
- printk("Unloading %s: version %s\n", driver_name, driver_version);
-
- while(mgslpc_device_list)
- mgslpc_remove_device(mgslpc_device_list);
-
- if ((rc = tty_unregister_driver(serial_driver)))
- printk("%s(%d) failed to unregister tty driver err=%d\n",
- __FILE__,__LINE__,rc);
- put_tty_driver(serial_driver);
-
- pcmcia_unregister_driver(&mgslpc_driver);
-
- /* XXX: this really needs to move into generic code.. */
- while (dev_list != NULL) {
- if (dev_list->state & DEV_CONFIG)
- mgslpc_release((u_long)dev_list);
- mgslpc_detach(dev_list);
- }
+ synclink_cs_cleanup();
}
module_init(synclink_cs_init);
port->ops->enable_irq (port);
}
-static ssize_t pp_read (struct file * file, char * buf, size_t count,
+static ssize_t pp_read (struct file * file, char __user * buf, size_t count,
loff_t * ppos)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
return bytes_read;
}
-static ssize_t pp_write (struct file * file, const char * buf, size_t count,
- loff_t * ppos)
+static ssize_t pp_write (struct file * file, const char __user * buf,
+ size_t count, loff_t * ppos)
{
unsigned int minor = iminor(file->f_dentry->d_inode);
struct pp_struct *pp = file->private_data;
unsigned int minor = iminor(inode);
struct pp_struct *pp = file->private_data;
struct parport * port;
+ void __user *argp = (void __user *)arg;
/* First handle the cases that don't take arguments. */
switch (cmd) {
case PPSETMODE:
{
int mode;
- if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+ if (copy_from_user (&mode, argp, sizeof (mode)))
return -EFAULT;
/* FIXME: validate mode */
pp->state.mode = mode;
} else {
mode = pp->state.mode;
}
- if (copy_to_user ((int *)arg, &mode, sizeof (mode))) {
+ if (copy_to_user (argp, &mode, sizeof (mode))) {
return -EFAULT;
}
return 0;
case PPSETPHASE:
{
int phase;
- if (copy_from_user (&phase, (int *) arg, sizeof (phase))) {
+ if (copy_from_user (&phase, argp, sizeof (phase))) {
return -EFAULT;
}
/* FIXME: validate phase */
} else {
phase = pp->state.phase;
}
- if (copy_to_user ((int *)arg, &phase, sizeof (phase))) {
+ if (copy_to_user (argp, &phase, sizeof (phase))) {
return -EFAULT;
}
return 0;
return -ENODEV;
modes = port->modes;
- if (copy_to_user ((unsigned int *)arg, &modes, sizeof (modes))) {
+ if (copy_to_user (argp, &modes, sizeof (modes))) {
return -EFAULT;
}
return 0;
{
int uflags;
- if (copy_from_user (&uflags, (int *)arg, sizeof (uflags))) {
+ if (copy_from_user (&uflags, argp, sizeof (uflags))) {
return -EFAULT;
}
pp->flags &= ~PP_FLAGMASK;
int uflags;
uflags = pp->flags & PP_FLAGMASK;
- if (copy_to_user ((int *)arg, &uflags, sizeof (uflags))) {
+ if (copy_to_user (argp, &uflags, sizeof (uflags))) {
return -EFAULT;
}
return 0;
case PPRSTATUS:
reg = parport_read_status (port);
- if (copy_to_user ((unsigned char *) arg, ®, sizeof (reg)))
+ if (copy_to_user (argp, ®, sizeof (reg)))
return -EFAULT;
return 0;
case PPRDATA:
reg = parport_read_data (port);
- if (copy_to_user ((unsigned char *) arg, ®, sizeof (reg)))
+ if (copy_to_user (argp, ®, sizeof (reg)))
return -EFAULT;
return 0;
case PPRCONTROL:
reg = parport_read_control (port);
- if (copy_to_user ((unsigned char *) arg, ®, sizeof (reg)))
+ if (copy_to_user (argp, ®, sizeof (reg)))
return -EFAULT;
return 0;
case PPYIELD:
return 0;
case PPWCONTROL:
- if (copy_from_user (®, (unsigned char *) arg, sizeof (reg)))
+ if (copy_from_user (®, argp, sizeof (reg)))
return -EFAULT;
parport_write_control (port, reg);
return 0;
case PPWDATA:
- if (copy_from_user (®, (unsigned char *) arg, sizeof (reg)))
+ if (copy_from_user (®, argp, sizeof (reg)))
return -EFAULT;
parport_write_data (port, reg);
return 0;
case PPFCONTROL:
- if (copy_from_user (&mask, (unsigned char *) arg,
+ if (copy_from_user (&mask, argp,
sizeof (mask)))
return -EFAULT;
- if (copy_from_user (®, 1 + (unsigned char *) arg,
+ if (copy_from_user (®, 1 + (unsigned char __user *) arg,
sizeof (reg)))
return -EFAULT;
parport_frob_control (port, mask, reg);
return 0;
case PPDATADIR:
- if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+ if (copy_from_user (&mode, argp, sizeof (mode)))
return -EFAULT;
if (mode)
port->ops->data_reverse (port);
return 0;
case PPNEGOT:
- if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+ if (copy_from_user (&mode, argp, sizeof (mode)))
return -EFAULT;
switch ((ret = parport_negotiate (port, mode))) {
case 0: break;
return ret;
case PPWCTLONIRQ:
- if (copy_from_user (®, (unsigned char *) arg,
- sizeof (reg)))
+ if (copy_from_user (®, argp, sizeof (reg)))
return -EFAULT;
/* Remember what to set the control lines to, for next
case PPCLRIRQ:
ret = atomic_read (&pp->irqc);
- if (copy_to_user ((int *) arg, &ret, sizeof (ret)))
+ if (copy_to_user (argp, &ret, sizeof (ret)))
return -EFAULT;
atomic_sub (ret, &pp->irqc);
return 0;
case PPSETTIME:
- if (copy_from_user (&par_timeout, (struct timeval *)arg,
- sizeof(struct timeval))) {
+ if (copy_from_user (&par_timeout, argp, sizeof(struct timeval))) {
return -EFAULT;
}
/* Convert to jiffies, place in pp->pdev->timeout */
to_jiffies = pp->pdev->timeout;
par_timeout.tv_sec = to_jiffies / HZ;
par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
- if (copy_to_user ((struct timeval *)arg, &par_timeout,
- sizeof(struct timeval))) {
+ if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
return -EFAULT;
- }
return 0;
default:
static int rtc_irq = PCI_IRQ_NONE;
#endif
+#ifdef CONFIG_HPET_RTC_IRQ
+#undef RTC_IRQ
+#define RTC_IRQ 0
+#endif
+
#ifdef RTC_IRQ
static int rtc_has_irq = 1;
#endif
MODULE_PARM(major, "i");
MODULE_PARM_DESC(major, "Major device number");
-static ssize_t scx200_gpio_write(struct file *file, const char *data,
+static ssize_t scx200_gpio_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
unsigned m = iminor(file->f_dentry->d_inode);
return len;
}
-static ssize_t scx200_gpio_read(struct file *file, char *buf,
+static ssize_t scx200_gpio_read(struct file *file, char __user *buf,
size_t len, loff_t *ppos)
{
unsigned m = iminor(file->f_dentry->d_inode);
return 0;
}
-static ssize_t sonypi_misc_read(struct file * file, char * buf,
- size_t count, loff_t *pos) {
+static ssize_t sonypi_misc_read(struct file * file, char __user * buf,
+ size_t count, loff_t *pos)
+{
DECLARE_WAITQUEUE(wait, current);
ssize_t i = count;
unsigned char c;
static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
unsigned int cmd, unsigned long arg) {
int ret = 0;
+ void __user *argp = (void __user *)arg;
u8 val8;
u16 val16;
ret = -EIO;
break;
}
- if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+ if (copy_to_user(argp, &val8, sizeof(val8)))
ret = -EFAULT;
break;
case SONYPI_IOCSBRT:
- if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+ if (copy_from_user(&val8, argp, sizeof(val8))) {
ret = -EFAULT;
break;
}
ret = -EIO;
break;
}
- if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+ if (copy_to_user(argp, &val16, sizeof(val16)))
ret = -EFAULT;
break;
case SONYPI_IOCGBAT1REM:
ret = -EIO;
break;
}
- if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+ if (copy_to_user(argp, &val16, sizeof(val16)))
ret = -EFAULT;
break;
case SONYPI_IOCGBAT2CAP:
ret = -EIO;
break;
}
- if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+ if (copy_to_user(argp, &val16, sizeof(val16)))
ret = -EFAULT;
break;
case SONYPI_IOCGBAT2REM:
ret = -EIO;
break;
}
- if (copy_to_user((u16 *)arg, &val16, sizeof(val16)))
+ if (copy_to_user(argp, &val16, sizeof(val16)))
ret = -EFAULT;
break;
case SONYPI_IOCGBATFLAGS:
break;
}
val8 &= 0x07;
- if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+ if (copy_to_user(argp, &val8, sizeof(val8)))
ret = -EFAULT;
break;
case SONYPI_IOCGBLUE:
val8 = sonypi_device.bluetooth_power;
- if (copy_to_user((u8 *)arg, &val8, sizeof(val8)))
+ if (copy_to_user(argp, &val8, sizeof(val8)))
ret = -EFAULT;
break;
case SONYPI_IOCSBLUE:
- if (copy_from_user(&val8, (u8 *)arg, sizeof(val8))) {
+ if (copy_from_user(&val8, argp, sizeof(val8))) {
ret = -EFAULT;
break;
}
/*
* linux/drivers/char/synclink.c
*
- * $Id: synclink.c,v 4.21 2004/03/08 15:29:22 paulkf Exp $
+ * $Id: synclink.c,v 4.24 2004/06/03 14:50:09 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
void mgsl_release_resources(struct mgsl_struct *info);
void mgsl_add_device(struct mgsl_struct *info);
struct mgsl_struct* mgsl_allocate_device(void);
-int mgsl_enum_isa_devices(void);
/*
* DMA buffer manupulation functions.
static int tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount
- *user_icount);
-static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS *user_params);
-static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS *new_params);
-static int mgsl_get_txidle(struct mgsl_struct * info, int*idle_mode);
+ __user *user_icount);
+static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params);
+static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params);
+static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode);
static int mgsl_set_txidle(struct mgsl_struct * info, int idle_mode);
static int mgsl_txenable(struct mgsl_struct * info, int enable);
static int mgsl_txabort(struct mgsl_struct * info);
static int mgsl_rxenable(struct mgsl_struct * info, int enable);
-static int mgsl_wait_event(struct mgsl_struct * info, int * mask);
+static int mgsl_wait_event(struct mgsl_struct * info, int __user *mask);
static int mgsl_loopmode_send_done( struct mgsl_struct * info );
#define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
+/* set non-zero on successful registration with PCI subsystem */
+static int pci_registered;
+
/*
* Global linked list of SyncLink devices
*/
MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.21 $";
+static char *driver_version = "$Revision: 4.24 $";
static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
* (gdb) to get the .text address for the add-symbol-file command.
* This allows remote debugging of dynamically loadable modules.
*/
-void* mgsl_get_text_ptr(void);
-void* mgsl_get_text_ptr() {return mgsl_get_text_ptr;}
+void* mgsl_get_text_ptr(void)
+{
+ return mgsl_get_text_ptr;
+}
/*
* tmp_buf is used as a temporary buffer by mgsl_write. We need to
*
* Return Value: 0 if success, otherwise error code
*/
-static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount *user_icount)
+static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *user_icount)
{
int err;
*
* Return Value: 0 if success, otherwise error code
*/
-static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS *user_params)
+static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params)
{
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
*
* Return Value: 0 if success, otherwise error code
*/
-static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS *new_params)
+static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params)
{
unsigned long flags;
MGSL_PARAMS tmp_params;
*
* Return Value: 0 if success, otherwise error code
*/
-static int mgsl_get_txidle(struct mgsl_struct * info, int*idle_mode)
+static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode)
{
int err;
* of events triggerred,
* otherwise error code
*/
-static int mgsl_wait_event(struct mgsl_struct * info, int * mask_ptr)
+static int mgsl_wait_event(struct mgsl_struct * info, int __user * mask_ptr)
{
unsigned long flags;
int s;
{
int error;
struct mgsl_icount cnow; /* kernel counter temps */
- struct serial_icounter_struct *p_cuser; /* user space */
+ void __user *argp = (void __user *)arg;
+ struct serial_icounter_struct __user *p_cuser; /* user space */
unsigned long flags;
switch (cmd) {
case MGSL_IOCGPARAMS:
- return mgsl_get_params(info,(MGSL_PARAMS *)arg);
+ return mgsl_get_params(info, argp);
case MGSL_IOCSPARAMS:
- return mgsl_set_params(info,(MGSL_PARAMS *)arg);
+ return mgsl_set_params(info, argp);
case MGSL_IOCGTXIDLE:
- return mgsl_get_txidle(info,(int*)arg);
+ return mgsl_get_txidle(info, argp);
case MGSL_IOCSTXIDLE:
return mgsl_set_txidle(info,(int)arg);
case MGSL_IOCTXENABLE:
case MGSL_IOCTXABORT:
return mgsl_txabort(info);
case MGSL_IOCGSTATS:
- return mgsl_get_stats(info,(struct mgsl_icount*)arg);
+ return mgsl_get_stats(info, argp);
case MGSL_IOCWAITEVENT:
- return mgsl_wait_event(info,(int*)arg);
+ return mgsl_wait_event(info, argp);
case MGSL_IOCLOOPTXDONE:
return mgsl_loopmode_send_done(info);
/* Wait for modem input (DCD,RI,DSR,CTS) change
spin_lock_irqsave(&info->irq_spinlock,flags);
cnow = info->icount;
spin_unlock_irqrestore(&info->irq_spinlock,flags);
- p_cuser = (struct serial_icounter_struct *) arg;
+ p_cuser = argp;
PUT_USER(error,cnow.cts, &p_cuser->cts);
if (error) return error;
PUT_USER(error,cnow.dsr, &p_cuser->dsr);
* Arguments: none
* Return Value: pointer to mgsl_struct if success, otherwise NULL
*/
-struct mgsl_struct* mgsl_allocate_device()
+struct mgsl_struct* mgsl_allocate_device(void)
{
struct mgsl_struct *info;
/*
* perform tty device initialization
*/
-int mgsl_init_tty(void);
-int mgsl_init_tty()
+static int mgsl_init_tty(void)
{
- serial_driver = alloc_tty_driver(mgsl_device_count);
+ int rc;
+
+ serial_driver = alloc_tty_driver(128);
if (!serial_driver)
return -ENOMEM;
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
serial_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(serial_driver, &mgsl_ops);
- if (tty_register_driver(serial_driver) < 0)
+ if ((rc = tty_register_driver(serial_driver)) < 0) {
printk("%s(%d):Couldn't register serial driver\n",
__FILE__,__LINE__);
+ put_tty_driver(serial_driver);
+ serial_driver = NULL;
+ return rc;
+ }
printk("%s %s, tty major#%d\n",
driver_name, driver_version,
/* enumerate user specified ISA adapters
*/
-int mgsl_enum_isa_devices()
+static void mgsl_enum_isa_devices(void)
{
struct mgsl_struct *info;
int i;
mgsl_add_device( info );
}
-
- return 0;
}
-/* mgsl_init()
- *
- * Driver initialization entry point.
- *
- * Arguments: None
- * Return Value: 0 if success, otherwise error code
- */
-int __init mgsl_init(void)
-{
- int rc;
-
- printk("%s %s\n", driver_name, driver_version);
-
- mgsl_enum_isa_devices();
- pci_register_driver(&synclink_pci_driver);
-
- if ( !mgsl_device_list ) {
- printk("%s(%d):No SyncLink devices found.\n",__FILE__,__LINE__);
- return -ENODEV;
- }
- if ((rc = mgsl_init_tty()))
- return rc;
-
- return 0;
-}
-
-static int __init synclink_init(void)
-{
-/* Uncomment this to kernel debug module.
- * mgsl_get_text_ptr() leaves the .text address in eax
- * which can be used with add-symbol-file with gdb.
- */
- if (break_on_load) {
- mgsl_get_text_ptr();
- BREAKPOINT();
- }
-
- return mgsl_init();
-}
-
-static void __exit synclink_exit(void)
+static void synclink_cleanup(void)
{
int rc;
struct mgsl_struct *info;
printk("Unloading %s: %s\n", driver_name, driver_version);
- if ((rc = tty_unregister_driver(serial_driver)))
- printk("%s(%d) failed to unregister tty driver err=%d\n",
- __FILE__,__LINE__,rc);
+ if (serial_driver) {
+ if ((rc = tty_unregister_driver(serial_driver)))
+ printk("%s(%d) failed to unregister tty driver err=%d\n",
+ __FILE__,__LINE__,rc);
+ put_tty_driver(serial_driver);
+ }
- put_tty_driver(serial_driver);
info = mgsl_device_list;
while(info) {
#ifdef CONFIG_SYNCLINK_SYNCPPP
tmp_buf = NULL;
}
- pci_unregister_driver(&synclink_pci_driver);
+ if (pci_registered)
+ pci_unregister_driver(&synclink_pci_driver);
+}
+
+static int __init synclink_init(void)
+{
+ int rc;
+
+ if (break_on_load) {
+ mgsl_get_text_ptr();
+ BREAKPOINT();
+ }
+
+ printk("%s %s\n", driver_name, driver_version);
+
+ mgsl_enum_isa_devices();
+ if ((rc = pci_register_driver(&synclink_pci_driver)) < 0)
+ printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc);
+ else
+ pci_registered = 1;
+
+ if ((rc = mgsl_init_tty()) < 0)
+ goto error;
+
+ return 0;
+
+error:
+ synclink_cleanup();
+ return rc;
+}
+
+static void __exit synclink_exit(void)
+{
+ synclink_cleanup();
}
module_init(synclink_init);
/*
- * $Id: synclinkmp.c,v 4.19 2004/03/08 15:29:23 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.22 2004/06/03 14:50:10 paulkf Exp $
*
* Device driver for Microgate SyncLink Multiport
* high speed multiprotocol serial adapter.
MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.19 $";
+static char *driver_version = "$Revision: 4.22 $";
static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
static void synclinkmp_remove_one(struct pci_dev *dev);
/* ioctl handlers */
-static int get_stats(SLMP_INFO *info, struct mgsl_icount *user_icount);
-static int get_params(SLMP_INFO *info, MGSL_PARAMS *params);
-static int set_params(SLMP_INFO *info, MGSL_PARAMS *params);
-static int get_txidle(SLMP_INFO *info, int*idle_mode);
+static int get_stats(SLMP_INFO *info, struct mgsl_icount __user *user_icount);
+static int get_params(SLMP_INFO *info, MGSL_PARAMS __user *params);
+static int set_params(SLMP_INFO *info, MGSL_PARAMS __user *params);
+static int get_txidle(SLMP_INFO *info, int __user *idle_mode);
static int set_txidle(SLMP_INFO *info, int idle_mode);
static int tx_enable(SLMP_INFO *info, int enable);
static int tx_abort(SLMP_INFO *info);
static int rx_enable(SLMP_INFO *info, int enable);
static int map_status(int signals);
static int modem_input_wait(SLMP_INFO *info,int arg);
-static int wait_mgsl_event(SLMP_INFO *info, int *mask_ptr);
+static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
static int tiocmget(struct tty_struct *tty, struct file *file);
static int tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
* This allows remote debugging of dynamically loadable modules.
*/
static void* synclinkmp_get_text_ptr(void);
-static void* synclinkmp_get_text_ptr() {return synclinkmp_get_text_ptr;}
+static void* synclinkmp_get_text_ptr(void) {return synclinkmp_get_text_ptr;}
static inline int sanity_check(SLMP_INFO *info,
char *name, const char *routine)
SLMP_INFO *info = (SLMP_INFO *)tty->driver_data;
int error;
struct mgsl_icount cnow; /* kernel counter temps */
- struct serial_icounter_struct *p_cuser; /* user space */
+ struct serial_icounter_struct __user *p_cuser; /* user space */
unsigned long flags;
+ void __user *argp = (void __user *)arg;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s ioctl() cmd=%08X\n", __FILE__,__LINE__,
switch (cmd) {
case MGSL_IOCGPARAMS:
- return get_params(info,(MGSL_PARAMS *)arg);
+ return get_params(info, argp);
case MGSL_IOCSPARAMS:
- return set_params(info,(MGSL_PARAMS *)arg);
+ return set_params(info, argp);
case MGSL_IOCGTXIDLE:
- return get_txidle(info,(int*)arg);
+ return get_txidle(info, argp);
case MGSL_IOCSTXIDLE:
- return set_txidle(info,(int)arg);
+ return set_txidle(info, (int)arg);
case MGSL_IOCTXENABLE:
- return tx_enable(info,(int)arg);
+ return tx_enable(info, (int)arg);
case MGSL_IOCRXENABLE:
- return rx_enable(info,(int)arg);
+ return rx_enable(info, (int)arg);
case MGSL_IOCTXABORT:
return tx_abort(info);
case MGSL_IOCGSTATS:
- return get_stats(info,(struct mgsl_icount*)arg);
+ return get_stats(info, argp);
case MGSL_IOCWAITEVENT:
- return wait_mgsl_event(info,(int*)arg);
+ return wait_mgsl_event(info, argp);
case MGSL_IOCLOOPTXDONE:
return 0; // TODO: Not supported, need to document
/* Wait for modem input (DCD,RI,DSR,CTS) change
spin_lock_irqsave(&info->lock,flags);
cnow = info->icount;
spin_unlock_irqrestore(&info->lock,flags);
- p_cuser = (struct serial_icounter_struct *) arg;
+ p_cuser = argp;
PUT_USER(error,cnow.cts, &p_cuser->cts);
if (error) return error;
PUT_USER(error,cnow.dsr, &p_cuser->dsr);
program_hw(info);
}
-static int get_stats(SLMP_INFO * info, struct mgsl_icount *user_icount)
+static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
{
int err;
return 0;
}
-static int get_params(SLMP_INFO * info, MGSL_PARAMS *user_params)
+static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params)
{
int err;
if (debug_level >= DEBUG_LEVEL_INFO)
return 0;
}
-static int set_params(SLMP_INFO * info, MGSL_PARAMS *new_params)
+static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params)
{
unsigned long flags;
MGSL_PARAMS tmp_params;
return 0;
}
-static int get_txidle(SLMP_INFO * info, int*idle_mode)
+static int get_txidle(SLMP_INFO * info, int __user *idle_mode)
{
int err;
/* wait for specified event to occur
*/
-static int wait_mgsl_event(SLMP_INFO * info, int * mask_ptr)
+static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
{
unsigned long flags;
int s;
.tiocmset = tiocmset,
};
-/* Driver initialization entry point.
- */
-
-static int __init synclinkmp_init(void)
-{
- if (break_on_load) {
- synclinkmp_get_text_ptr();
- BREAKPOINT();
- }
-
- printk("%s %s\n", driver_name, driver_version);
-
- synclinkmp_adapter_count = -1;
- pci_register_driver(&synclinkmp_pci_driver);
-
- if ( !synclinkmp_device_list ) {
- printk("%s(%d):No SyncLink devices found.\n",__FILE__,__LINE__);
- return -ENODEV;
- }
-
- serial_driver = alloc_tty_driver(synclinkmp_device_count);
- if (!serial_driver)
- return -ENOMEM;
-
- /* Initialize the tty_driver structure */
-
- serial_driver->owner = THIS_MODULE;
- serial_driver->driver_name = "synclinkmp";
- serial_driver->name = "ttySLM";
- serial_driver->major = ttymajor;
- serial_driver->minor_start = 64;
- serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
- serial_driver->subtype = SERIAL_TYPE_NORMAL;
- serial_driver->init_termios = tty_std_termios;
- serial_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- serial_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(serial_driver, &ops);
- if (tty_register_driver(serial_driver) < 0)
- printk("%s(%d):Couldn't register serial driver\n",
- __FILE__,__LINE__);
-
- printk("%s %s, tty major#%d\n",
- driver_name, driver_version,
- serial_driver->major);
-
- return 0;
-}
-
-static void __exit synclinkmp_exit(void)
+static void synclinkmp_cleanup(void)
{
unsigned long flags;
int rc;
printk("Unloading %s %s\n", driver_name, driver_version);
- if ((rc = tty_unregister_driver(serial_driver)))
- printk("%s(%d) failed to unregister tty driver err=%d\n",
- __FILE__,__LINE__,rc);
- put_tty_driver(serial_driver);
+ if (serial_driver) {
+ if ((rc = tty_unregister_driver(serial_driver)))
+ printk("%s(%d) failed to unregister tty driver err=%d\n",
+ __FILE__,__LINE__,rc);
+ put_tty_driver(serial_driver);
+ }
info = synclinkmp_device_list;
while(info) {
pci_unregister_driver(&synclinkmp_pci_driver);
}
+/* Driver initialization entry point.
+ */
+
+static int __init synclinkmp_init(void)
+{
+ int rc;
+
+ if (break_on_load) {
+ synclinkmp_get_text_ptr();
+ BREAKPOINT();
+ }
+
+ printk("%s %s\n", driver_name, driver_version);
+
+ if ((rc = pci_register_driver(&synclinkmp_pci_driver)) < 0) {
+ printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc);
+ return rc;
+ }
+
+ serial_driver = alloc_tty_driver(128);
+ if (!serial_driver) {
+ rc = -ENOMEM;
+ goto error;
+ }
+
+ /* Initialize the tty_driver structure */
+
+ serial_driver->owner = THIS_MODULE;
+ serial_driver->driver_name = "synclinkmp";
+ serial_driver->name = "ttySLM";
+ serial_driver->major = ttymajor;
+ serial_driver->minor_start = 64;
+ serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ serial_driver->subtype = SERIAL_TYPE_NORMAL;
+ serial_driver->init_termios = tty_std_termios;
+ serial_driver->init_termios.c_cflag =
+ B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ serial_driver->flags = TTY_DRIVER_REAL_RAW;
+ tty_set_operations(serial_driver, &ops);
+ if ((rc = tty_register_driver(serial_driver)) < 0) {
+ printk("%s(%d):Couldn't register serial driver\n",
+ __FILE__,__LINE__);
+ put_tty_driver(serial_driver);
+ serial_driver = NULL;
+ goto error;
+ }
+
+ printk("%s %s, tty major#%d\n",
+ driver_name, driver_version,
+ serial_driver->major);
+
+ return 0;
+
+error:
+ synclinkmp_cleanup();
+ return rc;
+}
+
+static void __exit synclinkmp_exit(void)
+{
+ synclinkmp_cleanup();
+}
+
module_init(synclinkmp_init);
module_exit(synclinkmp_exit);
unsigned long arg)
{
SMMRegisters regs;
+ SMMRegisters __user *argp = (SMMRegisters __user *)arg;
unsigned short ax,bx;
int err;
- if (!arg)
+ if (!argp)
return -EINVAL;
- if (copy_from_user(®s, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+ if (copy_from_user(®s, argp, sizeof(SMMRegisters)))
return -EFAULT;
switch (cmd) {
return -EINVAL;
}
- if (copy_to_user((SMMRegisters *) arg, ®s, sizeof(SMMRegisters)))
+ if (copy_to_user(argp, ®s, sizeof(SMMRegisters)))
return -EFAULT;
return (err==0) ? 0:-EINVAL;
* request would return the EOF flag for the previous file.
*/
-static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_tape_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
{
int type = iminor(filp->f_dentry->d_inode);
unsigned short flags = filp->f_flags;
* tape device again. The driver will detect an exception status in (No Cartridge)
* and force a rewind. After that tar may continue writing.
*/
-static ssize_t qic02_tape_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_tape_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
{
int type = iminor(filp->f_dentry->d_inode);
unsigned short flags = filp->f_flags;
struct mtop operation;
unsigned char blk_addr[6];
struct mtpos ioctl_tell;
+ void __user *argp = (void __user *)ioarg;
if (TP_DIAGS(current_type))
if (c == _IOC_NR(MTIOCGETCONFIG)) {
CHECK_IOC_SIZE(mtconfiginfo);
- if (copy_to_user((char *) ioarg, (char *) &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
+ if (copy_to_user(argp, &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
return -EFAULT;
return 0;
} else if (c == _IOC_NR(MTIOCSETCONFIG)) {
qic02_release_resources(); /* and go zombie */
/* copy struct from user space to kernel space */
- if (copy_from_user((char *) &qic02_tape_dynconf, (char *) ioarg, sizeof(qic02_tape_dynconf)))
+ if (copy_from_user(&qic02_tape_dynconf, argp, sizeof(qic02_tape_dynconf)))
return -EFAULT;
return update_ifc_masks(qic02_tape_dynconf.ifc_type);
CHECK_IOC_SIZE(mtop);
/* copy mtop struct from user space to kernel space */
- if (copy_from_user((char *) &operation, (char *) ioarg, sizeof(operation)))
+ if (copy_from_user(&operation, argp, sizeof(operation)))
return -EFAULT;
/* ---note: mt_count is signed, negative seeks must be
*/
/* copy results to user space */
- if (copy_to_user((char *) ioarg, (char *) &ioctl_status, sizeof(ioctl_status)))
+ if (copy_to_user(argp, &ioctl_status, sizeof(ioctl_status)))
return -EFAULT;
return 0;
} else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS))) {
ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
/* copy results to user space */
- if (copy_to_user((char *) ioarg, (char *) &ioctl_tell, sizeof(ioctl_tell)))
+ if (copy_to_user(argp, &ioctl_tell, sizeof(ioctl_tell)))
return -EFAULT;
return 0;
} /* qic02_tape_ioctl */
-static ssize_t qic02_do_tape_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_do_tape_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
{
int err;
return err;
}
-static ssize_t qic02_do_tape_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+static ssize_t qic02_do_tape_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
{
int err;
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
+#include <linux/idr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#ifdef CONFIG_UNIX98_PTYS
extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
extern int pty_limit; /* Config limit on Unix98 ptys */
+static DEFINE_IDR(allocated_ptys);
+static DECLARE_MUTEX(allocated_ptys_lock);
#endif
extern void disable_early_printk(void);
{
struct tty_struct *tty, *o_tty;
int pty_master, tty_closing, o_tty_closing, do_sleep;
+ int devpts_master;
int idx;
char buf[64];
idx = tty->index;
pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER);
+ devpts_master = pty_master && (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM);
o_tty = tty->link;
#ifdef TTY_PARANOIA_CHECK
o_tty->ldisc = ldiscs[N_TTY];
}
- /*
+ /*
* The release_mem function takes care of the details of clearing
* the slots and preserving the termios structure.
*/
release_mem(tty, idx);
+
+#ifdef CONFIG_UNIX98_PTYS
+ /* Make this pty number available for reallocation */
+ if (devpts_master) {
+ down(&allocated_ptys_lock);
+ idr_remove(&allocated_ptys, idx);
+ up(&allocated_ptys_lock);
+ }
+#endif
+
}
/*
int index;
dev_t device = inode->i_rdev;
unsigned short saved_flags = filp->f_flags;
+
retry_open:
noctty = filp->f_flags & O_NOCTTY;
+ index = -1;
+ retval = 0;
+
if (device == MKDEV(TTYAUX_MAJOR,0)) {
if (!current->signal->tty)
return -ENXIO;
#ifdef CONFIG_UNIX98_PTYS
if (device == MKDEV(TTYAUX_MAJOR,2)) {
+ int idr_ret;
+
/* find a device that is not in use. */
- static int next_ptmx_dev = 0;
- retval = -1;
+ down(&allocated_ptys_lock);
+ if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) {
+ up(&allocated_ptys_lock);
+ return -ENOMEM;
+ }
+ idr_ret = idr_get_new(&allocated_ptys, NULL, &index);
+ if (idr_ret < 0) {
+ up(&allocated_ptys_lock);
+ if (idr_ret == -EAGAIN)
+ return -ENOMEM;
+ return -EIO;
+ }
+ if (index >= pty_limit) {
+ idr_remove(&allocated_ptys, index);
+ up(&allocated_ptys_lock);
+ return -EIO;
+ }
+ up(&allocated_ptys_lock);
+
driver = ptm_driver;
- while (driver->refcount < pty_limit) {
- index = next_ptmx_dev;
- next_ptmx_dev = (next_ptmx_dev+1) % driver->num;
- if (!init_dev(driver, index, &tty))
- goto ptmx_found; /* ok! */
+ retval = init_dev(driver, index, &tty);
+ if (retval) {
+ down(&allocated_ptys_lock);
+ idr_remove(&allocated_ptys, index);
+ up(&allocated_ptys_lock);
+ return retval;
}
- return -EIO; /* no free ptys */
- ptmx_found:
+
set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
- if (devpts_pty_new(tty->link)) {
- /* BADNESS - need to destroy both ptm and pts! */
- return -ENOMEM;
- }
- noctty = 1;
+ if (devpts_pty_new(tty->link))
+ retval = -ENOMEM;
} else
#endif
{
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "opening %s...", tty->name);
#endif
- if (tty->driver->open)
- retval = tty->driver->open(tty, filp);
- else
- retval = -ENODEV;
+ if (!retval) {
+ if (tty->driver->open)
+ retval = tty->driver->open(tty, filp);
+ else
+ retval = -ENODEV;
+ }
filp->f_flags = saved_flags;
if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
tty->name);
#endif
+#ifdef CONFIG_UNIX98_PTYS
+ if (index != -1) {
+ down(&allocated_ptys_lock);
+ idr_remove(&allocated_ptys, index);
+ up(&allocated_ptys_lock);
+ }
+#endif
+
release_dev(filp);
if (retval != -ERESTARTSYS)
return retval;
* /dev/watchdog handling.
*/
-static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
unsigned long arg)
{
int options, retval = -EINVAL;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident =
{
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
switch(cmd)
{
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) ? -EFAULT : 0;
+ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
acq_keepalive();
return 0;
case WDIOC_GETTIMEOUT:
- return put_user(WATCHDOG_HEARTBEAT, (int *)arg);
+ return put_user(WATCHDOG_HEARTBEAT, p);
case WDIOC_SETOPTIONS:
{
- if (get_user(options, (int *)arg))
+ if (get_user(options, p))
return -EFAULT;
if (options & WDIOS_DISABLECARD)
}
static ssize_t
-advwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
unsigned long arg)
{
int new_timeout;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
switch (cmd) {
case WDIOC_GETSUPPORT:
- if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+ if (copy_to_user(argp, &ident, sizeof(ident)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
advwdt_ping();
break;
case WDIOC_SETTIMEOUT:
- if (get_user(new_timeout, (int *)arg))
+ if (get_user(new_timeout, p))
return -EFAULT;
if ((new_timeout < 1) || (new_timeout > 63))
return -EINVAL;
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
case WDIOC_SETOPTIONS:
{
int options, retval = -EINVAL;
- if (get_user(options, (int *)arg))
+ if (get_user(options, p))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
* the next close to turn off the watchdog.
*/
-static ssize_t ali_write(struct file *file, const char *data,
+static ssize_t ali_write(struct file *file, const char __user *data,
size_t len, loff_t * ppos)
{
/* Can't seek (pwrite) on this device */
static int ali_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
switch (cmd) {
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *) arg, &ident,
+ return copy_to_user(argp, &ident,
sizeof (ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *) arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
ali_keepalive();
{
int new_options, retval = -EINVAL;
- if (get_user (new_options, (int *) arg))
+ if (get_user (new_options, p))
return -EFAULT;
if (new_options & WDIOS_DISABLECARD) {
{
int new_timeout;
- if (get_user(new_timeout, (int *) arg))
+ if (get_user(new_timeout, p))
return -EFAULT;
if (ali_settimer(new_timeout))
}
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
default:
return -ENOIOCTLCMD;
* /dev/watchdog handling
*/
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
{
/* We can't seek */
if(ppos != &file->f_pos)
static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident =
{
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
switch(cmd)
{
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdt_keepalive();
return 0;
{
int new_options, retval = -EINVAL;
- if(get_user(new_options, (int *)arg))
+ if(get_user(new_options, p))
return -EFAULT;
if(new_options & WDIOS_DISABLECARD) {
{
int new_timeout;
- if(get_user(new_timeout, (int *)arg))
+ if(get_user(new_timeout, p))
return -EFAULT;
if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
/* Fall through */
}
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
default:
return -ENOIOCTLCMD;
}
static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
unsigned int value;
static struct watchdog_info ident =
{
case WDIOC_GETSTATUS:
value = inb(port + CPU5WDT_STATUS_REG);
value = (value >> 2) & 1;
- if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) )
+ if ( copy_to_user(argp, &value, sizeof(int)) )
return -EFAULT;
break;
case WDIOC_GETSUPPORT:
- if ( copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) )
+ if ( copy_to_user(argp, &ident, sizeof(ident)) )
return -EFAULT;
break;
case WDIOC_SETOPTIONS:
- if ( copy_from_user(&value, (int *)arg, sizeof(int)) )
+ if ( copy_from_user(&value, argp, sizeof(int)) )
return -EFAULT;
switch(value) {
case WDIOS_ENABLECARD:
return 0;
}
-static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
if ( !count )
return -EIO;
* write of data will do, as we we don't define content meaning.
*/
-static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count,
-loff_t *ppos)
+static ssize_t eurwdt_write(struct file *file, const char __user *buf,
+size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
static int eurwdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident,
- sizeof(ident)) ? -EFAULT : 0;
+ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *) arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
eurwdt_ping();
return 0;
case WDIOC_SETTIMEOUT:
- if (copy_from_user(&time, (int *) arg, sizeof(int)))
+ if (copy_from_user(&time, p, sizeof(int)))
return -EFAULT;
/* Sanity check */
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(eurwdt_timeout, (int *)arg);
+ return put_user(eurwdt_timeout, p);
case WDIOC_SETOPTIONS:
- if (get_user(options, (int *)arg))
+ if (get_user(options, p))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
eurwdt_disable_timer();
return 0;
}
-static ssize_t i8xx_tco_write (struct file *file, const char *data,
+static ssize_t i8xx_tco_write (struct file *file, const char __user *data,
size_t len, loff_t * ppos)
{
/* Can't seek (pwrite) on this device */
{
int new_options, retval = -EINVAL;
int new_heartbeat;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
switch (cmd) {
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *) arg, &ident,
+ return copy_to_user(argp, &ident,
sizeof (ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user (0, (int *) arg);
+ return put_user (0, p);
case WDIOC_KEEPALIVE:
tco_timer_keepalive ();
case WDIOC_SETOPTIONS:
{
- if (get_user (new_options, (int *) arg))
+ if (get_user (new_options, p))
return -EFAULT;
if (new_options & WDIOS_DISABLECARD) {
case WDIOC_SETTIMEOUT:
{
- if (get_user(new_heartbeat, (int *) arg))
+ if (get_user(new_heartbeat, p))
return -EFAULT;
if (tco_timer_set_heartbeat(new_heartbeat))
}
case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, (int *)arg);
+ return put_user(heartbeat, p);
default:
return -ENOIOCTLCMD;
}
static ssize_t
-ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
unsigned long arg)
{
int i, new_margin;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
switch (cmd) {
case WDIOC_GETSUPPORT:
- if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+ if (copy_to_user(argp, &ident, sizeof(ident)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
- return put_user(0, (int *) arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
ibwdt_ping();
break;
case WDIOC_SETTIMEOUT:
- if (get_user(new_margin, (int *)arg))
+ if (get_user(new_margin, p))
return -EFAULT;
if ((new_margin < 0) || (new_margin > 30))
return -EINVAL;
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(wd_times[wd_margin], (int *)arg);
+ return put_user(wd_times[wd_margin], p);
break;
default:
}
}
-static ssize_t zf_write(struct file *file, const char *buf, size_t count,
+static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
switch(cmd){
case WDIOC_GETSUPPORT:
- if (copy_to_user((struct watchdog_info *)arg,
- &zf_info, sizeof(zf_info)))
+ if (copy_to_user(argp, &zf_info, sizeof(zf_info)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
- return put_user(0, (int *) arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
zf_ping(0);
}
-static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
{
if (ppos != &file->f_pos) {
return -ESPIPE;
static int mixcomwd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
int status;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
if (!nowayout) {
status|=mixcomwd_timer_alive;
}
- if (copy_to_user((int *)arg, &status, sizeof(int))) {
+ if (copy_to_user(p, &status, sizeof(int))) {
return -EFAULT;
}
break;
case WDIOC_GETSUPPORT:
- if (copy_to_user((struct watchdog_info *)arg, &ident,
- sizeof(ident))) {
+ if (copy_to_user(argp, &ident, sizeof(ident))) {
return -EFAULT;
}
break;
#include <asm/uaccess.h>
#include <asm/io.h>
-#define WD_VER "1.16 (03/27/2004)"
+#define WD_VER "1.16 (06/12/2004)"
#define PFX "pcwd: "
/*
return 0;
}
-static void pcwd_keepalive(void)
+static int pcwd_keepalive(void)
{
/* user land ping */
next_heartbeat = jiffies + (heartbeat * HZ);
+ return 0;
}
static int pcwd_set_heartbeat(int t)
int status;
int temperature;
int new_heartbeat;
+ int __user *argp = (int __user *)arg;
static struct watchdog_info ident = {
.options = WDIOF_OVERHEAT |
WDIOF_CARDRESET |
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- if(copy_to_user((void*)arg, &ident, sizeof(ident)))
+ if(copy_to_user(argp, &ident, sizeof(ident)))
return -EFAULT;
return 0;
case WDIOC_GETSTATUS:
pcwd_get_status(&status);
- return put_user(status, (int *) arg);
+ return put_user(status, argp);
case WDIOC_GETBOOTSTATUS:
- return put_user(initial_status, (int *) arg);
+ return put_user(initial_status, argp);
case WDIOC_GETTEMP:
if (pcwd_get_temperature(&temperature))
return -EFAULT;
- return put_user(temperature, (int *) arg);
+ return put_user(temperature, argp);
case WDIOC_SETOPTIONS:
if (revision == PCWD_REVISION_C)
{
- if(copy_from_user(&rv, (int*) arg, sizeof(int)))
+ if(copy_from_user(&rv, argp, sizeof(int)))
return -EFAULT;
if (rv & WDIOS_DISABLECARD)
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(new_heartbeat, (int *) arg))
+ if (get_user(new_heartbeat, argp))
return -EFAULT;
if (pcwd_set_heartbeat(new_heartbeat))
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, (int *)arg);
+ return put_user(heartbeat, argp);
}
return 0;
}
-static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
+static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len,
loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
{
if (expect_close == 42) {
pcwd_stop();
- atomic_inc( &open_allowed );
} else {
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
pcwd_keepalive();
}
expect_close = 0;
+ atomic_inc( &open_allowed );
return 0;
}
* /dev/temperature handling
*/
-static ssize_t pcwd_temp_read(struct file *file, char *buf, size_t count,
+static ssize_t pcwd_temp_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
int temperature;
/* Module and version information */
#define WATCHDOG_VERSION "1.00"
-#define WATCHDOG_DATE "13/03/2004"
+#define WATCHDOG_DATE "12 Jun 2004"
#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
#define WATCHDOG_NAME "pcwd_pci"
#define PFX WATCHDOG_NAME ": "
#define WD_PCI_TTRP 0x04 /* Temperature Trip status */
/* according to documentation max. time to process a command for the pci
- watchdog card is 100 ms, so we give it 150 ms to do it's job */
+ * watchdog card is 100 ms, so we give it 150 ms to do it's job */
#define PCI_COMMAND_TIMEOUT 150
/* Watchdog's internal commands */
* /dev/watchdog handling
*/
-static ssize_t pcipcwd_write(struct file *file, const char *data,
+static ssize_t pcipcwd_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
static int pcipcwd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_OVERHEAT |
WDIOF_CARDRESET |
switch (cmd) {
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *) arg, &ident,
+ return copy_to_user(argp, &ident,
sizeof (ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
pcipcwd_get_status(&status);
- return put_user(status, (int *) arg);
+ return put_user(status, p);
}
case WDIOC_GETBOOTSTATUS:
- return put_user(pcipcwd_private.boot_status, (int *) arg);
+ return put_user(pcipcwd_private.boot_status, p);
case WDIOC_GETTEMP:
{
if (pcipcwd_get_temperature(&temperature))
return -EFAULT;
- return put_user(temperature, (int *) arg);
+ return put_user(temperature, p);
}
case WDIOC_KEEPALIVE:
{
int new_options, retval = -EINVAL;
- if (get_user (new_options, (int *) arg))
+ if (get_user (new_options, p))
return -EFAULT;
if (new_options & WDIOS_DISABLECARD) {
{
int new_heartbeat;
- if (get_user(new_heartbeat, (int *) arg))
+ if (get_user(new_heartbeat, p))
return -EFAULT;
if (pcipcwd_set_heartbeat(new_heartbeat))
}
case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, (int *)arg);
+ return put_user(heartbeat, p);
default:
return -ENOIOCTLCMD;
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
pcipcwd_keepalive();
}
- clear_bit(0, &is_active);
expect_release = 0;
+ clear_bit(0, &is_active);
return 0;
}
* /dev/temperature handling
*/
-static ssize_t pcipcwd_temp_read(struct file *file, char *data,
+static ssize_t pcipcwd_temp_read(struct file *file, char __user *data,
size_t len, loff_t *ppos)
{
int temperature;
printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n");
/* Check that the heartbeat value is within it's range ; if not reset to the default */
- if (heartbeat < 1 || heartbeat > 0xFFFF) {
- heartbeat = WATCHDOG_HEARTBEAT;
+ if (pcipcwd_set_heartbeat(heartbeat)) {
+ pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
- heartbeat);
+ WATCHDOG_HEARTBEAT);
}
- /* Calculate the watchdog's heartbeat */
- pcipcwd_set_heartbeat(heartbeat);
-
ret = register_reboot_notifier(&pcipcwd_notifier);
if (ret != 0) {
printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
goto err_out_release_region;
}
- ret = misc_register(&pcipcwd_miscdev);
- if (ret != 0) {
- printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, ret);
- goto err_out_unregister_reboot;
- }
-
if (pcipcwd_private.supports_temp) {
ret = misc_register(&pcipcwd_temp_miscdev);
if (ret != 0) {
printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
TEMP_MINOR, ret);
- goto err_out_misc_deregister;
+ goto err_out_unregister_reboot;
}
}
+ ret = misc_register(&pcipcwd_miscdev);
+ if (ret != 0) {
+ printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+ WATCHDOG_MINOR, ret);
+ goto err_out_misc_deregister;
+ }
+
printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
heartbeat, nowayout);
return 0;
err_out_misc_deregister:
- misc_deregister(&pcipcwd_miscdev);
+ if (pcipcwd_private.supports_temp)
+ misc_deregister(&pcipcwd_temp_miscdev);
err_out_unregister_reboot:
unregister_reboot_notifier(&pcipcwd_notifier);
err_out_release_region:
pcipcwd_stop();
/* Deregister */
+ misc_deregister(&pcipcwd_miscdev);
if (pcipcwd_private.supports_temp)
misc_deregister(&pcipcwd_temp_miscdev);
- misc_deregister(&pcipcwd_miscdev);
unregister_reboot_notifier(&pcipcwd_notifier);
pci_release_regions(pdev);
pci_disable_device(pdev);
/* Module and Version Information */
-#define DRIVER_VERSION "v1.00 (28/02/2004)"
+#define DRIVER_VERSION "1.00"
+#define DRIVER_DATE "12 Jun 2004"
#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
#define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
#define DRIVER_LICENSE "GPL"
* /dev/watchdog handling
*/
-static ssize_t usb_pcwd_write(struct file *file, const char *data,
+static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
switch (cmd) {
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *) arg, &ident,
+ return copy_to_user(argp, &ident,
sizeof (ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *) arg);
+ return put_user(0, p);
case WDIOC_GETTEMP:
{
if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
return -EFAULT;
- return put_user(temperature, (int *) arg);
+ return put_user(temperature, p);
}
case WDIOC_KEEPALIVE:
{
int new_options, retval = -EINVAL;
- if (get_user (new_options, (int *) arg))
+ if (get_user (new_options, p))
return -EFAULT;
if (new_options & WDIOS_DISABLECARD) {
{
int new_heartbeat;
- if (get_user(new_heartbeat, (int *) arg))
+ if (get_user(new_heartbeat, p))
return -EFAULT;
if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat))
}
case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, (int *)arg);
+ return put_user(heartbeat, p);
default:
return -ENOIOCTLCMD;
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
usb_pcwd_keepalive(usb_pcwd_device);
}
- clear_bit(0, &is_active);
expect_release = 0;
+ clear_bit(0, &is_active);
return 0;
}
* /dev/temperature handling
*/
-static ssize_t usb_pcwd_temperature_read(struct file *file, char *data,
+static ssize_t usb_pcwd_temperature_read(struct file *file, char __user *data,
size_t len, loff_t *ppos)
{
int temperature;
if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
return -EFAULT;
- if (copy_to_user (data, &temperature, 1))
+ if (copy_to_user(data, &temperature, 1))
return -EFAULT;
return 1;
((option_switches & 0x08) ? "ON" : "OFF"));
/* Check that the heartbeat value is within it's range ; if not reset to the default */
- if (heartbeat < 1 || heartbeat > 0xFFFF) {
- heartbeat = WATCHDOG_HEARTBEAT;
+ if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
+ usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n",
- heartbeat);
+ WATCHDOG_HEARTBEAT);
}
- /* Calculate the watchdog's heartbeat */
- usb_pcwd_set_heartbeat(usb_pcwd, heartbeat);
-
retval = register_reboot_notifier(&usb_pcwd_notifier);
if (retval != 0) {
printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
goto error;
}
- retval = misc_register(&usb_pcwd_miscdev);
+ retval = misc_register(&usb_pcwd_temperature_miscdev);
if (retval != 0) {
printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, retval);
+ TEMP_MINOR, retval);
goto err_out_unregister_reboot;
}
- retval = misc_register(&usb_pcwd_temperature_miscdev);
+ retval = misc_register(&usb_pcwd_miscdev);
if (retval != 0) {
printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
- TEMP_MINOR, retval);
+ WATCHDOG_MINOR, retval);
goto err_out_misc_deregister;
}
return 0;
err_out_misc_deregister:
- misc_deregister(&usb_pcwd_miscdev);
+ misc_deregister(&usb_pcwd_temperature_miscdev);
err_out_unregister_reboot:
unregister_reboot_notifier(&usb_pcwd_notifier);
error:
usb_pcwd->exists = 0;
/* Deregister */
- misc_deregister(&usb_pcwd_temperature_miscdev);
misc_deregister(&usb_pcwd_miscdev);
+ misc_deregister(&usb_pcwd_temperature_miscdev);
unregister_reboot_notifier(&usb_pcwd_notifier);
up (&usb_pcwd->sem);
return result;
}
- printk(KERN_INFO PFX DRIVER_DESC " " DRIVER_VERSION "\n");
+ printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION " (" DRIVER_DATE ")\n");
return 0;
}
* /dev/watchdog handling
*/
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
{
/* We can't seek */
if(ppos != &file->f_pos)
static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident=
{
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdt_keepalive();
return 0;
{
int new_options, retval = -EINVAL;
- if(get_user(new_options, (int *)arg))
+ if(get_user(new_options, p))
return -EFAULT;
if(new_options & WDIOS_DISABLECARD) {
{
int new_timeout;
- if(get_user(new_timeout, (int *)arg))
+ if(get_user(new_timeout, p))
return -EFAULT;
if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
/* Fall through */
}
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
}
}
static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int new_timeout;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 0,
return -ENOIOCTLCMD; /* Keep Pavel Machek amused ;) */
case WDIOC_GETSUPPORT:
- if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident))
+ if (copy_to_user(argp, &ident, sizeof ident))
return -EFAULT;
return 0;
case WDIOC_GETSTATUS:
- return put_user(sc1200wdt_status(), (int *)arg);
+ return put_user(sc1200wdt_status(), p);
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
sc1200wdt_write_data(WDTO, timeout);
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(new_timeout, (int *)arg))
+ if (get_user(new_timeout, p))
return -EFAULT;
/* the API states this is given in secs */
/* fall through and return the new timeout */
case WDIOC_GETTIMEOUT:
- return put_user(timeout * 60, (int *)arg);
+ return put_user(timeout * 60, p);
case WDIOC_SETOPTIONS:
{
int options, retval = -EINVAL;
- if (get_user(options, (int *)arg))
+ if (get_user(options, p))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
}
-static ssize_t sc1200wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t sc1200wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
{
if (ppos != &file->f_pos)
return -ESPIPE;
* /dev/watchdog handling
*/
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
{
/* We can't seek */
if(ppos != &file->f_pos)
static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdt_keepalive();
return 0;
{
int new_options, retval = -EINVAL;
- if(get_user(new_options, (int *)arg))
+ if(get_user(new_options, p))
return -EFAULT;
if(new_options & WDIOS_DISABLECARD) {
{
int new_timeout;
- if(get_user(new_timeout, (int *)arg))
+ if(get_user(new_timeout, p))
return -EFAULT;
if(wdt_set_heartbeat(new_timeout))
/* Fall through */
}
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
}
}
.notifier_call = scx200_wdt_notify_sys,
};
-static ssize_t scx200_wdt_write(struct file *file, const char *data,
+static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
if (ppos != &file->f_pos)
static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.identity = "NatSemi SCx200 Watchdog",
.firmware_version = 1,
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- if(copy_to_user((struct watchdog_info *)arg, &ident,
- sizeof(ident)))
+ if(copy_to_user(argp, &ident, sizeof(ident)))
return -EFAULT;
return 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- if (put_user(0, (int *)arg))
+ if (put_user(0, p))
return -EFAULT;
return 0;
case WDIOC_KEEPALIVE:
scx200_wdt_ping();
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(new_margin, (int *)arg))
+ if (get_user(new_margin, p))
return -EFAULT;
if (new_margin < 1)
return -EINVAL;
scx200_wdt_update_margin();
scx200_wdt_ping();
case WDIOC_GETTIMEOUT:
- if (put_user(margin, (int *)arg))
+ if (put_user(margin, p))
return -EFAULT;
return 0;
}
return 0;
}
-static ssize_t softdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
static int softdog_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
int new_margin;
static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident,
+ return copy_to_user(argp, &ident,
sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0,(int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
softdog_keepalive();
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(new_margin, (int *)arg))
+ if (get_user(new_margin, p))
return -EFAULT;
if (softdog_set_heartbeat(new_margin))
return -EINVAL;
softdog_keepalive();
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(soft_margin, (int *)arg);
+ return put_user(soft_margin, p);
}
}
}
static ssize_t
-wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
int new_timeout;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
switch (cmd) {
case WDIOC_GETSUPPORT:
- if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+ if (copy_to_user(argp, &ident, sizeof(ident)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdt_ping();
break;
case WDIOC_SETTIMEOUT:
- if (get_user(new_timeout, (int *)arg))
+ if (get_user(new_timeout, p))
return -EFAULT;
if (wdt_set_heartbeat(new_timeout))
return -EINVAL;
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
case WDIOC_SETOPTIONS:
{
int options, retval = -EINVAL;
- if (get_user(options, (int *)arg))
+ if (get_user(options, p))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
* /dev/watchdog handling
*/
-static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
+static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos)
{
/* We can't seek */
if(ppos != &file->f_pos)
static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident=
{
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdt_keepalive();
return 0;
{
int new_options, retval = -EINVAL;
- if(get_user(new_options, (int *)arg))
+ if(get_user(new_options, p))
return -EFAULT;
if(new_options & WDIOS_DISABLECARD) {
{
int new_timeout;
- if(get_user(new_timeout, (int *)arg))
+ if(get_user(new_timeout, p))
return -EFAULT;
if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
/* Fall through */
}
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
}
}
inb_p(wdt_stop);
}
-static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
unsigned long arg)
{
int new_timeout;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1,
switch (cmd) {
case WDIOC_GETSUPPORT:
- if (copy_to_user
- ((struct watchdog_info *) arg, &ident, sizeof (ident)))
+ if (copy_to_user(argp, &ident, sizeof (ident)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wafwdt_ping();
break;
case WDIOC_SETTIMEOUT:
- if (get_user(new_timeout, (int *)arg))
+ if (get_user(new_timeout, p))
return -EFAULT;
if ((new_timeout < 1) || (new_timeout > 255))
return -EINVAL;
wafwdt_start();
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(timeout, (int *)arg);
+ return put_user(timeout, p);
case WDIOC_SETOPTIONS:
{
int options, retval = -EINVAL;
- if (get_user(options, (int *)arg))
+ if (get_user(options, p))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
* write of data will do, as we we don't define content meaning.
*/
-static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
int new_heartbeat;
int status;
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
wdt_get_status(&status);
- return put_user(status,(int *)arg);
+ return put_user(status, p);
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdt_ping();
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(new_heartbeat, (int *)arg))
+ if (get_user(new_heartbeat, p))
return -EFAULT;
if (wdt_set_heartbeat(new_heartbeat))
wdt_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, (int *)arg);
+ return put_user(heartbeat, p);
}
}
* farenheit. It was designed by an imperial measurement luddite.
*/
-static ssize_t wdt_temp_read(struct file *file, char *buf, size_t count, loff_t *ptr)
+static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
{
int temperature;
* write of data will do, as we we don't define content meaning.
*/
-static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
/* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos)
{
int new_heartbeat;
int status;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT|
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
+ return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
case WDIOC_GETSTATUS:
wdtpci_get_status(&status);
- return put_user(status,(int *)arg);
+ return put_user(status, p);
case WDIOC_GETBOOTSTATUS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case WDIOC_KEEPALIVE:
wdtpci_ping();
return 0;
case WDIOC_SETTIMEOUT:
- if (get_user(new_heartbeat, (int *)arg))
+ if (get_user(new_heartbeat, p))
return -EFAULT;
if (wdtpci_set_heartbeat(new_heartbeat))
wdtpci_ping();
/* Fall */
case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, (int *)arg);
+ return put_user(heartbeat, p);
}
}
* fahrenheit. It was designed by an imperial measurement luddite.
*/
-static ssize_t wdtpci_temp_read(struct file *file, char *buf, size_t count, loff_t *ptr)
+static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
{
int temperature;
unsigned int target_freq,
unsigned int relation)
{
- return cpufreq_driver->target(policy, target_freq, relation);
+ int retval = -EINVAL;
+ lock_cpu_hotplug();
+ if (cpu_online(policy->cpu))
+ retval = cpufreq_driver->target(policy, target_freq, relation);
+ unlock_cpu_hotplug();
+ return retval;
}
EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
if (oldlen != sizeof(unsigned int))
return -EINVAL;
- if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
+ if (put_user(cpufreq_get(cpu), (unsigned int __user *)oldval) ||
put_user(sizeof(unsigned int), oldlenp))
return -EFAULT;
}
if (newlen != sizeof(unsigned int))
return -EINVAL;
- if (get_user(freq, (unsigned int *)newval))
+ if (get_user(freq, (unsigned int __user *)newval))
return -EFAULT;
cpufreq_set(freq, cpu);
*/
static int cpufreq_proc_write (
struct file *file,
- const char *buffer,
+ const char __user *buffer,
unsigned long count,
void *data)
{
#include <asm/irq.h>
#include <asm/semaphore.h>
#include "fcp_impl.h"
-#include "../scsi/hosts.h"
+#include <scsi/scsi_host.h>
/* #define FCDEBUG */
}
static ssize_t
-edd_show_legacy_cylinders(struct edd_device *edev, char *buf)
+edd_show_legacy_max_cylinder(struct edd_device *edev, char *buf)
{
struct edd_info *info;
char *p = buf;
if (!info || !buf)
return -EINVAL;
- p += snprintf(p, left, "0x%x\n", info->legacy_cylinders);
+ p += snprintf(p, left, "%u\n", info->legacy_max_cylinder);
return (p - buf);
}
static ssize_t
-edd_show_legacy_heads(struct edd_device *edev, char *buf)
+edd_show_legacy_max_head(struct edd_device *edev, char *buf)
{
struct edd_info *info;
char *p = buf;
if (!info || !buf)
return -EINVAL;
- p += snprintf(p, left, "0x%x\n", info->legacy_heads);
+ p += snprintf(p, left, "%u\n", info->legacy_max_head);
return (p - buf);
}
static ssize_t
-edd_show_legacy_sectors(struct edd_device *edev, char *buf)
+edd_show_legacy_sectors_per_track(struct edd_device *edev, char *buf)
{
struct edd_info *info;
char *p = buf;
if (!info || !buf)
return -EINVAL;
- p += snprintf(p, left, "0x%x\n", info->legacy_sectors);
+ p += snprintf(p, left, "%u\n", info->legacy_sectors_per_track);
return (p - buf);
}
if (!info || !buf)
return -EINVAL;
- p += scnprintf(p, left, "0x%x\n", info->params.num_default_cylinders);
+ p += scnprintf(p, left, "%u\n", info->params.num_default_cylinders);
return (p - buf);
}
if (!info || !buf)
return -EINVAL;
- p += scnprintf(p, left, "0x%x\n", info->params.num_default_heads);
+ p += scnprintf(p, left, "%u\n", info->params.num_default_heads);
return (p - buf);
}
if (!info || !buf)
return -EINVAL;
- p += scnprintf(p, left, "0x%x\n", info->params.sectors_per_track);
+ p += scnprintf(p, left, "%u\n", info->params.sectors_per_track);
return (p - buf);
}
if (!info || !buf)
return -EINVAL;
- p += scnprintf(p, left, "0x%llx\n", info->params.number_of_sectors);
+ p += scnprintf(p, left, "%llu\n", info->params.number_of_sectors);
return (p - buf);
}
*/
static int
-edd_has_legacy_cylinders(struct edd_device *edev)
+edd_has_legacy_max_cylinder(struct edd_device *edev)
{
struct edd_info *info;
if (!edev)
info = edd_dev_get_info(edev);
if (!info)
return -EINVAL;
- return info->legacy_cylinders > 0;
+ return info->legacy_max_cylinder > 0;
}
static int
-edd_has_legacy_heads(struct edd_device *edev)
+edd_has_legacy_max_head(struct edd_device *edev)
{
struct edd_info *info;
if (!edev)
info = edd_dev_get_info(edev);
if (!info)
return -EINVAL;
- return info->legacy_heads > 0;
+ return info->legacy_max_head > 0;
}
static int
-edd_has_legacy_sectors(struct edd_device *edev)
+edd_has_legacy_sectors_per_track(struct edd_device *edev)
{
struct edd_info *info;
if (!edev)
info = edd_dev_get_info(edev);
if (!info)
return -EINVAL;
- return info->legacy_sectors > 0;
+ return info->legacy_sectors_per_track > 0;
}
static int
static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, NULL);
static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, NULL);
static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, NULL);
-static EDD_DEVICE_ATTR(legacy_cylinders, 0444, edd_show_legacy_cylinders,
- edd_has_legacy_cylinders);
-static EDD_DEVICE_ATTR(legacy_heads, 0444, edd_show_legacy_heads,
- edd_has_legacy_heads);
-static EDD_DEVICE_ATTR(legacy_sectors, 0444, edd_show_legacy_sectors,
- edd_has_legacy_sectors);
+static EDD_DEVICE_ATTR(legacy_max_cylinder, 0444,
+ edd_show_legacy_max_cylinder,
+ edd_has_legacy_max_cylinder);
+static EDD_DEVICE_ATTR(legacy_max_head, 0444, edd_show_legacy_max_head,
+ edd_has_legacy_max_head);
+static EDD_DEVICE_ATTR(legacy_sectors_per_track, 0444,
+ edd_show_legacy_sectors_per_track,
+ edd_has_legacy_sectors_per_track);
static EDD_DEVICE_ATTR(default_cylinders, 0444, edd_show_default_cylinders,
edd_has_default_cylinders);
static EDD_DEVICE_ATTR(default_heads, 0444, edd_show_default_heads,
/* These attributes are conditional and only added for some devices. */
static struct edd_attribute * edd_attrs[] = {
- &edd_attr_legacy_cylinders,
- &edd_attr_legacy_heads,
- &edd_attr_legacy_sectors,
+ &edd_attr_legacy_max_cylinder,
+ &edd_attr_legacy_max_head,
+ &edd_attr_legacy_sectors_per_track,
&edd_attr_default_cylinders,
&edd_attr_default_heads,
&edd_attr_default_sectors_per_track,
goto out_unlock;
}
- id = idr_get_new(&i2c_adapter_idr, NULL);
+ res = idr_get_new(&i2c_adapter_idr, NULL, &id);
+ if (res < 0) {
+ if (res == -EAGAIN)
+ res = -ENOMEM;
+ goto out_unlock;
+ }
+
adap->nr = id & MAX_ID_MASK;
init_MUTEX(&adap->bus_lock);
init_MUTEX(&adap->clist_lock);
dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr);
- out_unlock:
+out_unlock:
up(&core_lists);
return res;
}
config BLK_DEV_HD_IDE
bool "Use old disk-only driver on primary interface"
- depends on ((X86 && X86_PC9800!=y) || SH_MPC1211)
- ---help---
- There are two drivers for MFM/RLL/IDE disks. Most people use just
- the new enhanced driver by itself. This option however installs the
- old hard disk driver to control the primary IDE/disk interface in
- the system, leaving the new enhanced IDE driver to take care of only
- the 2nd/3rd/4th IDE interfaces. Doing this will prevent you from
- having an IDE/ATAPI CD-ROM or tape drive connected to the primary
- IDE interface. Choosing this option may be useful for older systems
- which have MFM/RLL/ESDI controller+drives at the primary port
- address (0x1f0), along with IDE drives at the secondary/3rd/4th port
- addresses.
-
- Normally, just say N here; you will then use the new driver for all
- 4 interfaces.
-
-config BLK_DEV_HD_IDE98
- bool "Use old disk-only driver on primary interface"
- depends on X86 && X86_PC9800
+ depends on (X86 || SH_MPC1211)
---help---
There are two drivers for MFM/RLL/IDE disks. Most people use just
the new enhanced driver by itself. This option however installs the
If in doubt, say N.
-config IDEDISK_STROKE
- bool "Auto-Geometry Resizing support"
- depends on BLK_DEV_IDEDISK
- help
- Should you have a system w/ an AWARD Bios and your drives are larger
- than 32GB and it will not boot, one is required to perform a few OEM
- operations first. The option is called "STROKE" because it allows
- one to "soft clip" the drive to work around a barrier limit. For
- Maxtor drives it is called "jumpon.exe". Please search Maxtor's
- web-site for "JUMPON.EXE". IBM has a similar tool at:
- <http://www.storage.ibm.com/hdd/support/download.htm>.
-
- If you are unsure, say N here.
-
config BLK_DEV_IDECS
tristate "PCMCIA IDE support"
depends on PCMCIA
if BLK_DEV_IDEDMA_PCI
-# TCQ is disabled for now
-config BLK_DEV_IDE_TCQ
- bool "ATA tagged command queueing (EXPERIMENTAL)"
- depends on EXPERIMENTAL && n
- help
- Support for tagged command queueing on ATA disk drives. This enables
- the IDE layer to have multiple in-flight requests on hardware that
- supports it. For now this includes the IBM Deskstar series drives,
- such as the 22GXP, 75GXP, 40GV, 60GXP, and 120GXP (ie any Deskstar made
- in the last couple of years), and at least some of the Western
- Digital drives in the Expert series (by nature of really being IBM
- drives).
-
- If you have such a drive, say Y here.
-
-config BLK_DEV_IDE_TCQ_DEFAULT
- bool "TCQ on by default"
- depends on BLK_DEV_IDE_TCQ
- ---help---
- Enable tagged command queueing unconditionally on drives that report
- support for it. Regardless of the chosen value here, tagging can be
- controlled at run time:
-
- echo "using_tcq:32" > /proc/ide/hdX/settings
-
- where any value between 1-32 selects chosen queue depth and enables
- TCQ, and 0 disables it. hdparm version 4.7 an above also support
- TCQ manipulations.
-
- Generally say Y here.
-
-config BLK_DEV_IDE_TCQ_DEPTH
- int "Default queue depth"
- depends on BLK_DEV_IDE_TCQ
- default "8"
- help
- Maximum size of commands to enable per-drive. Any value between 1
- and 32 is valid, with 32 being the maxium that the hardware supports.
-
- You probably just want the default of 32 here. If you enter an invalid
- number, the default value will be used.
-
config BLK_DEV_IDEDMA_FORCED
bool "Force enable legacy 2.0.X HOSTS to use DMA"
help
ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o
# built-in only drivers from legacy/
-ide-core-$(CONFIG_BLK_DEV_IDE_PC9800) += legacy/pc9800.o
ide-core-$(CONFIG_BLK_DEV_BUDDHA) += legacy/buddha.o
ide-core-$(CONFIG_BLK_DEV_FALCON_IDE) += legacy/falconide.o
ide-core-$(CONFIG_BLK_DEV_GAYLE) += legacy/gayle.o
rq->flags = REQ_PC;
}
-static void cdrom_queue_request_sense(ide_drive_t *drive,
- struct completion *wait,
- void *sense,
+static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
struct cdrom_info *info = drive->driver_data;
rq->cmd[4] = rq->data_len = 18;
rq->flags = REQ_SENSE;
- rq->waiting = wait;
/* NOTE! Save the failed command in "rq->buffer" */
rq->buffer = (void *) failed_command;
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
rq->errors = 1;
ide_end_drive_cmd(drive, stat, err);
return ide_stopped;
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
/* retry only "normal" I/O: */
- if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
rq->errors = 1;
ide_end_drive_cmd(drive, BUSY_STAT, 0);
return ide_stopped;
struct request *failed = (struct request *) rq->buffer;
struct cdrom_info *info = drive->driver_data;
void *sense = &info->sense_data;
-
- if (failed && failed->sense) {
- sense = failed->sense;
- failed->sense_len = rq->sense_len;
+ unsigned long flags;
+
+ if (failed) {
+ if (failed->sense) {
+ sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }
+
+ /*
+ * now end failed request
+ */
+ spin_lock_irqsave(&ide_lock, flags);
+ end_that_request_chunk(failed, 0, failed->data_len);
+ end_that_request_last(failed);
+ spin_unlock_irqrestore(&ide_lock, flags);
}
cdrom_analyze_sense_data(drive, failed, sense);
if (!rq->current_nr_sectors && blk_fs_request(rq))
uptodate = 1;
+ /* make sure it's fully ended */
+ if (blk_pc_request(rq))
+ nsectors = (rq->data_len + 511) >> 9;
if (!nsectors)
nsectors = 1;
} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
/* All other functions, except for READ. */
- struct completion *wait = NULL;
+ unsigned long flags;
/*
* if we have an error, pass back CHECK_CONDITION as the
ide_dump_status(drive, "packet command error", stat);
}
- /* Set the error flag and complete the request.
- Then, if we have a CHECK CONDITION status,
- queue a request sense command. We must be careful,
- though: we don't want the thread in
- cdrom_queue_packet_command to wake up until
- the request sense has completed. We do this
- by transferring the semaphore from the packet
- command request to the request sense request. */
-
rq->flags |= REQ_FAILED;
- if ((stat & ERR_STAT) != 0) {
- wait = rq->waiting;
- rq->waiting = NULL;
- if ((rq->flags & REQ_BLOCK_PC) != 0) {
- cdrom_queue_request_sense(drive, wait,
- rq->sense, rq);
- return 1; /* REQ_BLOCK_PC self-cares */
- }
- }
- cdrom_end_request(drive, 0);
+ /*
+ * instead of playing games with moving completions around,
+ * remove failed request completely and end it when the
+ * request sense has completed
+ */
+ if (stat & ERR_STAT) {
+ spin_lock_irqsave(&ide_lock, flags);
+ blkdev_dequeue_request(rq);
+ HWGROUP(drive)->rq = NULL;
+ spin_unlock_irqrestore(&ide_lock, flags);
+
+ cdrom_queue_request_sense(drive, rq->sense, rq);
+ } else
+ cdrom_end_request(drive, 0);
- if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense(drive, wait, rq->sense, rq);
} else if (blk_fs_request(rq)) {
int do_end_request = 0;
/* If we got a CHECK_CONDITION status,
queue a request sense command. */
if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense(drive, NULL, NULL, NULL);
+ cdrom_queue_request_sense(drive, NULL, NULL);
} else {
blk_dump_rq_flags(rq, "ide-cd: bad rq");
cdrom_end_request(drive, 0);
dma_error = HWIF(drive)->ide_dma_end(drive);
}
- if (cdrom_decode_status(drive, 0, &stat)) {
- if ((stat & ERR_STAT) != 0) {
- end_that_request_chunk(rq, 0, rq->data_len);
- goto end_request; /* purge the whole thing... */
- }
- end_that_request_chunk(rq, 1, rq->data_len);
+ if (cdrom_decode_status(drive, 0, &stat))
return ide_stopped;
- }
/*
* using dma, transfer is complete now
return 0;
}
-
/*
* Close down the device. Invalidate all cached blocks.
*/
devinfo->mask |= CDC_CLOSE_TRAY;
if (!CDROM_CONFIG_FLAGS(drive)->mo_drive)
devinfo->mask |= CDC_MO_DRIVE;
- if (!CDROM_CONFIG_FLAGS(drive)->mrw)
- devinfo->mask |= CDC_MRW;
- if (!CDROM_CONFIG_FLAGS(drive)->mrw_w)
- devinfo->mask |= CDC_MRW_W;
- if (!CDROM_CONFIG_FLAGS(drive)->ram)
- devinfo->mask |= CDC_RAM;
devinfo->disk = drive->disk;
return register_cdrom(devinfo);
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo;
struct atapi_capabilities_page cap;
- int nslots = 1, mrw_write = 0, ram_write = 0;
+ int nslots = 1;
if (drive->media == ide_optical) {
CDROM_CONFIG_FLAGS(drive)->mo_drive = 1;
if (ide_cdrom_get_capabilities(drive, &cap))
return 0;
- if (!cdrom_is_mrw(cdi, &mrw_write)) {
- CDROM_CONFIG_FLAGS(drive)->mrw = 1;
- if (mrw_write) {
- CDROM_CONFIG_FLAGS(drive)->mrw_w = 1;
- CDROM_CONFIG_FLAGS(drive)->ram = 1;
- }
- }
- if (!cdrom_is_random_writable(cdi, &ram_write))
- if (ram_write)
- CDROM_CONFIG_FLAGS(drive)->ram = 1;
-
if (cap.lock == 0)
CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
if (cap.eject)
(CDROM_CONFIG_FLAGS(drive)->cd_r)? "-R" : "",
(CDROM_CONFIG_FLAGS(drive)->cd_rw)? "/RW" : "");
- if (CDROM_CONFIG_FLAGS(drive)->mrw || CDROM_CONFIG_FLAGS(drive)->mrw_w)
- printk(" CD-MR%s", CDROM_CONFIG_FLAGS(drive)->mrw_w ? "W" : "");
-
if (CDROM_CONFIG_FLAGS(drive)->is_changer)
printk(" changer w/%d slots", nslots);
else
__u8 dvd : 1; /* Drive is a DVD-ROM */
__u8 dvd_r : 1; /* Drive can write DVD-R */
__u8 dvd_ram : 1; /* Drive can write DVD-RAM */
- __u8 mrw : 1; /* drive can read mrw */
- __u8 mrw_w : 1; /* drive can write mrw */
__u8 ram : 1; /* generic WRITE (dvd-ram/mrw) */
__u8 test_write : 1; /* Drive can fake writes */
__u8 supp_disc_present : 1; /* Changer can report exact contents
#undef REALLY_SLOW_IO /* most systems can safely undef this */
+//#define DEBUG
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
return 0; /* lba_capacity value may be bad */
}
-static int idedisk_start_tag(ide_drive_t *drive, struct request *rq)
-{
- unsigned long flags;
- int ret = 1;
-
- spin_lock_irqsave(&ide_lock, flags);
-
- if (ata_pending_commands(drive) < drive->queue_depth)
- ret = blk_queue_start_tag(drive->queue, rq);
-
- spin_unlock_irqrestore(&ide_lock, flags);
- return ret;
-}
-
#ifndef CONFIG_IDE_TASKFILE_IO
/*
if (drive->addressing == 1) {
task_ioreg_t tasklets[10];
- if (blk_rq_tagged(rq)) {
- tasklets[0] = nsectors.b.low;
- tasklets[1] = nsectors.b.high;
- tasklets[2] = rq->tag << 3;
- tasklets[3] = 0;
- } else {
- tasklets[0] = 0;
- tasklets[1] = 0;
- tasklets[2] = nsectors.b.low;
- tasklets[3] = nsectors.b.high;
- }
+ pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
+ tasklets[0] = 0;
+ tasklets[1] = 0;
+ tasklets[2] = nsectors.b.low;
+ tasklets[3] = nsectors.b.high;
tasklets[4] = (task_ioreg_t) block;
tasklets[5] = (task_ioreg_t) (block>>8);
tasklets[6] = (task_ioreg_t) (block>>16);
tasklets[9] = (task_ioreg_t)((u64)block >> 40);
}
#ifdef DEBUG
- printk("%s: %sing: LBAsect=%lu, sectors=%ld, "
- "buffer=0x%08lx, LBAsect=0x%012lx\n",
- drive->name,
- rq_data_dir(rq)==READ?"read":"writ",
- block,
- rq->nr_sectors,
- (unsigned long) rq->buffer,
- block);
printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n",
drive->name, tasklets[3], tasklets[2],
tasklets[9], tasklets[8], tasklets[7],
hwif->OUTB(tasklets[6], IDE_HCYL_REG);
hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG);
} else {
-#ifdef DEBUG
- printk("%s: %sing: LBAsect=%llu, sectors=%ld, "
- "buffer=0x%08lx\n",
- drive->name,
- rq_data_dir(rq)==READ?"read":"writ",
- (unsigned long long)block, rq->nr_sectors,
- (unsigned long) rq->buffer);
-#endif
- if (blk_rq_tagged(rq)) {
- hwif->OUTB(nsectors.b.low, IDE_FEATURE_REG);
- hwif->OUTB(rq->tag << 3, IDE_NSECTOR_REG);
- } else {
- hwif->OUTB(0x00, IDE_FEATURE_REG);
- hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
- }
-
+ hwif->OUTB(0x00, IDE_FEATURE_REG);
+ hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
hwif->OUTB(block, IDE_SECTOR_REG);
hwif->OUTB(block>>=8, IDE_LCYL_REG);
hwif->OUTB(block>>=8, IDE_HCYL_REG);
head = track % drive->head;
cyl = track / drive->head;
- if (blk_rq_tagged(rq)) {
- hwif->OUTB(nsectors.b.low, IDE_FEATURE_REG);
- hwif->OUTB(rq->tag << 3, IDE_NSECTOR_REG);
- } else {
- hwif->OUTB(0x00, IDE_FEATURE_REG);
- hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
- }
+ pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
+ hwif->OUTB(0x00, IDE_FEATURE_REG);
+ hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
hwif->OUTB(cyl, IDE_LCYL_REG);
hwif->OUTB(cyl>>8, IDE_HCYL_REG);
hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
-#ifdef DEBUG
- printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n",
- drive->name, rq_data_dir(rq)==READ?"read":"writ", cyl,
- head, sect, rq->nr_sectors, (unsigned long) rq->buffer);
-#endif
}
if (rq_data_dir(rq) == READ) {
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
- if (blk_rq_tagged(rq))
- return __ide_dma_queued_read(drive);
-#endif
if (drive->using_dma && !hwif->ide_dma_read(drive))
return ide_started;
return ide_started;
} else {
ide_startstop_t startstop;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
- if (blk_rq_tagged(rq))
- return __ide_dma_queued_write(drive);
-#endif
+
if (drive->using_dma && !(HWIF(drive)->ide_dma_write(drive)))
return ide_started;
if (cmd == READ) {
task->command_type = IDE_DRIVE_TASK_IN;
- if (drive->using_tcq)
- return lba48 ? WIN_READDMA_QUEUED_EXT : WIN_READDMA_QUEUED;
if (drive->using_dma)
return lba48 ? WIN_READDMA_EXT : WIN_READDMA;
if (drive->mult_count) {
return lba48 ? WIN_READ_EXT : WIN_READ;
} else {
task->command_type = IDE_DRIVE_TASK_RAW_WRITE;
- if (drive->using_tcq)
- return lba48 ? WIN_WRITEDMA_QUEUED_EXT : WIN_WRITEDMA_QUEUED;
if (drive->using_dma)
return lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
if (drive->mult_count) {
nsectors.all = (u16) rq->nr_sectors;
-#ifdef DEBUG
- printk("%s: %sing: ", drive->name, (rq_data_dir(rq)==READ) ? "read" : "writ");
- printk("CHS=%d/%d/%d, ", cyl, head, sect);
- printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
-#endif
+ pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
memset(&args, 0, sizeof(ide_task_t));
sectors = (rq->nr_sectors == 256) ? 0x00 : rq->nr_sectors;
- if (blk_rq_tagged(rq)) {
- args.tfRegister[IDE_FEATURE_OFFSET] = sectors;
- args.tfRegister[IDE_NSECTOR_OFFSET] = rq->tag << 3;
- } else
- args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
-
+ args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
args.tfRegister[IDE_SECTOR_OFFSET] = sect;
args.tfRegister[IDE_LCYL_OFFSET] = cyl;
args.tfRegister[IDE_HCYL_OFFSET] = (cyl>>8);
nsectors.all = (u16) rq->nr_sectors;
-#ifdef DEBUG
- printk("%s: %sing: ", drive->name, (rq_data_dir(rq)==READ) ? "read" : "writ");
- printk("LBAsect=%lld, ", block);
- printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
-#endif
-
memset(&args, 0, sizeof(ide_task_t));
sectors = (rq->nr_sectors == 256) ? 0x00 : rq->nr_sectors;
- if (blk_rq_tagged(rq)) {
- args.tfRegister[IDE_FEATURE_OFFSET] = sectors;
- args.tfRegister[IDE_NSECTOR_OFFSET] = rq->tag << 3;
- } else
- args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
-
+ args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
args.tfRegister[IDE_SECTOR_OFFSET] = block;
args.tfRegister[IDE_LCYL_OFFSET] = (block>>=8);
args.tfRegister[IDE_HCYL_OFFSET] = (block>>=8);
nsectors.all = (u16) rq->nr_sectors;
-#ifdef DEBUG
- printk("%s: %sing: ", drive->name, (rq_data_dir(rq)==READ) ? "read" : "writ");
- printk("LBAsect=%lld, ", block);
- printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
-#endif
-
memset(&args, 0, sizeof(ide_task_t));
sectors = (rq->nr_sectors == 65536) ? 0 : rq->nr_sectors;
- if (blk_rq_tagged(rq)) {
- args.tfRegister[IDE_FEATURE_OFFSET] = sectors;
- args.tfRegister[IDE_NSECTOR_OFFSET] = rq->tag << 3;
- args.hobRegister[IDE_FEATURE_OFFSET] = sectors >> 8;
- args.hobRegister[IDE_NSECTOR_OFFSET] = 0;
- } else {
- args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
- args.hobRegister[IDE_NSECTOR_OFFSET] = sectors >> 8;
- }
-
+ args.tfRegister[IDE_NSECTOR_OFFSET] = sectors;
+ args.hobRegister[IDE_NSECTOR_OFFSET] = sectors >> 8;
args.tfRegister[IDE_SECTOR_OFFSET] = block; /* low lba */
args.tfRegister[IDE_LCYL_OFFSET] = (block>>=8); /* mid lba */
args.tfRegister[IDE_HCYL_OFFSET] = (block>>=8); /* hi lba */
return ide_stopped;
}
- if (drive->using_tcq && idedisk_start_tag(drive, rq)) {
- if (!ata_pending_commands(drive))
- BUG();
-
- return ide_started;
- }
+ pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
+ drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
+ block, rq->nr_sectors, (unsigned long)rq->buffer);
if (hwif->rw_disk)
return hwif->rw_disk(drive, rq, block);
ide_hwif_t *hwif;
struct request *rq;
u8 err;
- int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
err = idedisk_dump_status(drive, msg, stat);
rq->errors |= ERROR_RECAL;
}
}
- if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) {
- /*
- * try_to_flush_leftover_data() is invoked in response to
- * a drive unexpectedly having its DRQ_STAT bit set. As
- * an alternative to resetting the drive, this routine
- * tries to clear the condition by read a sector's worth
- * of data from the drive. Of course, this may not help
- * if the drive is *waiting* for data from *us*.
- */
- while (i > 0) {
- u32 buffer[16];
- unsigned int wcount = (i > 16) ? 16 : i;
- i -= wcount;
- taskfile_input_data(drive, buffer, wcount);
- }
- }
+ if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ)
+ try_to_flush_leftover_data(drive);
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) {
/* force an abort */
hwif->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
return addr;
}
-#ifdef CONFIG_IDEDISK_STROKE
/*
* Sets maximum virtual LBA address of the drive.
* Returns new maximum virtual LBA address (> 0) or 0 on failure.
return addr_set;
}
-#endif /* CONFIG_IDEDISK_STROKE */
-
static unsigned long long sectors_to_MB(unsigned long long n)
{
n <<= 9; /* make it bytes */
drive->name,
capacity, sectors_to_MB(capacity),
set_max, sectors_to_MB(set_max));
-#ifdef CONFIG_IDEDISK_STROKE
+
+ if (!drive->stroke)
+ return;
+
if (lba48)
set_max = idedisk_set_max_address_ext(drive, set_max);
else
printk(KERN_INFO "%s: Host Protected Area disabled.\n",
drive->name);
}
-#endif
}
/*
return 0;
}
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static int set_using_tcq(ide_drive_t *drive, int arg)
-{
- int ret;
-
- if (!drive->driver)
- return -EPERM;
- if (arg == drive->queue_depth && drive->using_tcq)
- return 0;
-
- /*
- * set depth, but check also id for max supported depth
- */
- drive->queue_depth = arg ? arg : 1;
- if (drive->id) {
- if (drive->queue_depth > drive->id->queue_depth + 1)
- drive->queue_depth = drive->id->queue_depth + 1;
- }
-
- if (arg)
- ret = __ide_dma_queued_on(drive);
- else
- ret = __ide_dma_queued_off(drive);
-
- return ret ? -EIO : 0;
-}
-#endif
-
/*
* drive->addressing:
* 0: 28-bit
ide_add_setting(drive, "acoustic", SETTING_RW, HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, TYPE_BYTE, 0, 254, 1, 1, &drive->acoustic, set_acoustic);
ide_add_setting(drive, "failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->failures, NULL);
ide_add_setting(drive, "max_failures", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->max_failures, NULL);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
- ide_add_setting(drive, "using_tcq", SETTING_RW, HDIO_GET_QDMA, HDIO_SET_QDMA, TYPE_BYTE, 0, IDE_MAX_TAG, 1, 1, &drive->using_tcq, set_using_tcq);
-#endif
}
/*
drive->wcache = 1;
write_cache(drive, 1);
-
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
- if (drive->using_dma)
- __ide_dma_queued_on(drive);
-#endif
}
static void ide_cacheflush_p(ide_drive_t *drive)
if (HWIF(drive)->ide_dma_host_off(drive))
return 1;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
- __ide_dma_queued_off(drive);
-#endif
+
return 0;
}
**
*/
-static int idefloppy_get_format_capacities(ide_drive_t *drive, int *arg)
+static int idefloppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
{
idefloppy_pc_t pc;
idefloppy_capacity_header_t *header;
int i, descriptors, blocks, length;
int u_array_size;
int u_index;
- int *argp;
+ int __user *argp;
if (get_user(u_array_size, arg))
return (-EFAULT);
** 0x01 - verify media after format.
*/
-static int idefloppy_begin_format(ide_drive_t *drive, int *arg)
+static int idefloppy_begin_format(ide_drive_t *drive, int __user *arg)
{
int blocks;
int length;
** the dsc bit, and return either 0 or 65536.
*/
-static int idefloppy_get_format_progress(ide_drive_t *drive, int *arg)
+static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
{
idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t pc;
struct block_device *bdev = inode->i_bdev;
ide_drive_t *drive = bdev->bd_disk->private_data;
idefloppy_floppy_t *floppy = drive->driver_data;
+ void __user *argp = (void __user *)arg;
int err = generic_ide_ioctl(bdev, cmd, arg);
int prevent = (arg) ? 1 : 0;
idefloppy_pc_t pc;
case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
return 0;
case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
- return idefloppy_get_format_capacities(drive, (int *)arg);
+ return idefloppy_get_format_capacities(drive, argp);
case IDEFLOPPY_IOCTL_FORMAT_START:
if (!(file->f_mode & 2))
set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
- err = idefloppy_begin_format(drive, (int *)arg);
+ err = idefloppy_begin_format(drive, argp);
if (err)
clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
return err;
** format progress reporting.
*/
case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
- return idefloppy_get_format_progress(drive, (int *)arg);
+ return idefloppy_get_format_progress(drive, argp);
}
return -EINVAL;
}
if (!end_that_request_first(rq, uptodate, nr_sectors)) {
add_disk_randomness(rq->rq_disk);
- if (!blk_rq_tagged(rq))
- blkdev_dequeue_request(rq);
- else
- blk_queue_end_tag(drive->queue, rq);
+ blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
end_that_request_last(rq);
ret = 0;
drive->sleep = 0;
drive->service_start = jiffies;
-queue_next:
- if (!ata_can_queue(drive)) {
- if (!ata_pending_commands(drive))
- hwgroup->busy = 0;
-
- break;
- }
-
if (blk_queue_plugged(drive->queue)) {
- if (drive->using_tcq)
- break;
-
printk(KERN_ERR "ide: huh? queue was plugged!\n");
break;
}
*/
rq = elv_next_request(drive->queue);
if (!rq) {
- hwgroup->busy = !!ata_pending_commands(drive);
+ hwgroup->busy = 0;
break;
}
break;
}
- if (!rq->bio && ata_pending_commands(drive))
- break;
-
hwgroup->rq = rq;
/*
spin_lock_irq(&ide_lock);
if (hwif->irq != masked_irq)
enable_irq(hwif->irq);
- if (startstop == ide_released)
- goto queue_next;
if (startstop == ide_stopped)
hwgroup->busy = 0;
}
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/ide.h>
#include <linux/init.h>
-
#include <linux/pnp.h>
-
-#define GENERIC_HD_DATA 0
-#define GENERIC_HD_ERROR 1
-#define GENERIC_HD_NSECTOR 2
-#define GENERIC_HD_SECTOR 3
-#define GENERIC_HD_LCYL 4
-#define GENERIC_HD_HCYL 5
-#define GENERIC_HD_SELECT 6
-#define GENERIC_HD_STATUS 7
-
-static int generic_ide_offsets[IDE_NR_PORTS] = {
- GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR,
- GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL,
- GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1
-};
+#include <linux/ide.h>
/* Add your devices here :)) */
struct pnp_device_id idepnp_devices[] = {
if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0)))
return -1;
- ide_setup_ports(&hw, (unsigned long) pnp_port_start(dev, 0),
- generic_ide_offsets,
- (unsigned long) pnp_port_start(dev, 1),
- 0, NULL,
-// generic_pnp_ide_iops,
- pnp_irq(dev, 0));
+ memset(&hw, 0, sizeof(hw));
+ ide_std_init_ports(&hw, pnp_port_start(dev, 0),
+ pnp_port_start(dev, 1));
+ hw.irq = pnp_irq(dev, 0);
+ hw.dma = NO_DMA;
index = ide_register_hw(&hw, &hwif);
.remove = idepnp_remove,
};
-
-void pnpide_init(int enable)
+void __init pnpide_init(void)
{
- if(enable)
- pnp_register_driver(&idepnp_driver);
- else
- pnp_unregister_driver(&idepnp_driver);
+ pnp_register_driver(&idepnp_driver);
}
drive->media = ide_disk;
printk("%s DISK drive\n", (drive->is_flash) ? "CFA" : "ATA" );
QUIRK_LIST(drive);
-
- /* Initialize queue depth settings */
- drive->queue_depth = 1;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
- drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
-#else
- drive->queue_depth = drive->id->queue_depth + 1;
-#endif
- if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG)
- drive->queue_depth = IDE_MAX_TAG;
-
return;
err_misc:
device_register(&hwif->gendev);
}
-//EXPORT_SYMBOL(hwif_register);
-
#ifdef CONFIG_PPC
static int wait_hwif_ready(ide_hwif_t *hwif)
{
* This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here.
*/
-void probe_hwif (ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif)
{
unsigned int unit;
unsigned long flags;
}
}
-EXPORT_SYMBOL(probe_hwif);
-
-int hwif_init (ide_hwif_t *hwif);
+static int hwif_init(ide_hwif_t *hwif);
int probe_hwif_init (ide_hwif_t *hwif)
{
probe_hwif(hwif);
*
* This routine detects and reports such situations, but does not fix them.
*/
-void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
+static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match)
{
ide_hwif_t *m = *match;
if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */
*match = new;
}
-EXPORT_SYMBOL(save_match);
#endif /* MAX_HWIFS > 1 */
/*
THIS_MODULE, ata_probe, ata_lock, hwif);
}
-EXPORT_SYMBOL(init_gendisk);
-
-int hwif_init (ide_hwif_t *hwif)
+static int hwif_init(ide_hwif_t *hwif)
{
int old_irq, unit;
return 0;
}
-EXPORT_SYMBOL(hwif_init);
-
int ideprobe_init (void)
{
unsigned int index;
}
#endif /* CONFIG_BLK_DEV_IDEPCI */
} else { /* not pci */
-#if !defined(__mc68000__) && !defined(CONFIG_APUS)
-
-/*
-* Geert Uytterhoeven
-*
-* unless you can explain me what it really does.
-* On m68k, we don't have outw() and outl() yet,
-* and I need a good reason to implement it.
-*
-* BTW, IMHO the main remaining portability problem with the IDE driver
-* is that it mixes IO (ioport) and MMIO (iomem) access on different platforms.
-*
-* I think all accesses should be done using
-*
-* ide_in[bwl](ide_device_instance, offset)
-* ide_out[bwl](ide_device_instance, value, offset)
-*
-* so the architecture specific code can #define ide_{in,out}[bwl] to the
-* appropriate function.
-*
-*/
switch (r->size) {
case 1: hwif->OUTB(val, reg);
break;
case 4: hwif->OUTL(val, reg);
break;
}
-#endif /* !__mc68000__ && !CONFIG_APUS */
}
}
spin_unlock_irqrestore(&ide_lock, flags);
goto out1;
}
-int proc_ide_read_config
+static int proc_ide_read_config
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
char *out = page;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_config);
-
static int proc_ide_read_imodel
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
- case ide_pc9800: name = "pc9800"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_imodel);
-
-int proc_ide_read_mate
+static int proc_ide_read_mate
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_mate);
-
-int proc_ide_read_channel
+static int proc_ide_read_channel
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_hwif_t *hwif = (ide_hwif_t *) data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_channel);
-
-int proc_ide_read_identify
+static int proc_ide_read_identify
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *)data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_identify);
-
-int proc_ide_read_settings
+static int proc_ide_read_settings
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_settings);
-
#define MAX_LEN 30
-int proc_ide_write_settings(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+static int proc_ide_write_settings(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
char name[MAX_LEN + 1];
return -EINVAL;
}
-EXPORT_SYMBOL(proc_ide_write_settings);
-
int proc_ide_read_capacity
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_capacity);
-
int proc_ide_read_geometry
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
EXPORT_SYMBOL(proc_ide_read_geometry);
-int proc_ide_read_dmodel
+static int proc_ide_read_dmodel
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_dmodel);
-
-int proc_ide_read_driver
+static int proc_ide_read_driver
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_driver);
-
-int proc_ide_write_driver
+static int proc_ide_write_driver
(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
return count;
}
-EXPORT_SYMBOL(proc_ide_write_driver);
-
-int proc_ide_read_media
+static int proc_ide_read_media
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
-EXPORT_SYMBOL(proc_ide_read_media);
-
static ide_proc_entry_t generic_drive_entries[] = {
{ "driver", S_IFREG|S_IRUGO, proc_ide_read_driver, proc_ide_write_driver },
{ "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL },
}
}
-EXPORT_SYMBOL(ide_add_proc_entries);
-
void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
{
if (!dir || !p)
}
}
-EXPORT_SYMBOL(ide_remove_proc_entries);
-
-void create_proc_ide_drives(ide_hwif_t *hwif)
+static void create_proc_ide_drives(ide_hwif_t *hwif)
{
int d;
struct proc_dir_entry *ent;
}
}
-EXPORT_SYMBOL(create_proc_ide_drives);
-
-void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
+static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive)
{
ide_driver_t *driver = drive->driver;
}
}
-EXPORT_SYMBOL(destroy_proc_ide_device);
-
void destroy_proc_ide_drives(ide_hwif_t *hwif)
{
int d;
}
}
-EXPORT_SYMBOL(destroy_proc_ide_drives);
-
static ide_proc_entry_t hwif_entries[] = {
{ "channel", S_IFREG|S_IRUGO, proc_ide_read_channel, NULL },
{ "config", S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config, proc_ide_write_config },
entry->proc_fops = &ide_drivers_operations;
}
-EXPORT_SYMBOL(proc_ide_create);
-
void proc_ide_destroy(void)
{
remove_proc_entry("ide/drivers", proc_ide_root);
destroy_proc_ide_interfaces();
remove_proc_entry("ide", 0);
}
-
-EXPORT_SYMBOL(proc_ide_destroy);
return __idetape_kmalloc_stage(tape, 0, 0);
}
-static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char *buf, int n)
+static void idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char __user *buf, int n)
{
struct idetape_bh *bh = tape->bh;
int count;
tape->bh = bh;
}
-static void idetape_copy_stage_to_user (idetape_tape_t *tape, char *buf, idetape_stage_t *stage, int n)
+static void idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, idetape_stage_t *stage, int n)
{
struct idetape_bh *bh = tape->bh;
int count;
{
idetape_tape_t *tape = drive->driver_data;
idetape_config_t config;
+ void __user *argp = (void __user *)arg;
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 4)
#endif /* IDETAPE_DEBUG_LOG */
switch (cmd) {
case 0x0340:
- if (copy_from_user ((char *) &config, (char *) arg, sizeof (idetape_config_t)))
+ if (copy_from_user(&config, argp, sizeof (idetape_config_t)))
return -EFAULT;
tape->best_dsc_rw_frequency = config.dsc_rw_frequency;
tape->max_stages = config.nr_stages;
case 0x0350:
config.dsc_rw_frequency = (int) tape->best_dsc_rw_frequency;
config.nr_stages = tape->max_stages;
- if (copy_to_user((char *) arg, (char *) &config, sizeof (idetape_config_t)))
+ if (copy_to_user(argp, &config, sizeof (idetape_config_t)))
return -EFAULT;
break;
default:
* will no longer hit performance.
* This is not applicable to Onstream.
*/
-static ssize_t idetape_chrdev_read (struct file *file, char *buf,
+static ssize_t idetape_chrdev_read (struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
ide_drive_t *drive = file->private_data;
return actually_read;
}
-static ssize_t idetape_chrdev_write (struct file *file, const char *buf,
+static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
ide_drive_t *drive = file->private_data;
struct mtget mtget;
struct mtpos mtpos;
int block_offset = 0, position = tape->first_frame_position;
+ void __user *argp = (void __user *)arg;
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 3)
}
switch (cmd) {
case MTIOCTOP:
- if (copy_from_user((char *) &mtop, (char *) arg, sizeof (struct mtop)))
+ if (copy_from_user(&mtop, argp, sizeof (struct mtop)))
return -EFAULT;
return (idetape_mtioctop(drive,mtop.mt_op,mtop.mt_count));
case MTIOCGET:
if (tape->drv_write_prot) {
mtget.mt_gstat |= GMT_WR_PROT(0xffffffff);
}
- if (copy_to_user((char *) arg,(char *) &mtget, sizeof(struct mtget)))
+ if (copy_to_user(argp, &mtget, sizeof(struct mtget)))
return -EFAULT;
return 0;
case MTIOCPOS:
mtpos.mt_blkno = position / tape->user_bs_factor - block_offset;
- if (copy_to_user((char *) arg,(char *) &mtpos, sizeof(struct mtpos)))
+ if (copy_to_user(argp, &mtpos, sizeof(struct mtpos)))
return -EFAULT;
return 0;
default:
if (!hwif->ide_dma_read(drive))
return ide_started;
break;
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
- case WIN_READDMA_QUEUED:
- case WIN_READDMA_QUEUED_EXT:
- return __ide_dma_queued_read(drive);
- case WIN_WRITEDMA_QUEUED:
- case WIN_WRITEDMA_QUEUED_EXT:
- return __ide_dma_queued_write(drive);
-#endif
default:
if (task->handler == NULL)
return ide_stopped;
*/
#ifndef CONFIG_IDE_TASKFILE_IO
-#define task_map_rq(rq, flags) ide_map_buffer((rq), (flags))
-#define task_unmap_rq(rq, buf, flags) ide_unmap_buffer((rq), (buf), (flags))
-
/*
* Handler for command with PIO data-in phase, READ
*/
-/*
- * FIXME before 2.4 enable ...
- * DATA integrity issue upon error. <andre@linux-ide.org>
- */
ide_startstop_t task_in_intr (ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
ide_hwif_t *hwif = HWIF(drive);
char *pBuf = NULL;
u8 stat;
- unsigned long flags;
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
-#if 0
- DTF("%s: attempting to recover last " \
- "sector counter status=0x%02x\n",
- drive->name, stat);
- /*
- * Expect a BUG BOMB if we attempt to rewind the
- * offset in the BH aka PAGE in the current BLOCK
- * segment. This is different than the HOST segment.
- */
-#endif
- if (!rq->bio)
- rq->current_nr_sectors++;
return DRIVER(drive)->error(drive, "task_in_intr", stat);
}
if (!(stat & BUSY_STAT)) {
return ide_started;
}
}
-#if 0
- /*
- * Holding point for a brain dump of a thought :-/
- */
-
- if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) {
- DTF("%s: READ attempting to recover last " \
- "sector counter status=0x%02x\n",
- drive->name, stat);
- rq->current_nr_sectors++;
- return DRIVER(drive)->error(drive, "task_in_intr", stat);
- }
- if (!rq->current_nr_sectors)
- if (!DRIVER(drive)->end_request(drive, 1, 0))
- return ide_stopped;
-
- if (--rq->current_nr_sectors <= 0)
- if (!DRIVER(drive)->end_request(drive, 1, 0))
- return ide_stopped;
-#endif
-
- pBuf = task_map_rq(rq, &flags);
+ pBuf = rq->buffer + task_rq_offset(rq);
DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n",
pBuf, (int) rq->current_nr_sectors, stat);
taskfile_input_data(drive, pBuf, SECTOR_WORDS);
- task_unmap_rq(rq, pBuf, &flags);
- /*
- * FIXME :: We really can not legally get a new page/bh
- * regardless, if this is the end of our segment.
- * BH walking or segment can only be updated after we have a good
- * hwif->INB(IDE_STATUS_REG); return.
- */
+
+ /* FIXME: check drive status */
if (--rq->current_nr_sectors <= 0)
if (!DRIVER(drive)->end_request(drive, 1, 0))
return ide_stopped;
char *pBuf = NULL;
unsigned int msect = drive->mult_count;
unsigned int nsect;
- unsigned long flags;
u8 stat;
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
- if (!rq->bio) {
- rq->current_nr_sectors += drive->mult_count;
- /*
- * NOTE: could rewind beyond beginning :-/
- */
- } else {
- printk(KERN_ERR "%s: MULTI-READ assume all data " \
- "transfered is bad status=0x%02x\n",
- drive->name, stat);
- }
return DRIVER(drive)->error(drive, "task_mulin_intr", stat);
}
/* no data yet, so wait for another interrupt */
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
- pBuf = task_map_rq(rq, &flags);
+ pBuf = rq->buffer + task_rq_offset(rq);
DTF("Multiread: %p, nsect: %d, msect: %d, " \
" rq->current_nr_sectors: %d\n",
pBuf, nsect, msect, rq->current_nr_sectors);
taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
- task_unmap_rq(rq, pBuf, &flags);
rq->errors = 0;
rq->current_nr_sectors -= nsect;
msect -= nsect;
- /*
- * FIXME :: We really can not legally get a new page/bh
- * regardless, if this is the end of our segment.
- * BH walking or segment can only be updated after we have a
- * good hwif->INB(IDE_STATUS_REG); return.
- */
+
+ /* FIXME: check drive status */
if (!rq->current_nr_sectors) {
if (!DRIVER(drive)->end_request(drive, 1, 0))
return ide_stopped;
*/
ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
{
- char *pBuf = NULL;
- unsigned long flags;
ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, DATA_READY,
return startstop;
}
/* For Write_sectors we need to stuff the first sector */
- pBuf = task_map_rq(rq, &flags);
- taskfile_output_data(drive, pBuf, SECTOR_WORDS);
+ taskfile_output_data(drive, rq->buffer + task_rq_offset(rq), SECTOR_WORDS);
rq->current_nr_sectors--;
- task_unmap_rq(rq, pBuf, &flags);
return ide_started;
}
ide_hwif_t *hwif = HWIF(drive);
struct request *rq = HWGROUP(drive)->rq;
char *pBuf = NULL;
- unsigned long flags;
u8 stat;
if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) {
- DTF("%s: WRITE attempting to recover last " \
- "sector counter status=0x%02x\n",
- drive->name, stat);
- rq->current_nr_sectors++;
return DRIVER(drive)->error(drive, "task_out_intr", stat);
}
/*
return ide_stopped;
if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) {
rq = HWGROUP(drive)->rq;
- pBuf = task_map_rq(rq, &flags);
+ pBuf = rq->buffer + task_rq_offset(rq);
DTF("write: %p, rq->current_nr_sectors: %d\n",
pBuf, (int) rq->current_nr_sectors);
taskfile_output_data(drive, pBuf, SECTOR_WORDS);
- task_unmap_rq(rq, pBuf, &flags);
rq->errors = 0;
rq->current_nr_sectors--;
}
EXPORT_SYMBOL(task_out_intr);
-#undef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
-
ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
{
-#ifdef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
- ide_hwif_t *hwif = HWIF(drive);
- char *pBuf = NULL;
- unsigned int nsect = 0, msect = drive->mult_count;
- u8 stat;
- unsigned long flags;
-#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
-
ide_task_t *args = rq->special;
ide_startstop_t startstop;
-#if 0
- /*
- * assign private copy for multi-write
- */
- memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
-#endif
-
if (ide_wait_stat(&startstop, drive, DATA_READY,
drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %s\n",
drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE");
return startstop;
}
-#ifdef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
-
- do {
- nsect = rq->current_nr_sectors;
- if (nsect > msect)
- nsect = msect;
- pBuf = task_map_rq(rq, &flags);
- DTF("Pre-Multiwrite: %p, nsect: %d, msect: %d, " \
- "rq->current_nr_sectors: %ld\n",
- pBuf, nsect, msect, rq->current_nr_sectors);
- msect -= nsect;
- taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
- task_unmap_rq(rq, pBuf, &flags);
- rq->current_nr_sectors -= nsect;
- if (!rq->current_nr_sectors) {
- if (!DRIVER(drive)->end_request(drive, 1, 0))
- if (!rq->bio) {
- stat = hwif->INB(IDE_STATUS_REG);
- return ide_stopped;
- }
- }
- } while (msect);
- rq->errors = 0;
- return ide_started;
-#else /* ! ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
if (!(drive_is_ready(drive))) {
int i;
for (i=0; i<100; i++) {
* move the DATA-TRANSFER T-Bar as BSY != 0. <andre@linux-ide.org>
*/
return args->handler(drive);
-#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
}
EXPORT_SYMBOL(pre_task_mulout_intr);
-/*
- * FIXME before enabling in 2.4 ... DATA integrity issue upon error.
- */
/*
* Handler for command write multiple
* Called directly from execute_drive_cmd for the first bunch of sectors,
u8 stat = hwif->INB(IDE_STATUS_REG);
struct request *rq = HWGROUP(drive)->rq;
char *pBuf = NULL;
- ide_startstop_t startstop = ide_stopped;
unsigned int msect = drive->mult_count;
unsigned int nsect;
- unsigned long flags;
- /*
- * (ks/hs): Handle last IRQ on multi-sector transfer,
- * occurs after all data was sent in this chunk
- */
- if (rq->current_nr_sectors == 0) {
+ if (!OK_STAT(stat, DATA_READY, BAD_R_STAT) || !rq->current_nr_sectors) {
if (stat & (ERR_STAT|DRQ_STAT)) {
- if (!rq->bio) {
- rq->current_nr_sectors += drive->mult_count;
- /*
- * NOTE: could rewind beyond beginning :-/
- */
- } else {
- printk(KERN_ERR "%s: MULTI-WRITE assume all data " \
- "transfered is bad status=0x%02x\n",
- drive->name, stat);
- }
return DRIVER(drive)->error(drive, "task_mulout_intr", stat);
}
- if (!rq->bio)
+ /* Handle last IRQ, occurs after all data was sent. */
+ if (!rq->current_nr_sectors) {
DRIVER(drive)->end_request(drive, 1, 0);
- return startstop;
- }
- /*
- * DON'T be lazy code the above and below togather !!!
- */
- if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
- if (stat & (ERR_STAT|DRQ_STAT)) {
- if (!rq->bio) {
- rq->current_nr_sectors += drive->mult_count;
- /*
- * NOTE: could rewind beyond beginning :-/
- */
- } else {
- printk("%s: MULTI-WRITE assume all data " \
- "transfered is bad status=0x%02x\n",
- drive->name, stat);
- }
- return DRIVER(drive)->error(drive, "task_mulout_intr", stat);
+ return ide_stopped;
}
/* no data yet, so wait for another interrupt */
if (HWGROUP(drive)->handler == NULL)
return ide_started;
}
-#ifndef ALTERNATE_STATE_DIAGRAM_MULTI_OUT
if (HWGROUP(drive)->handler != NULL) {
unsigned long lflags;
spin_lock_irqsave(&ide_lock, lflags);
del_timer(&HWGROUP(drive)->timer);
spin_unlock_irqrestore(&ide_lock, lflags);
}
-#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */
do {
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
- pBuf = task_map_rq(rq, &flags);
+ pBuf = rq->buffer + task_rq_offset(rq);
DTF("Multiwrite: %p, nsect: %d, msect: %d, " \
"rq->current_nr_sectors: %ld\n",
pBuf, nsect, msect, rq->current_nr_sectors);
msect -= nsect;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
- task_unmap_rq(rq, pBuf, &flags);
rq->current_nr_sectors -= nsect;
- /*
- * FIXME :: We really can not legally get a new page/bh
- * regardless, if this is the end of our segment.
- * BH walking or segment can only be updated after we
- * have a good hwif->INB(IDE_STATUS_REG); return.
- */
+
+ /* FIXME: check drive status */
if (!rq->current_nr_sectors) {
if (!DRIVER(drive)->end_request(drive, 1, 0))
if (!rq->bio)
else
rq.nr_sectors = data_size / SECTOR_SIZE;
+ if (!rq.nr_sectors) {
+ printk(KERN_ERR "%s: in/out command without data\n",
+ drive->name);
+ return -EFAULT;
+ }
+
rq.hard_nr_sectors = rq.nr_sectors;
rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
}
char *pBuf = NULL;
int retries = 5;
- if (rq->current_nr_sectors == 0)
- return DRIVER(drive)->error(drive, "flagged_task_in_intr (no data requested)", stat);
-
if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) {
if (stat & ERR_STAT) {
return DRIVER(drive)->error(drive, "flagged_task_in_intr", stat);
int retries = 5;
unsigned int msect, nsect;
- if (rq->current_nr_sectors == 0)
- return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (no data requested)", stat);
-
msect = drive->mult_count;
if (msect == 0)
return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (multimode not set)", stat);
*/
ide_startstop_t flagged_pre_task_out_intr (ide_drive_t *drive, struct request *rq)
{
- ide_hwif_t *hwif = HWIF(drive);
- u8 stat = hwif->INB(IDE_STATUS_REG);
ide_startstop_t startstop;
- if (!rq->current_nr_sectors) {
- return DRIVER(drive)->error(drive, "flagged_pre_task_out_intr (write data not specified)", stat);
- }
-
if (ide_wait_stat(&startstop, drive, DATA_READY,
BAD_W_STAT, WAIT_DRQ)) {
printk(KERN_ERR "%s: No DRQ bit after issuing write command.\n", drive->name);
ide_startstop_t startstop;
unsigned int msect, nsect;
- if (!rq->current_nr_sectors)
- return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (write data not specified)", stat);
-
msect = drive->mult_count;
if (msect == 0)
return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (multimode not set)", stat);
#endif
EXPORT_SYMBOL(noautodma);
-EXPORT_SYMBOL(ide_bus_type);
/*
* This is declared extern in ide.h, for access by other IDE modules:
return -EBUSY;
}
-EXPORT_SYMBOL(ide_hwif_request_regions);
-
/**
* ide_hwif_release_regions - free IDE resources
*
release_region(hwif->io_ports[i], 1);
}
-EXPORT_SYMBOL(ide_hwif_release_regions);
-
/* restore hwif to a sane state */
static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
{
*/
}
-EXPORT_SYMBOL(ide_setup_ports);
-
/*
* Register an IDE interface, specifying exactly the registers etc
* Set init=1 iff calling before probes have taken place.
*/
DECLARE_MUTEX(ide_setting_sem);
-EXPORT_SYMBOL(ide_setting_sem);
/**
* ide_add_setting - add an ide setting option
kfree(setting);
}
-/**
- * ide_remove_setting - remove an ide setting option
- * @drive: drive to use
- * @name: setting name
- *
- * Removes the setting named from the device if it is present.
- * The function takes the settings_lock to protect against
- * parallel changes. This function must not be called from IRQ
- * context.
- */
-
-void ide_remove_setting (ide_drive_t *drive, char *name)
-{
- down(&ide_setting_sem);
- __ide_remove_setting(drive, name);
- up(&ide_setting_sem);
-}
-
-EXPORT_SYMBOL(ide_remove_setting);
-
/**
* ide_find_setting_by_ioctl - find a drive specific ioctl
* @drive: drive to scan
return 0;
}
-EXPORT_SYMBOL(ide_write_setting);
-
static int set_io_32bit(ide_drive_t *drive, int arg)
{
drive->io_32bit = arg;
return 1;
}
-EXPORT_SYMBOL(ide_replace_subdriver);
-
int ata_attach(ide_drive_t *drive)
{
struct list_head *p;
return 1;
}
-EXPORT_SYMBOL(ata_attach);
-
static int generic_ide_suspend(struct device *dev, u32 state)
{
ide_drive_t *drive = dev->driver_data;
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {
"none", "noprobe", "nowerr", "cdrom", "serialize",
- "autotune", "noautotune", "minus8", "swapdata", "bswap",
+ "autotune", "noautotune", "stroke", "swapdata", "bswap",
"minus11", "remap", "remap63", "scsi", NULL };
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
case -7: /* "noautotune" */
drive->autotune = IDE_TUNE_NOAUTO;
goto done;
+ case -8: /* stroke */
+ drive->stroke = 1;
+ goto done;
case -9: /* "swapdata" */
case -10: /* "bswap" */
drive->bswap = 1;
return 1;
}
+extern void pnpide_init(void);
extern void h8300_ide_init(void);
/*
buddha_init();
}
#endif /* CONFIG_BLK_DEV_BUDDHA */
-#if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP)
- {
- extern void pnpide_init(int enable);
- pnpide_init(1);
- }
-#endif /* CONFIG_BLK_DEV_IDEPNP */
+#ifdef CONFIG_BLK_DEV_IDEPNP
+ pnpide_init();
+#endif
#ifdef CONFIG_H8300
h8300_ide_init();
#endif
up(&ide_setting_sem);
return 1;
}
-#if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP) && defined(MODULE)
- pnpide_init(0);
-#endif /* CONFIG_BLK_DEV_IDEPNP */
#ifdef CONFIG_PROC_FS
ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc);
ide_remove_proc_entries(drive->proc, generic_subdriver_entries);
BUG_ON(rq->nr_sectors > 127);
-#ifdef DEBUG
- printk(KERN_DEBUG "%s: %sing: LBAsect=%lu, sectors=%lu\n",
- drive->name, rq_data_dir(rq) ? "writ" : "read",
- block, rq->nr_sectors);
-#endif
-
#ifndef CONFIG_IDE_TASKFILE_IO
if (IDE_CONTROL_REG)
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
return 0;
}
-static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
{
int bus_speed = system_bus_clock();
return dev->irq;
}
-static void __init init_hwif_aec62xx (ide_hwif_t *hwif)
+static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
{
hwif->autodma = 0;
hwif->tuneproc = &aec62xx_tune_drive;
hwif->drives[1].autodma = hwif->autodma;
}
-static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase)
{
struct pci_dev *dev = hwif->pci_dev;
ide_setup_dma(hwif, dmabase, 8);
}
-static void __init init_setup_aec62xx (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
{
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_aec6x80 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
{
unsigned long bar4reg = pci_resource_start(dev, 4);
#include <asm/io.h>
-#include "alim15x3.h"
+#define DISPLAY_ALI_TIMINGS
/*
* ALi devices are not plug in. Otherwise these static values would
ide_setup_dma(hwif, dmabase, 8);
}
+static ide_pci_device_t ali15x3_chipset __devinitdata = {
+ .name = "ALI15X3",
+ .init_chipset = init_chipset_ali15x3,
+ .init_hwif = init_hwif_ali15x3,
+ .init_dma = init_dma_ali15x3,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+};
+
/**
* alim15x3_init_one - set up an ALi15x3 IDE controller
* @dev: PCI device to set up
static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &ali15x3_chipsets[id->driver_data];
-
+ ide_pci_device_t *d = &ali15x3_chipset;
+
if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
return (dma_stat & 7) != 4;
}
-static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name)
{
u32 class_rev = 0;
u8 mrdmode = 0;
return 0;
}
-static unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif)
{
u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01;
return (ata66 & mask) ? 1 : 0;
}
-static void __init init_hwif_cmd64x (ide_hwif_t *hwif)
+static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
unsigned int class_rev;
#include <asm/io.h>
#include <asm/irq.h>
-#include "cs5520.h"
+#define DISPLAY_CS5520_TIMINGS
#if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
}
-
+
+#define DECLARE_CS_DEV(name_str) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_cs5520, \
+ .init_setup_dma = cs5520_init_setup_dma, \
+ .init_hwif = init_hwif_cs5520, \
+ .channels = 2, \
+ .autodma = AUTODMA, \
+ .bootable = ON_BOARD, \
+ .flags = IDEPCI_FLAG_ISA_PORTS, \
+ }
+
+static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
+ /* 0 */ DECLARE_CS_DEV("Cyrix 5510"),
+ /* 1 */ DECLARE_CS_DEV("Cyrix 5520")
+};
+
/*
* The 5510/5520 are a bit weird. They don't quite set up the way
* the PCI helper layer expects so we must do much of the set up
#include <asm/io.h>
#include <asm/irq.h>
-#include "cs5530.h"
+#define DISPLAY_CS5530_TIMINGS
#if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
hwif->drives[1].autodma = hwif->autodma;
}
+static ide_pci_device_t cs5530_chipset __devinitdata = {
+ .name = "CS5530",
+ .init_chipset = init_chipset_cs5530,
+ .init_hwif = init_hwif_cs5530,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ .flags = IDEPCI_FLAG_FORCE_MASTER,
+};
+
static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &cs5530_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &cs5530_chipset);
return 0;
}
*/
#define HPT34X_PCI_INIT_REG 0x80
-static unsigned int __init init_chipset_hpt34x (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const char *name)
{
int i = 0;
unsigned long hpt34xIoBase = pci_resource_start(dev, 4);
return dev->irq;
}
-static void __init init_hwif_hpt34x (ide_hwif_t *hwif)
+static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
{
u16 pcicmd = 0;
return 0;
}
-static int __init init_hpt37x(struct pci_dev *dev)
+static int __devinit init_hpt37x(struct pci_dev *dev)
{
int adjust, i;
u16 freq;
return 0;
}
-static int __init init_hpt366 (struct pci_dev *dev)
+static int __devinit init_hpt366(struct pci_dev *dev)
{
u32 reg1 = 0;
u8 drive_fast = 0;
return 0;
}
-static unsigned int __init init_chipset_hpt366 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)
{
int ret = 0;
u8 test = 0;
return dev->irq;
}
-static void __init init_hwif_hpt366 (ide_hwif_t *hwif)
+static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02;
hwif->drives[1].autodma = hwif->autodma;
}
-static void __init init_dma_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
{
u8 masterdma = 0, slavedma = 0;
u8 dma_new = 0, dma_old = 0;
ide_setup_dma(hwif, dmabase, 8);
}
-static void __init init_setup_hpt374 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
{
struct pci_dev *findev = NULL;
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_hpt37x (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
{
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_hpt366 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
{
struct pci_dev *findev = NULL;
u8 pin1 = 0, pin2 = 0;
#include <asm/io.h>
-#include "ns87415.h"
-
static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
/*
hwif->drives[1].autodma = hwif->autodma;
}
+static ide_pci_device_t ns87415_chipset __devinitdata = {
+ .name = "NS87415",
+ .init_hwif = init_hwif_ns87415,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+};
+
static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &ns87415_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &ns87415_chipset);
return 0;
}
}
#endif /* CONFIG_PPC_PMAC */
-static unsigned int __init init_chipset_pdcnew (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name)
{
if (dev->resource[PCI_ROM_RESOURCE].start) {
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
return dev->irq;
}
-static void __init init_hwif_pdc202new (ide_hwif_t *hwif)
+static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
{
hwif->autodma = 0;
#endif /* PDC202_DEBUG_CABLE */
}
-static void __init init_setup_pdcnew (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
{
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_pdc20270 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
{
struct pci_dev *findev = NULL;
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_pdc20276 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
{
if ((dev->bus->self) &&
(dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
return 0;
}
-static unsigned int __init init_chipset_pdc202xx (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name)
{
if (dev->resource[PCI_ROM_RESOURCE].start) {
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
return dev->irq;
}
-static void __init init_hwif_pdc202xx (ide_hwif_t *hwif)
+static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
{
hwif->autodma = 0;
hwif->tuneproc = &config_chipset_for_pio;
#endif /* PDC202_DEBUG_CABLE */
}
-static void __init init_dma_pdc202xx (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
{
u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
ide_setup_dma(hwif, dmabase, 8);
}
-static void __init init_setup_pdc202ata4 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d)
{
if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
u8 irq = 0, irq2 = 0;
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_pdc20265 (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc20265(struct pci_dev *dev, ide_pci_device_t *d)
{
if ((dev->bus->self) &&
(dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
ide_setup_pci_device(dev, d);
}
-static void __init init_setup_pdc202xx (struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit init_setup_pdc202xx(struct pci_dev *dev, ide_pci_device_t *d)
{
ide_setup_pci_device(dev, d);
}
* pci_read_config_word(HWIF(drive)->pci_dev, 0x40, ®40);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x42, ®42);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x44, ®44);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x48, ®48);
+ * pci_read_config_byte(HWIF(drive)->pci_dev, 0x48, ®48);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, ®4a);
- * pci_read_config_word(HWIF(drive)->pci_dev, 0x54, ®54);
+ * pci_read_config_byte(HWIF(drive)->pci_dev, 0x54, ®54);
*
* Documentation
* Publically available from Intel web site. Errata documentation
int w_flag = 0x10 << drive->dn;
int u_speed = 0;
int sitre;
- u16 reg4042, reg44, reg48, reg4a, reg54;
- u8 reg55;
+ u16 reg4042, reg4a;
+ u8 reg48, reg54, reg55;
pci_read_config_word(dev, maslave, ®4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
- pci_read_config_word(dev, 0x44, ®44);
- pci_read_config_word(dev, 0x48, ®48);
+ pci_read_config_byte(dev, 0x48, ®48);
pci_read_config_word(dev, 0x4a, ®4a);
- pci_read_config_word(dev, 0x54, ®54);
+ pci_read_config_byte(dev, 0x54, ®54);
pci_read_config_byte(dev, 0x55, ®55);
switch(speed) {
if (speed >= XFER_UDMA_0) {
if (!(reg48 & u_flag))
- pci_write_config_word(dev, 0x48, reg48|u_flag);
+ pci_write_config_byte(dev, 0x48, reg48 | u_flag);
if (speed == XFER_UDMA_5) {
pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
} else {
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
- if (!(reg4a & u_speed)) {
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- pci_write_config_word(dev, 0x4a, reg4a|u_speed);
- }
+ if ((reg4a & a_speed) != u_speed)
+ pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
if (speed > XFER_UDMA_2) {
- if (!(reg54 & v_flag)) {
- pci_write_config_word(dev, 0x54, reg54|v_flag);
- }
- } else {
- pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
- }
+ if (!(reg54 & v_flag))
+ pci_write_config_byte(dev, 0x54, reg54 | v_flag);
+ } else
+ pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
if (reg48 & u_flag)
- pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
+ pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
if (reg54 & v_flag)
- pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
+ pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
if (reg55 & w_flag)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
* Set up the ide_hwif_t for the PIIX interface according to the
* capabilities of the hardware.
*/
-
-static void __init init_hwif_piix (ide_hwif_t *hwif)
+
+static void __devinit init_hwif_piix(ide_hwif_t *hwif)
{
u8 reg54h = 0, reg55h = 0, ata66 = 0;
u8 mask = hwif->channel ? 0xc0 : 0x30;
* Enable the xp fixup for the PIIX controller and then perform
* a standard ide PCI setup
*/
-
-static void __init init_setup_piix (struct pci_dev *dev, ide_pci_device_t *d)
+
+static void __devinit init_setup_piix(struct pci_dev *dev, ide_pci_device_t *d)
{
ide_setup_pci_device(dev, d);
}
* Check for the present of 450NX errata #19 and errata #25. If
* they are found, disable use of DMA IDE
*/
-
-static void __init piix_check_450nx(void)
+
+static void __devinit piix_check_450nx(void)
{
struct pci_dev *pdev = NULL;
u16 cfg;
#include <asm/io.h>
-#include "rz1000.h"
-
static void __init init_hwif_rz1000 (ide_hwif_t *hwif)
{
u16 reg;
}
}
+static ide_pci_device_t rz1000_chipset __devinitdata = {
+ .name = "RZ100x",
+ .init_hwif = init_hwif_rz1000,
+ .channels = 2,
+ .autodma = NODMA,
+ .bootable = ON_BOARD,
+};
+
static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &rz1000_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &rz1000_chipset);
return 0;
}
static struct pci_device_id rz1000_pci_tbl[] = {
{ PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl);
#include <asm/io.h>
#include <asm/irq.h>
-#include "sc1200.h"
-
#define SC1200_REV_A 0x00
#define SC1200_REV_B1 0x01
#define SC1200_REV_B3 0x02
hwif->drives[1].autodma = hwif->autodma;
}
+static ide_pci_device_t sc1200_chipset __devinitdata = {
+ .name = "SC1200",
+ .init_chipset = init_chipset_sc1200,
+ .init_hwif = init_hwif_sc1200,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+};
+
static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &sc1200_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &sc1200_chipset);
return 0;
}
#include <asm/io.h>
-#include "siimage.h"
+#undef SIIMAGE_VIRTUAL_DMAPIO
+#undef SIIMAGE_LARGE_DMA
/**
* pdev_is_sata - check if device is SATA
* to 133MHz clocking if the system isn't already set up to do it.
*/
-static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
{
u32 class_rev = 0;
u8 tmpbyte = 0;
* The hardware supports buffered taskfiles and also some rather nice
* extended PRD tables. Unfortunately right now we don't.
*/
-
-static void __init init_mmio_iops_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
void *addr = pci_get_drvdata(dev);
* look in we get for setting up the hwif so that we
* can get the iops right before using them.
*/
-
-static void __init init_iops_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_iops_siimage(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
u32 class_rev = 0;
* Check for the presence of an ATA66 capable cable on the
* interface.
*/
-
-static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
+
+static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif)
{
unsigned long addr = siimage_selreg(hwif, 0);
if (pci_get_drvdata(hwif->pci_dev) == NULL) {
* requires several custom handlers so we override the default
* ide DMA handlers appropriately
*/
-
-static void __init init_hwif_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
{
hwif->autodma = 0;
hwif->drives[1].autodma = hwif->autodma;
}
+#define DECLARE_SII_DEV(name_str) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_siimage, \
+ .init_iops = init_iops_siimage, \
+ .init_hwif = init_hwif_siimage, \
+ .channels = 2, \
+ .autodma = AUTODMA, \
+ .bootable = ON_BOARD, \
+ }
+
+static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+ /* 0 */ DECLARE_SII_DEV("SiI680"),
+ /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
+ /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
+};
+
/**
* siimage_init_one - pci layer discovery entry
* @dev: PCI device
#include <asm/irq.h>
#include "ide-timing.h"
-#include "sis5513.h"
+
+#define DISPLAY_SIS_TIMINGS
/* registers layout and init values are chipset family dependant */
return;
}
+static ide_pci_device_t sis5513_chipset __devinitdata = {
+ .name = "SIS5513",
+ .init_chipset = init_chipset_sis5513,
+ .init_hwif = init_hwif_sis5513,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+ .bootable = ON_BOARD,
+};
+
static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &sis5513_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &sis5513_chipset);
return 0;
}
#include <asm/io.h>
#include <asm/dma.h>
-#include "sl82c105.h"
-
#undef DEBUG
#ifdef DEBUG
#endif /* CONFIG_BLK_DEV_IDEDMA */
}
+static ide_pci_device_t sl82c105_chipset __devinitdata = {
+ .name = "W82C105",
+ .init_chipset = init_chipset_sl82c105,
+ .init_hwif = init_hwif_sl82c105,
+ .init_dma = init_dma_sl82c105,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
+ .bootable = ON_BOARD,
+};
+
static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &sl82c105_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &sl82c105_chipset);
return 0;
}
#include <asm/io.h>
-#include "slc90e66.h"
+#define DISPLAY_SLC90E66_TIMINGS
#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#endif /* !CONFIG_BLK_DEV_IDEDMA */
}
+static ide_pci_device_t slc90e66_chipset __devinitdata = {
+ .name = "SLC90E66",
+ .init_chipset = init_chipset_slc90e66,
+ .init_hwif = init_hwif_slc90e66,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
+ .bootable = ON_BOARD,
+};
+
static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &slc90e66_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &slc90e66_chipset);
return 0;
}
#include <linux/ide.h>
#include <linux/init.h>
-#include "triflex.h"
-
static struct pci_dev *triflex_dev;
#ifdef CONFIG_PROC_FS
return 0;
}
+static ide_pci_device_t triflex_device __devinitdata = {
+ .name = "TRIFLEX",
+ .init_chipset = init_chipset_triflex,
+ .init_hwif = init_hwif_triflex,
+ .channels = 2,
+ .autodma = AUTODMA,
+ .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
+ .bootable = ON_BOARD,
+};
+
static int __devinit triflex_init_one(struct pci_dev *dev,
const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &triflex_devices[id->driver_data]);
+ ide_setup_pci_device(dev, &triflex_device);
triflex_dev = dev;
return 0;
}
+static struct pci_device_id triflex_pci_tbl[] = {
+ { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, triflex_pci_tbl);
+
static struct pci_driver driver = {
.name = "TRIFLEX IDE",
.id_table = triflex_pci_tbl,
#include <asm/io.h>
-#include "trm290.h"
-
static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
{
ide_hwif_t *hwif = HWIF(drive);
/*
* Invoked from ide-dma.c at boot time.
*/
-void __init init_hwif_trm290 (ide_hwif_t *hwif)
+void __devinit init_hwif_trm290(ide_hwif_t *hwif)
{
unsigned int cfgbase = 0;
unsigned long flags;
#endif
}
+static ide_pci_device_t trm290_chipset __devinitdata = {
+ .name = "TRM290",
+ .init_hwif = init_hwif_trm290,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .bootable = ON_BOARD,
+};
+
static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &trm290_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &trm290_chipset);
return 0;
}
#include <asm/io.h>
#include "ide-timing.h"
-#include "via82cxxx.h"
+
+#define DISPLAY_VIA_TIMINGS
#define VIA_IDE_ENABLE 0x40
#define VIA_IDE_CONFIG 0x41
hwif->drives[1].autodma = hwif->autodma;
}
+static ide_pci_device_t via82cxxx_chipset __devinitdata = {
+ .name = "VP_IDE",
+ .init_chipset = init_chipset_via82cxxx,
+ .init_hwif = init_hwif_via82cxxx,
+ .channels = 2,
+ .autodma = NOAUTODMA,
+ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+ .bootable = ON_BOARD,
+};
+
static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &via82cxxx_chipset);
return 0;
}
}
nkv = kv->next;
+ if (kv->prev)
+ kv->prev->next = NULL;
+ if (kv->next)
+ kv->next->prev = NULL;
kv->prev = NULL;
kv->next = NULL;
}
/* Make sure the Extended ROM leaf is a multiple of
* max_rom in size. */
leaf_size = (cache->len + (csr->max_rom - 1)) &
- (csr->max_rom - 1);
+ ~(csr->max_rom - 1);
/* Zero out the unused ROM region */
memset(cache->data + bytes_to_quads(cache->len), 0x00,
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <asm/pgalloc.h>
-#define CSR1212_MALLOC(size) kmalloc((size), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
-#define CSR1212_FREE(ptr) kfree(ptr)
+#define CSR1212_MALLOC(size) vmalloc((size))
+#define CSR1212_FREE(ptr) vfree(ptr)
#define CSR1212_BE16_TO_CPU(quad) be16_to_cpu(quad)
#define CSR1212_CPU_TO_BE16(quad) cpu_to_be16(quad)
#define CSR1212_BE32_TO_CPU(quad) be32_to_cpu(quad)
#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
static char version[] __devinitdata =
- "$Rev: 1198 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1224 $ Ben Collins <bcollins@debian.org>";
struct fragment_info {
struct list_head list;
static void ether1394_iso(struct hpsb_iso *iso);
static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr);
+static int ether1394_ethtool_ioctl(struct net_device *dev, void __user *useraddr);
static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
quadlet_t *data, u64 addr, size_t len, u16 flags);
if (!node)
return -ENOMEM;
-
node_info = kmalloc(sizeof(struct eth1394_node_info),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+ if (!node_info) {
+ kfree(node);
+ return -ENOMEM;
+ }
spin_lock_init(&node_info->pdg.lock);
INIT_LIST_HEAD(&node_info->pdg.list);
{
switch(cmd) {
case SIOCETHTOOL:
- return ether1394_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+ return ether1394_ethtool_ioctl(dev, ifr->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCGMIIREG: /* Read MII PHY register. */
return 0;
}
-static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int ether1394_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
u32 ethcmd;
- if (get_user(ethcmd, (u32 *)useraddr))
+ if (get_user(ethcmd, (u32 __user *)useraddr))
return -EFAULT;
switch (ethcmd) {
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, driver_name);
- strcpy (info.version, "$Rev: 1198 $");
+ strcpy (info.version, "$Rev: 1224 $");
/* FIXME XXX provide sane businfo */
strcpy (info.bus_info, "ieee1394");
if (copy_to_user (useraddr, &info, sizeof (info)))
a2sa = a2->start & align_mask;
a2ea = (a2->end + alignment -1) & align_mask;
- if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (end - a1ea >= size)) {
+ if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (a2sa > start)) {
as->start = max(start, a1ea);
as->end = as->start + size;
list_add(&as->host_list, entry);
#include "config_roms.h"
-static void delayed_reset_bus(unsigned long __reset_info)
+static void delayed_reset_bus(void * __reset_info)
{
struct hpsb_host *host = (struct hpsb_host*)__reset_info;
int generation = host->csr.generation + 1;
skb_queue_head_init(&h->pending_packet_queue);
INIT_LIST_HEAD(&h->addr_space);
- init_timer(&h->delayed_reset);
- h->delayed_reset.function = delayed_reset_bus;
- h->delayed_reset.data = (unsigned long)h;
for (i = 2; i < 16; i++)
h->csr.gen_timestamp[i] = jiffies - 60 * HZ;
atomic_set(&h->generation, 0);
+ INIT_WORK(&h->delayed_reset, delayed_reset_bus, h);
+
init_timer(&h->timeout);
h->timeout.data = (unsigned long) h;
h->timeout.function = abort_timedouts;
{
host->is_shutdown = 1;
- del_timer_sync(&host->delayed_reset);
+ cancel_delayed_work(&host->delayed_reset);
+ flush_scheduled_work();
host->driver = &dummy_driver;
int hpsb_update_config_rom_image(struct hpsb_host *host)
{
- unsigned long reset_time;
+ unsigned long reset_delay;
int next_gen = host->csr.generation + 1;
if (!host->update_config_rom)
/* Stop the delayed interrupt, we're about to change the config rom and
* it would be a waste to do a bus reset twice. */
- del_timer_sync(&host->delayed_reset);
+ cancel_delayed_work(&host->delayed_reset);
/* IEEE 1394a-2000 prohibits using the same generation number
* twice in a 60 second period. */
if (jiffies - host->csr.gen_timestamp[next_gen] < 60 * HZ)
/* Wait 60 seconds from the last time this generation number was
* used. */
- reset_time = (60 * HZ) + host->csr.gen_timestamp[next_gen];
+ reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies;
else
/* Wait 1 second in case some other code wants to change the
* Config ROM in the near future. */
- reset_time = jiffies + HZ;
+ reset_delay = HZ;
- /* This will add the timer as well as modify it */
- mod_timer(&host->delayed_reset, reset_time);
+ PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host);
+ schedule_delayed_work(&host->delayed_reset, reset_delay);
return 0;
}
struct class_device class_dev;
int update_config_rom;
- struct timer_list delayed_reset;
+ struct work_struct delayed_reset;
unsigned int config_roms;
#include <linux/bitops.h>
#include <linux/kdev_t.h>
#include <linux/skbuff.h>
+#include <linux/suspend.h>
#include <asm/byteorder.h>
#include <asm/semaphore.h>
if (khpsbpkt_kill)
break;
+ if (current->flags & PF_FREEZE) {
+ refrigerator(0);
+ continue;
+ }
+
while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) {
packet = (struct hpsb_packet *)skb->data;
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/moduleparam.h>
+#include <linux/suspend.h>
#include <asm/atomic.h>
#include "ieee1394_types.h"
/* Sit and wait for a signal to probe the nodes on the bus. This
* happens when we get a bus reset. */
- while (!down_interruptible(&hi->reset_sem) &&
- !down_interruptible(&nodemgr_serialize)) {
+ while (1) {
unsigned int generation = 0;
int i;
+ if (down_interruptible(&hi->reset_sem) ||
+ down_interruptible(&nodemgr_serialize)) {
+ if (current->flags & PF_FREEZE) {
+ refrigerator(0);
+ continue;
+ }
+ printk("NodeMgr: received unexpected signal?!\n" );
+ break;
+ }
+
if (hi->kill_me)
break;
printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
static char version[] __devinitdata =
- "$Rev: 1203 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1223 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
ohci->max_packet_size =
1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1);
+ if (ohci->max_packet_size < 512) {
+ HPSB_ERR("warning: Invalid max packet size of %d, setting to 512",
+ ohci->max_packet_size);
+ ohci->max_packet_size = 512;
+ }
+
/* Don't accept phy packets into AR request context */
reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400);
#include <asm/scatterlist.h>
#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
+#include <scsi/scsi_host.h>
#include "csr1212.h"
#include "ieee1394.h"
#include "sbp2.h"
static char version[] __devinitdata =
- "$Rev: 1205 $ Ben Collins <bcollins@debian.org>";
+ "$Rev: 1219 $ Ben Collins <bcollins@debian.org>";
/*
* Module load parameter definitions
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
+ if (d == NULL) return -EFAULT;
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id,
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
+ if (d == NULL) return -EFAULT;
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id,
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
+ if (d == NULL) return -EFAULT;
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id,
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
+ if (d == NULL) return -EFAULT;
if ((v.buffer<0) || (v.buffer>d->num_desc)) {
PRINT(KERN_ERR, ohci->host->id,
bool "Provide legacy /dev/psaux device"
default y
depends on INPUT_MOUSEDEV
+ ---help---
+ Say Y here if you want your mouse also be accessible as char device
+ 10:1 - /dev/psaux. The data available through /dev/psaux is exactly
+ the same as the data from /dev/input/mice.
+
+ If unsure, say Y.
+
config INPUT_MOUSEDEV_SCREEN_X
int "Horizontal screen resolution"
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
#include <linux/device.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Input driver event debug module");
+MODULE_DESCRIPTION("Input driver event debug module");
MODULE_LICENSE("GPL");
static char evbug_name[] = "evbug";
static void evbug_disconnect(struct input_handle *handle)
{
printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
-
+
input_close_device(handle);
kfree(handle);
};
MODULE_DEVICE_TABLE(input, evbug_ids);
-
+
static struct input_handler evbug_handler = {
.event = evbug_event,
.connect = evbug_connect,
int i = iminor(inode) - EVDEV_MINOR_BASE;
int accept_err;
- if (i >= EVDEV_MINORS || !evdev_table[i])
+ if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist)
return -ENODEV;
if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
return -EAGAIN;
retval = wait_event_interruptible(list->evdev->wait,
- list->head != list->tail && list->evdev->exist);
+ list->head != list->tail || (!list->evdev->exist));
if (retval)
return retval;
case EVIOCGID:
return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0;
-
+
case EVIOCGKEYCODE:
if (get_user(t, ip)) return -EFAULT;
if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
- class_simple_device_add(input_class,
+ class_simple_device_add(input_class,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
dev->dev, "event%d", minor);
/*
- The all defines and part of code (such as cs461x_*) are
- contributed from ALSA 0.5.8 sources.
+ The all defines and part of code (such as cs461x_*) are
+ contributed from ALSA 0.5.8 sources.
See http://www.alsa-project.org/ for sources
-
+
Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610
*/
#define JSIO_BXOE 0x00000040
#define JSIO_BYOE 0x00000080
-/*
- The card initialization code is obfuscated; the module cs461x
+/*
+ The card initialization code is obfuscated; the module cs461x
need to be loaded after ALSA modules initialized and something
played on the CS 4610 chip (see sources for details of CS4610
initialization code from ALSA)
#define BA1_DWORD_SIZE (13 * 1024 + 512)
#define BA1_MEMORY_COUNT 3
-/*
+/*
Only one CS461x card is still suppoted; the code requires
redesign to avoid this limitatuion.
*/
if(port){
gameport_unregister_port(port);
kfree(port);
- }
+ }
if (ba0) iounmap(ba0);
#ifdef CS461X_FULL_MAP
if (ba1.name.data0) iounmap(ba1.name.data0);
static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
{
unsigned js1, js2, jst;
-
+
js1 = cs461x_peekBA0(BA0_JSC1);
js2 = cs461x_peekBA0(BA0_JSC2);
jst = cs461x_peekBA0(BA0_JSPT);
-
- *buttons = (~jst >> 4) & 0x0F;
-
+
+ *buttons = (~jst >> 4) & 0x0F;
+
axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
{
int rc;
struct gameport* port;
-
+
rc = pci_enable_device(pdev);
if (rc) {
printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",
#ifdef CS461X_FULL_MAP
ba1_addr = pci_resource_start(pdev, 1);
#endif
- if (ba0_addr == 0 || ba0_addr == ~0
+ if (ba0_addr == 0 || ba0_addr == ~0
#ifdef CS461X_FULL_MAP
|| ba1_addr == 0 || ba1_addr == ~0
#endif
memset(port, 0, sizeof(struct gameport));
pci_set_drvdata(pdev, port);
-
+
port->open = cs461x_gameport_open;
port->trigger = cs461x_gameport_trigger;
port->read = cs461x_gameport_read;
{
cs461x_free(pdev);
}
-
+
static struct pci_driver cs461x_pci_driver = {
.name = "CS461x Gameport",
.id_table = cs461x_pci_tbl,
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
int size;
char phys[32];
};
-
+
static struct pci_device_id emu_tbl[] = {
{ 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */
{ 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */
{
int ioport, iolen;
struct emu *emu;
-
+
if (pci_enable_device(pdev))
return -EBUSY;
pci_set_drvdata(pci, gp);
- outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */
+ outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */
gameport_register_port(&gp->gameport);
return -1;
gameport->dev = dev;
-
+
return 0;
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
result = 0;
-fail: outb(L4_SELECT_ANALOG, L4_PORT);
+fail: outb(L4_SELECT_ANALOG, L4_PORT);
return result;
}
static int l4_getcal(int port, int *cal)
{
int i, result = -1;
-
+
outb(L4_SELECT_ANALOG, L4_PORT);
outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT);
return 0;
}
-
+
static int __init l4_init(void)
{
int cal[4] = {255,255,255,255};
if (rev > 0x28) /* on 2.9+ the setcal command works correctly */
l4_setcal(l4->port, cal);
-
+
gameport_register_port(gameport);
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
char phys[32];
char name[32];
};
-
+
static LIST_HEAD(ns558_list);
/*
i = 0;
goto out;
}
-/*
+/*
* And now find the number of mirrors of the port.
*/
release_region(port->gameport.io & ~(port->size - 1), port->size);
kfree(port);
break;
-
+
default:
break;
}
axes[i] = readw(vortex->io + VORTEX_AXD + i * sizeof(u32));
if (axes[i] == 0x1fff) axes[i] = -1;
}
-
+
return 0;
}
vortex->gameport.driver = vortex;
vortex->gameport.fuzz = 64;
-
+
vortex->gameport.read = vortex_read;
vortex->gameport.trigger = vortex_trigger;
vortex->gameport.cooked_read = vortex_cooked_read;
vortex->io = vortex->base + id->driver_data;
gameport_register_port(&vortex->gameport);
-
+
printk(KERN_INFO "gameport at pci%s speed %d kHz\n",
pci_name(dev), vortex->gameport.speed);
}
break;
-
+
case EV_ABS:
if (code > ABS_MAX || !test_bit(code, dev->absbit))
if (code > MSC_MAX || !test_bit(code, dev->mscbit))
return;
- if (dev->event) dev->event(dev, type, code, value);
-
+ if (dev->event) dev->event(dev, type, code, value);
+
break;
case EV_LED:
-
+
if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
return;
change_bit(code, dev->led);
- if (dev->event) dev->event(dev, type, code, value);
-
+ if (dev->event) dev->event(dev, type, code, value);
+
break;
case EV_SND:
-
+
if (code > SND_MAX || !test_bit(code, dev->sndbit))
return;
- if (dev->event) dev->event(dev, type, code, value);
-
+ if (dev->event) dev->event(dev, type, code, value);
+
break;
case EV_REP:
break;
}
- if (type != EV_SYN)
+ if (type != EV_SYN)
dev->sync = 0;
if (dev->grab)
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
if (id->id.vendor != dev->id.vendor)
continue;
-
+
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
if (id->id.product != dev->id.product)
continue;
-
+
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
if (id->id.version != dev->id.version)
continue;
}
if (in_interrupt()) {
printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
- return;
+ return;
}
if (!current->fs->root) {
printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
- return;
+ return;
}
if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
envp[i++] = scratch;
scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
- dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
-
+ dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
+
if (dev->name) {
envp[i++] = scratch;
- scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
+ scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
}
if (dev->phys) {
envp[i++] = scratch;
- scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
- }
+ scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
+ }
SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
input_table[handler->minor >> 5] = handler;
list_add_tail(&handler->node, &input_handler_list);
-
+
list_for_each_entry(dev, &input_dev_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev)))
/*
* Joystick device driver for the input driver suite.
*
- * Copyright (c) 1999-2002 Vojtech Pavlik
- * Copyright (c) 1999 Colin Van Dyke
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 1999 Colin Van Dyke
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
MODULE_LICENSE("GPL");
#define JOYDEV_MINOR_BASE 0
-#define JOYDEV_MINORS 16
+#define JOYDEV_MINORS 16
#define JOYDEV_BUFFER_SIZE 64
#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
default:
return;
- }
+ }
event.time = MSECS(jiffies);
return 0;
}
-static ssize_t joydev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos)
+static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
{
return -EINVAL;
}
-static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct joydev_list *list = file->private_data;
struct joydev *joydev = list->joydev;
struct joydev_list *list = file->private_data;
struct joydev *joydev = list->joydev;
struct input_dev *dev = joydev->handle.dev;
+ void __user *argp = (void __user *)arg;
int i, j;
if (!joydev->exist) return -ENODEV;
switch (cmd) {
case JS_SET_CAL:
- return copy_from_user(&joydev->glue.JS_CORR, (struct JS_DATA_TYPE *) arg,
+ return copy_from_user(&joydev->glue.JS_CORR, argp,
sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
case JS_GET_CAL:
- return copy_to_user((struct JS_DATA_TYPE *) arg, &joydev->glue.JS_CORR,
+ return copy_to_user(argp, &joydev->glue.JS_CORR,
sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
case JS_SET_TIMEOUT:
- return get_user(joydev->glue.JS_TIMEOUT, (int *) arg);
+ return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
case JS_GET_TIMEOUT:
- return put_user(joydev->glue.JS_TIMEOUT, (int *) arg);
+ return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
case JS_SET_TIMELIMIT:
- return get_user(joydev->glue.JS_TIMELIMIT, (long *) arg);
+ return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
case JS_GET_TIMELIMIT:
- return put_user(joydev->glue.JS_TIMELIMIT, (long *) arg);
+ return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
case JS_SET_ALL:
- return copy_from_user(&joydev->glue, (struct JS_DATA_SAVE_TYPE *) arg,
+ return copy_from_user(&joydev->glue, argp,
sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
case JS_GET_ALL:
- return copy_to_user((struct JS_DATA_SAVE_TYPE *) arg, &joydev->glue,
+ return copy_to_user(argp, &joydev->glue,
sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
case JSIOCGVERSION:
- return put_user(JS_VERSION, (__u32 *) arg);
+ return put_user(JS_VERSION, (__u32 __user *) arg);
case JSIOCGAXES:
- return put_user(joydev->nabs, (__u8 *) arg);
+ return put_user(joydev->nabs, (__u8 __user *) arg);
case JSIOCGBUTTONS:
- return put_user(joydev->nkey, (__u8 *) arg);
+ return put_user(joydev->nkey, (__u8 __user *) arg);
case JSIOCSCORR:
- if (copy_from_user(joydev->corr, (struct js_corr *)arg,
+ if (copy_from_user(joydev->corr, argp,
sizeof(struct js_corr) * joydev->nabs))
return -EFAULT;
for (i = 0; i < joydev->nabs; i++) {
}
return 0;
case JSIOCGCORR:
- return copy_to_user((struct js_corr *) arg, joydev->corr,
+ return copy_to_user(argp, joydev->corr,
sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
case JSIOCSAXMAP:
- if (copy_from_user(joydev->abspam, (__u8 *) arg, sizeof(__u8) * ABS_MAX))
+ if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * ABS_MAX))
return -EFAULT;
for (i = 0; i < joydev->nabs; i++) {
if (joydev->abspam[i] > ABS_MAX) return -EINVAL;
}
return 0;
case JSIOCGAXMAP:
- return copy_to_user((__u8 *) arg, joydev->abspam,
+ return copy_to_user(argp, joydev->abspam,
sizeof(__u8) * ABS_MAX) ? -EFAULT : 0;
case JSIOCSBTNMAP:
- if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
+ if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
return -EFAULT;
for (i = 0; i < joydev->nkey; i++) {
if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
}
return 0;
case JSIOCGBTNMAP:
- return copy_to_user((__u16 *) arg, joydev->keypam,
+ return copy_to_user(argp, joydev->keypam,
sizeof(__u16) * (KEY_MAX - BTN_MISC)) ? -EFAULT : 0;
default:
if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
if (!dev->name) return 0;
len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
- if (copy_to_user((char *) arg, dev->name, len)) return -EFAULT;
+ if (copy_to_user(argp, dev->name, len)) return -EFAULT;
return len;
}
}
}
joydev_table[minor] = joydev;
-
+
devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
- class_simple_device_add(input_class,
+ class_simple_device_add(input_class,
MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
dev->dev, "js%d", minor);
joydev->exist = 0;
if (joydev->open)
- input_close_device(handle);
+ input_close_device(handle);
else
joydev_free(joydev);
}
supports many extensions, including joysticks with throttle control,
with rudders, additional hats and buttons compatible with CH
Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or
- Saitek Cyborg joysticks.
+ Saitek Cyborg joysticks.
Please read the file <file:Documentation/input/joystick.txt> which
contains more information.
depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help
Say Y here if you have an FPGaming or MadCatz controller using the
- A3D protocol over the PC gameport.
+ A3D protocol over the PC gameport.
To compile this driver as a module, choose M here: the
module will be called a3d.
depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help
Say Y here if you have a Logitech controller using the ADI
- protocol over the PC gameport.
+ protocol over the PC gameport.
To compile this driver as a module, choose M here: the
module will be called adi.
depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help
Say Y here if you have a Gravis controller using the GrIP protocol
- over the PC gameport.
+ over the PC gameport.
To compile this driver as a module, choose M here: the
module will be called grip.
depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help
Say Y here if you have a Guillemot joystick using a digital
- protocol over the PC gameport.
+ protocol over the PC gameport.
To compile this driver as a module, choose M here: the
module will be called guillemot.
depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help
Say Y here if you have a ThrustMaster controller using the
- DirectConnect (BSP) protocol over the PC gameport.
+ DirectConnect (BSP) protocol over the PC gameport.
To compile this driver as a module, choose M here: the
module will be called tmdc.
select SERIO
help
Say Y here if you have a Logitech WingMan Warrior joystick connected
- to your computer's serial port.
+ to your computer's serial port.
To compile this driver as a module, choose M here: the
module will be called warrior.
help
Say Y here if you want to dump data from your joystick into the system
log for debugging purposes. Say N if you are making a production
- configuration or aren't sure.
+ configuration or aren't sure.
To compile this driver as a module, choose M here: the
module will be called joydump.
MODULE_DESCRIPTION("FP-Gaming Assasin 3D joystick driver");
MODULE_LICENSE("GPL");
-#define A3D_MAX_START 400 /* 400 us */
-#define A3D_MAX_STROBE 60 /* 40 us */
+#define A3D_MAX_START 400 /* 400 us */
+#define A3D_MAX_STROBE 60 /* 40 us */
#define A3D_DELAY_READ 3 /* 3 ms */
#define A3D_MAX_LENGTH 40 /* 40*3 bits */
#define A3D_REFRESH_TIME HZ/50 /* 20 ms */
input_report_rel(dev, REL_X, ((data[5] << 6) | (data[6] << 3) | data[ 7]) - ((data[5] & 4) << 7));
input_report_rel(dev, REL_Y, ((data[8] << 6) | (data[9] << 3) | data[10]) - ((data[8] & 4) << 7));
-
+
input_report_key(dev, BTN_RIGHT, data[2] & 1);
input_report_key(dev, BTN_LEFT, data[3] & 2);
input_report_key(dev, BTN_MIDDLE, data[3] & 4);
int i;
for (i = 0; i < 4; i++)
axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1;
- *buttons = a3d->buttons;
+ *buttons = a3d->buttons;
return 0;
}
if (mode != GAMEPORT_MODE_COOKED)
return -1;
if (!a3d->used++)
- mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
+ mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
return 0;
}
{
struct a3d *a3d = dev->private;
if (!a3d->used++)
- mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
+ mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
return 0;
}
a3d->adc.open = a3d_adc_open;
a3d->adc.close = a3d_adc_close;
a3d->adc.cooked_read = a3d_adc_cooked_read;
- a3d->adc.fuzz = 1;
+ a3d->adc.fuzz = 1;
a3d->adc.name = a3d_names[a3d->mode];
a3d->adc.phys = a3d->adcphys;
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
static char *adi_names[] = { "WingMan Extreme Digital", "ThunderPad Digital", "SideCar", "CyberMan 2",
- "WingMan Interceptor", "WingMan Formula", "WingMan GamePad",
- "WingMan Extreme Digital 3D", "WingMan GamePad Extreme",
+ "WingMan Interceptor", "WingMan Formula", "WingMan GamePad",
+ "WingMan Extreme Digital 3D", "WingMan GamePad Extreme",
"WingMan GamePad USB", "Unknown Device %#x" };
static char adi_wmgpe_abs[] = { ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y };
/*
* adi_move_bits() detects a possible 2-stream mode, and moves
- * the bits accordingly.
+ * the bits accordingly.
*/
static void adi_move_bits(struct adi_port *port, int length)
int i;
if ((adi->idx += count) > adi->ret) return 0;
for (i = 0; i < count; i++)
- bits |= ((adi->data[adi->idx - i] >> 5) & 1) << i;
+ bits |= ((adi->data[adi->idx - i] >> 5) & 1) << i;
return bits;
}
int i, t;
if (adi->ret < adi->length || adi->id != (adi_get_bits(adi, 4) | (adi_get_bits(adi, 4) << 4)))
- return -1;
+ return -1;
- for (i = 0; i < adi->axes10; i++)
+ for (i = 0; i < adi->axes10; i++)
input_report_abs(dev, *abs++, adi_get_bits(adi, 10));
- for (i = 0; i < adi->axes8; i++)
+ for (i = 0; i < adi->axes8; i++)
input_report_abs(dev, *abs++, adi_get_bits(adi, 8));
for (i = 0; i < adi->buttons && i < 63; i++) {
for (i = 63; i < adi->buttons; i++)
input_report_key(dev, *key++, adi_get_bits(adi, 1));
-
+
input_sync(dev);
return 0;
{
struct adi_port *port = dev->private;
if (!port->used++)
- mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
+ mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
return 0;
}
return;
if (adi->ret < (t = adi_get_bits(adi, 10))) {
- printk(KERN_WARNING "adi: Short ID packet: reported: %d != read: %d\n", t, adi->ret);
+ printk(KERN_WARNING "adi: Short ID packet: reported: %d != read: %d\n", t, adi->ret);
return;
}
adi_init_digital(gameport);
adi_read_packet(port);
-
+
if (port->adi[0].ret >= ADI_MIN_LEN_LENGTH)
adi_move_bits(port, adi_get_bits(port->adi, 10));
MODULE_LICENSE("GPL");
static int amijoy[2] = { 0, 1 };
-static int amijoy_nargs;
+static int amijoy_nargs;
module_param_array_named(map, amijoy, uint, amijoy_nargs, 0);
MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
loopout = (ANALOG_LOOP_TIME * port->loop) / 1000;
timeout = ANALOG_MAX_TIME * port->speed;
-
+
local_irq_save(flags);
gameport_trigger(gameport);
GET_TIME(now);
u = gameport_read(port->gameport);
- if (!chf) {
+ if (!chf) {
port->buttons = (~u >> 4) & 0xf;
return 0;
}
}
}
- for (i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++)
if (port->analog[i].mask)
analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
{
struct analog_port *port = dev->private;
if (!port->used++)
- mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
+ mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
return 0;
}
static void analog_name(struct analog *analog)
{
- sprintf(analog->name, "Analog %d-axis %d-button",
+ sprintf(analog->name, "Analog %d-axis %d-button",
hweight8(analog->mask & ANALOG_AXES_STD),
hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 +
hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4);
analog->dev.close = analog_close;
analog->dev.private = port;
analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
+
for (i = j = 0; i < 4; i++)
if (analog->mask & (1 << i)) {
-
+
t = analog_axes[j];
x = port->axes[i];
y = (port->axes[0] + port->axes[1]) >> 1;
j++;
}
- for (i = j = 0; i < 3; i++)
- if (analog->mask & analog_exts[i])
+ for (i = j = 0; i < 3; i++)
+ if (analog->mask & analog_exts[i])
for (x = 0; x < 2; x++) {
t = analog_hats[j++];
set_bit(t, analog->dev.absbit);
else
printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
- port->speed > 10000 ? "M" : "k",
+ port->speed > 10000 ? "M" : "k",
port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
: (port->loop * 1000000) / port->speed);
}
gameport_calibrate(port->gameport, port->axes, max);
}
-
- for (i = 0; i < 4; i++)
+
+ for (i = 0; i < 4; i++)
port->initial[i] = port->axes[i];
- return -!(analog[0].mask || analog[1].mask);
+ return -!(analog[0].mask || analog[1].mask);
}
static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port)
msleep(ANALOG_MAX_TIME);
port->mask = (gameport_read(gameport) ^ t) & t & 0xf;
port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS;
-
+
for (i = 0; i < ANALOG_INIT_RETRIES; i++) {
if (!analog_cooked_read(port)) break;
msleep(ANALOG_MAX_TIME);
msleep(ANALOG_MAX_TIME);
t = gameport_time(gameport, ANALOG_MAX_TIME * 1000);
gameport_trigger(gameport);
- while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++;
+ while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++;
udelay(ANALOG_SAITEK_DELAY);
t = gameport_time(gameport, ANALOG_SAITEK_TIME);
gameport_trigger(gameport);
- while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++;
+ while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++;
if (v < (u >> 1)) { /* FIXME - more than one port */
analog_options[0] |= /* FIXME - more than one port */
if (!strcmp(analog_types[j].name, js[i])) {
analog_options[i] = analog_types[j].value;
break;
- }
+ }
if (analog_types[j].name) continue;
analog_options[i] = simple_strtoul(js[i], &end, 0);
r[i] = buf[i] = 0;
t[i] = COBRA_MAX_STROBE;
}
-
+
local_irq_save(flags);
u = gameport_read(gameport);
}
- mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
+ mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
}
static int cobra_open(struct input_dev *dev)
{
struct cobra *cobra = dev->private;
if (!cobra->used++)
- mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
+ mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
return 0;
}
cobra->exists = cobra_read_packet(gameport, data);
- for (i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++)
if ((cobra->exists >> i) & data[i] & 1) {
printk(KERN_WARNING "cobra.c: Device %d on %s has the Ext bit set. ID is: %d"
" Contact vojtech@ucw.cz\n", i, gameport->phys, (data[i] >> 2) & 7);
cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
cobra->dev[i].id.product = 0x0008;
cobra->dev[i].id.version = 0x0100;
-
+
cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
cobra->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
struct db9 {
struct input_dev dev[DB9_MAX_DEVICES];
struct timer_list timer;
- struct pardevice *pd;
+ struct pardevice *pd;
int mode;
int used;
char phys[2][32];
}
/*
- * db9_saturn_read_packet() reads whole saturn packet at connector
+ * db9_saturn_read_packet() reads whole saturn packet at connector
* and returns device identifier code.
*/
static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
- parport_write_control(port, 0x0a);
+ parport_write_control(port, 0x0a);
- for (i = 0; i < 7; i++) {
+ for (i = 0; i < 7; i++) {
data = parport_read_data(port);
- parport_write_control(port, 0x02);
- parport_write_control(port, 0x0a);
+ parport_write_control(port, 0x02);
+ parport_write_control(port, 0x0a);
input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
}
- parport_write_control(port, 0x00);
+ parport_write_control(port, 0x00);
break;
}
db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; j < db9_buttons[db9->mode]; j++)
- set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
+ set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
for (j = 0; j < db9_num_axis[db9->mode]; j++) {
set_bit(db9_abs[j], db9->dev[i].absbit);
if (j < 2) {
{
int i, j;
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 3; i++)
if (db9_base[i]) {
for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
input_unregister_device(db9_base[i]->dev + j);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define GC_NES4 3
#define GC_MULTI 4
#define GC_MULTI2 5
-#define GC_N64 6
+#define GC_N64 6
#define GC_PSX 7
#define GC_MAX 7
#define GC_REFRESH_TIME HZ/100
-
+
struct gc {
struct pardevice *pd;
struct input_dev dev[5];
#define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */
#define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */
#define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */
- /* GC_N64_DWS > 24 is known to fail */
+ /* GC_N64_DWS > 24 is known to fail */
#define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */
#define GC_N64_POWER_R 0xfd /* power during read */
#define GC_N64_OUT 0x1d /* output bits to the 4 pads */
/* than 123 us */
#define GC_N64_CLOCK 0x02 /* clock bits for read */
-/*
- * gc_n64_read_packet() reads an N64 packet.
+/*
+ * gc_n64_read_packet() reads an N64 packet.
* Each pad uses one bit per byte. So all pads connected to this port are read in parallel.
*/
* http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt
* http://www.gamesx.com/controldata/psxcont/psxcont.htm
* ftp://milano.usal.es/pablo/
- *
+ *
*/
#define GC_PSX_DELAY 25 /* 25 usec */
s = gc_status_bit[i];
if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) {
-
+
signed char axes[2];
axes[0] = axes[1] = 0;
for (j = 0; j < 8; j++) {
- if (data[23 - j] & s) axes[0] |= 1 << j;
- if (data[31 - j] & s) axes[1] |= 1 << j;
+ if (data[23 - j] & s) axes[0] |= 1 << j;
+ if (data[31 - j] & s) axes[1] |= 1 << j;
}
input_report_abs(dev + i, ABS_X, axes[0]);
break;
case GC_PSX:
-
+
psx = gc_psx_read_packet(gc, data);
switch(psx) {
}
sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
-
+
gc->dev[i].name = gc_names[config[i + 1]];
gc->dev[i].phys = gc->phys[i];
gc->dev[i].id.bustype = BUS_PARPORT;
return NULL;
}
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 5; i++)
if (gc->pads[0] & gc_status_bit[i]) {
input_register_device(gc->dev + i);
printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
if (gc_base[i]) {
for (j = 0; j < 5; j++)
if (gc_base[i]->pads[0] & gc_status_bit[j])
- input_unregister_device(gc_base[i]->dev + j);
+ input_unregister_device(gc_base[i]->dev + j);
parport_unregister_device(gc_base[i]->pd);
}
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
{
struct gf2k *gf2k = dev->private;
if (!gf2k->used++)
- mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
+ mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
return 0;
}
for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
- gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
+ gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
gf2k->dev.absmin[gf2k_abs[i]] = 32;
gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
#define GRIP_STROBE_GPP 200 /* 200 us */
#define GRIP_LENGTH_XT 4
#define GRIP_STROBE_XT 64 /* 64 us */
-#define GRIP_MAX_CHUNKS_XT 10
-#define GRIP_MAX_BITS_XT 30
+#define GRIP_MAX_CHUNKS_XT 10
+#define GRIP_MAX_BITS_XT 30
#define GRIP_REFRESH_TIME HZ/50 /* 20 ms */
buf = (buf << 1) | (u >> 1);
t = strobe;
i++;
- } else
+ } else
if ((((u ^ v) & (v ^ w)) >> 1) & ~(u | v | w) & 1) {
if (i == 20) {
#define IO_MODE_FAST 0x0200 /* Used 3 data bits per gameport read */
#define IO_SLOT_CHANGE 0x0800 /* Multiport physical slot status changed */
#define IO_DONE 0x1000 /* Multiport is done sending packets */
-#define IO_RETRY 0x4000 /* Try again later to get packet */
+#define IO_RETRY 0x4000 /* Try again later to get packet */
#define IO_RESET 0x8000 /* Force multiport to resend all packets */
/*
/*
* Gets a 28-bit packet from the multiport.
*
- * After getting a packet successfully, commands encoded by sendcode may
- * be sent to the multiport.
+ * After getting a packet successfully, commands encoded by sendcode may
+ * be sent to the multiport.
*
* The multiport clock value is reflected in gameport bit B4.
*
*packet = 0;
raw_data = gameport_read(gameport);
- if (raw_data & 1)
+ if (raw_data & 1)
return IO_RETRY;
for (i = 0; i < 64; i++) {
if (raw_data & 0x31)
return IO_RESET;
- gameport_trigger(gameport);
+ gameport_trigger(gameport);
if (!poll_until(0x10, 0, 308, gameport, &raw_data))
return IO_RESET;
- } else
+ } else
return IO_RETRY;
/* Determine packet transfer mode and prepare for packet construction. */
if (raw_data & 0x20) { /* 3 data bits/read */
portvals |= raw_data >> 4; /* Compare B4-B7 before & after trigger */
- if (portvals != 0xb)
+ if (portvals != 0xb)
return 0;
data_mask = 7;
bits_per_read = 3;
return IO_RESET;
}
- if (raw_data)
+ if (raw_data)
return IO_RESET;
/* If 3 bits/read used, drop from 30 bits to 28. */
pkt = (pkt >> 2) | 0xf0000000;
}
- if (bit_parity(pkt) == 1)
+ if (bit_parity(pkt) == 1)
return IO_RESET;
/* Acknowledge packet receipt */
/* Return if we just wanted the packet or multiport wants to send more */
- *packet = pkt;
+ *packet = pkt;
if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE)))
return IO_GOT_PACKET;
-
+
if (pkt & PACKET_MP_MORE)
return IO_GOT_PACKET | IO_RETRY;
if (!poll_until(0x30, 0, 193, gameport, &raw_data))
return IO_GOT_PACKET | IO_RESET;
- if (raw_data & 1)
+ if (raw_data & 1)
return IO_GOT_PACKET | IO_RESET;
if (sendcode & 1)
strange_code = joytype;
}
}
- return flags;
+ return flags;
}
/*
* Returns true if all multiport slot states appear valid.
*/
-
+
static int slots_valid(struct grip_mp *grip)
{
int flags, slot, invalid = 0, active = 0;
flags = get_and_decode_packet(grip, 0);
- if (!(flags & IO_GOT_PACKET))
+ if (!(flags & IO_GOT_PACKET))
return 0;
for (slot = 0; slot < 4; slot++) {
* Returns whether the multiport was placed into digital mode and
* able to communicate its state successfully.
*/
-
+
static int multiport_init(struct grip_mp *grip)
{
int dig_mode, initialized = 0, tries = 0;
dbg("multiport_init(): unable to achieve digital mode.\n");
return 0;
}
-
+
/* Get packets, store multiport state, and check state's validity */
for (tries = 0; tries < 4096; tries++) {
if ( slots_valid(grip) ) {
}
/*
- * Get the multiport state.
+ * Get the multiport state.
*/
-
+
static void get_and_report_mp_state(struct grip_mp *grip)
{
int i, npkts, flags;
break;
}
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
if (grip->dirty[i])
report_slot(grip, i);
}
/*
* Called when a joystick device file is opened
*/
-
+
static int grip_open(struct input_dev *dev)
{
struct grip_mp *grip = dev->private;
/*
* Repeatedly polls the multiport and generates events.
*/
-
+
static void grip_timer(unsigned long private)
{
struct grip_mp *grip = (void*) private;
#define GUILLEMOT_MAX_LENGTH 17 /* 17 bytes */
#define GUILLEMOT_REFRESH_TIME HZ/50 /* 20 ms */
-static short guillemot_abs_pad[] =
+static short guillemot_abs_pad[] =
{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };
static short guillemot_btn_pad[] =
{
struct guillemot *guillemot = dev->private;
if (!guillemot->used++)
- mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
+ mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
return 0;
}
if (!guillemot_type[i].name) {
printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n",
gameport->phys, data[12], data[13], data[11], data[14], data[15]);
- goto fail2;
+ goto fail2;
}
sprintf(guillemot->phys, "%s/input0", gameport->phys);
guillemot->dev.absmax[t] = 255;
}
- if (guillemot->type->hat)
+ if (guillemot->type->hat)
for (i = 0; i < 2; i++) {
t = ABS_HAT0X + i;
set_bit(t, guillemot->dev.absbit);
depends on JOYSTICK_IFORCE && (JOYSTICK_IFORCE=m || USB=y) && USB
help
Say Y here if you have an I-Force joystick or steering wheel
- connected to your USB port.
+ connected to your USB port.
config JOYSTICK_IFORCE_232
bool "I-Force Serial joysticks and wheels"
# Goal definition
iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o
-obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
+obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y)
- iforce-objs += iforce-serio.o
+ iforce-objs += iforce-serio.o
endif
ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y)
- iforce-objs += iforce-usb.o
+ iforce-objs += iforce-usb.o
endif
EXTRA_CFLAGS = -Werror-implicit-function-declaration
}
/*
- * Analyse the changes in an effect, and tell if we need to send an condition
+ * Analyse the changes in an effect, and tell if we need to send an condition
* parameter packet
*/
static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
int core_err = 0;
if (!is_update || need_period_modifier(iforce, effect)) {
- param1_err = make_period_modifier(iforce, mod1_chunk,
+ param1_err = make_period_modifier(iforce, mod1_chunk,
is_update,
effect->u.periodic.magnitude, effect->u.periodic.offset,
effect->u.periodic.period, effect->u.periodic.phase);
else {
/* We want to update an effect */
if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES;
-
+
/* Parameter type cannot be updated */
if (effect->type != iforce->core_effects[effect->id].effect.type)
return -EINVAL;
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
current->pid == iforce->core_effects[i].owner) {
-
+
/* Stop effect */
input_report_ff(dev, i, 0);
int empty;
int head, tail;
unsigned long flags;
-
+
/*
* Update head and tail of xmit buffer
*/
break;
#endif
#ifdef CONFIG_JOYSTICK_IFORCE_USB
- case IFORCE_USB:
+ case IFORCE_USB:
if (iforce->usbdev && empty &&
!test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
cs ^= iforce->xmit.buf[iforce->xmit.tail];
XMIT_INC(iforce->xmit.tail, 1);
}
-
+
serio_write(iforce->serio, cs);
if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
struct circ_buf xmit;
unsigned char xmit_data[XMIT_SIZE];
long xmit_flags[1];
-
+
/* Force Feedback */
wait_queue_head_t wait;
struct resource device_memory;
char phys[32];
};
-static short interact_abs_hhfx[] =
+static short interact_abs_hhfx[] =
{ ABS_RX, ABS_RY, ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y, -1 };
static short interact_abs_pp8d[] =
{ ABS_X, ABS_Y, -1 };
case INTERACT_TYPE_PP8D:
for (i = 0; i < 2; i++)
- input_report_abs(dev, interact_abs_pp8d[i],
+ input_report_abs(dev, interact_abs_pp8d[i],
((data[0] >> ((i << 1) + 20)) & 1) - ((data[0] >> ((i << 1) + 21)) & 1));
for (i = 0; i < 8; i++)
{
struct interact *interact = dev->private;
if (!interact->used++)
- mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
+ mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
return 0;
}
if (!interact_type[i].length) {
printk(KERN_WARNING "interact.c: Unknown joystick on %s. [len %d d0 %08x d1 %08x i2 %08x]\n",
gameport->phys, i, data[0], data[1], data[2]);
- goto fail2;
+ goto fail2;
}
sprintf(interact->phys, "%s/input0", gameport->phys);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
printk(KERN_INFO "joydump: | Raw mode not available - trying cooked. |\n");
if (gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) {
-
+
printk(KERN_INFO "joydump: | Cooked not available either. Failing. |\n");
printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
return;
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
memset(magellan, 0, sizeof(struct magellan));
- magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 9; i++)
set_bit(magellan_buttons[i], magellan->dev.keybit);
magellan->dev.id.vendor = SERIO_MAGELLAN;
magellan->dev.id.product = 0x0001;
magellan->dev.id.version = 0x0100;
-
+
serio->private = magellan;
if (serio_open(serio, dev)) {
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
buf[i] = v >> 5; /* Store it */
i++; /* Advance index */
bitout = strobe; /* Extend timeout for next bit */
- }
+ }
if (kick && (~v & u & 0x01)) { /* Falling edge on axis 0 */
sched = kick; /* Schedule second trigger */
kick = 0; /* Don't schedule next time on falling edge */
pending = 1; /* Mark schedule */
- }
+ }
if (pending && sched < 0 && (i > -SW_END)) { /* Second trigger time */
gameport_trigger(gameport); /* Trigger */
bitout = start; /* Long bit timeout */
pending = 0; /* Unmark schedule */
- timeout = 0; /* Switch from global to bit timeouts */
+ timeout = 0; /* Switch from global to bit timeouts */
}
}
sw_read_packet(sw->gameport, buf, SW_LENGTH, i); /* Read ID packet, this initializes the stick */
sw->fail = SW_FAIL;
-
+
return -1;
}
static void sw_timer(unsigned long private)
{
struct sw *sw = (void *) private;
-
+
sw->reads++;
if (sw_read(sw)) sw->bads++;
mod_timer(&sw->timer, jiffies + SW_REFRESH);
case 60:
sw->number++;
case 45: /* Ambiguous packet length */
- if (j <= 40) { /* ID length less or eq 40 -> FSP */
+ if (j <= 40) { /* ID length less or eq 40 -> FSP */
case 43:
sw->type = SW_ID_FSP;
break;
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY };
static char *spaceball_names[] = {
- "?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B",
- "SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController",
+ "?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B",
+ "SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController",
"SpaceTec SpaceBall 3003C", "SpaceTec SpaceBall 4000FLX", "SpaceTec SpaceBall 4000FLX Lefty" };
/*
case 'D': /* Ball data */
if (spaceball->idx != 15) return;
for (i = 0; i < 6; i++)
- input_report_abs(dev, spaceball_axes[i],
+ input_report_abs(dev, spaceball_axes[i],
(__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
break;
return;
memset(spaceball, 0, sizeof(struct spaceball));
- spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
switch (id) {
case SPACEBALL_4000FLX:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
default:
- spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
+ spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
case SPACEBALL_3003C:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
spaceball->dev.id.vendor = SERIO_SPACEBALL;
spaceball->dev.id.product = id;
spaceball->dev.id.version = 0x0100;
-
+
serio->private = spaceball;
if (serio_open(serio, dev)) {
* $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
- *
+ *
* Based on the work of:
* David Thompson
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
static unsigned char spaceorb_xor[] = "SpaceWare";
static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive queue overflow", "Transmit queue timeout",
- "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" };
+ "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" };
/*
* spaceorb_process_packet() decodes packets the driver receives from the
case 'D': /* Ball + button data */
if (spaceorb->idx != 12) return;
- for (i = 0; i < 9; i++) spaceorb->data[i+2] ^= spaceorb_xor[i];
+ for (i = 0; i < 9; i++) spaceorb->data[i+2] ^= spaceorb_xor[i];
axes[0] = ( data[2] << 3) | (data[ 3] >> 4);
axes[1] = ((data[3] & 0x0f) << 6) | (data[ 4] >> 1);
axes[2] = ((data[4] & 0x01) << 9) | (data[ 5] << 2) | (data[4] >> 5);
return;
memset(spaceorb, 0, sizeof(struct spaceorb));
- spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 6; i++)
set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
spaceorb->dev.id.vendor = SERIO_SPACEORB;
spaceorb->dev.id.product = 0x0001;
spaceorb->dev.id.version = 0x0100;
-
+
serio->private = spaceorb;
if (serio_open(serio, dev)) {
memset(stinger, 0, sizeof(struct stinger));
- stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
BIT(BTN_START) | BIT(BTN_SELECT);
stinger->dev.id.version = 0x0100;
for (i = 0; i < 2; i++) {
- stinger->dev.absmax[ABS_X+i] = 64;
- stinger->dev.absmin[ABS_X+i] = -64;
+ stinger->dev.absmax[ABS_X+i] = 64;
+ stinger->dev.absmin[ABS_X+i] = -64;
stinger->dev.absflat[ABS_X+i] = 4;
}
* Copyright (c) 1998-2001 Vojtech Pavlik
*
* Based on the work of:
- * Trystan Larey-Williams
+ * Trystan Larey-Williams
*/
/*
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
#define TMDC_BYTE_REV 11
#define TMDC_BYTE_DEF 12
-#define TMDC_ABS 7
+#define TMDC_ABS 7
#define TMDC_ABS_HAT 4
#define TMDC_BTN 16
unsigned char btno[2][4];
int used;
int reads;
- int bads;
+ int bads;
unsigned char exists;
};
local_irq_save(flags);
gameport_trigger(gameport);
-
+
w = gameport_read(gameport) >> 4;
do {
}
data[k][i[k]] |= (~v & 1) << (j[k]++ - 1); /* Data bit */
}
- t[k]--;
+ t[k]--;
}
} while (t[0] > 0 || t[1] > 0);
bad = 1;
else
- for (j = 0; j < 2; j++)
+ for (j = 0; j < 2; j++)
if (r & (1 << j) & tmdc->exists) {
if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
{
struct tmdc *tmdc = dev->private;
if (!tmdc->used++)
- mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
+ mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
return 0;
}
struct tmdc *tmdc = gameport->private;
int i;
for (i = 0; i < 2; i++)
- if (tmdc->exists & (1 << i))
+ if (tmdc->exists & (1 << i))
input_unregister_device(tmdc->dev + i);
gameport_close(gameport);
kfree(tmdc);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
#define TGFX_TRIGGER 0x08
#define TGFX_UP 0x10
-#define TGFX_DOWN 0x20
+#define TGFX_DOWN 0x20
#define TGFX_LEFT 0x40
#define TGFX_RIGHT 0x80
if (!tgfx->used++) {
parport_claim(tgfx->pd);
parport_write_control(tgfx->pd->port, 0x04);
- mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
+ mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
}
return 0;
}
memset(tgfx, 0, sizeof(struct tgfx));
tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
-
+
parport_put_port(pp);
if (!tgfx->pd) {
tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
for (j = 0; j < config[i+1]; j++)
- set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
+ set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
kfree(tgfx);
return NULL;
}
-
+
return tgfx;
}
{
int i, j;
- for (i = 0; i < 3; i++)
+ for (i = 0; i < 3; i++)
if (tgfx_base[i]) {
for (j = 0; j < 7; j++)
if (tgfx_base[i]->sticks & (1 << j))
#include <linux/serio.h>
#include <linux/init.h>
+MODULE_DESCRIPTION("Handykey Twiddler keyboard as a joystick driver");
+MODULE_LICENSE("GPL");
+
/*
* Constants.
*/
* packet processing routine.
*/
-static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs)
+static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
{
struct twidjoy *twidjoy = serio->private;
if ((data & 0x80) == 0)
twidjoy->idx = 0; /* this byte starts a new packet */
else if (twidjoy->idx == 0)
- return; /* wrong MSB -- ignore this byte */
+ return IRQ_HANDLED; /* wrong MSB -- ignore this byte */
if (twidjoy->idx < TWIDJOY_MAX_LENGTH)
twidjoy->data[twidjoy->idx++] = data;
twidjoy->idx = 0;
}
- return;
+ return IRQ_HANDLED;
}
/*
twidjoy->dev.id.product = 0x0001;
twidjoy->dev.id.version = 0x0100;
- twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (bp = twidjoy_buttons; bp->bitmask; bp++) {
for (i = 0; i < bp->bitmask; i++)
twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
for (i = 0; i < 2; i++) {
- twidjoy->dev.absmax[ABS_X+i] = 50;
- twidjoy->dev.absmin[ABS_X+i] = -50;
+ twidjoy->dev.absmax[ABS_X+i] = 50;
+ twidjoy->dev.absmin[ABS_X+i] = -50;
/* TODO: arndt 20010708: Are these values appropriate? */
twidjoy->dev.absfuzz[ABS_X+i] = 4;
/*
* This program is free warftware; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#define WARRIOR_MAX_LENGTH 16
-static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
+static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
static char *warrior_name = "Logitech WingMan Warrior";
/*
warrior->data[warrior->idx++] = data;
if (warrior->idx == warrior->len) {
- if (warrior->idx) warrior_process_packet(warrior, regs);
+ if (warrior->idx) warrior_process_packet(warrior, regs);
warrior->idx = 0;
warrior->len = 0;
}
memset(warrior, 0, sizeof(struct warrior));
- warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
+ warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
warrior->dev.relbit[0] = BIT(REL_DIAL);
warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
warrior->dev.id.version = 0x0100;
for (i = 0; i < 2; i++) {
- warrior->dev.absmax[ABS_X+i] = -64;
- warrior->dev.absmin[ABS_X+i] = 64;
- warrior->dev.absflat[ABS_X+i] = 8;
+ warrior->dev.absmax[ABS_X+i] = -64;
+ warrior->dev.absmin[ABS_X+i] = 64;
+ warrior->dev.absflat[ABS_X+i] = 8;
}
- warrior->dev.absmax[ABS_THROTTLE] = -112;
- warrior->dev.absmin[ABS_THROTTLE] = 112;
+ warrior->dev.absmax[ABS_THROTTLE] = -112;
+ warrior->dev.absmin[ABS_THROTTLE] = 112;
for (i = 0; i < 2; i++) {
- warrior->dev.absmax[ABS_HAT0X+i] = -1;
- warrior->dev.absmin[ABS_HAT0X+i] = 1;
+ warrior->dev.absmax[ABS_HAT0X+i] = -1;
+ warrior->dev.absmin[ABS_HAT0X+i] = 1;
}
warrior->dev.private = warrior;
-
+
serio->private = warrior;
- if (serio_open(serio, dev)) {
+ if (serio_open(serio, dev)) {
kfree(warrior);
return;
}
Say Y here if you want to use the old IBM PC/XT keyboard (or
compatible) on your system. This is only possible with a
parallel port keyboard adapter, you cannot connect it to the
- keyboard port on a PC that runs Linux.
+ keyboard port on a PC that runs Linux.
To compile this driver as a module, choose M here: the
module will be called xtkbd.
depends on AMIGA && INPUT && INPUT_KEYBOARD
help
Say Y here if you are running Linux on any AMIGA and have a keyboard
- attached.
+ attached.
To compile this driver as a module, choose M here: the
module will be called amikbd.
-
-config KEYBOARD_98KBD
- tristate "NEC PC-9800 Keyboard support"
- depends on X86_PC9800 && INPUT && INPUT_KEYBOARD
- select SERIO
- help
- Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or
- compatible) on your system.
-
- To compile this driver as a module, choose M here: the
- module will be called 98kbd.
-
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>
-#include <linux/timer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
unsigned char keycode[512];
struct input_dev dev;
struct serio *serio;
- struct timer_list timer;
+
char name[64];
char phys[32];
+ unsigned short id;
+ unsigned char set;
+ unsigned int translated:1;
+ unsigned int extra:1;
+ unsigned int write:1;
+
unsigned char cmdbuf[4];
unsigned char cmdcnt;
- unsigned char set;
- unsigned char extra;
- unsigned char release;
- int lastkey;
volatile signed char ack;
unsigned char emul;
- unsigned short id;
- unsigned char write;
- unsigned char translated;
- unsigned char resend;
- unsigned char bat_xl;
+ unsigned int resend:1;
+ unsigned int release:1;
+ unsigned int bat_xl:1;
+ unsigned int enabled:1;
+
unsigned int last;
unsigned long time;
};
goto out;
}
+ if (!atkbd->enabled)
+ goto out;
+
if (atkbd->translated) {
if (atkbd->emul ||
atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
goto out;
case ATKBD_RET_ERR:
- printk(KERN_WARNING "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+ printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
goto out;
}
case ATKBD_KEY_NULL:
break;
case ATKBD_KEY_UNKNOWN:
- printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
- atkbd->release ? "released" : "pressed",
- atkbd->translated ? "translated" : "raw",
- atkbd->set, code, serio->phys);
- if (atkbd->translated && atkbd->set == 2 && code == 0x7a)
- printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access"
- " hardware directly.\n");
- else
- printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", code & 0x80 ? "e0" : "", code & 0x7f);
+ if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
+ printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
+ "like XFree86, might be trying access hardware directly.\n",
+ data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+ } else {
+ printk(KERN_WARNING "atkbd.c: Unknown key %s "
+ "(%s set %d, code %#x on %s).\n",
+ atkbd->release ? "released" : "pressed",
+ atkbd->translated ? "translated" : "raw",
+ atkbd->set, code, serio->phys);
+ printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' "
+ "to make it known.\n",
+ code & 0x80 ? "e0" : "", code & 0x7f);
+ }
break;
case ATKBD_SCR_1:
scroll = 1 - atkbd->release * 2;
atkbd->id = 0xab00;
}
+ atkbd->enabled = 1;
+
if (atkbd->extra) {
atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
sprintf(atkbd->name, "AT Set 2 Extra keyboard");
param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
| (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0)
| (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0);
-
+
if (atkbd_probe(atkbd))
return -1;
if (atkbd->set != atkbd_set_3(atkbd))
return -1;
-
+
atkbd_enable(atkbd);
if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
kbd->dev.name = dev->product_name;
kbd->dev.id.bustype = BUS_MAPLE;
-
+
input_register_device(&kbd->dev);
maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
case EV_LED:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
- sunkbd->serio->write(sunkbd->serio,
+ sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) |
(!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led));
return 0;
case SND_CLICK:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
return 0;
-
+
case SND_BELL:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
return 0;
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
- sunkbd->serio->write(sunkbd->serio,
+ sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
(!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_SUNKBD)
return;
-
+
if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
return;
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
#define XTKBD_KEY 0x7f
#define XTKBD_RELEASE 0x80
-static unsigned char xtkbd_keycode[256] = {
+static unsigned char xtkbd_keycode[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
return;
memset(xtkbd, 0, sizeof(struct xtkbd));
-
+
xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
xtkbd->serio = serio;
tristate "M68k Beeper support"
depends on M68K && INPUT && INPUT_MISC
-config INPUT_98SPKR
- tristate "PC-9800 Speaker support"
- depends on X86_PC9800 && INPUT && INPUT_MISC
-
config INPUT_UINPUT
tristate "User level driver support"
depends on INPUT && INPUT_MISC
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
- }
+ }
if (value > 20 && value < 32767)
count = PIT_TICK_RATE / value;
-
+
spin_lock_irqsave(&i8253_beep_lock, flags);
if (count) {
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
- }
+ }
if (value > 20 && value < 32767)
count = 1193182 / value;
-
+
spin_lock_irqsave(&beep_lock, flags);
/* EBUS speaker only has on/off state, the frequency does not
case SND_BELL: if (value) value = 1000;
case SND_TONE: break;
default: return -1;
- }
+ }
if (value > 20 && value < 32767)
count = 1193182 / value;
-
+
spin_lock_irqsave(&beep_lock, flags);
if (count) {
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
- *
+ *
* Changes/Revisions:
* 0.1 20/06/2002
* - first public version
static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
{
return 0;
-}
+}
static int uinput_create_device(struct uinput_device *udev)
{
memset(newinput, 0, sizeof(struct input_dev));
newdev->dev = newinput;
-
+
file->private_data = newdev;
return 0;
{
unsigned int cnt;
int retval = 0;
-
+
for (cnt = 0; cnt < ABS_MAX; cnt++) {
- if (!test_bit(cnt, dev->absbit))
+ if (!test_bit(cnt, dev->absbit))
continue;
-
+
if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
(dev->absmax[cnt] <= dev->absmin[cnt])) {
- printk(KERN_DEBUG
+ printk(KERN_DEBUG
"%s: invalid abs[%02x] min:%d max:%d\n",
- UINPUT_NAME, cnt,
+ UINPUT_NAME, cnt,
dev->absmin[cnt], dev->absmax[cnt]);
retval = -EINVAL;
break;
if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
(dev->absflat[cnt] > dev->absmax[cnt])) {
- printk(KERN_DEBUG
+ printk(KERN_DEBUG
"%s: absflat[%02x] out of range: %d "
"(min:%d/max:%d)\n",
UINPUT_NAME, cnt, dev->absflat[cnt],
return retval;
}
-static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
+static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count)
{
struct uinput_user_dev *user_dev;
struct input_dev *dev;
goto exit;
}
- if (NULL != dev->name)
+ if (NULL != dev->name)
kfree(dev->name);
size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
return retval;
}
-static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct uinput_device *udev = file->private_data;
-
+
if (test_bit(UIST_CREATED, &(udev->state))) {
struct input_event ev;
return count;
}
-static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct uinput_device *udev = file->private_data;
int retval = 0;
-
+
if (!test_bit(UIST_CREATED, &(udev->state)))
return -ENODEV;
return -EAGAIN;
retval = wait_event_interruptible(udev->waitq,
- (udev->head != udev->tail) ||
+ (udev->head != udev->tail) ||
!test_bit(UIST_CREATED, &(udev->state)));
-
+
if (retval)
return retval;
if (!test_bit(UIST_CREATED, &(udev->state)))
return -ENODEV;
- while ((udev->head != udev->tail) &&
+ while ((udev->head != udev->tail) &&
(retval + sizeof(struct input_event) <= count)) {
if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
sizeof(struct input_event))) return -EFAULT;
if (udev->head != udev->tail)
return POLLIN | POLLRDNORM;
- return 0;
+ return 0;
}
static int uinput_burn_device(struct uinput_device *udev)
case UI_DEV_CREATE:
retval = uinput_create_device(udev);
break;
-
+
case UI_DEV_DESTROY:
retval = uinput_destroy_device(udev);
break;
}
set_bit(arg, udev->dev->evbit);
break;
-
+
case UI_SET_KEYBIT:
if (arg > KEY_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->keybit);
break;
-
+
case UI_SET_RELBIT:
if (arg > REL_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->relbit);
break;
-
+
case UI_SET_ABSBIT:
if (arg > ABS_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->absbit);
break;
-
+
case UI_SET_MSCBIT:
if (arg > MSC_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->mscbit);
break;
-
+
case UI_SET_LEDBIT:
if (arg > LED_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->ledbit);
break;
-
+
case UI_SET_SNDBIT:
if (arg > SND_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->sndbit);
break;
-
+
case UI_SET_FFBIT:
if (arg > FF_MAX) {
retval = -EINVAL;
}
set_bit(arg, udev->dev->ffbit);
break;
-
+
default:
retval = -EFAULT;
}
described in the source file). This driver should, in theory,
also work with the digitizer DEC produced, but it isn't tested
with that (I don't have the hardware yet).
-
-config MOUSE_PC9800
- tristate "NEC PC-9800 busmouse"
- depends on X86_PC9800 && INPUT && INPUT_MOUSE && ISA
- help
- Say Y here if you have NEC PC-9801/PC-9821 computer and want its
- native mouse supported.
-
- To compile this driver as a module, choose M here: the
- module will be called 98busmouse.
-
obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
-obj-$(CONFIG_MOUSE_PC9800) += 98busmouse.o
obj-$(CONFIG_MOUSE_PS2) += psmouse.o
obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
#include "psmouse.h"
#include "logips2pp.h"
+/* Logitech mouse types */
+#define PS2PP_KIND_WHEEL 1
+#define PS2PP_KIND_MX 2
+#define PS2PP_KIND_TP3 3
+
+/* Logitech mouse features */
+#define PS2PP_WHEEL 0x01
+#define PS2PP_HWHEEL 0x02
+#define PS2PP_SIDE_BTN 0x04
+#define PS2PP_EXTRA_BTN 0x08
+#define PS2PP_TASK_BTN 0x10
+#define PS2PP_NAV_BTN 0x20
+
+struct ps2pp_info {
+ const int model;
+ unsigned const int kind;
+ unsigned const int features;
+};
+
/*
* Process a PS2++ or PS2T++ packet.
*/
packet[0] &= 0x0f;
packet[1] = 0;
packet[2] = 0;
-
}
}
static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
{
- unsigned char d;
- int i;
-
- if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
+ if (psmouse_sliced_command(psmouse, command))
return -1;
- for (i = 6; i >= 0; i -= 2) {
- d = (command >> i) & 3;
- if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
- return -1;
- }
-
if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
return -1;
* enabled if we do nothing to it. Of course I put this in because I want it
* disabled :P
* 1 - enabled (if previously disabled, also default)
- * 0/2 - disabled
+ * 0/2 - disabled
*/
static void ps2pp_set_smartscroll(struct psmouse *psmouse)
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
- if (psmouse_smartscroll == 1)
- param[0] = 1;
- else
- if (psmouse_smartscroll > 2)
- return;
-
- /* else leave param[0] == 0 to disable */
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ if (psmouse_smartscroll < 2) {
+ /* 0 - disabled, 1 - enabled */
+ param[0] = psmouse_smartscroll;
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ }
}
/*
psmouse_command(psmouse, ¶m, PSMOUSE_CMD_SETRES);
}
+static struct ps2pp_info *get_model_info(unsigned char model)
+{
+ static struct ps2pp_info ps2pp_list[] = {
+ { 12, 0, PS2PP_SIDE_BTN},
+ { 13, 0, 0 },
+ { 40, 0, PS2PP_SIDE_BTN },
+ { 41, 0, PS2PP_SIDE_BTN },
+ { 42, 0, PS2PP_SIDE_BTN },
+ { 43, 0, PS2PP_SIDE_BTN },
+ { 50, 0, 0 },
+ { 51, 0, 0 },
+ { 52, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
+ { 53, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 61, PS2PP_KIND_MX,
+ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+ PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, /* MX700 */
+ { 73, 0, PS2PP_SIDE_BTN },
+ { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
+ { 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 96, 0, 0 },
+ { 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL },
+ { 100, PS2PP_KIND_MX,
+ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+ PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, /* MX510 */
+ { 112, PS2PP_KIND_MX,
+ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
+ PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, /* MX500 */
+ { 114, PS2PP_KIND_MX,
+ PS2PP_WHEEL | PS2PP_SIDE_BTN |
+ PS2PP_TASK_BTN | PS2PP_EXTRA_BTN }, /* M310 */
+ { }
+ };
+ int i;
+
+ for (i = 0; ps2pp_list[i].model; i++)
+ if (model == ps2pp_list[i].model)
+ return &ps2pp_list[i];
+ return NULL;
+}
+
/*
- * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or
- * touchpad.
+ * Set up input device's properties based on the detected mouse model.
*/
-static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
+static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info)
{
- int i;
- static struct _logips2_list {
- const int model;
- unsigned const int features;
- } logips2pp_list [] = {
- { 12, PS2PP_4BTN},
- { 13, 0 },
- { 40, PS2PP_4BTN },
- { 41, PS2PP_4BTN },
- { 42, PS2PP_4BTN },
- { 43, PS2PP_4BTN },
- { 50, 0 },
- { 51, 0 },
- { 52, PS2PP_4BTN | PS2PP_WHEEL },
- { 53, PS2PP_WHEEL },
- { 61, PS2PP_WHEEL | PS2PP_MX }, /* MX700 */
- { 73, PS2PP_4BTN },
- { 75, PS2PP_WHEEL },
- { 76, PS2PP_WHEEL },
- { 80, PS2PP_4BTN | PS2PP_WHEEL },
- { 81, PS2PP_WHEEL },
- { 83, PS2PP_WHEEL },
- { 88, PS2PP_WHEEL },
- { 96, 0 },
- { 97, 0 },
- { 100 , PS2PP_WHEEL | PS2PP_MX }, /* MX510 */
- { 112 , PS2PP_WHEEL | PS2PP_MX }, /* MX500 */
- { 114 , PS2PP_WHEEL | PS2PP_MX | PS2PP_MX310 }, /* MX310 */
- { }
- };
+ if (model_info->features & PS2PP_SIDE_BTN)
+ set_bit(BTN_SIDE, psmouse->dev.keybit);
+
+ if (model_info->features & PS2PP_EXTRA_BTN)
+ set_bit(BTN_EXTRA, psmouse->dev.keybit);
- psmouse->vendor = "Logitech";
- psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+ if (model_info->features & PS2PP_TASK_BTN)
+ set_bit(BTN_TASK, psmouse->dev.keybit);
- if (param[1] < 3)
- clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
- if (param[1] < 2)
- clear_bit(BTN_RIGHT, psmouse->dev.keybit);
+ if (model_info->features & PS2PP_NAV_BTN) {
+ set_bit(BTN_FORWARD, psmouse->dev.keybit);
+ set_bit(BTN_BACK, psmouse->dev.keybit);
+ }
- psmouse->type = PSMOUSE_PS2;
+ if (model_info->features & PS2PP_WHEEL)
+ set_bit(REL_WHEEL, psmouse->dev.relbit);
- for (i = 0; logips2pp_list[i].model; i++){
- if (logips2pp_list[i].model == psmouse->model){
- psmouse->type = PSMOUSE_PS2PP;
- if (logips2pp_list[i].features & PS2PP_4BTN)
- set_bit(BTN_SIDE, psmouse->dev.keybit);
+ if (model_info->features & PS2PP_HWHEEL)
+ set_bit(REL_HWHEEL, psmouse->dev.relbit);
- if (logips2pp_list[i].features & PS2PP_WHEEL){
- set_bit(REL_WHEEL, psmouse->dev.relbit);
- psmouse->name = "Wheel Mouse";
- }
- if (logips2pp_list[i].features & PS2PP_MX) {
- set_bit(BTN_SIDE, psmouse->dev.keybit);
- set_bit(BTN_EXTRA, psmouse->dev.keybit);
- set_bit(BTN_TASK, psmouse->dev.keybit);
- if (!(logips2pp_list[i].features & PS2PP_MX310)){
- set_bit(BTN_BACK, psmouse->dev.keybit);
- set_bit(BTN_FORWARD, psmouse->dev.keybit);
- }
- psmouse->name = "MX Mouse";
- }
+ switch (model_info->kind) {
+ case PS2PP_KIND_WHEEL:
+ psmouse->name = "Wheel Mouse";
+ break;
+
+ case PS2PP_KIND_MX:
+ psmouse->name = "MX Mouse";
+ break;
+
+ case PS2PP_KIND_TP3:
+ psmouse->name = "TouchPad 3";
break;
- }
}
+}
+
+
/*
- * Do Logitech PS2++ / PS2T++ magic init.
+ * Logitech magic init. Detect whether the mouse is a Logitech one
+ * and its exact model and try turning on extended protocol for ones
+ * that support it.
*/
- if (psmouse->type == PSMOUSE_PS2PP) {
- if (psmouse->model == 97) { /* TouchPad 3 */
+int ps2pp_init(struct psmouse *psmouse, int set_properties)
+{
+ unsigned char param[4];
+ unsigned char protocol = PSMOUSE_PS2;
+ unsigned char model, buttons;
+ struct ps2pp_info *model_info;
+
+ param[0] = 0;
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
+ param[1] = 0;
+ psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+ if (param[1] != 0) {
+ model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
+ buttons = param[1];
+ model_info = get_model_info(model);
- set_bit(REL_WHEEL, psmouse->dev.relbit);
- set_bit(REL_HWHEEL, psmouse->dev.relbit);
+/*
+ * Do Logitech PS2++ / PS2T++ magic init.
+ */
+ if (model == 97) { /* Touch Pad 3 */
- param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */
+ /* Unprotect RAM */
+ param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
psmouse_command(psmouse, param, 0x30d1);
- param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */
+ /* Enable features */
+ param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
psmouse_command(psmouse, param, 0x30d1);
- param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */
+ /* Enable PS2++ */
+ param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
psmouse_command(psmouse, param, 0x30d1);
param[0] = 0;
if (!psmouse_command(psmouse, param, 0x13d1) &&
- param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
- psmouse->name = "TouchPad 3";
- return PSMOUSE_PS2TPP;
+ param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
+ protocol = PSMOUSE_PS2TPP;
}
- } else {
+ } else if (get_model_info(model) != NULL) {
param[0] = param[1] = param[2] = 0;
ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
ps2pp_cmd(psmouse, param, 0xDB);
- if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 &&
- (param[2] & 3) == ((param[1] >> 2) & 3)) {
- ps2pp_set_smartscroll(psmouse);
- return PSMOUSE_PS2PP;
+ if ((param[0] & 0x78) == 0x48 &&
+ (param[1] & 0xf3) == 0xc2 &&
+ (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
+ ps2pp_set_smartscroll(psmouse);
+ protocol = PSMOUSE_PS2PP;
}
}
- }
- return 0;
-}
+ if (set_properties) {
+ psmouse->vendor = "Logitech";
+ psmouse->model = model;
-/*
- * Logitech magic init.
- */
-int ps2pp_detect(struct psmouse *psmouse)
-{
- unsigned char param[4];
+ if (buttons < 3)
+ clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
+ if (buttons < 2)
+ clear_bit(BTN_RIGHT, psmouse->dev.keybit);
- param[0] = 0;
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
- psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
- param[1] = 0;
- psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+ if (model_info)
+ ps2pp_set_model_properties(psmouse, model_info);
+ }
+ }
- return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0;
+ return protocol;
}
#ifndef _LOGIPS2PP_H
#define _LOGIPS2PP_H
-#define PS2PP_4BTN 0x01
-#define PS2PP_WHEEL 0x02
-#define PS2PP_MX 0x04
-#define PS2PP_MX310 0x08
-
-struct psmouse;
void ps2pp_process_packet(struct psmouse *psmouse);
void ps2pp_set_800dpi(struct psmouse *psmouse);
-int ps2pp_detect(struct psmouse *psmouse);
+int ps2pp_init(struct psmouse *psmouse, int set_properties);
+
#endif
module_param_named(smartscroll, psmouse_smartscroll, bool, 0);
MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
-unsigned int psmouse_resetafter;
+static unsigned int psmouse_resetafter;
module_param_named(resetafter, psmouse_resetafter, uint, 0);
-MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
__obsolete_setup("psmouse_noext");
__obsolete_setup("psmouse_resolution=");
static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
/*
- * psmouse_process_packet() analyzes the PS/2 mouse packet contents and
- * reports relevant events to the input module.
+ * psmouse_process_byte() analyzes the PS/2 data stream and reports
+ * relevant events to the input module once full packet has arrived.
*/
-static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
struct input_dev *dev = &psmouse->dev;
unsigned char *packet = psmouse->packet;
+ if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS))
+ return PSMOUSE_GOOD_DATA;
+
+/*
+ * Full packet accumulated, process it
+ */
+
input_regs(dev, regs);
/*
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
input_sync(dev);
+
+ return PSMOUSE_FULL_PACKET;
}
/*
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
struct psmouse *psmouse = serio->private;
+ psmouse_ret_t rc;
if (psmouse->state == PSMOUSE_IGNORE)
goto out;
if (psmouse->pktcnt == 2) {
if (psmouse->packet[1] == PSMOUSE_RET_ID) {
psmouse->state = PSMOUSE_IGNORE;
- serio_rescan(serio);
+ serio_reconnect(serio);
goto out;
}
if (psmouse->type == PSMOUSE_SYNAPTICS) {
}
}
- if (psmouse->type == PSMOUSE_SYNAPTICS) {
- /*
- * The synaptics driver has its own resync logic,
- * so it needs to receive all bytes one at a time.
- */
- synaptics_process_byte(psmouse, regs);
- goto out;
- }
+ rc = psmouse->protocol_handler(psmouse, regs);
- if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
- psmouse_process_packet(psmouse, regs);
- psmouse->pktcnt = 0;
- goto out;
+ switch (rc) {
+ case PSMOUSE_BAD_DATA:
+ printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
+ psmouse->name, psmouse->phys, psmouse->pktcnt);
+ psmouse->pktcnt = 0;
+
+ if (++psmouse->out_of_sync == psmouse_resetafter) {
+ psmouse->state = PSMOUSE_IGNORE;
+ printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
+ serio_reconnect(psmouse->serio);
+ }
+ break;
+
+ case PSMOUSE_FULL_PACKET:
+ psmouse->pktcnt = 0;
+ if (psmouse->out_of_sync) {
+ psmouse->out_of_sync = 0;
+ printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
+ psmouse->name, psmouse->phys);
+ }
+ break;
+
+ case PSMOUSE_GOOD_DATA:
+ break;
}
out:
return IRQ_HANDLED;
}
+/*
+ * psmouse_sliced_command() sends an extended PS/2 command to the mouse
+ * using sliced syntax, understood by advanced devices, such as Logitech
+ * or Synaptics touchpads. The command is encoded as:
+ * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
+ * is the command.
+ */
+int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
+{
+ int i;
+
+ if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
+ return -1;
+
+ for (i = 6; i >= 0; i -= 2) {
+ unsigned char d = (command >> i) & 3;
+ if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
+ return -1;
+ }
+
+ return 0;
+}
+
+
/*
* psmouse_reset() resets the mouse into power-on state.
*/
* the mouse may have.
*/
-static int psmouse_extensions(struct psmouse *psmouse)
+static int psmouse_extensions(struct psmouse *psmouse,
+ unsigned int max_proto, int set_properties)
{
int synaptics_hardware = 0;
- psmouse->vendor = "Generic";
- psmouse->name = "Mouse";
- psmouse->model = 0;
-
/*
* Try Synaptics TouchPad
*/
- if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
+ if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
synaptics_hardware = 1;
- psmouse->vendor = "Synaptics";
- psmouse->name = "TouchPad";
- if (psmouse_max_proto > PSMOUSE_IMEX) {
- if (synaptics_init(psmouse) == 0)
+ if (set_properties) {
+ psmouse->vendor = "Synaptics";
+ psmouse->name = "TouchPad";
+ }
+
+ if (max_proto > PSMOUSE_IMEX) {
+ if (!set_properties || synaptics_init(psmouse) == 0)
return PSMOUSE_SYNAPTICS;
/*
* Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
* Unfortunately Logitech/Genius probes confuse some firmware versions so
* we'll have to skip them.
*/
- psmouse_max_proto = PSMOUSE_IMEX;
+ max_proto = PSMOUSE_IMEX;
}
/*
* Make sure that touchpad is in relative mode, gestures (taps) are enabled
synaptics_reset(psmouse);
}
- if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
- set_bit(BTN_EXTRA, psmouse->dev.keybit);
- set_bit(BTN_SIDE, psmouse->dev.keybit);
- set_bit(REL_WHEEL, psmouse->dev.relbit);
+ if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
+
+ if (set_properties) {
+ set_bit(BTN_EXTRA, psmouse->dev.keybit);
+ set_bit(BTN_SIDE, psmouse->dev.keybit);
+ set_bit(REL_WHEEL, psmouse->dev.relbit);
+ psmouse->vendor = "Genius";
+ psmouse->name = "Wheel Mouse";
+ }
- psmouse->vendor = "Genius";
- psmouse->name = "Wheel Mouse";
return PSMOUSE_GENPS;
}
- if (psmouse_max_proto > PSMOUSE_IMEX) {
- int type = ps2pp_detect(psmouse);
- if (type)
+ if (max_proto > PSMOUSE_IMEX) {
+ int type = ps2pp_init(psmouse, set_properties);
+ if (type > PSMOUSE_PS2)
return type;
}
- if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
- set_bit(REL_WHEEL, psmouse->dev.relbit);
+ if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {
- if (psmouse_max_proto >= PSMOUSE_IMEX &&
- im_explorer_detect(psmouse)) {
+ if (set_properties) {
+ set_bit(REL_WHEEL, psmouse->dev.relbit);
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(BTN_EXTRA, psmouse->dev.keybit);
+ if (!psmouse->name)
+ psmouse->name = "Explorer Mouse";
+ }
+
+ return PSMOUSE_IMEX;
+ }
+
+ if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
- psmouse->name = "Explorer Mouse";
- return PSMOUSE_IMEX;
+ if (set_properties) {
+ set_bit(REL_WHEEL, psmouse->dev.relbit);
+ if (!psmouse->name)
+ psmouse->name = "Wheel Mouse";
}
- psmouse->name = "Wheel Mouse";
return PSMOUSE_IMPS;
}
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);
-/*
- * And here we try to determine if it has any extensions over the
- * basic PS/2 3-button mouse.
- */
-
- return psmouse->type = psmouse_extensions(psmouse);
+ return 0;
}
/*
psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-
psmouse->state = PSMOUSE_CMD_MODE;
psmouse->serio = serio;
psmouse->dev.private = psmouse;
return;
}
- if (psmouse_probe(psmouse) <= 0) {
+ if (psmouse_probe(psmouse) < 0) {
serio_close(serio);
kfree(psmouse);
serio->private = NULL;
return;
}
+ psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
+ if (!psmouse->vendor)
+ psmouse->vendor = "Generic";
+ if (!psmouse->name)
+ psmouse->name = "Mouse";
+ if (!psmouse->protocol_handler)
+ psmouse->protocol_handler = psmouse_process_byte;
+
sprintf(psmouse->devname, "%s %s %s",
psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
sprintf(psmouse->phys, "%s/input0",
{
struct psmouse *psmouse = serio->private;
struct serio_dev *dev = serio->dev;
- int old_type;
if (!dev || !psmouse) {
printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
return -1;
}
- old_type = psmouse->type;
-
psmouse->state = PSMOUSE_CMD_MODE;
- psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0;
+ psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
if (psmouse->reconnect) {
if (psmouse->reconnect(psmouse))
return -1;
- } else if (psmouse_probe(psmouse) != old_type)
+ } else if (psmouse_probe(psmouse) < 0 ||
+ psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
return -1;
/* ok, the device type (and capabilities) match the old one,
* we can continue using it, complete intialization
*/
- psmouse->type = old_type;
psmouse_initialize(psmouse);
if (psmouse->ptport) {
#define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2
+/* psmouse protocol handler return codes */
+typedef enum {
+ PSMOUSE_BAD_DATA,
+ PSMOUSE_GOOD_DATA,
+ PSMOUSE_FULL_PACKET
+} psmouse_ret_t;
+
struct psmouse;
struct psmouse_ptport {
unsigned char type;
unsigned char model;
unsigned long last;
+ unsigned long out_of_sync;
unsigned char state;
char acking;
volatile char ack;
char devname[64];
char phys[32];
+ psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse);
};
#define PSMOUSE_SYNAPTICS 7
int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
+int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
int psmouse_reset(struct psmouse *psmouse);
extern int psmouse_smartscroll;
extern unsigned int psmouse_rate;
-extern unsigned int psmouse_resetafter;
#endif /* _PSMOUSE_H */
* Synaptics communications functions
****************************************************************************/
-/*
- * Use the Synaptics extended ps/2 syntax to write a special command byte.
- * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
- * is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
- * and synaptics_mode_cmd)
- */
-static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command)
-{
- int i;
-
- if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
- return -1;
-
- for (i = 6; i >= 0; i -= 2) {
- unsigned char d = (command >> i) & 3;
- if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
- return -1;
- }
-
- return 0;
-}
-
/*
* Send a command to the synpatics touchpad by special commands
*/
static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
{
- if (synaptics_special_cmd(psmouse, c))
+ if (psmouse_sliced_command(psmouse, c))
return -1;
if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
return -1;
{
unsigned char param[1];
- if (synaptics_special_cmd(psmouse, mode))
+ if (psmouse_sliced_command(psmouse, mode))
return -1;
param[0] = SYN_PS_SET_MODE2;
if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
return -1;
- priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+ priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
priv->ext_cap = 0;
if (!SYN_CAP_VALID(priv->capabilities))
return -1;
- if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) {
+ /*
+ * Unless capExtended is set the rest of the flags should be ignored
+ */
+ if (!SYN_CAP_EXTENDED(priv->capabilities))
+ priv->capabilities = 0;
+
+ if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
printk(KERN_ERR "Synaptics claims to have extended capabilities,"
" but I'm not able to read them.");
- } else
- priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2];
+ } else {
+ priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
+
+ /*
+ * if nExtBtn is greater than 8 it should be considered
+ * invalid and treated as 0
+ */
+ if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
+ priv->ext_cap &= 0xff0fff;
+ }
}
return 0;
}
if (SYN_CAP_EXTENDED(priv->capabilities)) {
printk(KERN_INFO " Touchpad has extended capability bits\n");
- if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
- SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8)
+ if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
(int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
- else if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
+ if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+ printk(KERN_INFO " -> middle button\n");
+ if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
printk(KERN_INFO " -> four buttons\n");
if (SYN_CAP_MULTIFINGER(priv->capabilities))
printk(KERN_INFO " -> multifinger detection\n");
/*****************************************************************************
* Synaptics pass-through PS/2 port support
****************************************************************************/
-static int synaptics_pt_open(struct serio *port)
-{
- return 0;
-}
-
-static void synaptics_pt_close(struct serio *port)
-{
-}
-
static int synaptics_pt_write(struct serio *port, unsigned char c)
{
struct psmouse *parent = port->driver;
char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
- if (synaptics_special_cmd(parent, c))
+ if (psmouse_sliced_command(parent, c))
return -1;
if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
return -1;
port->serio.name = "Synaptics pass-through";
port->serio.phys = "synaptics-pt/serio0";
port->serio.write = synaptics_pt_write;
- port->serio.open = synaptics_pt_open;
- port->serio.close = synaptics_pt_close;
port->serio.driver = psmouse;
port->activate = synaptics_pt_activate;
}
-/*****************************************************************************
- * Driver initialization/cleanup functions
- ****************************************************************************/
-
-static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
-{
- dev->absmin[axis] = min;
- dev->absmax[axis] = max;
- dev->absfuzz[axis] = fuzz;
- dev->absflat[axis] = flat;
-
- set_bit(axis, dev->absbit);
-}
-
-static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
-{
- set_bit(EV_ABS, dev->evbit);
- set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
- set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
- set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
- set_bit(ABS_TOOL_WIDTH, dev->absbit);
-
- set_bit(EV_KEY, dev->evbit);
- set_bit(BTN_TOUCH, dev->keybit);
- set_bit(BTN_TOOL_FINGER, dev->keybit);
- set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
- set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
-
- set_bit(BTN_LEFT, dev->keybit);
- set_bit(BTN_RIGHT, dev->keybit);
- set_bit(BTN_FORWARD, dev->keybit);
- set_bit(BTN_BACK, dev->keybit);
- if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
- switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
- default:
- /*
- * if nExtBtn is greater than 8 it should be considered
- * invalid and treated as 0
- */
- break;
- case 8:
- set_bit(BTN_7, dev->keybit);
- set_bit(BTN_6, dev->keybit);
- case 6:
- set_bit(BTN_5, dev->keybit);
- set_bit(BTN_4, dev->keybit);
- case 4:
- set_bit(BTN_3, dev->keybit);
- set_bit(BTN_2, dev->keybit);
- case 2:
- set_bit(BTN_1, dev->keybit);
- set_bit(BTN_0, dev->keybit);
- break;
- }
- }
-
- clear_bit(EV_REL, dev->evbit);
- clear_bit(REL_X, dev->relbit);
- clear_bit(REL_Y, dev->relbit);
-}
-
-void synaptics_reset(struct psmouse *psmouse)
-{
- /* reset touchpad back to relative mode, gestures enabled */
- synaptics_mode_cmd(psmouse, 0);
-}
-
-static void synaptics_disconnect(struct psmouse *psmouse)
-{
- synaptics_reset(psmouse);
- kfree(psmouse->private);
-}
-
-static int synaptics_reconnect(struct psmouse *psmouse)
-{
- struct synaptics_data *priv = psmouse->private;
- struct synaptics_data old_priv = *priv;
-
- if (!synaptics_detect(psmouse))
- return -1;
-
- if (synaptics_query_hardware(psmouse)) {
- printk(KERN_ERR "Unable to query Synaptics hardware.\n");
- return -1;
- }
-
- if (old_priv.identity != priv->identity ||
- old_priv.model_id != priv->model_id ||
- old_priv.capabilities != priv->capabilities ||
- old_priv.ext_cap != priv->ext_cap)
- return -1;
-
- if (synaptics_set_mode(psmouse, 0)) {
- printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
- return -1;
- }
-
- return 0;
-}
-
-int synaptics_detect(struct psmouse *psmouse)
-{
- unsigned char param[4];
-
- param[0] = 0;
-
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
- psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
- psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
-
- return param[1] == 0x47;
-}
-
-int synaptics_init(struct psmouse *psmouse)
-{
- struct synaptics_data *priv;
-
- psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
- if (!priv)
- return -1;
- memset(priv, 0, sizeof(struct synaptics_data));
-
- if (synaptics_query_hardware(psmouse)) {
- printk(KERN_ERR "Unable to query Synaptics hardware.\n");
- goto init_fail;
- }
-
- if (synaptics_set_mode(psmouse, 0)) {
- printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
- goto init_fail;
- }
-
- priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
-
- if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
- synaptics_pt_create(psmouse);
-
- print_ident(priv);
- set_input_params(&psmouse->dev, priv);
-
- psmouse->disconnect = synaptics_disconnect;
- psmouse->reconnect = synaptics_reconnect;
-
- return 0;
-
- init_fail:
- kfree(priv);
- return -1;
-}
-
/*****************************************************************************
* Functions to interpret the absolute mode packets
****************************************************************************/
hw->left = (buf[0] & 0x01) ? 1 : 0;
hw->right = (buf[0] & 0x02) ? 1 : 0;
- if (SYN_CAP_EXTENDED(priv->capabilities) &&
- (SYN_CAP_FOUR_BUTTON(priv->capabilities))) {
- hw->up = ((buf[3] & 0x01)) ? 1 : 0;
- if (hw->left)
- hw->up = !hw->up;
- hw->down = ((buf[3] & 0x02)) ? 1 : 0;
- if (hw->right)
- hw->down = !hw->down;
+
+ if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+ hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+
+ if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+ hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+ hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
}
+
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
- ((buf[3] & 2) ? !hw->right : hw->right)) {
+ ((buf[0] ^ buf[3]) & 0x02)) {
switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
default:
/*
*/
break;
case 8:
- hw->b7 = ((buf[5] & 0x08)) ? 1 : 0;
- hw->b6 = ((buf[4] & 0x08)) ? 1 : 0;
+ hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
+ hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
case 6:
- hw->b5 = ((buf[5] & 0x04)) ? 1 : 0;
- hw->b4 = ((buf[4] & 0x04)) ? 1 : 0;
+ hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
+ hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
case 4:
- hw->b3 = ((buf[5] & 0x02)) ? 1 : 0;
- hw->b2 = ((buf[4] & 0x02)) ? 1 : 0;
+ hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
+ hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
case 2:
- hw->b1 = ((buf[5] & 0x01)) ? 1 : 0;
- hw->b0 = ((buf[4] & 0x01)) ? 1 : 0;
+ hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
+ hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
}
}
} else {
struct synaptics_hw_state hw;
int num_fingers;
int finger_width;
+ int i;
synaptics_parse_hw_state(psmouse->packet, priv, &hw);
input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
- input_report_key(dev, BTN_LEFT, hw.left);
- input_report_key(dev, BTN_RIGHT, hw.right);
- input_report_key(dev, BTN_FORWARD, hw.up);
- input_report_key(dev, BTN_BACK, hw.down);
- if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
- switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
- default:
- /*
- * if nExtBtn is greater than 8 it should be considered
- * invalid and treated as 0
- */
- break;
- case 8:
- input_report_key(dev, BTN_7, hw.b7);
- input_report_key(dev, BTN_6, hw.b6);
- case 6:
- input_report_key(dev, BTN_5, hw.b5);
- input_report_key(dev, BTN_4, hw.b4);
- case 4:
- input_report_key(dev, BTN_3, hw.b3);
- input_report_key(dev, BTN_2, hw.b2);
- case 2:
- input_report_key(dev, BTN_1, hw.b1);
- input_report_key(dev, BTN_0, hw.b0);
- break;
- }
+ input_report_key(dev, BTN_LEFT, hw.left);
+ input_report_key(dev, BTN_RIGHT, hw.right);
+
+ if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+ input_report_key(dev, BTN_MIDDLE, hw.middle);
+
+ if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+ input_report_key(dev, BTN_FORWARD, hw.up);
+ input_report_key(dev, BTN_BACK, hw.down);
+ }
+
+ for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
+ input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i));
+
input_sync(dev);
}
static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
+ if (idx < 0 || idx > 4)
+ return 0;
+
switch (pkt_type) {
case SYN_NEWABS:
case SYN_NEWABS_RELAXED:
return SYN_NEWABS_STRICT;
}
-void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{
struct input_dev *dev = &psmouse->dev;
struct synaptics_data *priv = psmouse->private;
input_regs(dev, regs);
if (psmouse->pktcnt >= 6) { /* Full packet received */
- if (priv->out_of_sync) {
- priv->out_of_sync = 0;
- printk(KERN_NOTICE "Synaptics driver resynced.\n");
- }
-
if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse);
synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
else
synaptics_process_packet(psmouse);
- psmouse->pktcnt = 0;
-
- } else if (psmouse->pktcnt &&
- !synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type)) {
- printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
- psmouse->pktcnt = 0;
- if (++priv->out_of_sync == psmouse_resetafter) {
- psmouse->state = PSMOUSE_IGNORE;
- printk(KERN_NOTICE "synaptics: issuing reconnect request\n");
- serio_reconnect(psmouse->serio);
- }
+
+ return PSMOUSE_FULL_PACKET;
+ }
+
+ return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ?
+ PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
+}
+
+/*****************************************************************************
+ * Driver initialization/cleanup functions
+ ****************************************************************************/
+static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
+{
+ int i;
+
+ set_bit(EV_ABS, dev->evbit);
+ input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
+ input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+ input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
+ set_bit(ABS_TOOL_WIDTH, dev->absbit);
+
+ set_bit(EV_KEY, dev->evbit);
+ set_bit(BTN_TOUCH, dev->keybit);
+ set_bit(BTN_TOOL_FINGER, dev->keybit);
+ set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
+ set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+
+ set_bit(BTN_LEFT, dev->keybit);
+ set_bit(BTN_RIGHT, dev->keybit);
+
+ if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
+ set_bit(BTN_MIDDLE, dev->keybit);
+
+ if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
+ set_bit(BTN_FORWARD, dev->keybit);
+ set_bit(BTN_BACK, dev->keybit);
+ }
+
+ for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
+ set_bit(BTN_0 + i, dev->keybit);
+
+ clear_bit(EV_REL, dev->evbit);
+ clear_bit(REL_X, dev->relbit);
+ clear_bit(REL_Y, dev->relbit);
+}
+
+void synaptics_reset(struct psmouse *psmouse)
+{
+ /* reset touchpad back to relative mode, gestures enabled */
+ synaptics_mode_cmd(psmouse, 0);
+}
+
+static void synaptics_disconnect(struct psmouse *psmouse)
+{
+ synaptics_reset(psmouse);
+ kfree(psmouse->private);
+}
+
+static int synaptics_reconnect(struct psmouse *psmouse)
+{
+ struct synaptics_data *priv = psmouse->private;
+ struct synaptics_data old_priv = *priv;
+
+ if (!synaptics_detect(psmouse))
+ return -1;
+
+ if (synaptics_query_hardware(psmouse)) {
+ printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+ return -1;
+ }
+
+ if (old_priv.identity != priv->identity ||
+ old_priv.model_id != priv->model_id ||
+ old_priv.capabilities != priv->capabilities ||
+ old_priv.ext_cap != priv->ext_cap)
+ return -1;
+
+ if (synaptics_set_mode(psmouse, 0)) {
+ printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int synaptics_detect(struct psmouse *psmouse)
+{
+ unsigned char param[4];
+
+ param[0] = 0;
+
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+ psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+
+ return param[1] == 0x47;
+}
+
+int synaptics_init(struct psmouse *psmouse)
+{
+ struct synaptics_data *priv;
+
+ psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
+ if (!priv)
+ return -1;
+ memset(priv, 0, sizeof(struct synaptics_data));
+
+ if (synaptics_query_hardware(psmouse)) {
+ printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+ goto init_fail;
+ }
+
+ if (synaptics_set_mode(psmouse, 0)) {
+ printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
+ goto init_fail;
}
+
+ priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
+
+ if (SYN_CAP_PASS_THROUGH(priv->capabilities))
+ synaptics_pt_create(psmouse);
+
+ print_ident(priv);
+ set_input_params(&psmouse->dev, priv);
+
+ psmouse->protocol_handler = synaptics_process_byte;
+ psmouse->disconnect = synaptics_disconnect;
+ psmouse->reconnect = synaptics_reconnect;
+
+ return 0;
+
+ init_fail:
+ kfree(priv);
+ return -1;
}
+
+
#ifndef _SYNAPTICS_H
#define _SYNAPTICS_H
-extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
extern int synaptics_detect(struct psmouse *psmouse);
extern int synaptics_init(struct psmouse *psmouse);
extern void synaptics_reset(struct psmouse *psmouse);
/* synaptics capability bits */
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
+#define SYN_CAP_MIDDLE_BUTTON(c) ((c) & (1 << 18))
#define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7))
#define SYN_CAP_SLEEP(c) ((c) & (1 << 4))
#define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3))
#define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1))
#define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0))
#define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
-#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1)
+#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20)
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
/* synaptics modes query bits */
int y;
int z;
int w;
- int left;
- int right;
- int up;
- int down;
- int b0;
- int b1;
- int b2;
- int b3;
- int b4;
- int b5;
- int b6;
- int b7;
+ unsigned int left:1;
+ unsigned int right:1;
+ unsigned int middle:1;
+ unsigned int up:1;
+ unsigned int down:1;
+ unsigned char ext_buttons;
};
struct synaptics_data {
unsigned long int identity; /* Identification */
/* Data for normal processing */
- unsigned int out_of_sync; /* # of packets out of sync */
int old_w; /* Previous w value */
unsigned char pkt_type; /* packet type - old, new, etc */
};
* Input driver to ExplorerPS/2 device driver module.
*
* Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2004 Dmitry Torokhov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published by
module_param(yres, uint, 0);
MODULE_PARM_DESC(yres, "Vertical screen resolution");
+struct mousedev_motion {
+ int dx, dy, dz;
+};
+
struct mousedev {
int exist;
int open;
int minor;
- int misc;
char name[16];
wait_queue_head_t wait;
struct list_head list;
struct input_handle handle;
+
+ struct mousedev_motion packet;
+ unsigned long buttons;
+ unsigned int pkt_count;
+ int old_x[4], old_y[4];
+ unsigned int touch;
};
struct mousedev_list {
struct mousedev *mousedev;
struct list_head node;
int dx, dy, dz;
- int old_x[4], old_y[4];
unsigned long buttons;
signed char ps2[6];
unsigned char ready, buffer, bufsiz;
unsigned char mode, imexseq, impsseq;
- unsigned int pkt_count;
- unsigned char touch;
};
#define MOUSEDEV_SEQ_LEN 6
static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
static struct mousedev mousedev_mix;
-#define fx(i) (list->old_x[(list->pkt_count - (i)) & 03])
-#define fy(i) (list->old_y[(list->pkt_count - (i)) & 03])
+#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
+#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
-static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
+static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
{
- int size;
- int touchpad;
+ if (mousedev->touch) {
+ switch (code) {
+ case ABS_X:
+ fx(0) = value;
+ if (mousedev->pkt_count >= 2)
+ mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
+ break;
- /* Ignore joysticks */
- if (test_bit(BTN_TRIGGER, handle->dev->keybit))
- return;
+ case ABS_Y:
+ fy(0) = value;
+ if (mousedev->pkt_count >= 2)
+ mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
+ break;
+ }
+ }
+}
- touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
+static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
+{
+ int size;
switch (code) {
case ABS_X:
- if (touchpad) {
- if (list->touch) {
- fx(0) = value;
- if (list->pkt_count >= 2)
- list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
- }
- } else {
- size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
- if (size == 0) size = xres;
- list->dx += (value * xres - list->old_x[0]) / size;
- list->old_x[0] += list->dx * size;
- }
+ size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+ if (size == 0) size = xres;
+ mousedev->packet.dx = (value * xres - mousedev->old_x[0]) / size;
+ mousedev->old_x[0] = mousedev->packet.dx * size;
break;
+
case ABS_Y:
- if (touchpad) {
- if (list->touch) {
- fy(0) = value;
- if (list->pkt_count >= 2)
- list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
- }
- } else {
- size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
- if (size == 0) size = yres;
- list->dy -= (value * yres - list->old_y[0]) / size;
- list->old_y[0] -= list->dy * size;
- }
+ size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
+ if (size == 0) size = yres;
+ mousedev->packet.dy = (value * yres - mousedev->old_y[0]) / size;
+ mousedev->old_y[0] = mousedev->packet.dy * size;
break;
}
}
-static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+ switch (code) {
+ case REL_X: mousedev->packet.dx += value; break;
+ case REL_Y: mousedev->packet.dy -= value; break;
+ case REL_WHEEL: mousedev->packet.dz -= value; break;
+ }
+}
+
+static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+ int index;
+
+ switch (code) {
+ case BTN_TOUCH:
+ case BTN_0:
+ case BTN_FORWARD:
+ case BTN_LEFT: index = 0; break;
+ case BTN_STYLUS:
+ case BTN_1:
+ case BTN_RIGHT: index = 1; break;
+ case BTN_2:
+ case BTN_STYLUS2:
+ case BTN_MIDDLE: index = 2; break;
+ case BTN_3:
+ case BTN_BACK:
+ case BTN_SIDE: index = 3; break;
+ case BTN_4:
+ case BTN_EXTRA: index = 4; break;
+ default: return;
+ }
+
+ if (value) {
+ set_bit(index, &mousedev->buttons);
+ set_bit(index, &mousedev_mix.buttons);
+ } else {
+ clear_bit(index, &mousedev->buttons);
+ clear_bit(index, &mousedev_mix.buttons);
+ }
+}
+
+static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
{
- struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL };
- struct mousedev **mousedev = mousedevs;
struct mousedev_list *list;
- int index, wake;
-
- while (*mousedev) {
-
- wake = 0;
-
- list_for_each_entry(list, &(*mousedev)->list, node)
- switch (type) {
- case EV_ABS:
- mousedev_abs_event(handle, list, code, value);
- break;
-
- case EV_REL:
- switch (code) {
- case REL_X: list->dx += value; break;
- case REL_Y: list->dy -= value; break;
- case REL_WHEEL: if (list->mode) list->dz -= value; break;
- }
- break;
-
- case EV_KEY:
- if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
- /* Handle touchpad data */
- list->touch = value;
- if (!list->touch)
- list->pkt_count = 0;
- break;
- }
-
- switch (code) {
- case BTN_TOUCH:
- case BTN_0:
- case BTN_FORWARD:
- case BTN_LEFT: index = 0; break;
- case BTN_4:
- case BTN_EXTRA: if (list->mode == 2) { index = 4; break; }
- case BTN_STYLUS:
- case BTN_1:
- case BTN_RIGHT: index = 1; break;
- case BTN_3:
- case BTN_BACK:
- case BTN_SIDE: if (list->mode == 2) { index = 3; break; }
- case BTN_2:
- case BTN_STYLUS2:
- case BTN_MIDDLE: index = 2; break;
- default: return;
- }
- switch (value) {
- case 0: clear_bit(index, &list->buttons); break;
- case 1: set_bit(index, &list->buttons); break;
- case 2: return;
- }
- break;
-
- case EV_SYN:
- switch (code) {
- case SYN_REPORT:
- if (list->touch) {
- list->pkt_count++;
- /* Input system eats duplicate events,
- * but we need all of them to do correct
- * averaging so apply present one forward
- */
- fx(0) = fx(1);
- fy(0) = fy(1);
- }
-
- list->ready = 1;
- kill_fasync(&list->fasync, SIGIO, POLL_IN);
- wake = 1;
- break;
- }
+
+ list_for_each_entry(list, &mousedev->list, node) {
+ list->dx += packet->dx;
+ list->dy += packet->dy;
+ list->dz += packet->dz;
+ list->buttons = mousedev->buttons;
+ list->ready = 1;
+ kill_fasync(&list->fasync, SIGIO, POLL_IN);
+ }
+
+ wake_up_interruptible(&mousedev->wait);
+}
+
+static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+{
+ struct mousedev *mousedev = handle->private;
+
+ switch (type) {
+ case EV_ABS:
+ /* Ignore joysticks */
+ if (test_bit(BTN_TRIGGER, handle->dev->keybit))
+ return;
+
+ if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+ mousedev_touchpad_event(mousedev, code, value);
+ else
+ mousedev_abs_event(handle->dev, mousedev, code, value);
+
+ break;
+
+ case EV_REL:
+ mousedev_rel_event(mousedev, code, value);
+ break;
+
+ case EV_KEY:
+ if (value != 2) {
+ if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
+ /* Handle touchpad data */
+ mousedev->touch = value;
+ if (!mousedev->touch)
+ mousedev->pkt_count = 0;
+ }
+ else
+ mousedev_key_event(mousedev, code, value);
}
+ break;
+
+ case EV_SYN:
+ if (code == SYN_REPORT) {
+ if (mousedev->touch) {
+ mousedev->pkt_count++;
+ /* Input system eats duplicate events, but we need all of them
+ * to do correct averaging so apply present one forward
+ */
+ fx(0) = fx(1);
+ fy(0) = fy(1);
+ }
- if (wake)
- wake_up_interruptible(&((*mousedev)->wait));
+ mousedev_notify_readers(mousedev, &mousedev->packet);
+ mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
- mousedev++;
+ memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
+ }
+ break;
}
}
mousedev_free(list->mousedev);
}
}
-
+
kfree(list);
return 0;
}
if (list->mousedev->minor == MOUSEDEV_MIX) {
list_for_each_entry(handle, &mousedev_handler.h_list, h_node) {
mousedev = handle->private;
- if (!mousedev->open && mousedev->exist)
+ if (!mousedev->open && mousedev->exist)
input_open_device(handle);
}
- } else
- if (!mousedev_mix.open && list->mousedev->exist)
+ } else
+ if (!mousedev_mix.open && list->mousedev->exist)
input_open_device(&list->mousedev->handle);
}
list->dz -= list->ps2[off + 3];
list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
list->bufsiz++;
+ } else {
+ list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
}
-
+
if (list->mode == 1) {
list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz));
list->dz -= list->ps2[off + 3];
list->impsseq = 0;
list->imexseq = 0;
list->mode = 0;
- list->ps2[0] = 0xaa;
- list->ps2[1] = 0x00;
- list->bufsiz = 2;
+ list->ps2[1] = 0xaa;
+ list->ps2[2] = 0x00;
+ list->bufsiz = 3;
break;
}
kill_fasync(&list->fasync, SIGIO, POLL_IN);
wake_up_interruptible(&list->mousedev->wait);
-
+
return count;
}
if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count))
return -EFAULT;
- return count;
+ return count;
}
/* No kernel lock - fine */
devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
- class_simple_device_add(input_class,
+ class_simple_device_add(input_class,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
dev->dev, "mouse%d", minor);
};
MODULE_DEVICE_TABLE(input, mousedev_ids);
-
+
static struct input_handler mousedev_handler = {
.event = mousedev_event,
.connect = mousedev_connect,
static struct miscdevice psaux_mouse = {
PSMOUSE_MINOR, "psaux", &mousedev_fops
};
+static int psaux_registered;
#endif
static int __init mousedev_init(void)
NULL, "mice");
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
- if (!(mousedev_mix.misc = !misc_register(&psaux_mouse)))
+ if (!(psaux_registered = !misc_register(&psaux_mouse)))
printk(KERN_WARNING "mice: could not misc_register the device\n");
#endif
static void __exit mousedev_exit(void)
{
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
- if (mousedev_mix.misc)
+ if (psaux_registered)
misc_deregister(&psaux_mouse);
#endif
devfs_remove("input/mice");
/*
* $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $
*
- * Copyright (c) 2001 "Crazy" James Simmons
+ * Copyright (c) 2001 "Crazy" James Simmons
*
* Input driver Power Management.
*
static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL);
-static void power_event(struct input_handle *handle, unsigned int type,
+static void power_event(struct input_handle *handle, unsigned int type,
unsigned int code, int down)
{
struct input_dev *dev = handle->dev;
case KEY_POWER:
/* Hum power down the machine. */
break;
- default:
+ default:
return;
}
} else {
/* This is risky. See pm.h for details. */
if (dev->state != PM_RESUME)
dev->state = PM_RESUME;
- else
- dev->state = PM_SUSPEND;
- pm_send(dev->pm_dev, dev->state, dev);
+ else
+ dev->state = PM_SUSPEND;
+ pm_send(dev->pm_dev, dev->state, dev);
break;
case KEY_POWER:
/* Turn the input device off completely ? */
return;
}
-static struct input_handle *power_connect(struct input_handler *handler,
- struct input_dev *dev,
+static struct input_handle *power_connect(struct input_handler *handler,
+ struct input_dev *dev,
struct input_device_id *id)
{
struct input_handle *handle;
if (!test_bit(EV_KEY, dev->evbit) || !test_bit(EV_PWR, dev->evbit))
- return NULL;
+ return NULL;
if (!test_bit(KEY_SUSPEND, dev->keybit) || (!test_bit(KEY_POWER, dev->keybit)))
return NULL;
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) },
.keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) }
- },
+ },
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) },
.keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) }
- },
+ },
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_PWR) },
- },
+ },
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(input, power_ids);
-
+
static struct input_handler power_handler = {
.event = power_event,
.connect = power_connect,
MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
MODULE_DESCRIPTION("Input Power Management driver");
+MODULE_LICENSE("GPL");
tristate "Intel SA1111 keyboard controller"
depends on SA1111 && SERIO
-config SERIO_98KBD
- tristate "NEC PC-9800 keyboard controller"
- depends on X86_PC9800 && SERIO
- help
- Say Y here if you have the NEC PC-9801/PC-9821 and want to use its
- standard keyboard connected to its keyboard controller.
-
- To compile this driver as a module, choose M here: the
- module will be called 98kbd-io.
-
config SERIO_GSCPS2
tristate "HP GSC PS/2 keyboard and PS/2 mouse controller"
depends on GSC && SERIO
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/slab.h>
+#include <linux/err.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware/amba.h>
#include <asm/hardware/amba_kmi.h>
+#include <asm/hardware/clock.h>
#define KMI_BASE (kmi->base)
struct amba_kmi_port {
struct serio io;
- struct amba_kmi_port *next;
+ struct clk *clk;
unsigned char *base;
unsigned int irq;
unsigned int divisor;
static int amba_kmi_open(struct serio *io)
{
struct amba_kmi_port *kmi = io->driver;
+ unsigned int divisor;
int ret;
- writeb(kmi->divisor, KMICLKDIV);
+ ret = clk_use(kmi->clk);
+ if (ret)
+ goto out;
+
+ ret = clk_enable(kmi->clk);
+ if (ret)
+ goto clk_unuse;
+
+ divisor = clk_get_rate(kmi->clk) / 8000000 - 1;
+ writeb(divisor, KMICLKDIV);
writeb(KMICR_EN, KMICR);
ret = request_irq(kmi->irq, amba_kmi_int, 0, "kmi-pl050", kmi);
if (ret) {
printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
writeb(0, KMICR);
- return ret;
+ goto clk_disable;
}
writeb(KMICR_EN | KMICR_RXINTREN, KMICR);
return 0;
+
+ clk_disable:
+ clk_disable(kmi->clk);
+ clk_unuse:
+ clk_unuse(kmi->clk);
+ out:
+ return ret;
}
static void amba_kmi_close(struct serio *io)
writeb(0, KMICR);
free_irq(kmi->irq, kmi);
+ clk_disable(kmi->clk);
+ clk_unuse(kmi->clk);
}
static int amba_kmi_probe(struct amba_device *dev, void *id)
goto out;
}
- kmi->irq = dev->irq[0];
- kmi->divisor = 24 / 8 - 1;
+ kmi->clk = clk_get(&dev->dev, "KMIREFCLK");
+ if (IS_ERR(kmi->clk)) {
+ ret = PTR_ERR(kmi->clk);
+ goto unmap;
+ }
+ kmi->irq = dev->irq[0];
amba_set_drvdata(dev, kmi);
serio_register_port(&kmi->io);
return 0;
+ unmap:
+ iounmap(kmi->base);
out:
kfree(kmi);
amba_release_regions(dev);
amba_set_drvdata(dev, NULL);
serio_unregister_port(&kmi->io);
+ clk_put(kmi->clk);
iounmap(kmi->base);
kfree(kmi);
amba_release_regions(dev);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
- *
+ *
* TODO:
* - Dino testing (did HP ever shipped a machine on which this port
* was usable/enabled ?)
#define PFX "gscps2.c: "
-/*
+/*
* Driver constants
*/
/**
* gscps2_interrupt() - Interruption service routine
*
- * This function reads received PS/2 bytes and processes them on
+ * This function reads received PS/2 bytes and processes them on
* all interfaces.
* The problematic part here is, that the keyboard and mouse PS/2 port
* share the same interrupt and it's not possible to send data if any
unsigned long flags;
spin_lock_irqsave(&ps2port->lock, flags);
- while ( (ps2port->buffer[ps2port->append].str =
+ while ( (ps2port->buffer[ps2port->append].str =
gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
- ps2port->buffer[ps2port->append].data =
+ ps2port->buffer[ps2port->append].data =
gscps2_readb_input(ps2port->addr);
ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
}
if (!dev->irq)
return -ENODEV;
-
+
/* Offset for DINO PS/2. Works with LASI even */
if (dev->id.sversion == 0x96)
hpa += GSC_DINO_OFFSET;
gscps2_reset(ps2port);
ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f;
snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s",
- gscps2_serio_port.name,
+ gscps2_serio_port.name,
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
ps2port->port.phys);
serio_register_port(&ps2port->port);
-
+
return 0;
-
+
fail:
free_irq(dev->irq, ps2port);
list_del(&ps2port->node);
iounmap(ps2port->addr);
#if 0
- release_mem_region(dev->hpa, GSC_STATUS + 4);
+ release_mem_region(dev->hpa, GSC_STATUS + 4);
#endif
dev_set_drvdata(&dev->dev, NULL);
kfree(ps2port);
static struct parisc_device_id gscps2_device_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
#ifdef DINO_TESTED
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
#endif
{ 0, } /* 0 terminated list */
};
*/
static int i8042_command(unsigned char *param, int command)
-{
+{
unsigned long flags;
int retval = 0, i = 0;
dbg("%02x -> i8042 (command)", command & 0xff);
i8042_write_command(command & 0xff);
}
-
+
if (!retval)
for (i = 0; i < ((command >> 12) & 0xf); i++) {
if ((retval = i8042_wait_write())) break;
if (!retval)
for (i = 0; i < ((command >> 8) & 0xf); i++) {
if ((retval = i8042_wait_read())) break;
- if (i8042_read_status() & I8042_STR_AUXDATA)
+ if (i8042_read_status() & I8042_STR_AUXDATA)
param[i] = ~i8042_read_data();
else
param[i] = i8042_read_data();
} else dfl = 0;
dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
- data, (str >> 6), irq,
+ data, (str >> 6), irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
-
+
goto irq_ret;
}
dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
- data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
+ data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa9)
return -1;
param = 0xa4;
- if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == 0x5b)
+ if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == 0x5b) {
+
+/*
+ * Do another loop test with the 0x5a value. Doing anything else upsets
+ * Profusion/ServerWorks OSB4 chipsets.
+ */
+
+ param = 0x5a;
+ i8042_command(¶m, I8042_CMD_AUX_LOOP);
return -1;
+ }
if (mux_version)
*mux_version = ~param;
if (i8042_enable_mux_mode(values, &mux_version))
return -1;
-
+
/* Workaround for broken chips which seem to support MUX, but in reality don't. */
- /* They all report version 12.10 */
- if (mux_version == 0xCA)
+ /* They all report version 10.12 */
+ if (mux_version == 0xAC)
return -1;
printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
/*
* Bit assignment test - filters out PS/2 i8042's in AT mode
*/
-
+
if (i8042_command(¶m, I8042_CMD_AUX_DISABLE))
return -1;
if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
if (i8042_command(¶m, I8042_CMD_AUX_ENABLE))
return -1;
if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
- return -1;
+ return -1;
/*
* Disable the interface.
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
values->exists = 0;
- return -1;
+ return -1;
}
printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
- if (code==SYS_DOWN || code==SYS_HALT)
+ if (code == SYS_DOWN || code == SYS_HALT)
i8042_controller_cleanup();
return NOTIFY_DONE;
}
sysdev_class_unregister(&kbc_sysclass);
}
- del_timer_sync(&i8042_timer);
-
i8042_controller_cleanup();
-
+
if (i8042_kbd_values.exists)
serio_unregister_port(&i8042_kbd_port);
if (i8042_aux_values.exists)
serio_unregister_port(&i8042_aux_port);
-
+
for (i = 0; i < 4; i++)
if (i8042_mux_values[i].exists)
serio_unregister_port(i8042_mux_port + i);
+ del_timer_sync(&i8042_timer);
i8042_platform_exit();
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
return 0;
}
-static int parkbd_open(struct serio *port)
-{
- return 0;
-}
-
-static void parkbd_close(struct serio *port)
-{
-}
-
static struct serio parkbd_port =
{
.write = parkbd_write,
- .open = parkbd_open,
- .close = parkbd_close,
.name = parkbd_name,
.phys = parkbd_phys,
};
parkbd_writing = 0;
parkbd_writelines(3);
return;
- }
+ }
parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2);
if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) {
parkbd_counter = 0;
parkbd_buffer = 0;
- }
+ }
parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* Based on the work of:
- * Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>
+ * Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>
*/
/*
MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
MODULE_LICENSE("GPL");
-
-static int q40kbd_open(struct serio *port)
-{
- return 0;
-}
-static void q40kbd_close(struct serio *port)
-{
-}
-
static struct serio q40kbd_port =
{
.type = SERIO_8042,
.name = "Q40 kbd port",
.phys = "Q40",
.write = NULL,
- .open = q40kbd_open,
- .close = q40kbd_close,
};
static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
static void rpckbd_close(struct serio *port)
{
free_irq(IRQ_KEYBOARDRX, port);
- free_irq(IRQ_KEYBOARDTX, port);
+ free_irq(IRQ_KEYBOARDTX, port);
}
static struct serio rpckbd_port =
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
struct serio_event *event;
list_for_each_safe(node, next, &serio_event_list) {
- event = container_of(node, struct serio_event, node);
+ event = container_of(node, struct serio_event, node);
down(&serio_sem);
if (event->serio == NULL)
do {
serio_handle_events();
- wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
+ wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
if (current->flags & PF_FREEZE)
refrigerator(PF_FREEZE);
} while (!signal_pending(current));
int serio_open(struct serio *serio, struct serio_dev *dev)
{
serio->dev = dev;
- if (serio->open(serio)) {
+ if (serio->open && serio->open(serio)) {
serio->dev = NULL;
return -1;
}
/* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio)
{
- serio->close(serio);
+ if (serio->close)
+ serio->close(serio);
serio->dev = NULL;
}
return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
}
-static int serport_serio_open(struct serio *serio)
-{
- return 0;
-}
-
static void serport_serio_close(struct serio *serio)
{
struct serport *serport = serio->driver;
serport->serio.type = SERIO_RS232;
serport->serio.write = serport_serio_write;
- serport->serio.open = serport_serio_open;
serport->serio.close = serport_serio_close;
serport->serio.driver = serport;
}
/*
- * serport_ldisc_read() just waits indefinitely if everything goes well.
+ * serport_ldisc_read() just waits indefinitely if everything goes well.
* However, when the serio driver closes the serio port, it finishes,
* returning 0 characters.
*/
static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
{
struct serport *serport = (struct serport*) tty->disc_data;
-
+
if (cmd == SPIOCSTYPE)
return get_user(serport->serio.type, (unsigned long __user *) arg);
memset(gunze, 0, sizeof(struct gunze));
init_input_dev(&gunze->dev);
- gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
- gunze->dev.absmin[ABS_X] = 96; gunze->dev.absmin[ABS_Y] = 72;
- gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000;
+ input_set_abs_params(&gunze->dev, ABS_X, 96, 4000, 0, 0);
+ input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0);
gunze->serio = serio;
serio->private = gunze;
/*
* $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
*
- * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
+ * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
*
- * Sponsored by Transvirtual Technology.
- *
- * Derived from the code in h3600_ts.[ch] by Charles Flynn
+ * Sponsored by Transvirtual Technology.
+ *
+ * Derived from the code in h3600_ts.[ch] by Charles Flynn
*/
/*
#include <asm/arch/hardware.h>
#include <asm/arch/irqs.h>
+MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
+MODULE_DESCRIPTION("H3600 touchscreen driver");
+MODULE_LICENSE("GPL");
+
/*
* Definitions & global arrays.
*/
#define MAX_ID 14
#define H3600_MAX_LENGTH 16
-#define H3600_KEY 0xf
+#define H3600_KEY 0xf
#define H3600_SCANCODE_RECORD 1 /* 1 -> record button */
#define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */
char phys[32];
};
-static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
{
int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
struct input_dev *dev = (struct input_dev *) dev_id;
input_regs(dev, regs);
input_report_key(dev, KEY_ENTER, down);
input_sync(dev);
+
+ return IRQ_HANDLED;
}
-static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
{
int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
struct input_dev *dev = (struct input_dev *) dev_id;
- /*
- * This interrupt is only called when we release the key. So we have
+ /*
+ * This interrupt is only called when we release the key. So we have
* to fake a key press.
- */
+ */
input_regs(dev, regs);
input_report_key(dev, KEY_SUSPEND, 1);
- input_report_key(dev, KEY_SUSPEND, down);
+ input_report_key(dev, KEY_SUSPEND, down);
input_sync(dev);
+
+ return IRQ_HANDLED;
}
#ifdef CONFIG_PM
* h3600_flite_power: enables or disables power to frontlight, using last bright */
unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
{
- unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness);
+ unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness;
struct h3600_dev *ts = dev->private;
- /* Must be in this order */
+ /* Must be in this order */
ts->serio->write(ts->serio, 1);
ts->serio->write(ts->serio, pwr);
- ts->serio->write(ts->serio, brightness);
+ ts->serio->write(ts->serio, brightness);
return 0;
}
static int suspended = 0;
-static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
+static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
void *data)
{
- struct input_dev *dev = (struct input_dev *) data;
+ struct input_dev *dev = (struct input_dev *) data;
switch (req) {
case PM_SUSPEND: /* enter D1-D3 */
/*
* This function translates the native event packets to linux input event
* packets. Some packets coming from serial are not touchscreen related. In
- * this case we send them off to be processed elsewhere.
+ * this case we send them off to be processed elsewhere.
*/
static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
{
Note: This is true for non interrupt generated key events.
*/
case KEYBD_ID:
- down = (ts->buf[0] & 0x80) ? 0 : 1;
+ down = (ts->buf[0] & 0x80) ? 0 : 1;
switch (ts->buf[0] & 0x7f) {
case H3600_SCANCODE_RECORD:
case H3600_SCANCODE_CONTACTS:
key = KEY_PROG2;
break;
- case H3600_SCANCODE_Q:
+ case H3600_SCANCODE_Q:
key = KEY_Q;
break;
case H3600_SCANCODE_START:
key = KEY_DOWN;
break;
default:
- key = 0;
- }
- if (key)
+ key = 0;
+ }
+ if (key)
input_report_key(dev, key, down);
break;
/*
* byte 0 1 2 3
*/
case TOUCHS_ID:
- if (!touched) {
+ if (!touched) {
input_report_key(dev, BTN_TOUCH, 1);
touched = 1;
- }
+ }
if (ts->len) {
- unsigned short x, y;
+ unsigned short x, y;
x = ts->buf[0]; x <<= 8; x += ts->buf[1];
y = ts->buf[2]; y <<= 8; y += ts->buf[3];
} else {
input_report_key(dev, BTN_TOUCH, 0);
touched = 0;
- }
+ }
break;
default:
/* Send a non input event elsewhere */
/*
* h3600ts_event() handles events from the input module.
*/
-static int h3600ts_event(struct input_dev *dev, unsigned int type,
+static int h3600ts_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
struct h3600_dev *ts = dev->private;
// ts->serio->write(ts->serio, SOME_CMD);
return 0;
}
- }
+ }
return -1;
}
#define STATE_DATA 2 /* state where we decode data */
#define STATE_EOF 3 /* state where we decode checksum or EOF */
-static void h3600ts_interrupt(struct serio *serio, unsigned char data,
- unsigned int flags)
+static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
+ unsigned int flags, struct pt_regs *regs)
{
struct h3600_dev *ts = serio->private;
/*
- * We have a new frame coming in.
+ * We have a new frame coming in.
*/
switch (state) {
case STATE_SOF:
if (data == CHAR_SOF)
- state = STATE_ID;
- return;
+ state = STATE_ID;
+ break;
case STATE_ID:
ts->event = (data & 0xf0) >> 4;
ts->len = (data & 0xf);
break;
}
ts->chksum = data;
- state=(ts->len > 0 ) ? STATE_DATA : STATE_EOF;
+ state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
break;
case STATE_DATA:
ts->chksum += data;
ts->buf[ts->idx]= data;
- if(++ts->idx == ts->len)
+ if(++ts->idx == ts->len)
state = STATE_EOF;
break;
case STATE_EOF:
state = STATE_SOF;
- if (data == CHAR_EOF || data == ts->chksum )
- h3600ts_process_packet(ts);
+ if (data == CHAR_EOF || data == ts->chksum)
+ h3600ts_process_packet(ts, regs);
break;
default:
printk("Error3\n");
break;
}
+
+ return IRQ_HANDLED;
}
/*
init_input_dev(&ts->dev);
/* Device specific stuff */
- set_GPIO_IRQ_edge( GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES );
- set_GPIO_IRQ_edge( GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE );
+ set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
+ set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
- SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
+ SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_action", &ts->dev)) {
printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
kfree(ts);
}
if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
- SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
+ SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_suspend", &ts->dev)) {
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
kfree(ts);
return;
}
+
/* Now we have things going we setup our input device */
ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
- ts->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- ts->dev.ledbit[0] = BIT(LED_SLEEP);
-
- ts->dev.absmin[ABS_X] = 60; ts->dev.absmin[ABS_Y] = 35;
- ts->dev.absmax[ABS_X] = 985; ts->dev.absmax[ABS_Y] = 1024;
- ts->dev.absfuzz[ABS_X] = 0; ts->dev.absfuzz[ABS_Y] = 0;
-
- ts->serio = serio;
- serio->private = ts;
+ ts->dev.ledbit[0] = BIT(LED_SLEEP);
+ input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
+ input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
set_bit(KEY_RECORD, ts->dev.keybit);
set_bit(KEY_Q, ts->dev.keybit);
ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
+ ts->serio = serio;
+ serio->private = ts;
+
sprintf(ts->phys, "%s/input0", serio->phys);
ts->dev.event = h3600ts_event;
//h3600_flite_control(1, 25); /* default brightness */
#ifdef CONFIG_PM
- ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
+ ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
h3600ts_pm_callback);
printk("registered pm callback\n");
#endif
static void h3600ts_disconnect(struct serio *serio)
{
struct h3600_dev *ts = serio->private;
-
+
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
input_unregister_device(&ts->dev);
return 0;
}
-static ssize_t tsdev_read(struct file *file, char *buffer, size_t count,
+static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count,
loff_t * ppos)
{
struct tsdev_list *list = file->private_data;
cs->hw.njet.ctrl_reg = 0xff; /* Reset On */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
mdelay(10);
- cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
/* now edge triggered for TJ320 GE 13/07/00 */
/* see comment in IRQ function */
+ if (cs->subtyp) /* TJ320 */
+ cs->hw.njet.ctrl_reg = 0x40; /* Reset Off and status read clear */
+ else
+ cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */
byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
mdelay(10);
cs->hw.njet.auxd = 0;
int __init
setup_netjet_s(struct IsdnCard *card)
{
- int bytecnt;
+ int bytecnt,cfg;
struct IsdnCardState *cs = card->cs;
char tmp[64];
printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n");
return(0);
}
+ /* the TJ300 and TJ320 must be detected, the IRQ handling is different
+ * unfortunatly the chips use the same device ID, but the TJ320 has
+ * the bit20 in status PCI cfg register set
+ */
+ pci_read_config_dword(dev_netjet, 0x04, &cfg);
+ if (cfg & 0x00100000)
+ cs->subtyp = 1; /* TJ320 */
+ else
+ cs->subtyp = 0; /* TJ300 */
/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */
if ((dev_netjet->subsystem_vendor == 0x55) &&
(dev_netjet->subsystem_device == 0x02)) {
bytecnt = 256;
printk(KERN_INFO
- "NETjet-S: PCI card configured at %#lx IRQ %d\n",
- cs->hw.njet.base, cs->irq);
+ "NETjet-S: %s card configured at %#lx IRQ %d\n",
+ cs->subtyp ? "TJ320" : "TJ300", cs->hw.njet.base, cs->irq);
if (!request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn")) {
printk(KERN_WARNING
"HiSax: %s config port %#lx-%#lx already in use\n",
* Begin of a CAPI like LL<->HL interface, currently used only for
* supplementary service (CAPI 2.0 part III)
*/
-#include <linux/isdn//capicmd.h>
+#include <linux/isdn/capicmd.h>
int
isdn_capi_rec_hl_msg(capi_msg *cm) {
If unsure, say N.
+config DM_SNAPSHOT
+ tristate "Snapshot target (EXPERIMENTAL)"
+ depends on BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ Allow volume managers to take writeable snapshots of a device.
+
+config DM_MIRROR
+ tristate "Mirror target (EXPERIMENTAL)"
+ depends on BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ Allow volume managers to mirror logical volumes, also
+ needed for live data migration tools such as 'pvmove'.
+
+config DM_ZERO
+ tristate "Zero target (EXPERIMENTAL)"
+ depends on BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ A target that discards writes, and returns all zeroes for
+ reads. Useful in some recovery situations.
+
endmenu
#
dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
- dm-ioctl.o
+ dm-ioctl.o dm-io.o kcopyd.o
+dm-snapshot-objs := dm-snap.o dm-exception-store.o
+dm-mirror-objs := dm-log.o dm-raid1.o
raid6-objs := raid6main.o raid6algos.o raid6recov.o raid6tables.o \
raid6int1.o raid6int2.o raid6int4.o \
raid6int8.o raid6int16.o raid6int32.o \
raid6mmx.o raid6sse1.o raid6sse2.o
host-progs := mktables
+CFLAGS_raid6int8.o += -O2
+
# Note: link order is important. All raid personalities
# and xor.o must come before md.o, as they each initialise
# themselves, and md.o may use the personalities when it
obj-$(CONFIG_BLK_DEV_MD) += md.o
obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o
obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
+obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o
+obj-$(CONFIG_DM_MIRROR) += dm-mirror.o
+obj-$(CONFIG_DM_ZERO) += dm-zero.o
quiet_cmd_unroll = UNROLL $@
cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
return 0;
}
-static void list_version_get_needed(struct target_type *tt, void *param)
+static void list_version_get_needed(struct target_type *tt, void *needed_param)
{
- int *needed = param;
+ size_t *needed = needed_param;
*needed += strlen(tt->name);
*needed += sizeof(tt->version);
* As well as checking the version compatibility this always
* copies the kernel interface version out.
*/
-static int check_version(unsigned int cmd, struct dm_ioctl *user)
+static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
{
uint32_t version[3];
int r = 0;
vfree(param);
}
-static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param)
+static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
{
struct dm_ioctl tmp, *dmi;
int r = 0;
unsigned int cmd;
struct dm_ioctl *param;
- struct dm_ioctl *user = (struct dm_ioctl *) u;
+ struct dm_ioctl __user *user = (struct dm_ioctl __user *) u;
ioctl_fn fn = NULL;
size_t param_size;
struct dm_dev dd_copy;
dev_t dev = dd->bdev->bd_dev;
- memcpy(&dd_copy, dd, sizeof(dd_copy));
+ dd_copy = *dd;
dd->mode |= new_mode;
dd->bdev = NULL;
if (!r)
close_dev(&dd_copy);
else
- memcpy(dd, &dd_copy, sizeof(dd_copy));
+ *dd = dd_copy;
return r;
}
struct bio_vec *bv = bio->bi_io_vec + idx;
clone = bio_alloc(GFP_NOIO, 1);
- memcpy(clone->bi_io_vec, bv, sizeof(*bv));
+ *clone->bi_io_vec = *bv;
clone->bi_sector = sector;
clone->bi_bdev = bio->bi_bdev;
}
-static int get_version(void * arg)
+static int get_version(void __user * arg)
{
mdu_version_t ver;
return 0;
}
-static int get_array_info(mddev_t * mddev, void * arg)
+static int get_array_info(mddev_t * mddev, void __user * arg)
{
mdu_array_info_t info;
int nr,working,active,failed,spare;
return 0;
}
-static int get_disk_info(mddev_t * mddev, void * arg)
+static int get_disk_info(mddev_t * mddev, void __user * arg)
{
mdu_disk_info_t info;
unsigned int nr;
return -EINVAL;
}
- rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
+ if (mddev->persistent)
+ rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
+ else
+ rdev->sb_offset =
+ rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
+
size = calc_dev_size(rdev, mddev->chunk_size);
rdev->size = size;
return 0;
}
+/*
+ * update_array_info is used to change the configuration of an
+ * on-line array.
+ * The version, ctime,level,size,raid_disks,not_persistent, layout,chunk_size
+ * fields in the info are checked against the array.
+ * Any differences that cannot be handled will cause an error.
+ * Normally, only one change can be managed at a time.
+ */
+static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
+{
+ int rv = 0;
+ int cnt = 0;
+
+ if (mddev->major_version != info->major_version ||
+ mddev->minor_version != info->minor_version ||
+/* mddev->patch_version != info->patch_version || */
+ mddev->ctime != info->ctime ||
+ mddev->level != info->level ||
+ mddev->layout != info->layout ||
+ !mddev->persistent != info->not_persistent||
+ mddev->chunk_size != info->chunk_size )
+ return -EINVAL;
+ /* Check there is only one change */
+ if (mddev->size != info->size) cnt++;
+ if (mddev->raid_disks != info->raid_disks) cnt++;
+ if (cnt == 0) return 0;
+ if (cnt > 1) return -EINVAL;
+
+ if (mddev->size != info->size) {
+ mdk_rdev_t * rdev;
+ struct list_head *tmp;
+ if (mddev->pers->resize == NULL)
+ return -EINVAL;
+ /* The "size" is the amount of each device that is used.
+ * This can only make sense for arrays with redundancy.
+ * linear and raid0 always use whatever space is available
+ * We can only consider changing the size of no resync
+ * or reconstruction is happening, and if the new size
+ * is acceptable. It must fit before the sb_offset or,
+ * if that is <data_offset, it must fit before the
+ * size of each device.
+ * If size is zero, we find the largest size that fits.
+ */
+ if (mddev->sync_thread)
+ return -EBUSY;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ sector_t avail;
+ int fit = (info->size == 0);
+ if (rdev->sb_offset > rdev->data_offset)
+ avail = (rdev->sb_offset*2) - rdev->data_offset;
+ else
+ avail = get_capacity(rdev->bdev->bd_disk)
+ - rdev->data_offset;
+ if (fit && (info->size == 0 || info->size > avail/2))
+ info->size = avail/2;
+ if (avail < ((sector_t)info->size << 1))
+ return -ENOSPC;
+ }
+ rv = mddev->pers->resize(mddev, (sector_t)info->size *2);
+ if (!rv) {
+ struct block_device *bdev;
+
+ bdev = bdget_disk(mddev->gendisk, 0);
+ if (bdev) {
+ down(&bdev->bd_inode->i_sem);
+ i_size_write(bdev->bd_inode, mddev->array_size << 10);
+ up(&bdev->bd_inode->i_sem);
+ bdput(bdev);
+ }
+ }
+ }
+ if (mddev->raid_disks != info->raid_disks) {
+ /* change the number of raid disks */
+ if (mddev->pers->reshape == NULL)
+ return -EINVAL;
+ if (info->raid_disks <= 0 ||
+ info->raid_disks >= mddev->max_disks)
+ return -EINVAL;
+ if (mddev->sync_thread)
+ return -EBUSY;
+ rv = mddev->pers->reshape(mddev, info->raid_disks);
+ if (!rv) {
+ struct block_device *bdev;
+
+ bdev = bdget_disk(mddev->gendisk, 0);
+ if (bdev) {
+ down(&bdev->bd_inode->i_sem);
+ i_size_write(bdev->bd_inode, mddev->array_size << 10);
+ up(&bdev->bd_inode->i_sem);
+ bdput(bdev);
+ }
+ }
+ }
+ md_update_sb(mddev);
+ return rv;
+}
+
static int set_disk_faulty(mddev_t *mddev, dev_t dev)
{
mdk_rdev_t *rdev;
{
char b[BDEVNAME_SIZE];
int err = 0;
- struct hd_geometry *loc = (struct hd_geometry *) arg;
+ void __user *argp = (void __user *)arg;
+ struct hd_geometry __user *loc = argp;
mddev_t *mddev = NULL;
if (!capable(CAP_SYS_ADMIN))
switch (cmd)
{
case RAID_VERSION:
- err = get_version((void *)arg);
+ err = get_version(argp);
goto done;
case PRINT_RAID_DEBUG:
switch (cmd)
{
case SET_ARRAY_INFO:
-
- if (!list_empty(&mddev->disks)) {
- printk(KERN_WARNING
- "md: array %s already has disks!\n",
- mdname(mddev));
- err = -EBUSY;
- goto abort_unlock;
- }
- if (mddev->raid_disks) {
- printk(KERN_WARNING
- "md: array %s already initialised!\n",
- mdname(mddev));
- err = -EBUSY;
- goto abort_unlock;
- }
{
mdu_array_info_t info;
if (!arg)
memset(&info, 0, sizeof(info));
- else if (copy_from_user(&info, (void*)arg, sizeof(info))) {
+ else if (copy_from_user(&info, argp, sizeof(info))) {
err = -EFAULT;
goto abort_unlock;
}
+ if (mddev->pers) {
+ err = update_array_info(mddev, &info);
+ if (err) {
+ printk(KERN_WARNING "md: couldn't update"
+ " array info. %d\n", err);
+ goto abort_unlock;
+ }
+ goto done_unlock;
+ }
+ if (!list_empty(&mddev->disks)) {
+ printk(KERN_WARNING
+ "md: array %s already has disks!\n",
+ mdname(mddev));
+ err = -EBUSY;
+ goto abort_unlock;
+ }
+ if (mddev->raid_disks) {
+ printk(KERN_WARNING
+ "md: array %s already initialised!\n",
+ mdname(mddev));
+ err = -EBUSY;
+ goto abort_unlock;
+ }
err = set_array_info(mddev, &info);
if (err) {
printk(KERN_WARNING "md: couldn't set"
- " array info. %d\n", err);
+ " array info. %d\n", err);
goto abort_unlock;
}
}
switch (cmd)
{
case GET_ARRAY_INFO:
- err = get_array_info(mddev, (void *)arg);
+ err = get_array_info(mddev, argp);
goto done_unlock;
case GET_DISK_INFO:
- err = get_disk_info(mddev, (void *)arg);
+ err = get_disk_info(mddev, argp);
goto done_unlock;
case RESTART_ARRAY_RW:
err = -EINVAL;
goto abort_unlock;
}
- err = put_user (2, (char *) &loc->heads);
+ err = put_user (2, (char __user *) &loc->heads);
if (err)
goto abort_unlock;
- err = put_user (4, (char *) &loc->sectors);
+ err = put_user (4, (char __user *) &loc->sectors);
if (err)
goto abort_unlock;
err = put_user(get_capacity(mddev->gendisk)/8,
- (short *) &loc->cylinders);
+ (short __user *) &loc->cylinders);
if (err)
goto abort_unlock;
err = put_user (get_start_sect(inode->i_bdev),
- (long *) &loc->start);
+ (long __user *) &loc->start);
goto done_unlock;
}
case ADD_NEW_DISK:
{
mdu_disk_info_t info;
- if (copy_from_user(&info, (void*)arg, sizeof(info)))
+ if (copy_from_user(&info, argp, sizeof(info)))
err = -EFAULT;
else
err = add_new_disk(mddev, &info);
j += sectors;
if (j>1) mddev->curr_resync = j;
- if (last_check + window > j)
+ if (last_check + window > j || j == max_sectors)
continue;
last_check = j;
if (rdev->raid_disk >= 0 &&
rdev->faulty &&
atomic_read(&rdev->nr_pending)==0) {
- mddev->pers->hot_remove_disk(mddev, rdev->raid_disk);
- rdev->raid_disk = -1;
+ if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0)
+ rdev->raid_disk = -1;
}
if (!rdev->faulty && rdev->raid_disk >= 0 && !rdev->in_sync)
spares++;
kfree(mpb);
}
-static int multipath_map (mddev_t *mddev, mdk_rdev_t **rdevp)
+static int multipath_map (multipath_conf_t *conf)
{
- multipath_conf_t *conf = mddev_to_conf(mddev);
int i, disks = conf->raid_disks;
/*
for (i = 0; i < disks; i++) {
mdk_rdev_t *rdev = conf->multipaths[i].rdev;
if (rdev && rdev->in_sync) {
- *rdevp = rdev;
atomic_inc(&rdev->nr_pending);
spin_unlock_irq(&conf->device_lock);
- return 0;
+ return i;
}
}
spin_unlock_irq(&conf->device_lock);
(unsigned long long)bio->bi_sector);
multipath_reschedule_retry(mp_bh);
}
- atomic_dec(&rdev->nr_pending);
- return 0;
-}
-
-/*
- * This routine returns the disk from which the requested read should
- * be done.
- */
-
-static int multipath_read_balance (multipath_conf_t *conf)
-{
- int disk;
-
- for (disk = 0; disk < conf->raid_disks; disk++) {
- mdk_rdev_t *rdev = conf->multipaths[disk].rdev;
- if (rdev && rdev->in_sync)
- return disk;
- }
- BUG();
+ rdev_dec_pending(rdev, conf->mddev);
return 0;
}
disk_stat_inc(mddev->gendisk, reads);
disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio));
}
- /*
- * read balancing logic:
- */
- spin_lock_irq(&conf->device_lock);
- mp_bh->path = multipath_read_balance(conf);
+
+ mp_bh->path = multipath_map(conf);
+ if (mp_bh->path < 0) {
+ bio_endio(bio, bio->bi_size, -EIO);
+ mempool_free(mp_bh, conf->pool);
+ return 0;
+ }
multipath = conf->multipaths + mp_bh->path;
- atomic_inc(&multipath->rdev->nr_pending);
- spin_unlock_irq(&conf->device_lock);
mp_bh->bio = *bio;
mp_bh->bio.bi_bdev = multipath->rdev->bdev;
struct multipath_bh *mp_bh;
struct bio *bio;
unsigned long flags;
- mdk_rdev_t *rdev;
+ multipath_conf_t *conf = mddev_to_conf(mddev);
md_check_recovery(mddev);
for (;;) {
bio = &mp_bh->bio;
bio->bi_sector = mp_bh->master_bio->bi_sector;
- rdev = NULL;
- if (multipath_map (mddev, &rdev)<0) {
+ if ((mp_bh->path = multipath_map (conf))<0) {
printk(KERN_ALERT "multipath: %s: unrecoverable IO read"
" error for block %llu\n",
bdevname(bio->bi_bdev,b),
" to another IO path\n",
bdevname(bio->bi_bdev,b),
(unsigned long long)bio->bi_sector);
- bio->bi_bdev = rdev->bdev;
+ bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev;
generic_make_request(bio);
}
}
static void * r1bio_pool_alloc(int gfp_flags, void *data)
{
- mddev_t *mddev = data;
+ struct pool_info *pi = data;
r1bio_t *r1_bio;
/* allocate a r1bio with room for raid_disks entries in the bios array */
- r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*mddev->raid_disks,
+ r1_bio = kmalloc(sizeof(r1bio_t) + sizeof(struct bio*)*pi->raid_disks,
gfp_flags);
if (r1_bio)
- memset(r1_bio, 0, sizeof(*r1_bio) + sizeof(struct bio*)*mddev->raid_disks);
+ memset(r1_bio, 0, sizeof(*r1_bio) +
+ sizeof(struct bio*) * pi->raid_disks);
else
- unplug_slaves(mddev);
+ unplug_slaves(pi->mddev);
return r1_bio;
}
static void * r1buf_pool_alloc(int gfp_flags, void *data)
{
- conf_t *conf = data;
+ struct pool_info *pi = data;
struct page *page;
r1bio_t *r1_bio;
struct bio *bio;
int i, j;
- r1_bio = r1bio_pool_alloc(gfp_flags, conf->mddev);
+ r1_bio = r1bio_pool_alloc(gfp_flags, pi);
if (!r1_bio) {
- unplug_slaves(conf->mddev);
+ unplug_slaves(pi->mddev);
return NULL;
}
/*
* Allocate bios : 1 for reading, n-1 for writing
*/
- for (j = conf->raid_disks ; j-- ; ) {
+ for (j = pi->raid_disks ; j-- ; ) {
bio = bio_alloc(gfp_flags, RESYNC_PAGES);
if (!bio)
goto out_free_bio;
for ( ; i > 0 ; i--)
__free_page(bio->bi_io_vec[i-1].bv_page);
out_free_bio:
- while ( ++j < conf->raid_disks )
+ while ( ++j < pi->raid_disks )
bio_put(r1_bio->bios[j]);
- r1bio_pool_free(r1_bio, conf->mddev);
+ r1bio_pool_free(r1_bio, data);
return NULL;
}
static void r1buf_pool_free(void *__r1_bio, void *data)
{
+ struct pool_info *pi = data;
int i;
- conf_t *conf = data;
r1bio_t *r1bio = __r1_bio;
struct bio *bio = r1bio->bios[0];
__free_page(bio->bi_io_vec[i].bv_page);
bio->bi_io_vec[i].bv_page = NULL;
}
- for (i=0 ; i < conf->raid_disks; i++)
+ for (i=0 ; i < pi->raid_disks; i++)
bio_put(r1bio->bios[i]);
- r1bio_pool_free(r1bio, conf->mddev);
+ r1bio_pool_free(r1bio, data);
}
static void put_all_bios(conf_t *conf, r1bio_t *r1_bio)
reschedule_retry(r1_bio);
}
- atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
+ rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
return 0;
}
raid_end_bio_io(r1_bio);
}
- atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
+ rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
return 0;
}
* device if no resync is going on, or below the resync window.
* We take the first readable disk when above the resync window.
*/
- if (!conf->mddev->in_sync && (this_sector + sectors >= conf->next_resync)) {
+ if (conf->mddev->recovery_cp < MaxSector &&
+ (this_sector + sectors >= conf->next_resync)) {
/* make sure that disk is operational */
new_disk = 0;
mirror_info_t *mirror;
r1bio_t *r1_bio;
struct bio *read_bio;
- int i, disks = conf->raid_disks;
+ int i, disks;
/*
* Register the new request and wait if the reconstruction
* inc refcount on their rdev. Record them by setting
* bios[x] to bio
*/
+ disks = conf->raid_disks;
spin_lock_irq(&conf->device_lock);
for (i = 0; i < disks; i++) {
if (conf->mirrors[i].rdev &&
conf->mirrors[r1_bio->read_disk].rdev);
else
set_bit(R1BIO_Uptodate, &r1_bio->state);
- atomic_dec(&conf->mirrors[r1_bio->read_disk].rdev->nr_pending);
+ rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
reschedule_retry(r1_bio);
return 0;
}
md_done_sync(mddev, r1_bio->sectors, uptodate);
put_buf(r1_bio);
}
- atomic_dec(&conf->mirrors[mirror].rdev->nr_pending);
+ rdev_dec_pending(conf->mirrors[mirror].rdev, mddev);
return 0;
}
buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
if (conf->r1buf_pool)
BUG();
- conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free, conf);
+ conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free,
+ conf->poolinfo);
if (!conf->r1buf_pool)
return -ENOMEM;
conf->next_resync = 0;
sector_t max_sector, nr_sectors;
int disk;
int i;
+ int write_targets = 0;
if (!conf->r1buf_pool)
if (init_resync(conf))
sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) {
bio->bi_rw = WRITE;
bio->bi_end_io = end_sync_write;
+ write_targets ++;
} else
continue;
bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset;
bio->bi_bdev = conf->mirrors[i].rdev->bdev;
bio->bi_private = r1_bio;
}
+ if (write_targets == 0) {
+ /* There is nowhere to write, so all non-sync
+ * drives must be failed - so we are finished
+ */
+ int rv = max_sector - sector_nr;
+ md_done_sync(mddev, rv, 1);
+ put_buf(r1_bio);
+ atomic_dec(&conf->mirrors[disk].rdev->nr_pending);
+ return rv;
+ }
+
nr_sectors = 0;
do {
struct page *page;
*/
conf = kmalloc(sizeof(conf_t), GFP_KERNEL);
mddev->private = conf;
- if (!conf) {
- printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
- mdname(mddev));
- goto out;
- }
+ if (!conf)
+ goto out_no_mem;
+
memset(conf, 0, sizeof(*conf));
conf->mirrors = kmalloc(sizeof(struct mirror_info)*mddev->raid_disks,
GFP_KERNEL);
- if (!conf->mirrors) {
- printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
- mdname(mddev));
- goto out_free_conf;
- }
+ if (!conf->mirrors)
+ goto out_no_mem;
+
memset(conf->mirrors, 0, sizeof(struct mirror_info)*mddev->raid_disks);
+ conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
+ if (!conf->poolinfo)
+ goto out_no_mem;
+ conf->poolinfo->mddev = mddev;
+ conf->poolinfo->raid_disks = mddev->raid_disks;
conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
- r1bio_pool_free, mddev);
- if (!conf->r1bio_pool) {
- printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
- mdname(mddev));
- goto out_free_conf;
- }
+ r1bio_pool_free,
+ conf->poolinfo);
+ if (!conf->r1bio_pool)
+ goto out_no_mem;
+
mddev->queue->unplug_fn = raid1_unplug;
return 0;
+out_no_mem:
+ printk(KERN_ERR "raid1: couldn't allocate memory for %s\n",
+ mdname(mddev));
+
out_free_conf:
- if (conf->r1bio_pool)
- mempool_destroy(conf->r1bio_pool);
- if (conf->mirrors)
- kfree(conf->mirrors);
- kfree(conf);
- mddev->private = NULL;
+ if (conf) {
+ if (conf->r1bio_pool)
+ mempool_destroy(conf->r1bio_pool);
+ if (conf->mirrors)
+ kfree(conf->mirrors);
+ if (conf->poolinfo)
+ kfree(conf->poolinfo);
+ kfree(conf);
+ mddev->private = NULL;
+ }
out:
return -EIO;
}
mempool_destroy(conf->r1bio_pool);
if (conf->mirrors)
kfree(conf->mirrors);
+ if (conf->poolinfo)
+ kfree(conf->poolinfo);
kfree(conf);
mddev->private = NULL;
return 0;
}
+static int raid1_resize(mddev_t *mddev, sector_t sectors)
+{
+ /* no resync is happening, and there is enough space
+ * on all devices, so we can resize.
+ * We need to make sure resync covers any new space.
+ * If the array is shrinking we should possibly wait until
+ * any io in the removed space completes, but it hardly seems
+ * worth it.
+ */
+ mddev->array_size = sectors>>1;
+ set_capacity(mddev->gendisk, mddev->array_size << 1);
+ mddev->changed = 1;
+ if (mddev->array_size > mddev->size && mddev->recovery_cp == MaxSector) {
+ mddev->recovery_cp = mddev->size << 1;
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ }
+ mddev->size = mddev->array_size;
+ return 0;
+}
+
+static int raid1_reshape(mddev_t *mddev, int raid_disks)
+{
+ /* We need to:
+ * 1/ resize the r1bio_pool
+ * 2/ resize conf->mirrors
+ *
+ * We allocate a new r1bio_pool if we can.
+ * Then raise a device barrier and wait until all IO stops.
+ * Then resize conf->mirrors and swap in the new r1bio pool.
+ */
+ mempool_t *newpool, *oldpool;
+ struct pool_info *newpoolinfo;
+ mirror_info_t *newmirrors;
+ conf_t *conf = mddev_to_conf(mddev);
+
+ int d;
+
+ for (d= raid_disks; d < conf->raid_disks; d++)
+ if (conf->mirrors[d].rdev)
+ return -EBUSY;
+
+ newpoolinfo = kmalloc(sizeof(newpoolinfo), GFP_KERNEL);
+ if (!newpoolinfo)
+ return -ENOMEM;
+ newpoolinfo->mddev = mddev;
+ newpoolinfo->raid_disks = raid_disks;
+
+ newpool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
+ r1bio_pool_free, newpoolinfo);
+ if (!newpool) {
+ kfree(newpoolinfo);
+ return -ENOMEM;
+ }
+ newmirrors = kmalloc(sizeof(struct mirror_info) * raid_disks, GFP_KERNEL);
+ if (!newmirrors) {
+ kfree(newpoolinfo);
+ mempool_destroy(newpool);
+ return -ENOMEM;
+ }
+ memset(newmirrors, 0, sizeof(struct mirror_info)*raid_disks);
+
+ spin_lock_irq(&conf->resync_lock);
+ conf->barrier++;
+ wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
+ conf->resync_lock, unplug_slaves(mddev));
+ spin_unlock_irq(&conf->resync_lock);
+
+ /* ok, everything is stopped */
+ oldpool = conf->r1bio_pool;
+ conf->r1bio_pool = newpool;
+ for (d=0; d < raid_disks && d < conf->raid_disks; d++)
+ newmirrors[d] = conf->mirrors[d];
+ kfree(conf->mirrors);
+ conf->mirrors = newmirrors;
+ kfree(conf->poolinfo);
+ conf->poolinfo = newpoolinfo;
+
+ mddev->degraded += (raid_disks - conf->raid_disks);
+ conf->raid_disks = mddev->raid_disks = raid_disks;
+
+ spin_lock_irq(&conf->resync_lock);
+ conf->barrier--;
+ spin_unlock_irq(&conf->resync_lock);
+ wake_up(&conf->wait_resume);
+ wake_up(&conf->wait_idle);
+
+
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
+
+ mempool_destroy(oldpool);
+ return 0;
+}
+
+
static mdk_personality_t raid1_personality =
{
.name = "raid1",
.hot_remove_disk= raid1_remove_disk,
.spare_active = raid1_spare_active,
.sync_request = sync_request,
+ .resize = raid1_resize,
+ .reshape = raid1_reshape,
};
static int __init raid_init(void)
md_error(conf->mddev, conf->disks[i].rdev);
clear_bit(R5_UPTODATE, &sh->dev[i].flags);
}
- atomic_dec(&conf->disks[i].rdev->nr_pending);
+ rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
#if 0
/* must restore b_page before unlocking buffer... */
if (sh->bh_page[i] != bh->b_page) {
if (!uptodate)
md_error(conf->mddev, conf->disks[i].rdev);
- atomic_dec(&conf->disks[i].rdev->nr_pending);
+ rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
set_bit(STRIPE_HANDLE, &sh->state);
* parity, or to satisfy requests
* or to load a block that is being partially written.
*/
- if (to_read || non_overwrite || (syncing && (uptodate+failed < disks))) {
+ if (to_read || non_overwrite || (syncing && (uptodate < disks))) {
for (i=disks; i--;) {
dev = &sh->dev[i];
if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) &&
conf->algorithm = mddev->layout;
conf->max_nr_stripes = NR_STRIPES;
+ /* device size must be a multiple of chunk size */
+ mddev->size &= ~(mddev->chunk_size/1024 -1);
+
if (!conf->chunk_size || conf->chunk_size % 4) {
printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
conf->chunk_size, mdname(mddev));
return found;
}
+static int raid5_resize(mddev_t *mddev, sector_t sectors)
+{
+ /* no resync is happening, and there is enough space
+ * on all devices, so we can resize.
+ * We need to make sure resync covers any new space.
+ * If the array is shrinking we should possibly wait until
+ * any io in the removed space completes, but it hardly seems
+ * worth it.
+ */
+ sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+ mddev->array_size = (sectors * (mddev->raid_disks-1))>>1;
+ set_capacity(mddev->gendisk, mddev->array_size << 1);
+ mddev->changed = 1;
+ if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) {
+ mddev->recovery_cp = mddev->size << 1;
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ }
+ mddev->size = sectors /2;
+ return 0;
+}
+
static mdk_personality_t raid5_personality=
{
.name = "raid5",
.hot_remove_disk= raid5_remove_disk,
.spare_active = raid5_spare_active,
.sync_request = sync_request,
+ .resize = raid5_resize,
};
static int __init raid5_init (void)
md_error(conf->mddev, conf->disks[i].rdev);
clear_bit(R5_UPTODATE, &sh->dev[i].flags);
}
- atomic_dec(&conf->disks[i].rdev->nr_pending);
+ rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
#if 0
/* must restore b_page before unlocking buffer... */
if (sh->bh_page[i] != bh->b_page) {
if (!uptodate)
md_error(conf->mddev, conf->disks[i].rdev);
- atomic_dec(&conf->disks[i].rdev->nr_pending);
+ rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
set_bit(STRIPE_HANDLE, &sh->state);
* parity, or to satisfy requests
* or to load a block that is being partially written.
*/
- if (to_read || non_overwrite || (syncing && (uptodate+failed < disks))) {
+ if (to_read || non_overwrite || (syncing && (uptodate < disks))) {
for (i=disks; i--;) {
dev = &sh->dev[i];
if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) &&
conf->algorithm = mddev->layout;
conf->max_nr_stripes = NR_STRIPES;
+ /* device size must be a multiple of chunk size */
+ mddev->size &= ~(mddev->chunk_size/1024 -1);
+
if (conf->raid_disks < 4) {
printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
mdname(mddev), conf->raid_disks);
return found;
}
+static int raid6_resize(mddev_t *mddev, sector_t sectors)
+{
+ /* no resync is happening, and there is enough space
+ * on all devices, so we can resize.
+ * We need to make sure resync covers any new space.
+ * If the array is shrinking we should possibly wait until
+ * any io in the removed space completes, but it hardly seems
+ * worth it.
+ */
+ sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+ mddev->array_size = (sectors * (mddev->raid_disks-2))>>1;
+ set_capacity(mddev->gendisk, mddev->array_size << 1);
+ mddev->changed = 1;
+ if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) {
+ mddev->recovery_cp = mddev->size << 1;
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ }
+ mddev->size = sectors /2;
+ return 0;
+}
+
static mdk_personality_t raid6_personality=
{
.name = "raid6",
.hot_remove_disk= raid6_remove_disk,
.spare_active = raid6_spare_active,
.sync_request = sync_request,
+ .resize = raid6_resize,
};
static int __init raid6_init (void)
return 0;
}
-static ssize_t fops_read(struct file *file, char *data, size_t count, loff_t *ppos)
+static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
struct saa7146_fh *fh = file->private_data;
static struct fwinfo tda10046h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x3c4f9,.fw_size = 24479} };
static int tda10046h_fwinfo_count = sizeof(tda10046h_fwinfo) / sizeof(struct fwinfo);
+static int errno;
static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int data)
#include <linux/errno.h>
#include <linux/init.h>
#include <asm/io.h>
-#if defined (__sparc__)
-#include <linux/timer.h>
-#endif
-
-/* Hmmm, avoid undefined spinlock_t on lk-2.2.14-5.0 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#include <asm/spinlock.h>
-#endif
#define MODULEAUTHOR "Steven J. Ralston"
#define COPYRIGHT "Copyright (c) 2001-2004 " MODULEAUTHOR
#ifndef FUSION_LINUX_COMPAT_H
#define FUSION_LINUX_COMPAT_H
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#include <linux/version.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#ifndef rwlock_init
-#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0)
-#endif
-
-#define SET_NICE(current,x) do {(current)->nice = (x);} while (0)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
- typedef unsigned int dma_addr_t;
-# endif
-#else
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)
- typedef unsigned int dma_addr_t;
-# endif
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* This block snipped from lk-2.2.18/include/linux/init.h { */
-/*
- * Used for initialization calls..
- */
-typedef int (*initcall_t)(void);
-typedef void (*exitcall_t)(void);
-
-#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
-#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
-
-extern initcall_t __initcall_start, __initcall_end;
-
-#define __initcall(fn) \
- static initcall_t __initcall_##fn __init_call = fn
-#define __exitcall(fn) \
- static exitcall_t __exitcall_##fn __exit_call = fn
-
-#ifdef MODULE
-/* These macros create a dummy inline: gcc 2.9x does not count alias
- as usage, hence the `unused function' warning when __init functions
- are declared static. We use the dummy __*_module_inline functions
- both to kill the warning and check the type of the init/cleanup
- function. */
-typedef int (*__init_module_func_t)(void);
-typedef void (*__cleanup_module_func_t)(void);
-#define module_init(x) \
- int init_module(void) __attribute__((alias(#x))); \
- static inline __init_module_func_t __init_module_inline(void) \
- { return x; }
-#define module_exit(x) \
- void cleanup_module(void) __attribute__((alias(#x))); \
- static inline __cleanup_module_func_t __cleanup_module_inline(void) \
- { return x; }
-
-#else
-#define module_init(x) __initcall(x);
-#define module_exit(x) __exitcall(x);
-#endif
-/* } block snipped from lk-2.2.18/include/linux/init.h */
-
-/* This block snipped from lk-2.2.18/include/linux/sched.h { */
-/*
- * Used prior to schedule_timeout calls..
- */
-#define __set_current_state(state_value) do { current->state = state_value; } while (0)
-#ifdef CONFIG_SMP
-#define set_current_state(state_value) do { __set_current_state(state_value); mb(); } while (0)
-#else
-#define set_current_state(state_value) __set_current_state(state_value)
-#endif
-/* } block snipped from lk-2.2.18/include/linux/sched.h */
-
-/* procfs compat stuff... */
-#define proc_mkdir(x,y) create_proc_entry(x, S_IFDIR, y)
-
-/* MUTEX compat stuff... */
-#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
-#define DECLARE_MUTEX_LOCKED(name) struct semaphore name=MUTEX_LOCKED
-#define init_MUTEX(x) *(x)=MUTEX
-#define init_MUTEX_LOCKED(x) *(x)=MUTEX_LOCKED
-
-/* Wait queues. */
-#define DECLARE_WAIT_QUEUE_HEAD(name) \
- struct wait_queue * (name) = NULL
-#define DECLARE_WAITQUEUE(name, task) \
- struct wait_queue (name) = { (task), NULL }
-
-#if defined(__sparc__) && defined(__sparc_v9__)
-/* The sparc64 ioremap implementation is wrong in 2.2.x,
- * but fixing it would break all of the drivers which
- * workaround it. Fixed in 2.3.x onward. -DaveM
- */
-#define ARCH_IOREMAP(base) ((unsigned long) (base))
-#else
-#define ARCH_IOREMAP(base) ioremap(base)
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#else /* LINUX_VERSION_CODE must be >= KERNEL_VERSION(2,2,18) */
-
-/* No ioremap bugs in >2.3.x kernels. */
-#define ARCH_IOREMAP(base) ioremap(base)
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) */
-
-
-/*
- * Inclined to use:
- * #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
- * here, but MODULE_LICENSE defined in 2.4.9-6 and 2.4.9-13
- * breaks the rule:-(
- */
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-
-/* PCI/driver subsystem { */
-#define PCI_BASEADDR_FLAGS(idx) resource[idx].flags
-#define PCI_BASEADDR_START(idx) resource[idx].start
-#define PCI_BASEADDR_SIZE(dev,idx) (dev)->resource[idx].end - (dev)->resource[idx].start + 1
-
-/* Compatability for the 2.3.x PCI DMA API. */
-#ifndef PCI_DMA_BIDIRECTIONAL
-/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#define PCI_DMA_BIDIRECTIONAL 0
-#define PCI_DMA_TODEVICE 1
-#define PCI_DMA_FROMDEVICE 2
-#define PCI_DMA_NONE 3
-
-#ifdef __KERNEL__
-#include <asm/page.h>
-/* Pure 2^n version of get_order */
-static __inline__ int __get_order(unsigned long size)
-{
- int order;
-
- size = (size-1) >> (PAGE_SHIFT-1);
- order = -1;
- do {
- size >>= 1;
- order++;
- } while (size);
- return order;
-}
-#endif
-
-#define pci_alloc_consistent(hwdev, size, dma_handle) \
-({ void *__ret = (void *)__get_free_pages(GFP_ATOMIC, __get_order(size)); \
- if (__ret != NULL) { \
- memset(__ret, 0, size); \
- *(dma_handle) = virt_to_bus(__ret); \
- } \
- __ret; \
-})
-
-#define pci_free_consistent(hwdev, size, vaddr, dma_handle) \
- free_pages((unsigned long)vaddr, __get_order(size))
-
-#define pci_map_single(hwdev, ptr, size, direction) \
- virt_to_bus(ptr);
-
-#define pci_unmap_single(hwdev, dma_addr, size, direction) \
- do { /* Nothing to do */ } while (0)
-
-#define pci_map_sg(hwdev, sg, nents, direction) (nents)
-#define pci_unmap_sg(hwdev, sg, nents, direction) \
- do { /* Nothing to do */ } while(0)
-
-#define sg_dma_address(sg) (virt_to_bus((sg)->address))
-#define sg_dma_len(sg) ((sg)->length)
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#endif /* PCI_DMA_BIDIRECTIONAL */
-
-
-#define mpt_work_struct work_struct
-#define MPT_INIT_WORK(_task, _func, _data) INIT_WORK(_task, _func, _data)
-#define mpt_sync_irq(_irq) synchronize_irq(_irq)
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* _LINUX_COMPAT_H */
-
typedef unsigned short U16;
-#if defined(unix) || defined(__arm) || defined(ALPHA)
-
- typedef signed int S32;
- typedef unsigned int U32;
-
-#else
-
- typedef signed long S32;
- typedef unsigned long U32;
-
-#endif
+typedef int32_t S32;
+typedef u_int32_t U32;
+/*
+ * The only way crap below could work on big-endian boxen would be if it
+ * wasn't used at all.
+ */
typedef struct _S64
{
mem_phys = msize = 0;
port = psize = 0;
for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
- if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) {
+ if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
/* Get I/O space! */
- port = pdev->PCI_BASEADDR_START(ii);
- psize = PCI_BASEADDR_SIZE(pdev,ii);
+ port = pci_resource_start(pdev, ii);
+ psize = pci_resource_len(pdev,ii);
} else {
/* Get memmap */
- mem_phys = pdev->PCI_BASEADDR_START(ii);
- msize = PCI_BASEADDR_SIZE(pdev,ii);
+ mem_phys = pci_resource_start(pdev, ii);
+ msize = pci_resource_len(pdev,ii);
break;
}
}
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
- mpt_sync_irq(pdev->irq);
+ synchronize_irq(pdev->irq);
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
/* Prime reply FIFO... */
dprintk((KERN_INFO MYNAM ": %s.reply_alloc @ %p[%p], sz=%d bytes\n",
- ioc->name, mem, (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
+ ioc->name, ioc->reply_alloc,
+ (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
b = (unsigned long) ioc->reply_alloc;
b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
/* Request FIFO - WE manage this! */
dprintk((KERN_INFO MYNAM ": %s.req_alloc @ %p[%p], sz=%d bytes\n",
- ioc->name, mem, (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
+ ioc->name, ioc->req_alloc,
+ (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
b = (unsigned long) ioc->req_alloc;
b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
#define MPTBASE_H_INCLUDED
/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#include "linux_compat.h" /* linux-2.2.x (vs. -2.4.x) tweaks */
+#include <linux/version.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
#include "scsi3.h" /* SCSI defines */
#include "lsi/mpi_type.h"
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.01.06"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.06"
+#define MPT_LINUX_VERSION_COMMON "3.01.07"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.07"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
#include <asm/io.h>
#include <asm/uaccess.h>
+#include <linux/compat.h>
#include <linux/kdev_t.h> /* needed for access to Scsi_Host struct */
#include <linux/blkdev.h>
#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
#define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation"
#define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney"
#define my_VERSION MPT_LINUX_VERSION_COMMON
#define MYNAM "mptctl"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)
-EXPORT_NO_SYMBOLS;
-#endif
MODULE_AUTHOR(MODULEAUTHOR);
MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");
/*
* Private function calls.
*/
-static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local);
-static int mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen);
+static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr);
+static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
return 1;
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * struct file_operations functionality.
- * Members:
- * llseek, write, read, ioctl, open, release
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
-static loff_t
-mptctl_llseek(struct file *file, loff_t offset, int origin)
-{
- return -ESPIPE;
-}
-#define no_llseek mptctl_llseek
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
- printk(KERN_ERR MYNAM ": ioctl WRITE not yet supported\n");
- return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static ssize_t
-mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
-{
- printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n");
- return 0;
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* MPT ioctl handler
static int
mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
- mpt_ioctl_header *uhdr = (mpt_ioctl_header *) arg;
+ mpt_ioctl_header __user *uhdr = (void __user *) arg;
mpt_ioctl_header khdr;
int iocnum;
unsigned iocnumX;
if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
"Unable to copy mpt_ioctl_header data @ %p\n",
- __FILE__, __LINE__, (void*)uhdr);
+ __FILE__, __LINE__, uhdr);
return -EFAULT;
}
ret = -ENXIO; /* (-6) No such device or address */
static int mptctl_do_reset(unsigned long arg)
{
- struct mpt_ioctl_diag_reset *urinfo = (struct mpt_ioctl_diag_reset *) arg;
+ struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
struct mpt_ioctl_diag_reset krinfo;
MPT_ADAPTER *iocp;
if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
printk(KERN_ERR "%s@%d::mptctl_do_reset - "
"Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
- __FILE__, __LINE__, (void*)urinfo);
+ __FILE__, __LINE__, urinfo);
return -EFAULT;
}
return 0;
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_open(struct inode *inode, struct file *file)
-{
- /*
- * Should support multiple management users
- */
- return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int mptctl_release(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* MPT FW download function. Cast the arg into the mpt_fw_xfer structure.
static int
mptctl_fw_download(unsigned long arg)
{
- struct mpt_fw_xfer *ufwdl = (struct mpt_fw_xfer *) arg;
+ struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
struct mpt_fw_xfer kfwdl;
dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
"Unable to copy mpt_fw_xfer struct @ %p\n",
- __FILE__, __LINE__, (void*)ufwdl);
+ __FILE__, __LINE__, ufwdl);
return -EFAULT;
}
* -ENOMSG if FW upload returned bad status
*/
static int
-mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
+mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
{
FWDownload_t *dlmsg;
MPT_FRAME_HDR *mf;
if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
"Unable to copy f/w buffer hunk#%d @ %p\n",
- __FILE__, __LINE__, n, (void*)ufwbuf);
+ __FILE__, __LINE__, n, ufwbuf);
goto fwdl_out;
}
fw_bytes_copied += bl->len;
static int
mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
{
- struct mpt_ioctl_iocinfo *uarg = (struct mpt_ioctl_iocinfo *) arg;
+ struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
struct mpt_ioctl_iocinfo *karg;
MPT_ADAPTER *ioc;
struct pci_dev *pdev;
if (copy_from_user(karg, uarg, data_size)) {
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
"Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
kfree(karg);
return -EFAULT;
}
karg->pciId = pdev->device;
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
karg->hwRev = revision;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
karg->subSystemDevice = pdev->subsystem_device;
karg->subSystemVendor = pdev->subsystem_vendor;
-#endif
if (cim_rev == 1) {
/* Get the PCI bus, device, and function numbers for the IOC
/* Copy the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, karg, data_size)) {
+ if (copy_to_user((char __user *)arg, karg, data_size)) {
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
"Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
kfree(karg);
return -EFAULT;
}
static int
mptctl_gettargetinfo (unsigned long arg)
{
- struct mpt_ioctl_targetinfo *uarg = (struct mpt_ioctl_targetinfo *) arg;
+ struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
struct mpt_ioctl_targetinfo karg;
MPT_ADAPTER *ioc;
struct Scsi_Host *sh;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
"Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
/* Copy part of the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, &karg,
+ if (copy_to_user((char __user *)arg, &karg,
sizeof(struct mpt_ioctl_targetinfo))) {
printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
kfree(pmem);
return -EFAULT;
}
/* Copy the remaining data from kernel memory to user memory
*/
- if (copy_to_user((char *) uarg->targetInfo, pmem, numBytes)) {
+ if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)pdata);
+ __FILE__, __LINE__, pdata);
kfree(pmem);
return -EFAULT;
}
static int
mptctl_readtest (unsigned long arg)
{
- struct mpt_ioctl_test *uarg = (struct mpt_ioctl_test *) arg;
+ struct mpt_ioctl_test __user *uarg = (void __user *) arg;
struct mpt_ioctl_test karg;
MPT_ADAPTER *ioc;
int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
printk(KERN_ERR "%s@%d::mptctl_readtest - "
"Unable to read in mpt_ioctl_test struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
/* Copy the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
+ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
printk(KERN_ERR "%s@%d::mptctl_readtest - "
"Unable to write out mpt_ioctl_test struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
static int
mptctl_eventquery (unsigned long arg)
{
- struct mpt_ioctl_eventquery *uarg = (struct mpt_ioctl_eventquery *) arg;
+ struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
struct mpt_ioctl_eventquery karg;
MPT_ADAPTER *ioc;
int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
printk(KERN_ERR "%s@%d::mptctl_eventquery - "
"Unable to read in mpt_ioctl_eventquery struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
/* Copy the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
+ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
printk(KERN_ERR "%s@%d::mptctl_eventquery - "
"Unable to write out mpt_ioctl_eventquery struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
return 0;
static int
mptctl_eventenable (unsigned long arg)
{
- struct mpt_ioctl_eventenable *uarg = (struct mpt_ioctl_eventenable *) arg;
+ struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
struct mpt_ioctl_eventenable karg;
MPT_ADAPTER *ioc;
int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
printk(KERN_ERR "%s@%d::mptctl_eventenable - "
"Unable to read in mpt_ioctl_eventenable struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
static int
mptctl_eventreport (unsigned long arg)
{
- struct mpt_ioctl_eventreport *uarg = (struct mpt_ioctl_eventreport *) arg;
+ struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
struct mpt_ioctl_eventreport karg;
MPT_ADAPTER *ioc;
int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
printk(KERN_ERR "%s@%d::mptctl_eventreport - "
"Unable to read in mpt_ioctl_eventreport struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
/* Copy the data from kernel memory to user memory
*/
numBytes = max * sizeof(MPT_IOCTL_EVENTS);
- if (copy_to_user((char *) uarg->eventData, ioc->events, numBytes)) {
+ if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
printk(KERN_ERR "%s@%d::mptctl_eventreport - "
"Unable to write out mpt_ioctl_eventreport struct @ %p\n",
- __FILE__, __LINE__, (void*)ioc->events);
+ __FILE__, __LINE__, ioc->events);
return -EFAULT;
}
static int
mptctl_replace_fw (unsigned long arg)
{
- struct mpt_ioctl_replace_fw *uarg = (struct mpt_ioctl_replace_fw *) arg;
+ struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
struct mpt_ioctl_replace_fw karg;
MPT_ADAPTER *ioc;
fw_image_t **fwmem = NULL;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
"Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) {
printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
"Unable to read in mpt_ioctl_replace_fw image @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
mpt_free_fw_memory(ioc, fwmem);
return -EFAULT;
static int
mptctl_mpt_command (unsigned long arg)
{
- struct mpt_ioctl_command *uarg = (struct mpt_ioctl_command *) arg;
+ struct mpt_ioctl_command __user *uarg = (void __user *) arg;
struct mpt_ioctl_command karg;
MPT_ADAPTER *ioc;
int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
"Unable to read in mpt_ioctl_command struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
return -ENODEV;
}
- rc = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+ rc = mptctl_do_mpt_command (karg, &uarg->MF);
return rc;
}
* -EPERM if SCSI I/O and target is untagged
*/
static int
-mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
+mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
{
MPT_ADAPTER *ioc;
MPT_FRAME_HDR *mf = NULL;
/* Copy the request frame
* Reset the saved message context.
+ * Request frame in user space
*/
- if (local) {
- /* Request frame in kernel space
- */
- memcpy((char *)mf, (char *) mfPtr, karg.dataSgeOffset * 4);
- } else {
- /* Request frame in user space
- */
- if (copy_from_user((char *)mf, (char *) mfPtr,
- karg.dataSgeOffset * 4)){
- printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
- "Unable to read MF from mpt_ioctl_command struct @ %p\n",
- __FILE__, __LINE__, (void*)mfPtr);
- rc = -EFAULT;
- goto done_free_mem;
- }
- }
+ if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
+ printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+ "Unable to read MF from mpt_ioctl_command struct @ %p\n",
+ __FILE__, __LINE__, mfPtr);
+ rc = -EFAULT;
+ goto done_free_mem;
+ }
hdr->MsgContext = cpu_to_le32(msgContext);
"%s@%d::mptctl_do_mpt_command - Unable "
"to read user data "
"struct @ %p\n",
- __FILE__, __LINE__,(void*)karg.dataOutBufPtr);
+ __FILE__, __LINE__,karg.dataOutBufPtr);
rc = -EFAULT;
goto done_free_mem;
}
}
if (sz > 0) {
- if (copy_to_user((char *)karg.replyFrameBufPtr,
+ if (copy_to_user(karg.replyFrameBufPtr,
&ioc->ioctl->ReplyFrame, sz)){
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Unable to write out reply frame %p\n",
- __FILE__, __LINE__, (void*)karg.replyFrameBufPtr);
+ __FILE__, __LINE__, karg.replyFrameBufPtr);
rc = -ENODATA;
goto done_free_mem;
}
if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
if (sz > 0) {
- if (copy_to_user((char *)karg.senseDataPtr, ioc->ioctl->sense, sz)) {
+ if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Unable to write sense data to user %p\n",
__FILE__, __LINE__,
- (void*)karg.senseDataPtr);
+ karg.senseDataPtr);
rc = -ENODATA;
goto done_free_mem;
}
if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
(karg.dataInSize > 0) && (bufIn.kptr)) {
- if (copy_to_user((char *)karg.dataInBufPtr,
+ if (copy_to_user(karg.dataInBufPtr,
bufIn.kptr, karg.dataInSize)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Unable to write data to user %p\n",
__FILE__, __LINE__,
- (void*)karg.dataInBufPtr);
+ karg.dataInBufPtr);
rc = -ENODATA;
}
}
static int
mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
{
- hp_host_info_t *uarg = (hp_host_info_t *) arg;
+ hp_host_info_t __user *uarg = (void __user *) arg;
MPT_ADAPTER *ioc;
struct pci_dev *pdev;
char *pbuf;
if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
"Unable to read in hp_host_info struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
karg.vendor = pdev->vendor;
karg.device = pdev->device;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
karg.subsystem_id = pdev->subsystem_device;
karg.subsystem_vendor = pdev->subsystem_vendor;
-#endif
karg.devfn = pdev->devfn;
karg.bus = pdev->bus->number;
break;
}
- karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
+ karg.base_io_addr = pci_resource_start(pdev, 0);
if ((int)ioc->chip_type <= (int) FC929)
karg.bus_phys_width = HP_BUS_WIDTH_UNK;
/* Copy the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, &karg,
- sizeof(hp_host_info_t))) {
+ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
"Unable to write out hp_host_info @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
static int
mptctl_hp_targetinfo(unsigned long arg)
{
- hp_target_info_t *uarg = (hp_target_info_t *) arg;
+ hp_target_info_t __user *uarg = (void __user *) arg;
SCSIDevicePage0_t *pg0_alloc;
SCSIDevicePage3_t *pg3_alloc;
MPT_ADAPTER *ioc;
if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
"Unable to read in hp_host_targetinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
/* Copy the data from kernel memory to user memory
*/
- if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
+ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
- __FILE__, __LINE__, (void*)uarg);
+ __FILE__, __LINE__, uarg);
return -EFAULT;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-#define owner_THIS_MODULE .owner = THIS_MODULE,
-#else
-#define owner_THIS_MODULE
-#endif
-
static struct file_operations mptctl_fops = {
- owner_THIS_MODULE
+ .owner = THIS_MODULE,
.llseek = no_llseek,
- .read = mptctl_read,
- .write = mptctl_write,
.ioctl = mptctl_ioctl,
- .open = mptctl_open,
- .release = mptctl_release,
};
static struct miscdevice mptctl_miscdev = {
dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n"));
- if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
+ if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
return -EFAULT;
/* Verify intended MPT adapter */
kfw.iocnum = iocnum;
kfw.fwlen = kfw32.fwlen;
- kfw.bufp = (void *)(unsigned long)kfw32.bufp;
+ kfw.bufp = compat_ptr(kfw32.bufp);
ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
unsigned long arg, struct file *filp)
{
struct mpt_ioctl_command32 karg32;
- struct mpt_ioctl_command32 *uarg = (struct mpt_ioctl_command32 *) arg;
+ struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
struct mpt_ioctl_command karg;
MPT_ADAPTER *iocp = NULL;
int iocnum, iocnumX;
dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n"));
- if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
+ if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
return -EFAULT;
/* Verify intended MPT adapter */
karg.maxSenseBytes = karg32.maxSenseBytes;
karg.dataSgeOffset = karg32.dataSgeOffset;
- karg.replyFrameBufPtr = (char *)(unsigned long)karg32.replyFrameBufPtr;
- karg.dataInBufPtr = (char *)(unsigned long)karg32.dataInBufPtr;
- karg.dataOutBufPtr = (char *)(unsigned long)karg32.dataOutBufPtr;
- karg.senseDataPtr = (char *)(unsigned long)karg32.senseDataPtr;
+ karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
+ karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
+ karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
+ karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
/* Pass new structure to do_mpt_command
*/
- ret = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
+ ret = mptctl_do_mpt_command (karg, &uarg->MF);
up(&mptctl_syscall_sem_ioc[iocp->id]);
struct mpt_fw_xfer {
unsigned int iocnum; /* IOC unit number */
unsigned int fwlen;
- void *bufp; /* Pointer to firmware buffer */
+ void __user *bufp; /* Pointer to firmware buffer */
};
#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
struct mpt_ioctl_command {
mpt_ioctl_header hdr;
int timeout; /* optional (seconds) */
- char *replyFrameBufPtr;
- char *dataInBufPtr;
- char *dataOutBufPtr;
- char *senseDataPtr;
+ char __user *replyFrameBufPtr;
+ char __user *dataInBufPtr;
+ char __user *dataOutBufPtr;
+ char __user *senseDataPtr;
int maxReplyBytes;
int dataInSize;
int dataOutSize;
u32 total_received;
struct net_device_stats stats; /* Per device statistics */
- struct mpt_work_struct post_buckets_task;
+ struct work_struct post_buckets_task;
unsigned long post_buckets_active;
};
if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
if (priority) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
schedule_work(&priv->post_buckets_task);
-#else
- queue_task(&priv->post_buckets_task, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-#endif
} else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
schedule_delayed_work(&priv->post_buckets_task, 1);
-#else
- queue_task(&priv->post_buckets_task, &tq_timer);
-#endif
dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
"timer.\n"));
}
priv->mpt_dev = mpt_dev;
priv->pnum = pnum;
- memset(&priv->post_buckets_task, 0, sizeof(struct mpt_work_struct));
- MPT_INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
+ memset(&priv->post_buckets_task, 0, sizeof(struct work_struct));
+ INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
priv->post_buckets_active = 0;
dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59)
-MODULE_PARM(tx_max_out_p, "i");
-MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
-#endif
module_init(mpt_lan_init);
module_exit(mpt_lan_exit);
#include <linux/delay.h> /* for mdelay */
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
#include <linux/reboot.h> /* notifier code */
+#include <linux/sched.h>
+#include <linux/workqueue.h>
#include "../../scsi/scsi.h"
#include <scsi/scsi_host.h>
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
-static struct mpt_work_struct mptscsih_rstTask;
+static struct work_struct mptscsih_rstTask;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static spinlock_t dvtaskQ_lock = SPIN_LOCK_UNLOCKED;
static int dvtaskQ_active = 0;
static int dvtaskQ_release = 0;
-static struct mpt_work_struct mptscsih_dvTask;
+static struct work_struct mptscsih_dvTask;
#endif
/*
static Scsi_Cmnd *foo_to[8];
#endif
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* see mptscsih.h */
-
-static struct scsi_host_template driver_template = {
- .proc_name = "mptscsih",
- .proc_info = x_scsi_proc_info,
- .name = "MPT SCSI Host",
- .info = x_scsi_info,
- .queuecommand = x_scsi_queuecommand,
- .slave_alloc = x_scsi_slave_alloc,
- .slave_configure = x_scsi_slave_configure,
- .slave_destroy = x_scsi_slave_destroy,
- .eh_abort_handler = x_scsi_abort,
- .eh_device_reset_handler = x_scsi_dev_reset,
- .eh_bus_reset_handler = x_scsi_bus_reset,
- .eh_host_reset_handler = x_scsi_host_reset,
- .bios_param = x_scsi_bios_param,
- .can_queue = MPT_SCSI_CAN_QUEUE,
- .this_id = -1,
- .sg_tablesize = MPT_SCSI_SG_DEPTH,
- .max_sectors = MPT_SCSI_MAX_SECTORS,
- .cmd_per_lun = MPT_SCSI_CMD_PER_LUN,
- .use_clustering = ENABLE_CLUSTERING,
-};
+static struct scsi_host_template driver_template;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
}
sh->max_lun = MPT_LAST_LUN + 1;
- sh->max_sectors = MPT_SCSI_MAX_SECTORS;
sh->max_channel = 0;
sh->this_id = ioc->pfacts[0].PortSCSIID;
}
dprintk((MYIOC_s_INFO_FMT
- "Free'd ScsiLookup (%d), chain (%d) and Target (%d+%d) memory\n",
- hd->ioc->name, sz1, szchain, sz3, sztarget));
+ "Free'd ScsiLookup (%d) Target (%d+%d) memory\n",
+ hd->ioc->name, sz1, sz3, sztarget));
dprintk(("Free'd done and free Q (%d) memory\n", szQ));
/* NULL the Scsi_Host pointer
if (!dvtaskQ_active) {
dvtaskQ_active = 1;
spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
- MPT_INIT_WORK(&mptscsih_dvTask,
+ INIT_WORK(&mptscsih_dvTask,
mptscsih_domainValidation, (void *) hd);
- SCHEDULE_TASK(&mptscsih_dvTask);
+ schedule_work(&mptscsih_dvTask);
} else {
spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
}
#endif
};
-
/* SCSI host fops start here... */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
if (!dvtaskQ_active) {
dvtaskQ_active = 1;
spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
- MPT_INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
+ INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
- SCHEDULE_TASK(&mptscsih_dvTask);
+ schedule_work(&mptscsih_dvTask);
} else {
spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
}
return 1; /* currently means nothing really */
}
+static struct scsi_host_template driver_template = {
+ .proc_name = "mptscsih",
+ .proc_info = mptscsih_proc_info,
+ .name = "MPT SCSI Host",
+ .info = mptscsih_info,
+ .queuecommand = mptscsih_qcmd,
+ .slave_alloc = mptscsih_slave_alloc,
+ .slave_configure = mptscsih_slave_configure,
+ .slave_destroy = mptscsih_slave_destroy,
+ .eh_abort_handler = mptscsih_abort,
+ .eh_device_reset_handler = mptscsih_dev_reset,
+ .eh_bus_reset_handler = mptscsih_bus_reset,
+ .eh_host_reset_handler = mptscsih_host_reset,
+ .bios_param = mptscsih_bios_param,
+ .can_queue = MPT_SCSI_CAN_QUEUE,
+ .this_id = -1,
+ .sg_tablesize = MPT_SCSI_SG_DEPTH,
+ .max_sectors = 8192,
+ .cmd_per_lun = 7,
+ .use_clustering = ENABLE_CLUSTERING,
+};
+
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Private data...
/* Call the reset handler. Already had a TM request
* timeout - so issue a diagnostic reset
*/
- MPT_INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
- SCHEDULE_TASK(&mptscsih_rstTask);
+ INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
+ schedule_work(&mptscsih_rstTask);
return;
}
MPTSCSIH_SAF_TE, \
}
-
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * Various bits and pieces broke within the lk-2.4.0-testN series:-(
- * So here are various HACKS to work around them.
- */
-
-/*
- * tq_scheduler disappeared @ lk-2.4.0-test12
- * (right when <linux/sched.h> newly defined TQ_ACTIVE)
- * tq_struct reworked in 2.5.41. Include workqueue.h.
- */
-# include <linux/sched.h>
-# include <linux/workqueue.h>
-#define SCHEDULE_TASK(x) \
- if (schedule_work(x) == 0) { \
- /*MOD_DEC_USE_COUNT*/; \
- }
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#define x_scsi_info mptscsih_info
-#define x_scsi_queuecommand mptscsih_qcmd
-#define x_scsi_abort mptscsih_abort
-#define x_scsi_bus_reset mptscsih_bus_reset
-#define x_scsi_dev_reset mptscsih_dev_reset
-#define x_scsi_host_reset mptscsih_host_reset
-#define x_scsi_bios_param mptscsih_bios_param
-
-#define x_scsi_slave_alloc mptscsih_slave_alloc
-#define x_scsi_slave_configure mptscsih_slave_configure
-#define x_scsi_slave_destroy mptscsih_slave_destroy
-#define x_scsi_proc_info mptscsih_proc_info
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * MPT SCSI Host / Initiator decls...
- */
-extern const char *x_scsi_info(struct Scsi_Host *);
-extern int x_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int x_scsi_abort(Scsi_Cmnd *);
-extern int x_scsi_bus_reset(Scsi_Cmnd *);
-extern int x_scsi_dev_reset(Scsi_Cmnd *);
-extern int x_scsi_host_reset(Scsi_Cmnd *);
-extern int x_scsi_bios_param(struct scsi_device * sdev, struct block_device *bdev,
- sector_t capacity, int geom[]);
-extern int x_scsi_slave_alloc(Scsi_Device *);
-extern int x_scsi_slave_configure(Scsi_Device *);
-extern void x_scsi_slave_destroy(Scsi_Device *);
-extern int x_scsi_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/* include/scsi/scsi.h may not be quite complete... */
-#ifndef RESERVE_10
-#define RESERVE_10 0x56
-#endif
-#ifndef RELEASE_10
-#define RELEASE_10 0x57
-#endif
-#ifndef PERSISTENT_RESERVE_IN
-#define PERSISTENT_RESERVE_IN 0x5e
#endif
-#ifndef PERSISTENT_RESERVE_OUT
-#define PERSISTENT_RESERVE_OUT 0x5f
-#endif
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#endif
-
{
struct i2o_controller *c = dev->controller;
int tid = dev->tid;
- unsigned long msg;
- unsigned long mptr;
+ void *msg;
+ void *mptr;
u64 offset;
struct request *req = ireq->req;
int count = req->nr_sectors<<9;
// printk(KERN_INFO "i2ob_send called\n");
/* Map the message to a virtual address */
- msg = c->mem_offset + m;
+ msg = c->msg_virt + m;
sgnum = i2ob_build_sglist(dev, ireq);
/* Now flush the message by making it a NOP */
m[0]&=0x00FFFFFF;
m[0]|=(I2O_CMD_UTIL_NOP)<<24;
- i2o_post_message(c, ((unsigned long)m) - c->mem_offset);
+ i2o_post_message(c, (unsigned long) m - (unsigned long) c->msg_virt);
return;
}
u32 *msg = (u32 *)m;
if (msg[0] & MSG_FAIL) {
- u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+ u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
printk(KERN_ERR "i2o_config: IOP failed to process the msg.\n");
if (msg[0] & MSG_FAIL) // Fail bit is set
{
- u32 *preserved_msg = (u32*)(c->mem_offset + msg[7]);
+ u32 *preserved_msg = (u32*)(c->msg_virt + msg[7]);
i2o_report_status(KERN_INFO, "i2o_core", msg);
i2o_dump_message(preserved_msg);
m=i2o_wait_message(c, "AdapterReset");
if(m==0xFFFFFFFF)
return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
+ msg=(u32 *)(c->msg_virt+m);
status = pci_alloc_consistent(c->pdev, 4, &status_phys);
if(status == NULL) {
m=i2o_wait_message(c, "StatusGet");
if(m==0xFFFFFFFF)
return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
+ msg=(u32 *)(c->msg_virt+m);
msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
m=i2o_wait_message(c, "OutboundInit");
if(m==0xFFFFFFFF)
return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
+ msg=(u32 *)(c->msg_virt+m);
status = pci_alloc_consistent(c->pdev, 4, &status_phys);
if (status==NULL) {
sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
sys_tbl->iops[count].iop_capabilities =
iop->status_block->iop_capabilities;
- sys_tbl->iops[count].inbound_low = iop->post_port;
+ sys_tbl->iops[count].inbound_low = (u32)iop->post_port;
sys_tbl->iops[count].inbound_high = 0; // FIXME: 64-bit support
count++;
c->name);
return -ETIMEDOUT;
}
- msg = (u32 *)(c->mem_offset + m);
+ msg = (u32 *)(c->msg_virt + m);
memcpy_toio(msg, data, len);
i2o_post_message(c,m);
return 0;
I2O_IRQ_WRITE32(c,0xFFFFFFFF);
if(c->irq > 0)
free_irq(c->irq, c);
- iounmap(((u8 *)c->post_port)-0x40);
+ iounmap(c->base_virt);
+ if(c->raptor)
+ iounmap(c->msg_virt);
#ifdef CONFIG_MTRR
if(c->mtrr_reg0 > 0)
{
struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
GFP_KERNEL);
- unsigned long mem;
- u32 memptr = 0;
- u32 size;
+ void *bar0_virt;
+ void *bar1_virt;
+ unsigned long bar0_phys = 0;
+ unsigned long bar1_phys = 0;
+ unsigned long bar0_size = 0;
+ unsigned long bar1_size = 0;
int i;
}
memset(c, 0, sizeof(*c));
- for(i=0; i<6; i++)
- {
- /* Skip I/O spaces */
- if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
- {
- memptr = pci_resource_start(dev, i);
- break;
- }
- }
-
- if(i==6)
- {
- printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
- kfree(c);
- return -EINVAL;
- }
-
- size = dev->resource[i].end-dev->resource[i].start+1;
- /* Map the I2O controller */
-
- printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
- mem = (unsigned long)ioremap(memptr, size);
- if(mem==0)
- {
- printk(KERN_ERR "i2o: Unable to map controller.\n");
- kfree(c);
- return -EINVAL;
- }
-
c->irq = -1;
c->dpt = 0;
+ c->raptor = 0;
c->short_req = 0;
c->pdev = dev;
c->context_list_lock = SPIN_LOCK_UNLOCKED;
#endif
- c->irq_mask = mem+0x34;
- c->post_port = mem+0x40;
- c->reply_port = mem+0x44;
-
- c->mem_phys = memptr;
- c->mem_offset = mem;
-
/*
* Cards that fall apart if you hit them with large I/O
* loads...
c->short_req = 1;
printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
}
+
if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
{
c->promise = 1;
* them
*/
- if(dev->vendor == PCI_VENDOR_ID_DPT)
+ if(dev->vendor == PCI_VENDOR_ID_DPT) {
c->dpt=1;
+ if(dev->device == 0xA511)
+ c->raptor=1;
+ }
+
+ for(i=0; i<6; i++)
+ {
+ /* Skip I/O spaces */
+ if(!(pci_resource_flags(dev, i) & IORESOURCE_IO))
+ {
+ if(!bar0_phys)
+ {
+ bar0_phys = pci_resource_start(dev, i);
+ bar0_size = pci_resource_len(dev, i);
+ if(!c->raptor)
+ break;
+ }
+ else
+ {
+ bar1_phys = pci_resource_start(dev, i);
+ bar1_size = pci_resource_len(dev, i);
+ break;
+ }
+ }
+ }
+
+ if(i==6)
+ {
+ printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n");
+ kfree(c);
+ return -EINVAL;
+ }
+
+
+ /* Map the I2O controller */
+ if(!c->raptor)
+ printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n", bar0_phys, bar0_size);
+ else
+ printk(KERN_INFO "i2o: PCI I2O controller\n BAR0 at 0x%08lX size=%ld\n BAR1 at 0x%08lX size=%ld\n", bar0_phys, bar0_size, bar1_phys, bar1_size);
+
+ bar0_virt = ioremap(bar0_phys, bar0_size);
+ if(bar0_virt==0)
+ {
+ printk(KERN_ERR "i2o: Unable to map controller.\n");
+ kfree(c);
+ return -EINVAL;
+ }
+
+ if(c->raptor)
+ {
+ bar1_virt = ioremap(bar1_phys, bar1_size);
+ if(bar1_virt==0)
+ {
+ printk(KERN_ERR "i2o: Unable to map controller.\n");
+ kfree(c);
+ iounmap(bar0_virt);
+ return -EINVAL;
+ }
+ } else {
+ bar1_virt = bar0_virt;
+ bar1_phys = bar0_phys;
+ bar1_size = bar0_size;
+ }
+
+ c->irq_mask = bar0_virt+0x34;
+ c->post_port = bar0_virt+0x40;
+ c->reply_port = bar0_virt+0x44;
+
+ c->base_phys = bar0_phys;
+ c->base_virt = bar0_virt;
+ c->msg_phys = bar1_phys;
+ c->msg_virt = bar1_virt;
/*
* Enable Write Combining MTRR for IOP's memory region
*/
#ifdef CONFIG_MTRR
- c->mtrr_reg0 =
- mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
+ c->mtrr_reg0 = mtrr_add(c->base_phys, bar0_size, MTRR_TYPE_WRCOMB, 1);
/*
* If it is an INTEL i960 I/O processor then set the first 64K to
* Uncacheable since the region contains the Messaging unit which
if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
{
printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n");
- c->mtrr_reg1 = mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+ c->mtrr_reg1 = mtrr_add(c->base_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
if(c->mtrr_reg1< 0)
{
printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
- mtrr_del(c->mtrr_reg0, c->mem_phys, size);
+ mtrr_del(c->mtrr_reg0, c->msg_phys, bar1_size);
c->mtrr_reg0 = -1;
}
}
+ if(c->raptor)
+ c->mtrr_reg1 = mtrr_add(c->msg_phys, bar1_size, MTRR_TYPE_WRCOMB, 1);
#endif
{
printk(KERN_ERR "i2o: Unable to install controller.\n");
kfree(c);
- iounmap((void *)mem);
+ iounmap(bar0_virt);
+ if(c->raptor)
+ iounmap(bar1_virt);
return i;
}
c->name, dev->irq);
c->irq = -1;
i2o_delete_controller(c);
- iounmap((void *)mem);
+ iounmap(bar0_virt);
+ if(c->raptor)
+ iounmap(bar1_virt);
return -EBUSY;
}
}
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
{
- if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O)
+ if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O &&
+ (dev->vendor!=PCI_VENDOR_ID_DPT || dev->device!=0xA511))
continue;
- if((dev->class&0xFF)>1)
+ if((dev->class>>8)==PCI_CLASS_INTELLIGENT_I2O &&
+ (dev->class&0xFF)>1)
{
printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n");
continue;
#include <asm/atomic.h>
#include <linux/blkdev.h>
#include <linux/i2o.h>
-#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
#define VERSION_STRING "Version 0.1.2"
static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
{
- Scsi_Cmnd *current_command;
+ struct scsi_cmnd *current_command;
spinlock_t *lock;
u32 *m = (u32 *)msg;
u8 as,ds,st;
{
spin_unlock_irqrestore(&retry_lock, flags);
/* Create a scsi error for this */
- current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c);
+ current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c);
if(!current_command)
return;
return;
}
- current_command = (Scsi_Cmnd *)i2o_context_list_get(m[3], c);
+ current_command = (struct scsi_cmnd *)i2o_context_list_get(m[3], c);
/*
* Is this a control request coming back - eg an abort ?
*/
current_command->result = DID_OK << 16 | ds;
- if (current_command->use_sg)
- pci_unmap_sg(c->pdev, (struct scatterlist *)current_command->buffer, current_command->use_sg, scsi_to_pci_dma_dir(current_command->sc_data_direction));
- else if (current_command->request_bufflen)
- pci_unmap_single(c->pdev, (dma_addr_t)((long)current_command->SCp.ptr), current_command->request_bufflen, scsi_to_pci_dma_dir(current_command->sc_data_direction));
+ if (current_command->use_sg) {
+ pci_unmap_sg(c->pdev,
+ (struct scatterlist *)current_command->buffer,
+ current_command->use_sg,
+ current_command->sc_data_direction);
+ } else if (current_command->request_bufflen) {
+ pci_unmap_single(c->pdev,
+ (dma_addr_t)((long)current_command->SCp.ptr),
+ current_command->request_bufflen,
+ current_command->sc_data_direction);
+ }
lock = current_command->device->host->host_lock;
spin_lock_irqsave(lock, flags);
* scsi controller and then let the enumeration fake up the rest
*/
-static int i2o_scsi_detect(Scsi_Host_Template * tpnt)
+static int i2o_scsi_detect(struct scsi_host_template * tpnt)
{
struct Scsi_Host *shpnt = NULL;
int i;
* Locks: takes the controller lock on error path only
*/
-static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+ void (*done) (struct scsi_cmnd *))
{
int i;
int tid;
struct i2o_controller *c;
- Scsi_Cmnd *current_command;
+ struct scsi_cmnd *current_command;
struct Scsi_Host *host;
struct i2o_scsi_host *hostdata;
u32 *msg, *mptr;
if(m==0xFFFFFFFF)
return 1;
- msg = (u32 *)(c->mem_offset + m);
+ msg = (u32 *)(c->msg_virt + m);
/*
* Put together a scsi execscb message
len = SCpnt->request_bufflen;
direction = 0x00000000; // SGL IN (osm<--iop)
- if(SCpnt->sc_data_direction == SCSI_DATA_NONE)
+ if (SCpnt->sc_data_direction == DMA_NONE) {
scsidir = 0x00000000; // DATA NO XFER
- else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE)
- {
- direction=0x04000000; // SGL OUT (osm-->iop)
- scsidir =0x80000000; // DATA OUT (iop-->dev)
- }
- else if(SCpnt->sc_data_direction == SCSI_DATA_READ)
- {
- scsidir =0x40000000; // DATA IN (iop<--dev)
- }
- else
- {
+ } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
+ direction = 0x04000000; // SGL OUT (osm-->iop)
+ scsidir = 0x80000000; // DATA OUT (iop-->dev)
+ } else if(SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
+ scsidir = 0x40000000; // DATA IN (iop<--dev)
+ } else {
/* Unknown - kill the command */
SCpnt->result = DID_NO_CONNECT << 16;
len = 0;
sg_count = pci_map_sg(c->pdev, sg, SCpnt->use_sg,
- scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+ SCpnt->sc_data_direction);
/* FIXME: handle fail */
if(!sg_count)
dma_addr = pci_map_single(c->pdev,
SCpnt->request_buffer,
SCpnt->request_bufflen,
- scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+ SCpnt->sc_data_direction);
if(dma_addr == 0)
BUG(); /* How to handle ?? */
SCpnt->SCp.ptr = (char *)(unsigned long) dma_addr;
* Locks: no locks are held or needed
*/
-int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_abort(struct scsi_cmnd * SCpnt)
{
struct i2o_controller *c;
struct Scsi_Host *host;
* Locks: called with no lock held, requires no locks.
*/
-static int i2o_scsi_bus_reset(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_bus_reset(struct scsi_cmnd * SCpnt)
{
int tid;
struct i2o_controller *c;
struct Scsi_Host *host;
struct i2o_scsi_host *hostdata;
u32 m;
- unsigned long msg;
+ void *msg;
unsigned long timeout;
while(time_before(jiffies, timeout));
- msg = c->mem_offset + m;
+ msg = c->msg_virt + m;
i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4);
i2o_raw_writel(scsi_context|0x80000000, msg+8);
return SUCCESS;
}
-/**
- * i2o_scsi_host_reset - host reset callback
- * @SCpnt: command causing the reset
- *
- * An I2O controller can be many things at once. While we can
- * reset a controller the potential mess from doing so is vast, and
- * it's better to simply hold on and pray
- */
-
-static int i2o_scsi_host_reset(Scsi_Cmnd * SCpnt)
-{
- return FAILED;
-}
-
-/**
- * i2o_scsi_device_reset - device reset callback
- * @SCpnt: command causing the reset
- *
- * I2O does not (AFAIK) support doing a device reset
- */
-
-static int i2o_scsi_device_reset(Scsi_Cmnd * SCpnt)
-{
- return FAILED;
-}
-
/**
* i2o_scsi_bios_param - Invent disk geometry
* @sdev: scsi device
MODULE_LICENSE("GPL");
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.proc_name = "i2o_scsi",
.name = "I2O SCSI Layer",
.detect = i2o_scsi_detect,
.queuecommand = i2o_scsi_queuecommand,
.eh_abort_handler = i2o_scsi_abort,
.eh_bus_reset_handler = i2o_scsi_bus_reset,
- .eh_device_reset_handler= i2o_scsi_device_reset,
- .eh_host_reset_handler = i2o_scsi_host_reset,
.bios_param = i2o_scsi_bios_param,
.can_queue = I2O_SCSI_CAN_QUEUE,
.this_id = 15,
return dentry;
}
-int ibmasmfs_register()
+int ibmasmfs_register(void)
{
return register_filesystem(&ibmasmfs_type);
}
-void ibmasmfs_unregister()
+void ibmasmfs_unregister(void)
{
unregister_filesystem(&ibmasmfs_type);
}
return 0;
}
-static ssize_t command_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t command_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
struct ibmasmfs_command_data *command_data = file->private_data;
struct command *cmd;
return len;
}
-static ssize_t command_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t command_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
{
struct ibmasmfs_command_data *command_data = file->private_data;
struct command *cmd;
if (!cmd)
return -ENOMEM;
- if (copy_from_user((void *)cmd->buffer, (void *)ubuff, count)) {
+ if (copy_from_user(cmd->buffer, ubuff, count)) {
command_put(cmd);
return -EFAULT;
}
return 0;
}
-static ssize_t event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
struct ibmasmfs_event_data *event_data = file->private_data;
struct event_reader *reader = &event_data->reader;
return reader->data_size;
}
-static ssize_t event_file_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
struct ibmasmfs_event_data *event_data = file->private_data;
return 0;
}
-static ssize_t r_heartbeat_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t r_heartbeat_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
unsigned long flags;
return result;
}
-static ssize_t r_heartbeat_file_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
return 0;
}
-static ssize_t remote_settings_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
unsigned long address = (unsigned long)file->private_data;
unsigned char *page;
return retval;
}
-static ssize_t remote_settings_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
{
unsigned long address = (unsigned long)file->private_data;
char *buff;
memset(buff, 0x0, count + 1);
- if (copy_from_user((void *)buff, (void *)ubuff, count)) {
+ if (copy_from_user(buff, ubuff, count)) {
kfree(buff);
return -EFAULT;
}
return 0;
}
-static ssize_t remote_event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
struct service_processor *sp = file->private_data;
struct remote_queue *q = &sp->remote_queue;
.open = event_file_open,
.release = event_file_close,
.read = event_file_read,
- .write event_file_write,
+ .write = event_file_write,
};
static struct file_operations r_heartbeat_fops = {
#define M29W160DT 0x22C4
#define M29W160DB 0x2249
#define M29W040B 0x00E3
+#define M50FW040 0x002C
+#define M50FW080 0x002D
+#define M50FW016 0x002E
/* SST */
#define SST29EE512 0x005d
.regions = {
ERASEINFO(0x10000,8),
}
+ }, {
+ .mfr_id = MANUFACTURER_ST,
+ .dev_id = M50FW040,
+ .name = "ST M50FW040",
+ .uaddr = {
+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
+ },
+ .DevSize = SIZE_512KiB,
+ .CmdSet = P_ID_INTEL_EXT,
+ .NumEraseRegions= 1,
+ .regions = {
+ ERASEINFO(0x10000,8),
+ }
+ }, {
+ .mfr_id = MANUFACTURER_ST,
+ .dev_id = M50FW080,
+ .name = "ST M50FW080",
+ .uaddr = {
+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
+ },
+ .DevSize = SIZE_1MiB,
+ .CmdSet = P_ID_INTEL_EXT,
+ .NumEraseRegions= 1,
+ .regions = {
+ ERASEINFO(0x10000,16),
+ }
+ }, {
+ .mfr_id = MANUFACTURER_ST,
+ .dev_id = M50FW016,
+ .name = "ST M50FW016",
+ .uaddr = {
+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
+ },
+ .DevSize = SIZE_2MiB,
+ .CmdSet = P_ID_INTEL_EXT,
+ .NumEraseRegions= 1,
+ .regions = {
+ ERASEINFO(0x10000,32),
+ }
}, {
.mfr_id = MANUFACTURER_TOSHIBA,
.dev_id = TC58FVT160,
help
Map driver to support image based filesystems for uClinux.
+config MTD_WRSBC8260
+ tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
+ depends on MTD_PARTITIONS && SBC82xx
+ help
+ Map driver for WindRiver PowerQUICC II MPC82xx board. Drives
+ all three flash regions on CS0, CS1 and CS6 if they are configured
+ correctly by the boot loader.
+
endmenu
obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
obj-$(CONFIG_MTD_H720X) += h720x-flash.o
obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
+obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
+#include <asm/io.h>
#include <asm/hardware.h>
+#include <asm/arch/lubbock.h>
#define ROM_ADDR 0x00000000
/* OK, it's not open. Create cache info for it */
mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
- if (!mtdblks)
+ if (!mtdblk)
return -ENOMEM;
memset(mtdblk, 0, sizeof(*mtdblk));
* Reserve I/O resource for exclusive use by this driver
*/
- if (!request_region(ioaddr, EL1_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, EL1_IO_EXTENT, DRV_NAME))
return -ENODEV;
/*
release_region(dev->base_addr, EL2_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init el2_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
/* Probe for the Etherlink II card at I/O port base IOADDR,
returning non-zero on success. If found, set the station
static unsigned version_printed;
unsigned long vendor_id;
- if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
return -EBUSY;
- if (!request_region(ioaddr + 0x400, 8, dev->name)) {
+ if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) {
retval = -EBUSY;
goto out;
}
return err;
}
+#ifndef MODULE
struct net_device * __init elplus_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(elp_device));
return dev;
}
-#ifdef MODULE
+#else
static struct net_device *dev_3c505[ELP_MAX_CARDS];
static int io[ELP_MAX_CARDS];
static int irq[ELP_MAX_CARDS];
init_ID_done = 1;
}
- if (!request_region(ioaddr, EL16_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, EL16_IO_EXTENT, DRV_NAME))
return -ENODEV;
if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') ||
irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
- irqval = request_irq(irq, &el16_interrupt, 0, dev->name, dev);
+ irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
if (irqval) {
printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
retval = -EAGAIN;
v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
- Introduce driver model for EISA cards.
*/
-/*
- FIXES for PC-9800:
- Shu Iwanaga: 3c569B(PC-9801 C-bus) support
-*/
#define DRV_NAME "3c509"
#define DRV_VERSION "1.19b"
};
#endif /* CONFIG_MCA */
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090),
if (lp->pmdev)
pm_unregister(lp->pmdev);
#endif
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
if (lp->type == EL3_PNP)
pnp_device_detach(to_pnp_dev(lp->dev));
#endif
u16 phys_addr[3];
static int current_tag;
int err = -ENODEV;
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
static int pnp_cards;
struct pnp_dev *idev = NULL;
no_pnp:
#endif /* __ISAPNP__ */
-#ifdef CONFIG_X86_PC9800
- id_port = 0x71d0;
-#else
/* Select an open I/O location at 0x1*0 to do contention select. */
for ( ; id_port < 0x200; id_port += 0x10) {
if (!request_region(id_port, 1, "3c509"))
printk(" WARNING: No I/O port available for 3c509 activation.\n");
return -ENODEV;
}
-#endif /* CONFIG_X86_PC9800 */
+
/* Next check for all ISA bus boards by sending the ID sequence to the
ID_PORT. We find cards past the first by setting the 'current_tag'
on cards as they are found. Cards with their tag set will not
phys_addr[i] = htons(id_read_eeprom(i));
}
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
if (nopnp == 0) {
/* The ISA PnP 3c509 cards respond to the ID sequence.
This check is needed in order not to register them twice. */
{
unsigned int iobase = id_read_eeprom(8);
if_port = iobase >> 14;
-#ifdef CONFIG_X86_PC9800
- ioaddr = 0x40d0 + ((iobase & 0x1f) << 8);
-#else
ioaddr = 0x200 + ((iobase & 0x1f) << 4);
-#endif
}
irq = id_read_eeprom(9) >> 12;
-#ifdef CONFIG_X86_PC9800
- if (irq == 7)
- irq = 6;
- else if (irq == 15)
- irq = 13;
-#endif
dev = alloc_etherdev(sizeof (struct el3_private));
if (!dev)
outb(0xd0 + ++current_tag, id_port);
/* Activate the adaptor at the EEPROM location. */
-#ifdef CONFIG_X86_PC9800
- outb((ioaddr >> 8) | 0xe0, id_port);
-#else
outb((ioaddr >> 4) | 0xe0, id_port);
-#endif
EL3WINDOW(0);
if (inw(ioaddr) != 0x6d50)
/* Free the interrupt so that some other card can use it. */
outw(0x0f00, ioaddr + WN0_IRQ);
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
found: /* PNP jumps here... */
#endif /* __ISAPNP__ */
dev->irq = irq;
dev->if_port = if_port;
lp = netdev_priv(dev);
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
lp->dev = &idev->dev;
#endif
err = el3_common_init(dev);
return 0;
out1:
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
if (idev)
pnp_device_detach(idev);
#endif
*/
static int
-netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
+netdev_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
{
u32 ethcmd;
struct el3_private *lp = netdev_priv(dev);
/* dev_ioctl() in ../../net/core/dev.c has already checked
capable(CAP_NET_ADMIN), so don't bother with that here. */
- if (get_user(ethcmd, (u32 *)useraddr))
+ if (get_user(ethcmd, (u32 __user *)useraddr))
return -EFAULT;
switch (ethcmd) {
switch (cmd) {
case SIOCETHTOOL:
- rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
break;
default:
outw(0x0001, ioaddr + 4);
/* Set the IRQ line. */
-#ifdef CONFIG_X86_PC9800
- if (dev->irq == 6)
- dev->irq = 7;
- else if (dev->irq == 13)
- dev->irq = 15;
-#endif
outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
/* Set the station address in window 2 each time opened. */
MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-#if defined(__ISAPNP__) && !defined(CONFIG_X86_PC9800)
+#if defined(__ISAPNP__)
MODULE_PARM(nopnp, "i");
MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
- if (!request_region(dev->base_addr, ELMC_IO_EXTENT, dev->name)) {
+ if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) {
slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
release_region(dev->base_addr, ELMC_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init elmc_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct priv));
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
/**********************************************
* init the chip (elmc-interrupt should be disabled?!)
}
}
+ free_netdev(dev);
return ERR_PTR(-ENODEV);
}
* Grab the IRQ
*/
- err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+ err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, DRV_NAME, dev);
if (err) {
release_region(dev->base_addr, MC32_IO_EXTENT);
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+ printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
goto err_exit_ports;
}
CH_3C905B_2,
CH_3C905B_FX,
CH_3C905C,
+ CH_3C9202,
CH_3C980,
CH_3C9805,
{"3c905B-FX Cyclone 100baseFx",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
{"3c905C Tornado",
- PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+ {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
+ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
{"3c980 Cyclone",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+
{"3c980C Python-T",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
-
{"3cSOHO100-TX Hurricane",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
{"3c555 Laptop Hurricane",
{"3c556B Laptop Hurricane",
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
WNO_XCVR_PWR|HAS_HWCKSM, 128, },
+
{"3c575 [Megahertz] 10/100 LAN CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
-
{"3c575 Boomerang CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
{"3CCFE575BT Cyclone CardBus",
{"3CCFE656 Cyclone CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
INVERT_LED_PWR|HAS_HWCKSM, 128, },
+
{"3CCFEM656B Cyclone+Winmodem CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
INVERT_LED_PWR|HAS_HWCKSM, 128, },
-
{"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
MAX_COLLISION_RESET|HAS_HWCKSM, 128, },
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
{"3c982 Hydra Dual Port A",
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
+
{"3c982 Hydra Dual Port B",
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
-
{"3c905B-T4",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
{"3c920B-EMB-WNM Tornado",
{ 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
{ 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX },
{ 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C },
+ { 0x10B7, 0x9202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9202 },
{ 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 },
{ 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 },
struct net_device *dev = (struct net_device *)data;
struct vortex_private *vp = netdev_priv(dev);
long ioaddr = dev->base_addr;
- int next_tick = 60*HZ;
+ int next_tick = 10*HZ;
int ok = 0;
int media_status, mii_status, old_window;
{
struct vortex_private *vp = netdev_priv(dev);
long ioaddr = dev->base_addr;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
int phy = vp->phys[0] & 0x1f;
int retval;
int err;
struct vortex_private *vp = netdev_priv(dev);
int state = 0;
-
+
if(VORTEX_PCI(vp))
state = VORTEX_PCI(vp)->current_state;
/* The kernel core really should have pci_get_power_state() */
if(state != 0)
- pci_set_power_state(VORTEX_PCI(vp), 0);
+ pci_set_power_state(VORTEX_PCI(vp), 0);
err = vortex_do_ioctl(dev, rq, cmd);
if(state != 0)
- pci_set_power_state(VORTEX_PCI(vp), state);
-
+ pci_set_power_state(VORTEX_PCI(vp), state);
+
return err;
}
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
struct cp_private *cp = netdev_priv(dev);
- struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data;
int rc;
unsigned long flags;
return -EINVAL;
spin_lock_irqsave(&cp->lock, flags);
- rc = generic_mii_ioctl(&cp->mii_if, mii, cmd, NULL);
+ rc = generic_mii_ioctl(&cp->mii_if, if_mii(rq), cmd, NULL);
spin_unlock_irqrestore(&cp->lock, flags);
return rc;
}
"rtl8139-diag -mmmaaavvveefN" output
enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
- See 8139too.txt for more details.
-
*/
#define DRV_NAME "8139too"
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct rtl8139_private *np = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
int rc;
if (!netif_running(dev))
return -EINVAL;
spin_lock_irq(&np->lock);
- rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
+ rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
return rc;
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
static char version[] __initdata =
"82596.c $Revision: 1.5 $\n";
+#define DRV_NAME "82596"
+
/* DEBUG flags
*/
/* this is easy the ethernet interface can only be at 0x300 */
/* first check nothing is already registered here */
- if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
+ if (!request_region(ioaddr, I596_TOTAL_SIZE, DRV_NAME)) {
printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
err = -EBUSY;
goto out;
config NET_ISA
bool "Other ISA cards"
- depends on NET_ETHERNET && ISA && !X86_PC9800
+ depends on NET_ETHERNET && ISA
---help---
If your network (Ethernet) card hasn't been mentioned yet and its
bus system (that's the way the cards talks to the other components
the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
-config NET_CBUS
- bool "NEC PC-9800 C-bus cards"
- depends on NET_ETHERNET && ISA && X86_PC9800
- ---help---
- If your network (Ethernet) card hasn't been mentioned yet and its
- bus system (that's the way the cards talks to the other components
- of your computer) is NEC PC-9800 C-Bus, say Y.
-
-config NE2K_CBUS
- tristate "Most NE2000-based Ethernet support"
- depends on NET_CBUS
- select CRC32
-
-config NE2K_CBUS_EGY98
- bool "Melco EGY-98 support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_LGY98
- bool "Melco LGY-98 support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_ICM
- bool "ICM IF-27xxET support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_IOLA98
- bool "I-O DATA LA-98 support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_CNET98EL
- bool "Contec C-NET(98)E/L support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_CNET98EL_IO_BASE
- hex "C-NET(98)E/L I/O base address (0xaaed or 0x55ed)"
- depends on NE2K_CBUS_CNET98EL
- default "0xaaed"
-
-config NE2K_CBUS_ATLA98
- bool "Allied Telesis LA-98 Support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_BDN
- bool "ELECOM Laneed LD-BDN[123]A Support"
- depends on NE2K_CBUS
-
-config NE2K_CBUS_NEC108
- bool "NEC PC-9801-108 Support"
- depends on NE2K_CBUS
-
config SKMC
tristate "SKnet MCA support"
depends on NET_ETHERNET && MCA && BROKEN
config AMD8111E_NAPI
bool "Enable NAPI support"
depends on AMD8111_ETH
+ help
+ NAPI is a new driver API designed to reduce CPU and interrupt load
+ when the driver is receiving lots of packets from the card. It is
+ still somewhat experimental and thus not yet enabled by default.
+
+ If your estimated Rx load is 10kpps or more, or if the card will be
+ deployed on potentially unfriendly networks (e.g. in a firewall),
+ then say Y here.
+
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
+
+ If in doubt, say N.
config ADAPTEC_STARFIRE
tristate "Adaptec Starfire/DuraLAN support"
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
+
+ If in doubt, say N.
+
config AC3200
tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
config E100_NAPI
bool "Use Rx Polling (NAPI)"
depends on E100
+ help
+ NAPI is a new driver API designed to reduce CPU and interrupt load
+ when the driver is receiving lots of packets from the card. It is
+ still somewhat experimental and thus not yet enabled by default.
+
+ If your estimated Rx load is 10kpps or more, or if the card will be
+ deployed on potentially unfriendly networks (e.g. in a firewall),
+ then say Y here.
+
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
+
+ If in doubt, say N.
config LNE390
tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
---help---
This is a driver for the Fast Ethernet PCI network cards based on
the RTL8139 chips. If you have one of those, say Y and read
- <file:Documentation/networking/8139too.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
+ the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
To compile this driver as a module, choose M here: the module
will be called 8139too. This is recommended.
If unsure, say Y.
+config VIA_VELOCITY
+ tristate "VIA Velocity support"
+ depends on NET_PCI && PCI
+ select CRC32
+ select MII
+ help
+ If you have a VIA "Velocity" based network card say Y here.
+
+ To compile this driver as a module, choose M here. The module
+ will be called via-rhine.
+
config LAN_SAA9730
bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)"
depends on NET_PCI && EXPERIMENTAL && MIPS
config E1000_NAPI
bool "Use Rx Polling (NAPI)"
depends on E1000
+ help
+ NAPI is a new driver API designed to reduce CPU and interrupt load
+ when the driver is receiving lots of packets from the card. It is
+ still somewhat experimental and thus not yet enabled by default.
+
+ If your estimated Rx load is 10kpps or more, or if the card will be
+ deployed on potentially unfriendly networks (e.g. in a firewall),
+ then say Y here.
+
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
+
+ If in doubt, say N.
config MYRI_SBUS
tristate "MyriCOM Gigabit Ethernet support"
config IXGB_NAPI
bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
depends on IXGB && EXPERIMENTAL
+ help
+ NAPI is a new driver API designed to reduce CPU and interrupt load
+ when the driver is receiving lots of packets from the card. It is
+ still somewhat experimental and thus not yet enabled by default.
+
+ If your estimated Rx load is 10kpps or more, or if the card will be
+ deployed on potentially unfriendly networks (e.g. in a firewall),
+ then say Y here.
+
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
+
+ If in doubt, say N.
config S2IO
tristate "S2IO 10Gbe XFrame NIC"
config S2IO_NAPI
bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
depends on S2IO && EXPERIMENTAL
+ help
+ NAPI is a new driver API designed to reduce CPU and interrupt load
+ when the driver is receiving lots of packets from the card. It is
+ still somewhat experimental and thus not yet enabled by default.
+
+ If your estimated Rx load is 10kpps or more, or if the card will be
+ deployed on potentially unfriendly networks (e.g. in a firewall),
+ then say Y here.
+
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
+
+ If in doubt, say N.
endmenu
obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
+obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
#
obj-$(CONFIG_WD80x3) += wd.o 8390.o
obj-$(CONFIG_EL2) += 3c503.o 8390.o
obj-$(CONFIG_NE2000) += ne.o 8390.o
-obj-$(CONFIG_NE2K_CBUS) += ne2k_cbus.o 8390.o
obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o
obj-$(CONFIG_HPLAN) += hp.o 8390.o
obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o
#ifdef CONFIG_E2100 /* Cabletron E21xx series. */
{e2100_probe, 0},
#endif
-#if defined(CONFIG_NE2000) || defined(CONFIG_NE2K_CBUS) || \
- defined(CONFIG_NE_H8300) /* ISA & PC-9800 CBUS (use ne2k-pci for PCI cards) */
+#if defined(CONFIG_NE2000) || \
+ defined(CONFIG_NE_H8300) /* ISA (use ne2k-pci for PCI cards) */
{ne_probe, 0},
#endif
#ifdef CONFIG_LANCE /* ISA/VLB (use pcnet32 for PCI cards) */
#include "8390.h"
+#define DRV_NAME "ac3200"
+
/* Offsets from the base address. */
#define AC_NIC_BASE 0x00
#define AC_SA_PROM 0x16 /* The station address PROM. */
iounmap((void *)dev->mem_start);
}
+#ifndef MODULE
struct net_device * __init ac3200_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init ac_probe1(int ioaddr, struct net_device *dev)
{
int i, retval;
- if (!request_region(ioaddr, AC_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
return -EBUSY;
if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
printk(", assigning");
}
- retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+ retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (retval) {
printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
goto out1;
#include <asm/uaccess.h>
+#define DRV_NAME "acenic"
+
#undef INDEX_DEBUG
#ifdef CONFIG_ACENIC_OMIT_TIGON_I
"acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
+static int ace_get_settings(struct net_device *, struct ethtool_cmd *);
+static int ace_set_settings(struct net_device *, struct ethtool_cmd *);
+static void ace_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
+
+static struct ethtool_ops ace_ethtool_ops = {
+ .get_settings = ace_get_settings,
+ .set_settings = ace_set_settings,
+ .get_drvinfo = ace_get_drvinfo,
+};
+
static int __devinit acenic_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
dev->hard_start_xmit = &ace_start_xmit;
dev->get_stats = &ace_get_stats;
dev->set_multicast_list = &ace_set_multicast_list;
- dev->do_ioctl = &ace_ioctl;
+ SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
dev->set_mac_address = &ace_set_mac_addr;
dev->change_mtu = &ace_change_mtu;
}
ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ,
- dev->name, dev);
+ DRV_NAME, dev);
if (ecode) {
printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
- dev->name, pdev->irq);
+ DRV_NAME, pdev->irq);
goto init_error;
} else
dev->irq = pdev->irq;
return 0;
}
-
-static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct ace_private *ap = dev->priv;
struct ace_regs *regs = ap->regs;
-#ifdef SIOCETHTOOL
- struct ethtool_cmd ecmd;
- u32 link, speed;
+ u32 link;
- if (cmd != SIOCETHTOOL)
- return -EOPNOTSUPP;
- if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
- return -EFAULT;
- switch (ecmd.cmd) {
- case ETHTOOL_GSET:
- ecmd.supported =
- (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_FIBRE);
-
- ecmd.port = PORT_FIBRE;
- ecmd.transceiver = XCVR_INTERNAL;
- ecmd.phy_address = 0;
-
- link = readl(®s->GigLnkState);
- if (link & LNK_1000MB)
- ecmd.speed = SPEED_1000;
- else {
- link = readl(®s->FastLnkState);
- if (link & LNK_100MB)
- ecmd.speed = SPEED_100;
- else if (link & LNK_100MB)
- ecmd.speed = SPEED_10;
- else
- ecmd.speed = 0;
- }
- if (link & LNK_FULL_DUPLEX)
- ecmd.duplex = DUPLEX_FULL;
- else
- ecmd.duplex = DUPLEX_HALF;
+ memset(ecmd, 0, sizeof(struct ethtool_cmd));
+ ecmd->supported =
+ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_FIBRE);
+
+ ecmd->port = PORT_FIBRE;
+ ecmd->transceiver = XCVR_INTERNAL;
- if (link & LNK_NEGOTIATE)
- ecmd.autoneg = AUTONEG_ENABLE;
+ link = readl(®s->GigLnkState);
+ if (link & LNK_1000MB)
+ ecmd->speed = SPEED_1000;
+ else {
+ link = readl(®s->FastLnkState);
+ if (link & LNK_100MB)
+ ecmd->speed = SPEED_100;
+ else if (link & LNK_10MB)
+ ecmd->speed = SPEED_10;
else
- ecmd.autoneg = AUTONEG_DISABLE;
+ ecmd->speed = 0;
+ }
+ if (link & LNK_FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+
+ if (link & LNK_NEGOTIATE)
+ ecmd->autoneg = AUTONEG_ENABLE;
+ else
+ ecmd->autoneg = AUTONEG_DISABLE;
#if 0
- /*
- * Current struct ethtool_cmd is insufficient
- */
- ecmd.trace = readl(®s->TuneTrace);
+ /*
+ * Current struct ethtool_cmd is insufficient
+ */
+ ecmd->trace = readl(®s->TuneTrace);
- ecmd.txcoal = readl(®s->TuneTxCoalTicks);
- ecmd.rxcoal = readl(®s->TuneRxCoalTicks);
+ ecmd->txcoal = readl(®s->TuneTxCoalTicks);
+ ecmd->rxcoal = readl(®s->TuneRxCoalTicks);
#endif
- ecmd.maxtxpkt = readl(®s->TuneMaxTxDesc);
- ecmd.maxrxpkt = readl(®s->TuneMaxRxDesc);
+ ecmd->maxtxpkt = readl(®s->TuneMaxTxDesc);
+ ecmd->maxrxpkt = readl(®s->TuneMaxRxDesc);
- if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
- return -EFAULT;
- return 0;
+ return 0;
+}
- case ETHTOOL_SSET:
- link = readl(®s->GigLnkState);
- if (link & LNK_1000MB)
- speed = SPEED_1000;
- else {
- link = readl(®s->FastLnkState);
- if (link & LNK_100MB)
- speed = SPEED_100;
- else if (link & LNK_100MB)
- speed = SPEED_10;
- else
- speed = SPEED_100;
- }
+static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+ struct ace_private *ap = dev->priv;
+ struct ace_regs *regs = ap->regs;
+ u32 link, speed;
- link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
- LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
- if (!ACE_IS_TIGON_I(ap))
- link |= LNK_TX_FLOW_CTL_Y;
- if (ecmd.autoneg == AUTONEG_ENABLE)
- link |= LNK_NEGOTIATE;
- if (ecmd.speed != speed) {
- link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
- switch (speed) {
- case SPEED_1000:
- link |= LNK_1000MB;
- break;
- case SPEED_100:
- link |= LNK_100MB;
- break;
- case SPEED_10:
- link |= LNK_10MB;
- break;
- }
+ link = readl(®s->GigLnkState);
+ if (link & LNK_1000MB)
+ speed = SPEED_1000;
+ else {
+ link = readl(®s->FastLnkState);
+ if (link & LNK_100MB)
+ speed = SPEED_100;
+ else if (link & LNK_10MB)
+ speed = SPEED_10;
+ else
+ speed = SPEED_100;
+ }
+
+ link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
+ LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
+ if (!ACE_IS_TIGON_I(ap))
+ link |= LNK_TX_FLOW_CTL_Y;
+ if (ecmd->autoneg == AUTONEG_ENABLE)
+ link |= LNK_NEGOTIATE;
+ if (ecmd->speed != speed) {
+ link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
+ switch (speed) {
+ case SPEED_1000:
+ link |= LNK_1000MB;
+ break;
+ case SPEED_100:
+ link |= LNK_100MB;
+ break;
+ case SPEED_10:
+ link |= LNK_10MB;
+ break;
}
- if (ecmd.duplex == DUPLEX_FULL)
- link |= LNK_FULL_DUPLEX;
+ }
- if (link != ap->link) {
- struct cmd cmd;
- printk(KERN_INFO "%s: Renegotiating link state\n",
- dev->name);
+ if (ecmd->duplex == DUPLEX_FULL)
+ link |= LNK_FULL_DUPLEX;
- ap->link = link;
- writel(link, ®s->TuneLink);
- if (!ACE_IS_TIGON_I(ap))
- writel(link, ®s->TuneFastLink);
- wmb();
+ if (link != ap->link) {
+ struct cmd cmd;
+ printk(KERN_INFO "%s: Renegotiating link state\n",
+ dev->name);
- cmd.evt = C_LNK_NEGOTIATION;
- cmd.code = 0;
- cmd.idx = 0;
- ace_issue_cmd(regs, &cmd);
- }
- return 0;
-
- case ETHTOOL_GDRVINFO: {
- struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
- strncpy(info.driver, "acenic", sizeof(info.driver) - 1);
- sprintf(info.fw_version, "%i.%i.%i",
- tigonFwReleaseMajor, tigonFwReleaseMinor,
- tigonFwReleaseFix);
- strncpy(info.version, version, sizeof(info.version) - 1);
- if (ap && ap->pdev)
- strcpy(info.bus_info, pci_name(ap->pdev));
- if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- default:
- break;
- }
-
-#endif
+ ap->link = link;
+ writel(link, ®s->TuneLink);
+ if (!ACE_IS_TIGON_I(ap))
+ writel(link, ®s->TuneFastLink);
+ wmb();
- return -EOPNOTSUPP;
+ cmd.evt = C_LNK_NEGOTIATION;
+ cmd.code = 0;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+ }
+ return 0;
}
+static void ace_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct ace_private *ap = dev->priv;
+
+ strlcpy(info->driver, "acenic", sizeof(info->driver));
+ snprintf(info->version, sizeof(info->version), "%i.%i.%i",
+ tigonFwReleaseMajor, tigonFwReleaseMinor,
+ tigonFwReleaseFix);
+
+ if (ap->pdev)
+ strlcpy(info->bus_info, pci_name(ap->pdev),
+ sizeof(info->bus_info));
+
+}
/*
* Set the hardware MAC address.
static void ace_dump_trace(struct ace_private *ap);
static void ace_set_multicast_list(struct net_device *dev);
static int ace_change_mtu(struct net_device *dev, int new_mtu);
-static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int ace_set_mac_addr(struct net_device *dev, void *p);
static void ace_set_rxtx_parms(struct net_device *dev, int jumbo);
static int ace_allocate_descriptors(struct net_device *dev);
This function handles all the ethtool ioctls. It gives driver info, gets/sets driver speed, gets memory mapped register values, forces auto negotiation, sets/gets WOL options for ethtool application.
*/
-static int amd8111e_ethtool_ioctl(struct net_device* dev, void* useraddr)
+static int amd8111e_ethtool_ioctl(struct net_device* dev, void __user *useraddr)
{
struct amd8111e_priv *lp = netdev_priv(dev);
struct pci_dev *pci_dev = lp->pci_dev;
}
static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
{
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+ struct mii_ioctl_data *data = if_mii(ifr);
struct amd8111e_priv *lp = netdev_priv(dev);
int err;
u32 mii_regval;
switch(cmd) {
case SIOCETHTOOL:
- return amd8111e_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+ return amd8111e_ethtool_ioctl(dev, ifr->ifr_data);
case SIOCGMIIPHY:
data->phy_id = PHY_ID;
/* ---- No user-serviceable parts below ---- */
+#define DRV_NAME "apne"
+
#define NE_BASE (dev->base_addr)
#define NE_CMD 0x00
#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */
return ERR_PTR(-ENODEV);
}
- if (!request_region(IOBASE, 0x20, dev->name)) {
+ if (!request_region(IOBASE, 0x20, DRV_NAME)) {
free_netdev(dev);
return ERR_PTR(-EBUSY);
}
dev->base_addr = ioaddr;
/* Install the Interrupt handler */
- i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, dev->name, dev);
+ i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, DRV_NAME, dev);
if (i) return i;
for(i = 0; i < ETHER_ADDR_LEN; i++) {
static void cops_load (struct net_device *dev)
{
struct ifreq ifr;
- struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_data;
+ struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru;
struct cops_local *lp = netdev_priv(dev);
int ioaddr=dev->base_addr;
int length, i = 0;
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct ipddp_route *rt = (struct ipddp_route *)ifr->ifr_data;
+ struct ipddp_route __user *rt = ifr->ifr_data;
struct ipddp_route rcp;
if(!capable(CAP_NET_ADMIN))
number (MTD support is required for this). Otherwise you will
need to set a suitable hw address using ifconfig.
+config SMC91X
+ tristate "SMC 91C9x/91C1xxx support"
+ select CRC32
+ select MII
+ depends on ARM
+ help
+ This is a driver for SMC's 91x series of Ethernet chipsets,
+ including the SMC91C94 and the SMC91C111. Say Y if you want it
+ compiled into the kernel, and read the file
+ <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
+ available from <http://www.linuxdoc.org/docs.html#howto>.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called smc91x. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt> as well
+ as <file:Documentation/networking/net-modules.txt>.
obj-$(CONFIG_ARM_ETHERH) += etherh.o
obj-$(CONFIG_ARM_ETHER3) += ether3.o
obj-$(CONFIG_ARM_ETHER1) += ether1.o
+obj-$(CONFIG_SMC91X) += smc91x.o
#ifdef __arm__
static void write_rreg(u_long base, u_int reg, u_int val)
{
- __asm__("str%?h %1, [%2] @ NET_RAP
- str%?h %0, [%2, #-4] @ NET_RDP
- " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
+ __asm__(
+ "str%?h %1, [%2] @ NET_RAP\n\t"
+ "str%?h %0, [%2, #-4] @ NET_RDP"
+ :
+ : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
}
static inline unsigned short read_rreg(u_long base_addr, u_int reg)
{
unsigned short v;
- __asm__("str%?h %1, [%2] @ NET_RAP
- ldr%?h %0, [%2, #-4] @ NET_RDP
- " : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464));
+ __asm__(
+ "str%?h %1, [%2] @ NET_RAP\n\t"
+ "ldr%?h %0, [%2, #-4] @ NET_RDP"
+ : "=r" (v)
+ : "r" (reg), "r" (ISAIO_BASE + 0x0464));
return v;
}
static inline void write_ireg(u_long base, u_int reg, u_int val)
{
- __asm__("str%?h %1, [%2] @ NET_RAP
- str%?h %0, [%2, #8] @ NET_IDP
- " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
+ __asm__(
+ "str%?h %1, [%2] @ NET_RAP\n\t"
+ "str%?h %0, [%2, #8] @ NET_IDP"
+ :
+ : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
}
static inline unsigned short read_ireg(u_long base_addr, u_int reg)
}
while (length > 8) {
unsigned int tmp, tmp2;
- __asm__ __volatile__("
- ldm%?ia %1!, {%2, %3}
- str%?h %2, [%0], #4
- mov%? %2, %2, lsr #16
- str%?h %2, [%0], #4
- str%?h %3, [%0], #4
- mov%? %3, %3, lsr #16
- str%?h %3, [%0], #4
- " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
- : "0" (offset), "1" (buf));
+ __asm__ __volatile__(
+ "ldm%?ia %1!, {%2, %3}\n\t"
+ "str%?h %2, [%0], #4\n\t"
+ "mov%? %2, %2, lsr #16\n\t"
+ "str%?h %2, [%0], #4\n\t"
+ "str%?h %3, [%0], #4\n\t"
+ "mov%? %3, %3, lsr #16\n\t"
+ "str%?h %3, [%0], #4"
+ : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
+ : "0" (offset), "1" (buf));
length -= 8;
}
while (length > 0) {
length = (length + 1) & ~1;
if ((int)buf & 2) {
unsigned int tmp;
- __asm__ __volatile__("
- ldr%?h %2, [%0], #4
- str%?b %2, [%1], #1
- mov%? %2, %2, lsr #8
- str%?b %2, [%1], #1
- " : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
+ __asm__ __volatile__(
+ "ldr%?h %2, [%0], #4\n\t"
+ "str%?b %2, [%1], #1\n\t"
+ "mov%? %2, %2, lsr #8\n\t"
+ "str%?b %2, [%1], #1"
+ : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
length -= 2;
}
while (length > 8) {
unsigned int tmp, tmp2, tmp3;
- __asm__ __volatile__("
- ldr%?h %2, [%0], #4
- ldr%?h %3, [%0], #4
- orr%? %2, %2, %3, lsl #16
- ldr%?h %3, [%0], #4
- ldr%?h %4, [%0], #4
- orr%? %3, %3, %4, lsl #16
- stm%?ia %1!, {%2, %3}
- " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
- : "0" (offset), "1" (buf));
+ __asm__ __volatile__(
+ "ldr%?h %2, [%0], #4\n\t"
+ "ldr%?h %3, [%0], #4\n\t"
+ "orr%? %2, %2, %3, lsl #16\n\t"
+ "ldr%?h %3, [%0], #4\n\t"
+ "ldr%?h %4, [%0], #4\n\t"
+ "orr%? %3, %3, %4, lsl #16\n\t"
+ "stm%?ia %1!, {%2, %3}"
+ : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
+ : "0" (offset), "1" (buf));
length -= 8;
}
while (length > 0) {
unsigned int tmp;
- __asm__ __volatile__("
- ldr%?h %2, [%0], #4
- str%?b %2, [%1], #1
- mov%? %2, %2, lsr #8
- str%?b %2, [%1], #1
- " : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
+ __asm__ __volatile__(
+ "ldr%?h %2, [%0], #4\n\t"
+ "str%?b %2, [%1], #1\n\t"
+ "mov%? %2, %2, lsr #8\n\t"
+ "str%?b %2, [%1], #1"
+ : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
length -= 2;
}
}
if (status & CSR0_CERR) {
handled = 1;
mod_timer(&priv->timer, jiffies);
+ }
} while (--n && status & (CSR0_RINT | CSR0_TINT));
return IRQ_RETVAL(handled);
static char version[] __initdata =
"at1700.c:v1.15 4/7/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+#define DRV_NAME "at1700"
+
/* Tunable parameters. */
/* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
* ISA
*/
-#ifndef CONFIG_X86_PC9800
static unsigned at1700_probe_list[] __initdata = {
0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
};
-#else /* CONFIG_X86_PC9800 */
-static unsigned at1700_probe_list[] __initdata = {
- 0x1d6, 0x1d8, 0x1da, 0x1d4, 0xd4, 0xd2, 0xd8, 0xd0, 0
-};
-
-#endif /* CONFIG_X86_PC9800 */
/*
* MCA
*/
/* Offsets from the base address. */
-#ifndef CONFIG_X86_PC9800
#define STATUS 0
#define TX_STATUS 0
#define RX_STATUS 1
#define RESET 31 /* Write to reset some parts of the chip. */
#define AT1700_IO_EXTENT 32
#define PORT_OFFSET(o) (o)
-#else /* CONFIG_X86_PC9800 */
-#define STATUS (0x0000)
-#define TX_STATUS (0x0000)
-#define RX_STATUS (0x0001)
-#define TX_INTR (0x0200)/* Bit-mapped interrupt enable registers. */
-#define RX_INTR (0x0201)
-#define TX_MODE (0x0400)
-#define RX_MODE (0x0401)
-#define CONFIG_0 (0x0600)/* Misc. configuration settings. */
-#define CONFIG_1 (0x0601)
-/* Run-time register bank 2 definitions. */
-#define DATAPORT (0x0800)/* Word-wide DMA or programmed-I/O dataport. */
-#define TX_START (0x0a00)
-#define COL16CNTL (0x0a01)/* Controll Reg for 16 collisions */
-#define MODE13 (0x0c01)
-#define RX_CTRL (0x0e00)
-/* Configuration registers only on the '865A/B chips. */
-#define EEPROM_Ctrl (0x1000)
-#define EEPROM_Data (0x1200)
-#define CARDSTATUS 16 /* FMV-18x Card Status */
-#define CARDSTATUS1 17 /* FMV-18x Card Status */
-#define IOCONFIG (0x1400)/* Either read the jumper, or move the I/O. */
-#define IOCONFIG1 (0x1600)
-#define SAPROM 20 /* The station address PROM, if no EEPROM. */
-#define MODE24 (0x1800)/* The station address PROM, if no EEPROM. */
-#define RESET (0x1e01)/* Write to reset some parts of the chip. */
-#define PORT_OFFSET(o) ({ int _o_ = (o); (_o_ & ~1) * 0x100 + (_o_ & 1); })
-#endif /* CONFIG_X86_PC9800 */
#define TX_TIMEOUT 10
(detachable devices only).
*/
-#ifndef CONFIG_X86_PC9800
static int io = 0x260;
-#else
-static int io = 0xd0;
-#endif
static int irq;
{
#ifdef CONFIG_MCA
struct net_local *lp = netdev_priv(dev);
- if (lp->mca_slot)
+ if (lp->mca_slot >= 0)
mca_mark_as_unused(lp->mca_slot);
#endif
free_irq(dev->irq, NULL);
-#ifndef CONFIG_X86_PC9800
release_region(dev->base_addr, AT1700_IO_EXTENT);
-#else
- {
- int i;
- for (i = 0; i < 0x2000; i += 0x200)
- release_region(dev->base_addr + i, 2);
- }
-#endif
}
struct net_device * __init at1700_probe(int unit)
int slot, ret = -ENODEV;
struct net_local *lp = netdev_priv(dev);
-#ifndef CONFIG_X86_PC9800
- if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME))
return -EBUSY;
-#else
- for (i = 0; i < 0x2000; i += 0x0200) {
- if (!request_region(ioaddr + i, 2, dev->name)) {
- while (i > 0) {
- i -= 0x0200;
- release_region(ioaddr + i, 2);
- }
- return -EBUSY;
- }
- }
-#endif
/* Resetting the chip doesn't reset the ISA interface, so don't bother.
That means we have to be careful with the register values we probe
outb(0, ioaddr + RESET);
if (is_at1700) {
-#ifndef CONFIG_X86_PC9800
irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
| (read_eeprom(ioaddr, 0)>>14)];
-#else
- {
- char re1000plus_irqmap[4] = {3, 5, 6, 12};
- irq = re1000plus_irqmap[inb(ioaddr + IOCONFIG1) >> 6];
- }
-#endif
} else {
/* Check PnP mode for FMV-183/184/183A/184A. */
/* This PnP routine is very poor. IO and IRQ should be known. */
break;
}
if (i == 8) {
- goto err_out;
+ goto err_mca;
}
} else {
if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
- goto err_out;
+ goto err_mca;
irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
}
}
/* Switch to bank 2 */
/* Lock our I/O address, and set manual processing mode for 16 collisions. */
outb(0x08, ioaddr + CONFIG_1);
-#ifndef CONFIG_X86_PC9800
outb(dev->if_port, ioaddr + MODE13);
-#else
- outb(0, ioaddr + MODE13);
-#endif
outb(0x00, ioaddr + COL16CNTL);
if (net_debug)
lp->jumpered = is_fmv18x;
lp->mca_slot = slot;
/* Snarf the interrupt vector now. */
- ret = request_irq(irq, &net_interrupt, 0, dev->name, dev);
+ ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev);
if (ret) {
printk (" AT1700 at %#3x is unusable due to a conflict on"
"IRQ %d.\n", ioaddr, irq);
- goto err_out;
+ goto err_mca;
}
return 0;
+err_mca:
+#ifdef CONFIG_MCA
+ if (slot >= 0)
+ mca_mark_as_unused(slot);
+#endif
err_out:
-#ifndef CONFIG_X86_PC9800
release_region(ioaddr, AT1700_IO_EXTENT);
-#else
- for (i = 0; i < 0x2000; i += 0x0200)
- release_region(ioaddr + i, 2);
-#endif
return ret;
}
#define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
#define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
-/* Delay between EEPROM clock transitions. */
-#ifndef CONFIG_X86_PC9800
-#define eeprom_delay() do { } while (0)
-#else
-#define eeprom_delay() __asm__ ("out%B0 %%al,%0" :: "N"(0x5f))
-#endif
-
/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD (5 << 6)
#define EE_READ_CMD (6 << 6)
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
outb(EE_CS, ee_addr);
outb(dataval, ee_daddr);
- eeprom_delay();
outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
- eeprom_delay();
}
outb(EE_DATA_WRITE, ee_daddr);
for (i = 16; i > 0; i--) {
outb(EE_CS, ee_addr);
- eeprom_delay();
outb(EE_CS | EE_SHIFT_CLK, ee_addr);
- eeprom_delay();
retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
}
/* Terminate the EEPROM access. */
outb(EE_CS, ee_addr);
- eeprom_delay();
outb(EE_SHIFT_CLK, ee_addr);
outb(0, ee_addr);
return retval;
static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
/* fixme */
switch(cmd) {
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct mii_ioctl_data __user *data = (struct mii_ioctl_data __user *)&ifr->ifr_data;
+ struct mii_ioctl_data *data = if_mii(ifr);
struct b44 *bp = netdev_priv(dev);
int err;
/* Yes, the mii is overlaid on the ifreq.ifr_ifru */
strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
- mii = (struct mii_ioctl_data *)&ifr.ifr_data;
+ mii = if_mii(&ifr);
if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
mii->reg_num = MII_BMSR;
if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr)
{
struct ethtool_drvinfo info;
- void *addr = ifr->ifr_data;
+ void __user *addr = ifr->ifr_data;
uint32_t cmd;
- if (get_user(cmd, (uint32_t *)addr)) {
+ if (get_user(cmd, (uint32_t __user *)addr)) {
return -EFAULT;
}
static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
{
struct net_device *slave_dev = NULL;
- struct ifbond *u_binfo = NULL, k_binfo;
- struct ifslave *u_sinfo = NULL, k_sinfo;
+ struct ifbond k_binfo;
+ struct ifbond __user *u_binfo = NULL;
+ struct ifslave k_sinfo;
+ struct ifslave __user *u_sinfo = NULL;
struct mii_ioctl_data *mii = NULL;
int prev_abi_ver = orig_app_abi_ver;
int res = 0;
case SIOCETHTOOL:
return bond_ethtool_ioctl(bond_dev, ifr);
case SIOCGMIIPHY:
- mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+ mii = if_mii(ifr);
if (!mii) {
return -EINVAL;
}
* We do this again just in case we were called by SIOCGMIIREG
* instead of SIOCGMIIPHY.
*/
- mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+ mii = if_mii(ifr);
if (!mii) {
return -EINVAL;
}
return 0;
case BOND_INFO_QUERY_OLD:
case SIOCBONDINFOQUERY:
- u_binfo = (struct ifbond *)ifr->ifr_data;
+ u_binfo = (struct ifbond __user *)ifr->ifr_data;
if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
return -EFAULT;
return res;
case BOND_SLAVE_INFO_QUERY_OLD:
case SIOCBONDSLAVEINFOQUERY:
- u_sinfo = (struct ifslave *)ifr->ifr_data;
+ u_sinfo = (struct ifslave __user *)ifr->ifr_data;
if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
return -EFAULT;
static char version[] __initdata =
"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
+#define DRV_NAME "cs89x0"
+
/* First, a few definitions that the brave might change.
A zero-terminated list of I/O addresses to be probed. Some special flags..
Addr & 1 = Read back the address port, look for signature and reset
}
__setup("cs89x0_media=", media_fn);
-#endif
\f
/* Check for a network adaptor of this type, and return '0' iff one exists.
printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
return ERR_PTR(err);
}
+#endif
static int
readreg(struct net_device *dev, int portno)
/* Grab the region so we can find another board if autoIRQ fails. */
/* WTF is going on here? */
- if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) {
+ if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
- dev->name, ioaddr, NETCARD_IO_EXTENT);
+ DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
retval = -EBUSY;
goto out1;
}
static char version[] __devinitdata =
"defxx.c:v1.06 2003/08/04 Lawrence V. Stefani and others\n";
+#define DRV_NAME "defxx"
+
#define DYNAMIC_BUFFERS 1
#define SKBUFF_RX_COPYBREAK 200
bp = dev->priv;
- if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, dev->name)) {
+ if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, DRV_NAME)) {
printk (KERN_ERR "%s: Cannot reserve I/O resource 0x%x @ 0x%lx, aborting\n",
- dev->name, PFI_K_CSR_IO_LEN, ioaddr);
+ DRV_NAME, PFI_K_CSR_IO_LEN, ioaddr);
err = -EBUSY;
goto err_out;
}
static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct depca_private *lp = (struct depca_private *) dev->priv;
- struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data;
+ struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_ifru;
int i, status = 0;
u_long ioaddr = dev->base_addr;
union {
struct depca_ioctl {
unsigned short cmd; /* Command to run */
unsigned short len; /* Length of the data buffer */
- unsigned char *data; /* Pointer to the data buffer */
+ unsigned char __user *data; /* Pointer to the data buffer */
};
/*
static void set_multicast (struct net_device *dev);
static struct net_device_stats *get_stats (struct net_device *dev);
static int clear_stats (struct net_device *dev);
-static int rio_ethtool_ioctl (struct net_device *dev, void *useraddr);
+static int rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr);
static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int rio_close (struct net_device *dev);
static int find_miiphy (struct net_device *dev);
}
static int
-rio_ethtool_ioctl (struct net_device *dev, void *useraddr)
+rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
{
struct netdev_private *np = dev->priv;
u32 ethcmd;
{
int phy_addr;
struct netdev_private *np = dev->priv;
- struct mii_data *miidata = (struct mii_data *) &rq->ifr_data;
+ struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
struct netdev_desc *desc;
int i;
phy_addr = np->phy_addr;
switch (cmd) {
case SIOCETHTOOL:
- return rio_ethtool_ioctl (dev, (void *) rq->ifr_data);
+ return rio_ethtool_ioctl(dev, rq->ifr_data);
case SIOCDEVPRIVATE:
break;
cb->prev->command &= cpu_to_le16(~cb_s);
while(nic->cb_to_send != nic->cb_to_use) {
- if(unlikely((err = e100_exec_cmd(nic, nic->cuc_cmd,
- nic->cb_to_send->dma_addr)))) {
+ if(unlikely(e100_exec_cmd(nic, nic->cuc_cmd,
+ nic->cb_to_send->dma_addr))) {
/* Ok, here's where things get sticky. It's
* possible that we can't schedule the command
* because the controller is too busy, so
static void e100_clean_cbs(struct nic *nic)
{
if(nic->cbs) {
- while(nic->cb_to_clean != nic->cb_to_use) {
+ while(nic->cbs_avail != nic->params.cbs.count) {
struct cb *cb = nic->cb_to_clean;
if(cb->skb) {
pci_unmap_single(nic->pdev,
dev_kfree_skb(cb->skb);
}
nic->cb_to_clean = nic->cb_to_clean->next;
+ nic->cbs_avail++;
}
- nic->cbs_avail = nic->params.cbs.count;
pci_free_consistent(nic->pdev,
sizeof(struct cb) * nic->params.cbs.count,
nic->cbs, nic->cbs_dma_addr);
goto err_clean_cbs;
e100_set_multicast_list(nic->netdev);
e100_start_receiver(nic);
- netif_start_queue(nic->netdev);
mod_timer(&nic->watchdog, jiffies);
if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
nic->netdev->name, nic->netdev)))
goto err_no_irq;
e100_enable_irq(nic);
+ netif_wake_queue(nic->netdev);
return 0;
err_no_irq:
del_timer_sync(&nic->watchdog);
- netif_stop_queue(nic->netdev);
err_clean_cbs:
e100_clean_cbs(nic);
err_rx_clean_list:
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct nic *nic = netdev_priv(netdev);
- struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr->ifr_data;
- return generic_mii_ioctl(&nic->mii, mii, cmd, NULL);
+ return generic_mii_ioctl(&nic->mii, if_mii(ifr), cmd, NULL);
}
static int e100_alloc(struct nic *nic)
struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
struct sk_buff *skb;
- if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + 2, GFP_KERNEL))) {
+ if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
+ GFP_KERNEL))) {
ret_val = 6;
goto err_nomem;
}
- skb_reserve(skb, 2);
+ skb_reserve(skb, NET_IP_ALIGN);
rxdr->buffer_info[i].skb = skb;
rxdr->buffer_info[i].length = E1000_RXBUFFER_2048;
rxdr->buffer_info[i].dma =
char e1000_driver_name[] = "e1000";
char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "5.2.52-k2";
+char e1000_driver_version[] = "5.2.52-k4";
char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
/* e1000_pci_tbl - PCI Device ID Table
if(work_done < work_to_do || !netif_running(netdev)) {
netif_rx_complete(netdev);
e1000_irq_enable(adapter);
+ return 0;
}
return (work_done >= work_to_do);
struct e1000_rx_desc *rx_desc;
struct e1000_buffer *buffer_info;
struct sk_buff *skb;
- int reserve_len = 2;
unsigned int i;
i = rx_ring->next_to_use;
while(!buffer_info->skb) {
rx_desc = E1000_RX_DESC(*rx_ring, i);
- skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
+ skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
if(!skb) {
/* Better luck next round */
* this will result in a 16 byte aligned IP header after
* the 14 byte MAC header is removed
*/
- skb_reserve(skb, reserve_len);
+ skb_reserve(skb, NET_IP_ALIGN);
skb->dev = netdev;
e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct e1000_adapter *adapter = netdev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+ struct mii_ioctl_data *data = if_mii(ifr);
int retval;
uint16_t mii_reg;
uint16_t spddplx;
#include "8390.h"
+#define DRV_NAME "e2100"
+
static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
/* Offsets from the base_addr.
release_region(dev->base_addr, E21_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init e2100_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init e21_probe1(struct net_device *dev, int ioaddr)
{
unsigned char *station_addr = dev->dev_addr;
static unsigned version_printed;
- if (!request_region(ioaddr, E21_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME))
return -EBUSY;
/* First check the station address for the Ctron prefix. */
#include <asm/io.h>
#include <asm/dma.h>
+#define DRV_NAME "eepro"
+
#define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
/* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
#define SLOW_DOWN inb(0x80)
return -ENODEV;
}
+#ifndef MODULE
struct net_device * __init eepro_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local));
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
{
int ioaddr = dev->base_addr;
/* Grab the region so we can find another board if autoIRQ fails. */
- if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) {
+ if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
if (!autoprobe)
printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
ioaddr);
return &sp->stats;
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
u32 ethcmd;
struct speedo_private *sp = netdev_priv(dev);
static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct speedo_private *sp = netdev_priv(dev);
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
int phy = sp->phy[0] & 0x1f;
int saved_acpi;
int t;
pci_set_power_state(sp->pdev, saved_acpi);
return 0;
case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return netdev_ethtool_ioctl(dev, rq->ifr_data);
default:
return -EOPNOTSUPP;
}
return -ENODEV;
}
+#ifndef MODULE
struct net_device * __init express_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
/*
* open and initialize the adapter, ready for use
LK1.1.14 (Kryzsztof Halasa):
* fix spurious bad initializations
* pound phy a la SMSC's app note on the subject
+
+ AC1.1.14ac
+ * fix power up/down for ethtool that broke in 1.11
*/
#define DRV_NAME "epic100"
-#define DRV_VERSION "1.11+LK1.1.14"
-#define DRV_RELDATE "Aug 4, 2002"
+#define DRV_VERSION "1.11+LK1.1.14+AC1.1.14"
+#define DRV_RELDATE "June 2, 2004"
/* The user-configurable values.
These may be modified when a driver module is loaded.*/
ep->rx_ring[entry].bufaddr,
ep->rx_buf_sz,
PCI_DMA_FROMDEVICE);
-#if 1 /* HAS_IP_COPYSUM */
eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
-#else
- memcpy(skb_put(skb, pkt_len), ep->rx_skbuff[entry]->tail,
- pkt_len);
-#endif
pci_dma_sync_single_for_device(ep->pci_dev,
ep->rx_ring[entry].bufaddr,
ep->rx_buf_sz,
debug = value;
}
+static int ethtool_begin(struct net_device *dev)
+{
+ unsigned long ioaddr = dev->base_addr;
+ /* power-up, if interface is down */
+ if (! netif_running(dev)) {
+ outl(0x0200, ioaddr + GENCTL);
+ outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
+ }
+ return 0;
+}
+
+static void ethtool_complete(struct net_device *dev)
+{
+ unsigned long ioaddr = dev->base_addr;
+ /* power-down, if interface is down */
+ if (! netif_running(dev)) {
+ outl(0x0008, ioaddr + GENCTL);
+ outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
+ }
+}
+
static struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
.get_settings = netdev_get_settings,
.set_msglevel = netdev_set_msglevel,
.get_sg = ethtool_op_get_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
+ .begin = ethtool_begin,
+ .complete = ethtool_complete
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct epic_private *np = dev->priv;
long ioaddr = dev->base_addr;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
int rc;
/* power-up, if interface is down */
return 0;
}
-static int eql_enslave(struct net_device *dev, slaving_request_t *srq);
-static int eql_emancipate(struct net_device *dev, slaving_request_t *srq);
+static int eql_enslave(struct net_device *dev, slaving_request_t __user *srq);
+static int eql_emancipate(struct net_device *dev, slaving_request_t __user *srq);
-static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *sc);
-static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *sc);
+static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *sc);
+static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *sc);
-static int eql_g_master_cfg(struct net_device *dev, master_config_t *mc);
-static int eql_s_master_cfg(struct net_device *dev, master_config_t *mc);
+static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mc);
+static int eql_s_master_cfg(struct net_device *dev, master_config_t __user *mc);
static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case EQL_ENSLAVE:
- return eql_enslave(dev,
- (slaving_request_t *) ifr->ifr_data);
+ return eql_enslave(dev, ifr->ifr_data);
case EQL_EMANCIPATE:
- return eql_emancipate(dev,
- (slaving_request_t *) ifr->ifr_data);
+ return eql_emancipate(dev, ifr->ifr_data);
case EQL_GETSLAVECFG:
- return eql_g_slave_cfg(dev,
- (slave_config_t *) ifr->ifr_data);
+ return eql_g_slave_cfg(dev, ifr->ifr_data);
case EQL_SETSLAVECFG:
- return eql_s_slave_cfg(dev,
- (slave_config_t *) ifr->ifr_data);
+ return eql_s_slave_cfg(dev, ifr->ifr_data);
case EQL_GETMASTRCFG:
- return eql_g_master_cfg(dev,
- (master_config_t *) ifr->ifr_data);
+ return eql_g_master_cfg(dev, ifr->ifr_data);
case EQL_SETMASTRCFG:
- return eql_s_master_cfg(dev,
- (master_config_t *) ifr->ifr_data);
+ return eql_s_master_cfg(dev, ifr->ifr_data);
default:
return -EOPNOTSUPP;
};
return -ENOSPC;
}
-static int eql_enslave(struct net_device *master_dev, slaving_request_t *srqp)
+static int eql_enslave(struct net_device *master_dev, slaving_request_t __user *srqp)
{
struct net_device *slave_dev;
slaving_request_t srq;
return -EINVAL;
}
-static int eql_emancipate(struct net_device *master_dev, slaving_request_t *srqp)
+static int eql_emancipate(struct net_device *master_dev, slaving_request_t __user *srqp)
{
equalizer_t *eql = master_dev->priv;
struct net_device *slave_dev;
return ret;
}
-static int eql_g_slave_cfg(struct net_device *dev, slave_config_t *scp)
+static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
{
equalizer_t *eql = dev->priv;
slave_t *slave;
return -EFAULT;
slave_dev = dev_get_by_name(sc.slave_name);
+ if (!slave_dev)
+ return -ENODEV;
ret = -EINVAL;
return ret;
}
-static int eql_s_slave_cfg(struct net_device *dev, slave_config_t *scp)
+static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
{
slave_t *slave;
equalizer_t *eql;
if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
return -EFAULT;
- eql = dev->priv;
slave_dev = dev_get_by_name(sc.slave_name);
+ if (!slave_dev)
+ return -ENODEV;
ret = -EINVAL;
+ eql = dev->priv;
spin_lock_bh(&eql->queue.lock);
if (eql_is_slave(slave_dev)) {
slave = __eql_find_slave_dev(&eql->queue, slave_dev);
return ret;
}
-static int eql_g_master_cfg(struct net_device *dev, master_config_t *mcp)
+static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mcp)
{
equalizer_t *eql;
master_config_t mc;
return -EINVAL;
}
-static int eql_s_master_cfg(struct net_device *dev, master_config_t *mcp)
+static int eql_s_master_cfg(struct net_device *dev, master_config_t __user *mcp)
{
equalizer_t *eql;
master_config_t mc;
release_region(dev->base_addr, ES_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init es_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init es_probe1(struct net_device *dev, int ioaddr)
{
return -ENODEV;
}
+#ifndef MODULE
struct net_device * __init eth16i_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
{
int retval;
/* Let's grab the region */
- if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, ETH16I_IO_EXTENT, cardname))
return -EBUSY;
/*
/* Try to obtain interrupt vector */
- if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, dev->name, dev))) {
- printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n",
- dev->name, cardname, ioaddr, dev->irq);
+ if ((retval = request_irq(dev->irq, (void *)ð16i_interrupt, 0, cardname, dev))) {
+ printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n",
+ cardname, ioaddr, dev->irq);
goto out;
}
mdelay(1);\
}
+#ifndef MODULE
struct net_device * __init ewrk3_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private));
return ERR_PTR(err);
}
+#endif
static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
{
for (; (i < maxSlots) && (dev != NULL);
iobase += EWRK3_IOP_INC, i++)
{
- if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name)) {
+ if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME)) {
if (DevicePresent(iobase) == 0) {
int irq = dev->irq;
ret = ewrk3_hw_init(dev, iobase);
for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
if (EISA_signature(name, EISA_ID) == 0) {
- if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name) &&
+ if (request_region(iobase, EWRK3_TOTAL_SIZE, DRV_NAME) &&
DevicePresent(iobase) == 0) {
int irq = dev->irq;
ret = ewrk3_hw_init(dev, iobase);
return status; /* return the device name string */
}
-static int ewrk3_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int ewrk3_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv;
u_long iobase = dev->base_addr;
u32 ethcmd;
- if (get_user(ethcmd, (u32 *)useraddr))
+ if (get_user(ethcmd, (u32 __user *)useraddr))
return -EFAULT;
switch (ethcmd) {
static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct ewrk3_private *lp = (struct ewrk3_private *) dev->priv;
- struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_data;
+ struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_ifru;
u_long iobase = dev->base_addr;
int i, j, status = 0;
u_char csr;
/* ethtool IOCTLs are handled elsewhere */
if (cmd == SIOCETHTOOL)
- return ewrk3_ethtool_ioctl(dev, (void *)rq->ifr_data);
+ return ewrk3_ethtool_ioctl(dev, rq->ifr_data);
/* Other than ethtool, all we handle are private IOCTLs */
if (cmd != EWRK3IOCTL)
struct ewrk3_ioctl {
unsigned short cmd; /* Command to run */
unsigned short len; /* Length of the data buffer */
- unsigned char *data; /* Pointer to the data buffer */
+ unsigned char __user *data; /* Pointer to the data buffer */
};
/*
others + includes if_fcdevice.h */
#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
#include "../../fc4/fcp.h"
#include <asm/system.h>
{
struct netdev_private *np = dev->priv;
long ioaddr = dev->base_addr;
+ int i;
writel(0x00000001, ioaddr + BCR); /* Reset */
if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev))
return -EAGAIN;
+ for (i = 0; i < 3; i++)
+ writew(((unsigned short*)dev->dev_addr)[i],
+ ioaddr + PAR0 + i*2);
+
init_ring(dev);
writel(np->rx_ring_dma, ioaddr + RXLBA);
static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct netdev_private *np = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
int rc;
if (!netif_running(dev))
return -EINVAL;
spin_lock_irq(&np->lock);
- rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
+ rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
return rc;
#include <asm/io.h>
#include <asm/dma.h>
+#define DRV_NAME "fmv18x"
+
static unsigned fmv18x_probe_list[] __initdata = {
0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
};
That means we have to be careful with the register values we probe for.
*/
- if (!request_region(ioaddr, FMV18X_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, FMV18X_IO_EXTENT, DRV_NAME))
return -EBUSY;
dev->irq = irq;
}
/* Snarf the interrupt vector now. */
- retval = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
+ retval = request_irq(dev->irq, &net_interrupt, 0, DRV_NAME, dev);
if (retval) {
printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
"IRQ %d.\n", ioaddr, dev->irq);
* superfluous timer interrupts from the nic.
*/
#define FORCEDETH_VERSION "0.25"
+#define DRV_NAME "forcedeth"
#include <linux/module.h>
#include <linux/types.h>
return &np->stats;
}
-static int nv_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int nv_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct fe_priv *np = get_nvpriv(dev);
u8 *base = get_hwbase(dev);
{
switch(cmd) {
case SIOCETHTOOL:
- return nv_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return nv_ethtool_ioctl(dev, rq->ifr_data);
default:
return -EOPNOTSUPP;
pci_set_master(pci_dev);
- err = pci_request_regions(pci_dev, dev->name);
+ err = pci_request_regions(pci_dev, DRV_NAME);
if (err < 0)
goto out_disable;
}
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct hamachi_private *np = dev->priv;
u32 ethcmd;
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct hamachi_private *np = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
int rc;
if (!netif_running(dev))
return -EINVAL;
if (cmd == SIOCETHTOOL)
- rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
else if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */
- u32 *d = (u32 *)&rq->ifr_data;
+ u32 *d = (u32 *)&rq->ifr_ifru;
/* Should add this check here or an ordinary user can do nasty
* things. -KDU
*
bc = netdev_priv(dev);
if (cmd != SIOCDEVPRIVATE)
return -ENOIOCTLCMD;
- if (get_user(cmd, (int *)ifr->ifr_data))
- return -EFAULT;
if (copy_from_user(&hi, ifr->ifr_data, sizeof(hi)))
return -EFAULT;
{
struct baycom_state *bc;
struct baycom_ioctl bi;
- int cmd2;
if (!dev || !dev->priv ||
((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
if (cmd != SIOCDEVPRIVATE)
return -ENOIOCTLCMD;
- if (get_user(cmd2, (int *)ifr->ifr_data))
- return -EFAULT;
switch (hi->cmd) {
default:
break;
{
struct baycom_state *bc;
struct baycom_ioctl bi;
- int cmd2;
if (!dev || !dev->priv ||
((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
if (cmd != SIOCDEVPRIVATE)
return -ENOIOCTLCMD;
- if (get_user(cmd2, (int *)ifr->ifr_data))
- return -EFAULT;
switch (hi->cmd) {
default:
break;
{
struct baycom_state *bc;
struct baycom_ioctl bi;
- int cmd2;
if (!dev || !dev->priv ||
((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
if (cmd != SIOCDEVPRIVATE)
return -ENOIOCTLCMD;
- if (get_user(cmd2, (int *)ifr->ifr_data))
- return -EFAULT;
switch (hi->cmd) {
default:
break;
*/
static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data;
+ struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
struct bpqdev *bpq = dev->priv;
struct bpq_req req;
struct scc_mem_config memcfg;
struct scc_hw_config hwcfg;
struct scc_calibrate cal;
- struct scc_channel *scc;
+ struct scc_channel *scc = (struct scc_channel *) dev->priv;
int chan;
unsigned char device_name[IFNAMSIZ];
- void *arg;
+ void __user *arg = ifr->ifr_data;
- scc = (struct scc_channel *) dev->priv;
- arg = (void *) ifr->ifr_data;
if (!Driver_Initialized)
{
#include "8390.h"
+#define DRV_NAME "hp-plus"
+
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int hpplus_portlist[] __initdata =
{0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init hp_plus_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
/* Do the interesting part of the probe at a single address. */
static int __init hpp_probe1(struct net_device *dev, int ioaddr)
int mem_start;
static unsigned version_printed;
- if (!request_region(ioaddr, HP_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
return -EBUSY;
/* Check for the HP+ signature, 50 48 0x 53. */
#include "8390.h"
+#define DRV_NAME "hp"
+
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int hppclan_portlist[] __initdata =
{ 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0};
release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init hp_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init hp_probe1(struct net_device *dev, int ioaddr)
{
const char *name;
static unsigned version_printed;
- if (!request_region(ioaddr, HP_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
return -EBUSY;
/* Check for the HP physical address, 08 00 09 xx xx xx. */
outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
if (irq == probe_irq_off(cookie) /* It's a good IRQ line! */
- && request_irq (irq, ei_interrupt, 0, dev->name, dev) == 0) {
+ && request_irq (irq, ei_interrupt, 0, DRV_NAME, dev) == 0) {
printk(" selecting IRQ %d.\n", irq);
dev->irq = *irqp;
break;
} else {
if (dev->irq == 2)
dev->irq = 9;
- if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+ if ((retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) {
printk (" unable to get IRQ %d.\n", dev->irq);
goto out;
}
}
+#ifndef MODULE
struct net_device * __init hp100_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init hp100_probe1(struct net_device *dev, int ioaddr,
u_char bus, struct pci_dev *pci_dev)
static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct ocp_enet_private *fep = dev->priv;
- uint *data = (uint *) & rq->ifr_data;
+ uint *data = (uint *) & rq->ifr_ifru;
switch (cmd) {
case SIOCGMIIPHY:
#undef DEBUG
+#define DRV_NAME "ibmlana"
+
/* ------------------------------------------------------------------------
* global static data - not more since we can handle multiple boards and
* have to pack all state info into the device struct!
printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
/* try to obtain I/O range */
- if (!request_region(iobase, IBM_LANA_IORANGE, dev->name)) {
- printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", dev->name, iobase);
+ if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
+ printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
startslot = slot + 1;
return -EBUSY;
}
adapter = netdev->priv;
memset(adapter, 0, sizeof(adapter));
- dev->driver_data = netdev;
+ dev->dev.driver_data = netdev;
adapter->vdev = dev;
adapter->netdev = netdev;
static int __devexit ibmveth_remove(struct vio_dev *dev)
{
- struct net_device *netdev = dev->driver_data;
+ struct net_device *netdev = dev->dev.driver_data;
struct ibmveth_adapter *adapter = netdev->priv;
unregister_netdev(netdev);
static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
struct ioc3_private *ip = netdev_priv(dev);
int rc;
spin_lock_irq(&ip->ioc3_lock);
- rc = generic_mii_ioctl(&ip->mii, data, cmd, NULL);
+ rc = generic_mii_ioctl(&ip->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&ip->ioc3_lock);
return rc;
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/serial_reg.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/dma.h>
self->tx_buff.truesize = 14384;
/* Allocate memory if needed */
- self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
- GFP_KERNEL |GFP_DMA);
+ self->rx_buff.head =
+ dma_alloc_coherent(NULL, self->rx_buff.truesize,
+ &self->rx_buff_dma, GFP_KERNEL);
if (self->rx_buff.head == NULL) {
err = -ENOMEM;
goto err_out2;
}
memset(self->rx_buff.head, 0, self->rx_buff.truesize);
- self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->tx_buff.head =
+ dma_alloc_coherent(NULL, self->tx_buff.truesize,
+ &self->tx_buff_dma, GFP_KERNEL);
if (self->tx_buff.head == NULL) {
err = -ENOMEM;
goto err_out3;
return 0;
err_out4:
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
err_out3:
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
err_out2:
release_region(self->io.fir_base, self->io.fir_ext);
err_out1:
release_region(self->io.fir_base, self->io.fir_ext);
if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
if (self->rx_buff.head)
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
dev_self[self->index] = NULL;
free_netdev(self->netdev);
self->io.direction = IO_XMIT;
irda_setup_dma(self->io.dma,
- self->tx_fifo.queue[self->tx_fifo.ptr].start,
+ ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start -
+ self->tx_buff.head) + self->tx_buff_dma,
self->tx_fifo.queue[self->tx_fifo.ptr].len,
DMA_TX_MODE);
self->st_fifo.len = self->st_fifo.pending_bytes = 0;
self->st_fifo.tail = self->st_fifo.head = 0;
- irda_setup_dma(self->io.dma, self->rx_buff.data,
- self->rx_buff.truesize, DMA_RX_MODE);
+ irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
+ DMA_RX_MODE);
/* Set Receive Mode,Brick Wall */
//switch_bank(iobase, BANK0);
#include <linux/spinlock.h>
#include <linux/pm.h>
+#include <linux/types.h>
#include <asm/io.h>
/* SIR Register */
chipio_t io; /* IrDA controller information */
iobuff_t tx_buff; /* Transmit buffer */
iobuff_t rx_buff; /* Receive buffer */
+ dma_addr_t tx_buff_dma;
+ dma_addr_t rx_buff_dma;
__u8 ier; /* Interrupt enable register */
struct irtty_info { char name[6]; } info;
struct sir_dev *dev;
struct sirtty_cb *priv = tty->disc_data;
- int size = _IOC_SIZE(cmd);
int err = 0;
ASSERT(priv != NULL, return -ENODEV;);
dev = priv->dev;
ASSERT(dev != NULL, return -1;);
- if (_IOC_DIR(cmd) & _IOC_READ)
- err = verify_area(VERIFY_WRITE, (void *) arg, size);
- else if (_IOC_DIR(cmd) & _IOC_WRITE)
- err = verify_area(VERIFY_READ, (void *) arg, size);
- if (err)
- return err;
-
switch (cmd) {
case TCGETS:
case TCGETA:
memset(&info, 0, sizeof(info));
strncpy(info.name, dev->netdev->name, sizeof(info.name)-1);
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
err = -EFAULT;
break;
default:
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/dma.h>
self->tx_buff.truesize = 14384;
/* Allocate memory if needed */
- self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->rx_buff.head =
+ dma_alloc_coherent(NULL, self->rx_buff.truesize,
+ &self->rx_buff_dma, GFP_KERNEL);
if (self->rx_buff.head == NULL) {
err = -ENOMEM;
goto out2;
}
memset(self->rx_buff.head, 0, self->rx_buff.truesize);
- self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->tx_buff.head =
+ dma_alloc_coherent(NULL, self->tx_buff.truesize,
+ &self->tx_buff_dma, GFP_KERNEL);
if (self->tx_buff.head == NULL) {
err = -ENOMEM;
goto out3;
return 0;
out4:
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
out3:
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
out2:
release_region(self->io.fir_base, self->io.fir_ext);
out1:
release_region(self->io.fir_base, self->io.fir_ext);
if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
if (self->rx_buff.head)
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
dev_self[self->index] = NULL;
free_netdev(self->netdev);
outb(ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1);
irda_setup_dma(self->io.dma,
- self->tx_fifo.queue[self->tx_fifo.ptr].start,
+ ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start -
+ self->tx_buff.head) + self->tx_buff_dma,
self->tx_fifo.queue[self->tx_fifo.ptr].len,
DMA_TX_MODE);
self->st_fifo.len = self->st_fifo.pending_bytes = 0;
self->st_fifo.tail = self->st_fifo.head = 0;
- irda_setup_dma(self->io.dma, self->rx_buff.data,
- self->rx_buff.truesize, DMA_RX_MODE);
+ irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
+ DMA_RX_MODE);
/* Enable DMA */
switch_bank(iobase, BANK0);
#include <linux/spinlock.h>
#include <linux/pm.h>
+#include <linux/types.h>
#include <asm/io.h>
/* DMA modes needed */
chipio_t io; /* IrDA controller information */
iobuff_t tx_buff; /* Transmit buffer */
iobuff_t rx_buff; /* Receive buffer */
+ dma_addr_t tx_buff_dma;
+ dma_addr_t rx_buff_dma;
__u8 ier; /* Interrupt enable register */
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/serial_reg.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/dma.h>
chipio_t io; /* IrDA controller information */
iobuff_t tx_buff; /* Transmit buffer */
iobuff_t rx_buff; /* Receive buffer */
+ dma_addr_t tx_buff_dma;
+ dma_addr_t rx_buff_dma;
struct qos_info qos; /* QoS capabilities for this device */
self->rx_buff.truesize = SMSC_IRCC2_RX_BUFF_TRUESIZE;
self->tx_buff.truesize = SMSC_IRCC2_TX_BUFF_TRUESIZE;
- self->rx_buff.head = (u8 *) kmalloc(self->rx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->rx_buff.head =
+ dma_alloc_coherent(NULL, self->rx_buff.truesize,
+ &self->rx_buff_dma, GFP_KERNEL);
if (self->rx_buff.head == NULL) {
ERROR("%s, Can't allocate memory for receive buffer!\n",
driver_name);
goto err_out2;
}
- self->tx_buff.head = (u8 *) kmalloc(self->tx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->tx_buff.head =
+ dma_alloc_coherent(NULL, self->tx_buff.truesize,
+ &self->tx_buff_dma, GFP_KERNEL);
if (self->tx_buff.head == NULL) {
ERROR("%s, Can't allocate memory for transmit buffer!\n",
driver_name);
return 0;
err_out4:
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
err_out3:
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
err_out2:
free_netdev(self->netdev);
dev_self[--dev_count] = NULL;
IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
/* Setup DMA controller (must be done after enabling chip DMA) */
- irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len,
+ irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
DMA_TX_MODE);
/* Enable interrupt */
outb(2050 & 0xff, iobase+IRCC_RX_SIZE_LO);
/* Setup DMA controller */
- irda_setup_dma(self->io.dma, self->rx_buff.data,
- self->rx_buff.truesize, DMA_RX_MODE);
+ irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
+ DMA_RX_MODE);
/* Enable burst mode chip Rx DMA */
register_bank(iobase, 1);
release_region(self->io.sir_base, self->io.sir_ext);
if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
if (self->rx_buff.head)
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
free_netdev(self->netdev);
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/dma.h>
/* Allocate memory if needed */
self->rx_buff.head =
- (__u8 *) kmalloc(self->rx_buff.truesize, GFP_KERNEL | GFP_DMA);
+ dma_alloc_coherent(NULL, self->rx_buff.truesize,
+ &self->rx_buff_dma, GFP_KERNEL);
if (self->rx_buff.head == NULL) {
err = -ENOMEM;
goto err_out2;
memset(self->rx_buff.head, 0, self->rx_buff.truesize);
self->tx_buff.head =
- (__u8 *) kmalloc(self->tx_buff.truesize, GFP_KERNEL | GFP_DMA);
+ dma_alloc_coherent(NULL, self->tx_buff.truesize,
+ &self->tx_buff_dma, GFP_KERNEL);
if (self->tx_buff.head == NULL) {
err = -ENOMEM;
goto err_out3;
return 0;
err_out4:
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
err_out3:
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
err_out2:
release_region(self->io.fir_base, self->io.fir_ext);
err_out1:
__FUNCTION__, self->io.fir_base);
release_region(self->io.fir_base, self->io.fir_ext);
if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
if (self->rx_buff.head)
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
dev_self[self->index] = NULL;
free_netdev(self->netdev);
EnTXDMA(iobase, ON);
EnRXDMA(iobase, OFF);
- irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len,
+ irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
DMA_TX_MODE);
SetSendByte(iobase, self->tx_buff.len);
EnTXDMA(iobase, ON);
EnRXDMA(iobase, OFF);
irda_setup_dma(self->io.dma,
- self->tx_fifo.queue[self->tx_fifo.ptr].start,
+ ((u8 *)self->tx_fifo.queue[self->tx_fifo.ptr].start -
+ self->tx_buff.head) + self->tx_buff_dma,
self->tx_fifo.queue[self->tx_fifo.ptr].len, DMA_TX_MODE);
#ifdef DBGMSG
DBG(printk
EnAllInt(iobase, ON);
EnTXDMA(iobase, OFF);
EnRXDMA(iobase, ON);
- irda_setup_dma(self->io.dma2, self->rx_buff.data,
- self->rx_buff.truesize, DMA_RX_MODE);
+ irda_setup_dma(self->io.dma2, self->rx_buff_dma,
+ self->rx_buff.truesize, DMA_RX_MODE);
TXStart(iobase, OFF);
RXStart(iobase, ON);
#include <linux/time.h>
#include <linux/spinlock.h>
#include <linux/pm.h>
+#include <linux/types.h>
#include <asm/io.h>
#define MAX_TX_WINDOW 7
chipio_t io; /* IrDA controller information */
iobuff_t tx_buff; /* Transmit buffer */
iobuff_t rx_buff; /* Receive buffer */
+ dma_addr_t tx_buff_dma;
+ dma_addr_t rx_buff_dma;
__u8 ier; /* Interrupt enable register */
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/dma.h>
self->tx_buff.truesize = 4000;
/* Allocate memory if needed */
- self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->rx_buff.head =
+ dma_alloc_coherent(NULL, self->rx_buff.truesize,
+ &self->rx_buff_dma, GFP_KERNEL);
if (self->rx_buff.head == NULL) {
err = -ENOMEM;
goto err_out1;
memset(self->rx_buff.head, 0, self->rx_buff.truesize);
- self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize,
- GFP_KERNEL|GFP_DMA);
+ self->tx_buff.head =
+ dma_alloc_coherent(NULL, self->tx_buff.truesize,
+ &self->tx_buff_dma, GFP_KERNEL);
if (self->tx_buff.head == NULL) {
err = -ENOMEM;
goto err_out2;
return 0;
err_out3:
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
err_out2:
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
err_out1:
free_netdev(dev);
err_out:
release_region(self->io.fir_base, self->io.fir_ext);
if (self->tx_buff.head)
- kfree(self->tx_buff.head);
+ dma_free_coherent(NULL, self->tx_buff.truesize,
+ self->tx_buff.head, self->tx_buff_dma);
if (self->rx_buff.head)
- kfree(self->rx_buff.head);
+ dma_free_coherent(NULL, self->rx_buff.truesize,
+ self->rx_buff.head, self->rx_buff_dma);
free_netdev(self->netdev);
disable_dma(self->io.dma);
clear_dma_ff(self->io.dma);
set_dma_mode(self->io.dma, DMA_MODE_READ);
- set_dma_addr(self->io.dma, isa_virt_to_bus(self->tx_buff.data));
+ set_dma_addr(self->io.dma, self->tx_buff_dma);
set_dma_count(self->io.dma, self->tx_buff.len);
#else
- irda_setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len,
+ irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
DMA_MODE_WRITE);
#endif
self->io.direction = IO_XMIT;
disable_dma(self->io.dma);
clear_dma_ff(self->io.dma);
set_dma_mode(self->io.dma, DMA_MODE_READ);
- set_dma_addr(self->io.dma, isa_virt_to_bus(self->rx_buff.data));
+ set_dma_addr(self->io.dma, self->rx_buff_dma);
set_dma_count(self->io.dma, self->rx_buff.truesize);
#else
- irda_setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize,
+ irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
DMA_MODE_READ);
#endif
/*
#define W83977AF_IR_H
#include <asm/io.h>
+#include <linux/types.h>
/* Flags for configuration register CRF0 */
#define ENBNKSEL 0x01
chipio_t io; /* IrDA controller information */
iobuff_t tx_buff; /* Transmit buffer */
iobuff_t rx_buff; /* Receive buffer */
+ dma_addr_t tx_buff_dma;
+ dma_addr_t rx_buff_dma;
/* Note : currently locking is *very* incomplete, but this
* will get you started. Check in nsc-ircc.c for a proper
release_region(dev->base_addr, NETCARD_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init netcard_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
/*
* This is the real probe routine. Linux has a history of friendly device
static int
ixgb_ethtool_seeprom(struct ixgb_adapter *adapter,
- struct ethtool_eeprom *eeprom, void *user_data)
+ struct ethtool_eeprom *eeprom, void __user *user_data)
{
struct ixgb_hw *hw = &adapter->hw;
uint16_t eeprom_buff[256];
int ixgb_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
{
struct ixgb_adapter *adapter = netdev->priv;
- void *addr = ifr->ifr_data;
+ void __user *addr = ifr->ifr_data;
uint32_t cmd;
- if (get_user(cmd, (uint32_t *) addr))
+ if (get_user(cmd, (uint32_t __user *) addr))
return -EFAULT;
switch (cmd) {
struct ixgb_rx_desc *rx_desc;
struct ixgb_buffer *buffer_info;
struct sk_buff *skb;
- int reserve_len = 2;
unsigned int i;
int num_group_tail_writes;
long cleancount;
while (--cleancount > 0) {
rx_desc = IXGB_RX_DESC(*rx_ring, i);
- skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
+ skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
if (unlikely(!skb)) {
/* Better luck next round */
* this will result in a 16 byte aligned IP header after
* the 14 byte MAC header is removed
*/
- skb_reserve(skb, reserve_len);
+ skb_reserve(skb, NET_IP_ALIGN);
skb->dev = netdev;
#include <asm/jazz.h>
#include <asm/jazzdma.h>
+#define DRV_NAME "jazzsonic"
+
#define SREGS_PAD(n) u16 n;
#include "sonic.h"
int err = -ENODEV;
int i;
- if (!request_region(base_addr, 0x100, dev->name))
+ if (!request_region(base_addr, 0x100, DRV_NAME))
return -EBUSY;
/*
* get the Silicon Revision ID. If this is one of the known
return -ENODEV;
}
+#ifndef MODULE
struct net_device * __init lance_probe(int unit)
{
struct net_device *dev = alloc_etherdev(0);
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
{
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
#include <asm/irq.h>
#include <asm/pdc.h>
#include <asm/cache.h>
#include "8390.h"
+#define DRV_NAME "lne390"
+
static int lne390_probe1(struct net_device *dev, int ioaddr);
static int lne390_open(struct net_device *dev);
SET_MODULE_OWNER(dev);
if (ioaddr > 0x1ff) { /* Check a single specified location. */
- if (!request_region(ioaddr, LNE390_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME))
return -EBUSY;
ret = lne390_probe1(dev, ioaddr);
if (ret)
/* EISA spec allows for up to 16 slots, but 8 is typical. */
for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- if (!request_region(ioaddr, LNE390_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME))
continue;
if (lne390_probe1(dev, ioaddr) == 0)
return 0;
iounmap((void *)dev->mem_start);
}
+#ifndef MODULE
struct net_device * __init lne390_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init lne390_probe1(struct net_device *dev, int ioaddr)
{
}
printk(" IRQ %d,", dev->irq);
- if ((ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+ if ((ret = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) {
printk (" unable to get IRQ %d.\n", dev->irq);
return ret;
}
#include <asm/io.h>
#include <asm/dma.h>
+#define DRV_NAME "lp486e"
+
/* debug print flags */
#define LOG_SRCDST 0x80000000
#define LOG_STATINT 0x40000000
return -ENODEV;
probed++;
- if (!request_region(IOADDR, LP486E_TOTAL_SIZE, dev->name)) {
+ if (!request_region(IOADDR, LP486E_TOTAL_SIZE, DRV_NAME)) {
printk(KERN_ERR "lp486e: IO address 0x%x in use\n", IOADDR);
return -EBUSY;
}
#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_via.h>
-#include <asm/pgalloc.h>
#define SREGS_PAD(n) u16 n;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
- i = pci_request_regions(pdev, dev->name);
+ i = pci_request_regions(pdev, DRV_NAME);
if (i)
goto err_pci_request_regions;
np->rx_dma[entry],
buflen,
PCI_DMA_FROMDEVICE);
-#if HAS_IP_COPYSUM
eth_copy_and_sum(skb,
np->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
-#else
- memcpy(skb_put(skb, pkt_len),
- np->rx_skbuff[entry]->tail, pkt_len);
-#endif
pci_dma_sync_single_for_device(np->pci_dev,
np->rx_dma[entry],
buflen,
spin_unlock_irq(&np->lock);
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct netdev_private *np = dev->priv;
u32 cmd;
- if (get_user(cmd, (u32 *)useraddr))
+ if (get_user(cmd, (u32 __user *)useraddr))
return -EFAULT;
switch (cmd) {
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
switch(cmd) {
case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return netdev_ethtool_ioctl(dev, rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = 1;
#include "8390.h"
+#define DRV_NAME "ne-h8300"
+
/* Some defines that people can play with if so inclined. */
/* Do we perform extra sanity checks on stuff ? */
release_region(dev->base_addr, NE_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init ne_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init ne_probe1(struct net_device *dev, int ioaddr)
{
struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
unsigned char bus_width;
- if (!request_region(ioaddr, NE_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
reg0 = inb_p(ioaddr);
#include "8390.h"
+#define DRV_NAME "ne"
+
/* Some defines that people can play with if so inclined. */
/* Do we support clones that don't adhere to 14,15 of the SAprom ? */
release_region(dev->base_addr, NE_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init ne_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init ne_probe_isapnp(struct net_device *dev)
{
int reg0, ret;
static unsigned version_printed;
- if (!request_region(ioaddr, NE_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
reg0 = inb_p(ioaddr);
#include "8390.h"
+#define DRV_NAME "ne2"
+
/* Some defines that people can play with if so inclined. */
/* Do we perform extra sanity checks on stuff ? */
release_region(dev->base_addr, NE_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init ne2_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
{
irq = irqs[(POS & 0x60)>>5];
}
- if (!request_region(base_addr, NE_IO_EXTENT, dev->name))
+ if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
#ifdef DEBUG
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
- retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+ retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (retval) {
printk (" unable to get IRQ %d (irqval=%d).\n",
dev->irq, retval);
#include "8390.h"
+#define DRV_NAME "ne3210"
+
static int ne3210_open(struct net_device *dev);
static int ne3210_close(struct net_device *dev);
device->driver_data = dev;
ioaddr = edev->base_addr;
- if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) {
+ if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) {
retval = -EBUSY;
goto out;
}
if (!request_region(ioaddr + NE3210_CFG1,
- NE3210_CFG_EXTENT, dev->name)) {
+ NE3210_CFG_EXTENT, DRV_NAME)) {
retval = -EBUSY;
goto out1;
}
dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07];
printk(".\nne3210.c: using IRQ %d, ", dev->irq);
- retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+ retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (retval) {
printk (" unable to get IRQ %d.\n", dev->irq);
goto out2;
}
}
- if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, dev->name)) {
+ if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, DRV_NAME)) {
printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n",
phys_mem);
goto out3;
#include "ni52.h"
+#define DRV_NAME "ni52"
+
#define DEBUG /* debug on */
#define SYSBUSVAL 1 /* 8 Bit */
dev->mem_start = memstart;
dev->mem_end = memend;
- if (!request_region(ioaddr, NI52_TOTAL_SIZE, dev->name))
+ if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME))
return -EBUSY;
if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
#include <asm/uaccess.h>
#include <asm/system.h>
+#define DRV_NAME "ns83820"
+
/* Global parameters. See MODULE_PARM near the bottom. */
static int ihr = 2;
static int reset_phy = 0;
return &dev->stats;
}
-static int ns83820_ethtool_ioctl (struct ns83820 *dev, void *useraddr)
+static int ns83820_ethtool_ioctl (struct ns83820 *dev, void __user *useraddr)
{
u32 ethcmd;
switch(cmd) {
case SIOCETHTOOL:
- return ns83820_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return ns83820_ethtool_ioctl(dev, rq->ifr_data);
default:
return -EOPNOTSUPP;
0);
err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
- ndev->name, ndev);
+ DRV_NAME, ndev);
if (err) {
printk(KERN_INFO "ns83820: unable to register irq %d\n",
pci_dev->irq);
ret = -EAGAIN;
if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) {
printk("%s: unable to request interrupt %d.\n",
- dev->name, dev->irq);
+ name, dev->irq);
goto out_region;
}
static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
struct netdrv_private *tp = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
unsigned long flags;
int rc = 0;
{
struct el3_private *lp = netdev_priv(dev);
ioaddr_t ioaddr = dev->base_addr;
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
int phy = lp->phys & 0x1f;
DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
axnet_dev_t *info = PRIV(dev);
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
switch (cmd) {
case SIOCGMIIPHY:
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
pcnet_dev_t *info = PRIV(dev);
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
switch (cmd) {
case SIOCGMIIPHY:
return 0;
}
-static int smc_ethtool_ioctl (struct net_device *dev, void *useraddr)
+static int smc_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
{
u32 ethcmd;
struct smc_private *smc = netdev_priv(dev);
- if (get_user(ethcmd, (u32 *)useraddr))
+ if (get_user(ethcmd, (u32 __user *)useraddr))
return -EFAULT;
switch (ethcmd) {
u_short saved_bank;
ioaddr_t ioaddr = dev->base_addr;
- mii = (struct mii_ioctl_data *) &rq->ifr_data;
+ mii = if_mii(rq);
if (!netif_running(dev))
return -EINVAL;
case SIOCETHTOOL:
saved_bank = inw(ioaddr + BANK_SELECT);
SMC_SELECT_BANK(3);
- rc = smc_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ rc = smc_ethtool_ioctl(dev, rq->ifr_data);
SMC_SELECT_BANK(saved_bank);
break;
{
local_info_t *local = netdev_priv(dev);
ioaddr_t ioaddr = dev->base_addr;
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct pcnet32_private *lp = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
int rc;
unsigned long flags;
/* SIOC[GS]MIIxxx ioctls */
if (lp->mii) {
spin_lock_irqsave(&lp->lock, flags);
- rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL);
+ rc = generic_mii_ioctl(&lp->mii_if, if_mii(rq), cmd, NULL);
spin_unlock_irqrestore(&lp->lock, flags);
} else {
rc = -EOPNOTSUPP;
plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct net_local *nl = netdev_priv(dev);
- struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
+ struct plipconf *pc = (struct plipconf *) &rq->ifr_ifru;
if (cmd != SIOCDEVPLIP)
return -EOPNOTSUPP;
goto err_out_disable;
}
- rc = pci_request_regions(pdev, dev->name);
+ rc = pci_request_regions(pdev, MODULENAME);
if (rc) {
printk(KERN_ERR PFX "%s: Could not request regions.\n", pdev->slot_name);
goto err_out_disable;
return error;
case SIOCRRID:
- return put_user(0x52523032, (int *)(&rq->ifr_data[0]));
+ return put_user(0x52523032, (int __user *)rq->ifr_data);
default:
return error;
}
};
static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
- {"tmac_frms"},
- {"tmac_data_octets"},
- {"tmac_drop_frms"},
- {"tmac_mcst_frms"},
- {"tmac_bcst_frms"},
- {"tmac_pause_ctrl_frms"},
- {"tmac_any_err_frms"},
- {"tmac_vld_ip_octets"},
- {"tmac_vld_ip"},
- {"tmac_drop_ip"},
- {"tmac_icmp"},
- {"tmac_rst_tcp"},
- {"tmac_tcp"},
- {"tmac_udp"},
- {"rmac_vld_frms"},
- {"rmac_data_octets"},
- {"rmac_fcs_err_frms"},
- {"rmac_drop_frms"},
- {"rmac_vld_mcst_frms"},
- {"rmac_vld_bcst_frms"},
- {"rmac_in_rng_len_err_frms"},
- {"rmac_long_frms"},
- {"rmac_pause_ctrl_frms"},
- {"rmac_discarded_frms"},
- {"rmac_usized_frms"},
- {"rmac_osized_frms"},
- {"rmac_frag_frms"},
- {"rmac_jabber_frms"},
- {"rmac_ip"},
- {"rmac_ip_octets"},
- {"rmac_hdr_err_ip"},
- {"rmac_drop_ip"},
- {"rmac_icmp"},
- {"rmac_tcp"},
- {"rmac_udp"},
- {"rmac_err_drp_udp"},
- {"rmac_pause_cnt"},
- {"rmac_accepted_ip"},
- {"rmac_err_tcp"},
+ "tmac_frms",
+ "tmac_data_octets",
+ "tmac_drop_frms",
+ "tmac_mcst_frms",
+ "tmac_bcst_frms",
+ "tmac_pause_ctrl_frms",
+ "tmac_any_err_frms",
+ "tmac_vld_ip_octets",
+ "tmac_vld_ip",
+ "tmac_drop_ip",
+ "tmac_icmp",
+ "tmac_rst_tcp",
+ "tmac_tcp",
+ "tmac_udp",
+ "rmac_vld_frms",
+ "rmac_data_octets",
+ "rmac_fcs_err_frms",
+ "rmac_drop_frms",
+ "rmac_vld_mcst_frms",
+ "rmac_vld_bcst_frms",
+ "rmac_in_rng_len_err_frms",
+ "rmac_long_frms",
+ "rmac_pause_ctrl_frms",
+ "rmac_discarded_frms",
+ "rmac_usized_frms",
+ "rmac_osized_frms",
+ "rmac_frag_frms",
+ "rmac_jabber_frms",
+ "rmac_ip",
+ "rmac_ip_octets",
+ "rmac_hdr_err_ip",
+ "rmac_drop_ip",
+ "rmac_icmp",
+ "rmac_tcp",
+ "rmac_udp",
+ "rmac_err_drp_udp",
+ "rmac_pause_cnt",
+ "rmac_accepted_ip",
+ "rmac_err_tcp",
};
#define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN
goto end;
}
- skb = dev_alloc_skb(size + HEADER_ALIGN_LAYER_3);
+ skb = dev_alloc_skb(size + NET_IP_ALIGN);
if (!skb) {
DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
return -ENOMEM;
}
- skb_reserve(skb, HEADER_ALIGN_LAYER_3);
+ skb_reserve(skb, NET_IP_ALIGN);
memset(rxdp, 0, sizeof(RxD_t));
rxdp->Buffer0_ptr = pci_map_single
(nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE);
#define HEADER_802_2_SIZE 3
#define HEADER_SNAP_SIZE 5
#define HEADER_VLAN_SIZE 4
-#define HEADER_ALIGN_LAYER_3 2
#define MIN_MTU 46
#define MAX_PYLD 1500
case SIOCGCMFREQUENCY: /* get frequency */
if ((status = sb1000_get_frequency(ioaddr, name, &frequency)))
return status;
- if(put_user(frequency, (int*) ifr->ifr_data))
+ if(put_user(frequency, (int __user *) ifr->ifr_data))
return -EFAULT;
break;
case SIOCSCMFREQUENCY: /* set frequency */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if(get_user(frequency, (int*) ifr->ifr_data))
+ if(get_user(frequency, (int __user *) ifr->ifr_data))
return -EFAULT;
if ((status = sb1000_set_frequency(ioaddr, name, frequency)))
return status;
static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct sbmac_softc *sc = netdev_priv(dev);
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
unsigned long flags;
int retval;
static int shaper_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_data;
+ struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_ifru;
struct shaper *sh=dev->priv;
if(ss->ss_cmd == SHAPER_SET_DEV || ss->ss_cmd == SHAPER_SET_SPEED)
static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
{
struct sis900_private *sis_priv = net_dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
switch(cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
{
struct slip *sl = (struct slip *) tty->disc_data;
unsigned int tmp;
+ int __user *p = (int __user *)arg;
/* First make sure we're connected. */
if (!sl || sl->magic != SLIP_MAGIC) {
switch(cmd) {
case SIOCGIFNAME:
tmp = strlen(sl->dev->name) + 1;
- if (copy_to_user((void *)arg, sl->dev->name, tmp))
+ if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
return -EFAULT;
return 0;
case SIOCGIFENCAP:
- if (put_user(sl->mode, (int *)arg))
+ if (put_user(sl->mode, p))
return -EFAULT;
return 0;
case SIOCSIFENCAP:
- if (get_user(tmp,(int *)arg))
+ if (get_user(tmp, p))
return -EFAULT;
#ifndef SL_INCLUDE_CSLIP
if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) {
#ifdef CONFIG_SLIP_SMART
/* VSV changes start here */
case SIOCSKEEPALIVE:
- if (get_user(tmp,(int *)arg))
+ if (get_user(tmp, p))
return -EFAULT;
if (tmp > 255) /* max for unchar */
return -EINVAL;
return 0;
case SIOCGKEEPALIVE:
- if (put_user(sl->keepalive, (int *)arg))
+ if (put_user(sl->keepalive, p))
return -EFAULT;
return 0;
case SIOCSOUTFILL:
- if (get_user(tmp,(int *)arg))
+ if (get_user(tmp, p))
return -EFAULT;
if (tmp > 255) /* max for unchar */
return -EINVAL;
return 0;
case SIOCGOUTFILL:
- if (put_user(sl->outfill, (int *)arg))
+ if (put_user(sl->outfill, p))
return -EFAULT;
return 0;
/* VSV changes end */
static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
{
struct slip *sl = (struct slip*)(dev->priv);
+ unsigned long *p = (unsigned long *)&rq->ifr_ifru;
if (sl == NULL) /* Allocation failed ?? */
return -ENODEV;
switch(cmd){
case SIOCSKEEPALIVE:
/* max for unchar */
- if (((unsigned int)((unsigned long)rq->ifr_data)) > 255) {
+ if ((unsigned)*p > 255) {
spin_unlock_bh(&sl->lock);
return -EINVAL;
}
- sl->keepalive = (unchar) ((unsigned long)rq->ifr_data);
+ sl->keepalive = (unchar) *p;
if (sl->keepalive != 0) {
sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
break;
case SIOCGKEEPALIVE:
- rq->ifr_data=(caddr_t)((unsigned long)sl->keepalive);
+ *p = sl->keepalive;
break;
case SIOCSOUTFILL:
- if (((unsigned)((unsigned long)rq->ifr_data)) > 255) { /* max for unchar */
+ if ((unsigned)*p > 255) { /* max for unchar */
spin_unlock_bh(&sl->lock);
return -EINVAL;
}
- if ((sl->outfill = (unchar)((unsigned long) rq->ifr_data)) != 0){
+ if ((sl->outfill = (unchar)*p) != 0){
mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
set_bit(SLF_OUTWAIT, &sl->flags);
} else {
break;
case SIOCGOUTFILL:
- rq->ifr_data=(caddr_t)((unsigned long)sl->outfill);
+ *p = sl->outfill;
break;
case SIOCSLEASE:
return -EPERM;
}
sl->leased = 0;
- if ((unsigned long)rq->ifr_data)
+ if (*p)
sl->leased = 1;
break;
case SIOCGLEASE:
- rq->ifr_data=(caddr_t)((unsigned long)sl->leased);
+ *p = sl->leased;
};
spin_unlock_bh(&sl->lock);
return 0;
#include "8390.h"
#include "smc-mca.h"
+#define DRV_NAME "smc-mca"
+
static int ultramca_open(struct net_device *dev);
static void ultramca_reset_8390(struct net_device *dev);
static void ultramca_get_8390_hdr(struct net_device *dev,
goto err_unclaim;
}
- if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) {
+ if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) {
rc = -ENODEV;
goto err_unclaim;
}
#include "8390.h"
+#define DRV_NAME "smc-ultra"
+
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int ultra_portlist[] __initdata =
{0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init ultra_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init ultra_probe1(struct net_device *dev, int ioaddr)
{
unsigned char idreg = inb(ioaddr + 7);
unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
- if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME))
return -EBUSY;
/* Check the ID nibble. */
#include "8390.h"
+#define DRV_NAME "smc-ultra32"
+
static int ultra32_probe1(struct net_device *dev, int ioaddr);
static int ultra32_open(struct net_device *dev);
static void ultra32_reset_8390(struct net_device *dev);
unsigned char reg4;
const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"};
- if (!request_region(ioaddr, ULTRA32_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME))
return -EBUSY;
if (inb(ioaddr + ULTRA32_IDPORT) == 0xff ||
#include "smc9194.h"
+#define DRV_NAME "smc9194"
+
/*------------------------------------------------------------------------
.
. Configuration options, for the experienced user to change.
word memory_cfg_register;
/* Grab the region so that no one else tries to probe our ioports. */
- if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
+ if (!request_region(ioaddr, SMC_IO_EXTENT, DRV_NAME))
return -EBUSY;
dev->irq = irq;
memset(dev->priv, 0, sizeof(struct smc_local));
/* Grab the IRQ */
- retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+ retval = request_irq(dev->irq, &smc_interrupt, 0, DRV_NAME, dev);
if (retval) {
- printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
+ printk("%s: unable to get IRQ %d (irqval=%d).\n", DRV_NAME,
dev->irq, retval);
goto err_out;
}
irq = pdev->irq;
- if (pci_request_regions (pdev, dev->name)) {
+ if (pci_request_regions (pdev, DRV_NAME)) {
printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
goto err_out_free_netdev;
}
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct ethtool_cmd ecmd;
struct netdev_private *np = dev->priv;
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct netdev_private *np = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
int rc;
if (!netif_running(dev))
return -EINVAL;
if (cmd == SIOCETHTOOL)
- rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
else {
+ struct mii_ioctl_data *data = if_mii(rq);
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
spin_unlock_irq(&np->lock);
#include "8390.h"
+#define DRV_NAME "stnic"
+
#define byte unsigned char
#define half unsigned short
#define word unsigned int
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
- err = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev);
+ err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (err) {
printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq);
free_netdev(dev);
#include "sun3_82586.h"
+#define DRV_NAME "sun3_82586"
+
#define DEBUG /* debug on */
#define SYSBUSVAL 0 /* 16 Bit */
#define SUN3_82586_TOTAL_SIZE PAGE_SIZE
{
int i, size, retval;
- if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
+ if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, DRV_NAME))
return -EBUSY;
/* copy in the ethernet address from the prom */
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
#include <asm/dvma.h>
#include <asm/idprom.h>
#include <asm/machines.h>
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct netdev_private *np = dev->priv;
u32 ethcmd;
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct netdev_private *np = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
int rc;
int i;
long ioaddr = dev->base_addr;
return -EINVAL;
if (cmd == SIOCETHTOOL)
- rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
else {
spin_lock_irq(&np->lock);
- rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
+ rc = generic_mii_ioctl(&np->mii_if, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
}
switch (cmd) {
static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct gem *gp = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+ struct mii_ioctl_data *data = if_mii(ifr);
int rc = -EOPNOTSUPP;
/* Hold the PM semaphore while doing ioctl's or we may collide
gp = dev->priv;
- err = pci_request_regions(pdev, dev->name);
+ err = pci_request_regions(pdev, DRV_NAME);
if (err) {
printk(KERN_ERR PFX "Cannot obtain PCI resources, "
"aborting.\n");
#include "sunhme.h"
+#define DRV_NAME "sunhme"
+
static int macaddr[6];
/* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
goto err_out_clear_quattro;
}
- if (pci_request_regions(pdev, dev->name)) {
+ if (pci_request_regions(pdev, DRV_NAME)) {
printk(KERN_ERR "happymeal(PCI): Cannot obtain PCI resources, "
"aborting.\n");
goto err_out_clear_quattro;
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.5"
-#define DRV_MODULE_RELDATE "May 25, 2004"
+#define DRV_MODULE_VERSION "3.6"
+#define DRV_MODULE_RELDATE "June 12, 2004"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX,
static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
+ struct mii_ioctl_data *data = if_mii(ifr);
struct tg3 *tp = netdev_priv(dev);
int err;
udelay(50);
tg3_nvram_init(tp);
+ /* Always use host TXDs, it performs better in particular
+ * with multi-frag packets. The tests below are kept here
+ * as documentation should we change this decision again
+ * in the future.
+ */
+ tp->tg3_flags |= TG3_FLAG_HOST_TXDS;
+
+#if 0
/* Determine if TX descriptors will reside in
* main memory or in the chip SRAM.
*/
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
tp->tg3_flags |= TG3_FLAG_HOST_TXDS;
+#endif
grc_misc_cfg = tr32(GRC_MISC_CFG);
grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
(tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 ||
tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 ||
- tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)))
+ tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) ||
+ (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
+ tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F))
tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
err = tg3_phy_probe(tp);
if (!netif_running(dev))
return 0;
+ pci_restore_state(tp->pdev, tp->pci_cfg_state);
+
err = tg3_set_power_state(tp, 0);
if (err)
return err;
static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
TLanPrivateInfo *priv = dev->priv;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
u32 phy = priv->phy[priv->phyNum];
if (!priv->phyOnline)
config TULIP_NAPI
bool "Use NAPI RX polling "
depends on TULIP
- ---help---
- This is of useful for servers and routers dealing with high network loads.
-
- See <file:Documentation/networking/NAPI_HOWTO.txt>.
+ help
+ NAPI is a new driver API designed to reduce CPU and interrupt load
+ when the driver is receiving lots of packets from the card. It is
+ still somewhat experimental and thus not yet enabled by default.
+
+ If your estimated Rx load is 10kpps or more, or if the card will be
+ deployed on potentially unfriendly networks (e.g. in a firewall),
+ then say Y here.
+
+ See <file:Documentation/networking/NAPI_HOWTO.txt> for more
+ information.
If in doubt, say N.
de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct de4x5_private *lp = netdev_priv(dev);
- struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data;
+ struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_ifru;
u_long iobase = dev->base_addr;
int i, j, status = 0;
s32 omr;
struct de4x5_ioctl {
unsigned short cmd; /* Command to run */
unsigned short len; /* Length of the data buffer */
- unsigned char *data; /* Pointer to the data buffer */
+ unsigned char __user *data; /* Pointer to the data buffer */
};
/*
tp->rx_ring[entry].status);
do {
+ if (inl(dev->base_addr + CSR5) == 0xffffffff) {
+ printk(KERN_DEBUG " In tulip_poll(), hardware disappeared.\n");
+ break;
+ }
/* Acknowledge current RX interrupt sources. */
outl((RxIntr | RxNoBuf), dev->base_addr + CSR5);
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct tulip_private *np = netdev_priv(dev);
u32 ethcmd;
{
struct tulip_private *tp = netdev_priv(dev);
long ioaddr = dev->base_addr;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
const unsigned int phy_idx = 0;
int phy = tp->phys[phy_idx] & 0x1f;
unsigned int regnum = data->reg_num;
switch (cmd) {
case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return netdev_ethtool_ioctl(dev, rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
if (tp->mii_cnt)
pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
np->rx_skbuff[entry]->len,
PCI_DMA_FROMDEVICE);
- /* Call copy + cksum if available. */
-#if HAS_IP_COPYSUM
eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
-#else
- memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail,
- pkt_len);
-#endif
pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
np->rx_skbuff[entry]->len,
PCI_DMA_FROMDEVICE);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
- struct netdev_private *np = dev->priv;
+ struct mii_ioctl_data *data = if_mii(rq);
+ struct netdev_private *np = netdev_priv(dev);
switch(cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
}
-static int xircom_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int xircom_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct ethtool_cmd ecmd;
struct xircom_private *tp = dev->priv;
static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct xircom_private *tp = dev->priv;
- u16 *data = (u16 *)&rq->ifr_data;
+ u16 *data = (u16 *)&rq->ifr_ifru;
int phy = tp->phys[0] & 0x1f;
unsigned long flags;
switch(cmd) {
case SIOCETHTOOL:
- return xircom_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return xircom_ethtool_ioctl(dev, rq->ifr_data);
/* Legacy mii-diag interface */
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
dev->addr_len = 0;
dev->mtu = 1500;
- /* Type PPP seems most suitable */
- dev->type = ARPHRD_PPP;
+ /* Zero header length */
+ dev->type = ARPHRD_NONE;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
dev->tx_queue_len = 10;
break;
}
/* Write */
-static ssize_t tun_chr_write(struct file * file, const char * buf,
+static ssize_t tun_chr_write(struct file * file, const char __user * buf,
size_t count, loff_t *pos)
{
- struct iovec iv = { (void *) buf, count };
+ struct iovec iv = { (void __user *) buf, count };
return tun_chr_writev(file, &iv, 1, pos);
}
}
/* Read */
-static ssize_t tun_chr_read(struct file * file, char * buf,
+static ssize_t tun_chr_read(struct file * file, char __user * buf,
size_t count, loff_t *pos)
{
struct iovec iv = { buf, count };
struct ifreq ifr;
int err;
- if (copy_from_user(&ifr, (void *)arg, sizeof(ifr)))
+ if (copy_from_user(&ifr, (void __user *)arg, sizeof(ifr)))
return -EFAULT;
ifr.ifr_name[IFNAMSIZ-1] = '\0';
if (err)
return err;
- if (copy_to_user((void *)arg, &ifr, sizeof(ifr)))
+ if (copy_to_user((void __user *)arg, &ifr, sizeof(ifr)))
return -EFAULT;
return 0;
}
}
static inline int
-typhoon_ethtool_ioctl(struct net_device *dev, void *useraddr)
+typhoon_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct typhoon *tp = (struct typhoon *) dev->priv;
u32 ethcmd;
{
switch (cmd) {
case SIOCETHTOOL:
- return typhoon_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+ return typhoon_ethtool_ioctl(dev, ifr->ifr_data);
default:
break;
}
second only the 1234 card.
*/
-enum pci_flags_bit {
- PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
- PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+enum rhine_revs {
+ VT86C100A = 0x00,
+ VT6102 = 0x40,
+ VT8231 = 0x50, /* Integrated MAC */
+ VT8233 = 0x60, /* Integrated MAC */
+ VT8235 = 0x74, /* Integrated MAC */
+ VT8237 = 0x78, /* Integrated MAC */
+ VTunknown0 = 0x7C,
+ VT6105 = 0x80,
+ VT6105_B0 = 0x83,
+ VT6105L = 0x8A,
+ VT6107 = 0x8C,
+ VTunknown1 = 0x8E,
+ VT6105M = 0x90,
};
-enum rhine_chips {
- VT86C100A = 0,
- VT6102,
- VT6105,
- VT6105M
-};
-
-struct rhine_chip_info {
- const char *name;
- u16 pci_flags;
- int io_size;
- int drv_flags;
-};
-
-
-enum chip_capability_flags {
- CanHaveMII=1, HasESIPhy=2, HasDavicomPhy=4,
- ReqTxAlign=0x10, HasWOL=0x20,
+enum rhine_quirks {
+ rqWOL = 0x0001, /* Wake-On-LAN support */
+ rqForceReset = 0x0002,
+ rqDavicomPhy = 0x0020,
+ rq6patterns = 0x0040, /* 6 instead of 4 patterns for WOL */
+ rqStatusWBRace = 0x0080, /* Tx Status Writeback Error possible */
+ rqRhineI = 0x0100, /* See comment below */
};
+/*
+ * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
+ * MMIO as well as for the collision counter and the Tx FIFO underflow
+ * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
+ */
-#ifdef USE_MMIO
-#define RHINE_IOTYPE (PCI_USES_MEM | PCI_USES_MASTER | PCI_ADDR1)
-#else
-#define RHINE_IOTYPE (PCI_USES_IO | PCI_USES_MASTER | PCI_ADDR0)
-#endif
/* Beware of PCI posted writes */
#define IOSYNC do { readb(dev->base_addr + StationAddr); } while (0)
-/* directly indexed by enum rhine_chips, above */
-static struct rhine_chip_info rhine_chip_info[] __devinitdata =
-{
- { "VIA VT86C100A Rhine", RHINE_IOTYPE, 128,
- CanHaveMII | ReqTxAlign | HasDavicomPhy },
- { "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
- CanHaveMII | HasWOL },
- { "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
- CanHaveMII | HasWOL },
- { "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256,
- CanHaveMII | HasWOL },
-};
-
static struct pci_device_id rhine_pci_tbl[] =
{
- {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
- {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
- {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */
- {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},
- {0,} /* terminate list */
+ {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT86C100A */
+ {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6102 */
+ {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* 6105{,L,LOM} */
+ {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, /* VT6105M */
+ { } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
- StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7,
- PwrcsrClr=0xAC,
+ StickyHW=0x83, IntrStatus2=0x84,
+ WOLcrSet=0xA0, WOLcrClr=0xA4, WOLcrClr1=0xA6,
+ WOLcgClr=0xA7,
+ PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD,
};
/* Bits in ConfigD */
spinlock_t lock;
/* Frequently used values: keep some adjacent for cache effect. */
- int chip_id, drv_flags;
+ u32 quirks;
struct rx_desc *rx_head_desc;
unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
unsigned int cur_tx, dirty_tx;
u16 chip_cmd; /* Current setting for ChipCmd */
/* These values are keep track of the transceiver/media in use. */
- unsigned int default_port:4; /* Last dev->if_port value. */
u8 tx_thresh, rx_thresh;
/* MII transceiver section. */
intr_status = readw(ioaddr + IntrStatus);
/* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
- if (rp->chip_id == VT6102)
+ if (rp->quirks & rqStatusWBRace)
intr_status |= readb(ioaddr + IntrStatus2) << 16;
return intr_status;
}
-static void wait_for_reset(struct net_device *dev, int chip_id, char *name)
+/*
+ * Get power related registers into sane state.
+ * Returns content of power-event (WOL) registers.
+ */
+static void rhine_power_init(struct net_device *dev)
+{
+ long ioaddr = dev->base_addr;
+ struct rhine_private *rp = netdev_priv(dev);
+
+ if (rp->quirks & rqWOL) {
+ /* Make sure chip is in power state D0 */
+ writeb(readb(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW);
+
+ /* Disable "force PME-enable" */
+ writeb(0x80, ioaddr + WOLcgClr);
+
+ /* Clear power-event config bits (WOL) */
+ writeb(0xFF, ioaddr + WOLcrClr);
+ /* More recent cards can manage two additional patterns */
+ if (rp->quirks & rq6patterns)
+ writeb(0x03, ioaddr + WOLcrClr1);
+
+ /* Clear power-event status bits */
+ writeb(0xFF, ioaddr + PwrcsrClr);
+ if (rp->quirks & rq6patterns)
+ writeb(0x03, ioaddr + PwrcsrClr1);
+ }
+}
+
+static void wait_for_reset(struct net_device *dev, u32 quirks, char *name)
{
long ioaddr = dev->base_addr;
int boguscnt = 20;
"Trying harder.\n", name);
/* Rhine-II needs to be forced sometimes */
- if (chip_id == VT6102)
+ if (quirks & rqForceReset)
writeb(0x40, ioaddr + MiscCmd);
/* VT86C100A may need long delay after reset (dlink) */
}
#ifdef USE_MMIO
-static void __devinit enable_mmio(long ioaddr, int chip_id)
+static void __devinit enable_mmio(long ioaddr, u32 quirks)
{
int n;
- if (chip_id == VT86C100A) {
+ if (quirks & rqRhineI) {
/* More recent docs say that this bit is reserved ... */
n = inb(ioaddr + ConfigA) | 0x20;
outb(n, ioaddr + ConfigA);
{
struct net_device *dev;
struct rhine_private *rp;
- int i, option;
- int chip_id = (int) ent->driver_data;
+ int i, option, rc;
+ u8 pci_rev;
+ u32 quirks;
static int card_idx = -1;
long ioaddr;
long memaddr;
int io_size;
- int pci_flags;
+ int phy, phy_idx = 0;
#ifdef USE_MMIO
long ioaddr0;
#endif
+ const char *name;
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
card_idx++;
option = card_idx < MAX_UNITS ? options[card_idx] : 0;
- io_size = rhine_chip_info[chip_id].io_size;
- pci_flags = rhine_chip_info[chip_id].pci_flags;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
- if (pci_enable_device(pdev))
+ io_size = 256;
+ if (pci_rev < VT6102) {
+ quirks = rqRhineI | rqDavicomPhy;
+ io_size = 128;
+ name = "VT86C100A Rhine";
+ }
+ else {
+ quirks = rqWOL | rqForceReset;
+ if (pci_rev < VT6105) {
+ name = "Rhine II";
+ quirks |= rqStatusWBRace; /* Rhine-II exclusive */
+ }
+ else {
+ name = "Rhine III";
+ if (pci_rev >= VT6105_B0)
+ quirks |= rq6patterns;
+ }
+ }
+
+ rc = pci_enable_device(pdev);
+ if (rc)
goto err_out;
/* this should always be supported */
- if (pci_set_dma_mask(pdev, 0xffffffff)) {
+ rc = pci_set_dma_mask(pdev, 0xffffffff);
+ if (rc) {
printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
"the card!?\n");
goto err_out;
/* sanity check */
if ((pci_resource_len(pdev, 0) < io_size) ||
(pci_resource_len(pdev, 1) < io_size)) {
+ rc = -EIO;
printk(KERN_ERR "Insufficient PCI resources, aborting\n");
goto err_out;
}
ioaddr = pci_resource_start(pdev, 0);
memaddr = pci_resource_start(pdev, 1);
- if (pci_flags & PCI_USES_MASTER)
- pci_set_master(pdev);
+ pci_set_master(pdev);
dev = alloc_etherdev(sizeof(*rp));
if (dev == NULL) {
+ rc = -ENOMEM;
printk(KERN_ERR "init_ethernet failed for card #%d\n",
card_idx);
goto err_out;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
- if (pci_request_regions(pdev, shortname))
+ rc = pci_request_regions(pdev, shortname);
+ if (rc)
goto err_out_free_netdev;
#ifdef USE_MMIO
ioaddr0 = ioaddr;
- enable_mmio(ioaddr0, chip_id);
+ enable_mmio(ioaddr0, quirks);
ioaddr = (long) ioremap(memaddr, io_size);
if (!ioaddr) {
+ rc = -EIO;
printk(KERN_ERR "ioremap failed for device %s, region 0x%X "
"@ 0x%lX\n", pci_name(pdev), io_size, memaddr);
goto err_out_free_res;
unsigned char a = inb(ioaddr0+reg);
unsigned char b = readb(ioaddr+reg);
if (a != b) {
+ rc = -EIO;
printk(KERN_ERR "MMIO do not match PIO [%02x] "
"(%02x != %02x)\n", reg, a, b);
goto err_out_unmap;
}
}
#endif /* USE_MMIO */
+ dev->base_addr = ioaddr;
- /* D-Link provided reset code (with comment additions) */
- if (rhine_chip_info[chip_id].drv_flags & HasWOL) {
- unsigned char byOrgValue;
-
- /* clear sticky bit before reset & read ethernet address */
- byOrgValue = readb(ioaddr + StickyHW);
- byOrgValue = byOrgValue & 0xFC;
- writeb(byOrgValue, ioaddr + StickyHW);
-
- /* (bits written are cleared?) */
- /* disable force PME-enable */
- writeb(0x80, ioaddr + WOLcgClr);
- /* disable power-event config bit */
- writeb(0xFF, ioaddr + WOLcrClr);
- /* clear power status (undocumented in vt6102 docs?) */
- writeb(0xFF, ioaddr + PwrcsrClr);
- }
+ rhine_power_init(dev);
/* Reset the chip to erase previous misconfiguration. */
writew(CmdReset, ioaddr + ChipCmd);
- dev->base_addr = ioaddr;
- wait_for_reset(dev, chip_id, shortname);
+ wait_for_reset(dev, quirks, shortname);
/* Reload the station address from the EEPROM. */
#ifdef USE_MMIO
/* Reloading from eeprom overwrites cfgA-D, so we must re-enable MMIO.
If reload_eeprom() was done first this could be avoided, but it is
not known if that still works with the "win98-reboot" problem. */
- enable_mmio(ioaddr0, chip_id);
+ enable_mmio(ioaddr0, quirks);
#else
reload_eeprom(ioaddr);
#endif
dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
if (!is_valid_ether_addr(dev->dev_addr)) {
+ rc = -EIO;
printk(KERN_ERR "Invalid MAC address for card #%d\n", card_idx);
goto err_out_unmap;
}
- if (chip_id == VT6102) {
+ if (quirks & rqWOL) {
/*
* for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
* turned on. it makes MAC receive magic packet
rp = netdev_priv(dev);
spin_lock_init(&rp->lock);
- rp->chip_id = chip_id;
- rp->drv_flags = rhine_chip_info[chip_id].drv_flags;
rp->pdev = pdev;
+ rp->quirks = quirks;
rp->mii_if.dev = dev;
rp->mii_if.mdio_read = mdio_read;
rp->mii_if.mdio_write = mdio_write;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = rhine_poll;
#endif
- if (rp->drv_flags & ReqTxAlign)
+ if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
/* dev->name not defined before register_netdev()! */
- i = register_netdev(dev);
- if (i)
+ rc = register_netdev(dev);
+ if (rc)
goto err_out_unmap;
/* The lower four bits are the media type. */
if (option > 0) {
if (option & 0x220)
rp->mii_if.full_duplex = 1;
- rp->default_port = option & 15;
}
if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
rp->mii_if.full_duplex = 1;
rp->mii_if.force_media = 1;
}
- printk(KERN_INFO "%s: %s at 0x%lx, ",
- dev->name, rhine_chip_info[chip_id].name,
- (pci_flags & PCI_USES_IO) ? ioaddr : memaddr);
+ printk(KERN_INFO "%s: VIA %s at 0x%lx, ",
+ dev->name, name,
+#ifdef USE_MMIO
+ memaddr
+#else
+ ioaddr
+#endif
+ );
for (i = 0; i < 5; i++)
printk("%2.2x:", dev->dev_addr[i]);
pci_set_drvdata(pdev, dev);
- if (rp->drv_flags & CanHaveMII) {
- int phy, phy_idx = 0;
- rp->phys[0] = 1; /* Standard for this chip. */
- for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) {
- int mii_status = mdio_read(dev, phy, 1);
- if (mii_status != 0xffff && mii_status != 0x0000) {
- rp->phys[phy_idx++] = phy;
- rp->mii_if.advertising = mdio_read(dev, phy, 4);
- printk(KERN_INFO "%s: MII PHY found at address "
- "%d, status 0x%4.4x advertising %4.4x "
- "Link %4.4x.\n", dev->name, phy,
- mii_status, rp->mii_if.advertising,
- mdio_read(dev, phy, 5));
-
- /* set IFF_RUNNING */
- if (mii_status & BMSR_LSTATUS)
- netif_carrier_on(dev);
- else
- netif_carrier_off(dev);
-
- break;
- }
+ rp->phys[0] = 1; /* Standard for this chip. */
+ for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) {
+ int mii_status = mdio_read(dev, phy, 1);
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ rp->phys[phy_idx++] = phy;
+ rp->mii_if.advertising = mdio_read(dev, phy, 4);
+ printk(KERN_INFO "%s: MII PHY found at address "
+ "%d, status 0x%4.4x advertising %4.4x "
+ "Link %4.4x.\n", dev->name, phy,
+ mii_status, rp->mii_if.advertising,
+ mdio_read(dev, phy, 5));
+
+ /* set IFF_RUNNING */
+ if (mii_status & BMSR_LSTATUS)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
+
+ break;
}
- rp->mii_cnt = phy_idx;
- rp->mii_if.phy_id = rp->phys[0];
}
+ rp->mii_cnt = phy_idx;
+ rp->mii_if.phy_id = rp->phys[0];
/* Allow forcing the media type. */
if (option > 0) {
if (option & 0x220)
rp->mii_if.full_duplex = 1;
- rp->default_port = option & 0x3ff;
if (option & 0x330) {
- /* FIXME: shouldn't someone check this variable? */
- /* rp->medialock = 1; */
printk(KERN_INFO " Forcing %dMbs %s-duplex "
"operation.\n",
(option & 0x300 ? 100 : 10),
err_out_free_netdev:
free_netdev(dev);
err_out:
- return -ENODEV;
+ return rc;
}
static int alloc_ring(struct net_device* dev)
printk(KERN_ERR "Could not allocate DMA memory.\n");
return -ENOMEM;
}
- if (rp->drv_flags & ReqTxAlign) {
+ if (rp->quirks & rqRhineI) {
rp->tx_bufs = pci_alloc_consistent(rp->pdev,
PKT_BUF_SZ * TX_RING_SIZE,
&rp->tx_bufs_dma);
rp->rx_thresh = 0x60; /* Written in rhine_set_rx_mode(). */
rp->mii_if.full_duplex = 0;
- if (dev->if_port == 0)
- dev->if_port = rp->default_port;
-
writel(rp->rx_ring_dma, ioaddr + RxRingPtr);
writel(rp->tx_ring_dma, ioaddr + TxRingPtr);
/* The LED outputs of various MII xcvrs should be configured. */
/* For NS or Mison phys, turn on bit 1 in register 0x17 */
- /* For ESI phys, turn on bit 7 in register 0x17. */
mdio_write(dev, rp->phys[0], 0x17, mdio_read(dev, rp->phys[0], 0x17) |
- (rp->drv_flags & HasESIPhy) ? 0x0080 : 0x0001);
+ 0x0001);
}
/* Read and write over the MII Management Data I/O (MDIO) interface. */
return i;
alloc_rbufs(dev);
alloc_tbufs(dev);
- wait_for_reset(dev, rp->chip_id, dev->name);
+ wait_for_reset(dev, rp->quirks, dev->name);
init_registers(dev);
if (debug > 2)
printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x "
dev->name, readw(ioaddr + IntrStatus),
mdio_read(dev, rp->phys[0], MII_BMSR));
- dev->if_port = 0;
-
/* protect against concurrent rx interrupts */
disable_irq(rp->pdev->irq);
alloc_rbufs(dev);
/* Reinitialize the hardware. */
- wait_for_reset(dev, rp->chip_id, dev->name);
+ wait_for_reset(dev, rp->quirks, dev->name);
init_registers(dev);
spin_unlock(&rp->lock);
rp->tx_skbuff[entry] = skb;
- if ((rp->drv_flags & ReqTxAlign) &&
+ if ((rp->quirks & rqRhineI) &&
(((long)skb->data & 3) || skb_shinfo(skb)->nr_frags != 0 || skb->ip_summed == CHECKSUM_HW)) {
/* Must use alignment buffer. */
if (skb->len > PKT_BUF_SZ) {
if (txstatus & 0x0200) rp->stats.tx_window_errors++;
if (txstatus & 0x0100) rp->stats.tx_aborted_errors++;
if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++;
- if (((rp->chip_id == VT86C100A) && txstatus & 0x0002) ||
+ if (((rp->quirks & rqRhineI) && txstatus & 0x0002) ||
(txstatus & 0x0800) || (txstatus & 0x1000)) {
rp->stats.tx_fifo_errors++;
rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
}
/* Transmitter restarted in 'abnormal' handler. */
} else {
- if (rp->chip_id == VT86C100A)
+ if (rp->quirks & rqRhineI)
rp->stats.collisions += (txstatus >> 3) & 0x0F;
else
rp->stats.collisions += txstatus & 0x0F;
eth_copy_and_sum is memcpy for all archs so
this is kind of pointless right now
... or? */
-#if HAS_IP_COPYSUM /* Call copy + cksum if available. */
eth_copy_and_sum(skb,
rp->rx_skbuff[entry]->tail,
pkt_len, 0);
skb_put(skb, pkt_len);
-#else
- memcpy(skb_put(skb, pkt_len),
- rp->rx_skbuff[entry]->tail, pkt_len);
-#endif
pci_dma_sync_single_for_device(rp->pdev,
rp->rx_skbuff_dma[entry],
rp->rx_buf_sz,
if (intr_status & (IntrLinkChange)) {
if (readb(ioaddr + MIIStatus) & 0x02) {
/* Link failed, restart autonegotiation. */
- if (rp->drv_flags & HasDavicomPhy)
+ if (rp->quirks & rqRhineI)
mdio_write(dev, rp->phys[0], MII_BMCR, 0x3300);
} else
rhine_check_duplex(dev);
struct rhine_private *rp = netdev_priv(dev);
int rc;
- if (!(rp->drv_flags & CanHaveMII))
- return -EINVAL;
-
spin_lock_irq(&rp->lock);
rc = mii_ethtool_gset(&rp->mii_if, cmd);
spin_unlock_irq(&rp->lock);
struct rhine_private *rp = netdev_priv(dev);
int rc;
- if (!(rp->drv_flags & CanHaveMII))
- return -EINVAL;
-
spin_lock_irq(&rp->lock);
rc = mii_ethtool_sset(&rp->mii_if, cmd);
spin_unlock_irq(&rp->lock);
{
struct rhine_private *rp = netdev_priv(dev);
- if (!(rp->drv_flags & CanHaveMII))
- return -EINVAL;
-
return mii_nway_restart(&rp->mii_if);
}
{
struct rhine_private *rp = netdev_priv(dev);
- if (!(rp->drv_flags & CanHaveMII))
- return 0; /* -EINVAL */
-
return mii_link_ok(&rp->mii_if);
}
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct rhine_private *rp = netdev_priv(dev);
- struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
int rc;
if (!netif_running(dev))
return -EINVAL;
spin_lock_irq(&rp->lock);
- rc = generic_mii_ioctl(&rp->mii_if, data, cmd, NULL);
+ rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL);
spin_unlock_irq(&rp->lock);
return rc;
return(ret);
}
-static int dlci_config(struct net_device *dev, struct dlci_conf *conf, int get)
+static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, int get)
{
struct dlci_conf config;
struct dlci_local *dlp;
if (!*(short *)(dev->dev_addr))
return(-EINVAL);
- return(dlci_config(dev, (struct dlci_conf *) ifr->ifr_data, cmd == DLCI_GET_CONF));
+ return(dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF));
break;
default:
return(err);
}
-static int dlci_ioctl(unsigned int cmd, void *arg)
+static int dlci_ioctl(unsigned int cmd, void __user *arg)
{
struct dlci_add add;
int err;
pc300conf_t conf_aux;
pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
int ch = chan->channel;
- void *arg = (void *) ifr->ifr_data;
+ void __user *arg = ifr->ifr_data;
struct if_settings *settings = &ifr->ifr_settings;
uclong scabase = card->hw.scabase;
return -EPERM;
spin_lock( &nl->lock );
- flags = *(struct sbni_flags*) &ifr->ifr_data;
+ flags = *(struct sbni_flags*) &ifr->ifr_ifru;
if( flags.fixed_rxl )
nl->delta_rxl = 0,
nl->cur_rxl_index = flags.rxl;
return(0);
}
-static int sdla_config(struct net_device *dev, struct frad_conf *conf, int get)
+static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
{
struct frad_local *flp;
struct conf_data data;
return(0);
}
-static int sdla_xfer(struct net_device *dev, struct sdla_mem *info, int read)
+static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
{
struct sdla_mem mem;
char *temp;
{
case FRAD_GET_CONF:
case FRAD_SET_CONF:
- return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
+ return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));
case SDLA_IDENTIFY:
ifr->ifr_flags = flp->type;
case SDLA_WRITEMEM:
case SDLA_READMEM:
- return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
+ return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));
case SDLA_START:
sdla_start(dev);
#include "8390.h"
+#define DRV_NAME "wd"
+
/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int wd_portlist[] __initdata =
{0x300, 0x280, 0x380, 0x240, 0};
release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
}
+#ifndef MODULE
struct net_device * __init wd_probe(int unit)
{
struct net_device *dev = alloc_ei_netdev();
free_netdev(dev);
return ERR_PTR(err);
}
+#endif
static int __init wd_probe1(struct net_device *dev, int ioaddr)
{
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
- i = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+ i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (i) {
printk (" unable to get IRQ %d.\n", dev->irq);
return i;
#define AIROGMICRID 11
#define AIROGMICSTATS 12
#define AIROGFLAGS 13
-#define AIROGID 14
#define AIRORRID 15
-#define AIRORSWVERSION 17
/* Leave gap of 40 commands after AIROGSTATSD32 for future */
#define AUXMEMSIZE (256 * 1024)
typedef struct aironet_ioctl {
- unsigned short command; // What to do
+ unsigned short command; // What to do
unsigned short len; // Len of data
- unsigned short ridnum; // rid number
unsigned char *data; // d-data
} aironet_ioctl;
-
-static char *swversion = "2.1";
#endif /* CISCO_EXT */
#define NUM_MODULES 2
static int mpi_send_packet (struct net_device *dev);
static void mpi_unmap_card(struct pci_dev *pci);
static void mpi_receive_802_3(struct airo_info *ai);
-static void mpi_receive_802_11(struct airo_info *ai);
static int waitbusy (struct airo_info *ai);
static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
cmd.parm0 = FID_TX;
cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
cmd.parm2 = MPI_MAX_FIDS;
+ rc=issuecommand(ai, &cmd, &rsp);
+ if (rc != SUCCESS) {
+ printk(KERN_ERR "airo: Couldn't allocate TX FID\n");
+ return rc;
+ }
for (i=0; i<MPI_MAX_FIDS; i++) {
ai->txfids[i].tx_desc.valid = 1;
memcpy((char *)ai->txfids[i].card_ram_off,
&ai->txfids[i].tx_desc, sizeof(TxFid));
}
- ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
-
- rc=issuecommand(ai, &cmd, &rsp);
- if (rc != SUCCESS) {
- printk(KERN_ERR "airo: Couldn't allocate TX FID\n");
- return rc;
- }
/* Alloc card Rid descriptor */
memset(&rsp,0,sizeof(rsp));
return dev;
}
-int reset_card( struct net_device *dev , int lock) {
+int reset_mpi_card( struct net_device *dev , int lock) {
struct airo_info *ai = dev->priv;
if (lock && down_interruptible(&ai->sem))
SET_NETDEV_DEV(dev, &pci->dev);
}
+ if (test_bit(FLAG_MPI,&ai->flags))
+ reset_mpi_card (dev, 1);
+
rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
if (rc) {
printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
printk(KERN_ERR "airo: Couldn't register_netdev\n");
goto err_out_map;
}
- ai->wifidev = init_wifidev(ai, dev);
+ if (!test_bit(FLAG_MPI,&ai->flags))
+ ai->wifidev = init_wifidev(ai, dev);
set_bit(FLAG_REGISTERED,&ai->flags);
printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
int i;
struct airo_info *ai = dev->priv;
- if (reset_card (dev, 1))
+ if (reset_mpi_card (dev, 1))
return -1;
if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
u16 *buffer;
if (test_bit(FLAG_MPI,&apriv->flags)) {
- if (test_bit(FLAG_802_11, &apriv->flags))
- mpi_receive_802_11(apriv);
- else
- mpi_receive_802_3(apriv);
+ mpi_receive_802_3(apriv);
OUT4500(apriv, EVACK, EV_RX);
goto exitrx;
}
}
}
-void mpi_receive_802_11 (struct airo_info *ai)
-{
- RxFid rxd;
- struct sk_buff *skb = NULL;
- u16 fc, len, hdrlen = 0;
-#pragma pack(1)
- struct {
- u16 status, len;
- u8 rssi[2];
- u8 rate;
- u8 freq;
- u16 tmp[4];
- } hdr;
-#pragma pack()
- u16 gap;
- u16 *buffer;
- char *ptr = ai->rxfids[0].virtual_host_addr+4;
-
- memcpy ((char *)&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
- memcpy ((char *)&hdr, ptr, sizeof(hdr));
- ptr += sizeof(hdr);
- /* Bad CRC. Ignore packet */
- if (le16_to_cpu(hdr.status) & 2)
- hdr.len = 0;
- if (ai->wifidev == NULL)
- hdr.len = 0;
- len = le16_to_cpu(hdr.len);
- if (len > 2312) {
- printk( KERN_ERR "airo: Bad size %d\n", len );
- goto badrx;
- }
- if (len == 0)
- goto badrx;
-
- memcpy ((char *)&fc, ptr, sizeof(fc));
- fc = le16_to_cpu(fc);
- switch (fc & 0xc) {
- case 4:
- if ((fc & 0xe0) == 0xc0)
- hdrlen = 10;
- else
- hdrlen = 16;
- break;
- case 8:
- if ((fc&0x300)==0x300){
- hdrlen = 30;
- break;
- }
- default:
- hdrlen = 24;
- }
-
- skb = dev_alloc_skb( len + hdrlen + 2 );
- if ( !skb ) {
- ai->stats.rx_dropped++;
- goto badrx;
- }
- buffer = (u16*)skb_put (skb, len + hdrlen);
- memcpy ((char *)buffer, ptr, hdrlen);
- ptr += hdrlen;
- if (hdrlen == 24)
- ptr += 6;
- memcpy ((char *)&gap, ptr, sizeof(gap));
- ptr += sizeof(gap);
- gap = le16_to_cpu(gap);
- if (gap) {
- if (gap <= 8)
- ptr += gap;
- else
- printk(KERN_ERR
- "airo: gaplen too big. Problems will follow...\n");
- }
- memcpy ((char *)buffer + hdrlen, ptr, len);
- ptr += len;
-#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
- if (ai->spy_data.spy_number > 0) {
- char *sa;
- struct iw_quality wstats;
- /* Prepare spy data : addr + qual */
- sa = (char*)buffer + 10;
- wstats.qual = hdr.rssi[0];
- if (ai->rssi)
- wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
- else
- wstats.level = (hdr.rssi[1] + 321) / 2;
- wstats.updated = 3;
- /* Update spy records */
- wireless_spy_update(ai->dev, sa, &wstats);
- }
-#endif /* IW_WIRELESS_SPY */
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_OTHERHOST;
- skb->dev = ai->wifidev;
- skb->protocol = htons(ETH_P_802_2);
- skb->dev->last_rx = jiffies;
- skb->ip_summed = CHECKSUM_NONE;
- netif_rx( skb );
-badrx:
- if (rxd.valid == 0) {
- rxd.valid = 1;
- rxd.rdy = 0;
- rxd.len = PKTSIZE;
- memcpy (ai->rxfids[0].card_ram_off, (char *)&rxd, sizeof(rxd));
- }
-}
-
static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
{
Cmd cmd;
status = readCapabilityRid(ai, &cap_rid, lock);
if ( status != SUCCESS ) return ERROR;
- /*
- * This driver supports MPI350 firmwares up to, and
- * including 5.30.17
- */
if (test_bit(FLAG_MPI, &ai->flags) &&
- strncmp (cap_rid.prodVer, "5.00.", 5) &&
- strncmp (cap_rid.prodVer, "5b00.", 5) &&
- strncmp (cap_rid.prodVer, "5.02.", 5) &&
- strncmp (cap_rid.prodVer, "5.20.", 5) &&
- strncmp (cap_rid.prodVer, "5.30.", 5))
+ strcmp (cap_rid.prodVer, "5.00.01") &&
+ strcmp (cap_rid.prodVer, "5.00.03") &&
+ strcmp (cap_rid.prodVer, "5b00.08"))
printk(KERN_ERR "airo: Firmware version %s is not supported. Use it at your own risk!\n", cap_rid.prodVer);
status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
memset(&rsp, 0, sizeof(rsp));
ai->config_desc.rid_desc.valid = 1;
- ai->config_desc.rid_desc.len = *((u16 *)pBuf);
+ ai->config_desc.rid_desc.len = RIDSIZE;
ai->config_desc.rid_desc.rid = 0;
cmd.cmd = CMD_WRITERID;
struct net_device *dev = pci_get_drvdata(pdev);
struct airo_info *ai = dev->priv;
Resp rsp;
+ int err;
printk(KERN_DEBUG "%s: airo_mpi waking up\n", dev->name);
return 0;
if (ai->power > 1) {
+ err = reset_mpi_card(dev, 0);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d resetting on %s()\n",
+ dev->name, err, __FUNCTION__);
+ return err;
+ }
+ schedule_timeout (HZ/2);
mpi_init_descriptors(ai);
setup_card(ai, dev->dev_addr, 0);
clear_bit(FLAG_RADIO_OFF, &ai->flags);
readAPListRid(local, &APList_rid);
readSsidRid(local, &SSID_rid);
- if (test_bit(FLAG_MPI,&local->flags))
- setup_card(local, dev->dev_addr, 1 );
- else
- reset_airo_card(dev);
+ reset_airo_card(dev);
disable_MAC(local, 1);
writeSsidRid(local, &SSID_rid, 1);
writeAPListRid(local, &APList_rid, 1);
/* Separate R/W functions bracket legality here
*/
- if ( com.command == AIRORSWVERSION ) {
- if (copy_to_user(com.data, swversion, sizeof(swversion)))
- rc = -EFAULT;
- else
- rc = 0;
- }
- else if ( com.command <= AIRORRID)
+ if ( com.command <= AIRORRID )
rc = readrids(dev,&com);
- else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
+ else if ( com.command >= AIROPCAP && com.command <= AIROPLEAPUSR )
rc = writerids(dev,&com);
else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
rc = flashcard(dev,&com);
return -EFAULT;
return 0;
#endif
- case AIRORRID: ridcode = comp->ridnum; break;
+ case AIRORRID: ridcode = comp->len; break;
default:
return -EINVAL;
break;
* then return it to the user
* 9/22/2000 Honor user given length
*/
- len = comp->len;
+ if (comp->command == AIRORRID)
+ len = le16_to_cpu(*(unsigned short *)iobuf); /* Yuck! */
+ else
+ len = comp->len;
if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
kfree (iobuf);
case AIROPLEAPPWD: ridcode = RID_LEAPPASSWORD; break;
case AIROPWEPKEY: ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
break;
- case AIROPLEAPUSR+1: ridcode = 0xFF2A; break;
- case AIROPLEAPUSR+2: ridcode = 0xFF2B; break;
/* this is not really a rid but a command given to the card
* same with MAC off
#include <linux/types.h>
#include <linux/delay.h>
-#include "isl_38xx.h"
-#include <linux/firmware.h>
-
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <linux/config.h>
-#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE)
-#error No Firmware Loading configured in the kernel !
-#endif
-
+#include "prismcompat.h"
+#include "isl_38xx.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
udelay(ISL38XX_WRITEIO_DELAY);
}
-int
-isl38xx_upload_firmware(char *fw_id, _REQ_FW_DEV_T dev, void *device_base,
- dma_addr_t host_address)
-{
- u32 reg, rc;
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_ERROR_MESSAGES, "isl38xx_upload_firmware(0x%lx, 0x%lx)\n",
- (long) device_base, (long) host_address);
-#endif
-
- /* clear the RAMBoot and the Reset bit */
- reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
- reg &= ~ISL38XX_CTRL_STAT_RESET;
- reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
- writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
- wmb();
- udelay(ISL38XX_WRITEIO_DELAY);
-
- /* set the Reset bit without reading the register ! */
- reg |= ISL38XX_CTRL_STAT_RESET;
- writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
- wmb();
- udelay(ISL38XX_WRITEIO_DELAY);
-
- /* clear the Reset bit */
- reg &= ~ISL38XX_CTRL_STAT_RESET;
- writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
- wmb();
-
- /* wait a while for the device to reboot */
- mdelay(50);
-
- {
- const struct firmware *fw_entry = 0;
- long fw_len;
- const u32 *fw_ptr;
-
- rc = request_firmware(&fw_entry, fw_id, dev);
- if (rc) {
- printk(KERN_ERR
- "%s: request_firmware() failed for '%s'\n",
- "prism54", fw_id);
- return rc;
- }
- /* prepare the Direct Memory Base register */
- reg = ISL38XX_DEV_FIRMWARE_ADDRES;
-
- fw_ptr = (u32 *) fw_entry->data;
- fw_len = fw_entry->size;
-
- if (fw_len % 4) {
- printk(KERN_ERR
- "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
- "prism54", fw_id);
- release_firmware(fw_entry);
- return EILSEQ; /* Illegal byte sequence */;
- }
-
- while (fw_len > 0) {
- long _fw_len =
- (fw_len >
- ISL38XX_MEMORY_WINDOW_SIZE) ?
- ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
- u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
-
- /* set the cards base address for writting the data */
- isl38xx_w32_flush(device_base, reg,
- ISL38XX_DIR_MEM_BASE_REG);
- wmb(); /* be paranoid */
-
- /* increment the write address for next iteration */
- reg += _fw_len;
- fw_len -= _fw_len;
-
- /* write the data to the Direct Memory Window 32bit-wise */
- /* memcpy_toio() doesn't guarantee 32bit writes :-| */
- while (_fw_len > 0) {
- /* use non-swapping writel() */
- __raw_writel(*fw_ptr, dev_fw_ptr);
- fw_ptr++, dev_fw_ptr++;
- _fw_len -= 4;
- }
-
- /* flush PCI posting */
- (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH);
- wmb(); /* be paranoid again */
-
- BUG_ON(_fw_len != 0);
- }
-
- BUG_ON(fw_len != 0);
-
- release_firmware(fw_entry);
- }
-
- /* now reset the device
- * clear the Reset & ClkRun bit, set the RAMBoot bit */
- reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
- reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
- reg &= ~ISL38XX_CTRL_STAT_RESET;
- reg |= ISL38XX_CTRL_STAT_RAMBOOT;
- isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG);
- wmb();
- udelay(ISL38XX_WRITEIO_DELAY);
-
- /* set the reset bit latches the host override and RAMBoot bits
- * into the device for operation when the reset bit is reset */
- reg |= ISL38XX_CTRL_STAT_RESET;
- writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
- /* don't do flush PCI posting here! */
- wmb();
- udelay(ISL38XX_WRITEIO_DELAY);
-
- /* clear the reset bit should start the whole circus */
- reg &= ~ISL38XX_CTRL_STAT_RESET;
- writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
- /* don't do flush PCI posting here! */
- wmb();
- udelay(ISL38XX_WRITEIO_DELAY);
-
- return 0;
-}
-
int
isl38xx_in_queue(isl38xx_control_block *cb, int queue)
{
#include <linux/version.h>
#include <asm/io.h>
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75))
-#include <linux/device.h>
-# define _REQ_FW_DEV_T struct device *
-#else
-# define _REQ_FW_DEV_T char *
-#endif
-
#include <asm/byteorder.h>
#define ISL38XX_CB_RX_QSIZE 8
void isl38xx_trigger_device(int, void *);
void isl38xx_interface_reset(void *, dma_addr_t);
-int isl38xx_upload_firmware(char *, _REQ_FW_DEV_T, void *, dma_addr_t);
-
#endif /* _ISL_38XX_H */
#include <linux/kernel.h>
#include <linux/if_arp.h>
#include <linux/pci.h>
-#include <linux/moduleparam.h>
#include <asm/uaccess.h>
+#include "prismcompat.h"
#include "isl_ioctl.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
* for it save old values */
if (init_mode > IW_MODE_MONITOR || init_mode < IW_MODE_AUTO) {
printk(KERN_DEBUG "%s(): You passed a non-valid init_mode. "
- "Using default mode\n", __FUNCTION__);
+ "Using default mode\n", __FUNCTION__);
init_mode = CARD_DEFAULT_IW_MODE;
}
/* This sets all of the mode-dependent values */
prism54_mib_mode_helper(priv, init_mode);
}
-void
-prism54_mib_init_work(islpci_private *priv)
-{
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-}
-
/* this will be executed outside of atomic context thanks to
* schedule_work(), thus we can as well use sleeping semaphore
* locking */
if (down_interruptible(&priv->stats_sem))
return;
-/* missing stats are :
- * iwstatistics.qual.updated
- * iwstatistics.discard.nwid
- * iwstatistics.discard.fragment
- * iwstatistics.discard.misc
- * iwstatistics.miss.beacon */
-
/* Noise floor.
* I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrevelant. */
+ * Note : If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
data = r.ptr;
/* copy this MAC to the bss */
- for (j = 0; j < 6; j++)
- bss.address[j] = data[j];
+ memcpy(bss.address, data, 6);
kfree(data);
/* now ask for the corresponding bss */
/* by default the card sets this to 20. */
sens = vwrq->disabled ? 20 : vwrq->value;
- /* set the ed threshold. */
return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens);
}
return 0;
/* Request the device for the supported frequencies
- * not really revelant since some devices will report the 5 GHz band
+ * not really relevant since some devices will report the 5 GHz band
* frequencies even if they don't support them.
*/
rvalue =
range->num_channels = freq->nr;
range->num_frequency = freq->nr;
- /* Frequencies are not listed in the right order. The reordering is probably
- * firmware dependant and thus should work for everyone.
- */
m = min(IW_MAX_FREQUENCIES, (int) freq->nr);
- for (i = 0; i < m - 12; i++) {
- range->freq[i].m = freq->mhz[12 + i];
+ for (i = 0; i < m; i++) {
+ range->freq[i].m = freq->mhz[i];
range->freq[i].e = 6;
- range->freq[i].i = i + 1;
+ range->freq[i].i = channel_of_freq(freq->mhz[i]);
}
- for (i = m - 12; i < m; i++) {
- range->freq[i].m = freq->mhz[i - m + 12];
- range->freq[i].e = 6;
- range->freq[i].i = i + 23;
- }
-
kfree(freq);
rvalue |= mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r);
i++;
data++;
}
-
range->num_bitrates = i;
-
kfree(r.ptr);
return rvalue;
int rvalue;
rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
-
memcpy(awrq->sa_data, r.ptr, 6);
awrq->sa_family = ARPHRD_ETHER;
kfree(r.ptr);
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
- iwe.u.freq.m = bss->channel;
- iwe.u.freq.e = 6;
+ iwe.u.freq.m = channel_of_freq(bss->channel);
+ iwe.u.freq.e = 0;
iwe.cmd = SIOCGIWFREQ;
current_ev =
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
kfree(buf);
}
}
-
return current_ev;
}
/* Ask the device for a list of known bss. We can report at most
* IW_MAX_AP=64 to the range struct. But the device won't repport anything
- * if you change the value of MAXBSS=24. Anyway 24 AP It is probably enough.
+ * if you change the value of IWMAX_BSS=24.
*/
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
memcpy(essid.octets, extra, dwrq->length);
} else
essid.length = 0;
-
+
if (priv->iw_mode != IW_MODE_MONITOR)
return mgt_set_request(priv, DOT11_OID_SSID, 0, &essid);
char *data;
int ret, i;
union oid_res_t r;
-
+
if (vwrq->value == -1) {
/* auto mode. No limit. */
profile = 1;
return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
}
-
+
if ((ret =
mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r)))
return ret;
-
+
rate = (u32) (vwrq->value / 500000);
data = r.ptr;
i = 0;
-
+
while (data[i]) {
if (rate && (data[i] == rate)) {
break;
data[i] |= 0x80;
i++;
}
-
+
if (!data[i]) {
return -EINVAL;
}
-
+
data[i] |= 0x80;
data[i + 1] = 0;
-
+
/* Now, check if we want a fixed or auto value */
if (vwrq->fixed) {
data[0] = data[i];
i++;
}
printk("0\n");
-*/
+*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
ret |= mgt_set_request(priv, DOT11_OID_RATES, 0, data);
-
+
kfree(r.ptr);
-
+
return ret;
}
data = r.ptr;
vwrq->fixed = (data[0] != 0) && (data[1] == 0);
kfree(r.ptr);
-
+
return 0;
}
* small frame <=> smaller than the rts threshold
* This is not really the behavior expected by the wireless tool but it seems
* to be a common behavior in other drivers.
- *
- * It seems that playing with this tends to hang the card -> DISABLED
*/
static int
lifetime = vwrq->value / 1024;
/* now set what is requested */
-
- if (slimit != 0)
+ if (slimit)
rvalue =
mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit);
- if (llimit != 0)
+ if (llimit)
rvalue |=
mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit);
- if (lifetime != 0)
+ if (lifetime)
rvalue |=
mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0,
&lifetime);
-
return rvalue;
}
}
}
}
-
- /* now read the flags */
+ /* now read the flags */
if (dwrq->flags & IW_ENCODE_DISABLED) {
/* Encoding disabled,
* authen = DOT11_AUTH_OS;
static int
prism54_set_u32(struct net_device *ndev, struct iw_request_info *info,
- __u32 * uwrq, char *extra)
+ __u32 * uwrq, char *extra)
{
- /*
- u32 *i = (int *) extra;
- int param = *i;
- int u = *(i + 1);
- */
u32 oid = uwrq[0], u = uwrq[1];
return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);
0);
break;
- /* Note : the following should never happen since we don't run the card in
- * extended mode.
- * Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
+ /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
* is backward compatible layout-wise with "struct obj_mlme".
*/
struct net_device *ndev = frame->ndev;
enum oid_num_t n = mgt_oidtonum(frame->header->oid);
- prism54_process_trap_helper(netdev_priv(ndev), n, frame->data);
+ if (n != OID_NUM_LAST)
+ prism54_process_trap_helper(netdev_priv(ndev), n, frame->data);
islpci_mgt_release(frame);
}
return 0;
}
-int
-prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
- __u32 * uwrq, char *extra)
-{
- islpci_private *priv = netdev_priv(ndev);
- u32 max_burst;
-
- max_burst = (*uwrq) ? *uwrq : CARD_DEFAULT_MAXFRAMEBURST;
- mgt_set_request(priv, DOT11_OID_MAXFRAMEBURST, 0, &max_burst);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-int
-prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
- __u32 * uwrq, char *extra)
-{
- islpci_private *priv = netdev_priv(ndev);
- union oid_res_t r;
- int rvalue;
-
- rvalue = mgt_get_request(priv, DOT11_OID_MAXFRAMEBURST, 0, NULL, &r);
- *uwrq = r.u;
-
- return rvalue;
-}
-
-int
-prism54_set_profile(struct net_device *ndev, struct iw_request_info *info,
- __u32 * uwrq, char *extra)
-{
- islpci_private *priv = netdev_priv(ndev);
- u32 profile;
-
- profile = (*uwrq) ? *uwrq : CARD_DEFAULT_PROFILE;
- mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-int
-prism54_get_profile(struct net_device *ndev, struct iw_request_info *info,
- __u32 * uwrq, char *extra)
-{
- islpci_private *priv = netdev_priv(ndev);
- union oid_res_t r;
- int rvalue;
-
- rvalue = mgt_get_request(priv, DOT11_OID_PROFILES, 0, NULL, &r);
- *uwrq = r.u;
-
- return rvalue;
-}
-
int
prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
-
+
priv->priv_oid = *uwrq;
printk("%s: oid 0x%08X\n", ndev->name, *uwrq);
int
prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct islpci_mgmtframe *response = NULL;
int ret = -EIO, response_op = PIMFOR_OP_ERROR;
-
+
printk("%s: get_oid 0x%08X\n", ndev->name, priv->priv_oid);
data->length = 0;
-
+
if (islpci_get_state(priv) >= PRV_STATE_INIT) {
ret =
islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
printk("%s: len: %i\n", ndev->name, data->length);
}
}
-
+
return ret;
}
int
prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct islpci_mgmtframe *response = NULL;
int ret = 0, response_op = PIMFOR_OP_ERROR;
-
+
printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid,
data->length);
-
+
if (islpci_get_state(priv) >= PRV_STATE_INIT) {
ret =
islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
}
if (ret || response_op == PIMFOR_OP_ERROR) {
printk("%s: EIO\n", ndev->name);
- ret = -EIO;
+ ret = -EIO;
}
}
-
- return ret;
+
+ return (ret ? ret : -EINPROGRESS);
}
static int
#define PRISM54_DBG_GET_OID SIOCIWFIRSTPRIV+15
#define PRISM54_DBG_SET_OID SIOCIWFIRSTPRIV+16
-#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17
+#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17
#define PRISM54_SET_OID_U32 SIOCIWFIRSTPRIV+18
#define PRISM54_SET_OID_STR SIOCIWFIRSTPRIV+20
#define PRISM54_SET_OID_ADDR SIOCIWFIRSTPRIV+22
#define PRISM54_GET_PRISMHDR SIOCIWFIRSTPRIV+23
#define PRISM54_SET_PRISMHDR SIOCIWFIRSTPRIV+24
-#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
-#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
-#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
-#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "get_"x }
+#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
+#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
+#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
+#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "g_"x }
#define IWPRIV_U32(n,x) IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x)
#define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x)
#define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x)
-/* Note : limited to 128 private ioctls */
+/* Note : limited to 128 private ioctls (wireless tools 26) */
static const struct iw_priv_args prism54_private_args[] = {
/*{ cmd, set_args, get_args, name } */
{PRISM54_DBG_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
"dbg_oid"},
{PRISM54_DBG_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "dbg_get_oid"},
- {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_get_oid"},
+ {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_set_oid"},
/* --- sub-ioctls handlers --- */
{PRISM54_GET_OID,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, ""},
IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"),
IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"),
IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"),
-
+
IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"),
IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"),
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
+
return -EOPNOTSUPP;
}
#define SUPPORTED_WIRELESS_EXT 16
void prism54_mib_init(islpci_private *);
-void prism54_mib_init_work(islpci_private *);
struct iw_statistics *prism54_get_wireless_stats(struct net_device *);
void prism54_update_stats(islpci_private *);
#include <asm/io.h>
+#include "prismcompat.h"
#include "isl_38xx.h"
#include "isl_ioctl.h"
#include "islpci_dev.h"
#include "islpci_eth.h"
#include "oid_mgt.h"
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-#define prism54_synchronize_irq(irq) synchronize_irq()
-#else
-#define prism54_synchronize_irq(irq) synchronize_irq(irq)
-#endif
-
#define ISL3877_IMAGE_FILE "isl3877"
#define ISL3890_IMAGE_FILE "isl3890"
* ndev->set_mac_address. Jean II */
const unsigned char dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 };
+static int
+isl_upload_firmware(islpci_private *priv)
+{
+ u32 reg, rc;
+ void *device_base = priv->device_base;
+
+ /* clear the RAMBoot and the Reset bit */
+ reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
+ reg &= ~ISL38XX_CTRL_STAT_RESET;
+ reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
+ writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+ wmb();
+ udelay(ISL38XX_WRITEIO_DELAY);
+
+ /* set the Reset bit without reading the register ! */
+ reg |= ISL38XX_CTRL_STAT_RESET;
+ writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+ wmb();
+ udelay(ISL38XX_WRITEIO_DELAY);
+
+ /* clear the Reset bit */
+ reg &= ~ISL38XX_CTRL_STAT_RESET;
+ writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+ wmb();
+
+ /* wait a while for the device to reboot */
+ mdelay(50);
+
+ {
+ const struct firmware *fw_entry = 0;
+ long fw_len;
+ const u32 *fw_ptr;
+
+ rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+ if (rc) {
+ printk(KERN_ERR
+ "%s: request_firmware() failed for '%s'\n",
+ "prism54", priv->firmware);
+ return rc;
+ }
+ /* prepare the Direct Memory Base register */
+ reg = ISL38XX_DEV_FIRMWARE_ADDRES;
+
+ fw_ptr = (u32 *) fw_entry->data;
+ fw_len = fw_entry->size;
+
+ if (fw_len % 4) {
+ printk(KERN_ERR
+ "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
+ "prism54", priv->firmware);
+ release_firmware(fw_entry);
+ return EILSEQ; /* Illegal byte sequence */;
+ }
+
+ while (fw_len > 0) {
+ long _fw_len =
+ (fw_len >
+ ISL38XX_MEMORY_WINDOW_SIZE) ?
+ ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
+ u32 *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
+
+ /* set the cards base address for writting the data */
+ isl38xx_w32_flush(device_base, reg,
+ ISL38XX_DIR_MEM_BASE_REG);
+ wmb(); /* be paranoid */
+
+ /* increment the write address for next iteration */
+ reg += _fw_len;
+ fw_len -= _fw_len;
+
+ /* write the data to the Direct Memory Window 32bit-wise */
+ /* memcpy_toio() doesn't guarantee 32bit writes :-| */
+ while (_fw_len > 0) {
+ /* use non-swapping writel() */
+ __raw_writel(*fw_ptr, dev_fw_ptr);
+ fw_ptr++, dev_fw_ptr++;
+ _fw_len -= 4;
+ }
+
+ /* flush PCI posting */
+ (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH);
+ wmb(); /* be paranoid again */
+
+ BUG_ON(_fw_len != 0);
+ }
+
+ BUG_ON(fw_len != 0);
+
+ release_firmware(fw_entry);
+ }
+
+ /* now reset the device
+ * clear the Reset & ClkRun bit, set the RAMBoot bit */
+ reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
+ reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
+ reg &= ~ISL38XX_CTRL_STAT_RESET;
+ reg |= ISL38XX_CTRL_STAT_RAMBOOT;
+ isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG);
+ wmb();
+ udelay(ISL38XX_WRITEIO_DELAY);
+
+ /* set the reset bit latches the host override and RAMBoot bits
+ * into the device for operation when the reset bit is reset */
+ reg |= ISL38XX_CTRL_STAT_RESET;
+ writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+ /* don't do flush PCI posting here! */
+ wmb();
+ udelay(ISL38XX_WRITEIO_DELAY);
+
+ /* clear the reset bit should start the whole circus */
+ reg &= ~ISL38XX_CTRL_STAT_RESET;
+ writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
+ /* don't do flush PCI posting here! */
+ wmb();
+ udelay(ISL38XX_WRITEIO_DELAY);
+
+ return 0;
+}
+
/******************************************************************************
Device Interrupt Handler
******************************************************************************/
if (reg & ISL38XX_CTRL_STAT_SLEEPMODE)
/* device is in sleep mode, IRQ was generated by someone else */
{
- printk(KERN_DEBUG "Assuming someone else called the IRQ\n");
+#if VERBOSE > SHOW_ERROR_MESSAGES
+ DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
+#endif
return IRQ_NONE;
}
printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name);
- rc = isl38xx_upload_firmware(priv->firmware,
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,75))
- &priv->pdev->dev,
-#else
- pci_name(priv->pdev),
-#endif
- priv->device_base,
- priv->device_host_address);
+ rc = isl_upload_firmware(priv);
if (rc) {
/* error uploading the firmware */
printk(KERN_ERR "%s: could not upload firmware ('%s')\n",
int result = -ETIME;
int count;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- /* This is 2.6 specific, nicer, shorter, but not in 2.4 yet */
DEFINE_WAIT(wait);
prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE);
-#else
- DECLARE_WAITQUEUE(wait, current);
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&priv->reset_done, &wait);
-#endif
/* now the last step is to reset the interface */
isl38xx_interface_reset(priv->device_base, priv->device_host_address);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- /* 2.6 specific too */
finish_wait(&priv->reset_done, &wait);
-#else
- remove_wait_queue(&priv->reset_done, &wait);
- set_current_state(TASK_RUNNING);
-#endif
if(result)
return result;
* the IRQ line until we know for sure the reset went through */
isl38xx_enable_common_interrupts(priv->device_base);
- prism54_mib_init_work(priv);
+ down_write(&priv->mib_sem);
+ mgt_commit(priv);
+ up_write(&priv->mib_sem);
islpci_set_state(priv, PRV_STATE_READY);
/* reset the mgmt receive queue */
for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
isl38xx_fragment *frag = &cb->rx_data_mgmt[counter];
- frag->size = MGMT_FRAME_SIZE;
+ frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
frag->flags = 0;
- frag->address = priv->mgmt_rx[counter].pci_addr;
+ frag->address = cpu_to_le32(priv->mgmt_rx[counter].pci_addr);
}
for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
skb = NULL;
goto out_free;
}
+ skb_reserve(skb, (4 - (long) skb->data) & 0x03);
/* add the new allocated sk_buff to the buffer array */
priv->data_low_rx[counter] = skb;
#include <net/iw_handler.h>
#include <linux/list.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
-# include <linux/workqueue.h>
-#else
-# include <linux/tqueue.h>
-# define work_struct tq_struct
-# define INIT_WORK INIT_TQUEUE
-# define schedule_work schedule_task
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)
-#define free_netdev(x) kfree(x)
-#define pci_name(x) x->slot_name
-#endif
-
#include "isl_38xx.h"
#include "isl_oid.h"
#include "islpci_mgt.h"
islpci_state_t state;
int state_off; /* enumeration of off-state, if 0 then
* we're not in any off-state */
-
+
/* WPA stuff */
int wpa; /* WPA mode enabled */
struct list_head bss_wpa_list;
#define ISLPCI_TX_TIMEOUT (2*HZ)
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,75))
-# define irqreturn_t void
-# define IRQ_HANDLED
-# define IRQ_NONE
-#endif
-
irqreturn_t islpci_interrupt(int, void *, struct pt_regs *);
int prism54_post_setup(islpci_private *, int);
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
/* check whether the destination queue has enough fragments for the frame */
curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
- if (curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE) {
+ if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
printk(KERN_ERR "%s: transmit device queue full when awake\n",
ndev->name);
netif_stop_queue(ndev);
/* Check alignment and WDS frame formatting. The start of the packet should
* be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
* and add WDS address information */
- if (((long) skb->data & 0x03) | init_wds) {
+ if (unlikely(((long) skb->data & 0x03) | init_wds)) {
/* get the number of bytes to add and re-allign */
offset = (4 - (long) skb->data) & 0x03;
offset += init_wds ? 6 : 0;
pci_map_address = pci_map_single(priv->pdev,
(void *) skb->data, skb->len,
PCI_DMA_TODEVICE);
- if (pci_map_address == 0) {
+ if (unlikely(pci_map_address == 0)) {
printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
ndev->name);
priv->data_low_tx[index] = skb;
/* set the proper fragment start address and size information */
fragment->size = cpu_to_le16(frame_size);
- fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
+ fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
fragment->address = cpu_to_le32(pci_map_address);
curr_frag++;
cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag);
if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD
- > ISL38XX_CB_TX_QSIZE) {
+ > ISL38XX_CB_TX_QSIZE) {
/* stop sends from upper layers */
netif_stop_queue(ndev);
return 0;
- drop_free:
+ drop_free:
/* free the skbuf structure before aborting */
dev_kfree_skb(skb);
skb = NULL;
if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) {
struct avs_80211_1_header *avs;
/* extract the relevant data from the header */
- u32 clock = hdr->clock;
+ u32 clock = le32_to_cpu(hdr->clock);
u8 rate = hdr->rate;
- u16 freq = be16_to_cpu(hdr->freq);
+ u16 freq = le16_to_cpu(hdr->freq);
u8 rssi = hdr->rssi;
skb_pull(*skb, sizeof (struct rfmon_header));
avs_80211_1_header),
0, GFP_ATOMIC);
if (newskb) {
- kfree_skb(*skb);
+ dev_kfree_skb_irq(*skb);
*skb = newskb;
} else
return -1;
(struct avs_80211_1_header *) skb_push(*skb,
sizeof (struct
avs_80211_1_header));
-
- avs->version = htonl(P80211CAPTURE_VERSION);
- avs->length = htonl(sizeof (struct avs_80211_1_header));
- avs->mactime = __cpu_to_be64(clock);
- avs->hosttime = __cpu_to_be64(jiffies);
- avs->phytype = htonl(6); /*OFDM: 6 for (g), 8 for (a) */
- avs->channel = htonl(channel_of_freq(freq));
- avs->datarate = htonl(rate * 5);
- avs->antenna = htonl(0); /*unknown */
- avs->priority = htonl(0); /*unknown */
- avs->ssi_type = htonl(2); /*2: dBm, 3: raw RSSI */
- avs->ssi_signal = htonl(rssi);
- avs->ssi_noise = htonl(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */
- avs->preamble = htonl(0); /*unknown */
- avs->encoding = htonl(0); /*unknown */
+
+ avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
+ avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
+ avs->mactime = cpu_to_be64(le64_to_cpu(clock));
+ avs->hosttime = cpu_to_be64(jiffies);
+ avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */
+ avs->channel = cpu_to_be32(channel_of_freq(freq));
+ avs->datarate = cpu_to_be32(rate * 5);
+ avs->antenna = cpu_to_be32(0); /*unknown */
+ avs->priority = cpu_to_be32(0); /*unknown */
+ avs->ssi_type = cpu_to_be32(3); /*2: dBm, 3: raw RSSI */
+ avs->ssi_signal = cpu_to_be32(rssi & 0x7f);
+ avs->ssi_noise = cpu_to_be32(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */
+ avs->preamble = cpu_to_be32(0); /*unknown */
+ avs->encoding = cpu_to_be32(0); /*unknown */
} else
skb_pull(*skb, sizeof (struct rfmon_header));
skb->dev = ndev;
/* take care of monitor mode and spy monitoring. */
- if (priv->iw_mode == IW_MODE_MONITOR)
+ if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
discard = islpci_monitor_rx(priv, &skb);
else {
- if (skb->data[2 * ETH_ALEN] == 0) {
+ if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
/* The packet has a rx_annex. Read it for spy monitoring, Then
* remove it, while keeping the 2 leading MAC addr.
*/
skb->data[0], skb->data[1], skb->data[2], skb->data[3],
skb->data[4], skb->data[5]);
#endif
- if (discard) {
- dev_kfree_skb(skb);
+ if (unlikely(discard)) {
+ dev_kfree_skb_irq(skb);
skb = NULL;
} else
netif_rx(skb);
index - priv->free_data_rx < ISL38XX_CB_RX_QSIZE) {
/* allocate an sk_buff for received data frames storage
* include any required allignment operations */
- if (skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2), skb == NULL) {
+ skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
+ if (unlikely(skb == NULL)) {
/* error allocating an sk_buff structure elements */
DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
break;
}
+ skb_reserve(skb, (4 - (long) skb->data) & 0x03);
/* store the new skb structure pointer */
index = index % ISL38XX_CB_RX_QSIZE;
priv->data_low_rx[index] = skb;
pci_map_single(priv->pdev, (void *) skb->data,
MAX_FRAGMENT_SIZE_RX + 2,
PCI_DMA_FROMDEVICE);
- if (priv->pci_map_rx_address[index] == (dma_addr_t) NULL) {
+ if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) {
/* error mapping the buffer to device accessable memory address */
DEBUG(SHOW_ERROR_MESSAGES,
"Error mapping DMA address\n");
/* free the skbuf structure before aborting */
- dev_kfree_skb((struct sk_buff *) skb);
+ dev_kfree_skb_irq((struct sk_buff *) skb);
skb = NULL;
break;
}
void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = (islpci_private *) data;
- islpci_reset(priv, 1);
- netif_wake_queue(priv->ndev);
- priv->reset_task_pending = 0;
+ islpci_private *priv = (islpci_private *) data;
+ islpci_reset(priv, 1);
+ netif_wake_queue(priv->ndev);
+ priv->reset_task_pending = 0;
}
void
#include <linux/delay.h>
#include <linux/init.h> /* For __init, __exit */
+#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
#define DRV_NAME "prism54"
-#define DRV_VERSION "1.1"
+#define DRV_VERSION "1.2"
MODULE_AUTHOR("[Intersil] R.Bastings and W.Termorshuizen, The prism54.org Development Team <prism54-devel@prism54.org>");
MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter");
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/moduleparam.h>
#include <asm/io.h>
#include <asm/system.h>
#include <linux/if_arp.h>
+#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
Queue handling for management frames
******************************************************************************/
-
/*
* Helper function to create a PIMFOR management frame header.
*/
{
pimfor_header_t *h = data;
- while ((void *) h < data + len) {
- if(h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
+ while ((void *) h < data + len) {
+ if (h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
le32_to_cpus(&h->oid);
le32_to_cpus(&h->length);
} else {
islpci_mgmt_rx_fill(struct net_device *ndev)
{
islpci_private *priv = netdev_priv(ndev);
- isl38xx_control_block *cb = /* volatile not needed */
- (isl38xx_control_block *) priv->control_block;
+ isl38xx_control_block *cb = /* volatile not needed */
+ (isl38xx_control_block *) priv->control_block;
u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);
#if VERBOSE > SHOW_ERROR_MESSAGES
if (buf->mem == NULL) {
buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC);
if (!buf->mem) {
- printk(KERN_WARNING "Error allocating management frame.\n");
+ printk(KERN_WARNING
+ "Error allocating management frame.\n");
return -ENOMEM;
}
buf->size = MGMT_FRAME_SIZE;
buf->pci_addr = pci_map_single(priv->pdev, buf->mem,
MGMT_FRAME_SIZE,
PCI_DMA_FROMDEVICE);
- if(!buf->pci_addr) {
- printk(KERN_WARNING "Failed to make memory DMA'able\n.");
+ if (!buf->pci_addr) {
+ printk(KERN_WARNING
+ "Failed to make memory DMA'able\n.");
return -ENOMEM;
}
}
- /* be safe: always reset control block information */
+ /* be safe: always reset control block information */
frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
frag->flags = 0;
frag->address = cpu_to_le32(buf->pci_addr);
curr++;
- /* The fragment address in the control block must have
- * been written before announcing the frame buffer to
- * device */
+ /* The fragment address in the control block must have
+ * been written before announcing the frame buffer to
+ * device */
wmb();
- cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] =
- cpu_to_le32(curr);
+ cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = cpu_to_le32(curr);
}
return 0;
}
{
islpci_private *priv = netdev_priv(ndev);
isl38xx_control_block *cb =
- (isl38xx_control_block *) priv->control_block;
+ (isl38xx_control_block *) priv->control_block;
void *p;
int err = -EINVAL;
unsigned long flags;
priv->mgmt_tx[index] = buf;
frag = &cb->tx_data_mgmt[index];
frag->size = cpu_to_le16(frag_len);
- frag->flags = 0; /* for any other than the last fragment, set to 1 */
+ frag->flags = 0; /* for any other than the last fragment, set to 1 */
frag->address = cpu_to_le32(buf.pci_addr);
/* The fragment address in the control block must have
* been written before announcing the frame buffer to
* device */
wmb();
- cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag+1);
+ cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1);
spin_unlock_irqrestore(&priv->slock, flags);
/* trigger the device */
islpci_trigger(priv);
return 0;
- error_unlock:
+ error_unlock:
spin_unlock_irqrestore(&priv->slock, flags);
- error_free:
+ error_free:
kfree(buf.mem);
- error:
+ error:
return err;
}
{
islpci_private *priv = netdev_priv(ndev);
isl38xx_control_block *cb =
- (isl38xx_control_block *) priv->control_block;
+ (isl38xx_control_block *) priv->control_block;
u32 curr_frag;
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n");
#endif
-
- /* Only once per interrupt, determine fragment range to
- * process. This avoids an endless loop (i.e. lockup) if
- * frames come in faster than we can process them. */
+ /* Only once per interrupt, determine fragment range to
+ * process. This avoids an endless loop (i.e. lockup) if
+ * frames come in faster than we can process them. */
curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]);
barrier();
- for ( ; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
+ for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
pimfor_header_t *header;
u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE;
struct islpci_membuf *buf = &priv->mgmt_rx[index];
u16 frag_len;
int size;
struct islpci_mgmtframe *frame;
-
- /* I have no idea (and no documentation) if flags != 0
- * is possible. Drop the frame, reuse the buffer. */
- if(le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
- printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
- ndev->name,
- le16_to_cpu(cb->rx_data_mgmt[index].flags));
- continue;
- }
+
+ /* I have no idea (and no documentation) if flags != 0
+ * is possible. Drop the frame, reuse the buffer. */
+ if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
+ printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
+ ndev->name,
+ le16_to_cpu(cb->rx_data_mgmt[index].flags));
+ continue;
+ }
/* The device only returns the size of the header(s) here. */
frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size);
/*
- * We appear to have no way to tell the device the
- * size of a receive buffer. Thus, if this check
- * triggers, we likely have kernel heap corruption. */
- if (frag_len > MGMT_FRAME_SIZE) {
- printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\
-n",
- ndev->name, frag_len, frag_len);
- frag_len = MGMT_FRAME_SIZE;
- }
+ * We appear to have no way to tell the device the
+ * size of a receive buffer. Thus, if this check
+ * triggers, we likely have kernel heap corruption. */
+ if (frag_len > MGMT_FRAME_SIZE) {
+ printk(KERN_WARNING
+ "%s: Bogus packet size of %d (%#x).\n",
+ ndev->name, frag_len, frag_len);
+ frag_len = MGMT_FRAME_SIZE;
+ }
/* Ensure the results of device DMA are visible to the CPU. */
pci_dma_sync_single(priv->pdev, buf->pci_addr,
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_PIMFOR_FRAMES,
"PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n",
- header->operation, header->oid, header->device_id,
+ header->operation, header->oid, header->device_id,
header->flags, header->length);
/* display the buffer contents for debugging */
display_buffer((char *) header, PIMFOR_HEADER_SIZE);
- display_buffer((char *) header + PIMFOR_HEADER_SIZE, header->length);
+ display_buffer((char *) header + PIMFOR_HEADER_SIZE,
+ header->length);
#endif
/* nobody sends these */
if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) {
- printk(KERN_DEBUG "%s: errant PIMFOR application frame\n",
+ printk(KERN_DEBUG
+ "%s: errant PIMFOR application frame\n",
ndev->name);
continue;
}
/* Determine frame size, skipping OID_INL_TUNNEL headers. */
size = PIMFOR_HEADER_SIZE + header->length;
- frame = kmalloc(sizeof(struct islpci_mgmtframe) + size,
+ frame = kmalloc(sizeof (struct islpci_mgmtframe) + size,
GFP_ATOMIC);
if (!frame) {
- printk(KERN_WARNING "%s: Out of memory, cannot handle oid 0x%08x\n",
-
+ printk(KERN_WARNING
+ "%s: Out of memory, cannot handle oid 0x%08x\n",
ndev->name, header->oid);
- continue;
+ continue;
}
frame->ndev = ndev;
memcpy(&frame->buf, header, size);
header->oid, header->device_id, header->flags,
header->length);
#endif
-
+
/* Create work to handle trap out of interrupt
* context. */
INIT_WORK(&frame->ws, prism54_process_trap, frame);
/* Signal the one waiting process that a response
* has been received. */
if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) {
- printk(KERN_WARNING "%s: mgmt response not collected\n",
+ printk(KERN_WARNING
+ "%s: mgmt response not collected\n",
ndev->name);
kfree(frame);
}
-
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_TRACING,
- "Wake up Mgmt Queue\n");
+ DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n");
#endif
wake_up(&priv->mgmt_wqueue);
}
islpci_mgt_cleanup_transmit(struct net_device *ndev)
{
islpci_private *priv = netdev_priv(ndev);
- isl38xx_control_block *cb = /* volatile not needed */
- (isl38xx_control_block *) priv->control_block;
+ isl38xx_control_block *cb = /* volatile not needed */
+ (isl38xx_control_block *) priv->control_block;
u32 curr_frag;
#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n");
+ DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n");
#endif
/* Only once per cleanup, determine fragment range to
* process. This avoids an endless loop (i.e. lockup) if
* the device became confused, incrementing device_curr_frag
* rapidly. */
- curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]);
+ curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]);
barrier();
- for ( ; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
+ for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE;
struct islpci_membuf *buf = &priv->mgmt_tx[index];
pci_unmap_single(priv->pdev, buf->pci_addr, buf->size,
const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
int err;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
DEFINE_WAIT(wait);
-#else
- DECLARE_WAITQUEUE(wait, current);
-#endif
if (down_interruptible(&priv->mgmt_sem))
return -ERESTARTSYS;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE);
-#else
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&priv->mgmt_wqueue, &wait);
-#endif
err = islpci_mgt_transmit(ndev, operation, oid, senddata, sendlen);
- if(err)
+ if (err)
goto out;
err = -ETIMEDOUT;
timeleft = schedule_timeout(wait_cycle_jiffies);
frame = xchg(&priv->mgmt_received, NULL);
if (frame) {
- *recvframe = frame;
- err = 0;
- goto out;
+ if (frame->header->oid == oid) {
+ *recvframe = frame;
+ err = 0;
+ goto out;
+ } else {
+ printk(KERN_DEBUG
+ "%s: expecting oid 0x%x, received 0x%x.\n",
+ ndev->name, (unsigned int) oid,
+ frame->header->oid);
+ kfree(frame);
+ frame = NULL;
+ }
}
- if(timeleft == 0) {
- printk(KERN_DEBUG "%s: timeout waiting for mgmt response %lu, trigging device\n",
- ndev->name, timeout_left);
+ if (timeleft == 0) {
+ printk(KERN_DEBUG
+ "%s: timeout waiting for mgmt response %lu, "
+ "triggering device\n",
+ ndev->name, timeout_left);
islpci_trigger(priv);
}
timeout_left += timeleft - wait_cycle_jiffies;
/* TODO: we should reset the device here */
out:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
finish_wait(&priv->mgmt_wqueue, &wait);
-#else
- remove_wait_queue(&priv->mgmt_wqueue, &wait);
- set_current_state(TASK_RUNNING);
-#endif
up(&priv->mgmt_sem);
return err;
}
#include <linux/wireless.h>
#include <linux/skbuff.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
-# include <linux/workqueue.h>
-#else
-# include <linux/tqueue.h>
-# define work_struct tq_struct
-# define INIT_WORK INIT_TQUEUE
-# define schedule_work schedule_task
-#endif
-
/*
* Function definitions
*/
#define TRACE(devname) K_DEBUG(SHOW_TRACING, VERBOSE, "%s: -> " __FUNCTION__ "()\n", devname)
extern int pc_debug;
-static const int init_wds = 0; /* help compiler optimize away dead code */
+#define init_wds 0 /* help compiler optimize away dead code */
/* General driver definitions */
*
*/
+#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
#include "isl_oid.h"
if ((f >= 2412) && (f <= 2484)) {
while ((c < 14) && (f != frequency_list_bg[c]))
c++;
- if (c >= 14)
- return 0;
+ return (c >= 14) ? 0 : ++c;
} else if ((f >= (int) 5170) && (f <= (int) 5320)) {
while ((c < 12) && (f != frequency_list_a[c]))
c++;
- if (c >= 12)
- return 0;
+ return (c >= 12) ? 0 : (c + 37);
} else
return 0;
-
- return ++c;
}
#define OID_STRUCT(name,oid,s,t) [name] = {oid, 0, sizeof(s), t}
if (cache)
down_write(&priv->mib_sem);
- if (islpci_get_state(priv) >= PRV_STATE_INIT) {
+ if (islpci_get_state(priv) >= PRV_STATE_READY) {
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
_data, dlen, &response);
if (!ret) {
islpci_mgt_release(response);
}
if (ret || response_op == PIMFOR_OP_ERROR)
- ret = -EIO;
+ ret = -EIO;
} else if (!cache)
ret = -EIO;
int ret = -EIO;
int reslen = 0;
struct islpci_mgmtframe *response = NULL;
-
+
int dlen;
void *cache, *_res = NULL;
u32 oid;
if (cache)
down_read(&priv->mib_sem);
- if (islpci_get_state(priv) >= PRV_STATE_INIT) {
+ if (islpci_get_state(priv) >= PRV_STATE_READY) {
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
oid, data, dlen, &response);
if (ret || !response ||
- response->header->operation == PIMFOR_OP_ERROR) {
+ response->header->operation == PIMFOR_OP_ERROR) {
if (response)
islpci_mgt_release(response);
ret = -EIO;
if (reslen > isl_oid[n].size)
printk(KERN_DEBUG
"mgt_get_request(0x%x): received data length was bigger "
- "than expected (%d > %d). Memory is probably corrupted... ",
+ "than expected (%d > %d). Memory is probably corrupted...",
oid, reslen, isl_oid[n].size);
-
+
return ret;
}
while (j <= t->range) {
response = NULL;
ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
- oid, data, t->size,
+ oid, data, t->size,
&response);
if (response) {
ret |= (response->header->operation ==
- PIMFOR_OP_ERROR);
+ PIMFOR_OP_ERROR);
islpci_mgt_release(response);
}
j++;
OID_INL_OUTPUTPOWER,
};
+/* update the MAC addr. */
+static int
+mgt_update_addr(islpci_private *priv)
+{
+ struct islpci_mgmtframe *res;
+ int ret;
+
+ ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
+ isl_oid[GEN_OID_MACADDRESS].oid, NULL,
+ isl_oid[GEN_OID_MACADDRESS].size, &res);
+
+ if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR))
+ memcpy(priv->ndev->dev_addr, res->data, 6);
+ else
+ ret = -EIO;
+ if (res)
+ islpci_mgt_release(res);
+
+ return ret;
+}
+
void
mgt_commit(islpci_private *priv)
{
int rvalue;
u32 u;
- union oid_res_t r;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return;
u = OID_INL_MODE;
rvalue |= mgt_commit_list(priv, &u, 1);
+ rvalue |= mgt_update_addr(priv);
if (rvalue) {
/* some request have failed. The device might be in an
incoherent state. We should reset it ! */
printk(KERN_DEBUG "%s: mgt_commit has failed. Restart the "
- "device \n", priv->ndev->name);
+ "device \n", priv->ndev->name);
}
-
- /* update the MAC addr. As it's not cached, no lock will be acquired by
- * the mgt_get_request
- */
- mgt_get_request(priv, GEN_OID_MACADDRESS, 0, NULL, &r);
- memcpy(priv->ndev->dev_addr, r.ptr, 6);
- kfree(r.ptr);
-
}
/* This will tell you if you are allowed to answer a mlme(ex) request .*/
{
int i;
- for (i = 0; i < OID_NUM_LAST - 1; i++)
+ for (i = 0; i < OID_NUM_LAST; i++)
if (isl_oid[i].oid == oid)
return i;
printk(KERN_DEBUG "looking for an unknown oid 0x%x", oid);
- return 0;
+ return OID_NUM_LAST;
}
int
case OID_TYPE_BSS:{
struct obj_bss *bss = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
- "age=%u\nchannel=%u\n\
- capinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", bss->age, bss->channel, bss->capinfo, bss->rates, bss->basic_rates);
+ "age=%u\nchannel=%u\n"
+ "capinfo=0x%X\nrates=0x%X\n"
+ "basic_rates=0x%X\n", bss->age,
+ bss->channel, bss->capinfo,
+ bss->rates, bss->basic_rates);
}
break;
case OID_TYPE_BSSLIST:{
k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
for (i = 0; i < list->nr; i++)
k += snprintf(str + k, PRIV_STR_SIZE - k,
- "bss[%u] : \nage=%u\nchannel=%u\ncapinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n",
+ "bss[%u] : \nage=%u\nchannel=%u\n"
+ "capinfo=0x%X\nrates=0x%X\n"
+ "basic_rates=0x%X\n",
i, list->bsslist[i].age,
list->bsslist[i].channel,
list->bsslist[i].capinfo,
break;
case OID_TYPE_MLME:{
struct obj_mlme *mlme = r->ptr;
- return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\
- code=0x%X\n", mlme->id, mlme->state,
- mlme->code);
+ return snprintf(str, PRIV_STR_SIZE,
+ "id=0x%X\nstate=0x%X\ncode=0x%X\n",
+ mlme->id, mlme->state, mlme->code);
}
break;
case OID_TYPE_MLMEEX:{
struct obj_mlmeex *mlme = r->ptr;
- return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\
- code=0x%X\nsize=0x%X\n", mlme->id, mlme->state,
- mlme->code, mlme->size);
+ return snprintf(str, PRIV_STR_SIZE,
+ "id=0x%X\nstate=0x%X\n"
+ "code=0x%X\nsize=0x%X\n", mlme->id,
+ mlme->state, mlme->code, mlme->size);
}
break;
case OID_TYPE_SSID:{
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
- union oid_res_t *);
+ union oid_res_t *);
int mgt_commit_list(islpci_private *, enum oid_num_t *, int);
#endif /* HISTOGRAM */
static inline int
-wl_netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+wl_netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
u32 ethcmd;
switch(cmd)
{
case SIOCETHTOOL:
- ret = wl_netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ ret = wl_netdev_ethtool_ioctl(dev, rq->ifr_data);
break;
/* ------------------- OTHER IOCTL ------------------- */
return wstats;
}
-static inline int wl3501_ethtool_ioctl(struct net_device *dev, void *uaddr)
+static inline int wl3501_ethtool_ioctl(struct net_device *dev, void __user *uaddr)
{
u32 ethcmd;
int rc = -EFAULT;
if (netif_device_present(dev)) {
rc = -EOPNOTSUPP;
if (cmd == SIOCETHTOOL)
- rc = wl3501_ethtool_ioctl(dev, (void *)rq->ifr_data);
+ rc = wl3501_ethtool_ioctl(dev, rq->ifr_data);
}
return rc;
}
np = dev->priv;
- if (pci_request_regions(pdev, dev->name))
+ if (pci_request_regions(pdev, DRV_NAME))
goto err_out_free_netdev;
pci_set_master (pdev);
break;
skb->dev = dev;
skb_reserve(skb, 2); /* 16 byte align the IP header */
-#if HAS_IP_COPYSUM
eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0);
skb_put(skb, pkt_len);
-#else
- memcpy(skb_put(skb, pkt_len),
- rx_skb->tail, pkt_len);
-#endif
pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
yp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
outw(cfg_value | 0x1000, ioaddr + Cnfg);
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
struct yellowfin_private *np = dev->priv;
u32 ethcmd;
{
struct yellowfin_private *np = dev->priv;
long ioaddr = dev->base_addr;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct mii_ioctl_data *data = if_mii(rq);
switch(cmd) {
case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ return netdev_ethtool_ioctl(dev, rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = np->phys[0] & 0x1f;
/* Fall Through */
#include "8390.h"
+#define DRV_NAME "zorro8390"
+
#define NE_BASE (dev->base_addr)
#define NE_CMD (0x00*2)
#define NE_DATAPORT (0x10*2) /* NatSemi-defined port window offset. */
if (!dev)
return -ENOMEM;
SET_MODULE_OWNER(dev);
- if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, dev->name)) {
+ if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) {
free_netdev(dev);
return -EBUSY;
}
dev->irq = IRQ_AMIGA_PORTS;
/* Install the Interrupt handler */
- i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, dev->name, dev);
+ i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, DRV_NAME, dev);
if (i) return i;
for(i = 0; i < ETHER_ADDR_LEN; i++) {
#include <asm/byteorder.h>
#include <asm/cache.h> /* for L1_CACHE_BYTES */
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/io.h>
#include <asm/hardware.h>
1676 NetXtreme BCM5750 Gigabit Ethernet
1677 NetXtreme BCM5751 Gigabit Ethernet
167c NetXtreme BCM5750M Gigabit Ethernet
+ 167d NetXtreme BCM5751M Gigabit Ethernet
+ 167e NetXtreme BCM5751F Gigabit Ethernet
1696 NetXtreme BCM5782 Gigabit Ethernet
103c 12bc HP d530 CMT (DG746A)
14e4 000d NetXtreme BCM5782 1000Base-T
169c NetXtreme BCM5788 Gigabit Ethernet
+ 169d NetXtreme BCM5789 Gigabit Ethernet
16a6 NetXtreme BCM5702X Gigabit Ethernet
0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
1028 0126 BCM5702 1000Base-T
/*====================================================================*/
-static ssize_t ds_read(struct file *file, char *buf,
+static ssize_t ds_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct pcmcia_bus_socket *s;
ret = wait_event_interruptible(s->queue, !queue_empty(user));
if (ret == 0)
- ret = put_user(get_queued_event(user), (int *)buf) ? -EFAULT : 4;
+ ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
return ret;
} /* ds_read */
/*====================================================================*/
-static ssize_t ds_write(struct file *file, const char *buf,
+static ssize_t ds_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct pcmcia_bus_socket *s;
if (s->req_pending) {
s->req_pending--;
- get_user(s->req_result, (int *)buf);
+ get_user(s->req_result, (int __user *)buf);
if ((s->req_result != 0) || (s->req_pending == 0))
wake_up_interruptible(&s->request);
} else
u_int cmd, u_long arg)
{
struct pcmcia_bus_socket *s;
+ void __user *uarg = (char __user *)arg;
u_int size;
int ret, err;
ds_ioctl_arg_t buf;
return -EPERM;
if (cmd & IOC_IN) {
- err = verify_area(VERIFY_READ, (char *)arg, size);
+ err = verify_area(VERIFY_READ, uarg, size);
if (err) {
ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err);
return err;
}
}
if (cmd & IOC_OUT) {
- err = verify_area(VERIFY_WRITE, (char *)arg, size);
+ err = verify_area(VERIFY_WRITE, uarg, size);
if (err) {
ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err);
return err;
err = ret = 0;
- if (cmd & IOC_IN) __copy_from_user((char *)&buf, (char *)arg, size);
+ if (cmd & IOC_IN) __copy_from_user((char *)&buf, uarg, size);
switch (cmd) {
case DS_ADJUST_RESOURCE_INFO:
}
}
- if (cmd & IOC_OUT) __copy_to_user((char *)arg, (char *)&buf, size);
+ if (cmd & IOC_OUT) __copy_to_user(uarg, (char *)&buf, size);
return err;
} /* ds_ioctl */
{
int i, ret;
- if (driver_register(&i82365_driver))
- return -1;
+ ret = driver_register(&i82365_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_device_register(&i82365_device);
+ if (ret) {
+ driver_unregister(&i82365_driver);
+ return ret;
+ }
printk(KERN_INFO "Intel ISA PCIC probe: ");
sockets = 0;
if (sockets == 0) {
printk("not found.\n");
+ platform_device_unregister(&i82365_device);
driver_unregister(&i82365_driver);
return -ENODEV;
}
- platform_device_register(&i82365_device);
-
/* Set up interrupt handler(s) */
if (grab_irq != 0)
request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
-#include <linux/notifier.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
return pxa2xx_pcmcia_set_mcxx(skt, clk);
}
+#ifdef CONFIG_CPU_FREQ
+
+static int
+pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
+ unsigned long val,
+ struct cpufreq_freqs *freqs)
+{
+#warning "it's not clear if this is right since the core CPU (N) clock has no effect on the memory (L) clock"
+ switch (val) {
+ case CPUFREQ_PRECHANGE:
+ if (freqs->new > freqs->old) {
+ debug(skt, 2, "new frequency %u.%uMHz > %u.%uMHz, "
+ "pre-updating\n",
+ freqs->new / 1000, (freqs->new / 100) % 10,
+ freqs->old / 1000, (freqs->old / 100) % 10);
+ pxa2xx_pcmcia_set_mcxx(skt, freqs->new);
+ }
+ break;
+
+ case CPUFREQ_POSTCHANGE:
+ if (freqs->new < freqs->old) {
+ debug(skt, 2, "new frequency %u.%uMHz < %u.%uMHz, "
+ "post-updating\n",
+ freqs->new / 1000, (freqs->new / 100) % 10,
+ freqs->old / 1000, (freqs->old / 100) % 10);
+ pxa2xx_pcmcia_set_mcxx(skt, freqs->new);
+ }
+ break;
+ }
+ return 0;
+}
+#endif
+
int pxa2xx_drv_pcmcia_probe(struct device *dev)
{
int ret;
/* Provide our PXA2xx specific timing routines. */
ops->set_timing = pxa2xx_pcmcia_set_timing;
+#ifdef CONFIG_CPU_FREQ
+ ops->frequency_change = pxa2xx_pcmcia_frequency_change;
+#endif
ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr);
.bus = &platform_bus_type,
};
-#ifdef CONFIG_CPU_FREQ
-
-/*
- * When pxa2xx_pcmcia_notifier() decides that a MC{IO,MEM,ATT} adjustment (due
- * to a core clock frequency change) is needed, this routine establishes
- * new values consistent with the clock speed `clock'.
- */
-static void pxa2xx_pcmcia_update_mcxx(unsigned int clock)
-{
- struct soc_pcmcia_socket *skt;
-
- down(&soc_sockets_lock);
- list_for_each_entry(skt, &soc_sockets, node) {
- pxa2xx_pcmcia_set_mcxx(skt, clock);
- }
- up(&soc_sockets_lock);
-}
-
-/*
- * When changing the processor L clock frequency, it is necessary
- * to adjust the MCXX timings accordingly. We've recorded the timings
- * requested by Card Services, so this is just a matter of finding
- * out what our current speed is, and then recomputing the new MCXX
- * values.
- *
- * Returns: 0 on success, -1 on error
- */
-static int
-pxa2xx_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
-{
- struct cpufreq_freqs *freqs = data;
-
-#warning "it's not clear if this is right since the core CPU (N) clock has no effect on the memory (L) clock"
- switch (val) {
- case CPUFREQ_PRECHANGE:
- if (freqs->new > freqs->old) {
- debug( 2, "new frequency %u.%uMHz > %u.%uMHz, "
- "pre-updating\n",
- freqs->new / 1000, (freqs->new / 100) % 10,
- freqs->old / 1000, (freqs->old / 100) % 10);
- pxa2xx_pcmcia_update_mcxx(freqs->new);
- }
- break;
-
- case CPUFREQ_POSTCHANGE:
- if (freqs->new < freqs->old) {
- debug( 2, "new frequency %u.%uMHz < %u.%uMHz, "
- "post-updating\n",
- freqs->new / 1000, (freqs->new / 100) % 10,
- freqs->old / 1000, (freqs->old / 100) % 10);
- pxa2xx_pcmcia_update_mcxx(freqs->new);
- }
- break;
- }
-
- return 0;
-}
-
-static struct notifier_block pxa2xx_pcmcia_notifier_block = {
- .notifier_call = pxa2xx_pcmcia_notifier
-};
-
-static int __init pxa2xx_pcmcia_cpufreq_init(void)
-{
- int ret;
-
- ret = cpufreq_register_notifier(&pxa2xx_pcmcia_notifier_block,
- CPUFREQ_TRANSITION_NOTIFIER);
- if (ret < 0)
- printk(KERN_ERR "Unable to register CPU frequency change "
- "notifier for PCMCIA (%d)\n", ret);
- return ret;
-}
-
-static void __exit pxa2xx_pcmcia_cpufreq_exit(void)
-{
- cpufreq_unregister_notifier(&pxa2xx_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-#else
-#define pxa2xx_pcmcia_cpufreq_init()
-#define pxa2xx_pcmcia_cpufreq_exit()
-#endif
-
static int __init pxa2xx_pcmcia_init(void)
{
- int ret = driver_register(&pxa2xx_pcmcia_driver);
- if (ret == 0)
- pxa2xx_pcmcia_cpufreq_init();
- return ret;
+ return driver_register(&pxa2xx_pcmcia_driver);
}
static void __exit pxa2xx_pcmcia_exit(void)
{
- pxa2xx_pcmcia_cpufreq_exit();
driver_unregister(&pxa2xx_pcmcia_driver);
}
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/mach-types.h>
+#include <asm/arch/lubbock.h>
#include "sa1111_generic.h"
#include <asm/hardware.h>
#include <asm/irq.h>
+#include <asm/arch/mainstone.h>
+
#include "soc_common.h"
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
-#include <linux/notifier.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
return 0;
}
+#ifdef CONFIG_CPU_FREQ
+static int
+sa1100_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
+ unsigned long val,
+ struct cpufreq_freqs *freqs)
+{
+ switch (val) {
+ case CPUFREQ_PRECHANGE:
+ if (freqs->new > freqs->old)
+ sa1100_pcmcia_set_mecr(skt, freqs->new);
+ break;
+
+ case CPUFREQ_POSTCHANGE:
+ if (freqs->new < freqs->old)
+ sa1100_pcmcia_set_mecr(skt, freqs->new);
+ break;
+ case CPUFREQ_RESUMECHANGE:
+ sa1100_pcmcia_set_mecr(skt, freqs->new);
+ break;
+ }
+
+ return 0;
+}
+
+#endif
+
static int
sa1100_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{
/* Provide our SA11x0 specific timing routines. */
ops->set_timing = sa1100_pcmcia_set_timing;
ops->show_timing = sa1100_pcmcia_show_timing;
+#ifdef CONFIG_CPU_FREQ
+ ops->frequency_change = sa1100_pcmcia_frequency_change;
+#endif
return soc_common_drv_pcmcia_probe(dev, ops, first, nr);
}
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
-#ifdef CONFIG_CPU_FREQ
-
-/* sa1100_pcmcia_update_mecr()
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * When sa1100_pcmcia_notifier() decides that a MECR adjustment (due
- * to a core clock frequency change) is needed, this routine establishes
- * new BS_xx values consistent with the clock speed `clock'.
- */
-static void sa1100_pcmcia_update_mecr(unsigned int clock)
-{
- struct soc_pcmcia_socket *skt;
-
- down(&soc_pcmcia_sockets_lock);
- list_for_each_entry(skt, &soc_pcmcia_sockets, node)
- sa1100_pcmcia_set_mecr(skt, clock);
- up(&soc_pcmcia_sockets_lock);
-}
-
-/* sa1100_pcmcia_notifier()
- * ^^^^^^^^^^^^^^^^^^^^^^^^
- * When changing the processor core clock frequency, it is necessary
- * to adjust the MECR timings accordingly. We've recorded the timings
- * requested by Card Services, so this is just a matter of finding
- * out what our current speed is, and then recomputing the new MECR
- * values.
- *
- * Returns: 0 on success, -1 on error
- */
-static int
-sa1100_pcmcia_notifier(struct notifier_block *nb, unsigned long val,
- void *data)
-{
- struct cpufreq_freqs *freqs = data;
-
- switch (val) {
- case CPUFREQ_PRECHANGE:
- if (freqs->new > freqs->old)
- sa1100_pcmcia_update_mecr(freqs->new);
- break;
-
- case CPUFREQ_POSTCHANGE:
- if (freqs->new < freqs->old)
- sa1100_pcmcia_update_mecr(freqs->new);
- break;
- case CPUFREQ_RESUMECHANGE:
- sa1100_pcmcia_update_mecr(freqs->new);
- break;
- }
-
- return 0;
-}
-
-static struct notifier_block sa1100_pcmcia_notifier_block = {
- .notifier_call = sa1100_pcmcia_notifier
-};
-
static int __init sa11xx_pcmcia_init(void)
{
- int ret;
-
- printk(KERN_INFO "SA11xx PCMCIA\n");
-
- ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
- CPUFREQ_TRANSITION_NOTIFIER);
- if (ret < 0)
- printk(KERN_ERR "Unable to register CPU frequency change "
- "notifier (%d)\n", ret);
-
- return ret;
+ return 0;
}
module_init(sa11xx_pcmcia_init);
-static void __exit sa11xx_pcmcia_exit(void)
-{
- cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-}
+static void __exit sa11xx_pcmcia_exit(void) {}
module_exit(sa11xx_pcmcia_exit);
-#endif
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
MODULE_DESCRIPTION("Linux PCMCIA Card Services: SA-11xx core socket driver");
======================================================================*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/cpufreq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#define SKT_DEV_INFO_SIZE(n) \
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+#ifdef CONFIG_CPU_FREQ
+static int
+soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+ struct soc_pcmcia_socket *skt;
+ struct cpufreq_freqs *freqs = data;
+ int ret = 0;
+
+ down(&soc_pcmcia_sockets_lock);
+ list_for_each_entry(skt, &soc_pcmcia_sockets, node)
+ if ( skt->ops->frequency_change )
+ ret += skt->ops->frequency_change(skt, val, freqs);
+ up(&soc_pcmcia_sockets_lock);
+
+ return ret;
+}
+
+static struct notifier_block soc_pcmcia_notifier_block = {
+ .notifier_call = soc_pcmcia_notifier
+};
+
+static int soc_pcmcia_cpufreq_register(void)
+{
+ int ret;
+
+ ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ if (ret < 0)
+ printk(KERN_ERR "Unable to register CPU frequency change "
+ "notifier for PCMCIA (%d)\n", ret);
+ return ret;
+}
+
+static void soc_pcmcia_cpufreq_unregister(void)
+{
+ cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+#define soc_pcmcia_cpufreq_register()
+#define soc_pcmcia_cpufreq_unregister()
+#endif
+
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{
struct skt_dev_info *sinfo;
goto out_err_5;
}
+ if ( list_empty(&soc_pcmcia_sockets) )
+ soc_pcmcia_cpufreq_register();
+
list_add(&skt->node, &soc_pcmcia_sockets);
/*
release_resource(&skt->res_io);
release_resource(&skt->res_skt);
}
+ if ( list_empty(&soc_pcmcia_sockets) )
+ soc_pcmcia_cpufreq_unregister();
+
up(&soc_pcmcia_sockets_lock);
kfree(sinfo);
#define _ASM_ARCH_PCMCIA
/* include the world */
+#include <linux/cpufreq.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
unsigned int (*get_timing)(struct soc_pcmcia_socket *, unsigned int, unsigned int);
int (*set_timing)(struct soc_pcmcia_socket *);
int (*show_timing)(struct soc_pcmcia_socket *, char *);
+
+#ifdef CONFIG_CPU_FREQ
+ /*
+ * CPUFREQ support.
+ */
+ int (*frequency_change)(struct soc_pcmcia_socket *, unsigned long, struct cpufreq_freqs *);
+#endif
};
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1451A, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, TI12XX),
+ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1620, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX),
MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
MODULE_LICENSE("GPL");
-#ifdef CONFIG_X86_PC9800
-#define _PIDXR 0x259
-#define _PNPWRP 0xa59
-#else
#define _PIDXR 0x279
#define _PNPWRP 0xa79
-#endif
/* short tags */
#define _STAG_PNPVERNO 0x01
return (file->f_pos = new);
}
-static ssize_t isapnp_proc_bus_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+static ssize_t isapnp_proc_bus_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
struct inode *ino = file->f_dentry->d_inode;
struct proc_dir_entry *dp = PDE(ino);
return len;
}
-static int proc_write_node(struct file *file, const char *buf,
+static int proc_write_node(struct file *file, const char __user *buf,
unsigned long count, void *data)
{
struct pnp_bios_node *node;
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
- * $Revision: 1.141 $
+ * $Revision: 1.142 $
*/
#include <linux/config.h>
* SECTION: exported variables of dasd.c
*/
debug_info_t *dasd_debug_area;
+struct dasd_discipline *dasd_diag_discipline_pointer;
MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
MODULE_DESCRIPTION("Linux on S/390 DASD device driver,"
DBF_EVENT(DBF_EMERG, "%s", "debug area created");
+ dasd_diag_discipline_pointer = NULL;
+
rc = devfs_mk_dir("dasd");
if (rc)
goto failed;
module_exit(dasd_exit);
EXPORT_SYMBOL(dasd_debug_area);
+EXPORT_SYMBOL(dasd_diag_discipline_pointer);
EXPORT_SYMBOL(dasd_add_request_head);
EXPORT_SYMBOL(dasd_add_request_tail);
dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args)
{
struct dasd_device *device;
- struct cmbdata * __user udata;
+ struct cmbdata __user *udata;
struct cmbdata data;
size_t size;
int ret;
device = bdev->bd_disk->private_data;
if (!device)
return -EINVAL;
- udata = (void *) args;
+ udata = (void __user *) args;
size = _IOC_SIZE(no);
if (!access_ok(VERIFY_WRITE, udata, size))
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.34 $
+ * $Revision: 1.36 $
*/
#include <linux/config.h>
MODULE_LICENSE("GPL");
+struct dasd_discipline dasd_diag_discipline;
+
struct dasd_diag_private {
struct dasd_diag_characteristics rdc_data;
struct dasd_diag_rw_io iob;
mdsk_term_io(device);
}
if (bsize <= PAGE_SIZE && label[3] == bsize &&
- label[0] == 0xc3d4e2f1 && label[13] != 0) {
+ label[0] == 0xc3d4e2f1) {
device->blocks = label[7];
device->bp_block = bsize;
device->s2b_shift = 0; /* bits to shift 512 to get a block */
ctl_set_bit(0, 9);
register_external_interrupt(0x2603, dasd_ext_handler);
+ dasd_diag_discipline_pointer = &dasd_diag_discipline;
return 0;
}
}
unregister_external_interrupt(0x2603, dasd_ext_handler);
ctl_clear_bit(0, 9);
+ dasd_diag_discipline_pointer = NULL;
}
module_init(dasd_diag_init);
/* Prepare for Read Subsystem Data */
prssdp = (struct dasd_psf_prssd_data *) cqr->data;
stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
- rc = copy_to_user((long *) args, (long *) stats,
+ rc = copy_to_user((long __user *) args, (long *) stats,
sizeof(struct dasd_rssd_perf_stats_t));
}
dasd_sfree_request(cqr, cqr->device);
private = (struct dasd_eckd_private *) device->private;
attrib = private->attrib;
-
- rc = copy_to_user((long *) args, (long *) &attrib,
+
+ rc = copy_to_user((long __user *) args, (long *) &attrib,
sizeof (struct attrib_data_t));
-
+
return rc;
}
if (device == NULL)
return -ENODEV;
- if (copy_from_user(&attrib, (void *) args,
+ if (copy_from_user(&attrib, (void __user *) args,
sizeof (struct attrib_data_t))) {
return -EFAULT;
}
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
- * $Revision: 1.57 $
+ * $Revision: 1.58 $
*/
#ifndef DASD_INT_H
int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
};
-extern struct dasd_discipline dasd_diag_discipline;
-#ifdef CONFIG_DASD_DIAG
-#define dasd_diag_discipline_pointer (&dasd_diag_discipline)
-#else
-#define dasd_diag_discipline_pointer (0)
-#endif
+extern struct dasd_discipline *dasd_diag_discipline_pointer;
struct dasd_device {
/* Block device stuff. */
dasd_ioctl_api_version(struct block_device *bdev, int no, long args)
{
int ver = DASD_API_VERSION;
- return put_user(ver, (int *) args);
+ return put_user(ver, (int __user *) args);
}
/*
return -ENODEV;
if (test_bit(DASD_FLAG_RO, &device->flags))
return -EROFS;
- if (copy_from_user(&fdata, (void *) args,
+ if (copy_from_user(&fdata, (void __user *) args,
sizeof (struct format_data_t)))
return -EFAULT;
if (bdev != bdev->bd_contains) {
if (device == NULL)
return -ENODEV;
- if (copy_to_user((long *) args, (long *) &device->profile,
+ if (copy_to_user((long __user *) args, (long *) &device->profile,
sizeof (struct dasd_profile_info_t)))
return -EFAULT;
return 0;
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
flags);
}
-
+
rc = 0;
- if (copy_to_user((long *) args, (long *) dasd_info,
+ if (copy_to_user((long __user *) args, (long *) dasd_info,
((no == (unsigned int) BIODASDINFO2) ?
sizeof (struct dasd_information2_t) :
sizeof (struct dasd_information_t))))
if (bdev != bdev->bd_contains)
// ro setting is not allowed for partitions
return -EINVAL;
- if (get_user(intval, (int *) args))
+ if (get_user(intval, (int __user *) args))
return -EFAULT;
device = bdev->bd_disk->private_data;
if (device == NULL)
geo = (struct hd_geometry) {};
device->discipline->fill_geometry(device, &geo);
geo.start = get_start_sect(bdev) >> device->s2b_shift;
- if (copy_to_user((struct hd_geometry *) args, &geo,
+ if (copy_to_user((struct hd_geometry __user *) args, &geo,
sizeof (struct hd_geometry)))
return -EFAULT;
static struct proc_dir_entry *dasd_statistics_entry = NULL;
static inline char *
-dasd_get_user_string(const char *user_buf, size_t user_len)
+dasd_get_user_string(const char __user *user_buf, size_t user_len)
{
char *buffer;
}
static int
-dasd_statistics_write(struct file *file, const char *user_buf,
+dasd_statistics_write(struct file *file, const char __user *user_buf,
unsigned long user_len, void *data)
{
#ifdef CONFIG_DASD_PROFILE
};
static struct list_head dcssblk_devices = LIST_HEAD_INIT(dcssblk_devices);
-static rwlock_t dcssblk_devices_lock = RW_LOCK_UNLOCKED;
-
+static struct rw_semaphore dcssblk_devices_sem;
/*
* release function for segment device.
/*
* get a minor number. needs to be called with
- * write_lock(&dcssblk_devices_lock) and the
- * device needs to be enqueued before the lock is
+ * down_write(&dcssblk_devices_sem) and the
+ * device needs to be enqueued before the semaphore is
* freed.
*/
static inline int
/*
* get the struct dcssblk_dev_info from dcssblk_devices
* for the given name.
- * read_lock(&dcssblk_devices_lock) must be held.
+ * down_read(&dcssblk_devices_sem) must be held.
*/
static struct dcssblk_dev_info *
dcssblk_get_device_by_name(char *name)
return NULL;
}
-/*
- * register the device that represents a segment in sysfs,
- * also add the attributes for the device
- */
-static inline int
-dcssblk_register_segment_device(struct device *dev)
-{
- int rc;
-
- rc = device_register(dev);
- if (rc)
- return rc;
- rc = device_create_file(dev, &dev_attr_shared);
- if (rc)
- goto unregister_dev;
- rc = device_create_file(dev, &dev_attr_save);
- if (rc)
- goto unregister_dev;
- return rc;
-
-unregister_dev:
- device_unregister(dev);
- return rc;
-}
-
/*
* device attribute for switching shared/nonshared (exclusive)
* operation (show + store)
PRINT_WARN("Invalid value, must be 0 or 1\n");
return -EINVAL;
}
- write_lock(&dcssblk_devices_lock);
+ down_write(&dcssblk_devices_sem);
dev_info = container_of(dev, struct dcssblk_dev_info, dev);
if (atomic_read(&dev_info->use_count)) {
PRINT_ERR("share: segment %s is busy!\n",
dev_info->segment_name);
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
return -EBUSY;
}
if ((inbuf[0] == '1') && (dev_info->is_shared == 1)) {
PRINT_WARN("Segment %s already loaded in shared mode!\n",
dev_info->segment_name);
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
return count;
}
if ((inbuf[0] == '0') && (dev_info->is_shared == 0)) {
PRINT_WARN("Segment %s already loaded in exclusive mode!\n",
dev_info->segment_name);
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
return count;
}
if (inbuf[0] == '1') {
PRINT_INFO("Segment %s reloaded, exclusive (read-write) mode.\n",
dev_info->segment_name);
} else {
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
PRINT_WARN("Invalid value, must be 0 or 1\n");
return -EINVAL;
}
dev_info->segment_name);
rc = -EPERM;
}
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
goto out;
removeseg:
PRINT_ERR("Could not reload segment %s, removing it now!\n",
dev_info->segment_name);
list_del(&dev_info->lh);
- write_unlock(&dcssblk_devices_lock);
del_gendisk(dev_info->gd);
blk_put_queue(dev_info->dcssblk_queue);
put_disk(dev_info->gd);
device_unregister(dev);
put_device(dev);
+ up_write(&dcssblk_devices_sem);
out:
return rc;
}
}
dev_info = container_of(dev, struct dcssblk_dev_info, dev);
- write_lock(&dcssblk_devices_lock);
+ down_write(&dcssblk_devices_sem);
if (inbuf[0] == '1') {
if (atomic_read(&dev_info->use_count) == 0) {
// device is idle => we save immediately
dev_info->segment_name);
}
} else {
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
PRINT_WARN("Invalid value, must be 0 or 1\n");
return -EINVAL;
}
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
return count;
}
/*
* already loaded?
*/
- read_lock(&dcssblk_devices_lock);
+ down_read(&dcssblk_devices_sem);
dev_info = dcssblk_get_device_by_name(local_buf);
- read_unlock(&dcssblk_devices_lock);
+ up_read(&dcssblk_devices_sem);
if (dev_info != NULL) {
PRINT_WARN("Segment %s already loaded!\n", local_buf);
rc = -EEXIST;
/*
* get minor, add to list
*/
- write_lock(&dcssblk_devices_lock);
+ down_write(&dcssblk_devices_sem);
rc = dcssblk_assign_free_minor(dev_info);
if (rc) {
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
PRINT_ERR("No free minor number available! "
"Unloading segment...\n");
goto unload_seg;
sprintf(dev_info->gd->disk_name, "dcssblk%d",
dev_info->gd->first_minor);
list_add_tail(&dev_info->lh, &dcssblk_devices);
+
+ if (!try_module_get(THIS_MODULE)) {
+ rc = -ENODEV;
+ goto list_del;
+ }
/*
* register the device
*/
- rc = dcssblk_register_segment_device(&dev_info->dev);
+ rc = device_register(&dev_info->dev);
if (rc) {
PRINT_ERR("Segment %s could not be registered RC=%d\n",
local_buf, rc);
+ module_put(THIS_MODULE);
goto list_del;
}
-
- if (!try_module_get(THIS_MODULE)) {
- rc = -ENODEV;
- goto list_del;
- }
-
get_device(&dev_info->dev);
+ rc = device_create_file(&dev_info->dev, &dev_attr_shared);
+ if (rc)
+ goto unregister_dev;
+ rc = device_create_file(&dev_info->dev, &dev_attr_save);
+ if (rc)
+ goto unregister_dev;
+
add_disk(dev_info->gd);
blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request);
break;
}
PRINT_DEBUG("Segment %s loaded successfully\n", local_buf);
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
rc = count;
goto out;
+unregister_dev:
+ PRINT_ERR("device_create_file() failed!\n");
+ list_del(&dev_info->lh);
+ blk_put_queue(dev_info->dcssblk_queue);
+ dev_info->gd->queue = NULL;
+ put_disk(dev_info->gd);
+ device_unregister(&dev_info->dev);
+ segment_unload(dev_info->segment_name);
+ put_device(&dev_info->dev);
+ up_write(&dcssblk_devices_sem);
+ goto out;
list_del:
list_del(&dev_info->lh);
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
unload_seg:
segment_unload(local_buf);
dealloc_gendisk:
goto out_buf;
}
- write_lock(&dcssblk_devices_lock);
+ down_write(&dcssblk_devices_sem);
dev_info = dcssblk_get_device_by_name(local_buf);
if (dev_info == NULL) {
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
PRINT_WARN("Segment %s is not loaded!\n", local_buf);
rc = -ENODEV;
goto out_buf;
}
if (atomic_read(&dev_info->use_count) != 0) {
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
PRINT_WARN("Segment %s is in use!\n", local_buf);
rc = -EBUSY;
goto out_buf;
}
list_del(&dev_info->lh);
- write_unlock(&dcssblk_devices_lock);
del_gendisk(dev_info->gd);
blk_put_queue(dev_info->dcssblk_queue);
PRINT_DEBUG("Segment %s unloaded successfully\n",
dev_info->segment_name);
put_device(&dev_info->dev);
+ up_write(&dcssblk_devices_sem);
+
rc = count;
out_buf:
kfree(local_buf);
rc = -ENODEV;
goto out;
}
- write_lock(&dcssblk_devices_lock);
+ down_write(&dcssblk_devices_sem);
if (atomic_dec_and_test(&dev_info->use_count)
&& (dev_info->save_pending)) {
PRINT_INFO("Segment %s became idle and is being saved now\n",
segment_replace(dev_info->segment_name);
dev_info->save_pending = 0;
}
- write_unlock(&dcssblk_devices_lock);
+ up_write(&dcssblk_devices_sem);
rc = 0;
out:
return rc;
dev_info = bio->bi_bdev->bd_disk->private_data;
if (dev_info == NULL)
goto fail;
- if ((bio->bi_sector & 3) != 0 || (bio->bi_size & 4095) != 0)
+ if ((bio->bi_sector & 7) != 0 || (bio->bi_size & 4095) != 0)
/* Request is not page-aligned. */
goto fail;
if (((bio->bi_size >> 9) + bio->bi_sector)
return rc;
}
dcssblk_major = rc;
+ init_rwsem(&dcssblk_devices_sem);
PRINT_DEBUG("...finished!\n");
return 0;
}
{
int cc;
- __asm__ __volatile(
+ __asm__ __volatile__ (
" lhi %0,2\n" /* return unused cc 2 if pgin traps */
" .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */
"0: ipm %0\n"
{
int cc;
- __asm__ __volatile(
+ __asm__ __volatile__ (
" lhi %0,2\n" /* return unused cc 2 if pgout traps */
" .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */
"0: ipm %0\n"
unsigned long bytes;
int i;
- if ((bio->bi_sector & 3) != 0 || (bio->bi_size & 4095) != 0)
+ if ((bio->bi_sector & 7) != 0 || (bio->bi_size & 4095) != 0)
/* Request is not page-aligned. */
goto fail;
if ((bio->bi_size >> 12) > xdev->size)
static int xpram_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
- struct hd_geometry *geo;
+ struct hd_geometry __user *geo;
unsigned long size;
- if (cmd != HDIO_GETGEO)
+ if (cmd != HDIO_GETGEO)
return -EINVAL;
/*
* get geometry: we have to fake one... trim the size to a
* multiple of 64 (32k): tell we have 16 sectors, 4 heads,
* whatever cylinders. Tell also that data starts at sector. 4.
*/
- geo = (struct hd_geometry *) arg;
+ geo = (struct hd_geometry __user *) arg;
size = (xpram_pages * 8) & ~0x3f;
put_user(size >> 6, &geo->cylinders);
put_user(4, &geo->heads);
return 0;
}
-static struct request_queue xpram_queue;
+static struct request_queue *xpram_queue;
static int __init xpram_setup_blkdev(void)
{
* Assign the other needed values: make request function, sizes and
* hardsect size. All the minor devices feature the same value.
*/
- blk_queue_make_request(&xpram_queue, xpram_make_request);
- blk_queue_hardsect_size(&xpram_queue, 4096);
+ xpram_queue = blk_alloc_queue(GFP_KERNEL);
+ if (!xpram_queue) {
+ rc = -ENOMEM;
+ goto out_unreg;
+ }
+ blk_queue_make_request(xpram_queue, xpram_make_request);
+ blk_queue_hardsect_size(xpram_queue, 4096);
/*
* Setup device structures.
disk->first_minor = i;
disk->fops = &xpram_devops;
disk->private_data = &xpram_devices[i];
- disk->queue = &xpram_queue;
+ disk->queue = xpram_queue;
sprintf(disk->disk_name, "slram%d", i);
sprintf(disk->devfs_name, "slram/%d", i);
set_capacity(disk, xpram_sizes[i] << 1);
}
return 0;
+out_unreg:
+ devfs_remove("slram");
+ unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
out:
while (i--)
put_disk(xpram_disks[i]);
}
unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
devfs_remove("slram");
+ blk_cleanup_queue(xpram_queue);
sysdev_unregister(&xpram_sys_device);
sysdev_class_unregister(&xpram_sysclass);
}
ret = 0;
while (count > 0) {
length = count < 80 ? count : 80;
- length -= copy_from_user(raw->ubuffer, buf, length);
+ length -= copy_from_user(raw->ubuffer,
+ (const unsigned char __user *)buf, length);
if (length == 0) {
if (!ret)
ret = -EFAULT;
* Ioctl stuff.
*/
static int
-do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry *user_kbe,
+do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe,
int cmd, int perm)
{
struct kbentry tmp;
}
static int
-do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry *u_kbs,
+do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
int cmd, int perm)
{
unsigned char kb_func;
kbd_ioctl(struct kbd_data *kbd, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct kbdiacrs *a;
+ struct kbdiacrs __user *a;
+ void __user *argp;
int ct, perm;
+ argp = (void __user *)arg;
+
/*
* 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.
perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
switch (cmd) {
case KDGKBTYPE:
- return put_user(KB_101, (char*) arg);
+ return put_user(KB_101, (char __user *)argp);
case KDGKBENT:
case KDSKBENT:
- return do_kdsk_ioctl(kbd, (struct kbentry *)arg, cmd, perm);
+ return do_kdsk_ioctl(kbd, argp, cmd, perm);
case KDGKBSENT:
case KDSKBSENT:
- return do_kdgkb_ioctl(kbd, (struct kbsentry *)arg, cmd, perm);
+ return do_kdgkb_ioctl(kbd, argp, cmd, perm);
case KDGKBDIACR:
- a = (struct kbdiacrs *) arg;
+ a = argp;
if (put_user(kbd->accent_table_size, &a->kb_cnt))
return -EFAULT;
return -EFAULT;
return 0;
case KDSKBDIACR:
- a = (struct kbdiacrs *) arg;
+ a = argp;
if (!perm)
return -EPERM;
if (get_user(ct, &a->kb_cnt))
switch (cmd) {
case TIOCSCLPSHTAB:
/* set width of horizontal tab */
- if (get_user(sclp_ioctls.htab, (unsigned short *) arg))
+ if (get_user(sclp_ioctls.htab, (unsigned short __user *) arg))
rc = -EFAULT;
else
check = 1;
break;
case TIOCSCLPGHTAB:
/* get width of horizontal tab */
- if (put_user(sclp_ioctls.htab, (unsigned short *) arg))
+ if (put_user(sclp_ioctls.htab, (unsigned short __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSECHO:
/* enable/disable echo of input */
- if (get_user(sclp_ioctls.echo, (unsigned char *) arg))
+ if (get_user(sclp_ioctls.echo, (unsigned char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPGECHO:
/* Is echo of input enabled ? */
- if (put_user(sclp_ioctls.echo, (unsigned char *) arg))
+ if (put_user(sclp_ioctls.echo, (unsigned char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSCOLS:
/* set number of columns for output */
- if (get_user(sclp_ioctls.columns, (unsigned short *) arg))
+ if (get_user(sclp_ioctls.columns, (unsigned short __user *) arg))
rc = -EFAULT;
else
check = 1;
break;
case TIOCSCLPGCOLS:
/* get number of columns for output */
- if (put_user(sclp_ioctls.columns, (unsigned short *) arg))
+ if (put_user(sclp_ioctls.columns, (unsigned short __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSNL:
/* enable/disable writing without final new line character */
- if (get_user(sclp_ioctls.final_nl, (signed char *) arg))
+ if (get_user(sclp_ioctls.final_nl, (signed char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPGNL:
/* Is writing without final new line character enabled ? */
- if (put_user(sclp_ioctls.final_nl, (signed char *) arg))
+ if (put_user(sclp_ioctls.final_nl, (signed char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSOBUF:
* up to next 4kB boundary and stored as number of SCCBs
* (4kB Buffers) limitation: 256 x 4kB
*/
- if (get_user(obuf, (unsigned int *) arg) == 0) {
+ if (get_user(obuf, (unsigned int __user *) arg) == 0) {
if (obuf & 0xFFF)
sclp_ioctls.max_sccb = (obuf >> 12) + 1;
else
case TIOCSCLPGOBUF:
/* get the maximum buffers size for output */
obuf = sclp_ioctls.max_sccb << 12;
- if (put_user(obuf, (unsigned int *) arg))
+ if (put_user(obuf, (unsigned int __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPGKBUF:
/* get the number of buffers got from kernel at startup */
- if (put_user(sclp_ioctls.kmem_sccb, (unsigned short *) arg))
+ if (put_user(sclp_ioctls.kmem_sccb, (unsigned short __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSCASE:
/* enable/disable conversion from upper to lower case */
- if (get_user(sclp_ioctls.tolower, (unsigned char *) arg))
+ if (get_user(sclp_ioctls.tolower, (unsigned char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPGCASE:
/* Is conversion from upper to lower case of input enabled? */
- if (put_user(sclp_ioctls.tolower, (unsigned char *) arg))
+ if (put_user(sclp_ioctls.tolower, (unsigned char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSDELIM:
* set special character used for separating upper and
* lower case, 0x00 disables this feature
*/
- if (get_user(sclp_ioctls.delim, (unsigned char *) arg))
+ if (get_user(sclp_ioctls.delim, (unsigned char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPGDELIM:
* get special character used for separating upper and
* lower case, 0x00 disables this feature
*/
- if (put_user(sclp_ioctls.delim, (unsigned char *) arg))
+ if (put_user(sclp_ioctls.delim, (unsigned char __user *) arg))
rc = -EFAULT;
break;
case TIOCSCLPSINIT:
while (count > 0) {
length = count < SCLP_TTY_BUF_SIZE ?
count : SCLP_TTY_BUF_SIZE;
- length -= copy_from_user(sclp_tty_chars, buf, length);
+ length -= copy_from_user(sclp_tty_chars,
+ (const unsigned char __user *)buf, length);
if (length == 0) {
if (!ret)
ret = -EFAULT;
while (count > 0) {
length = count < SCLP_VT220_BUF_SIZE ?
count : SCLP_VT220_BUF_SIZE;
- length -= copy_from_user(tty->driver_data, buf, length);
+ length -= copy_from_user(tty->driver_data,
+ (const unsigned char __user *)buf, length);
if (length == 0) {
if (!ret)
return -EFAULT;
#ifdef DBF_LIKE_HELL
#define DBF_LH(level, str, ...) \
do { \
- debug_sprintf_event(tape_dbf_area, level, str, ## __VA_ARGS__); \
+ debug_sprintf_event(TAPE_DBF_AREA, level, str, ## __VA_ARGS__); \
} while (0)
#else
#define DBF_LH(level, str, ...) do {} while(0)
*/
#define DBF_EVENT(d_level, d_str...) \
do { \
- debug_sprintf_event(tape_dbf_area, d_level, d_str); \
+ debug_sprintf_event(TAPE_DBF_AREA, d_level, d_str); \
} while (0)
#define DBF_EXCEPTION(d_level, d_str...) \
do { \
- debug_sprintf_exception(tape_dbf_area, d_level, d_str); \
+ debug_sprintf_exception(TAPE_DBF_AREA, d_level, d_str); \
} while (0)
#define TAPE_VERSION_MAJOR 2
extern void tape_med_state_set(struct tape_device *, enum tape_medium_state);
/* The debug area */
-extern debug_info_t *tape_dbf_area;
+extern debug_info_t *TAPE_DBF_AREA;
/* functions for building ccws */
static inline struct ccw1 *
#include <linux/bio.h>
#include <linux/workqueue.h>
+#define TAPE_DBF_AREA tape_34xx_dbf
+
#include "tape.h"
#include "tape_std.h"
#define PRINTK_HEADER "TAPE_34XX: "
+/*
+ * Pointer to debug area.
+ */
+debug_info_t *TAPE_DBF_AREA = NULL;
+EXPORT_SYMBOL(TAPE_DBF_AREA);
+
enum tape_34xx_type {
tape_3480,
tape_3490,
if (cmd == TAPE390_DISPLAY) {
struct display_struct disp;
- if (copy_from_user(&disp, (char *) arg, sizeof(disp)) != 0)
+ if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)) != 0)
return -EFAULT;
return tape_std_display(device, &disp);
{
int rc;
- DBF_EVENT(3, "34xx init: $Revision: 1.20 $\n");
+ TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long));
+ debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
+#ifdef DBF_LIKE_HELL
+ debug_set_level(TAPE_DBF_AREA, 6);
+#endif
+
+ DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n");
/* Register driver for 3480/3490 tapes. */
rc = ccw_driver_register(&tape_34xx_driver);
if (rc)
tape_34xx_exit(void)
{
ccw_driver_unregister(&tape_34xx_driver);
+
+ debug_unregister(TAPE_DBF_AREA);
}
MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
- "device driver ($Revision: 1.20 $)");
+ "device driver ($Revision: 1.21 $)");
MODULE_LICENSE("GPL");
module_init(tape_34xx_init);
#include <asm/debug.h>
+#define TAPE_DBF_AREA tape_core_dbf
+
#include "tape.h"
#define PRINTK_HEADER "TAPE_BLOCK: "
#include <asm/uaccess.h>
+#define TAPE_DBF_AREA tape_core_dbf
+
#include "tape.h"
#include "tape_std.h"
#include "tape_class.h"
/*
* file operation structure for tape character frontend
*/
-static ssize_t tapechar_read(struct file *, char *, size_t, loff_t *);
-static ssize_t tapechar_write(struct file *, const char *, size_t, loff_t *);
+static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *);
static int tapechar_open(struct inode *,struct file *);
static int tapechar_release(struct inode *,struct file *);
static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
* Tape device read function
*/
ssize_t
-tapechar_read (struct file *filp, char *data, size_t count, loff_t *ppos)
+tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
{
struct tape_device *device;
struct tape_request *request;
* Tape device write function
*/
ssize_t
-tapechar_write(struct file *filp, const char *data, size_t count, loff_t *ppos)
+tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos)
{
struct tape_device *device;
struct tape_request *request;
if (no == MTIOCTOP) {
struct mtop op;
- if (copy_from_user(&op, (char *) data, sizeof(op)) != 0)
+ if (copy_from_user(&op, (char __user *) data, sizeof(op)) != 0)
return -EFAULT;
if (op.mt_count < 0)
return -EINVAL;
if (rc < 0)
return rc;
pos.mt_blkno = rc;
- if (copy_to_user((char *) data, &pos, sizeof(pos)) != 0)
+ if (copy_to_user((char __user *) data, &pos, sizeof(pos)) != 0)
return -EFAULT;
return 0;
}
get.mt_blkno = rc;
}
- if (copy_to_user((char *) data, &get, sizeof(get)) != 0)
+ if (copy_to_user((char __user *) data, &get, sizeof(get)) != 0)
return -EFAULT;
return 0;
#include <asm/types.h> // for variable types
+#define TAPE_DBF_AREA tape_core_dbf
+
#include "tape.h"
#include "tape_std.h"
/*
* Pointer to debug area.
*/
-debug_info_t *tape_dbf_area = NULL;
+debug_info_t *TAPE_DBF_AREA = NULL;
+EXPORT_SYMBOL(TAPE_DBF_AREA);
/*
* Printable strings for tape enumerations.
static int
tape_init (void)
{
- tape_dbf_area = debug_register ( "tape", 1, 2, 4*sizeof(long));
- debug_register_view(tape_dbf_area, &debug_sprintf_view);
+ TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long));
+ debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
#ifdef DBF_LIKE_HELL
- debug_set_level(tape_dbf_area, 6);
+ debug_set_level(TAPE_DBF_AREA, 6);
#endif
- DBF_EVENT(3, "tape init: ($Revision: 1.49 $)\n");
+ DBF_EVENT(3, "tape init: ($Revision: 1.50 $)\n");
tape_proc_init();
tapechar_init ();
tapeblock_init ();
tapechar_exit();
tapeblock_exit();
tape_proc_cleanup();
- debug_unregister (tape_dbf_area);
+ debug_unregister (TAPE_DBF_AREA);
}
MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
"Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
MODULE_DESCRIPTION("Linux on zSeries channel attached "
- "tape device driver ($Revision: 1.49 $)");
+ "tape device driver ($Revision: 1.50 $)");
MODULE_LICENSE("GPL");
module_init(tape_init);
module_exit(tape_exit);
-EXPORT_SYMBOL(tape_dbf_area);
EXPORT_SYMBOL(tape_generic_remove);
EXPORT_SYMBOL(tape_generic_probe);
EXPORT_SYMBOL(tape_generic_online);
#include <linux/vmalloc.h>
#include <linux/seq_file.h>
+#define TAPE_DBF_AREA tape_core_dbf
+
#include "tape.h"
#define PRINTK_HEADER "TAPE_PROC: "
#include <asm/ebcdic.h>
#include <asm/tape390.h>
+#define TAPE_DBF_AREA tape_core_dbf
+
#include "tape.h"
#include "tape_std.h"
* drivers/s390/cio/airq.c
* S/390 common I/O routines -- support for adapter interruptions
*
- * $Revision: 1.11 $
+ * $Revision: 1.12 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/rcupdate.h>
#include "cio_debug.h"
#include "airq.h"
-static spinlock_t adapter_lock = SPIN_LOCK_UNLOCKED;
static adapter_int_handler_t adapter_handler;
/*
CIO_TRACE_EVENT (4, "rgaint");
- spin_lock (&adapter_lock);
-
if (handler == NULL)
ret = -EINVAL;
- else if (adapter_handler)
- ret = -EBUSY;
- else {
- adapter_handler = handler;
- ret = 0;
- }
-
- spin_unlock (&adapter_lock);
+ else
+ ret = (cmpxchg(&adapter_handler, NULL, handler) ? -EBUSY : 0);
+ if (!ret)
+ synchronize_kernel();
sprintf (dbf_txt, "ret:%d", ret);
CIO_TRACE_EVENT (4, dbf_txt);
- return (ret);
+ return ret;
}
int
CIO_TRACE_EVENT (4, "urgaint");
- spin_lock (&adapter_lock);
-
if (handler == NULL)
ret = -EINVAL;
- else if (handler != adapter_handler)
- ret = -EINVAL;
else {
adapter_handler = NULL;
+ synchronize_kernel();
ret = 0;
}
-
- spin_unlock (&adapter_lock);
-
sprintf (dbf_txt, "ret:%d", ret);
CIO_TRACE_EVENT (4, dbf_txt);
- return (ret);
+ return ret;
}
void
do_adapter_IO (void)
{
- CIO_TRACE_EVENT (4, "doaio");
-
- spin_lock (&adapter_lock);
+ CIO_TRACE_EVENT (6, "doaio");
if (adapter_handler)
(*adapter_handler) ();
-
- spin_unlock (&adapter_lock);
-
- return;
}
EXPORT_SYMBOL (s390_register_adapter_interrupt);
return len;
}
-static int cio_ignore_write (struct file *file, const char *user_buf,
+static int cio_ignore_write(struct file *file, const char __user *user_buf,
unsigned long user_len, void *data)
{
char *buf;
/*
* drivers/s390/cio/ccwgroup.c
* bus driver for ccwgroup
- * $Revision: 1.27 $
+ * $Revision: 1.28 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
|| gdev->cdev[i]->id.driver_info !=
gdev->cdev[0]->id.driver_info) {
rc = -EINVAL;
- goto error;
+ goto free_dev;
}
/* Don't allow a device to belong to more than one group. */
if (gdev->cdev[i]->dev.driver_data) {
rc = -EINVAL;
- goto error;
+ goto free_dev;
}
}
for (i = 0; i < argc; i++)
rc = device_register(&gdev->dev);
if (rc)
- goto error;
-
+ goto free_dev;
+ get_device(&gdev->dev);
rc = device_create_file(&gdev->dev, &dev_attr_ungroup);
if (rc) {
}
rc = __ccwgroup_create_symlinks(gdev);
- if (!rc)
+ if (!rc) {
+ put_device(&gdev->dev);
return 0;
-
+ }
device_remove_file(&gdev->dev, &dev_attr_ungroup);
device_unregister(&gdev->dev);
error:
+ for (i = 0; i < argc; i++)
+ if (gdev->cdev[i]) {
+ put_device(&gdev->cdev[i]->dev);
+ gdev->cdev[i]->dev.driver_data = NULL;
+ }
+ put_device(&gdev->dev);
+ return rc;
+free_dev:
for (i = 0; i < argc; i++)
if (gdev->cdev[i]) {
put_device(&gdev->cdev[i]->dev);
gdev->cdev[i]->dev.driver_data = NULL;
}
kfree(gdev);
-
return rc;
}
/*
* drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call
- * $Revision: 1.110 $
+ * $Revision: 1.112 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
#include "ioasm.h"
#include "chsc.h"
-#define CHPID_LONGS (256 / (8 * sizeof(long))) /* 256 chpids */
static struct channel_path *chps[NR_CHPIDS];
static void *sei_page;
int state;
state = get_chp_status(chp);
- if (state < 0)
- new_channel_path(chp);
- else
+ if (state < 0) {
+ need_rescan = 1;
+ queue_work(slow_path_wq, &slow_path_work);
+ } else
WARN_ON(!state);
- /* FIXME: should notify other subchannels here */
}
/* FIXME: this is _always_ called for every subchannel. shouldn't we
out_unreg:
spin_unlock(&sch->lock);
sch->lpm = 0;
- /* We can't block here. */
- device_call_nopath_notify(sch);
+ if (css_enqueue_subchannel_slow(sch->irq)) {
+ css_clear_subchannel_slow_list();
+ need_rescan = 1;
+ }
return 0;
}
bus_for_each_dev(&css_bus_type, NULL, &chpid,
s390_subchannel_remove_chpid);
+
+ if (need_rescan || css_slow_subchannels_exist())
+ queue_work(slow_path_wq, &slow_path_work);
}
static int
* can successfully terminate, even using the
* just varied off path. Then kill it.
*/
- if (!__check_for_io_and_kill(sch, chp) && !sch->lpm)
- /* Get over with it now. */
- device_call_nopath_notify(sch);
- else if (sch->driver && sch->driver->verify)
+ if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) {
+ if (css_enqueue_subchannel_slow(sch->irq)) {
+ css_clear_subchannel_slow_list();
+ need_rescan = 1;
+ }
+ } else if (sch->driver && sch->driver->verify)
sch->driver->verify(&sch->dev);
}
break;
return 0;
}
-extern void css_trigger_slow_path(void);
-typedef void (*workfunc)(void *);
-static DECLARE_WORK(varyonoff_work, (workfunc)css_trigger_slow_path,
- NULL);
-
/*
* Function: s390_vary_chpid
* Varies the specified chpid online or offline
s390_subchannel_vary_chpid_on :
s390_subchannel_vary_chpid_off);
if (!on)
- return 0;
+ goto out;
/* Scan for new devices on varied on path. */
for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
struct schib schib;
need_rescan = 1;
}
}
+out:
if (need_rescan || css_slow_subchannels_exist())
- schedule_work(&varyonoff_work);
+ queue_work(slow_path_wq, &slow_path_work);
return 0;
}
extern void s390_process_css( void );
extern void chsc_validate_chpids(struct subchannel *);
extern void chpid_is_actually_online(int);
-extern int is_chpid_online(int);
#endif
/*
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
- * $Revision: 1.121 $
+ * $Revision: 1.123 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
if (!cio_debug_msg_id)
goto out_unregister;
debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
- debug_set_level (cio_debug_msg_id, 6);
+ debug_set_level (cio_debug_msg_id, 2);
cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
if (!cio_debug_trace_id)
goto out_unregister;
debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
- debug_set_level (cio_debug_trace_id, 6);
+ debug_set_level (cio_debug_trace_id, 2);
cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long));
if (!cio_debug_crw_id)
goto out_unregister;
debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
- debug_set_level (cio_debug_crw_id, 6);
+ debug_set_level (cio_debug_crw_id, 2);
pr_debug("debugging initialized\n");
return 0;
/*
* drivers/s390/cio/css.c
* driver for channel subsystem
- * $Revision: 1.74 $
+ * $Revision: 1.77 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
if (sch && sch->schib.pmcw.dnv &&
(schib.pmcw.dev != sch->schib.pmcw.dev))
return CIO_REVALIDATE;
+ if (sch && !sch->lpm)
+ return CIO_NO_PATH;
return CIO_OPER;
}
-static inline int
+static int
css_evaluate_subchannel(int irq, int slow)
{
int event, ret, disc;
return -EAGAIN; /* Will be done on the slow path. */
}
event = css_get_subchannel_status(sch, irq);
+ CIO_MSG_EVENT(4, "Evaluating schid %04x, event %d, %s, %s path.\n",
+ irq, event, sch?(disc?"disconnected":"normal"):"unknown",
+ slow?"slow":"fast");
switch (event) {
+ case CIO_NO_PATH:
case CIO_GONE:
if (!sch) {
/* Never used this subchannel. Ignore. */
break;
}
if (sch->driver && sch->driver->notify &&
- sch->driver->notify(&sch->dev, CIO_GONE)) {
+ sch->driver->notify(&sch->dev, event)) {
+ cio_disable_subchannel(sch);
device_set_disconnected(sch);
ret = 0;
break;
* Unregister subchannel.
* The device will be killed automatically.
*/
+ cio_disable_subchannel(sch);
device_unregister(&sch->dev);
/* Reset intparm to zeroes. */
sch->schib.pmcw.intparm = 0;
}
}
-static void
-css_evaluate_slow_subchannel(unsigned long schid)
-{
- css_evaluate_subchannel(schid, 1);
-}
+struct slow_subchannel {
+ struct list_head slow_list;
+ unsigned long schid;
+};
-void
+static LIST_HEAD(slow_subchannels_head);
+static spinlock_t slow_subchannel_lock = SPIN_LOCK_UNLOCKED;
+
+static void
css_trigger_slow_path(void)
{
+ CIO_TRACE_EVENT(4, "slowpath");
+
if (need_rescan) {
need_rescan = 0;
css_rescan_devices();
return;
}
- css_walk_subchannel_slow_list(css_evaluate_slow_subchannel);
+
+ spin_lock_irq(&slow_subchannel_lock);
+ while (!list_empty(&slow_subchannels_head)) {
+ struct slow_subchannel *slow_sch =
+ list_entry(slow_subchannels_head.next,
+ struct slow_subchannel, slow_list);
+
+ list_del_init(slow_subchannels_head.next);
+ spin_unlock_irq(&slow_subchannel_lock);
+ css_evaluate_subchannel(slow_sch->schid, 1);
+ spin_lock_irq(&slow_subchannel_lock);
+ kfree(slow_sch);
+ }
+ spin_unlock_irq(&slow_subchannel_lock);
}
+typedef void (*workfunc)(void *);
+DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL);
+struct workqueue_struct *slow_path_wq;
+
/*
* Rescan for new devices. FIXME: This is slow.
* This function is called when we have lost CRWs due to overflows and we have
device_unregister(dev);
}
-struct slow_subchannel {
- struct list_head slow_list;
- unsigned long schid;
-};
-
-static LIST_HEAD(slow_subchannels_head);
-static spinlock_t slow_subchannel_lock = SPIN_LOCK_UNLOCKED;
-
int
css_enqueue_subchannel_slow(unsigned long schid)
{
spin_unlock_irqrestore(&slow_subchannel_lock, flags);
}
-void
-css_walk_subchannel_slow_list(void (*fn)(unsigned long))
-{
- unsigned long flags;
- spin_lock_irqsave(&slow_subchannel_lock, flags);
- while (!list_empty(&slow_subchannels_head)) {
- struct slow_subchannel *slow_sch =
- list_entry(slow_subchannels_head.next,
- struct slow_subchannel, slow_list);
-
- list_del_init(slow_subchannels_head.next);
- spin_unlock_irqrestore(&slow_subchannel_lock, flags);
- fn(slow_sch->schid);
- spin_lock_irqsave(&slow_subchannel_lock, flags);
- kfree(slow_sch);
- }
- spin_unlock_irqrestore(&slow_subchannel_lock, flags);
-}
int
css_slow_subchannels_exist(void)
/* Helper functions for vary on/off. */
void device_set_waiting(struct subchannel *);
-void device_call_nopath_notify(struct subchannel *);
/* Helper functions to build lists for the slow path. */
int css_enqueue_subchannel_slow(unsigned long schid);
void css_clear_subchannel_slow_list(void);
int css_slow_subchannels_exist(void);
extern int need_rescan;
+
+extern struct workqueue_struct *slow_path_wq;
+extern struct work_struct slow_path_work;
#endif
/*
* drivers/s390/cio/device.c
* bus driver for ccw devices
- * $Revision: 1.117 $
+ * $Revision: 1.120 $
*
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
ret = -ENOMEM; /* FIXME: better errno ? */
goto out_err;
}
+ slow_path_wq = create_singlethread_workqueue("kslowcrw");
+ if (!slow_path_wq) {
+ ret = -ENOMEM; /* FIXME: better errno ? */
+ goto out_err;
+ }
if ((ret = bus_register (&ccw_bus_type)))
goto out_err;
destroy_workqueue(ccw_device_work);
if (ccw_device_notify_work)
destroy_workqueue(ccw_device_notify_work);
+ if (slow_path_wq)
+ destroy_workqueue(slow_path_wq);
return ret;
}
cdev = to_ccwdev(dev);
if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
(cdev->private->devno == devno) &&
- (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id, 4))) {
+ (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id,
+ BUS_ID_SIZE))) {
cdev->private->state = DEV_STATE_NOT_OPER;
break;
}
struct subchannel *sch;
sch = to_subchannel(cdev->dev.parent);
- /* Check if device is registered. */
- if (!list_empty(&sch->dev.node))
- device_unregister(&sch->dev);
+ device_unregister(&sch->dev);
/* Reset intparm to zeroes. */
sch->schib.pmcw.intparm = 0;
cio_modify(sch);
sch = to_subchannel(cdev->dev.parent);
INIT_WORK(&cdev->private->kick_work,
ccw_device_call_sch_unregister, (void *) cdev);
- queue_work(ccw_device_work, &cdev->private->kick_work);
+ queue_work(slow_path_wq, &cdev->private->kick_work);
break;
case DEV_STATE_BOXED:
/* Device did not respond in time. */
}
}
-void
-device_call_nopath_notify(struct subchannel *sch)
-{
- struct ccw_device *cdev;
-
- if (!sch->dev.driver_data)
- return;
- cdev = sch->dev.driver_data;
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, (void *)cdev);
- queue_work(ccw_device_notify_work, &cdev->private->kick_work);
-}
-
-
void
ccw_device_verify_done(struct ccw_device *cdev, int err)
{
* device statemachine
*/
fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
- [DEV_STATE_NOT_OPER] {
- [DEV_EVENT_NOTOPER] ccw_device_nop,
- [DEV_EVENT_INTERRUPT] ccw_device_bug,
- [DEV_EVENT_TIMEOUT] ccw_device_nop,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_NOT_OPER] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_nop,
+ [DEV_EVENT_INTERRUPT] = ccw_device_bug,
+ [DEV_EVENT_TIMEOUT] = ccw_device_nop,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_SENSE_PGID] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_sense_pgid_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_SENSE_PGID] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_sense_pgid_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_SENSE_ID] {
- [DEV_EVENT_NOTOPER] ccw_device_recog_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_sense_id_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_recog_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_SENSE_ID] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_sense_id_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_recog_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_OFFLINE] {
- [DEV_EVENT_NOTOPER] ccw_device_offline_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_offline_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_nop,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_OFFLINE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_offline_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_nop,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_VERIFY] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_verify_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_VERIFY] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_ONLINE] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_online_timeout,
- [DEV_EVENT_VERIFY] ccw_device_online_verify,
+ [DEV_STATE_ONLINE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_online_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_online_verify,
},
- [DEV_STATE_W4SENSE] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_w4sense,
- [DEV_EVENT_TIMEOUT] ccw_device_nop,
- [DEV_EVENT_VERIFY] ccw_device_online_verify,
+ [DEV_STATE_W4SENSE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_w4sense,
+ [DEV_EVENT_TIMEOUT] = ccw_device_nop,
+ [DEV_EVENT_VERIFY] = ccw_device_online_verify,
},
- [DEV_STATE_DISBAND_PGID] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_disband_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_DISBAND_PGID] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_disband_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_BOXED] {
- [DEV_EVENT_NOTOPER] ccw_device_offline_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_stlck_done,
- [DEV_EVENT_TIMEOUT] ccw_device_stlck_done,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_BOXED] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_offline_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_stlck_done,
+ [DEV_EVENT_TIMEOUT] = ccw_device_stlck_done,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
/* states to wait for i/o completion before doing something */
- [DEV_STATE_CLEAR_VERIFY] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_clear_verify,
- [DEV_EVENT_TIMEOUT] ccw_device_nop,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_CLEAR_VERIFY] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_clear_verify,
+ [DEV_EVENT_TIMEOUT] = ccw_device_nop,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_TIMEOUT_KILL] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_killing_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_killing_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop, //FIXME
+ [DEV_STATE_TIMEOUT_KILL] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_killing_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME
},
- [DEV_STATE_WAIT4IO] {
- [DEV_EVENT_NOTOPER] ccw_device_online_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_wait4io_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_wait4io_timeout,
- [DEV_EVENT_VERIFY] ccw_device_wait4io_verify,
+ [DEV_STATE_WAIT4IO] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_wait4io_verify,
},
- [DEV_STATE_QUIESCE] {
- [DEV_EVENT_NOTOPER] ccw_device_quiesce_done,
- [DEV_EVENT_INTERRUPT] ccw_device_quiesce_done,
- [DEV_EVENT_TIMEOUT] ccw_device_quiesce_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_QUIESCE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done,
+ [DEV_EVENT_INTERRUPT] = ccw_device_quiesce_done,
+ [DEV_EVENT_TIMEOUT] = ccw_device_quiesce_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
/* special states for devices gone not operational */
- [DEV_STATE_DISCONNECTED] {
- [DEV_EVENT_NOTOPER] ccw_device_nop,
- [DEV_EVENT_INTERRUPT] ccw_device_start_id,
- [DEV_EVENT_TIMEOUT] ccw_device_bug,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_DISCONNECTED] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_nop,
+ [DEV_EVENT_INTERRUPT] = ccw_device_start_id,
+ [DEV_EVENT_TIMEOUT] = ccw_device_bug,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_DISCONNECTED_SENSE_ID] {
- [DEV_EVENT_NOTOPER] ccw_device_recog_notoper,
- [DEV_EVENT_INTERRUPT] ccw_device_sense_id_irq,
- [DEV_EVENT_TIMEOUT] ccw_device_recog_timeout,
- [DEV_EVENT_VERIFY] ccw_device_nop,
+ [DEV_STATE_DISCONNECTED_SENSE_ID] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper,
+ [DEV_EVENT_INTERRUPT] = ccw_device_sense_id_irq,
+ [DEV_EVENT_TIMEOUT] = ccw_device_recog_timeout,
+ [DEV_EVENT_VERIFY] = ccw_device_nop,
},
- [DEV_STATE_CMFCHANGE] {
- [DEV_EVENT_NOTOPER] ccw_device_change_cmfstate,
- [DEV_EVENT_INTERRUPT] ccw_device_change_cmfstate,
- [DEV_EVENT_TIMEOUT] ccw_device_change_cmfstate,
- [DEV_EVENT_VERIFY] ccw_device_change_cmfstate,
+ [DEV_STATE_CMFCHANGE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_change_cmfstate,
+ [DEV_EVENT_INTERRUPT] = ccw_device_change_cmfstate,
+ [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate,
+ [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate,
},
};
/*
* drivers/s390/cio/requestirq.c
* S/390 common I/O routines -- enabling and disabling of devices
- * $Revision: 1.45 $
+ * $Revision: 1.46 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
#include "css.h"
-/* for compatiblity only... */
-int
-request_irq (unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
- unsigned long irqflags, const char *devname, void *dev_id)
-{
- return -EINVAL;
-}
-
-/* for compatiblity only... */
-void
-free_irq (unsigned int irq, void *dev_id)
-{
-}
-
struct pgid global_pgid;
EXPORT_SYMBOL_GPL(global_pgid);
* - length(n_modulus) = inputdatalength
*/
struct ica_rsa_modexpo {
- char * inputdata;
+ char __user * inputdata;
unsigned int inputdatalength;
- char * outputdata;
+ char __user * outputdata;
unsigned int outputdatalength;
- char * b_key;
- char * n_modulus;
+ char __user * b_key;
+ char __user * n_modulus;
};
/**
* - length(u_mult_inv) = inputdatalength/2 + 8
*/
struct ica_rsa_modexpo_crt {
- char * inputdata;
+ char __user * inputdata;
unsigned int inputdatalength;
- char * outputdata;
+ char __user * outputdata;
unsigned int outputdatalength;
- char * bp_key;
- char * bq_key;
- char * np_prime;
- char * nq_prime;
- char * u_mult_inv;
+ char __user * bp_key;
+ char __user * bq_key;
+ char __user * np_prime;
+ char __user * nq_prime;
+ char __user * u_mult_inv;
};
#define Z90_IOCTL_MAGIC 'z' // NOTE: Need to allocate from linux folks
int buff_size; // size of the buffer for the request
char resp_buff[RESPBUFFSIZE];
int resp_buff_size;
- char * resp_addr; // address of response in user space
+ char __user * resp_addr; // address of response in user space
unsigned int funccode; // function code of request
wait_queue_head_t waitq;
unsigned long requestsent; // time at which the request was sent
*/
static int z90crypt_open(struct inode *, struct file *);
static int z90crypt_release(struct inode *, struct file *);
-static ssize_t z90crypt_read(struct file *, char *, size_t, loff_t *);
-static ssize_t z90crypt_write(struct file *, const char *, size_t, loff_t *);
+static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t z90crypt_write(struct file *, const char __user *,
+ size_t, loff_t *);
static int z90crypt_ioctl(struct inode *, struct file *,
unsigned int, unsigned long);
static void z90crypt_cleanup_task(unsigned long);
static int z90crypt_status(char *, char **, off_t, int, int *, void *);
-static int z90crypt_status_write(struct file *, const char *,
+static int z90crypt_status_write(struct file *, const char __user *,
unsigned long, void *);
/**
trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg,
struct file *file)
{
- struct ica_rsa_modexpo_32 *mex32u = compat_ptr(arg);
+ struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg);
struct ica_rsa_modexpo_32 mex32k;
- struct ica_rsa_modexpo *mex64;
+ struct ica_rsa_modexpo __user *mex64;
int ret = 0;
unsigned int i;
trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg,
struct file *file)
{
- struct ica_rsa_modexpo_crt_32 *crt32u = compat_ptr(arg);
+ struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg);
struct ica_rsa_modexpo_crt_32 crt32k;
- struct ica_rsa_modexpo_crt *crt64;
+ struct ica_rsa_modexpo_crt __user *crt64;
int ret = 0;
unsigned int i;
* z90crypt_read will not be supported beyond z90crypt 1.3.1
*/
static ssize_t
-z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
PDEBUG("filp %p (PID %d)\n", filp, PID());
return -EPERM;
*/
#include <linux/random.h>
static ssize_t
-z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
unsigned char *temp_buff;
* Write is is not allowed
*/
static ssize_t
-z90crypt_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+z90crypt_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
PDEBUG("filp %p (PID %d)\n", filp, PID());
return -EPERM;
* process_results copies the user's work from kernel space.
*/
static inline int
-z90crypt_process_results(struct work_element *we_p, char *buf)
+z90crypt_process_results(struct work_element *we_p, char __user *buf)
{
int rv;
static inline int
z90crypt_prepare(struct work_element *we_p, unsigned int funccode,
- const char *buffer)
+ const char __user *buffer)
{
int rv;
PDEBUG("PID %d: allocate_work_element returned ENOMEM\n", pid);
return rv;
}
- if ((rv = z90crypt_prepare(we_p, cmd, (const char *)arg)))
+ if ((rv = z90crypt_prepare(we_p, cmd, (const char __user *)arg)))
PDEBUG("PID %d: rv = %d from z90crypt_prepare\n", pid, rv);
if (!rv)
if ((rv = z90crypt_send(we_p, (const char *)arg)))
rv = we_p->retcode;
}
if (!rv)
- rv = z90crypt_process_results(we_p, (char *)arg);
+ rv = z90crypt_process_results(we_p, (char __user *)arg);
if ((we_p->status[0] & STAT_FAILED)) {
switch (rv) {
case Z90STAT_TOTALCOUNT:
tempstat = get_status_totalcount();
- if (copy_to_user((int *)arg, &tempstat,sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat,sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_PCICACOUNT:
tempstat = get_status_PCICAcount();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_PCICCCOUNT:
tempstat = get_status_PCICCcount();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_PCIXCCCOUNT:
tempstat = get_status_PCIXCCcount();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_REQUESTQ_COUNT:
tempstat = get_status_requestq_count();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_PENDINGQ_COUNT:
tempstat = get_status_pendingq_count();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_TOTALOPEN_COUNT:
tempstat = get_status_totalopen_count();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
case Z90STAT_DOMAIN_INDEX:
tempstat = get_status_domain_index();
- if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0)
+ if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
ret = -EFAULT;
break;
break;
}
get_status_status_mask(status);
- if (copy_to_user((char *) arg, status, Z90CRYPT_NUM_APS) != 0)
+ if (copy_to_user((char __user *) arg, status, Z90CRYPT_NUM_APS)
+ != 0)
ret = -EFAULT;
kfree(status);
break;
break;
}
get_status_qdepth_mask(qdepth);
- if (copy_to_user((char *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)
+ if (copy_to_user((char __user *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)
ret = -EFAULT;
kfree(qdepth);
break;
break;
}
get_status_perdevice_reqcnt(reqcnt);
- if (copy_to_user((char *) arg, reqcnt,
+ if (copy_to_user((char __user *) arg, reqcnt,
Z90CRYPT_NUM_APS * sizeof(int)) != 0)
ret = -EFAULT;
kfree(reqcnt);
get_status_status_mask(pstat->status);
get_status_qdepth_mask(pstat->qdepth);
- if (copy_to_user((struct ica_z90_status *) arg, pstat,
+ if (copy_to_user((struct ica_z90_status __user *) arg, pstat,
sizeof(struct ica_z90_status)) != 0)
ret = -EFAULT;
kfree(pstat);
}
static int
-z90crypt_status_write(struct file *file, const char *buffer,
+z90crypt_status_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
int i, j, len, offs, found, eof;
*/
static inline int
receive_from_crypto_device(int index, unsigned char *psmid, int *buff_len_p,
- unsigned char *buff, unsigned char **dest_p_p)
+ unsigned char *buff, unsigned char __user **dest_p_p)
{
int dv, rv;
struct device *dev_ptr;
static inline void
helper_handle_work_element(int index, unsigned char psmid[8], int rc,
int buff_len, unsigned char *buff,
- unsigned char *resp_addr)
+ unsigned char __user *resp_addr)
{
struct work_element *pq_p;
struct list_head *lptr, *tptr;
z90crypt_reader_task(unsigned long ptr)
{
int workavail, remaining, index, rc, buff_len;
- unsigned char psmid[8], *resp_addr;
+ unsigned char psmid[8];
+ unsigned char __user *resp_addr;
static unsigned char buff[1024];
PDEBUG("jiffies %ld\n", jiffies);
}
skb_reserve(skb, skb_res);
if (from_user)
- copy_from_user(skb_put(skb, c), buf, c);
+ copy_from_user(skb_put(skb, c),
+ (const u_char __user *)buf, c);
else
memcpy(skb_put(skb, c), buf, c);
skb_queue_tail(&info->tx_queue, skb);
* allows RS485 driver to be written in user space.
*/
static int
-ctc_tty_get_lsr_info(ctc_tty_info * info, uint * value)
+ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
{
u_char status;
uint result;
status = info->lsr;
spin_unlock_irqrestore(&ctc_tty_lock, flags);
result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
- put_user(result, (uint *) value);
+ put_user(result, value);
return 0;
}
printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
info->line);
#endif
- error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong *) arg);
+ error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
return error;
case TIOCSSOFTCAR:
#ifdef CTC_DEBUG_MODEM_IOCTL
printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
info->line);
#endif
- error = get_user(arg, (ulong *) arg);
+ error = get_user(arg, (ulong __user *) arg);
if (error)
return error;
tty->termios->c_cflag =
printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
info->line);
#endif
- error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(uint));
+ error = verify_area(VERIFY_WRITE, (void __user *) arg, sizeof(uint));
if (error)
return error;
else
- return ctc_tty_get_lsr_info(info, (uint *) arg);
+ return ctc_tty_get_lsr_info(info, (uint __user *) arg);
default:
#ifdef CTC_DEBUG_MODEM_IOCTL
printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
/*
- * $Id: iucv.c,v 1.32 2004/05/18 09:28:43 braunu Exp $
+ * $Id: iucv.c,v 1.33 2004/05/24 10:19:18 braunu Exp $
*
* IUCV network driver
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.32 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.33 $
*
*/
\f
static void
iucv_banner(void)
{
- char vbuf[] = "$Revision: 1.32 $";
+ char vbuf[] = "$Revision: 1.33 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
iucv_debug(2,
"found a matching handler");
break;
- }
+ } else
+ h = NULL;
}
spin_unlock_irqrestore (&iucv_lock, flags);
if (h) {
/*
- * $Id: netiucv.c,v 1.53 2004/05/07 14:29:37 mschwide Exp $
+ * $Id: netiucv.c,v 1.54 2004/05/28 08:04:14 braunu Exp $
*
* IUCV network driver
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV network driver $Revision: 1.53 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.54 $
*
*/
\f
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
-#include <asm/ebcdic.h>
#include "iucv.h"
#include "fsm.h"
}
static __u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-//static __u8 iucvMagic[16] = {
-// 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-// 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
-//};
+static __u8 iucvMagic[16] = {
+ 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
+};
/**
* This mask means the 16-byte IUCV "magic" and the origin userid must
struct iucv_event *ev = (struct iucv_event *)arg;
struct iucv_connection *conn = ev->conn;
__u16 msglimit;
- int rc, len;
- __u8 iucvMagic[16] = {
- 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
- };
+ int rc;
pr_debug("%s() called\n", __FUNCTION__);
- len = (IFNAMSIZ < sizeof(conn->netdev->name)) ?
- IFNAMSIZ : sizeof(conn->netdev->name);
- memcpy(iucvMagic, conn->netdev->name, len);
- ASCEBC (iucvMagic, len);
if (conn->handle == 0) {
conn->handle =
iucv_register_program(iucvMagic, conn->userid, mask,
static void
netiucv_banner(void)
{
- char vbuf[] = "$Revision: 1.53 $";
+ char vbuf[] = "$Revision: 1.54 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
#include "qeth_mpc.h"
-#define VERSION_QETH_H "$Revision: 1.108 $"
+#define VERSION_QETH_H "$Revision: 1.110 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
debug_event(qeth_dbf_##name,level,(void*)(addr),len); \
} while (0)
-#define QETH_DBF_TEXT_(name,level,text...) \
- do { \
- sprintf(qeth_dbf_text_buf, text); \
- debug_text_event(qeth_dbf_##name,level,qeth_dbf_text_buf);\
+extern DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);
+
+#define QETH_DBF_TEXT_(name,level,text...) \
+ do { \
+ char* dbf_txt_buf = get_cpu_var(qeth_dbf_txt_buf); \
+ sprintf(dbf_txt_buf, text); \
+ debug_text_event(qeth_dbf_##name,level,dbf_txt_buf); \
+ put_cpu_var(qeth_dbf_txt_buf); \
} while (0)
#define QETH_DBF_SPRINTF(name,level,text...) \
* outbound: filled by driver; owned by hardware in order to be sent
*/
QETH_QDIO_BUF_PRIMED,
- /*
- * inbound only: an error condition has been detected for a buffer
- * the buffer will be discarded (not read out)
- */
- QETH_QDIO_BUF_ERROR,
};
enum qeth_qdio_info_states {
struct qeth_qdio_out_buffer {
struct qdio_buffer *buffer;
- volatile enum qeth_qdio_buffer_states state;
+ atomic_t state;
volatile int next_element_to_fill;
struct sk_buff_head skb_list;
};
/*
*
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.112 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.121 $)
*
* Linux on zSeries OSA Express and HiperSockets support
*
* Frank Pavlic (pavlic@de.ibm.com) and
* Thomas Spatzier <tspat@de.ibm.com>
*
- * $Revision: 1.112 $ $Date: 2004/05/19 09:28:21 $
+ * $Revision: 1.121 $ $Date: 2004/06/11 16:32:15 $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "qeth_mpc.h"
#include "qeth_fs.h"
-#define VERSION_QETH_C "$Revision: 1.112 $"
+#define VERSION_QETH_C "$Revision: 1.121 $"
static const char *version = "qeth S/390 OSA-Express driver";
/**
static debug_info_t *qeth_dbf_trace = NULL;
static debug_info_t *qeth_dbf_sense = NULL;
static debug_info_t *qeth_dbf_qerr = NULL;
-static char qeth_dbf_text_buf[255];
+
+DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);
/**
* some more definitions and declarations
}
static inline void
-qeth_clear_output_buffer(struct qeth_card *card,
+qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
struct qeth_qdio_out_buffer *buf)
{
int i;
struct sk_buff *skb;
- for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
+ /* is PCI flag set on buffer? */
+ if (buf->buffer->element[0].flags & 0x40)
+ atomic_dec(&queue->set_pci_flags_count);
+
+ for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i){
buf->buffer->element[i].length = 0;
buf->buffer->element[i].addr = NULL;
buf->buffer->element[i].flags = 0;
}
}
buf->next_element_to_fill = 0;
- buf->state = QETH_QDIO_BUF_EMPTY;
+ atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
}
static inline void
QETH_DBF_TEXT(trace, 2, "flushbuf");
QETH_DBF_TEXT_(trace, 2, " err%d", rc);
queue->card->stats.tx_errors += count;
+ /* ok, since do_QDIO went wrong the buffers have not been given
+ * to the hardware. they still belong to us, so we can clear
+ * them and reuse then, i.e. set back next_buf_to_fill*/
+ for (i = index; i < index + count; ++i) {
+ buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
+ qeth_clear_output_buffer(queue, buf);
+ }
+ queue->next_buf_to_fill = index;
return;
}
+ atomic_add(count, &queue->used_buffers);
#ifdef CONFIG_QETH_PERF_STATS
queue->card->perf_stats.bufs_sent += count;
#endif
queue->do_pack = 0;
/* flush packing buffers */
buffer = &queue->bufs[queue->next_buf_to_fill];
- BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
- if (buffer->next_element_to_fill > 0) {
- buffer->state = QETH_QDIO_BUF_PRIMED;
+ if ((atomic_read(&buffer->state) ==
+ QETH_QDIO_BUF_EMPTY) &&
+ (buffer->next_element_to_fill > 0)) {
+ atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED);
flush_count++;
- atomic_inc(&queue->used_buffers);
queue->next_buf_to_fill =
(queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue, int under_int)
{
struct qeth_qdio_out_buffer *buffer;
+ int index;
- buffer = &queue->bufs[queue->next_buf_to_fill];
- BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
- if (buffer->next_element_to_fill > 0){
+ index = queue->next_buf_to_fill;
+ buffer = &queue->bufs[index];
+ if((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
+ (buffer->next_element_to_fill > 0)){
/* it's a packing buffer */
- buffer->state = QETH_QDIO_BUF_PRIMED;
- atomic_inc(&queue->used_buffers);
- qeth_flush_buffers(queue, under_int, queue->next_buf_to_fill,
- 1);
+ atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
queue->next_buf_to_fill =
(queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
+ qeth_flush_buffers(queue, under_int, index, 1);
}
}
qeth_schedule_recovery(card);
return;
}
- /* is PCI flag set on buffer? */
- if (buffer->buffer->element[0].flags & 0x40)
- atomic_dec(&queue->set_pci_flags_count);
-
- qeth_clear_output_buffer(card, buffer);
- atomic_dec(&queue->used_buffers);
+ qeth_clear_output_buffer(queue, buffer);
}
+ atomic_sub(count, &queue->used_buffers);
netif_wake_queue(card->dev);
#ifdef CONFIG_QETH_PERF_STATS
/* free outbound qdio_qs */
for (i = 0; i < card->qdio.no_out_queues; ++i){
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
- qeth_clear_output_buffer(card, &card->qdio.
- out_qs[i]->bufs[j]);
+ qeth_clear_output_buffer(card->qdio.out_qs[i],
+ &card->qdio.out_qs[i]->bufs[j]);
kfree(card->qdio.out_qs[i]);
}
kfree(card->qdio.out_qs);
for (i = 0; i < card->qdio.no_out_queues; ++i)
if (card->qdio.out_qs[i]){
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
- qeth_clear_output_buffer(card, &card->qdio.
- out_qs[i]->bufs[j]);
+ qeth_clear_output_buffer(card->qdio.out_qs[i],
+ &card->qdio.out_qs[i]->bufs[j]);
}
}
memset(card->qdio.out_qs[i]->qdio_bufs, 0,
QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){
- qeth_clear_output_buffer(card, &card->qdio.
- out_qs[i]->bufs[j]);
+ qeth_clear_output_buffer(card->qdio.out_qs[i],
+ &card->qdio.out_qs[i]->bufs[j]);
}
card->qdio.out_qs[i]->card = card;
card->qdio.out_qs[i]->next_buf_to_fill = 0;
if (!queue->do_pack) {
QETH_DBF_TEXT(trace, 6, "fillbfnp");
/* set state to PRIMED -> will be flushed */
- buf->state = QETH_QDIO_BUF_PRIMED;
+ atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
} else {
QETH_DBF_TEXT(trace, 6, "fillbfpa");
#ifdef CONFIG_QETH_PERF_STATS
* packed buffer if full -> set state PRIMED
* -> will be flushed
*/
- buf->state = QETH_QDIO_BUF_PRIMED;
+ atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
}
}
return 0;
{
struct qeth_qdio_out_buffer *buffer;
int index;
- int rc = 0;
QETH_DBF_TEXT(trace, 6, "dosndpfa");
spin_lock(&queue->lock);
- /* do we have empty buffers? */
- if (atomic_read(&queue->used_buffers) >= (QDIO_MAX_BUFFERS_PER_Q - 1)){
+ index = queue->next_buf_to_fill;
+ buffer = &queue->bufs[queue->next_buf_to_fill];
+ /*
+ * check if buffer is empty to make sure that we do not 'overtake'
+ * ourselves and try to fill a buffer that is already primed
+ */
+ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
card->stats.tx_dropped++;
- rc = -EBUSY;
spin_unlock(&queue->lock);
- goto out;
+ return -EBUSY;
}
- index = queue->next_buf_to_fill;
- buffer = &queue->bufs[queue->next_buf_to_fill];
- BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
- atomic_inc(&queue->used_buffers);
- spin_unlock(&queue->lock);
-
- /* go on sending ... */
- netif_wake_queue(skb->dev);
qeth_fill_buffer(queue, buffer, (char *)hdr, skb);
qeth_flush_buffers(queue, 0, index, 1);
-out:
- return rc;
+ spin_unlock(&queue->lock);
+ return 0;
}
static inline int
QETH_DBF_TEXT(trace, 6, "dosndpkt");
spin_lock(&queue->lock);
- /* do we have empty buffers? */
- if (atomic_read(&queue->used_buffers) >= (QDIO_MAX_BUFFERS_PER_Q - 2)){
- card->stats.tx_dropped++;
- rc = -EBUSY;
- goto out;
- }
start_index = queue->next_buf_to_fill;
buffer = &queue->bufs[queue->next_buf_to_fill];
- BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED);
+ /*
+ * check if buffer is empty to make sure that we do not 'overtake'
+ * ourselves and try to fill a buffer that is already primed
+ */
+ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
+ card->stats.tx_dropped++;
+ spin_unlock(&queue->lock);
+ return -EBUSY;
+ }
if (queue->do_pack){
/* does packet fit in current buffer? */
- if((QETH_MAX_BUFFER_ELEMENTS(card) - buffer->next_element_to_fill)
- < elements_needed){
+ if((QETH_MAX_BUFFER_ELEMENTS(card) -
+ buffer->next_element_to_fill) < elements_needed){
/* ... no -> set state PRIMED */
- buffer->state = QETH_QDIO_BUF_PRIMED;
+ atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
flush_count++;
- atomic_inc(&queue->used_buffers);
queue->next_buf_to_fill =
(queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
buffer = &queue->bufs[queue->next_buf_to_fill];
+ /* we did a step forward, so check buffer state again */
+ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
+ card->stats.tx_dropped++;
+ qeth_flush_buffers(queue, 0, start_index, 1);
+ spin_unlock(&queue->lock);
+ /* return EBUSY because we sent old packet, not
+ * the current one */
+ return -EBUSY;
+ }
}
}
-
qeth_fill_buffer(queue, buffer, (char *)hdr, skb);
- if (buffer->state == QETH_QDIO_BUF_PRIMED){
+ if (atomic_read(&buffer->state) == QETH_QDIO_BUF_PRIMED){
/* next time fill the next buffer */
flush_count++;
- atomic_inc(&queue->used_buffers);
queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
}
if (!atomic_read(&queue->set_pci_flags_count))
qeth_flush_buffers_on_no_pci(queue, 0);
-out:
- spin_unlock(&queue->lock);
+ spin_unlock(&queue->lock);
return rc;
}
static int
qeth_send_ipa_arp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
- int len, int (*reply_cb)
- (struct qeth_card *,
- struct qeth_reply*, unsigned long),
+ int len, int (*reply_cb)(struct qeth_card *,
+ struct qeth_reply *,
+ unsigned long),
void *reply_param)
{
- int rc;
-
QETH_DBF_TEXT(trace,4,"sendarp");
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
&card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
- rc = qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
- reply_cb, reply_param);
- return rc;
+ return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
+ reply_cb, reply_param);
+}
+
+static int
+qeth_send_ipa_snmp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
+ int len, int (*reply_cb)(struct qeth_card *,
+ struct qeth_reply *,
+ unsigned long),
+ void *reply_param)
+{
+ u16 s1, s2;
+
+ QETH_DBF_TEXT(trace,4,"sendsnmp");
+
+ memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
+ memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
+ &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
+ /* adjust PDU length fields in IPA_PDU_HEADER */
+ s1 = (u32) IPA_PDU_HEADER_SIZE + len;
+ s2 = (u32) len;
+ memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
+ memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
+ return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
+ reply_cb, reply_param);
}
static struct qeth_cmd_buffer *
rc = qeth_send_ipa_arp_cmd(card, iob,
QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
- qeth_arp_query_cb,
- (void *)&qinfo);
+ qeth_arp_query_cb, (void *)&qinfo);
if (rc) {
tmp = rc;
PRINT_WARN("Error while querying ARP cache on %s: %s "
}
data_len = *((__u16*)QETH_IPA_PDU_LEN_PDU1(data));
if (cmd->data.setadapterparms.hdr.seq_no == 1)
- data_len -= (__u16)((char*)&snmp->request - (char *)cmd);
- else
data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
+ else
+ data_len -= (__u16)((char*)&snmp->request - (char *)cmd);
+
/* check if there is enough room in userspace */
if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
QETH_DBF_TEXT_(trace, 4, "scer3%i", -ENOMEM);
}
QETH_DBF_TEXT_(trace, 4, "snore%i",
cmd->data.setadapterparms.hdr.used_total);
- QETH_DBF_TEXT_(trace, 4, "sseqn%i", cmd->data.setassparms.hdr.seq_no);
+ QETH_DBF_TEXT_(trace, 4, "sseqn%i", cmd->data.setadapterparms.hdr.seq_no);
/*copy entries to user buffer*/
if (cmd->data.setadapterparms.hdr.seq_no == 1) {
memcpy(qinfo->udata + qinfo->udata_offset,
- (char *)snmp,offsetof(struct qeth_snmp_cmd,data));
+ (char *)snmp,
+ data_len + offsetof(struct qeth_snmp_cmd,data));
qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
+ } else {
+ memcpy(qinfo->udata + qinfo->udata_offset,
+ (char *)&snmp->request, data_len);
}
- memcpy(qinfo->udata + qinfo->udata_offset,
- (char *)&snmp->data, data_len);
qinfo->udata_offset += data_len;
/* check if all replies received ... */
QETH_DBF_TEXT_(trace, 4, "srtot%i",
cmd->data.setadapterparms.hdr.used_total)
return 1;
return 0;
-
}
static struct qeth_cmd_buffer *
{
struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd;
- struct qeth_snmp_ureq ureq;
+ struct qeth_snmp_ureq *ureq;
+ int req_len;
struct qeth_arp_query_info qinfo = {0, };
int rc = 0;
"on %s!\n", card->info.if_name);
return -EOPNOTSUPP;
}
- if (copy_from_user(&ureq, udata, sizeof(struct qeth_snmp_ureq)))
+ /* skip 4 bytes (data_len struct member) to get req_len */
+ if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
return -EFAULT;
- qinfo.udata_len = ureq.hdr.data_len;
- if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL)))
+ ureq = kmalloc(req_len, GFP_KERNEL);
+ if (!ureq) {
+ QETH_DBF_TEXT(trace, 2, "snmpnome");
return -ENOMEM;
+ }
+ if (copy_from_user(ureq, udata, req_len)){
+ kfree(ureq);
+ return -EFAULT;
+ }
+ qinfo.udata_len = ureq->hdr.data_len;
+ if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))){
+ kfree(ureq);
+ return -ENOMEM;
+ }
memset(qinfo.udata, 0, qinfo.udata_len);
qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);
iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL,
- QETH_SNMP_SETADP_CMDLENGTH+ureq.hdr.req_len);
+ QETH_SNMP_SETADP_CMDLENGTH + req_len);
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
- memcpy(&cmd->data.setadapterparms.data.snmp, &ureq.cmd,
- sizeof(struct qeth_snmp_cmd));
- rc = qeth_send_ipa_arp_cmd(card, iob,
- QETH_SETADP_BASE_LEN + QETH_ARP_DATA_SIZE +
- ureq.hdr.req_len, qeth_snmp_command_cb,
- (void *)&qinfo);
+ memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
+ rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
+ qeth_snmp_command_cb, (void *)&qinfo);
if (rc)
PRINT_WARN("SNMP command failed on %s: (0x%x)\n",
card->info.if_name, rc);
else
copy_to_user(udata, qinfo.udata, qinfo.udata_len);
-
+ kfree(ureq);
kfree(qinfo.udata);
return rc;
}
rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
break;
case SIOC_QETH_GET_CARD_TYPE:
+ if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
+ !card->info.guestlan)
+ return 1;
+ return 0;
break;
case SIOCGMIIPHY:
- mii_data = (struct mii_ioctl_data *) &rq->ifr_ifru.ifru_data;
+ mii_data = if_mii(rq);
mii_data->phy_id = 0;
break;
case SIOCGMIIREG:
- mii_data = (struct mii_ioctl_data *) &rq->ifr_ifru.ifru_data;
+ mii_data = if_mii(rq);
if (mii_data->phy_id != 0)
rc = -EINVAL;
else
rc = -EPERM;
break;
}
- mii_data = (struct mii_ioctl_data *) &rq->ifr_ifru.ifru_data;
+ mii_data = if_mii(rq);
if (mii_data->phy_id != 0)
rc = -EINVAL;
else
/*
*
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.30 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.32 $)
*
* Linux on zSeries OSA Express and HiperSockets support
* This file contains code related to sysfs.
#include "qeth_mpc.h"
#include "qeth_fs.h"
-const char *VERSION_QETH_SYS_C = "$Revision: 1.30 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.32 $";
/*****************************************************************************/
/* */
{
int rc;
int signum;
- char *tmp;
+ char *tmp, *tmp2;
tmp = strsep((char **) &buf, "\n");
- if (!strcmp(tmp, "unregister")){
- return qeth_notifier_unregister(current);
+ if (!strncmp(tmp, "unregister", 10)){
+ if ((rc = qeth_notifier_unregister(current)))
+ return rc;
+ return count;
}
- signum = simple_strtoul(buf, &tmp, 10);
+ signum = simple_strtoul(tmp, &tmp2, 10);
if ((signum < 0) || (signum > 32)){
PRINT_WARN("Signal number %d is out of range\n", signum);
return -EINVAL;
return count;
}
-static DRIVER_ATTR(notifier_register, 0644, 0,
+static DRIVER_ATTR(notifier_register, 0200, 0,
qeth_driver_notifier_register_store);
int
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/workqueue.h>
#include <asm/lowcore.h>
// #define DBG(args,...) do {} while (0);
static struct semaphore m_sem;
-static struct semaphore s_sem;
extern int css_process_crw(int);
extern int chsc_process_crw(void);
extern int chp_process_crw(int, int);
extern void css_reiterate_subchannels(void);
-extern void css_trigger_slow_path(void);
+
+extern struct workqueue_struct *slow_path_wq;
+extern struct work_struct slow_path_work;
static void
s390_handle_damage(char *msg)
disabled_wait((unsigned long) __builtin_return_address(0));
}
-static int
-s390_mchk_slow_path(void *param)
-{
- struct semaphore *sem;
-
- sem = (struct semaphore *)param;
- /* Set a nice name. */
- daemonize("kslowcrw");
-repeat:
- down_interruptible(sem);
- css_trigger_slow_path();
- goto repeat;
- return 0;
-}
-
/*
* Retrieve CRWs and call function to handle event.
*
}
}
if (slow)
- up(&s_sem);
+ queue_work(slow_path_wq, &slow_path_work);
goto repeat;
return 0;
}
machine_check_init(void)
{
init_MUTEX_LOCKED(&m_sem);
- init_MUTEX_LOCKED( &s_sem );
ctl_clear_bit(14, 25); /* disable damage MCH */
ctl_set_bit(14, 26); /* enable degradation MCH */
ctl_set_bit(14, 27); /* enable system recovery MCH */
machine_check_crw_init (void)
{
kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES);
- kernel_thread(s390_mchk_slow_path, &s_sem, CLONE_FS|CLONE_FILES);
ctl_set_bit(14, 28); /* enable channel report MCH */
return 0;
}
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/byteorder.h>
-#include <linux/blkdev.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include "scsi.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
-
+#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_spi.h>
#include "53c700_d.h"
-STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_dev_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
-STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
-STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
+STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
+STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
STATIC struct device_attribute *NCR_700_dev_attrs[];
}
static inline __u8
-NCR_700_get_SXFER(Scsi_Device *SDp)
+NCR_700_get_SXFER(struct scsi_device *SDp)
{
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
}
struct Scsi_Host *
-NCR_700_detect(Scsi_Host_Template *tpnt,
+NCR_700_detect(struct scsi_host_template *tpnt,
struct NCR_700_Host_Parameters *hostdata)
{
dma_addr_t pScript, pSlots;
the ITL and (if tagged) the ITLQ lists in _queuecommand */
STATIC void
save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
- Scsi_Cmnd *SCp, __u32 dsp)
+ struct scsi_cmnd *SCp, __u32 dsp)
{
/* Its just possible that this gets executed twice */
if(SCp != NULL) {
}
STATIC inline void
-NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
struct NCR_700_command_slot *slot)
{
- if(SCp->sc_data_direction != SCSI_DATA_NONE &&
- SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
- enum dma_data_direction direction = SCp->sc_data_direction;
+ if(SCp->sc_data_direction != DMA_NONE &&
+ SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
if(SCp->use_sg) {
dma_unmap_sg(hostdata->dev, SCp->buffer,
- SCp->use_sg, direction);
+ SCp->use_sg, SCp->sc_data_direction);
} else {
- dma_unmap_single(hostdata->dev,
- slot->dma_handle,
+ dma_unmap_single(hostdata->dev, slot->dma_handle,
SCp->request_bufflen,
- direction);
+ SCp->sc_data_direction);
}
}
}
STATIC inline void
NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
- Scsi_Cmnd *SCp, int result)
+ struct scsi_cmnd *SCp, int result)
{
hostdata->state = NCR_700_HOST_FREE;
hostdata->cmd = NULL;
#ifdef NCR_700_DEBUG
printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
SCp, SCp->cmnd[7], result);
- print_sense("53c700", SCp);
+ scsi_print_sense("53c700", SCp);
#endif
/* restore the old result if the request sense was
STATIC __u32
process_extended_message(struct Scsi_Host *host,
struct NCR_700_Host_Parameters *hostdata,
- Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+ struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
{
__u32 resume_offset = dsp, temp = dsp + 8;
__u8 pun = 0xff, lun = 0xff;
printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
host->host_no, pun, lun,
NCR_700_phase[(dsps & 0xf00) >> 8]);
- print_msg(hostdata->msgin);
+ scsi_print_msg(hostdata->msgin);
printk("\n");
/* just reject it */
hostdata->msgout[0] = A_REJECT_MSG;
STATIC __u32
process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata,
- Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+ struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
{
/* work out where to return to */
__u32 temp = dsp + 8, resume_offset = dsp;
#ifdef NCR_700_DEBUG
printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
NCR_700_phase[(dsps & 0xf00) >> 8]);
- print_msg(hostdata->msgin);
+ scsi_print_msg(hostdata->msgin);
printk("\n");
#endif
host->host_no, pun, lun,
NCR_700_phase[(dsps & 0xf00) >> 8]);
- print_msg(hostdata->msgin);
+ scsi_print_msg(hostdata->msgin);
printk("\n");
/* just reject it */
hostdata->msgout[0] = A_REJECT_MSG;
}
STATIC __u32
-process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
+process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
struct Scsi_Host *host,
struct NCR_700_Host_Parameters *hostdata)
{
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
} else {
#ifdef NCR_DEBUG
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
printk(" cmd %p has status %d, requesting sense\n",
SCp, hostdata->status[0]);
#endif
SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
SCp->cmnd[7] = hostdata->status[0];
SCp->use_sg = 0;
- SCp->sc_data_direction = SCSI_DATA_READ;
+ SCp->sc_data_direction = DMA_FROM_DEVICE;
dma_sync_single_for_device(hostdata->dev, slot->pCmd,
SCp->cmd_len, DMA_TO_DEVICE);
SCp->request_bufflen = sizeof(SCp->sense_buffer);
NCR_700_phase[i],
sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
printk(KERN_ERR " len = %d, cmd =", SCp->cmd_len);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
NCR_700_internal_bus_reset(host);
} else if((dsps & 0xfffff000) == A_FATAL) {
__u8 lun;
struct NCR_700_command_slot *slot;
__u8 reselection_id = hostdata->reselection_id;
- Scsi_Device *SDp;
+ struct scsi_device *SDp;
lun = hostdata->msgin[0] & 0x1f;
BUG();
}
if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
- Scsi_Cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
+ struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
if(unlikely(SCp == NULL)) {
printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n",
host->host_no, reselection_id, lun, hostdata->msgin[2]);
host->host_no, SDp->id, SDp->lun,
hostdata->msgin[2], slot, slot->tag));
} else {
- Scsi_Cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
+ struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
if(unlikely(SCp == NULL)) {
printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n",
host->host_no, reselection_id, lun);
host->host_no, pun, lun, NCR_700_condition[i],
NCR_700_phase[j], dsp - hostdata->pScript);
if(SCp != NULL) {
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
if(SCp->use_sg) {
for(i = 0; i < SCp->use_sg + 1; i++) {
__u32 resume_offset = 0;
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)host->hostdata[0];
- Scsi_Cmnd *SCp = hostdata->cmd;
+ struct scsi_cmnd *SCp = hostdata->cmd;
__u8 sbcl;
for(count = 0; count < 5; count++) {
/* The queue lock with interrupts disabled must be held on entry to
* this function */
STATIC int
-NCR_700_start_command(Scsi_Cmnd *SCp)
+NCR_700_start_command(struct scsi_cmnd *SCp)
{
struct NCR_700_command_slot *slot =
(struct NCR_700_command_slot *)SCp->host_scribble;
__u32 dsps;
__u8 sstat0 = 0, dstat = 0;
__u32 dsp;
- Scsi_Cmnd *SCp = hostdata->cmd;
+ struct scsi_cmnd *SCp = hostdata->cmd;
enum NCR_700_Host_State state;
handled = 1;
}
if(sstat0 & SCSI_RESET_DETECTED) {
- Scsi_Device *SDp;
+ struct scsi_device *SDp;
int i;
hostdata->state = NCR_700_HOST_BUSY;
/* clear all the slots and their pending commands */
for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
- Scsi_Cmnd *SCp;
+ struct scsi_cmnd *SCp;
struct NCR_700_command_slot *slot =
&hostdata->slots[i];
printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
host->host_no, pun, lun,
SGcount, data_transfer);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
if(residual) {
printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
host->host_no, pun, lun,
}
STATIC int
-NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
+NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
{
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
#ifdef NCR_700_DEBUG
printk("53c700: scsi%d, command ", SCp->device->host->host_no);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
#endif
if(SCp->device->tagged_supported && !SCp->device->simple_tags
&& (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
/* sanity check: some of the commands generated by the mid-layer
* have an eccentric idea of their sc_data_direction */
if(!SCp->use_sg && !SCp->request_bufflen
- && SCp->sc_data_direction != SCSI_DATA_NONE) {
+ && SCp->sc_data_direction != DMA_NONE) {
#ifdef NCR_700_DEBUG
printk("53c700: Command");
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
printk("Has wrong data direction %d\n", SCp->sc_data_direction);
#endif
- SCp->sc_data_direction = SCSI_DATA_NONE;
+ SCp->sc_data_direction = DMA_NONE;
}
switch (SCp->cmnd[0]) {
default:
/* OK, get it from the command */
switch(SCp->sc_data_direction) {
- case SCSI_DATA_UNKNOWN:
+ case DMA_BIDIRECTIONAL:
default:
printk(KERN_ERR "53c700: Unknown command for data direction ");
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
move_ins = 0;
break;
- case SCSI_DATA_NONE:
+ case DMA_NONE:
move_ins = 0;
break;
- case SCSI_DATA_READ:
+ case DMA_FROM_DEVICE:
move_ins = SCRIPT_MOVE_DATA_IN;
break;
- case SCSI_DATA_WRITE:
+ case DMA_TO_DEVICE:
move_ins = SCRIPT_MOVE_DATA_OUT;
break;
}
}
STATIC int
-NCR_700_abort(Scsi_Cmnd * SCp)
+NCR_700_abort(struct scsi_cmnd * SCp)
{
struct NCR_700_command_slot *slot;
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
slot = (struct NCR_700_command_slot *)SCp->host_scribble;
}
STATIC int
-NCR_700_bus_reset(Scsi_Cmnd * SCp)
+NCR_700_bus_reset(struct scsi_cmnd * SCp)
{
DECLARE_COMPLETION(complete);
struct NCR_700_Host_Parameters *hostdata =
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
/* In theory, eh_complete should always be null because the
* eh is single threaded, but just in case we're handling a
* reset via sg or something */
}
STATIC int
-NCR_700_dev_reset(Scsi_Cmnd * SCp)
+NCR_700_dev_reset(struct scsi_cmnd * SCp)
{
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
return FAILED;
}
STATIC int
-NCR_700_host_reset(Scsi_Cmnd * SCp)
+NCR_700_host_reset(struct scsi_cmnd * SCp)
{
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
- print_command(SCp->cmnd);
+ scsi_print_command(SCp);
NCR_700_internal_bus_reset(SCp->device->host);
NCR_700_chip_reset(SCp->device->host);
STATIC int
-NCR_700_slave_configure(Scsi_Device *SDp)
+NCR_700_slave_configure(struct scsi_device *SDp)
{
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
}
STATIC void
-NCR_700_slave_destroy(Scsi_Device *SDp)
+NCR_700_slave_destroy(struct scsi_device *SDp)
{
/* to do here: deallocate memory */
}
#define _53C700_H
#include <linux/interrupt.h>
-
#include <asm/io.h>
+#include <scsi/scsi_device.h>
+
+
#if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED)
#define CONFIG_53C700_BOTH_MAPPED
#endif
struct NCR_700_Host_Parameters;
/* These are the externally used routines */
-struct Scsi_Host *NCR_700_detect(Scsi_Host_Template *, struct NCR_700_Host_Parameters *);
+struct Scsi_Host *NCR_700_detect(struct scsi_host_template *,
+ struct NCR_700_Host_Parameters *);
int NCR_700_release(struct Scsi_Host *host);
irqreturn_t NCR_700_intr(int, void *, struct pt_regs *);
#define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19)
static inline void
-NCR_700_set_depth(Scsi_Device *SDp, __u8 depth)
+NCR_700_set_depth(struct scsi_device *SDp, __u8 depth)
{
long l = (long)SDp->hostdata;
SDp->hostdata = (void *)l;
}
static inline __u8
-NCR_700_get_depth(Scsi_Device *SDp)
+NCR_700_get_depth(struct scsi_device *SDp)
{
return ((((unsigned long)SDp->hostdata) & 0xff00)>>8);
}
static inline int
-NCR_700_is_flag_set(Scsi_Device *SDp, __u32 flag)
+NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag)
{
return (((unsigned long)SDp->hostdata) & flag) == flag;
}
static inline int
-NCR_700_is_flag_clear(Scsi_Device *SDp, __u32 flag)
+NCR_700_is_flag_clear(struct scsi_device *SDp, __u32 flag)
{
return (((unsigned long)SDp->hostdata) & flag) == 0;
}
static inline void
-NCR_700_set_flag(Scsi_Device *SDp, __u32 flag)
+NCR_700_set_flag(struct scsi_device *SDp, __u32 flag)
{
SDp->hostdata = (void *)((long)SDp->hostdata | (flag & 0xffff0000));
}
static inline void
-NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
+NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag)
{
SDp->hostdata = (void *)((long)SDp->hostdata & ~(flag & 0xffff0000));
}
__u8 state;
int tag;
__u32 resume_offset;
- Scsi_Cmnd *cmnd;
+ struct scsi_cmnd *cmnd;
/* The pci_mapped address of the actual command in cmnd */
dma_addr_t pCmd;
__u32 temp;
__u32 pScript; /* physical mem addr of script */
enum NCR_700_Host_State state; /* protected by state lock */
- Scsi_Cmnd *cmd;
+ struct scsi_cmnd *cmd;
/* Note: pScript contains the single consistent block of
* memory. All the msgin, msgout and status are allocated in
* this memory too (at separate cache lines). TOTAL_MEM_SIZE
depends on DECSTATION && SCSI
config BLK_DEV_3W_XXXX_RAID
- tristate "3ware Hardware ATA-RAID support"
+ tristate "3ware 5/6/7/8xxx ATA-RAID support"
depends on PCI && SCSI
help
3ware is the only hardware ATA-Raid product in Linux to date.
Please read the comments at the top of
<file:drivers/scsi/3w-xxxx.c>.
+config SCSI_3W_9XXX
+ tristate "3ware 9xxx SATA-RAID support"
+ depends on PCI && SCSI
+ help
+ This driver supports the 9000 series 3ware SATA-RAID cards.
+
+ <http://www.amcc.com>
+
+ Please read the comments at the top of
+ <file:drivers/scsi/3w-9xxx.c>.
+
config SCSI_7000FASST
tristate "7000FASST SCSI support"
depends on ISA && SCSI
# All the I2O code and drivers do not seem to be 64bit safe.
config SCSI_DPT_I2O
tristate "Adaptec I2O RAID support "
- depends on !64BIT && SCSI
+ depends on !64BIT && SCSI && PCI
help
This driver supports all of Adaptec's I2O based RAID controllers as
well as the DPT SmartRaid V cards. This is an Adaptec maintained
Adapters. Consult the SCSI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, and the files
<file:Documentation/scsi/BusLogic.txt> and
- <file:Documentation/scsi/FlashPoint.txt> for more information. If this
- driver does not work correctly without modification, please contact
- the author, Leonard N. Zubkoff, by email to lnz@dandelion.com.
+ <file:Documentation/scsi/FlashPoint.txt> for more information.
To compile this driver as a module, choose M here: the
module will be called BusLogic.
substantial, so users of MultiMaster Host Adapters may wish to omit
it.
+#
+# This is marked broken because it uses over 4kB of stack in
+# just two routines:
+# 2076 CpqTsProcessIMQEntry
+# 2052 PeekIMQEntry
+#
config SCSI_CPQFCTS
tristate "Compaq Fibre Channel 64-bit/66Mhz HBA support"
- depends on PCI && SCSI
+ depends on PCI && SCSI && BROKEN
help
Say Y here to compile in support for the Compaq StorageWorks Fibre
Channel 64-bit/66Mhz Host Bus Adapter.
To compile this driver as a module, choose M here: the
module will be called esp.
-config SCSI_PC980155
- tristate "NEC PC-9801-55 SCSI support"
- depends on X86_PC9800 && SCSI
- help
- If you have the NEC PC-9801-55 SCSI interface card or compatibles
- for NEC PC-9801/PC-9821, say Y.
-
-config WD33C93_PIO
- bool
- depends on SCSI_PC980155
- default y
-
# bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
config ZFCP
obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o
obj-$(CONFIG_GVP11_SCSI) += gvp11.o wd33c93.o
-obj-$(CONFIG_SCSI_PC980155) += pc980155.o wd33c93.o
obj-$(CONFIG_MVME147_SCSI) += mvme147.o wd33c93.o
obj-$(CONFIG_SGIWD93_SCSI) += sgiwd93.o wd33c93.o
obj-$(CONFIG_CYBERSTORM_SCSI) += NCR53C9x.o cyberstorm.o
obj-$(CONFIG_SCSI_PLUTO) += pluto.o
obj-$(CONFIG_SCSI_DECNCR) += NCR53C9x.o dec_esp.o
obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
+obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o
obj-$(CONFIG_SCSI_PPA) += ppa.o
obj-$(CONFIG_SCSI_IMM) += imm.o
obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
scsi_devinfo.o
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
-scsi_mod-$(CONFIG_X86_PC9800) += scsi_pc98.o
sd_mod-objs := sd.o
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
}
#endif
+EXPORT_SYMBOL(esp_abort);
+EXPORT_SYMBOL(esp_allocate);
+EXPORT_SYMBOL(esp_deallocate);
+EXPORT_SYMBOL(esp_initialize);
+EXPORT_SYMBOL(esp_intr);
+EXPORT_SYMBOL(esp_queue);
+EXPORT_SYMBOL(esp_reset);
+EXPORT_SYMBOL(esp_slave_alloc);
+EXPORT_SYMBOL(esp_slave_destroy);
+EXPORT_SYMBOL(esps_in_use);
+
MODULE_LICENSE("GPL");
#include <linux/module.h>
#include <linux/mca.h>
#include <asm/io.h>
-
-#include "scsi.h"
#include <scsi/scsi_host.h>
#include "53c700.h"
/* Host template. The 53c700 routine NCR_700_detect will
* fill in all of the missing routines */
-static Scsi_Host_Template NCR_D700_driver_template = {
+static struct scsi_host_template NCR_D700_driver_template = {
.module = THIS_MODULE,
.name = "NCR Dual 700 MCA",
.proc_name = "NCR_D700",
*/
-
-/*
- * --- Linux Version
- */
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif /* LINUX_VERSION_CODE */
-
-/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
-#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
-#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
-#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
-
-/* Driver supported only in version 2.2 and version >= 2.4. */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
- (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
- LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
-#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
-#endif
-
/*
* --- Linux Include Files
*/
#include <linux/blkdev.h>
#include <linux/stat.h>
#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/system.h>
typedef unsigned char uchar;
-#ifndef NULL
-#define NULL (0)
-#endif
#ifndef TRUE
#define TRUE (1)
#endif
#define ASC_MIN_SENSE_LEN 14
#define ASC_MAX_CDB_LEN 12
#define ASC_SCSI_RESET_HOLD_TIME_US 60
-#define SCSICMD_TestUnitReady 0x00
-#define SCSICMD_Rewind 0x01
-#define SCSICMD_Rezero 0x01
-#define SCSICMD_RequestSense 0x03
-#define SCSICMD_Format 0x04
-#define SCSICMD_FormatUnit 0x04
-#define SCSICMD_Read6 0x08
-#define SCSICMD_Write6 0x0A
-#define SCSICMD_Seek6 0x0B
-#define SCSICMD_Inquiry 0x12
-#define SCSICMD_Verify6 0x13
-#define SCSICMD_ModeSelect6 0x15
-#define SCSICMD_ModeSense6 0x1A
-#define SCSICMD_StartStopUnit 0x1B
-#define SCSICMD_LoadUnloadTape 0x1B
-#define SCSICMD_ReadCapacity 0x25
-#define SCSICMD_Read10 0x28
-#define SCSICMD_Write10 0x2A
-#define SCSICMD_Seek10 0x2B
-#define SCSICMD_Erase10 0x2C
-#define SCSICMD_WriteAndVerify10 0x2E
-#define SCSICMD_Verify10 0x2F
-#define SCSICMD_WriteBuffer 0x3B
-#define SCSICMD_ReadBuffer 0x3C
-#define SCSICMD_ReadLong 0x3E
-#define SCSICMD_WriteLong 0x3F
-#define SCSICMD_ReadTOC 0x43
-#define SCSICMD_ReadHeader 0x44
-#define SCSICMD_ModeSelect10 0x55
-#define SCSICMD_ModeSense10 0x5A
-
-/* Inquiry Data Peripheral Device Types */
-#define SCSI_TYPE_DASD 0x00
-#define SCSI_TYPE_SASD 0x01
-#define SCSI_TYPE_PRN 0x02
-#define SCSI_TYPE_PROC 0x03
-#define SCSI_TYPE_WORM 0x04
-#define SCSI_TYPE_CDROM 0x05
-#define SCSI_TYPE_SCANNER 0x06
-#define SCSI_TYPE_OPTMEM 0x07
-#define SCSI_TYPE_MED_CHG 0x08
-#define SCSI_TYPE_COMM 0x09
-#define SCSI_TYPE_UNKNOWN 0x1F
#define ADV_INQ_CLOCKING_ST_ONLY 0x0
#define ADV_INQ_CLOCKING_DT_ONLY 0x1
#define ASC_SCSIDIR_T2H 0x08
#define ASC_SCSIDIR_H2T 0x10
#define ASC_SCSIDIR_NODATA 0x18
-#define SCSI_SENKEY_NO_SENSE 0x00
-#define SCSI_SENKEY_UNDEFINED 0x01
-#define SCSI_SENKEY_NOT_READY 0x02
-#define SCSI_SENKEY_MEDIUM_ERR 0x03
-#define SCSI_SENKEY_HW_ERR 0x04
-#define SCSI_SENKEY_ILLEGAL 0x05
-#define SCSI_SENKEY_ATTENTION 0x06
-#define SCSI_SENKEY_PROTECTED 0x07
-#define SCSI_SENKEY_BLANK 0x08
-#define SCSI_SENKEY_V_UNIQUE 0x09
-#define SCSI_SENKEY_CPY_ABORT 0x0A
-#define SCSI_SENKEY_ABORT 0x0B
-#define SCSI_SENKEY_EQUAL 0x0C
-#define SCSI_SENKEY_VOL_OVERFLOW 0x0D
-#define SCSI_SENKEY_MISCOMP 0x0E
-#define SCSI_SENKEY_RESERVED 0x0F
#define SCSI_ASC_NOMEDIA 0x3A
#define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
#define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
#define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
#define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
-#define SS_GOOD 0x00
-#define SS_CHK_CONDITION 0x02
-#define SS_CONDITION_MET 0x04
-#define SS_TARGET_BUSY 0x08
-#define SS_INTERMID 0x10
-#define SS_INTERMID_COND_MET 0x14
-#define SS_RSERV_CONFLICT 0x18
-#define SS_CMD_TERMINATED 0x22
-#define SS_QUEUE_FULL 0x28
#define MS_CMD_DONE 0x00
#define MS_EXTEND 0x01
#define MS_SDTR_LEN 0x03
#define MS_WDTR_CODE 0x03
#define MS_MDP_LEN 0x05
#define MS_MDP_CODE 0x00
-#define M1_SAVE_DATA_PTR 0x02
-#define M1_RESTORE_PTRS 0x03
-#define M1_DISCONNECT 0x04
-#define M1_INIT_DETECTED_ERR 0x05
-#define M1_ABORT 0x06
-#define M1_MSG_REJECT 0x07
-#define M1_NO_OP 0x08
-#define M1_MSG_PARITY_ERR 0x09
-#define M1_LINK_CMD_DONE 0x0A
-#define M1_LINK_CMD_DONE_WFLAG 0x0B
-#define M1_BUS_DVC_RESET 0x0C
-#define M1_ABORT_TAG 0x0D
-#define M1_CLR_QUEUE 0x0E
-#define M1_INIT_RECOVERY 0x0F
-#define M1_RELEASE_RECOVERY 0x10
-#define M1_KILL_IO_PROC 0x11
-#define M2_QTAG_MSG_SIMPLE 0x20
-#define M2_QTAG_MSG_HEAD 0x21
-#define M2_QTAG_MSG_ORDERED 0x22
-#define M2_IGNORE_WIDE_RESIDUE 0x23
/*
* Inquiry data structure and bitfield macros
uchar sdtr_period_offset[ASC_MAX_TID + 1];
ushort pci_slot_info;
uchar adapter_info[6];
- struct pci_dev *pci_dev;
+ struct device *dev;
} ASC_DVC_CFG;
#define ASC_DEF_DVC_CNTL 0xFFFF
ushort serial1; /* EEPROM serial number word 1 */
ushort serial2; /* EEPROM serial number word 2 */
ushort serial3; /* EEPROM serial number word 3 */
- struct pci_dev *pci_dev; /* pointer to the pci dev structure for this board */
+ struct device *dev; /* pointer to the pci dev structure for this board */
} ADV_DVC_CFG;
struct adv_dvc_var;
#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
-/*
- * If the Linux kernel version supports freeing initialization code
- * and data after loading, define macros for this purpose. These macros
- * are not used when the driver is built as a module, cf. linux/init.h.
- */
-#if ASC_LINUX_KERNEL24
-#define ASC_INITFUNC(type, func) type __init func
-#elif ASC_LINUX_KERNEL22
-#define ASC_INITFUNC(type, func) __initfunc(type func)
-#endif
-#define ASC_INITDATA __initdata
-#define ASC_INIT __init
-
#define ASC_INFO_SIZE 128 /* advansys_info() line size */
#ifdef CONFIG_PROC_FS
} \
cp += len; \
}
-
-#define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif /* CONFIG_PROC_FS */
/* Asc Library return codes */
/* Return non-zero, if the queue is empty. */
#define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
-/* PCI configuration declarations */
-
-#define PCI_BASE_CLASS_PREDEFINED 0x00
-#define PCI_BASE_CLASS_MASS_STORAGE 0x01
-#define PCI_BASE_CLASS_NETWORK 0x02
-#define PCI_BASE_CLASS_DISPLAY 0x03
-#define PCI_BASE_CLASS_MULTIMEDIA 0x04
-#define PCI_BASE_CLASS_MEMORY_CONTROLLER 0x05
-#define PCI_BASE_CLASS_BRIDGE_DEVICE 0x06
-
-/* MASS STORAGE */
-#define PCI_SUB_CLASS_SCSI_CONTROLLER 0x00
-#define PCI_SUB_CLASS_IDE_CONTROLLER 0x01
-#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER 0x02
-#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER 0x03
-#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER 0x80
-
-/* NETWORK CONTROLLER */
-#define PCI_SUB_CLASS_ETHERNET_CONTROLLER 0x00
-#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER 0x01
-#define PCI_SUB_CLASS_FDDI_CONTROLLER 0x02
-#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80
-
-/* DISPLAY CONTROLLER */
-#define PCI_SUB_CLASS_VGA_CONTROLLER 0x00
-#define PCI_SUB_CLASS_XGA_CONTROLLER 0x01
-#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80
-
-/* MULTIMEDIA CONTROLLER */
-#define PCI_SUB_CLASS_VIDEO_DEVICE 0x00
-#define PCI_SUB_CLASS_AUDIO_DEVICE 0x01
-#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE 0x80
-
-/* MEMORY CONTROLLER */
-#define PCI_SUB_CLASS_RAM_CONTROLLER 0x00
-#define PCI_SUB_CLASS_FLASH_CONTROLLER 0x01
-#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER 0x80
-
-/* BRIDGE CONTROLLER */
-#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER 0x00
-#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER 0x01
-#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER 0x02
-#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER 0x03
-#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER 0x04
-#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER 0x05
-#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER 0x80
-
#define PCI_MAX_SLOT 0x1F
#define PCI_MAX_BUS 0xFF
#define PCI_IOADDRESS_MASK 0xFFFE
#define ASC_PCI_DEVICE_ID_2500 0x2500 /* ASC-38C0800 */
#define ASC_PCI_DEVICE_ID_2700 0x2700 /* ASC-38C1600 */
-/* PCI IO Port Addresses to generate special cycle */
-
-#define PCI_CONFIG_ADDRESS_MECH1 0x0CF8
-#define PCI_CONFIG_DATA_MECH1 0x0CFC
-
-#define PCI_CONFIG_FORWARD_REGISTER 0x0CFA /* 0=type 0; 1=type 1; */
-
-#define PCI_CONFIG_BUS_NUMBER_MASK 0x00FF0000
-#define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00
-#define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8
-
-#define PCI_DEVICE_FOUND 0x0000
-#define PCI_DEVICE_NOT_FOUND 0xffff
-
-#define SUBCLASS_OFFSET 0x0A
-#define CLASSCODE_OFFSET 0x0B
-#define VENDORID_OFFSET 0x00
-#define DEVICEID_OFFSET 0x02
-
#ifndef ADVANSYS_STATS
#define ASC_STATS(shp, counter)
#define ASC_STATS_ADD(shp, counter, count)
/* Note: All driver global data should be initialized. */
-#if ASC_LINUX_KERNEL22
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry proc_scsi_advansys =
-{
- PROC_SCSI_ADVANSYS, /* unsigned short low_ino */
- 8, /* unsigned short namelen */
- "advansys", /* const char *name */
- S_IFDIR | S_IRUGO | S_IXUGO, /* mode_t mode */
- 2 /* nlink_t nlink */
-};
-#endif /* CONFIG_PROC_FS */
-#endif /* ASC_LINUX_KERNEL22 */
-
/* Number of boards detected in system. */
STATIC int asc_board_count = 0;
STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
STATIC ASC_SG_HEAD asc_sg_head = { 0 };
/* List of supported bus types. */
-STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
+STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
ASC_IS_ISA,
ASC_IS_VL,
ASC_IS_EISA,
STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
STATIC int advansys_slave_configure(Scsi_Device *);
-STATIC void asc_scsi_done_list(Scsi_Cmnd *, int from_isr);
+STATIC void asc_scsi_done_list(Scsi_Cmnd *);
STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *);
STATIC int asc_build_req(asc_board_t *, Scsi_Cmnd *);
STATIC int adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
-STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
+STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *, int);
STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
STATIC void adv_async_callback(ADV_DVC_VAR *, uchar);
* it must not call SCSI mid-level functions including scsi_malloc()
* and scsi_free().
*/
-ASC_INITFUNC(
-int,
+int __init
advansys_detect(Scsi_Host_Template *tpnt)
-)
{
static int detect_called = ASC_FALSE;
int iop;
struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
int pci_card_cnt_max = 0;
int pci_card_cnt = 0;
+ struct device *dev = NULL;
struct pci_dev *pci_devp = NULL;
int pci_device_id_cnt = 0;
unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
ASC_DBG(1, "advansys_detect: begin\n");
-#if ASC_LINUX_KERNEL24
- tpnt->proc_name = "advansys";
-#elif ASC_LINUX_KERNEL22
- tpnt->proc_dir = &proc_scsi_advansys;
-#endif
-
asc_board_count = 0;
/*
NULL) {
pci_device_id_cnt++;
} else {
-#if ASC_LINUX_KERNEL24
if (pci_enable_device(pci_devp) == 0) {
pci_devicep[pci_card_cnt_max++] = pci_devp;
}
-#elif ASC_LINUX_KERNEL22
- pci_devicep[pci_card_cnt_max++] = pci_devp;
-#endif
}
}
ASC_DBG2(2,
"advansys_detect: devfn %d, bus number %d\n",
pci_devp->devfn, pci_devp->bus->number);
-#if ASC_LINUX_KERNEL24
iop = pci_resource_start(pci_devp, 0);
-#elif ASC_LINUX_KERNEL22
- iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
-#endif
ASC_DBG2(1,
"advansys_detect: vendorID %X, deviceID %X\n",
pci_devp->vendor, pci_devp->device);
ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
iop, pci_devp->irq);
}
+ if(pci_devp)
+ dev = &pci_devp->dev;
+
#endif /* CONFIG_PCI */
break;
continue;
}
- scsi_set_device(shp, &pci_devp->dev);
+ scsi_set_device(shp, dev);
/* Save a pointer to the Scsi_Host of each board found. */
asc_host[asc_board_count++] = shp;
iolen = ADV_38C1600_IOLEN;
}
#ifdef CONFIG_PCI
-#if ASC_LINUX_KERNEL24
pci_memory_address = pci_resource_start(pci_devp, 1);
-#elif ASC_LINUX_KERNEL22
- pci_memory_address = pci_devp->base_address[1];
-#endif
ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
(ulong) pci_memory_address);
if ((boardp->ioremap_addr =
#endif /* CONFIG_PROC_FS */
if (ASC_NARROW_BOARD(boardp)) {
- /*
+ asc_dvc_varp->cfg->dev = dev;
+ /*
* Set the board bus type and PCI IRQ before
* calling AscInitGetConfig().
*/
#ifdef CONFIG_PCI
case ASC_IS_PCI:
shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
- asc_dvc_varp->cfg->pci_dev = pci_devp;
asc_dvc_varp->cfg->pci_slot_info =
ASC_PCI_MKID(pci_devp->bus->number,
PCI_SLOT(pci_devp->devfn),
break;
}
} else {
+ adv_dvc_varp->cfg->dev = dev;
/*
* For Wide boards set PCI information before calling
* AdvInitGetConfig().
*/
#ifdef CONFIG_PCI
shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
- adv_dvc_varp->cfg->pci_dev = pci_devp;
adv_dvc_varp->cfg->pci_slot_info =
ASC_PCI_MKID(pci_devp->bus->number,
PCI_SLOT(pci_devp->devfn),
/* BIOS start address. */
if (ASC_NARROW_BOARD(boardp)) {
-#if ASC_LINUX_KERNEL24
shp->base =
-#elif ASC_LINUX_KERNEL22
- shp->base = (char *)
-#endif
((ulong) AscGetChipBiosAddress(
asc_dvc_varp->iop_base,
asc_dvc_varp->bus_type));
* Convert x86 realmode code segment to a linear
* address by shifting left 4.
*/
- shp->base =
-#if ASC_LINUX_KERNEL22
- (char *)
-#endif
- ((ulong) boardp->bios_codeseg << 4);
+ shp->base = ((ulong) boardp->bios_codeseg << 4);
} else {
shp->base = 0;
}
ASC_DBG2(2,
"advansys_detect: request_region port 0x%lx, len 0x%x\n",
(ulong) shp->io_port, boardp->asc_n_io_port);
-#if ASC_LINUX_KERNEL24
if (request_region(shp->io_port, boardp->asc_n_io_port,
"advansys") == NULL) {
ASC_PRINT3(
asc_board_count--;
continue;
}
-#elif ASC_LINUX_KERNEL22
- request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
-#endif
/* Register DMA Channel for Narrow boards. */
shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
default:
done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
/* Interrupts could be enabled here. */
- asc_scsi_done_list(done_scp, 0);
+ asc_scsi_done_list(done_scp);
break;
}
spin_unlock_irqrestore(&boardp->lock, flags);
* Complete all the 'done_scp' requests.
*/
if (done_scp != NULL) {
- asc_scsi_done_list(done_scp, 0);
+ asc_scsi_done_list(done_scp);
}
ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
* ints[2] - second argument
* ...
*/
-ASC_INITFUNC(
-void,
+void __init
advansys_setup(char *str, int *ints)
-)
{
int i;
* Complete all requests on the done list.
*/
- asc_scsi_done_list(done_scp, 1);
+ asc_scsi_done_list(done_scp);
ASC_DBG(1, "advansys_interrupt: end\n");
return IRQ_HANDLED;
* Interrupts can be enabled on entry.
*/
STATIC void
-asc_scsi_done_list(Scsi_Cmnd *scp, int from_isr)
+asc_scsi_done_list(Scsi_Cmnd *scp)
{
Scsi_Cmnd *tscp;
- ulong flags = 0;
ASC_DBG(2, "asc_scsi_done_list: begin\n");
while (scp != NULL) {
+ asc_board_t *boardp;
+ struct device *dev;
+
ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
tscp = REQPNEXT(scp);
scp->host_scribble = NULL;
+
+ boardp = ASC_BOARDP(scp->device->host);
+
+ if (ASC_NARROW_BOARD(boardp))
+ dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
+ else
+ dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
+
+ if (scp->use_sg)
+ dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
+ scp->use_sg, scp->sc_data_direction);
+ else if (scp->request_bufflen)
+ dma_unmap_single(dev, scp->SCp.dma_handle,
+ scp->request_bufflen, scp->sc_data_direction);
+
ASC_STATS(scp->device->host, done);
ASC_ASSERT(scp->scsi_done != NULL);
- if (from_isr)
- spin_lock_irqsave(scp->device->host->host_lock, flags);
+
scp->scsi_done(scp);
- if (from_isr)
- spin_unlock_irqrestore(scp->device->host->host_lock, flags);
+
scp = tscp;
}
ASC_DBG(2, "asc_scsi_done_list: done\n");
STATIC int
asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
{
+ struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
+
/*
* Mutually exclusive access is required to 'asc_scsi_q' and
* 'asc_sg_head' until after the request is started.
*/
if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
(boardp->reqcnt[scp->device->id] % 255) == 0) {
- asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
+ asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
} else {
- asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
+ asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
}
/*
* CDB request of single contiguous buffer.
*/
ASC_STATS(scp->device->host, cont_cnt);
- asc_scsi_q.q1.data_addr =
- cpu_to_le32(virt_to_bus(scp->request_buffer));
+ scp->SCp.dma_handle = scp->request_bufflen ?
+ dma_map_single(dev, scp->request_buffer,
+ scp->request_bufflen, scp->sc_data_direction) : 0;
+ asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
ASC_STATS_ADD(scp->device->host, cont_xfer,
ASC_CEILING(scp->request_bufflen, 512));
* CDB scatter-gather request list.
*/
int sgcnt;
+ int use_sg;
struct scatterlist *slp;
- if (scp->use_sg > scp->device->host->sg_tablesize) {
+ slp = (struct scatterlist *)scp->request_buffer;
+ use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+
+ if (use_sg > scp->device->host->sg_tablesize) {
ASC_PRINT3(
"asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
- boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
+ boardp->id, use_sg, scp->device->host->sg_tablesize);
+ dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
return ASC_ERROR;
asc_scsi_q.q1.data_cnt = 0;
asc_scsi_q.q1.data_addr = 0;
/* This is a byte value, otherwise it would need to be swapped. */
- asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
+ asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
/*
* Convert scatter-gather list into ASC_SG_HEAD list.
*/
- slp = (struct scatterlist *) scp->request_buffer;
- for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
- asc_sg_head.sg_list[sgcnt].addr =
- cpu_to_le32(virt_to_bus(
- (unsigned char *)page_address(slp->page) + slp->offset));
- asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
- ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
+ for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
+ asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
+ asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
+ ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
}
}
ADV_SCSI_REQ_Q *scsiqp;
int i;
int ret;
+ struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
/*
* Allocate an adv_req_t structure from the board to execute
* Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
* buffer command.
*/
- scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
- scsiqp->vdata_addr = scp->request_buffer;
- scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
if (scp->use_sg == 0) {
/*
* CDB request of single contiguous buffer.
*/
reqp->sgblkp = NULL;
+ scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
+ if (scp->request_bufflen) {
+ scsiqp->vdata_addr = scp->request_buffer;
+ scp->SCp.dma_handle =
+ dma_map_single(dev, scp->request_buffer,
+ scp->request_bufflen, scp->sc_data_direction);
+ } else {
+ scsiqp->vdata_addr = 0;
+ scp->SCp.dma_handle = 0;
+ }
+ scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
scsiqp->sg_list_ptr = NULL;
scsiqp->sg_real_addr = 0;
ASC_STATS(scp->device->host, cont_cnt);
/*
* CDB scatter-gather request list.
*/
- if (scp->use_sg > ADV_MAX_SG_LIST) {
+ struct scatterlist *slp;
+ int use_sg;
+
+ scsiqp->data_cnt = 0;
+ scsiqp->vdata_addr = 0;
+ scsiqp->data_addr = 0;
+
+ slp = (struct scatterlist *)scp->request_buffer;
+ use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
+
+ if (use_sg > ADV_MAX_SG_LIST) {
ASC_PRINT3(
"adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
- boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
+ boardp->id, use_sg, scp->device->host->sg_tablesize);
+ dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
scp->result = HOST_BYTE(DID_ERROR);
asc_enqueue(&boardp->done, scp, ASC_BACK);
return ASC_ERROR;
}
- if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
+ if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
/*
* Free the adv_req_t structure by adding it back to the
* board free list.
}
ASC_STATS(scp->device->host, sg_cnt);
- ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg);
+ ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
}
ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
* ADV_ERROR(-1) - SG List creation failed
*/
STATIC int
-adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
+adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp, int use_sg)
{
adv_sgblk_t *sgblkp;
ADV_SCSI_REQ_Q *scsiqp;
scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
slp = (struct scatterlist *) scp->request_buffer;
- sg_elem_cnt = scp->use_sg;
+ sg_elem_cnt = use_sg;
prev_sg_block = NULL;
reqp->sgblkp = NULL;
for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
{
- sg_block->sg_list[i].sg_addr =
- cpu_to_le32(virt_to_bus(
- (unsigned char *)page_address(slp->page) + slp->offset));
- sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
- ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
+ sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
+ sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
+ ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
if (--sg_elem_cnt == 0)
{ /* Last ADV_SG_BLOCK and scatter-gather entry. */
* If an INQUIRY command completed successfully, then call
* the AscInquiryHandling() function to set-up the device.
*/
- if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 &&
+ if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
(scp->request_bufflen - qdonep->remain_bytes) >= 8)
{
AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
(ASC_SCSI_INQUIRY *) scp->request_buffer);
}
-#if ASC_LINUX_KERNEL24
/*
* Check for an underrun condition.
*
(unsigned) qdonep->remain_bytes);
scp->resid = qdonep->remain_bytes;
}
-#endif
break;
case QD_WITH_ERROR:
ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
switch (qdonep->d3.host_stat) {
case QHSTA_NO_ERROR:
- if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
- ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
+ if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
+ ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
sizeof(scp->sense_buffer));
/*
Scsi_Cmnd *scp;
struct Scsi_Host *shp;
int i;
-#if ASC_LINUX_KERNEL24
ADV_DCNT resid_cnt;
-#endif
ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
scp->result = 0;
-#if ASC_LINUX_KERNEL24
/*
* Check for an underrun condition.
*
(ulong) resid_cnt);
scp->resid = resid_cnt;
}
-#endif
break;
case QD_WITH_ERROR:
ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
switch (scsiqp->host_status) {
case QHSTA_NO_ERROR:
- if (scsiqp->scsi_status == SS_CHK_CONDITION) {
- ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
+ if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
+ ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
sizeof(scp->sense_buffer));
/*
(unsigned) offset, (unsigned) advoffset, cplen);
if (offset <= advoffset) {
/* Read offset below current offset, copy everything. */
- cnt = ASC_MIN(cplen, leftlen);
+ cnt = min(cplen, leftlen);
ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
(ulong) curbuf, (ulong) cp, cnt);
memcpy(curbuf, cp, cnt);
/* Read offset within current range, partial copy. */
cnt = (advoffset + cplen) - offset;
cp = (cp + cplen) - cnt;
- cnt = ASC_MIN(cnt, leftlen);
+ cnt = min(cnt, leftlen);
ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
(ulong) curbuf, (ulong) cp, cnt);
memcpy(curbuf, cp, cnt);
(void) printk(s);
ret = 0;
} else {
- ret = ASC_MIN(buflen, ret);
+ ret = min(buflen, ret);
memcpy(buf, s, ret);
}
va_end(args);
/*
* Read a PCI configuration byte.
*/
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
DvcReadPCIConfigByte(
ASC_DVC_VAR *asc_dvc,
ushort offset)
-)
{
#ifdef CONFIG_PCI
uchar byte_data;
- pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
+ pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
return byte_data;
#else /* !defined(CONFIG_PCI) */
return 0;
/*
* Write a PCI configuration byte.
*/
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
DvcWritePCIConfigByte(
ASC_DVC_VAR *asc_dvc,
ushort offset,
uchar byte_data)
-)
{
#ifdef CONFIG_PCI
- pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
+ pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
#endif /* CONFIG_PCI */
}
* Return the BIOS address of the adapter at the specified
* I/O port and with the specified bus type.
*/
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscGetChipBiosAddress(
PortAddr iop_base,
- ushort bus_type
-)
-)
+ ushort bus_type)
{
ushort cfg_lsw;
ushort bios_addr;
/*
* Read a PCI configuration byte.
*/
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
DvcAdvReadPCIConfigByte(
ADV_DVC_VAR *asc_dvc,
ushort offset)
-)
{
#ifdef CONFIG_PCI
uchar byte_data;
- pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
+ pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
return byte_data;
#else /* CONFIG_PCI */
return 0;
/*
* Write a PCI configuration byte.
*/
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
DvcAdvWritePCIConfigByte(
ADV_DVC_VAR *asc_dvc,
ushort offset,
uchar byte_data)
-)
{
#ifdef CONFIG_PCI
- pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
+ pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
#else /* CONFIG_PCI */
return 0;
#endif /* CONFIG_PCI */
s->host_busy, s->host_no,
(unsigned) s->last_reset);
-#if ASC_LINUX_KERNEL24
- printk(
-" hostt 0x%lx\n",
- (ulong) s->hostt);
-#elif ASC_LINUX_KERNEL22
- printk(
-" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
- (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
-#endif
-
printk(
" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
(ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
-#if ASC_LINUX_KERNEL24
printk (
"sc_data_direction %u, resid %d\n",
s->sc_data_direction, s->resid);
-#endif
printk(
" use_sg %u, sglist_len %u, abort_reason 0x%x\n",
" timeout_per_command %d, timeout_total %d, timeout %d\n",
s->timeout_per_command, s->timeout_total, s->timeout);
-#if ASC_LINUX_KERNEL24
printk(
" internal_timeout %u, flags %u\n",
s->internal_timeout, s->flags);
-#elif ASC_LINUX_KERNEL22
- printk(
-" internal_timeout %u, flags %u, this_count %d\n",
- s->internal_timeout, s->flags,s->this_count);
-#endif
printk(
" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
printk(
" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
- h->pci_dev->device, h->lib_serial_no, h->lib_version, h->mcode_date);
+ to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
+ h->mcode_date);
printk(
" mcode_version %d, overrun_buf 0x%lx\n",
printk(
" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
- h->mcode_version, h->pci_dev->device, h->lib_version);
+ h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
printk(
" control_flag 0x%x, pci_slot_info 0x%x\n",
* --- Asc Library Functions
*/
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscGetEisaChipCfg(
- PortAddr iop_base
-)
-)
+ PortAddr iop_base)
{
PortAddr eisa_cfg_iop;
return (inpw(eisa_cfg_iop));
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscSetChipScsiID(
PortAddr iop_base,
uchar new_host_id
)
-)
{
ushort cfg_lsw;
return (AscGetChipScsiID(iop_base));
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscGetChipScsiCtrl(
- PortAddr iop_base
-)
-)
+ PortAddr iop_base)
{
uchar sc;
return (sc);
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscGetChipVersion(
PortAddr iop_base,
ushort bus_type
)
-)
{
if ((bus_type & ASC_IS_EISA) != 0) {
PortAddr eisa_iop;
return (AscGetChipVerNo(iop_base));
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscGetChipBusType(
- PortAddr iop_base
-)
-)
+ PortAddr iop_base)
{
ushort chip_ver;
return (0);
}
-STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
+STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
{
0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
};
#ifdef CONFIG_ISA
-STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
+STATIC uchar _isa_pnp_inited __initdata = 0;
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
AscSearchIOPortAddr(
PortAddr iop_beg,
- ushort bus_type
-)
-)
+ ushort bus_type)
{
if (bus_type & ASC_IS_VL) {
while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
return (0);
}
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
AscSearchIOPortAddr11(
PortAddr s_addr
)
-)
{
int i;
PortAddr iop_base;
return (0);
}
-ASC_INITFUNC(
-STATIC void,
-AscSetISAPNPWaitForKey(
- void)
-)
+STATIC void __init
+AscSetISAPNPWaitForKey(void)
{
outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
}
#endif /* CONFIG_ISA */
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
AscToggleIRQAct(
PortAddr iop_base
)
-)
{
AscSetChipStatus(iop_base, CIW_IRQ_ACT);
AscSetChipStatus(iop_base, 0);
return;
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscGetChipIRQ(
PortAddr iop_base,
- ushort bus_type
-)
-)
+ ushort bus_type)
{
ushort cfg_lsw;
uchar chip_irq;
return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscSetChipIRQ(
PortAddr iop_base,
uchar irq_no,
- ushort bus_type
-)
-)
+ ushort bus_type)
{
ushort cfg_lsw;
}
#ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
AscEnableIsaDma(
- uchar dma_channel
-)
-)
+ uchar dma_channel)
{
if (dma_channel < 4) {
outp(0x000B, (ushort) (0xC0 | dma_channel));
return (0);
} else {
- ext_msg.msg_type = M1_MSG_REJECT;
+ ext_msg.msg_type = MESSAGE_REJECT;
AscMemWordCopyPtrToLram(iop_base,
ASCV_MSGOUT_BEG,
(uchar *) &ext_msg,
(ushort) ASCV_SCSIBUSY_B, scsi_busy);
asc_dvc->queue_full_or_busy |= target_id;
- if (scsi_status == SS_QUEUE_FULL) {
+ if (scsi_status == SAM_STAT_TASK_SET_FULL) {
if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
cur_dvc_qng -= 1;
asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
} else {
if ((AscReadLramByte(iop_base,
(ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
- SCSICMD_StartStopUnit)) {
+ START_STOP)) {
asc_dvc->unit_not_ready &= ~target_id;
if (scsiq->d3.done_stat != QD_NO_ERROR) {
asc_dvc->start_motor &= ~target_id;
#define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
{
- SCSICMD_Inquiry,
- SCSICMD_RequestSense,
- SCSICMD_ReadCapacity,
- SCSICMD_ReadTOC,
- SCSICMD_ModeSelect6,
- SCSICMD_ModeSense6,
- SCSICMD_ModeSelect10,
- SCSICMD_ModeSense10,
+ INQUIRY,
+ REQUEST_SENSE,
+ READ_CAPACITY,
+ READ_TOC,
+ MODE_SELECT,
+ MODE_SENSE,
+ MODE_SELECT_10,
+ MODE_SENSE_10,
0xFF,
0xFF,
0xFF,
target_ix = scsiq->q2.target_ix;
tid_no = ASC_TIX_TO_TID(target_ix);
n_q_required = 1;
- if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
+ if (scsiq->cdbptr[0] == REQUEST_SENSE) {
if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
}
}
if (disable_syn_offset_one_fix) {
- scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
+ scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
ASC_TAG_FLAG_DISABLE_DISCONNECT);
} else {
if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
if (asc_dvc->bug_fix_cntl) {
if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
- if ((scsi_cmd == SCSICMD_Read6) ||
- (scsi_cmd == SCSICMD_Read10)) {
+ if ((scsi_cmd == READ_6) ||
+ (scsi_cmd == READ_10)) {
addr =
(ADV_PADDR) le32_to_cpu(
sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
} else {
if (asc_dvc->bug_fix_cntl) {
if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
- if ((scsi_cmd == SCSICMD_Read6) ||
- (scsi_cmd == SCSICMD_Read10)) {
+ if ((scsi_cmd == READ_6) ||
+ (scsi_cmd == READ_10)) {
addr = le32_to_cpu(scsiq->q1.data_addr) +
le32_to_cpu(scsiq->q1.data_cnt);
extra_bytes = (uchar) ((ushort) addr & 0x0003);
}
q_addr = ASC_QNO_TO_QADDR(q_no);
if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
- scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
+ scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
}
scsiq->q1.status = QS_FREE;
AscMemWordCopyPtrToLram(iop_base,
}
#ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT __init
AscGetEisaProductID(
- PortAddr iop_base
-)
-)
+ PortAddr iop_base)
{
PortAddr eisa_iop;
ushort product_id_high, product_id_low;
return (product_id);
}
-ASC_INITFUNC(
-STATIC PortAddr,
+STATIC PortAddr __init
AscSearchIOPortAddrEISA(
- PortAddr iop_base
-)
-)
+ PortAddr iop_base)
{
ASC_DCNT eisa_product_id;
return (AscIsChipHalted(iop_base));
}
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT __init
AscGetMaxDmaCount(
- ushort bus_type
-)
-)
+ ushort bus_type)
{
if (bus_type & ASC_IS_ISA)
return (ASC_MAX_ISA_DMA_COUNT);
}
#ifdef CONFIG_ISA
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscGetIsaDmaChannel(
- PortAddr iop_base
-)
-)
+ PortAddr iop_base)
{
ushort channel;
return (channel + 4);
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscSetIsaDmaChannel(
PortAddr iop_base,
- ushort dma_channel
-)
-)
+ ushort dma_channel)
{
ushort cfg_lsw;
uchar value;
return (0);
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscSetIsaDmaSpeed(
PortAddr iop_base,
- uchar speed_value
-)
-)
+ uchar speed_value)
{
speed_value &= 0x07;
AscSetBank(iop_base, 1);
return (AscGetIsaDmaSpeed(iop_base));
}
-ASC_INITFUNC(
-STATIC uchar,
+STATIC uchar __init
AscGetIsaDmaSpeed(
PortAddr iop_base
)
-)
{
uchar speed_value;
}
#endif /* CONFIG_ISA */
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscReadPCIConfigWord(
ASC_DVC_VAR *asc_dvc,
ushort pci_config_offset)
-)
{
uchar lsb, msb;
return ((ushort) ((msb << 8) | lsb));
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscInitGetConfig(
ASC_DVC_VAR *asc_dvc
)
-)
{
ushort warn_code;
PortAddr iop_base;
return(warn_code);
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscInitSetConfig(
ASC_DVC_VAR *asc_dvc
)
-)
{
ushort warn_code = 0;
return (warn_code);
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscInitFromAscDvcVar(
ASC_DVC_VAR *asc_dvc
)
-)
{
PortAddr iop_base;
ushort cfg_msw;
ushort pci_device_id;
iop_base = asc_dvc->iop_base;
- pci_device_id = asc_dvc->cfg->pci_dev->device;
+ pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
warn_code = 0;
cfg_msw = AscGetChipCfgMsw(iop_base);
if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
return (warn_code);
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscInitAscDvcVar(
- ASC_DVC_VAR *asc_dvc
-)
-)
+ ASC_DVC_VAR *asc_dvc)
{
int i;
PortAddr iop_base;
return (warn_code);
}
-ASC_INITFUNC(
-STATIC ushort,
-AscInitFromEEP(
- ASC_DVC_VAR *asc_dvc
-)
-)
+STATIC ushort __init
+AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
{
ASCEEP_CONFIG eep_config_buf;
ASCEEP_CONFIG *eep_config;
return (warn_code);
}
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AscTestExternalLram(
- ASC_DVC_VAR *asc_dvc
-)
-)
+ ASC_DVC_VAR *asc_dvc)
{
PortAddr iop_base;
ushort q_addr;
return (sta);
}
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AscWriteEEPCmdReg(
PortAddr iop_base,
uchar cmd_reg
)
-)
{
uchar read_back;
int retry;
}
}
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AscWriteEEPDataReg(
PortAddr iop_base,
ushort data_reg
)
-)
{
ushort read_back;
int retry;
}
}
-ASC_INITFUNC(
-STATIC void,
-AscWaitEEPRead(
- void
-)
-)
+STATIC void __init
+AscWaitEEPRead(void)
{
DvcSleepMilliSecond(1);
return;
}
-ASC_INITFUNC(
-STATIC void,
-AscWaitEEPWrite(
- void
-)
-)
+STATIC void __init
+AscWaitEEPWrite(void)
{
DvcSleepMilliSecond(20);
return;
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscReadEEPWord(
PortAddr iop_base,
- uchar addr
-)
-)
+ uchar addr)
{
ushort read_wval;
uchar cmd_reg;
return (read_wval);
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscWriteEEPWord(
PortAddr iop_base,
uchar addr,
- ushort word_val
-)
-)
+ ushort word_val)
{
ushort read_wval;
return (read_wval);
}
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AscGetEEPConfig(
PortAddr iop_base,
- ASCEEP_CONFIG * cfg_buf, ushort bus_type
-)
-)
+ ASCEEP_CONFIG * cfg_buf, ushort bus_type)
{
ushort wval;
ushort sum;
return (sum);
}
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AscSetEEPConfigOnce(
PortAddr iop_base,
- ASCEEP_CONFIG * cfg_buf, ushort bus_type
-)
-)
+ ASCEEP_CONFIG * cfg_buf, ushort bus_type)
{
int n_error;
ushort *wbuf;
return (n_error);
}
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AscSetEEPConfig(
PortAddr iop_base,
ASCEEP_CONFIG * cfg_buf, ushort bus_type
)
-)
{
int retry;
int n_error;
{
if (!(asc_dvc->init_sdtr & tid_bits))
{
- if ((dvc_type == SCSI_TYPE_CDROM) &&
+ if ((dvc_type == TYPE_ROM) &&
(AscCompareString((uchar *) inq->vendor_id,
(uchar *) "HP ", 3) == 0))
{
asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
}
asc_dvc->pci_fix_asyn_xfer |= tid_bits;
- if ((dvc_type == SCSI_TYPE_PROC) ||
- (dvc_type == SCSI_TYPE_SCANNER) ||
- (dvc_type == SCSI_TYPE_CDROM) ||
- (dvc_type == SCSI_TYPE_SASD))
+ if ((dvc_type == TYPE_PROCESSOR) ||
+ (dvc_type == TYPE_SCANNER) ||
+ (dvc_type == TYPE_ROM) ||
+ (dvc_type == TYPE_TAPE))
{
asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
}
* unswapped on big-endian platforms.
*/
STATIC ADVEEP_3550_CONFIG
-Default_3550_EEPROM_Config ASC_INITDATA = {
+Default_3550_EEPROM_Config __initdata = {
ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
0x0000, /* cfg_msw */
0xFFFF, /* disc_enable */
};
STATIC ADVEEP_3550_CONFIG
-ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_3550_Config_Field_IsChar __initdata = {
0, /* cfg_lsw */
0, /* cfg_msw */
0, /* -disc_enable */
};
STATIC ADVEEP_38C0800_CONFIG
-Default_38C0800_EEPROM_Config ASC_INITDATA = {
+Default_38C0800_EEPROM_Config __initdata = {
ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
0x0000, /* 01 cfg_msw */
0xFFFF, /* 02 disc_enable */
};
STATIC ADVEEP_38C0800_CONFIG
-ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_38C0800_Config_Field_IsChar __initdata = {
0, /* 00 cfg_lsw */
0, /* 01 cfg_msw */
0, /* 02 disc_enable */
};
STATIC ADVEEP_38C1600_CONFIG
-Default_38C1600_EEPROM_Config ASC_INITDATA = {
+Default_38C1600_EEPROM_Config __initdata = {
ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
0x0000, /* 01 cfg_msw */
0xFFFF, /* 02 disc_enable */
};
STATIC ADVEEP_38C1600_CONFIG
-ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
+ADVEEP_38C1600_Config_Field_IsChar __initdata = {
0, /* 00 cfg_lsw */
0, /* 01 cfg_msw */
0, /* 02 disc_enable */
* For a non-fatal error return a warning code. If there are no warnings
* then 0 is returned.
*/
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
-)
{
ushort warn_code;
AdvPortAddr iop_base;
*
* Note: Chip is stopped on entry.
*/
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
-)
{
AdvPortAddr iop_base;
ushort warn_code;
*
* Note: Chip is stopped on entry.
*/
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
-)
{
AdvPortAddr iop_base;
ushort warn_code;
*
* Note: Chip is stopped on entry.
*/
-ASC_INITFUNC(
-STATIC int,
+STATIC int __init
AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
-)
{
AdvPortAddr iop_base;
ushort warn_code;
*
* Return a checksum based on the EEPROM configuration read.
*/
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
-)
{
ushort wval, chksum;
ushort *wbuf;
*
* Return a checksum based on the EEPROM configuration read.
*/
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
ADVEEP_38C0800_CONFIG *cfg_buf)
-)
{
ushort wval, chksum;
ushort *wbuf;
*
* Return a checksum based on the EEPROM configuration read.
*/
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
ADVEEP_38C1600_CONFIG *cfg_buf)
-)
{
ushort wval, chksum;
ushort *wbuf;
/*
* Read the EEPROM from specified location
*/
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort __init
AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
-)
{
AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
ASC_EEP_CMD_READ | eep_word_addr);
/*
* Wait for EEPROM command to complete
*/
-ASC_INITFUNC(
-STATIC void,
+STATIC void __init
AdvWaitEEPCmd(AdvPortAddr iop_base)
-)
{
int eep_delay_ms;
* the device, otherwise may erroneously set *_able bits.
*/
if (scsiq->done_status == QD_NO_ERROR &&
- scsiq->cdb[0] == SCSICMD_Inquiry &&
+ scsiq->cdb[0] == INQUIRY &&
scsiq->target_lun == 0 &&
(scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
== ADV_INQ_RTN_STD_INQUIRY_DATA)
#include <scsi/scsicam.h>
#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
#include "aha152x.h"
#define MSGO(i) (HOSTDATA(shpnt)->msgo[i])
#define MSGO_I (HOSTDATA(shpnt)->msgo_i)
#define MSGOLEN (HOSTDATA(shpnt)->msgo_len)
-#define ADDMSGO(x) (MSGOLEN<256 ? MSGO(MSGOLEN++)=x : aha152x_error(shpnt,"MSGO overflow"))
+#define ADDMSGO(x) (MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow"))
#define MSGI(i) (HOSTDATA(shpnt)->msgi[i])
#define MSGILEN (HOSTDATA(shpnt)->msgi_len)
-#define ADDMSGI(x) (MSGILEN<256 ? MSGI(MSGILEN++)=x : aha152x_error(shpnt,"MSGI overflow"))
+#define ADDMSGI(x) (MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow"))
#define DATA_LEN (HOSTDATA(shpnt)->data_len)
#include <asm/ecard.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include "acornscsi.h"
#include "msgqueue.h"
#include "scsi.h"
#include <asm/ecard.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include "fas216.h"
struct arxescsi_info {
#include <asm/system.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include <scsi/scsicam.h>
#include <asm/pgtable.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include "fas216.h"
#include "scsi.h"
#include <asm/system.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#define NCR5380_implementation_fields int port, ctrl
#define NCR5380_local_declare() struct Scsi_Host *_instance
#include <asm/pgtable.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include "fas216.h"
#include "scsi.h"
#include <asm/ecard.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include "fas216.h"
#include "scsi.h"
#include <asm/system.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#define AUTOSENSE
/*#define PSEUDO_DMA*/
#include <asm/pgtable.h>
#include "../scsi.h"
-#include "../hosts.h"
+#include <scsi/scsi_host.h>
#include "fas216.h"
#include "scsi.h"
int w_flag = 0x10 << drive_dn;
int u_speed = 0;
int sitre;
- u16 reg4042, reg44, reg48, reg4a, reg54;
- u8 reg55;
+ u16 reg4042, reg4a;
+ u8 reg48, reg54, reg55;
pci_read_config_word(dev, maslave, ®4042);
DPRINTK("reg4042 = 0x%04x\n", reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
- pci_read_config_word(dev, 0x44, ®44);
- pci_read_config_word(dev, 0x48, ®48);
+ pci_read_config_byte(dev, 0x48, ®48);
pci_read_config_word(dev, 0x4a, ®4a);
- pci_read_config_word(dev, 0x54, ®54);
+ pci_read_config_byte(dev, 0x54, ®54);
pci_read_config_byte(dev, 0x55, ®55);
switch(speed) {
}
if (!(reg48 & u_flag))
- pci_write_config_word(dev, 0x48, reg48|u_flag);
+ pci_write_config_byte(dev, 0x48, reg48 | u_flag);
if (speed == XFER_UDMA_5) {
pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
} else {
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
- if (!(reg4a & u_speed)) {
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- pci_write_config_word(dev, 0x4a, reg4a|u_speed);
- }
+ if ((reg4a & a_speed) != u_speed)
+ pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
if (speed > XFER_UDMA_2) {
- if (!(reg54 & v_flag)) {
- pci_write_config_word(dev, 0x54, reg54|v_flag);
- }
- } else {
- pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
- }
+ if (!(reg54 & v_flag))
+ pci_write_config_byte(dev, 0x54, reg54 | v_flag);
+ } else
+ pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
}
/* move to PCI layer, integrate w/ MSI stuff */
}
#endif
-void print_command (unsigned char *command) {
+void __scsi_print_command (unsigned char *command) {
int i,s;
print_opcode(command[0]);
for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
* (e.g. "0x2" for Check Condition).
**/
void
-print_status(unsigned char scsi_status) {
+scsi_print_status(unsigned char scsi_status) {
#if (CONSTANTS & CONST_STATUS)
const char * ccp;
#endif
}
-void print_sense(const char *devclass, struct scsi_cmnd *cmd)
+void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
{
print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
}
-void print_req_sense(const char *devclass, struct scsi_request *sreq)
+void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
{
print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
}
#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs) / sizeof (const char *))
#endif /* (CONSTANTS & CONST_MSG) */
-int print_msg (const unsigned char *msg) {
+int scsi_print_msg (const unsigned char *msg) {
int len = 0, i;
if (msg[0] == EXTENDED_MESSAGE) {
len = 3 + msg[1];
return len;
}
-void print_Scsi_Cmnd(struct scsi_cmnd *cmd) {
+void scsi_print_command(struct scsi_cmnd *cmd) {
printk("scsi%d : destination target %d, lun %d\n",
cmd->device->host->host_no,
cmd->device->id,
cmd->device->lun);
printk(" command = ");
- print_command(cmd->cmnd);
+ __scsi_print_command(cmd->cmnd);
}
#if (CONSTANTS & CONST_HOST)
"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL};
-void print_hostbyte(int scsiresult)
+void scsi_print_hostbyte(int scsiresult)
{ static int maxcode=0;
int i;
printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
}
#else
-void print_hostbyte(int scsiresult)
+void scsi_print_hostbyte(int scsiresult)
{ printk("Hostbyte=0x%02x ",host_byte(scsiresult));
}
#endif
unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
-void print_driverbyte(int scsiresult)
+void scsi_print_driverbyte(int scsiresult)
{ static int driver_max=0,suggest_max=0;
int i,dr=driver_byte(scsiresult)&DRIVER_MASK,
su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
su<suggest_max ? driversuggest_table[su]:"invalid");
}
#else
-void print_driverbyte(int scsiresult)
+void scsi_print_driverbyte(int scsiresult)
{ printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
}
#endif
if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 )
{
TachFCHDR_GCMND* fchs;
+#error This is too much stack
ULONG ulFibreFrame[2048/4]; // max DWORDS in incoming FC Frame
USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL);
ULONG x_ID;
ULONG ulBuff, dwStatus;
TachFCHDR_GCMND* fchs;
+#error This is too much stack
ULONG ulFibreFrame[2048/4]; // max number of DWORDS in incoming Fibre Frame
UCHAR ucInboundMessageType; // Inbound CM, dword 3 "type" field
#define DC390_H
#include <linux/version.h>
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#endif
#define DC390_BANNER "Tekram DC390/AM53C974"
-#define DC390_VERSION "2.1b 2004-04-13"
+#define DC390_VERSION "2.1d 2004-05-27"
/* We don't have eh_abort_handler, eh_device_reset_handler,
* eh_bus_reset_handler, eh_host_reset_handler yet!
# define NEW_EH use_new_eh_code: 1,
# define USE_NEW_EH
#endif
-
-static int DC390_detect(Scsi_Host_Template *psht);
-static int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
-static int DC390_abort(Scsi_Cmnd *cmd);
-static int DC390_reset(Scsi_Cmnd *cmd);
-static int DC390_bios_param(struct scsi_device *sdev, struct block_device *dev,
- sector_t capacity, int geom[]);
-
-static int DC390_release(struct Scsi_Host *);
-
#endif /* DC390_H */
#include <asm/pgtable.h>
#include <asm/io.h> /* for virt_to_bus, etc. */
-#include "scsi.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
#include "dpt/dptsig.h"
#include "dpti.h"
#elif defined(__ia64__)
PROC_INTEL, PROC_IA64,
#elif defined(__sparc__)
- PROC_ULTRASPARC,
+ PROC_ULTRASPARC, PROC_ULTRASPARC,
#elif defined(__alpha__)
- PROC_ALPHA ,
+ PROC_ALPHA, PROC_ALPHA,
#else
(-1),(-1),
#endif
};
MODULE_DEVICE_TABLE(pci,dptids);
-static int adpt_detect(Scsi_Host_Template* sht)
+static int adpt_detect(struct scsi_host_template* sht)
{
struct pci_dev *pDev = NULL;
adpt_hba* pHba;
}
-static int adpt_slave_configure(Scsi_Device * device)
+static int adpt_slave_configure(struct scsi_device * device)
{
struct Scsi_Host *host = device->host;
adpt_hba* pHba;
return 0;
}
-static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
{
adpt_hba* pHba = NULL;
struct adpt_device* pDev = NULL; /* dpt per device information */
*===========================================================================
*/
-static int adpt_abort(Scsi_Cmnd * cmd)
+static int adpt_abort(struct scsi_cmnd * cmd)
{
adpt_hba* pHba = NULL; /* host bus adapter structure */
struct adpt_device* dptdevice; /* dpt per device information */
// This is the same for BLK and SCSI devices
// NOTE this is wrong in the i2o.h definitions
// This is not currently supported by our adapter but we issue it anyway
-static int adpt_device_reset(Scsi_Cmnd* cmd)
+static int adpt_device_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 msg[4];
#define I2O_HBA_BUS_RESET 0x87
// This version of bus reset is called by the eh_error handler
-static int adpt_bus_reset(Scsi_Cmnd* cmd)
+static int adpt_bus_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 msg[4];
}
// This version of reset is called by the eh_error_handler
-static int adpt_reset(Scsi_Cmnd* cmd)
+static int adpt_reset(struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
int rcode;
#endif
-static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev)
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
{
adpt_hba* pHba = NULL;
static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
{
- Scsi_Cmnd* cmd;
+ struct scsi_cmnd* cmd;
adpt_hba* pHba = dev_id;
u32 m;
ulong reply;
status = I2O_POST_WAIT_OK;
}
if(!(context & 0x40000000)) {
- cmd = (Scsi_Cmnd*) readl(reply+12);
+ cmd = (struct scsi_cmnd*) readl(reply+12);
if(cmd != NULL) {
printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
}
}
adpt_i2o_post_wait_complete(context, status);
} else { // SCSI message
- cmd = (Scsi_Cmnd*) readl(reply+12);
+ cmd = (struct scsi_cmnd*) readl(reply+12);
if(cmd != NULL){
if(cmd->serial_number != 0) { // If not timedout
adpt_i2o_to_scsi(reply, cmd);
return IRQ_RETVAL(handled);
}
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* d)
{
int i;
u32 msg[MAX_MESSAGE_SIZE];
* cmd->cmnd[0] is an unsigned char
*/
switch(cmd->sc_data_direction){
- case SCSI_DATA_READ:
+ case DMA_FROM_DEVICE:
scsidir =0x40000000; // DATA IN (iop<--dev)
break;
- case SCSI_DATA_WRITE:
+ case DMA_TO_DEVICE:
direction=0x04000000; // SGL OUT
scsidir =0x80000000; // DATA OUT (iop-->dev)
break;
- case SCSI_DATA_NONE:
+ case DMA_NONE:
break;
- case SCSI_DATA_UNKNOWN:
+ case DMA_BIDIRECTIONAL:
scsidir =0x40000000; // DATA IN (iop<--dev)
// Assume In - and continue;
break;
if(cmd->use_sg) {
struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ cmd->sc_data_direction);
len = 0;
*mptr++ = pci_map_single(pHba->pDev,
cmd->request_buffer,
cmd->request_bufflen,
- scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ cmd->sc_data_direction);
}
}
}
-static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
{
struct Scsi_Host *host = NULL;
}
-static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
+static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
u32 hba_status;
static void adpt_fail_posted_scbs(adpt_hba* pHba)
{
- Scsi_Cmnd* cmd = NULL;
- Scsi_Device* d = NULL;
+ struct scsi_cmnd* cmd = NULL;
+ struct scsi_device* d = NULL;
shost_for_each_device(d, pHba->host) {
unsigned long flags;
#endif
-static Scsi_Host_Template driver_template = {
+static struct scsi_host_template driver_template = {
.name = "dpt_i2o",
.proc_name = "dpt_i2o",
.proc_info = adpt_proc_info,
* SCSI interface function Prototypes
*/
-static int adpt_detect(Scsi_Host_Template * sht);
-static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
-static int adpt_abort(Scsi_Cmnd * cmd);
-static int adpt_reset(Scsi_Cmnd* cmd);
+static int adpt_detect(struct scsi_host_template * sht);
+static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
+static int adpt_abort(struct scsi_cmnd * cmd);
+static int adpt_reset(struct scsi_cmnd* cmd);
static int adpt_release(struct Scsi_Host *host);
-static int adpt_slave_configure(Scsi_Device *);
+static int adpt_slave_configure(struct scsi_device *);
static const char *adpt_info(struct Scsi_Host *pSHost);
static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev,
sector_t, int geom[]);
-static int adpt_bus_reset(Scsi_Cmnd* cmd);
-static int adpt_device_reset(Scsi_Cmnd* cmd);
+static int adpt_bus_reset(struct scsi_cmnd* cmd);
+static int adpt_device_reset(struct scsi_cmnd* cmd);
/*
u8 state;
u16 tid;
struct i2o_device* pI2o_dev;
- Scsi_Device *pScsi_dev;
+ struct scsi_device *pScsi_dev;
};
struct adpt_channel {
static s32 adpt_i2o_status_get(adpt_hba* pHba);
static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
-static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
-static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
-static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
+static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd);
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
static s32 adpt_hba_reset(adpt_hba* pHba);
static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
static s32 adpt_rescan(adpt_hba* pHba);
static void adpt_inquiry(adpt_hba* pHba);
static void adpt_fail_posted_scbs(adpt_hba* pHba);
static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
-static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ;
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
static int adpt_i2o_online_hba(adpt_hba* pHba);
static void adpt_i2o_post_wait_complete(u32, int);
static int adpt_i2o_systab_send(adpt_hba* pHba);
__u8 rw_latency;
__u8 retries;
__u8 status; /* status of this queueslot */
- Scsi_Cmnd *cmd; /* address of cmd */
+ struct scsi_cmnd *cmd; /* address of cmd */
struct eata_sg_list *sg_list;
};
* last change: 2002/11/02 OS: Linux 2.5.45 *
************************************************************/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
-#include <linux/stat.h>
-#include <linux/config.h>
#include <linux/blkdev.h>
#include <linux/spinlock.h>
#include <asm/io.h>
-#include "scsi.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
-#include <scsi/scsicam.h>
#include "eata_generic.h"
#include "eata_pio.h"
static unsigned long int_counter;
static unsigned long queue_counter;
+static struct scsi_host_template driver_template;
+
/*
* eata_proc_info
* inout : decides on the direction of the dataflow and the meaning of the
if (sh->io_port && sh->n_io_port)
release_region(sh->io_port, sh->n_io_port);
}
- return (TRUE);
+ return 1;
}
-static void IncStat(Scsi_Pointer * SCp, uint Increment)
+static void IncStat(struct scsi_pointer *SCp, uint Increment)
{
SCp->ptr += Increment;
if ((SCp->this_residual -= Increment) == 0) {
if ((--SCp->buffers_residual) == 0)
- SCp->Status = FALSE;
+ SCp->Status = 0;
else {
SCp->buffer++;
SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset;
static void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
{
uint eata_stat = 0xfffff;
- Scsi_Cmnd *cmd;
+ struct scsi_cmnd *cmd;
hostdata *hd;
struct eata_ccb *cp;
uint base;
if (stat & HA_SDRQ) {
if (cp->DataIn) {
z = 256;
- odd = FALSE;
+ odd = 0;
while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
if (odd) {
*(cmd->SCp.ptr) = zwickel >> 8;
IncStat(&cmd->SCp, 1);
- odd = FALSE;
+ odd = 0;
}
x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
insw(base + HA_RDATA, cmd->SCp.ptr, x);
*(cmd->SCp.ptr) = zwickel & 0xff;
IncStat(&cmd->SCp, 1);
z--;
- odd = TRUE;
+ odd = 1;
}
}
while (z > 0) {
}
} else { /* cp->DataOut */
- odd = FALSE;
+ odd = 0;
z = 256;
while ((cmd->SCp.Status) && ((z > 0) || (odd))) {
if (odd) {
IncStat(&cmd->SCp, 1);
outw(zwickel, base + HA_RDATA);
z--;
- odd = FALSE;
+ odd = 0;
}
x = min_t(unsigned int, z, cmd->SCp.this_residual / 2);
outsw(base + HA_RDATA, cmd->SCp.ptr, x);
zwickel = *(cmd->SCp.ptr);
zwickel &= 0xff;
IncStat(&cmd->SCp, 1);
- odd = TRUE;
+ odd = 1;
}
}
while (z > 0 || odd) {
outw(zwickel, base + HA_RDATA);
z--;
- odd = FALSE;
+ odd = 0;
}
}
}
while (inb(base + HA_RSTATUS) & HA_SBUSY)
if (--loop == 0)
- return (TRUE);
+ return 1;
/* Enable interrupts for HBA. It is not the best way to do it at this
* place, but I hope that it doesn't interfere with the IDE driver
outb(HA_CTRL_8HEADS, base + HA_CTRLREG);
outb(command, base + HA_WCOMMAND);
- return (FALSE);
+ return 0;
}
-static int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int eata_pio_queue(struct scsi_cmnd *cmd,
+ void (*done)(struct scsi_cmnd *))
{
uint x, y;
uint base;
cmd->scsi_done = (void *) done;
- if(cmd->sc_data_direction == SCSI_DATA_WRITE)
- cp->DataOut = TRUE; /* Output mode */
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ cp->DataOut = 1; /* Output mode */
else
- cp->DataIn = TRUE; /* Input mode */
+ cp->DataIn = 0; /* Input mode */
cp->Interpret = (cmd->device->id == hd->hostid);
cp->cp_datalen = htonl((unsigned long) cmd->request_bufflen);
- cp->Auto_Req_Sen = FALSE;
+ cp->Auto_Req_Sen = 0;
cp->cp_reqDMA = htonl(0);
cp->reqlen = 0;
cp->cp_id = cmd->device->id;
cp->cp_lun = cmd->device->lun;
- cp->cp_dispri = FALSE;
- cp->cp_identify = TRUE;
+ cp->cp_dispri = 0;
+ cp->cp_identify = 1;
memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
cp->cp_statDMA = htonl(0);
return (0);
}
-static int eata_pio_abort(Scsi_Cmnd * cmd)
+static int eata_pio_abort(struct scsi_cmnd *cmd)
{
uint loop = HZ;
panic("eata_pio: abort: invalid slot status\n");
}
-static int eata_pio_host_reset(Scsi_Cmnd * cmd)
+static int eata_pio_host_reset(struct scsi_cmnd *cmd)
{
uint x, limit = 0;
- unsigned char success = FALSE;
- Scsi_Cmnd *sp;
+ unsigned char success = 0;
+ struct scsi_cmnd *sp;
struct Scsi_Host *host = cmd->device->host;
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
sp->scsi_done(sp);
}
- HD(cmd)->state = FALSE;
+ HD(cmd)->state = 0;
if (success) { /* hmmm... */
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
memset(&cp, 0, sizeof(struct eata_ccb));
memset(buff, 0, sizeof(buff));
- cp.DataIn = TRUE;
- cp.Interpret = TRUE; /* Interpret command */
+ cp.DataIn = 1;
+ cp.Interpret = 1; /* Interpret command */
cp.cp_datalen = htonl(254);
cp.cp_dataDMA = htonl(0);
int z;
unsigned short *p;
- if (check_region(base, 9))
- return (FALSE);
+ if (!request_region(base, 9, "eata_pio"))
+ return 0;
memset(buf, 0, sizeof(struct get_conf));
while (inb(base + HA_RSTATUS) & HA_SBUSY)
if (--loop == 0)
- return (FALSE);
+ goto fail;
DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base));
eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) {
while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
if (--loop == 0)
- return (FALSE);
+ goto fail;
loop = HZ / 2;
*p = inw(base + HA_RDATA);
}
- if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */
- if (htonl(EATA_SIGNATURE) == buf->signature) {
- DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " "at %#4x EATA Level: %x\n", base, (uint) (buf->version)));
-
- while (inb(base + HA_RSTATUS) & HA_SDRQ)
- inw(base + HA_RDATA);
- if (ALLOW_DMA_BOARDS == FALSE) {
- for (z = 0; z < MAXISA; z++)
- if (base == ISAbases[z]) {
- buf->IRQ = ISAirqs[z];
- break;
- }
+ if (inb(base + HA_RSTATUS) & HA_SERROR) {
+ DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during "
+ "transfer for HBA at %x\n", base));
+ goto fail;
+ }
+
+ if (htonl(EATA_SIGNATURE) != buf->signature)
+ goto fail;
+
+ DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found "
+ "at %#4x EATA Level: %x\n",
+ base, (uint) (buf->version)));
+
+ while (inb(base + HA_RSTATUS) & HA_SDRQ)
+ inw(base + HA_RDATA);
+
+ if (!ALLOW_DMA_BOARDS) {
+ for (z = 0; z < MAXISA; z++)
+ if (base == ISAbases[z]) {
+ buf->IRQ = ISAirqs[z];
+ break;
}
- return (TRUE);
- }
- } else {
- DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " "for HBA at %x\n", base));
}
- return (FALSE);
+
+ return 1;
+
+ fail:
+ release_region(base, 9);
+ return 0;
}
static void print_pio_config(struct get_conf *gc)
return (!(inb(base + HA_RSTATUS) & HA_SERROR));
}
-static int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
+static int register_pio_HBA(long base, struct get_conf *gc)
{
unsigned long size = 0;
char *buff;
DBG(DBG_REGISTER, print_pio_config(gc));
- if (gc->DMA_support == TRUE) {
+ if (gc->DMA_support) {
printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base);
- if (ALLOW_DMA_BOARDS == FALSE)
- return (FALSE);
+ if (!ALLOW_DMA_BOARDS)
+ return 0;
}
if ((buff = get_pio_board_data((uint) base, gc->IRQ, gc->scsi_id[3], cplen = (htonl(gc->cplen) + 1) / 2, cppadlen = (htons(gc->cppadlen) + 1) / 2)) == NULL) {
printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (unsigned long) base);
- return (FALSE);
+ return 0;
}
- if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE) {
+ if (!print_selftest(base) && !ALLOW_DMA_BOARDS) {
printk("HBA at %#lx failed while performing self test & setup.\n", (unsigned long) base);
- return (FALSE);
+ return 0;
}
- request_region(base, 8, "eata_pio");
-
size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
- sh = scsi_register(tpnt, size);
- if (sh == NULL) {
- release_region(base, 8);
- return FALSE;
- }
+ sh = scsi_register(&driver_template, size);
+ if (sh == NULL)
+ return 0;
if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */
if (!request_irq(gc->IRQ, do_eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", sh)) {
reg_IRQ[gc->IRQ]++;
if (!gc->IRQ_TR)
- reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */
+ reg_IRQL[gc->IRQ] = 1; /* IRQ is edge triggered */
} else {
printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ);
- release_region(base, 8);
- return (FALSE);
+ return 0;
}
} else { /* More than one HBA on this IRQ */
- if (reg_IRQL[gc->IRQ] == TRUE) {
+ if (reg_IRQL[gc->IRQ]) {
printk("Can't support more than one HBA on this IRQ,\n" " if the IRQ is edge triggered. Sorry.\n");
- release_region(base, 8);
- return (FALSE);
+ return 0;
} else
reg_IRQ[gc->IRQ]++;
}
}
if (ntohl(gc->len) >= 0x22) {
- if (gc->is_PCI == TRUE)
+ if (gc->is_PCI)
hd->bustype = IS_PCI;
- else if (gc->is_EISA == TRUE)
+ else if (gc->is_EISA)
hd->bustype = IS_EISA;
else
hd->bustype = IS_ISA;
sh->unique_id = base;
sh->base = base;
sh->io_port = base;
- sh->n_io_port = 8;
+ sh->n_io_port = 9;
sh->irq = gc->IRQ;
sh->dma_channel = PIO;
sh->this_id = gc->scsi_id[3];
sh->max_lun = 8;
if (gc->SECOND)
- hd->primary = FALSE;
+ hd->primary = 0;
else
- hd->primary = TRUE;
+ hd->primary = 1;
- sh->unchecked_isa_dma = FALSE; /* We can only do PIO */
+ sh->unchecked_isa_dma = 0; /* We can only do PIO */
hd->next = NULL; /* build a linked list of all HBAs */
hd->prev = last_HBA;
return (1);
}
-static void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
+static void find_pio_ISA(struct get_conf *buf)
{
int i;
for (i = 0; i < MAXISA; i++) {
- if (ISAbases[i]) {
- if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE) {
- register_pio_HBA(ISAbases[i], buf, tpnt);
- }
+ if (!ISAbases[i])
+ continue;
+ if (!get_pio_conf_PIO(ISAbases[i], buf))
+ continue;
+ if (!register_pio_HBA(ISAbases[i], buf))
+ release_region(ISAbases[i], 9);
+ else
ISAbases[i] = 0;
- }
}
return;
}
-static void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
+static void find_pio_EISA(struct get_conf *buf)
{
u32 base;
int i;
#endif
for (i = 0; i < MAXEISA; i++) {
- if (EISAbases[i] == TRUE) { /* Still a possibility ? */
+ if (EISAbases[i]) { /* Still a possibility ? */
base = 0x1c88 + (i * 0x1000);
#if CHECKPAL
if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3));
#endif
- if (get_pio_conf_PIO(base, buf) == TRUE) {
+ if (get_pio_conf_PIO(base, buf)) {
DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
if (buf->IRQ) {
- register_pio_HBA(base, buf, tpnt);
- } else
+ if (!register_pio_HBA(base, buf))
+ release_region(base, 9);
+ } else {
printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n");
+ release_region(base, 9);
+ }
}
/* Nothing found here so we take it from the list */
EISAbases[i] = 0;
return;
}
-static void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
+static void find_pio_PCI(struct get_conf *buf)
{
#ifndef CONFIG_PCI
printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
base += 0x10; /* Now, THIS is the real address */
if (base != 0x1f8) {
/* We didn't find it in the primary search */
- if (get_pio_conf_PIO(base, buf) == TRUE) {
- if (buf->FORCADR) /* If the address is forced */
+ if (get_pio_conf_PIO(base, buf)) {
+ if (buf->FORCADR) { /* If the address is forced */
+ release_region(base, 9);
continue; /* we'll find it later */
+ }
/* OK. We made it till here, so we can go now
* and register it. We only have to check and
* eventually remove it from the EISA and ISA list
*/
- register_pio_HBA(base, buf, tpnt);
+ if (!register_pio_HBA(base, buf)) {
+ release_region(base, 9);
+ continue;
+ }
if (base < 0x1000) {
for (x = 0; x < MAXISA; ++x) {
}
}
#if CHECK_BLINK
- else if (check_blink_state(base) == TRUE) {
+ else if (check_blink_state(base)) {
printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n");
}
#endif
#endif /* #ifndef CONFIG_PCI */
}
-
-static int eata_pio_detect(Scsi_Host_Template * tpnt)
+static int eata_pio_detect(struct scsi_host_template *tpnt)
{
struct Scsi_Host *HBA_ptr;
struct get_conf gc;
int i;
- tpnt->proc_name = "eata_pio";
-
- find_pio_PCI(&gc, tpnt);
-
- find_pio_EISA(&gc, tpnt);
-
- find_pio_ISA(&gc, tpnt);
+ find_pio_PCI(&gc);
+ find_pio_EISA(&gc);
+ find_pio_ISA(&gc);
for (i = 0; i <= MAXIRQ; i++)
if (reg_IRQ[i])
HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ?
"PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ",
- (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE) ? 'Y' : 'N', HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
+ (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id,
+ SD(HBA_ptr)->primary ? 'Y' : 'N', HBA_ptr->can_queue,
+ HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
HBA_ptr = SD(HBA_ptr)->next;
}
}
return (registered_HBAs);
}
-static Scsi_Host_Template driver_template = {
- .proc_info = eata_pio_proc_info,
+static struct scsi_host_template driver_template = {
+ .proc_name = "eata_pio",
.name = "EATA (Extended Attachment) PIO driver",
+ .proc_info = eata_pio_proc_info,
.detect = eata_pio_detect,
.release = eata_pio_release,
.queuecommand = eata_pio_queue,
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include "esp.h"
#include <asm/oplib.h>
#include <asm/io.h>
#include <asm/irq.h>
-
#ifndef __sparc_v9__
#include <asm/machines.h>
#include <asm/idprom.h>
#endif
-#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
#define DEBUG_ESP
/* #define DEBUG_ESP_HME */
#ifndef _SPARC_ESP_H
#define _SPARC_ESP_H
-#include <linux/config.h>
-
-/* #include "scsi.h" */
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_request.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-
/* For dvma controller register definitions. */
#include <asm/dma.h>
-#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
-
/* The ESP SCSI controllers have their register sets in three
* "classes":
*
unsigned disconnect:1;
};
+struct scsi_cmnd;
+
/* We get one of these for each ESP probed. */
struct esp {
unsigned long eregs; /* ESP controller registers */
#include <linux/delay.h>
#include <linux/mca.h>
#include <linux/spinlock.h>
+#include <scsi/scsicam.h>
#include <linux/mca-legacy.h>
#include <asm/io.h>
static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev,
sector_t capacity, int *info_array)
{
- unsigned char buf[512 + sizeof(int) * 2];
+ unsigned char *p = scsi_bios_ptable(bdev);
int size = capacity;
- int *sizes = (int *) buf;
- unsigned char *data = (unsigned char *) (sizes + 2);
- unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
- int retcode;
/* BIOS >= 3.4 for MCA cards */
/* This algorithm was provided by Future Domain (much thanks!). */
- sizes[0] = 0; /* zero bytes out */
- sizes[1] = 512; /* one sector in */
- memcpy(data, do_read, sizeof(do_read));
- retcode = kernel_scsi_ioctl(disk, SCSI_IOCTL_SEND_COMMAND, (void *) buf);
- if (!retcode /* SCSI command ok */
- && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
- && data[0x1c2]) { /* Partition type */
+ if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
+ && p[4]) { /* Partition type */
/* The partition table layout is as follows:
Start: 0x1b3h
Future Domain algorithm, but it seemed to be a reasonable thing
to do, especially in the Linux and BSD worlds. */
- info_array[0] = data[0x1c3] + 1; /* heads */
- info_array[1] = data[0x1c4] & 0x3f; /* sectors */
+ info_array[0] = p[5] + 1; /* heads */
+ info_array[1] = p[6] & 0x3f; /* sectors */
} else {
/* Note that this new method guarantees that there will always be
less than 1024 cylinders on a platter. This is good for drives
}
/* For both methods, compute the cylinders */
info_array[2] = (unsigned int) size / (info_array[0] * info_array[1]);
+ kfree(p);
return 0;
}
#include <linux/pci.h>
#include <linux/stat.h>
#include <linux/delay.h>
+#include <scsi/scsicam.h>
#include <asm/io.h>
#include <asm/system.h>
sector_t capacity, int *info_array)
{
int drive;
- unsigned char buf[512 + sizeof (Scsi_Ioctl_Command)];
- Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command *) buf;
int size = capacity;
- unsigned char *data = sic->data;
- unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
- int retcode;
unsigned long offset;
struct drive_info {
unsigned short cylinders;
info_array[2] = i.cylinders;
} else { /* 3.4 BIOS (and up?) */
/* This algorithm was provided by Future Domain (much thanks!). */
+ unsigned char *p = scsi_bios_ptable(bdev);
- sic->inlen = 0; /* zero bytes out */
- sic->outlen = 512; /* one sector in */
- memcpy( data, do_read, sizeof( do_read ) );
- retcode = kernel_scsi_ioctl( sdev,
- SCSI_IOCTL_SEND_COMMAND,
- sic );
- if (!retcode /* SCSI command ok */
- && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
- && data[0x1c2]) { /* Partition type */
+ if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */
+ && p[4]) { /* Partition type */
/* The partition table layout is as follows:
Future Domain algorithm, but it seemed to be a reasonable thing
to do, especially in the Linux and BSD worlds. */
- info_array[0] = data[0x1c3] + 1; /* heads */
- info_array[1] = data[0x1c4] & 0x3f; /* sectors */
+ info_array[0] = p[5] + 1; /* heads */
+ info_array[1] = p[6] & 0x3f; /* sectors */
} else {
/* Note that this new method guarantees that there will always be
}
/* For both methods, compute the cylinders */
info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
+ kfree(p);
}
return 0;
#endif
#include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
#include "gdth.h"
static void gdth_delay(int milliseconds);
GDTH_UNLOCK_HA(ha, flags);
}
-static void gdth_clear_events()
+static void gdth_clear_events(void)
{
TRACE(("gdth_clear_events()"));
return 0;
}
-static int ioc_event(unsigned long arg)
+static int ioc_event(void __user *arg)
{
gdth_ioctl_event evt;
gdth_ha_str *ha;
ulong flags;
- if (copy_from_user(&evt, (char *)arg, sizeof(gdth_ioctl_event)) ||
+ if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) ||
evt.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[evt.ionode]);
} else {
gdth_readapp_event(ha, evt.erase, &evt.event);
}
- if (copy_to_user((char *)arg, &evt, sizeof(gdth_ioctl_event)))
+ if (copy_to_user(arg, &evt, sizeof(gdth_ioctl_event)))
return -EFAULT;
return 0;
}
-static int ioc_lockdrv(unsigned long arg)
+static int ioc_lockdrv(void __user *arg)
{
gdth_ioctl_lockdrv ldrv;
unchar i, j;
ulong flags;
gdth_ha_str *ha;
- if (copy_from_user(&ldrv, (char *)arg, sizeof(gdth_ioctl_lockdrv)) ||
+ if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) ||
ldrv.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[ldrv.ionode]);
return 0;
}
-static int ioc_resetdrv(unsigned long arg, char *cmnd)
+static int ioc_resetdrv(void __user *arg, char *cmnd)
{
gdth_ioctl_reset res;
gdth_cmd_str cmd;
Scsi_Cmnd scp;
#endif
- if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
+ if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
return -EFAULT;
hanum = res.ionode;
gdth_do_cmd(&scp, &cmd, cmnd, 30);
res.status = (ushort)scp.SCp.Status;
#endif
- if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
+ if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset)))
return -EFAULT;
return 0;
}
-static int ioc_general(unsigned long arg, char *cmnd)
+static int ioc_general(void __user *arg, char *cmnd)
{
gdth_ioctl_general gen;
char *buf = NULL;
Scsi_Cmnd scp;
#endif
- if (copy_from_user(&gen, (char *)arg, sizeof(gdth_ioctl_general)) ||
+ if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) ||
gen.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = gen.ionode;
if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len,
FALSE, &paddr)))
return -EFAULT;
- if (copy_from_user(buf, (char *)arg + sizeof(gdth_ioctl_general),
+ if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general),
gen.data_len + gen.sense_len)) {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
gen.info = scp.SCp.Message;
#endif
- if (copy_to_user((char *)arg + sizeof(gdth_ioctl_general), buf,
+ if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf,
gen.data_len + gen.sense_len)) {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
}
- if (copy_to_user((char *)arg, &gen,
+ if (copy_to_user(arg, &gen,
sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr);
return -EFAULT;
return 0;
}
-static int ioc_hdrlist(unsigned long arg, char *cmnd)
+static int ioc_hdrlist(void __user *arg, char *cmnd)
{
gdth_ioctl_rescan rsc;
gdth_cmd_str cmd;
Scsi_Cmnd scp;
#endif
- if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
+ if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
rsc.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = rsc.ionode;
scsi_release_command(scp);
#endif
- if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
+ if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
return -EFAULT;
return 0;
}
-static int ioc_rescan(unsigned long arg, char *cmnd)
+static int ioc_rescan(void __user *arg, char *cmnd)
{
gdth_ioctl_rescan rsc;
gdth_cmd_str cmd;
Scsi_Cmnd scp;
#endif
- if (copy_from_user(&rsc, (char *)arg, sizeof(gdth_ioctl_rescan)) ||
+ if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
rsc.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = rsc.ionode;
scsi_release_command(scp);
#endif
- if (copy_to_user((char *)arg, &rsc, sizeof(gdth_ioctl_rescan)))
+ if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
return -EFAULT;
return 0;
}
#endif
ulong flags;
char cmnd[MAX_COMMAND_SIZE];
+ void __user *argp = (void __user *)arg;
memset(cmnd, 0xff, 12);
case GDTIOCTL_CTRCNT:
{
int cnt = gdth_ctr_count;
- if (put_user(cnt, (int *)arg))
+ if (put_user(cnt, (int __user *)argp))
return -EFAULT;
break;
}
case GDTIOCTL_DRVERS:
{
int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION;
- if (put_user(ver, (int *)arg))
+ if (put_user(ver, (int __user *)argp))
return -EFAULT;
break;
}
osv.version = (unchar)(LINUX_VERSION_CODE >> 16);
osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8);
osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff);
- if (copy_to_user((char *)arg, &osv, sizeof(gdth_ioctl_osvers)))
+ if (copy_to_user(argp, &osv, sizeof(gdth_ioctl_osvers)))
return -EFAULT;
break;
}
{
gdth_ioctl_ctrtype ctrt;
- if (copy_from_user(&ctrt, (char *)arg, sizeof(gdth_ioctl_ctrtype)) ||
+ if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) ||
ctrt.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[ctrt.ionode]);
}
ctrt.info = ha->brd_phys;
ctrt.oem_id = ha->oem_id;
- if (copy_to_user((char *)arg, &ctrt, sizeof(gdth_ioctl_ctrtype)))
+ if (copy_to_user(argp, &ctrt, sizeof(gdth_ioctl_ctrtype)))
return -EFAULT;
break;
}
case GDTIOCTL_GENERAL:
- return ioc_general(arg, cmnd);
+ return ioc_general(argp, cmnd);
case GDTIOCTL_EVENT:
- return ioc_event(arg);
+ return ioc_event(argp);
case GDTIOCTL_LOCKDRV:
- return ioc_lockdrv(arg);
+ return ioc_lockdrv(argp);
case GDTIOCTL_LOCKCHN:
{
gdth_ioctl_lockchn lchn;
unchar i, j;
- if (copy_from_user(&lchn, (char *)arg, sizeof(gdth_ioctl_lockchn)) ||
+ if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) ||
lchn.ionode >= gdth_ctr_count)
return -EFAULT;
ha = HADATA(gdth_ctr_tab[lchn.ionode]);
}
case GDTIOCTL_RESCAN:
- return ioc_rescan(arg, cmnd);
+ return ioc_rescan(argp, cmnd);
case GDTIOCTL_HDRLIST:
- return ioc_hdrlist(arg, cmnd);
+ return ioc_hdrlist(argp, cmnd);
case GDTIOCTL_RESET_BUS:
{
gdth_ioctl_reset res;
int hanum, rval;
- if (copy_from_user(&res, (char *)arg, sizeof(gdth_ioctl_reset)) ||
+ if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) ||
res.ionode >= gdth_ctr_count)
return -EFAULT;
hanum = res.ionode;
rval = gdth_eh_bus_reset(&scp);
res.status = (rval == SUCCESS ? S_OK : S_GENERR);
#endif
- if (copy_to_user((char *)arg, &res, sizeof(gdth_ioctl_reset)))
+ if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset)))
return -EFAULT;
break;
}
case GDTIOCTL_RESET_DRV:
- return ioc_resetdrv(arg, cmnd);
+ return ioc_resetdrv(argp, cmnd);
default:
break;
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
+ /* retry only "normal" I/O: */
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+ rq->errors = 1;
+ ide_end_drive_cmd(drive, stat, err);
+ return ide_stopped;
+ }
+
if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
/* force an abort */
HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
+ /* retry only "normal" I/O: */
+ if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
+ rq->errors = 1;
+ ide_end_drive_cmd(drive, BUSY_STAT, 0);
+ return ide_stopped;
+ }
+
#if IDESCSI_DEBUG_LOG
printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number);
(res->cfgte.res_addr.lun == sdev->lun)) {
res->sdev = sdev;
res->add_to_ml = 0;
+ res->in_erp = 0;
sdev->hostdata = res;
res->needs_sync_complete = 1;
break;
SCSI_SENSE_BUFFERSIZE);
}
- if (res)
+ if (res) {
res->needs_sync_complete = 1;
+ res->in_erp = 0;
+ }
ipr_unmap_sglist(ioa_cfg, ipr_cmd);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
scsi_cmd->scsi_done(scsi_cmd);
static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd)
{
struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
+ u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+ if (IPR_IOASC_SENSE_KEY(ioasc) > 0) {
+ ipr_erp_done(ipr_cmd);
+ return;
+ }
ipr_reinit_ipr_cmnd_for_erp(ipr_cmd);
ipr_erp_cancel_all(ipr_cmd);
return;
}
+ res->needs_sync_complete = 1;
break;
case IPR_IOASC_NR_INIT_CMD_REQUIRED:
break;
ipr_cmd->timer.data = (unsigned long) ipr_cmd;
ipr_cmd->timer.expires = jiffies + IPR_OPERATIONAL_TIMEOUT;
ipr_cmd->timer.function = (void (*)(unsigned long))ipr_timeout;
+ ipr_cmd->done = ipr_reset_ioa_job;
add_timer(&ipr_cmd->timer);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.0.7"
-#define IPR_DRIVER_DATE "(May 21, 2004)"
+#define IPR_DRIVER_VERSION "2.0.9"
+#define IPR_DRIVER_DATE "(May 26, 2004)"
/*
* IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
#include <asm/parisc-device.h>
#include <asm/delay.h>
-#include "scsi.h"
#include <scsi/scsi_host.h>
#include "lasi700.h"
{ 0 }
};
-static Scsi_Host_Template lasi700_template = {
+static struct scsi_host_template lasi700_template = {
.name = "LASI SCSI 53c700",
.proc_name = "lasi700",
.this_id = 7,
umc = MBOX_P(uiocp);
- upthru = (mega_passthru *)umc->xferaddr;
+ if (get_user(upthru, (mega_passthru **)&umc->xferaddr))
+ return (-EFAULT);
if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
return (-EFAULT);
umc = (megacmd_t *)uioc_mimd->mbox;
- upthru = (mega_passthru *)umc->xferaddr;
+ if (get_user(upthru, (mega_passthru **)&umc->xferaddr))
+ return (-EFAULT);
if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
return (-EFAULT);
* Wait till all the issued commands are complete and there are no
* commands in the pending queue
*/
- while( atomic_read(&adapter->pend_cmds) > 0 ||
- !list_empty(&adapter->pending_list) ) {
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1*HZ ); /* sleep for 1s */
- }
+ while (atomic_read(&adapter->pend_cmds) > 0 ||
+ !list_empty(&adapter->pending_list))
+ msleep(1000); /* sleep for 1s */
rval = mega_do_del_logdrv(adapter, logdrv);
pci_bus = pdev->bus->number;
pci_dev_func = pdev->devfn;
+
+ if(pdev->vendor == PCI_VENDOR_ID_INTEL) /* The megaraid3 stuff reports the id of the intel
+ part which is not remotely specific to the megaraid */
+ {
+ u16 magic;
+ /* Don't fall over the Compaq management cards using the same PCI identifier */
+ if(pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
+ pdev->subsystem_device == 0xC000)
+ return -ENODEV;
+ /* Now check the magic signature byte */
+ pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
+ if(magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
+ return -ENODEV;
+ /* Ok it is probably a megaraid */
+ }
+
+ /*
+ * The megaraid3 stuff reports the ID of the Intel part which is not
+ * remotely specific to the megaraid
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+ u16 magic;
+ /*
+ * Don't fall over the Compaq management cards using the same
+ * PCI identifier
+ */
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
+ pdev->subsystem_device == 0xC000)
+ return -ENODEV;
+ /* Now check the magic signature byte */
+ pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
+ if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
+ return -ENODEV;
+ /* Ok it is probably a megaraid */
+ }
/*
* For these vendor and device ids, signature offsets are not
static OSST_buffer *new_tape_buffer(int, int, int);
static int enlarge_buffer(OSST_buffer *, int);
static void normalize_buffer(OSST_buffer *);
-static int append_to_buffer(const char *, OSST_buffer *, int);
-static int from_buffer(OSST_buffer *, char *, int);
+static int append_to_buffer(const char __user *, OSST_buffer *, int);
+static int from_buffer(OSST_buffer *, char __user *, int);
static int osst_zero_buffer_tail(OSST_buffer *);
static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
/* Entry points to osst */
/* Write command */
-static ssize_t osst_write(struct file * filp, const char * buf, size_t count, loff_t *ppos)
+static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
{
ssize_t total, retval = 0;
ssize_t i, do_count, blks, transfer;
int write_threshold;
int doing_write = 0;
- const char * b_point;
+ const char __user * b_point;
Scsi_Request * SRpnt = NULL;
ST_mode * STm;
ST_partstat * STps;
/* Read command */
-static ssize_t osst_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
{
ssize_t total, retval = 0;
ssize_t i, transfer;
/* Move data from the user buffer to the tape buffer. Returns zero (success) or
negative error code. */
-static int append_to_buffer(const char *ubp, OSST_buffer *st_bp, int do_count)
+static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count)
{
int i, cnt, res, offset;
/* Move data from the tape buffer to the user buffer. Returns zero (success) or
negative error code. */
-static int from_buffer(OSST_buffer *st_bp, char *ubp, int do_count)
+static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count)
{
int i, cnt, res, offset;
#include <asm/irq.h>
#include <../drivers/scsi/scsi.h>
-#include <../drivers/scsi/hosts.h>
+#include <scsi/scsi_host.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
for (dev = host->host_queue; dev != NULL; dev = dev->next) {
- unsigned long arg[2], id;
- kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
- id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) +
- ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
+ unsigned long id;
+ id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
+ ((dev->channel & 0x0f) << 8) +
+ ((dev->host->host_no & 0x0f) << 12);
node = &info->node[info->ndev];
node->minor = 0;
switch (dev->type) {
* Returns:
* 0 = success, was able to issue command.
*/
+#ifdef QLA_64BIT_PTR
static int
qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
{
return status;
}
+#else /* !QLA_64BIT_PTR */
-
-#ifndef QLA_64BIT_PTR
/*
* qla1280_32bit_start_scsi
* The start SCSI is responsible for building request packets on
#define DEFAULT_LOOP_COUNT 1000000000
+#define ISP_TIMEOUT (2*HZ)
/* End Configuration section ************************************************ */
#include <linux/module.h>
cmd->control_flags = cpu_to_le16(CFLAG_READ);
if (Cmnd->device->tagged_supported) {
- if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * SCSI_TIMEOUT)) {
+ if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * ISP_TIMEOUT)) {
cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG);
hostdata->tag_ages[Cmnd->device->id] = jiffies;
} else
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_host.h>
+
+
#define MAX_TARGETS 16
#define MAX_LUNS 8 /* 32 for 1.31 F/W */
#ifndef _QLOGICPTI_H
#define _QLOGICPTI_H
-#include <linux/config.h>
-
-/* #include "scsi.h" */
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_request.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-
-#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
-
/* Qlogic/SBUS controller registers. */
#define SBUS_CFG1 0x006UL
#define SBUS_CTRL 0x008UL
char __opaque[QUEUE_ENTRY_LEN];
};
+struct scsi_cmnd;
+
/* Software state for the driver. */
struct qlogicpti {
/* These are the hot elements in the cache, so they come first. */
* add scatter-gather, multiple outstanding request, and other
* enhancements.
*/
+/*
+ * NOTE: this file only contains compatibility glue for old drivers. All
+ * these wrappers will be removed sooner or later. For new code please use
+ * the interfaces declared in the headers in include/scsi/
+ */
#ifndef _SCSI_H
#define _SCSI_H
#include <linux/config.h> /* for CONFIG_SCSI_LOGGING */
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_request.h>
#define FALSE 0
#endif
-#ifdef DEBUG
-#define SCSI_TIMEOUT (5*HZ)
-#else
-#define SCSI_TIMEOUT (2*HZ)
-#endif
-
struct Scsi_Host;
struct scsi_cmnd;
struct scsi_device;
struct scsi_target;
struct scatterlist;
-/*
- * Prototypes for functions in constants.c
- * Some of these used to live in constants.h
- */
-extern void print_Scsi_Cmnd(struct scsi_cmnd *);
-extern void print_command(unsigned char *);
-extern void print_sense(const char *, struct scsi_cmnd *);
-extern void print_req_sense(const char *, struct scsi_request *);
-extern void print_driverbyte(int scsiresult);
-extern void print_hostbyte(int scsiresult);
-extern void print_status(unsigned char status);
-extern int print_msg(const unsigned char *);
-extern const char *scsi_sense_key_string(unsigned char);
-extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
-
/*
* Legacy dma direction interfaces.
*
#define scsi_to_pci_dma_dir(scsi_dir) ((int)(scsi_dir))
#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir))
+/*
+ * Old names for debug prettyprinting functions.
+ */
+static inline void print_Scsi_Cmnd(struct scsi_cmnd *cmd)
+{
+ return scsi_print_command(cmd);
+}
+static inline void print_command(unsigned char *cdb)
+{
+ return __scsi_print_command(cdb);
+}
+static inline void print_sense(const char *devclass, struct scsi_cmnd *cmd)
+{
+ return scsi_print_sense(devclass, cmd);
+}
+static inline void print_req_sense(const char *devclass, struct scsi_request *req)
+{
+ return scsi_print_req_sense(devclass, req);
+}
+static inline void print_driverbyte(int scsiresult)
+{
+ return scsi_print_driverbyte(scsiresult);
+}
+static inline void print_hostbyte(int scsiresult)
+{
+ return scsi_print_hostbyte(scsiresult);
+}
+static inline void print_status(unsigned char status)
+{
+ return scsi_print_status(status);
+}
+static inline int print_msg(const unsigned char *msg)
+{
+ return scsi_print_msg(msg);
+}
+
/*
* This is the crap from the old error handling code. We have it in a special
* place so that we can more easily delete it later on.
-/*
+/*
* linux/kernel/scsi_debug.c
* vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
* Copyright (C) 1992 Eric Youngdale
* anything out of the ordinary is seen.
* ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
- * This version is more generic, simulating a variable number of disk
- * (or disk like devices) sharing a common amount of RAM
- *
+ * This version is more generic, simulating a variable number of disk
+ * (or disk like devices) sharing a common amount of RAM
+ *
*
* For documentation see http://www.torque.net/sg/sdebug25.html
*
#include "scsi_logging.h"
#include "scsi_debug.h"
-static const char * scsi_debug_version_str = "Version: 1.71 (20031007)";
+#define SCSI_DEBUG_VERSION "1.73"
+static const char * scsi_debug_version_date = "20040518";
/* Additional Sense Code (ASC) used */
#define NO_ADDED_SENSE 0x0
/* With these defaults, this driver will make 1 host with 1 target
* (id 0) containing 1 logical unit (lun 0). That is 1 device.
*/
+#define DEF_DELAY 1
#define DEF_DEV_SIZE_MB 8
#define DEF_EVERY_NTH 0
-#define DEF_DELAY 1
-#define DEF_SCSI_LEVEL 3
+#define DEF_NUM_PARTS 0
#define DEF_OPTS 0
+#define DEF_SCSI_LEVEL 3
+#define DEF_PTYPE 0
/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1
* or "peripheral device" addressing (value 0) */
#define SAM2_LUN_ADDRESS_METHOD 0
+static int scsi_debug_add_host = DEF_NUM_HOST;
+static int scsi_debug_delay = DEF_DELAY;
static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
-static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */
-static int scsi_debug_opts = DEF_OPTS;
static int scsi_debug_every_nth = DEF_EVERY_NTH;
-static int scsi_debug_cmnd_count = 0;
-static int scsi_debug_delay = DEF_DELAY;
static int scsi_debug_max_luns = DEF_MAX_LUNS;
+static int scsi_debug_num_parts = DEF_NUM_PARTS;
+static int scsi_debug_num_tgts = DEF_NUM_TGTS; /* targets per host */
+static int scsi_debug_opts = DEF_OPTS;
static int scsi_debug_scsi_level = DEF_SCSI_LEVEL;
-static int scsi_debug_add_host = DEF_NUM_HOST;
+static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */
+
+static int scsi_debug_cmnd_count = 0;
#define DEV_READONLY(TGT) (0)
#define DEV_REMOVEABLE(TGT) (0)
-#define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK);
static unsigned long sdebug_store_size; /* in bytes */
static sector_t sdebug_capacity; /* in sectors */
#define SECT_SIZE (1 << POW2_SECT_SIZE)
#define SECT_SIZE_PER(TGT) SECT_SIZE
+#define SDEBUG_MAX_PARTS 4
+
#define SDEBUG_SENSE_LEN 32
struct sdebug_dev_info {
.remove = sdebug_driver_remove,
};
-static const int check_condition_result =
+static const int check_condition_result =
(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
/* function declarations */
static int resp_mode_sense(unsigned char * cmd, int target,
unsigned char * buff, int bufflen,
struct sdebug_dev_info * devip);
-static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
+static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int num, struct sdebug_dev_info * devip);
static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int num, struct sdebug_dev_info * devip);
int bufflen, struct sdebug_dev_info * devip);
static void timer_intr_handler(unsigned long);
static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
-static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
+static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
int asc, int asq, int inbandLen);
-static int check_reset(struct scsi_cmnd * SCpnt,
+static int check_reset(struct scsi_cmnd * SCpnt,
struct sdebug_dev_info * devip);
-static int schedule_resp(struct scsi_cmnd * cmnd,
- struct sdebug_dev_info * devip,
+static int schedule_resp(struct scsi_cmnd * cmnd,
+ struct sdebug_dev_info * devip,
done_funct_t done, int scsi_result, int delta_jiff);
-static void init_all_queued(void);
+static void __init sdebug_build_parts(unsigned char * ramp);
+static void __init init_all_queued(void);
static void stop_all_queued(void);
static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
static int sdebug_add_adapter(void);
static void sdebug_remove_adapter(void);
+static void sdebug_max_tgts_luns(void);
+
static struct device pseudo_primary;
static struct bus_type pseudo_lld_bus;
if (NULL == sclp)
return NULL;
else if (sclp->page)
- return (unsigned char *)page_address(sclp->page) +
+ return (unsigned char *)page_address(sclp->page) +
sclp->offset;
else
return NULL;
bufflen = sgpnt[0].length;
/* READ and WRITE process scatterlist themselves */
}
- else
+ else
buff = (unsigned char *) SCpnt->request_buffer;
if (NULL == buff) {
buff = spare_buff; /* assume cmd moves no data */
}
if (SCpnt->device->lun >= scsi_debug_max_luns)
- return schedule_resp(SCpnt, NULL, done,
+ return schedule_resp(SCpnt, NULL, done,
DID_NO_CONNECT << 16, 0);
devip = devInfoReg(SCpnt->device);
if (NULL == devip)
- return schedule_resp(SCpnt, NULL, done,
+ return schedule_resp(SCpnt, NULL, done,
DID_NO_CONNECT << 16, 0);
if ((scsi_debug_every_nth > 0) &&
* shouldn't need to call REQUEST_SENSE */
if (devip) {
sbuff = devip->sense_buff;
- memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ?
+ memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ?
bufflen : SDEBUG_SENSE_LEN);
mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0, 7);
} else {
break;
upper_blk = 0;
if ((*cmd) == READ_16) {
- upper_blk = cmd[5] + (cmd[4] << 8) +
+ upper_blk = cmd[5] + (cmd[4] << 8) +
(cmd[3] << 16) + (cmd[2] << 24);
- block = cmd[9] + (cmd[8] << 8) +
+ block = cmd[9] + (cmd[8] << 8) +
(cmd[7] << 16) + (cmd[6] << 24);
- num = cmd[13] + (cmd[12] << 8) +
+ num = cmd[13] + (cmd[12] << 8) +
(cmd[11] << 16) + (cmd[10] << 24);
} else if ((*cmd) == READ_12) {
- block = cmd[5] + (cmd[4] << 8) +
+ block = cmd[5] + (cmd[4] << 8) +
(cmd[3] << 16) + (cmd[2] << 24);
- num = cmd[9] + (cmd[8] << 8) +
+ num = cmd[9] + (cmd[8] << 8) +
(cmd[7] << 16) + (cmd[6] << 24);
} else if ((*cmd) == READ_10) {
- block = cmd[5] + (cmd[4] << 8) +
+ block = cmd[5] + (cmd[4] << 8) +
(cmd[3] << 16) + (cmd[2] << 24);
num = cmd[8] + (cmd[7] << 8);
} else {
- block = cmd[3] + (cmd[2] << 8) +
+ block = cmd[3] + (cmd[2] << 8) +
((cmd[1] & 0x1f) << 16);
num = cmd[4];
}
errsts = resp_read(SCpnt, upper_blk, block, num, devip);
if (inj_recovered && (0 == errsts)) {
- mk_sense_buffer(devip, RECOVERED_ERROR,
+ mk_sense_buffer(devip, RECOVERED_ERROR,
THRESHHOLD_EXCEEDED, 0, 18);
errsts = check_condition_result;
}
break;
upper_blk = 0;
if ((*cmd) == WRITE_16) {
- upper_blk = cmd[5] + (cmd[4] << 8) +
+ upper_blk = cmd[5] + (cmd[4] << 8) +
(cmd[3] << 16) + (cmd[2] << 24);
- block = cmd[9] + (cmd[8] << 8) +
+ block = cmd[9] + (cmd[8] << 8) +
(cmd[7] << 16) + (cmd[6] << 24);
- num = cmd[13] + (cmd[12] << 8) +
+ num = cmd[13] + (cmd[12] << 8) +
(cmd[11] << 16) + (cmd[10] << 24);
} else if ((*cmd) == WRITE_12) {
- block = cmd[5] + (cmd[4] << 8) +
+ block = cmd[5] + (cmd[4] << 8) +
(cmd[3] << 16) + (cmd[2] << 24);
- num = cmd[9] + (cmd[8] << 8) +
+ num = cmd[9] + (cmd[8] << 8) +
(cmd[7] << 16) + (cmd[6] << 24);
} else if ((*cmd) == WRITE_10) {
- block = cmd[5] + (cmd[4] << 8) +
+ block = cmd[5] + (cmd[4] << 8) +
(cmd[3] << 16) + (cmd[2] << 24);
num = cmd[8] + (cmd[7] << 8);
} else {
- block = cmd[3] + (cmd[2] << 8) +
+ block = cmd[3] + (cmd[2] << 8) +
((cmd[1] & 0x1f) << 16);
num = cmd[4];
}
errsts = resp_write(SCpnt, upper_blk, block, num, devip);
if (inj_recovered && (0 == errsts)) {
- mk_sense_buffer(devip, RECOVERED_ERROR,
+ mk_sense_buffer(devip, RECOVERED_ERROR,
THRESHHOLD_EXCEEDED, 0, 18);
errsts = check_condition_result;
}
static const char * product_id = "scsi_debug ";
static const char * product_rev = "0004";
-static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
+static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
const char * dev_id_str, int dev_id_str_len)
{
int num;
{
unsigned char pq_pdt;
unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
- int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ?
+ int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ?
SDEBUG_MAX_INQ_ARR_SZ : bufflen;
if (bufflen < cmd[4])
"< alloc_length=%d\n", bufflen, (int)cmd[4]);
memset(buff, 0, bufflen);
memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
- pq_pdt = PERIPH_DEVICE_TYPE(target);
+ pq_pdt = (scsi_debug_ptype & 0x1f);
arr[0] = pq_pdt;
if (0x2 & cmd[1]) { /* CMDDT bit set */
mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
dev_id_str, len);
} else {
/* Illegal request, invalid field in cdb */
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(devip, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0, 18);
return check_condition_result;
}
- memcpy(buff, arr, min_len);
+ memcpy(buff, arr, min_len);
return 0;
}
/* drops through here for a standard inquiry */
return 0;
}
-/* <<Following mode page info copied from ST318451LW>> */
+/* <<Following mode page info copied from ST318451LW>> */
static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target)
{ /* Read-Write Error Recovery page for mode_sense */
- unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
+ unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0,
5, 0, 0xff, 0xff};
memcpy(p, err_recov_pg, sizeof(err_recov_pg));
static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target)
{ /* Disconnect-Reconnect page for mode_sense */
- unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
+ unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
memcpy(p, disconnect_pg, sizeof(disconnect_pg));
static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
{ /* Caching page for mode_sense */
- unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
+ unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
memcpy(p, caching_pg, sizeof(caching_pg));
int alloc_len, msense_6, offset, len;
unsigned char * ap;
unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
- int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ?
+ int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ?
SDEBUG_MAX_MSENSE_SZ : bufflen;
SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen));
arr[0] = offset - 1;
else {
offset -= 2;
- arr[0] = (offset >> 8) & 0xff;
- arr[1] = offset & 0xff;
+ arr[0] = (offset >> 8) & 0xff;
+ arr[1] = offset & 0xff;
}
memcpy(buff, arr, min_len);
return 0;
}
-static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
+static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int num, struct sdebug_dev_info * devip)
{
unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
unsigned long iflags;
if (upper_blk || (block + num > sdebug_capacity)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
+ mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
0, 18);
return check_condition_result;
}
if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
- (block <= OPT_MEDIUM_ERR_ADDR) &&
+ (block <= OPT_MEDIUM_ERR_ADDR) &&
((block + num) > OPT_MEDIUM_ERR_ADDR)) {
- mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
+ mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
0, 18);
/* claim unrecoverable read error */
return check_condition_result;
read_lock_irqsave(&atomic_rw, iflags);
sgcount = 0;
nbytes = bufflen;
- /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n",
+ /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n",
block, bufflen); */
if (SCpnt->use_sg) {
sgcount = 0;
static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
int bufflen, struct sdebug_dev_info * devip)
{
- unsigned int alloc_len;
+ unsigned int alloc_len;
int lun_cnt, i, upper;
int select_report = (int)cmd[2];
struct scsi_lun *one_lun;
0, 18);
return check_condition_result;
}
- if (bufflen > 8) { /* can produce response with up to 16k luns
+ if (bufflen > 8) { /* can produce response with up to 16k luns
(lun 0 to lun 16383) */
memset(buff, 0, bufflen);
lun_cnt = scsi_debug_max_luns;
buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
- lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)),
+ lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)),
lun_cnt);
one_lun = (struct scsi_lun *) &buff[8];
for (i = 0; i < lun_cnt; i++) {
upper = (i >> 8) & 0x3f;
if (upper)
- one_lun[i].scsi_lun[0] =
+ one_lun[i].scsi_lun[0] =
(upper | (SAM2_LUN_ADDRESS_METHOD << 6));
one_lun[i].scsi_lun[1] = i & 0xff;
}
static int scsi_debug_slave_configure(struct scsi_device * sdp)
{
- struct sdebug_dev_info * devip;
+ struct sdebug_dev_info * devip;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
devip = devInfoReg(sdp);
sdp->hostdata = devip;
if (sdp->host->cmd_per_lun)
- scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
+ scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
sdp->host->cmd_per_lun);
return 0;
}
static void scsi_debug_slave_destroy(struct scsi_device * sdp)
{
- struct sdebug_dev_info * devip =
+ struct sdebug_dev_info * devip =
(struct sdebug_dev_info *)sdp->hostdata;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
open_devip = devip;
}
}
+ if (NULL == open_devip) { /* try and make a new one */
+ open_devip = kmalloc(sizeof(*open_devip),GFP_KERNEL);
+ if (NULL == open_devip) {
+ printk(KERN_ERR "%s: out of memory at line %d\n",
+ __FUNCTION__, __LINE__);
+ return NULL;
+ }
+ memset(open_devip, 0, sizeof(*open_devip));
+ open_devip->sdbg_host = sdbg_host;
+ list_add_tail(&open_devip->dev_list,
+ &sdbg_host->dev_info_list);
+ }
if (open_devip) {
open_devip->channel = sdev->channel;
open_devip->target = sdev->id;
return NULL;
}
-static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
+static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
int asc, int asq, int inbandLen)
{
unsigned char * sbuff;
printk(KERN_INFO "scsi_debug: biosparam\n");
buf = scsi_bios_ptable(bdev);
if (buf) {
- res = scsi_partsize(buf, capacity,
+ res = scsi_partsize(buf, capacity,
&info[2], &info[0], &info[1]);
kfree(buf);
if (! res)
}
/* Initializes timers in queued array */
-static void init_all_queued(void)
+static void __init init_all_queued(void)
{
unsigned long iflags;
int k;
spin_unlock_irqrestore(&queued_arr_lock, iflags);
}
-static int schedule_resp(struct scsi_cmnd * cmnd,
+static void __init sdebug_build_parts(unsigned char * ramp)
+{
+ struct partition * pp;
+ int starts[SDEBUG_MAX_PARTS + 2];
+ int sectors_per_part, num_sectors, k;
+ int heads_by_sects, start_sec, end_sec;
+
+ /* assume partition table already zeroed */
+ if ((scsi_debug_num_parts < 1) || (sdebug_store_size < 1048576))
+ return;
+ if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) {
+ scsi_debug_num_parts = SDEBUG_MAX_PARTS;
+ printk(KERN_WARNING "scsi_debug:build_parts: reducing "
+ "partitions to %d\n", SDEBUG_MAX_PARTS);
+ }
+ num_sectors = (int)(sdebug_store_size / SECT_SIZE);
+ sectors_per_part = (num_sectors - sdebug_sectors_per)
+ / scsi_debug_num_parts;
+ heads_by_sects = sdebug_heads * sdebug_sectors_per;
+ starts[0] = sdebug_sectors_per;
+ for (k = 1; k < scsi_debug_num_parts; ++k)
+ starts[k] = ((k * sectors_per_part) / heads_by_sects)
+ * heads_by_sects;
+ starts[scsi_debug_num_parts] = num_sectors;
+ starts[scsi_debug_num_parts + 1] = 0;
+
+ ramp[510] = 0x55; /* magic partition markings */
+ ramp[511] = 0xAA;
+ pp = (struct partition *)(ramp + 0x1be);
+ for (k = 0; starts[k + 1]; ++k, ++pp) {
+ start_sec = starts[k];
+ end_sec = starts[k + 1] - 1;
+ pp->boot_ind = 0;
+
+ pp->cyl = start_sec / heads_by_sects;
+ pp->head = (start_sec - (pp->cyl * heads_by_sects))
+ / sdebug_sectors_per;
+ pp->sector = (start_sec % sdebug_sectors_per) + 1;
+
+ pp->end_cyl = end_sec / heads_by_sects;
+ pp->end_head = (end_sec - (pp->end_cyl * heads_by_sects))
+ / sdebug_sectors_per;
+ pp->end_sector = (end_sec % sdebug_sectors_per) + 1;
+
+ pp->start_sect = start_sec;
+ pp->nr_sects = end_sec - start_sec + 1;
+ pp->sys_ind = 0x83; /* plain Linux partition */
+ }
+}
+
+static int schedule_resp(struct scsi_cmnd * cmnd,
struct sdebug_dev_info * devip,
done_funct_t done, int scsi_result, int delta_jiff)
{
- int k, num;
+ int k, num;
if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmnd) {
printk(KERN_INFO "scsi_debug: cmd ");
if (cmnd && devip) {
/* simulate autosense by this driver */
if (SAM_STAT_CHECK_CONDITION == (scsi_result & 0xff))
- memcpy(cmnd->sense_buffer, devip->sense_buff,
+ memcpy(cmnd->sense_buffer, devip->sense_buff,
(SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ?
SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE);
}
/* Set 'perm' (4th argument) to 0 to disable module_param's definition
* of sysfs parameters (which module_param doesn't yet support).
- * Sysfs parameters defined explicitly below.
+ * Sysfs parameters defined explicitly below.
*/
-module_param_named(num_tgts, scsi_debug_num_tgts, int, 0);
-module_param_named(max_luns, scsi_debug_max_luns, int, 0);
-module_param_named(scsi_level, scsi_debug_scsi_level, int, 0);
+module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */
+module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */
module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0);
-module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */
module_param_named(every_nth, scsi_debug_every_nth, int, 0);
-module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */
-module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */
+module_param_named(max_luns, scsi_debug_max_luns, int, 0);
+module_param_named(num_parts, scsi_debug_num_parts, int, 0);
+module_param_named(num_tgts, scsi_debug_num_tgts, int, 0);
+module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */
+module_param_named(ptype, scsi_debug_ptype, int, 0);
+module_param_named(scsi_level, scsi_debug_scsi_level, int, 0);
MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert");
MODULE_DESCRIPTION("SCSI debug adapter driver");
MODULE_LICENSE("GPL");
+MODULE_VERSION(SCSI_DEBUG_VERSION);
-MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate");
-MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate");
-MODULE_PARM_DESC(scsi_level, "SCSI level to simulate");
+MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)");
+MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs");
-MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->...");
MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)");
-MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
-MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)");
+MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate");
+MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
+MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate");
+MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->...");
+MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
+MODULE_PARM_DESC(scsi_level, "SCSI level to simulate");
static char sdebug_info[256];
static const char * scsi_debug_info(struct Scsi_Host * shp)
{
- sprintf(sdebug_info, "scsi_debug, %s, num_tgts=%d, "
- "dev_size_mb=%d, opts=0x%x", scsi_debug_version_str,
- scsi_debug_num_tgts, scsi_debug_dev_size_mb,
+ sprintf(sdebug_info, "scsi_debug, version %s [%s], "
+ "dev_size_mb=%d, opts=0x%x", SCSI_DEBUG_VERSION,
+ scsi_debug_version_date, scsi_debug_dev_size_mb,
scsi_debug_opts);
return sdebug_info;
}
return length;
}
begin = 0;
- pos = len = sprintf(buffer, "scsi_debug adapter driver, %s\n"
+ pos = len = sprintf(buffer, "scsi_debug adapter driver, version "
+ "%s [%s]\n"
"num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, "
"every_nth=%d(curr:%d)\n"
"delay=%d, max_luns=%d, scsi_level=%d\n"
"sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
- "number of aborts=%d, device_reset=%d, bus_resets=%d, "
+ "number of aborts=%d, device_reset=%d, bus_resets=%d, "
"host_resets=%d\n",
- scsi_debug_version_str, scsi_debug_num_tgts,
+ SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts,
scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
scsi_debug_cmnd_count, scsi_debug_delay,
scsi_debug_max_luns, scsi_debug_scsi_level,
return len;
}
-static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_delay_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay);
}
-static ssize_t sdebug_delay_store(struct device_driver * ddp,
+static ssize_t sdebug_delay_store(struct device_driver * ddp,
const char * buf, size_t count)
{
int delay;
}
return -EINVAL;
}
-DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
+DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
sdebug_delay_store)
-static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts);
}
-static ssize_t sdebug_opts_store(struct device_driver * ddp,
+static ssize_t sdebug_opts_store(struct device_driver * ddp,
const char * buf, size_t count)
{
int opts;
scsi_debug_cmnd_count = 0;
return count;
}
-DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
+DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
sdebug_opts_store)
-static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ptype);
+}
+static ssize_t sdebug_ptype_store(struct device_driver * ddp,
+ const char * buf, size_t count)
+{
+ int n;
+
+ if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
+ scsi_debug_ptype = n;
+ return count;
+ }
+ return -EINVAL;
+}
+DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store)
+
+static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts);
}
-static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
+static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
const char * buf, size_t count)
{
int n;
if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
scsi_debug_num_tgts = n;
+ sdebug_max_tgts_luns();
return count;
}
return -EINVAL;
}
-DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
- sdebug_num_tgts_store)
+DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
+ sdebug_num_tgts_store)
-static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb);
}
-DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL)
+DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL)
+
+static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts);
+}
+DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL)
-static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_every_nth);
}
-static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
+static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
const char * buf, size_t count)
{
int nth;
return -EINVAL;
}
DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show,
- sdebug_every_nth_store)
+ sdebug_every_nth_store)
-static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_luns);
}
-static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
+static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
const char * buf, size_t count)
{
int n;
if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
scsi_debug_max_luns = n;
+ sdebug_max_tgts_luns();
return count;
}
return -EINVAL;
}
-DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
- sdebug_max_luns_store)
+DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
+ sdebug_max_luns_store)
-static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level);
}
-DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL)
+DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL)
-static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
+static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host);
}
-static ssize_t sdebug_add_host_store(struct device_driver * ddp,
+static ssize_t sdebug_add_host_store(struct device_driver * ddp,
const char * buf, size_t count)
{
int delta_hosts;
DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
sdebug_add_host_store)
-static void do_create_driverfs_files()
+static void do_create_driverfs_files(void)
{
+ driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay);
- driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
- driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
+ driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
+ driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
+ driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+ driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts);
driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
- driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host);
}
-static void do_remove_driverfs_files()
+static void do_remove_driverfs_files(void)
{
- driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_scsi_level);
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_ptype);
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_parts);
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_max_luns);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_every_nth);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb);
- driver_remove_file(&sdebug_driverfs_driver, &driver_attr_num_tgts);
- driver_remove_file(&sdebug_driverfs_driver, &driver_attr_opts);
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
+ driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host);
}
static int __init scsi_debug_init(void)
int host_to_add;
int k;
+ if (scsi_debug_dev_size_mb < 1)
+ scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */
sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576;
sdebug_capacity = sdebug_store_size / SECT_SIZE;
/* play around with geometry, don't waste too much on track 0 */
sdebug_heads = 8;
sdebug_sectors_per = 32;
- if (scsi_debug_dev_size_mb >= 16)
+ if (scsi_debug_dev_size_mb >= 16)
sdebug_heads = 32;
else if (scsi_debug_dev_size_mb >= 256)
sdebug_heads = 64;
- sdebug_cylinders_per = (unsigned long)sdebug_capacity /
+ sdebug_cylinders_per = (unsigned long)sdebug_capacity /
(sdebug_sectors_per * sdebug_heads);
- if (sdebug_cylinders_per >= 1024) {
+ if (sdebug_cylinders_per >= 1024) {
/* other LLDs do this; implies >= 1GB ram disk ... */
sdebug_heads = 255;
sdebug_sectors_per = 63;
- sdebug_cylinders_per = (unsigned long)sdebug_capacity /
+ sdebug_cylinders_per = (unsigned long)sdebug_capacity /
(sdebug_sectors_per * sdebug_heads);
}
return -ENOMEM;
}
memset(fake_storep, 0, sz);
+ if (scsi_debug_num_parts > 0)
+ sdebug_build_parts(fake_storep);
init_all_queued();
.release = pseudo_0_release,
};
-static int pseudo_lld_bus_match(struct device *dev,
+static int pseudo_lld_bus_match(struct device *dev,
struct device_driver *dev_driver)
{
return 1;
kfree(sdbg_host);
}
-static int sdebug_add_adapter()
+static int sdebug_add_adapter(void)
{
int k, devs_per_host;
int error = 0;
return error;
}
-static void sdebug_remove_adapter()
+static void sdebug_remove_adapter(void)
{
struct sdebug_host_info * sdbg_host = NULL;
scsi_host_put(sdbg_host->shost);
return 0;
}
+
+static void sdebug_max_tgts_luns(void)
+{
+ struct sdebug_host_info * sdbg_host;
+ struct Scsi_Host *hpnt;
+
+ spin_lock(&sdebug_host_list_lock);
+ list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
+ hpnt = sdbg_host->shost;
+ if ((hpnt->this_id >= 0) &&
+ (scsi_debug_num_tgts > hpnt->this_id))
+ hpnt->max_id = scsi_debug_num_tgts + 1;
+ else
+ hpnt->max_id = scsi_debug_num_tgts;
+ hpnt->max_lun = scsi_debug_max_luns;
+ }
+ spin_unlock(&sdebug_host_list_lock);
+}
static int scsi_debug_slave_alloc(struct scsi_device *);
static int scsi_debug_slave_configure(struct scsi_device *);
static void scsi_debug_slave_destroy(struct scsi_device *);
-static int scsi_debug_queuecommand(struct scsi_cmnd *,
+static int scsi_debug_queuecommand(struct scsi_cmnd *,
void (*done) (struct scsi_cmnd *));
static int scsi_debug_ioctl(struct scsi_device *, int, void *);
static int scsi_debug_biosparam(struct scsi_device *, struct block_device *,
static int scsi_debug_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static const char * scsi_debug_info(struct Scsi_Host *);
-/*
- * This driver is written for the lk 2.5 series
- */
#define SCSI_DEBUG_CANQUEUE 255 /* needs to be >= 1 */
#define SCSI_DEBUG_MAX_CMD_LEN 16
static const char spaces[] = " "; /* 16 of them */
static unsigned scsi_default_dev_flags;
static LIST_HEAD(scsi_dev_info_list);
-static __init char scsi_dev_flags[256];
+static __initdata char scsi_dev_flags[256];
/*
* scsi_static_device_list: deprecated list of devices that require
{"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN},
{"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN},
{"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN},
- {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_SPARSELUN},
+ {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN},
{"CANON", "IPUBJD", NULL, BLIST_SPARSELUN},
{"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN},
{"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */
{"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN},
{"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
{"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN},
- {"Generic", "USB Storage-SMC", "0090", BLIST_FORCELUN},
{"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN},
{"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN},
{"HITACHI", "DF400", "*", BLIST_SPARSELUN},
{"HP", "C1557A", NULL, BLIST_FORCELUN},
{"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
- {"ICSI", "SD Card", "2.7C", BLIST_FORCELUN},
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
{"IOMEGA", "Io20S *F", NULL, BLIST_KEY},
{"INSITE", "Floptical F*8I", NULL, BLIST_KEY},
#include "scsi_priv.h"
#include "scsi_logging.h"
-#ifdef DEBUG
-#define SENSE_TIMEOUT SCSI_TIMEOUT
-#else
-#define SENSE_TIMEOUT (10*HZ)
-#endif
-
-#define START_UNIT_TIMEOUT (30*HZ)
+#define SENSE_TIMEOUT (10*HZ)
+#define START_UNIT_TIMEOUT (30*HZ)
/*
* These should *probably* be handled by the host itself.
* Since it is allowed to sleep, it probably should.
*/
-#define BUS_RESET_SETTLE_TIME 10*HZ
-#define HOST_RESET_SETTLE_TIME 10*HZ
+#define BUS_RESET_SETTLE_TIME (10*HZ)
+#define HOST_RESET_SETTLE_TIME (10*HZ)
/* called with shost->host_lock held */
void scsi_eh_wakeup(struct Scsi_Host *shost)
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
if (rtn == SUCCESS) {
- scsi_sleep(BUS_RESET_SETTLE_TIME);
+ if (!scmd->device->host->hostt->skip_settle_delay)
+ scsi_sleep(BUS_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
if (rtn == SUCCESS) {
- scsi_sleep(HOST_RESET_SETTLE_TIME);
+ if (!scmd->device->host->hostt->skip_settle_delay)
+ scsi_sleep(HOST_RESET_SETTLE_TIME);
spin_lock_irqsave(scmd->device->host->host_lock, flags);
scsi_report_bus_reset(scmd->device->host, scmd->device->channel);
spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
}
return -EINVAL;
}
-
-/*
- * Just like scsi_ioctl, only callable from kernel space with no
- * fs segment fiddling.
- */
-
-int kernel_scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
-{
- mm_segment_t oldfs;
- int tmp;
- oldfs = get_fs();
- set_fs(get_ds());
- tmp = scsi_ioctl(sdev, cmd, arg);
- set_fs(oldfs);
- return tmp;
-}
sreq->sr_request->rq_status = RQ_SCSI_BUSY;
scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done,
timeout, retries);
- generic_unplug_device(sreq->sr_device->request_queue);
wait_for_completion(&wait);
sreq->sr_request->waiting = NULL;
if (sreq->sr_request->rq_status != RQ_SCSI_DONE)
#define ALLOC_FAILURE_MSG KERN_ERR "%s: Allocation failure during" \
" SCSI scanning, some SCSI devices might not be configured\n"
+/*
+ * Default timeout
+ */
+#define SCSI_TIMEOUT (2*HZ)
+
/*
* Prefix values for the SCSI id's (stored in driverfs name field)
*/
EXPORT_SYMBOL(scsi_partsize);
EXPORT_SYMBOL(scsi_bios_ptable);
EXPORT_SYMBOL(scsi_ioctl);
-EXPORT_SYMBOL(print_command);
-EXPORT_SYMBOL(print_sense);
-EXPORT_SYMBOL(print_req_sense);
-EXPORT_SYMBOL(print_msg);
-EXPORT_SYMBOL(print_status);
+EXPORT_SYMBOL(scsi_print_command);
+EXPORT_SYMBOL(__scsi_print_command);
+EXPORT_SYMBOL(scsi_print_sense);
+EXPORT_SYMBOL(scsi_print_req_sense);
+EXPORT_SYMBOL(scsi_print_msg);
+EXPORT_SYMBOL(scsi_print_status);
EXPORT_SYMBOL(scsi_sense_key_string);
EXPORT_SYMBOL(scsi_extd_sense_format);
-EXPORT_SYMBOL(kernel_scsi_ioctl);
-EXPORT_SYMBOL(print_Scsi_Cmnd);
EXPORT_SYMBOL(scsi_block_when_processing_errors);
EXPORT_SYMBOL(scsi_ioctl_send_command);
EXPORT_SYMBOL(scsi_set_medium_removal);
spi_dv_device(sdev);
return count;
}
-static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate)
+static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
/* Translate the period into ns according to the current spec
* for SDTR/PPR messages */
{
struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
struct scsi_device *sdev = sreq->sr_device;
- int period, prevperiod = 0;
+ int period = 0, prevperiod = 0;
for (;;) {
+ int newperiod;
if (compare_fn(sreq, buffer, ptr, DV_LOOPS))
/* Successful DV */
break;
/* OK, retrain, fallback */
if (i->f->get_period)
i->f->get_period(sdev);
- period = spi_period(sdev);
+ newperiod = spi_period(sdev);
+ period = newperiod > period ? newperiod : period;
if (period < 0x0d)
period++;
else
pDCB->TagMask &= ~(1 << pSRB->TagNumber); /* free tag mask */
pSRB->TagNumber = 255;
}
-};
+}
static UCHAR
printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN);
return 1;
//goto no_tag;
- };
+ }
DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
DC390_write8 (ScsiFifo, tag_no);
{
// no_tag:
DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB));
- };
+ }
pSRB->SRBState = SRB_START_;
//pSRB->SRBState = SRB_MSGOUT_;
pSRB->SRBState |= DO_SYNC_NEGO;
cmd = SEL_W_ATN_STOP;
- };
+ }
/* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
if (cmd != SEL_W_ATN_STOP)
ptr = (PUCHAR) pSRB->pcmd->cmnd;
for (i=0; i<pSRB->pcmd->cmd_len; i++)
DC390_write8 (ScsiFifo, *(ptr++));
- };
+ }
}
DEBUG0(if (pACB->pActiveDCB) \
printk (KERN_WARNING "DC390: ActiveDCB != 0\n"));
//DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
pACB->SelLost++;
return 1;
- };
+ }
DC390_write8 (ScsiCmd, cmd);
pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB;
pACB->Connected = 1;
{
printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
return dstate;
- };
+ }
if (dstate & DMA_XFER_DONE)
{
UINT residual, xferCnt; int ctr = 6000000;
{
DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
return IRQ_NONE;
- };
+ }
#else
//DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
//dstatus = DC390_read8 (DMA_Status);
{
printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
goto unlock;
- };
+ }
pSRB = pDCB->pActiveSRB;
if( pDCB->DCBFlag & ABORT_DEV_ )
dc390_EnableMsgOut_Abort (pACB, pSRB);
DC390_write8 (CtrlReg3, pDCB->CtrlR3);
DC390_write8 (CtrlReg4, pDCB->CtrlR4);
dc390_SetXferRate (pACB, pDCB);
-};
+}
#ifdef DC390_DEBUG0
for (i = 1; i < len; i++)
printk (" %02x", MsgBuf[i]);
printk ("\n");
-};
+}
#endif
#define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
{
printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
- };
+ }
memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
pSRB->MsgCnt = 5;
DC390_ENABLE_MSGOUT;
- };
+ }
pSRB->SRBState &= ~DO_SYNC_NEGO;
pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
}
dc390_reprog (pACB, pDCB);
-};
+}
/* handle RESTORE_PTR */
}
pSRB->TotalXferredLen = pSRB->Saved_Ptr;
-};
+}
/* According to the docs, the AM53C974 reads the message and
/* read and eval received messages */
-void
+static void
dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
PDCB pDCB = pACB->pActiveDCB;
dc390_MsgIn_set_async (pACB, pSRB);
else
dc390_MsgIn_set_sync (pACB, pSRB);
- };
+ }
// nothing has to be done
case COMMAND_COMPLETE: break;
dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
}
-void
+static void
dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
PDCB pDCB;
//DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
}
-void
+static void
dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
UCHAR bval, i, cnt;
}
-void
+static void
dc390_Disconnect( PACB pACB )
{
PDCB pDCB;
}
-void
+static void
dc390_Reselect( PACB pACB )
{
PDCB pDCB;
DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",\
pDCB->TargetID, pDCB->TargetLUN, (int)pDCB, pDCB->GoingSRBCnt));
return;
- };
+ }
pACB->DCBmap[pDCB->TargetID] &= ~(1 << pDCB->TargetLUN);
// The first one
if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB;
kfree (pDCB);
pACB->DCBCnt--;
- /* pACB->DeviceCnt--; */
-};
+}
static UCHAR __inline__
if (memcmp (name, dc390_baddevname1[i], 28) == 0)
return 1;
return 0;
-};
+}
static void
else
pDCB->MaxCommand = 1;
}
-};
+}
static void
pDCB->DevType = bval1;
/* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
dc390_disc_tagq_set (pDCB, ptr);
-};
+}
-void
+static void
dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
{
- UCHAR bval, status, i, DCB_removed;
+ UCHAR bval, status, i;
PSCSICMD pcmd;
PSCSI_INQDATA ptr;
PSGL ptr2;
/* KG: Moved pci_unmap here */
dc390_pci_unmap(pSRB);
- DCB_removed = 0;
status = pSRB->TargetStatus;
ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
if( pcmd->use_sg )
- ptr = (PSCSI_INQDATA) sg_dma_address((PSGL) ptr);
+ ptr = (PSCSI_INQDATA) (page_address(((PSGL) ptr)->page) + ((PSGL) ptr)->offset);
DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
pSRB, pcmd->pid));
pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
else printk ("\n");
#endif
- if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) ||
- ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
- (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )
- {
- /* device not present: remove */
- //dc390_Going_remove (pDCB, pSRB);
- dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
-
- if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
- ((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) )
- pACB->scan_devices = 0;
- }
- else
- {
- /* device present: add */
- if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
- (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
- pACB->scan_devices = END_SCAN ;
- /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
- }
}
}
-
- //if( pSRB->pcmd->cmnd[0] == INQUIRY &&
- // (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
+
if( pcmd->cmnd[0] == INQUIRY &&
(pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
{
- if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)
- {
- //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);
- /* device not present: remove */
- //dc390_Going_remove (pDCB, pSRB);
- dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
- }
- else
+ if ((ptr->DevType & SCSI_DEVTYPE) != TYPE_NODEV)
{
/* device found: add */
dc390_add_dev (pACB, pDCB, ptr);
- if (pACB->scan_devices) pACB->DeviceCnt++;
}
- if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
- (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
- pACB->scan_devices = 0;
- };
+ }
pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
- if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);
+ dc390_Going_remove (pDCB, pSRB);
/* Add to free list */
dc390_Free_insert (pACB, pSRB);
/* Remove all SRBs from Going list and inform midlevel */
-void
+static void
dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
{
PDCB pDCB, pdcb;
if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
}
-
good_bytes = 0;
break;
- case RECOVERED_ERROR:
+ case RECOVERED_ERROR: /* an error occurred, but it recovered */
+ case NO_SENSE: /* LLDD got sense data */
/*
- * An error occurred, but it recovered. Inform the
- * user, but make sure that it's not treated as a
- * hard error.
+ * Inform the user, but make sure that it's not treated
+ * as a hard error.
*/
print_sense("sd", SCpnt);
SCpnt->result = 0;
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/devfs_fs_kernel.h>
#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
-static char *sg_version_date = "20040513";
+static char *sg_version_date = "20040516";
static int sg_proc_init(void);
static void sg_proc_cleanup(void);
#define SG_ALLOW_DIO_DEF 0
#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
-#define SG_MAX_DEVS 8192
+#define SG_MAX_DEVS 32768
/*
* Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
(void *) SRpnt->sr_buffer, hp->dxfer_len,
sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
/* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
- generic_unplug_device(q);
return 0;
}
void *old_sg_dev_arr = NULL;
int k, error;
- sdp = vmalloc(sizeof(Sg_device));
- if (!sdp)
+ sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL);
+ if (!sdp) {
+ printk(KERN_WARNING "kmalloc Sg_device failure\n");
return -ENOMEM;
+ }
write_lock_irqsave(&sg_dev_arr_lock, iflags);
if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */
int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- tmp_da = vmalloc(tmp_dev_max * sizeof(Sg_device *));
+ tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL);
if (unlikely(!tmp_da))
goto expand_failed;
out:
if (error < 0)
- vfree(sdp);
- vfree(old_sg_dev_arr);
+ kfree(sdp);
+ kfree(old_sg_dev_arr);
return error;
expand_failed:
- printk(KERN_ERR "sg_alloc: device array cannot be resized\n");
+ printk(KERN_WARNING "sg_alloc: device array cannot be resized\n");
error = -ENOMEM;
goto out;
int error, k;
disk = alloc_disk(1);
- if (!disk)
+ if (!disk) {
+ printk(KERN_WARNING "alloc_disk failed\n");
return -ENOMEM;
+ }
disk->major = SCSI_GENERIC_MAJOR;
error = -ENOMEM;
cdev = cdev_alloc();
- if (!cdev)
+ if (!cdev) {
+ printk(KERN_WARNING "cdev_alloc failed\n");
goto out;
+ }
cdev->owner = THIS_MODULE;
cdev->ops = &sg_fops;
error = sg_alloc(disk, scsidp);
- if (error < 0)
+ if (error < 0) {
+ printk(KERN_WARNING "sg_alloc failed\n");
goto out;
+ }
k = error;
sdp = sg_dev_arr[k];
put_disk(sdp->disk);
sdp->disk = NULL;
if (NULL == sdp->headfp)
- vfree((char *) sdp);
+ kfree((char *) sdp);
}
if (delay)
unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
SG_MAX_DEVS);
if (sg_dev_arr != NULL) {
- vfree((char *) sg_dev_arr);
+ kfree((char *) sg_dev_arr);
sg_dev_arr = NULL;
}
sg_dev_max = 0;
}
if (k < maxd)
sg_dev_arr[k] = NULL;
- vfree((char *) sdp);
+ kfree((char *) sdp);
res = 1;
}
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
#include <linux/mca.h>
#include <linux/eisa.h>
#include <linux/interrupt.h>
-
-#include "scsi.h"
#include <scsi/scsi_host.h>
+
#include "53c700.h"
}
__setup("sim710=", param_setup);
-static Scsi_Host_Template sim710_driver_template = {
+static struct scsi_host_template sim710_driver_template = {
.name = "LSI (Symbios) 710 MCA/EISA",
.proc_name = "sim710",
.this_id = 7,
static void get_capabilities(struct scsi_cd *cd)
{
unsigned char *buffer;
- int rc, n, mrw_write = 0, mrw = 1,ram_write=0;
struct scsi_mode_data data;
struct scsi_request *SRpnt;
unsigned char cmd[MAX_COMMAND_SIZE];
unsigned int the_result;
- int retries;
+ int retries, rc, n;
static char *loadmech[] =
{
return;
}
- if (cdrom_is_mrw(&cd->cdi, &mrw_write)) {
- mrw = 0;
- cd->cdi.mask |= CDC_MRW;
- cd->cdi.mask |= CDC_MRW_W;
- }
- if (!mrw_write)
- cd->cdi.mask |= CDC_MRW_W;
-
- if (cdrom_is_random_writable(&cd->cdi, &ram_write))
- cd->cdi.mask |= CDC_RAM;
- if (!ram_write)
- cd->cdi.mask |= CDC_RAM;
-
n = data.header_length + data.block_descriptor_length;
cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
cd->readcd_known = 1;
int result;
unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+ if (!buffer)
+ return -ENOMEM;
+
memset(&cgc, 0, sizeof(struct packet_command));
cgc.timeout = IOCTL_TIMEOUT;
static ST_buffer *new_tape_buffer(int, int, int);
static int enlarge_buffer(ST_buffer *, int, int);
static void normalize_buffer(ST_buffer *);
-static int append_to_buffer(const char *, ST_buffer *, int);
-static int from_buffer(ST_buffer *, char *, int);
+static int append_to_buffer(const char __user *, ST_buffer *, int);
+static int from_buffer(ST_buffer *, char __user *, int);
static void move_buffer_data(ST_buffer *, int);
static void buf_to_sg(ST_buffer *, unsigned int);
}
-static int setup_buffering(Scsi_Tape *STp, const char *buf, size_t count, int is_read)
+static int setup_buffering(Scsi_Tape *STp, const char __user *buf, size_t count, int is_read)
{
int i, bufsize, retval = 0;
ST_buffer *STbp = STp->buffer;
/* Write command */
static ssize_t
- st_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
+st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
{
ssize_t total;
ssize_t i, do_count, blks, transfer;
int undone, retry_eot = 0, scode;
int async_write;
unsigned char cmd[MAX_COMMAND_SIZE];
- const char *b_point;
+ const char __user *b_point;
Scsi_Request *SRpnt = NULL;
Scsi_Tape *STp = filp->private_data;
ST_mode *STm;
/* Read command */
static ssize_t
- st_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
+st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
{
ssize_t total;
ssize_t retval = 0;
/* Move data from the user buffer to the tape buffer. Returns zero (success) or
negative error code. */
-static int append_to_buffer(const char *ubp, ST_buffer * st_bp, int do_count)
+static int append_to_buffer(const char __user *ubp, ST_buffer * st_bp, int do_count)
{
int i, cnt, res, offset;
/* Move data from the tape buffer to the user buffer. Returns zero (success) or
negative error code. */
-static int from_buffer(ST_buffer * st_bp, char *ubp, int do_count)
+static int from_buffer(ST_buffer * st_bp, char __user *ubp, int do_count)
{
int i, cnt, res, offset;
int ints[2];
ints[0] = 1;
- for(; *base; base++)
- {
- if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
- {
- ints[1] = *base;
- sym53c416_setup(NULL, ints);
+ for(; *base; base++) {
+ if (request_region(*base, IO_RANGE, ID)) {
+ if (sym53c416_test(*base)) {
+ ints[1] = *base;
+ sym53c416_setup(NULL, ints);
+ }
+ release_region(*base, IO_RANGE);
}
}
}
sym53c416_probe();
/* Now we register and set up each host adapter found... */
- for(count = 0, i = 0; i < host_index; i++)
- {
- if(!sym53c416_test(hosts[i].base))
+ for(count = 0, i = 0; i < host_index; i++) {
+ if (!request_region(hosts[i].base, IO_RANGE, ID))
+ continue;
+ if (!sym53c416_test(hosts[i].base)) {
printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base);
- else
- {
- if(hosts[i].irq == 0)
- /* We don't have an irq yet, so we should probe for one */
- if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
- printk(KERN_WARNING "IRQ autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
- if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
- {
- shpnt = scsi_register(tpnt, 0);
- if(shpnt==NULL)
- continue;
- spin_lock_irqsave(&sym53c416_lock, flags);
- /* Request for specified IRQ */
- if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
- {
- spin_unlock_irqrestore(&sym53c416_lock, flags);
- printk(KERN_ERR "sym53c416: Unable to assign IRQ %d\n", hosts[i].irq);
- scsi_unregister(shpnt);
- }
- else
- {
- /* Inform the kernel of our IO range */
- request_region(hosts[i].base, IO_RANGE, ID);
- shpnt->unique_id = hosts[i].base;
- shpnt->io_port = hosts[i].base;
- shpnt->n_io_port = IO_RANGE;
- shpnt->irq = hosts[i].irq;
- shpnt->this_id = hosts[i].scsi_id;
- sym53c416_init(hosts[i].base, hosts[i].scsi_id);
- count++;
- spin_unlock_irqrestore(&sym53c416_lock, flags);
- }
- }
+ goto fail_release_region;
}
+
+ /* We don't have an irq yet, so we should probe for one */
+ if (!hosts[i].irq)
+ hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id);
+ if (!hosts[i].irq)
+ goto fail_release_region;
+
+ shpnt = scsi_register(tpnt, 0);
+ if (!shpnt)
+ goto fail_release_region;
+ /* Request for specified IRQ */
+ if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt))
+ goto fail_free_host;
+
+ spin_lock_irqsave(&sym53c416_lock, flags);
+ shpnt->unique_id = hosts[i].base;
+ shpnt->io_port = hosts[i].base;
+ shpnt->n_io_port = IO_RANGE;
+ shpnt->irq = hosts[i].irq;
+ shpnt->this_id = hosts[i].scsi_id;
+ sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+ count++;
+ spin_unlock_irqrestore(&sym53c416_lock, flags);
+ continue;
+
+ fail_free_host:
+ scsi_unregister(shpnt);
+ fail_release_region:
+ release_region(hosts[i].base, IO_RANGE);
}
return count;
}
* 2.1b1 04/01/31 GL (applied 05.04) Remove internal *
* command-queuing. *
* 2.1b2 04/02/01 CH (applied 05.04) Fix error-handling *
+ * 2.1c 04/05/23 GL Update to use the new pci_driver API, *
+ * some scsi EH updates, more cleanup. *
+ * 2.1d 04/05/27 GL Moved setting of scan_devices to *
+ * slave_alloc/_configure/_destroy, as *
+ * suggested by CH. *
***********************************************************************/
/* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
#include <linux/init.h>
#include <linux/spinlock.h>
-#if defined(MODULE)
static struct pci_device_id tmscsim_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_AMD,
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
-#endif
-
+
#define USE_SPINLOCKS 1
#define DC390_IFLAGS unsigned long iflags
static int DC390_release(struct Scsi_Host *host);
static int dc390_shutdown (struct Scsi_Host *host);
+static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
+ off_t offset, int length, int inout);
static PACB dc390_pACB_start= NULL;
static PACB dc390_pACB_current = NULL;
/* Startup values, to be overriden on the commandline */
static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
+static int tmscsim_paramnum = ARRAY_SIZE(tmscsim);
-#if defined(MODULE)
-MODULE_PARM(tmscsim, "1-6i");
+module_param_array(tmscsim, int, tmscsim_paramnum, 0);
MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
MODULE_LICENSE("GPL");
-
MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
-#endif
static PVOID dc390_phase0[]={
dc390_DataOut_0,
}
}
+static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
+{
+ memset(sg, 0, sizeof(struct scatterlist));
+ sg->page = virt_to_page(addr);
+ sg->length = length;
+ sg->offset = (unsigned long)addr & ~PAGE_MASK;
+ return sg;
+}
/* Create pci mapping */
static int dc390_pci_map (PSRB pSRB)
Scsi_Cmnd *pcmd = pSRB->pcmd;
struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp));
+
/* Map sense buffer */
if (pSRB->SRBFlag & AUTO_REQSENSE) {
- sg_dma_address(&pSRB->Segmentx) = cmdp->saved_dma_handle =
- pci_map_page(pdev, virt_to_page(pcmd->sense_buffer),
- (unsigned long)pcmd->sense_buffer & ~PAGE_MASK, sizeof(pcmd->sense_buffer),
- DMA_FROM_DEVICE);
- sg_dma_len(&pSRB->Segmentx) = sizeof(pcmd->sense_buffer);
- pSRB->SGcount = 1;
- pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
+ pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->sense_buffer, sizeof(pcmd->sense_buffer));
+ pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1,
+ DMA_FROM_DEVICE);
+ cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList);
+
+ /* TODO: error handling */
+ if (pSRB->SGcount != 1)
+ error = 1;
DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
- /* Make SG list */
+ /* Map SG list */
} else if (pcmd->use_sg) {
- pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
- pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList,
- pcmd->use_sg,
- scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+ pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
+ pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg,
+ scsi_to_pci_dma_dir(pcmd->sc_data_direction));
/* TODO: error handling */
if (!pSRB->SGcount)
error = 1;
- DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n", __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
+ DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\
+ __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
/* Map single segment */
} else if (pcmd->request_buffer && pcmd->request_bufflen) {
- sg_dma_address(&pSRB->Segmentx) = cmdp->saved_dma_handle =
- pci_map_page(pdev, virt_to_page(pcmd->request_buffer),
- (unsigned long)pcmd->request_buffer & ~PAGE_MASK,
- pcmd->request_bufflen, scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+ pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen);
+ pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1,
+ scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+ cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList);
+
/* TODO: error handling */
- sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen;
- pSRB->SGcount = 1;
- pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
+ if (pSRB->SGcount != 1)
+ error = 1;
DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle));
/* No mapping !? */
} else
pSRB->SGcount = 0;
+
return error;
}
{
Scsi_Cmnd* pcmd = pSRB->pcmd;
struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
- dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp));
+ DEBUG1(dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp)));
if (pSRB->SRBFlag) {
- pci_unmap_page(pdev, cmdp->saved_dma_handle,
- sizeof(pcmd->sense_buffer), DMA_FROM_DEVICE);
+ pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE);
DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
} else if (pcmd->use_sg) {
- pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg,
- scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+ pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, scsi_to_pci_dma_dir(pcmd->sc_data_direction));
DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg));
} else if (pcmd->request_buffer && pcmd->request_bufflen) {
- pci_unmap_page(pdev,
- cmdp->saved_dma_handle,
- pcmd->request_bufflen,
- scsi_to_pci_dma_dir(pcmd->sc_data_direction));
+ pci_unmap_sg(pdev, &pSRB->Segmentx, 1, scsi_to_pci_dma_dir(pcmd->sc_data_direction));
DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
}
}
* 2.0.x: always return 0
* 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x
* TO BE DONE:
- * new model: return 0 if successful
- * return 1 if command cannot be queued (queue full)
+ * new model: return 0 if successful, or must not be re-queued
+ * return 1 if command cannot be queued (queue full)
* command will be inserted in midlevel queue then ...
*
***********************************************************************/
static int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
{
- PDCB pDCB;
+ PDCB pDCB = (PDCB) cmd->device->hostdata;
PSRB pSRB;
PACB pACB = (PACB) cmd->device->host->hostdata;
/* TODO: Change the policy: Always accept TEST_UNIT_READY or INQUIRY
* commands and alloc a DCB for the device if not yet there. DCB will
* be removed in dc390_SRBdone if SEL_TIMEOUT */
-
- if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
- pACB->scan_devices = 0;
-
- else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
- pACB->scan_devices = 0;
-
- if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) &&
- !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
- {
- pACB->scan_devices = 1;
-
- dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun );
- if (!pDCB)
- {
- printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n",
- cmd->device->id, cmd->device->lun);
- goto fail;
- }
-
- }
- else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
- {
+ if (!(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun))) {
printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
goto fail;
}
- else
- {
- pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
- if (!pDCB)
- { /* should never happen */
- printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n",
- cmd->device->id, cmd->device->lun);
- goto fail;
- }
+
+ /* Should it be: BUG_ON(!pDCB); ? */
+
+ if (!pDCB)
+ { /* should never happen */
+ printk (KERN_ERR "DC390: no DCB found, target %02x lun %02x\n",
+ cmd->device->id, cmd->device->lun);
+ goto fail;
}
pACB->Cmds++;
static int DC390_abort (Scsi_Cmnd *cmd)
{
- PDCB pDCB;
+ PDCB pDCB = (PDCB) cmd->device->hostdata;
PSRB pSRB, psrb;
UINT count, i;
int status;
printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
cmd->pid, cmd->device->id, cmd->device->lun);
- pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
if( !pDCB ) goto NOT_RUN;
/* Added 98/07/02 KG */
{
PEEprom prom;
UCHAR index;
- PDCB pDCB, pDCB2;
+ PDCB pDCB, pDCB2 = 0;
pDCB = kmalloc (sizeof(DC390_DCB), GFP_ATOMIC);
DCBDEBUG(printk (KERN_INFO "DC390: alloc mem for DCB (ID %i, LUN %i): %p\n", \
id, lun, pDCB));
-
+
*ppDCB = pDCB;
- if (!pDCB) return;
- pDCB2 = 0;
+ if (!pDCB)
+ return;
+
if( pACB->DCBCnt == 0 )
{
pACB->pLinkDCB = pDCB;
pACB->SRBCount = MAX_SRB_CNT;
pACB->AdapterIndex = index;
pACB->status = 0;
- psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
- pACB->DeviceCnt = 0;
pACB->DCBCnt = 0;
pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM];
pACB->ACBFlag = 0;
*
* Inputs : host - pointer to this host adapter's structure
* io_port - IO ports mapped to this adapter
- * Irq - IRQ assigned to this adpater
+ * irq - IRQ assigned to this adpater
* struct pci_dev - PCI access handle
* index - Adapter index
*
* Note: written in capitals, because the locking is only done here,
* not in DC390_detect, called from outside
***********************************************************************/
-
-static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_dev *pdev, UCHAR index)
+static int __init dc390_init (PSH psh, unsigned long io_port, u8 irq, struct pci_dev *pdev, UCHAR index)
{
- PSH psh;
PACB pACB;
if (dc390_CheckEEpromCheckSum (PDEV, index))
dc390_check_for_safe_settings ();
dc390_EEprom_Override (index);
}
-
- psh = scsi_register( psht, sizeof(DC390_ACB) );
- if( !psh ) return( -1 );
-
- scsi_set_device(psh, &pdev->dev);
pACB = (PACB) psh->hostdata;
DEBUG0(printk(KERN_INFO "DC390: pSH = %8x, Index %02i\n", (UINT) psh, index));
- dc390_initACB( psh, io_port, Irq, index );
+ dc390_initACB( psh, io_port, irq, index );
PDEVSET;
- if( !dc390_initAdapter( psh, io_port, Irq, index ) )
+ if( !dc390_initAdapter( psh, io_port, irq, index ) )
{
- DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
- (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array));
- DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
- sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) ));
return (0);
}
else
PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
}
-int __init DC390_detect (Scsi_Host_Template *psht)
+/**
+ * dc390_slave_alloc - Called by the scsi mid layer to tell us about a new
+ * scsi device that we need to deal with.
+ *
+ * @scsi_device: The new scsi device that we need to handle.
+ */
+static int dc390_slave_alloc(struct scsi_device *scsi_device)
+{
+ PDCB pDCB;
+ PACB pACB = (PACB) scsi_device->host->hostdata;
+ dc390_initDCB(pACB, &pDCB, scsi_device->id, scsi_device->lun);
+ if (pDCB != NULL) {
+ scsi_device->hostdata = pDCB;
+ pACB->scan_devices = 1;
+ return 0;
+ }
+ return -ENOMEM;
+}
+
+/**
+ * dc390_slave_destroy - Called by the scsi mid layer to tell us about a
+ * device that is going away.
+ *
+ * @scsi_device: The scsi device that we need to remove.
+ */
+static void dc390_slave_destroy(struct scsi_device *scsi_device)
+{
+ PACB pACB = (PACB) scsi_device->host->hostdata;
+ PDCB pDCB = (PDCB) scsi_device->hostdata;
+ pACB->scan_devices = 0;
+ if (pDCB != NULL)
+ dc390_remove_dev(pACB, pDCB);
+ else
+ printk(KERN_ERR"%s() called for non-existing device!\n", __FUNCTION__);
+}
+
+static int dc390_slave_configure(struct scsi_device *scsi_device)
{
- struct pci_dev *pdev = NULL;
- UCHAR irq;
- ULONG io_port;
+ PACB pACB = (PACB) scsi_device->host->hostdata;
+ pACB->scan_devices = 0;
+ return 0;
+}
- dc390_pACB_start = NULL;
+static Scsi_Host_Template driver_template = {
+ .module = THIS_MODULE,
+ .proc_name = "tmscsim",
+ .proc_info = DC390_proc_info,
+ .name = DC390_BANNER " V" DC390_VERSION,
+ .slave_alloc = dc390_slave_alloc,
+ .slave_configure = dc390_slave_configure,
+ .slave_destroy = dc390_slave_destroy,
+ .queuecommand = DC390_queue_command,
+ .eh_abort_handler = DC390_abort,
+ .eh_bus_reset_handler = DC390_reset,
+ .bios_param = DC390_bios_param,
+ .can_queue = 42,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = 16,
+ .use_clustering = DISABLE_CLUSTERING,
+};
- if ( PCI_PRESENT )
- while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974, pdev)))
- {
- if (pci_enable_device (pdev))
- continue;
+static int __devinit dc390_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct Scsi_Host *scsi_host;
+ unsigned long io_port;
+ u8 irq;
+ PACB pACB;
+ int ret = -ENOMEM;
- if (pci_set_dma_mask(pdev, 0xffffffff)) {
- printk(KERN_ERR "DC390(%i): No suitable DMA available.\n", dc390_adapterCnt);
- continue;
- }
- PCI_GET_IO_AND_IRQ;
- DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq));
+ if (pci_enable_device(dev))
+ return -ENODEV;
- if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt))
- {
- pci_set_master(pdev);
- dc390_set_pci_cfg (PDEV);
- dc390_adapterCnt++;
- }
+ io_port = pci_resource_start(dev, 0);
+ irq = dev->irq;
+
+ /* allocate scsi host information (includes out adapter) */
+ scsi_host = scsi_host_alloc(&driver_template, sizeof(struct _ACB));
+ if (!scsi_host)
+ goto nomem;
+
+ pACB = (PACB) scsi_host->hostdata;
+
+ if (dc390_init(scsi_host, io_port, irq, dev, dc390_adapterCnt)) {
+ ret = -EBUSY;
+ goto busy;
}
- else
- printk (KERN_ERR "DC390: No PCI BIOS found!\n");
-
- if (dc390_adapterCnt)
- psht->proc_name = "tmscsim";
- printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
- return( dc390_adapterCnt );
+ pci_set_master(dev);
+ dc390_set_pci_cfg(dev);
+ dc390_adapterCnt++;
+
+ /* get the scsi mid level to scan for new devices on the bus */
+ if (scsi_add_host(scsi_host, &dev->dev)) {
+ ret = -ENODEV;
+ goto nodev;
+ }
+ pci_set_drvdata(dev, scsi_host);
+ scsi_scan_host(scsi_host);
+
+ return 0;
+
+nodev:
+busy:
+ scsi_host_put(scsi_host);
+nomem:
+ pci_disable_device(dev);
+ return ret;
+}
+
+/**
+ * dc390_remove_one - Called to remove a single instance of the adapter.
+ *
+ * @dev: The PCI device to remove.
+ */
+static void __devexit dc390_remove_one(struct pci_dev *dev)
+{
+ struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
+
+ scsi_remove_host(scsi_host);
+ DC390_release(scsi_host);
+ pci_disable_device(dev);
+ scsi_host_put(scsi_host);
+ pci_set_drvdata(dev, NULL);
}
/********************************************************************
SPRINTF(" Lost arbitrations %i, Sel. connected %i, Connected: %s\n",
pACB->SelLost, pACB->SelConn, pACB->Connected? "Yes": "No");
- SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB->DeviceCnt, pACB->DCBCnt);
+ SPRINTF("Nr of DCBs: %i\n", pACB->DCBCnt);
SPRINTF("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n",
pACB->DCBmap[0], pACB->DCBmap[1], pACB->DCBmap[2], pACB->DCBmap[3],
pACB->DCBmap[4], pACB->DCBmap[5], pACB->DCBmap[6], pACB->DCBmap[7]);
static int dc390_shutdown (struct Scsi_Host *host)
{
UCHAR bval;
- PACB pACB = (PACB)(host->hostdata);
+ PACB pACB = (PACB) host->hostdata;
/* pACB->soft_reset(host); */
static void dc390_freeDCBs (struct Scsi_Host *host)
{
PDCB pDCB, nDCB;
- PACB pACB = (PACB)(host->hostdata);
+ PACB pACB = (PACB) host->hostdata;
pDCB = pACB->pLinkDCB;
if (!pDCB) return;
static int DC390_release (struct Scsi_Host *host)
{
DC390_IFLAGS;
- PACB pACB = (PACB)(host->hostdata);
+ PACB pACB = (PACB) host->hostdata;
DC390_LOCK_IO(host);
release_region(host->io_port,host->n_io_port);
dc390_freeDCBs (host);
DC390_UNLOCK_IO(host);
- scsi_unregister(host);
return( 1 );
}
-static Scsi_Host_Template driver_template = {
- .proc_name = "tmscsim",
- .proc_info = DC390_proc_info,
- .name = DC390_BANNER " V" DC390_VERSION,
- .detect = DC390_detect,
- .release = DC390_release,
- .queuecommand = DC390_queue_command,
- .eh_abort_handler = DC390_abort,
- .eh_bus_reset_handler = DC390_reset,
- .bios_param = DC390_bios_param,
- .can_queue = 42,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 16,
- .use_clustering = DISABLE_CLUSTERING,
+static struct pci_driver dc390_driver = {
+ .name = "tmscsim",
+ .id_table = tmscsim_pci_tbl,
+ .probe = dc390_init_one,
+ .remove = __devexit_p(dc390_remove_one),
};
-#include "scsi_module.c"
+
+static int __init dc390_module_init(void)
+{
+ return pci_module_init(&dc390_driver);
+}
+
+static void __exit dc390_module_exit(void)
+{
+ pci_unregister_driver(&dc390_driver);
+}
+
+module_init(dc390_module_init);
+module_exit(dc390_module_exit);
#define SEL_TIMEOUT 153 /* 250 ms selection timeout (@ 40 MHz) */
-#define END_SCAN 2
-
#define pci_dma_lo32(a) (a & 0xffffffff)
typedef u8 UCHAR; /* 8 bits */
UCHAR SRBCount;
UCHAR AdapterIndex; /*; nth Adapter this driver */
-UCHAR DeviceCnt;
UCHAR DCBCnt;
-/* 0x10: */
UCHAR TagMaxNum;
UCHAR ACBFlag;
UCHAR Gmode2;
PSRB pFreeSRB;
PSRB pTmpSRB;
-/* 0x2c: */
UCHAR msgin123[4];
UCHAR DCBmap[MAX_SCSI_ID];
UCHAR Connected;
UCHAR pad;
-/* 0x30: */
#if defined(USE_SPINLOCKS) && USE_SPINLOCKS > 1 && (defined(CONFIG_SMP) || DEBUG_SPINLOCKS > 0)
spinlock_t lock;
#endif
UCHAR Ignore_IRQ; /* Not used */
PDEVDECL1; /* Pointer to PCI cfg. space */
-/* 0x40/0x3c: */
+
ULONG Cmds;
UINT SelLost;
UINT SelConn;
UINT CmdInQ;
UINT CmdOutOfSRB;
-/* 0x54/0x50: */
struct timer_list Waiting_Timer;
-/* 0x68/0x64: */
+
DC390_SRB TmpSRB;
-/* 0xcc/0xc8: */
DC390_SRB SRB_array[MAX_SRB_CNT]; /* 50 SRBs */
-/* 0xfa4/0xfa0: */
};
typedef struct _ACB DC390_ACB, *PACB;
return 0;
}
+#if 0
/*
* I have absolutely NO idea how to do an abort with the WD7000...
*/
}
return FAILED;
}
-
+#endif
/*
* I also have no idea how to do a reset...
static acpi_status acpi_serial_ext_irq(struct serial_struct *req,
struct acpi_resource_ext_irq *ext_irq)
{
- if (ext_irq->number_of_interrupts > 0) {
-#ifdef CONFIG_IA64
- req->irq = acpi_register_irq(ext_irq->interrupts[0],
- ext_irq->active_high_low, ext_irq->edge_level);
-#else
- req->irq = ext_irq->interrupts[0];
-#endif
- }
+ if (ext_irq->number_of_interrupts > 0)
+ req->irq = acpi_register_gsi(ext_irq->interrupts[0],
+ ext_irq->edge_level, ext_irq->active_high_low);
return AE_OK;
}
static acpi_status acpi_serial_irq(struct serial_struct *req,
struct acpi_resource_irq *irq)
{
- if (irq->number_of_interrupts > 0) {
-#ifdef CONFIG_IA64
- req->irq = acpi_register_irq(irq->interrupts[0],
- irq->active_high_low, irq->edge_level);
-#else
- req->irq = irq->interrupts[0];
-#endif
- }
+ if (irq->number_of_interrupts > 0)
+ req->irq = acpi_register_gsi(irq->interrupts[0],
+ irq->edge_level, irq->active_high_low);
return AE_OK;
}
}
if (HCDP_IRQ_SUPPORTED(hcdp_dev)) {
-#ifdef CONFIG_IA64
if (HCDP_PCI_UART(hcdp_dev))
- port.irq = acpi_register_irq(gsi,
- ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
+ port.irq = acpi_register_gsi(gsi,
+ ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
else
- port.irq = acpi_register_irq(gsi,
- ACPI_ACTIVE_HIGH, ACPI_EDGE_SENSITIVE);
-#else
- port.irq = gsi;
-#endif
+ port.irq = acpi_register_gsi(gsi,
+ ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH);
port.flags |= UPF_AUTO_IRQ;
if (HCDP_PCI_UART(hcdp_dev))
((port->min == 0x2f8) ||
(port->min == 0x3f8) ||
(port->min == 0x2e8) ||
-#ifdef CONFIG_X86_PC9800
- (port->min == 0x8b0) ||
-#endif
(port->min == 0x3e8)))
return 1;
}
.name = "serial",
.id_table = pnp_dev_table,
.probe = serial_pnp_probe,
- .remove = serial_pnp_remove,
+ .remove = __devexit_p(serial_pnp_remove),
};
static int __init serial8250_pnp_init(void)
config SERIAL_S3C2410_CONSOLE
bool "Support for console on S3C2410 serial port"
depends on SERIAL_S3C2410=y
+ select SERIAL_CORE_CONSOLE
help
Allow selection of the S3C2410 on-board serial ports for use as
an virtual console.
depends on V850E_UART
select SERIAL_CORE_CONSOLE
-config SERIAL98
- tristate "PC-9800 8251-based primary serial port support"
- depends on X86_PC9800
- select SERIAL_CORE
- help
- If you want to use standard primary serial ports on PC-9800,
- say Y. Otherwise, say N.
-
-config SERIAL98_CONSOLE
- bool "Support for console on PC-9800 standard serial port"
- depends on SERIAL98=y
- select SERIAL_CORE_CONSOLE
-
config SERIAL_SH_SCI
tristate "SH SCI(F) serial port support"
depends on SUPERH || H8300
obj-$(CONFIG_SERIAL_68360) += 68360serial.o
obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
obj-$(CONFIG_V850E_UART) += v850e_uart.o
-obj-$(CONFIG_SERIAL98) += serial98.o
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o
obj-$(CONFIG_SERIAL_DZ) += dz.o
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware/amba.h>
+#include <asm/hardware/clock.h>
#if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
*/
struct uart_amba_port {
struct uart_port port;
+ struct clk *clk;
unsigned int im; /* interrupt mask */
unsigned int old_status;
};
unsigned int cr;
int retval;
+ /*
+ * Try to enable the clock producer.
+ */
+ retval = clk_enable(uap->clk);
+ if (retval)
+ goto out;
+
+ uap->port.uartclk = clk_get_rate(uap->clk);
+
/*
* Allocate the IRQ
*/
retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
if (retval)
- goto out;
+ goto clk_dis;
writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
uap->port.membase + UART011_IFLS);
return 0;
+ clk_dis:
+ clk_disable(uap->clk);
out:
return retval;
}
val = readw(uap->port.membase + UART011_LCRH);
val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
writew(val, uap->port.membase + UART011_LCRH);
+
+ /*
+ * Shut down the clock producer
+ */
+ clk_disable(uap->clk);
}
static void
#ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE
static inline void
-pl011_console_write_char(struct uart_port *port, char ch)
+pl011_console_write_char(struct uart_amba_port *uap, char ch)
{
unsigned int status;
do {
- status = readw(port->membase + UART01x_FR);
+ status = readw(uap->port.membase + UART01x_FR);
} while (status & UART01x_FR_TXFF);
- writew(ch, port->membase + UART01x_DR);
+ writew(ch, uap->port.membase + UART01x_DR);
}
static void
pl011_console_write(struct console *co, const char *s, unsigned int count)
{
- struct uart_port *port = &amba_ports[co->index]->port;
+ struct uart_amba_port *uap = amba_ports[co->index];
unsigned int status, old_cr, new_cr;
int i;
+ clk_enable(uap->clk);
+
/*
* First save the CR then disable the interrupts
*/
- old_cr = readw(port->membase + UART011_CR);
+ old_cr = readw(uap->port.membase + UART011_CR);
new_cr = old_cr & ~UART011_CR_CTSEN;
new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
- writew(new_cr, port->membase + UART011_CR);
+ writew(new_cr, uap->port.membase + UART011_CR);
/*
* Now, do each character
*/
for (i = 0; i < count; i++) {
- pl011_console_write_char(port, s[i]);
+ pl011_console_write_char(uap, s[i]);
if (s[i] == '\n')
- pl011_console_write_char(port, '\r');
+ pl011_console_write_char(uap, '\r');
}
/*
* and restore the TCR
*/
do {
- status = readw(port->membase + UART01x_FR);
+ status = readw(uap->port.membase + UART01x_FR);
} while (status & UART01x_FR_BUSY);
- writew(old_cr, port->membase + UART011_CR);
+ writew(old_cr, uap->port.membase + UART011_CR);
+
+ clk_disable(uap->clk);
}
static void __init
-pl011_console_get_options(struct uart_port *port, int *baud,
+pl011_console_get_options(struct uart_amba_port *uap, int *baud,
int *parity, int *bits)
{
- if (readw(port->membase + UART011_CR) & UART01x_CR_UARTEN) {
+ if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) {
unsigned int lcr_h, ibrd, fbrd;
- lcr_h = readw(port->membase + UART011_LCRH);
+ lcr_h = readw(uap->port.membase + UART011_LCRH);
*parity = 'n';
if (lcr_h & UART01x_LCRH_PEN) {
else
*bits = 8;
- ibrd = readw(port->membase + UART011_IBRD);
- fbrd = readw(port->membase + UART011_FBRD);
+ ibrd = readw(uap->port.membase + UART011_IBRD);
+ fbrd = readw(uap->port.membase + UART011_FBRD);
- *baud = port->uartclk * 4 / (64 * ibrd + fbrd);
+ *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
}
}
co->index = 0;
uap = amba_ports[co->index];
+ uap->port.uartclk = clk_get_rate(uap->clk);
+
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
- pl011_console_get_options(&uap->port, &baud, &parity, &bits);
+ pl011_console_get_options(uap, &baud, &parity, &bits);
return uart_set_options(&uap->port, co, baud, parity, bits, flow);
}
}
memset(uap, 0, sizeof(struct uart_amba_port));
+ uap->clk = clk_get(&dev->dev, "UARTCLK");
+ if (IS_ERR(uap->clk)) {
+ ret = PTR_ERR(uap->clk);
+ goto unmap;
+ }
+
+ ret = clk_use(uap->clk);
+ if (ret)
+ goto putclk;
+
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
uap->port.iotype = UPIO_MEM;
uap->port.irq = dev->irq[0];
-#if 0 /* FIXME */
- uap->port.uartclk = 14745600;
-#else
- uap->port.uartclk = 24000000;
-#endif
uap->port.fifosize = 16;
uap->port.ops = &amba_pl011_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
if (ret) {
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
+ clk_unuse(uap->clk);
+ putclk:
+ clk_put(uap->clk);
+ unmap:
iounmap(base);
free:
kfree(uap);
amba_ports[i] = NULL;
iounmap(uap->port.membase);
+ clk_unuse(uap->clk);
+ clk_put(uap->clk);
kfree(uap);
return 0;
}
#define SERIAL_S3C2410_NAME "ttySAC"
#define SERIAL_S3C2410_MAJOR 204
-#define SERIAL_S3C2410_MINOR 4
+#define SERIAL_S3C2410_MINOR 64
/* we can support 3 uarts, but not always use them */
static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp);
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp);
/* Serial Control Interface funtions */
static int SCI_Control(IXJ *j, int control);
static int SCI_Prepare(IXJ *j);
}
}
-static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
+static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
{
unsigned long i = *ppos;
IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode));
}
}
-static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
+static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length,
loff_t * ppos)
{
int pre_retval;
return read_retval;
}
-static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos)
{
unsigned long i = *ppos;
IXJ *j = file_p->private_data;
return min(count, j->write_buffer_size);
}
-static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos)
{
int pre_retval;
ssize_t write_retval = 0;
ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */
}
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp)
{
- IXJ_CADENCE *lcp;
+ ixj_cadence *lcp;
+ IXJ_CADENCE_ELEMENT __user *cep;
IXJ_CADENCE_ELEMENT *lcep;
IXJ_TONE ti;
+ int err;
- lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
+ lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL);
if (lcp == NULL)
return -ENOMEM;
- if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT) )
- {
- kfree(lcp);
- return -EFAULT;
- }
+
+ err = -EFAULT;
+ if (copy_from_user(&lcp->elements_used,
+ &cp->elements_used, sizeof(int)))
+ goto out;
+ if (copy_from_user(&lcp->termination,
+ &cp->termination, sizeof(IXJ_CADENCE_TERM)))
+ goto out;
+ if (get_user(cep, &cp->ce))
+ goto out;
+
+ err = -EINVAL;
+ if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT))
+ goto out;
+
+ err = -ENOMEM;
lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
- if (lcep == NULL) {
- kfree(lcp);
- return -ENOMEM;
- }
- if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
- {
- kfree(lcep);
- kfree(lcp);
- return -EFAULT;
- }
+ if (!lcep)
+ goto out;
+
+ err = -EFAULT;
+ if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
+ goto out1;
+
if (j->cadence_t) {
kfree(j->cadence_t->ce);
kfree(j->cadence_t);
}
ixj_play_tone(j, lcp->ce[0].index);
return 1;
+out1:
+ kfree(lcep);
+out:
+ kfree(lcp);
+ return err;
}
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp)
{
IXJ_FILTER_CADENCE *lcp;
lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL);
}
return -ENOMEM;
}
- if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) {
+ if (copy_from_user(lcp, cp, sizeof(IXJ_FILTER_CADENCE))) {
if(ixjdebug & 0x0001) {
printk(KERN_INFO "Could not copy cadence to kernel\n");
}
IXJ_TONE ti;
IXJ_FILTER jf;
IXJ_FILTER_RAW jfr;
+ void __user *argp = (void __user *)arg;
unsigned int raise, mant;
unsigned int minor = iminor(inode);
retval = j->serial;
break;
case IXJCTL_VERSION:
- if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
+ if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision)))
retval = -EFAULT;
break;
case PHONE_RING_CADENCE:
break;
case IXJCTL_CIDCW:
if(arg) {
- if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
+ if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
retval = -EFAULT;
break;
}
/* Fall through */
case PHONE_RING_START:
if(arg) {
- if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
+ if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
retval = -EFAULT;
break;
}
samplerate = arg;
break;
case IXJCTL_DRYBUFFER_READ:
- put_user(j->drybuffer, (unsigned long *) arg);
+ put_user(j->drybuffer, (unsigned long __user *) argp);
break;
case IXJCTL_DRYBUFFER_CLEAR:
j->drybuffer = 0;
break;
case IXJCTL_FRAMES_READ:
- put_user(j->framesread, (unsigned long *) arg);
+ put_user(j->framesread, (unsigned long __user *) argp);
break;
case IXJCTL_FRAMES_WRITTEN:
- put_user(j->frameswritten, (unsigned long *) arg);
+ put_user(j->frameswritten, (unsigned long __user *) argp);
break;
case IXJCTL_READ_WAIT:
- put_user(j->read_wait, (unsigned long *) arg);
+ put_user(j->read_wait, (unsigned long __user *) argp);
break;
case IXJCTL_WRITE_WAIT:
- put_user(j->write_wait, (unsigned long *) arg);
+ put_user(j->write_wait, (unsigned long __user *) argp);
break;
case PHONE_MAXRINGS:
j->maxrings = arg;
12, 10, 16, 9, 8, 48, 5,
40, 40, 80, 40, 40, 6
};
- if(copy_from_user(&pd, (void *)arg, sizeof(pd))) {
+ if(copy_from_user(&pd, argp, sizeof(pd))) {
retval = -EFAULT;
break;
}
default:val=proto_size[pd.type]*3;break;
}
pd.buf_min=pd.buf_max=pd.buf_opt=val;
- if(copy_to_user((void *)arg, &pd, sizeof(pd)))
+ if(copy_to_user(argp, &pd, sizeof(pd)))
retval = -EFAULT;
break;
}
ixj_write_vmwi(j, arg);
break;
case IXJCTL_CID:
- if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
+ if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID)))
retval = -EFAULT;
j->ex.bits.caller_id = 0;
break;
break;
case PHONE_CAPABILITIES_LIST:
add_caps(j);
- if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
+ if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps))
retval = -EFAULT;
break;
case PHONE_CAPABILITIES_CHECK:
{
struct phone_capability cap;
- if (copy_from_user(&cap, (char *) arg, sizeof(cap)))
+ if (copy_from_user(&cap, argp, sizeof(cap)))
retval = -EFAULT;
else {
add_caps(j);
j->ex.bits.pstn_ring = 0;
break;
case IXJCTL_SET_FILTER:
- if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
+ if (copy_from_user(&jf, argp, sizeof(jf)))
retval = -EFAULT;
retval = ixj_init_filter(j, &jf);
break;
case IXJCTL_SET_FILTER_RAW:
- if (copy_from_user(&jfr, (char *) arg, sizeof(jfr)))
+ if (copy_from_user(&jfr, argp, sizeof(jfr)))
retval = -EFAULT;
else
retval = ixj_init_filter_raw(j, &jfr);
retval = j->filter_hist[arg];
break;
case IXJCTL_INIT_TONE:
- if (copy_from_user(&ti, (char *) arg, sizeof(ti)))
+ if (copy_from_user(&ti, argp, sizeof(ti)))
retval = -EFAULT;
else
retval = ixj_init_tone(j, &ti);
break;
case IXJCTL_TONE_CADENCE:
- retval = ixj_build_cadence(j, (IXJ_CADENCE *) arg);
+ retval = ixj_build_cadence(j, argp);
break;
case IXJCTL_FILTER_CADENCE:
- retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
+ retval = ixj_build_filter_cadence(j, argp);
break;
case IXJCTL_SIGCTL:
- if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF))) {
+ if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {
retval = -EFAULT;
break;
}
*
******************************************************************************/
+typedef struct {
+ int elements_used;
+ IXJ_CADENCE_TERM termination;
+ IXJ_CADENCE_ELEMENT *ce;
+} ixj_cadence;
+
typedef struct {
struct phone_device p;
struct timer_list timer;
char tone_index;
char tone_state;
char maxrings;
- IXJ_CADENCE *cadence_t;
- IXJ_CADENCE *cadence_r;
+ ixj_cadence *cadence_t;
+ ixj_cadence *cadence_r;
int tone_cadence_state;
IXJ_CADENCE_F cadence_f[6];
DTMF dtmf;
# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
config USB
tristate "Support for Host-side USB"
- depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610
+ depends on PCI || SA1111 || ARCH_OMAP1510 || ARCH_OMAP1610 || ARCH_LH7A404
---help---
Universal Serial Bus (USB) is a specification for a serial bus
subsystem which offers higher speeds and more features than the
{
struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data;
int i, j, val;
+ int __user *user_arg = (int __user *)arg;
if (!ms->state->usbdev)
return -ENODEV;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, user_arg);
if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
if (_IOC_DIR(cmd) == _IOC_READ) {
val = get_rec_src(ms);
if (val < 0)
return val;
- return put_user(val, (int *)arg);
+ return put_user(val, user_arg);
case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
for (val = i = 0; i < ms->numch; i++)
val |= 1 << ms->ch[i].osschannel;
- return put_user(val, (int *)arg);
+ return put_user(val, user_arg);
case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
for (val = i = 0; i < ms->numch; i++)
if (ms->ch[i].slctunitid)
val |= 1 << ms->ch[i].osschannel;
- return put_user(val, (int *)arg);
+ return put_user(val, user_arg);
case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
for (val = i = 0; i < ms->numch; i++)
if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))
val |= 1 << ms->ch[i].osschannel;
- return put_user(val, (int *)arg);
+ return put_user(val, user_arg);
case SOUND_MIXER_CAPS:
- return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+ return put_user(SOUND_CAP_EXCL_INPUT, user_arg);
default:
i = _IOC_NR(cmd);
return -EINVAL;
for (j = 0; j < ms->numch; j++) {
if (ms->ch[j].osschannel == i) {
- return put_user(ms->ch[j].value, (int *)arg);
+ return put_user(ms->ch[j].value, user_arg);
}
}
return -EINVAL;
ms->modcnt++;
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
return set_rec_src(ms, val);
for (j = 0; j < ms->numch && ms->ch[j].osschannel != i; j++);
if (j >= ms->numch)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (wrmixer(ms, j, val))
return -EIO;
- return put_user(ms->ch[j].value, (int *)arg);
+ return put_user(ms->ch[j].value, user_arg);
}
}
{
struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
struct usb_audio_state *s = as->state;
+ int __user *user_arg = (int __user *)arg;
unsigned long flags;
audio_buf_info abinfo;
count_info cinfo;
#endif
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, user_arg);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
case SNDCTL_DSP_GETCAPS:
return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
- DSP_CAP_MMAP | DSP_CAP_BATCH, (int *)arg);
+ DSP_CAP_MMAP | DSP_CAP_BATCH, user_arg);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (val >= 0) {
if (val < 4000)
if (set_format(as, file->f_mode, AFMT_QUERY, val))
return -EIO;
}
- return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ?
+ as->usbin.dma.srate : as->usbout.dma.srate,
+ user_arg);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
if (val)
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (val != 0) {
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
return -EIO;
}
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
- return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg);
+ return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
return put_user(AFMT_U8 | AFMT_U16_LE | AFMT_U16_BE |
- AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, (int *)arg);
+ AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE, user_arg);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (val != AFMT_QUERY) {
if (hweight32(val) != 1)
return -EIO;
}
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
- return put_user(val2 & ~AFMT_STEREO, (int *)arg);
+ return put_user(val2 & ~AFMT_STEREO, user_arg);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if (file->f_mode & FMODE_WRITE && as->usbout.flags & FLG_RUNNING)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, user_arg);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
spin_lock_irqsave(&as->lock, flags);
val = as->usbout.dma.count;
spin_unlock_irqrestore(&as->lock, flags);
- return put_user(val, (int *)arg);
+ return put_user(val, user_arg);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf_out(as)))
return val;
- return put_user(as->usbout.dma.fragsize, (int *)arg);
+ return put_user(as->usbout.dma.fragsize, user_arg);
}
if ((val = prog_dmabuf_in(as)))
return val;
- return put_user(as->usbin.dma.fragsize, (int *)arg);
+ return put_user(as->usbin.dma.fragsize, user_arg);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
as->usbin.dma.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && as->usbin.dma.subdivision) ||
(file->f_mode & FMODE_WRITE && as->usbout.dma.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, user_arg))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ?
+ as->usbin.dma.srate : as->usbout.dma.srate,
+ user_arg);
case SOUND_PCM_READ_CHANNELS:
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
- return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, (int *)arg);
+ return put_user(AFMT_ISSTEREO(val2) ? 2 : 1, user_arg);
case SOUND_PCM_READ_BITS:
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
- return put_user(AFMT_IS16BIT(val2) ? 16 : 8, (int *)arg);
+ return put_user(AFMT_IS16BIT(val2) ? 16 : 8, user_arg);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
* v0.22 - probe only the control interface. if usbcore doesn't choose the
* config we want, sysadmin changes bConfigurationValue in sysfs.
* v0.23 - use softirq for rx processing, as needed by tty layer
+ * v0.24 - change probe method to evaluate CDC union descriptor
*/
/*
#include <linux/usb.h>
#include <asm/byteorder.h>
+#include "cdc-acm.h"
+
/*
* Version Information
*/
#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
-/*
- * CMSPAR, some architectures can't have space and mark parity.
- */
-
-#ifndef CMSPAR
-#define CMSPAR 0
-#endif
-
-/*
- * Major and minor numbers.
- */
-
-#define ACM_TTY_MAJOR 166
-#define ACM_TTY_MINORS 32
-
-/*
- * Requests.
- */
-
-#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
-
-#define ACM_REQ_COMMAND 0x00
-#define ACM_REQ_RESPONSE 0x01
-#define ACM_REQ_SET_FEATURE 0x02
-#define ACM_REQ_GET_FEATURE 0x03
-#define ACM_REQ_CLEAR_FEATURE 0x04
-
-#define ACM_REQ_SET_LINE 0x20
-#define ACM_REQ_GET_LINE 0x21
-#define ACM_REQ_SET_CONTROL 0x22
-#define ACM_REQ_SEND_BREAK 0x23
-
-/*
- * IRQs.
- */
-
-#define ACM_IRQ_NETWORK 0x00
-#define ACM_IRQ_LINE_STATE 0x20
-
-/*
- * Output control lines.
- */
-
-#define ACM_CTRL_DTR 0x01
-#define ACM_CTRL_RTS 0x02
-
-/*
- * Input control lines and line errors.
- */
-
-#define ACM_CTRL_DCD 0x01
-#define ACM_CTRL_DSR 0x02
-#define ACM_CTRL_BRK 0x04
-#define ACM_CTRL_RI 0x08
-
-#define ACM_CTRL_FRAMING 0x10
-#define ACM_CTRL_PARITY 0x20
-#define ACM_CTRL_OVERRUN 0x40
-
-/*
- * Line speed and caracter encoding.
- */
-
-struct acm_line {
- __u32 speed;
- __u8 stopbits;
- __u8 parity;
- __u8 databits;
-} __attribute__ ((packed));
-
-/*
- * Internal driver structures.
- */
-
-struct acm {
- struct usb_device *dev; /* the corresponding usb device */
- struct usb_interface *control; /* control interface */
- struct usb_interface *data; /* data interface */
- struct tty_struct *tty; /* the corresponding tty */
- struct urb *ctrlurb, *readurb, *writeurb; /* urbs */
- struct acm_line line; /* line coding (bits, stop, parity) */
- struct work_struct work; /* work queue entry for line discipline waking up */
- struct tasklet_struct bh; /* rx processing */
- unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
- unsigned int ctrlout; /* output control lines (DTR, RTS) */
- unsigned int writesize; /* max packet size for the output bulk endpoint */
- unsigned int used; /* someone has this acm's device open */
- unsigned int minor; /* acm minor number */
- unsigned char throttle; /* throttled by tty layer */
- unsigned char clocal; /* termios CLOCAL */
-};
-
static struct usb_driver acm_driver;
static struct tty_driver *acm_tty_driver;
static struct acm *acm_table[ACM_TTY_MINORS];
+static DECLARE_MUTEX(open_sem);
+
#define ACM_READY(acm) (acm && acm->dev && acm->used)
/*
struct acm *acm = (struct acm *)urb->context;
if (!ACM_READY(acm))
- return;
+ goto out;
if (urb->status)
dbg("nonzero write bulk status received: %d", urb->status);
schedule_work(&acm->work);
+out:
+ acm->ready_for_write = 1;
}
static void acm_softint(void *private)
tty->driver_data = acm;
acm->tty = tty;
- lock_kernel();
+ down(&open_sem);
- if (acm->used++) {
- unlock_kernel();
- return 0;
+ if (acm->used) {
+ goto done;
}
- unlock_kernel();
-
acm->ctrlurb->dev = acm->dev;
- if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL))
+ if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
dbg("usb_submit_urb(ctrl irq) failed");
+ goto bail_out;
+ }
acm->readurb->dev = acm->dev;
- if (usb_submit_urb(acm->readurb, GFP_KERNEL))
+ if (usb_submit_urb(acm->readurb, GFP_KERNEL)) {
dbg("usb_submit_urb(read bulk) failed");
+ goto bail_out_and_unlink;
+ }
acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
otherwise it is scheduled, and with high data rates data can get lost. */
tty->low_latency = 1;
+done:
+ acm->used++;
+ up(&open_sem);
return 0;
+
+bail_out_and_unlink:
+ usb_unlink_urb(acm->ctrlurb);
+bail_out:
+ up(&open_sem);
+ return -EIO;
}
static void acm_tty_close(struct tty_struct *tty, struct file *filp)
if (!acm || !acm->used)
return;
+ down(&open_sem);
if (!--acm->used) {
if (acm->dev) {
acm_set_control(acm, acm->ctrlout = 0);
kfree(acm);
}
}
+ up(&open_sem);
}
static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
if (!ACM_READY(acm))
return -EINVAL;
- if (acm->writeurb->status == -EINPROGRESS)
+ if (!acm->ready_for_write)
return 0;
if (!count)
return 0;
acm->writeurb->transfer_buffer_length = count;
acm->writeurb->dev = acm->dev;
- /* GFP_KERNEL probably works if from_user */
- stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC);
+ acm->ready_for_write = 0;
+ stat = usb_submit_urb(acm->writeurb, GFP_NOIO);
if (stat < 0) {
dbg("usb_submit_urb(write bulk) failed");
+ acm->ready_for_write = 1;
return stat;
}
struct acm *acm = tty->driver_data;
if (!ACM_READY(acm))
return -EINVAL;
- return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize;
+ return !acm->ready_for_write ? 0 : acm->writesize;
}
static int acm_tty_chars_in_buffer(struct tty_struct *tty)
struct acm *acm = tty->driver_data;
if (!ACM_READY(acm))
return -EINVAL;
- return acm->writeurb->status == -EINPROGRESS ? acm->writeurb->transfer_buffer_length : 0;
+ return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0;
}
static void acm_tty_throttle(struct tty_struct *tty)
* USB probe and disconnect routines.
*/
-#define CHECK_XFERTYPE(descr, xfer_type) (((descr)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == xfer_type)
-
static int acm_probe (struct usb_interface *intf,
const struct usb_device_id *id)
{
- struct usb_device *dev;
+ struct union_desc *union_header = NULL;
+ char *buffer = intf->altsetting->extra;
+ int buflen = intf->altsetting->extralen;
+ struct usb_interface *control_interface;
+ struct usb_interface *data_interface;
+ struct usb_endpoint_descriptor *epctrl;
+ struct usb_endpoint_descriptor *epread;
+ struct usb_endpoint_descriptor *epwrite;
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
struct acm *acm;
- struct usb_host_config *cfacm;
- struct usb_interface *data = NULL;
- struct usb_host_interface *ifcom, *ifdata = NULL;
- struct usb_endpoint_descriptor *epctrl = NULL;
- struct usb_endpoint_descriptor *epread = NULL;
- struct usb_endpoint_descriptor *epwrite = NULL;
- int readsize, ctrlsize, minor, j;
- unsigned char *buf;
-
- dev = interface_to_usbdev (intf);
-
- cfacm = dev->actconfig;
-
- /* We know we're probe()d with the control interface. */
- ifcom = intf->cur_altsetting;
-
- /* ACM doesn't guarantee the data interface is
- * adjacent to the control interface, or that if one
- * is there it's not for call management ... so find
- * it
- */
- for (j = 0; j < cfacm->desc.bNumInterfaces; j++) {
- ifdata = cfacm->interface[j]->cur_altsetting;
- data = cfacm->interface[j];
-
- if (ifdata->desc.bInterfaceClass == USB_CLASS_CDC_DATA
- && ifdata->desc.bNumEndpoints == 2) {
-
- epctrl = &ifcom->endpoint[0].desc;
- epread = &ifdata->endpoint[0].desc;
- epwrite = &ifdata->endpoint[1].desc;
-
- if ((epctrl->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN
- || !CHECK_XFERTYPE(epctrl, USB_ENDPOINT_XFER_INT)
- || !CHECK_XFERTYPE(epread, USB_ENDPOINT_XFER_BULK)
- || !CHECK_XFERTYPE(epwrite, USB_ENDPOINT_XFER_BULK)
- || ((epread->bEndpointAddress & USB_DIR_IN)
- ^ (epwrite->bEndpointAddress & USB_DIR_IN)) != USB_DIR_IN) {
- /* not suitable */
- goto next_interface;
- }
-
- if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
- /* descriptors are swapped */
- epread = &ifdata->endpoint[1].desc;
- epwrite = &ifdata->endpoint[0].desc;
- }
- dev_dbg(&intf->dev, "found data interface at %d\n", j);
- break;
- } else {
-next_interface:
- ifdata = NULL;
- data = NULL;
+ int minor;
+ int ctrlsize,readsize;
+ char *buf;
+
+ if (!buffer) {
+ err("Wierd descriptor references");
+ return -EINVAL;
+ }
+
+ while (buflen > 0) {
+ if (buffer [1] != USB_DT_CS_INTERFACE) {
+ err("skipping garbage");
+ goto next_desc;
}
+
+ switch (buffer [2]) {
+ case CDC_UNION_TYPE: /* we've found it */
+ if (union_header) {
+ err("More than one union descriptor, skipping ...");
+ goto next_desc;
+ }
+ union_header = (struct union_desc *)buffer;
+ break;
+ default:
+ err("Ignoring extra header");
+ break;
+ }
+next_desc:
+ buflen -= buffer[0];
+ buffer += buffer[0];
+ }
+
+ if (!union_header) {
+ dev_dbg(&intf->dev,"No union descriptor, giving up\n");
+ return -ENODEV;
}
- /* there's been a problem */
- if (!ifdata) {
- dev_dbg(&intf->dev, "data interface not found\n");
+ control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
+ data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0);
+ if (!control_interface || !data_interface) {
+ dev_dbg(&intf->dev,"no interfaces\n");
return -ENODEV;
+ }
+
+ if (usb_interface_claimed(data_interface)) { /* valid in this context */
+ dev_dbg(&intf->dev,"The data interface isn't available\n");
+ return -EBUSY;
+ }
+
+ /*workaround for switched interfaces */
+ if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
+ if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
+ struct usb_interface *t;
+ dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
+ t = control_interface;
+ control_interface = data_interface;
+ data_interface = t;
+ } else {
+ return -EINVAL;
+ }
}
+ if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
+ return -EINVAL;
+
+ epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
+ epread = &data_interface->cur_altsetting->endpoint[0].desc;
+ epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
+
+ /* workaround for switched endpoints */
+ if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
+ /* descriptors are swapped */
+ struct usb_endpoint_descriptor *t;
+ dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
+
+ t = epread;
+ epread = epwrite;
+ epwrite = t;
+ }
+ dbg("interfaces are valid");
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
+
if (acm_table[minor]) {
err("no more free acm devices");
return -ENODEV;
dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n");
return -ENOMEM;
}
-
memset(acm, 0, sizeof(struct acm));
ctrlsize = epctrl->wMaxPacketSize;
readsize = epread->wMaxPacketSize;
acm->writesize = epwrite->wMaxPacketSize;
- acm->control = intf;
- acm->data = data;
+ acm->control = control_interface;
+ acm->data = data_interface;
acm->minor = minor;
- acm->dev = dev;
+ acm->dev = usb_dev;
acm->bh.func = acm_rx_tasklet;
acm->bh.data = (unsigned long) acm;
INIT_WORK(&acm->work, acm_softint, acm);
+ acm->ready_for_write = 1;
+
if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
dev_dbg(&intf->dev, "out of memory (buf kmalloc)\n");
return -ENOMEM;
}
- usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
- buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+ usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress),
+ buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
- usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
- buf += ctrlsize, readsize, acm_read_bulk, acm);
+ usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
+ buf += ctrlsize, readsize, acm_read_bulk, acm);
acm->readurb->transfer_flags |= URB_NO_FSBR;
- usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
- buf += readsize, acm->writesize, acm_write_bulk, acm);
+ usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+ buf += readsize, acm->writesize, acm_write_bulk, acm);
acm->writeurb->transfer_flags |= URB_NO_FSBR;
- if ( (j = usb_driver_claim_interface(&acm_driver, data, acm)) != 0) {
- err("claim failed");
- usb_free_urb(acm->ctrlurb);
- usb_free_urb(acm->readurb);
- usb_free_urb(acm->writeurb);
- kfree(acm);
- kfree(buf);
- return j;
- }
-
- tty_register_device(acm_tty_driver, minor, &intf->dev);
-
dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
acm_set_control(acm, acm->ctrlout);
acm->line.databits = 8;
acm_set_line(acm, &acm->line);
+ usb_driver_claim_interface(&acm_driver, data_interface, acm);
+
+ tty_register_device(acm_tty_driver, minor, &intf->dev);
+
acm_table[minor] = acm;
usb_set_intfdata (intf, acm);
return 0;
}
-#undef CHECK_XFERTYPE
static void acm_disconnect(struct usb_interface *intf)
{
usb_unlink_urb(acm->readurb);
usb_unlink_urb(acm->writeurb);
+ flush_scheduled_work(); /* wait for acm_softint */
+
kfree(acm->ctrlurb->transfer_buffer);
usb_driver_release_interface(&acm_driver, acm->data);
#define IOCNR_HP_SET_CHANNEL 4
#define IOCNR_GET_BUS_ADDRESS 5
#define IOCNR_GET_VID_PID 6
+#define IOCNR_SOFT_RESET 7
/* Get device_id string: */
#define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len)
/* The following ioctls were added for http://hpoj.sourceforge.net: */
#define LPIOC_GET_BUS_ADDRESS(len) _IOC(_IOC_READ, 'P', IOCNR_GET_BUS_ADDRESS, len)
/* Get two-int array: [0]=vendor ID, [1]=product ID: */
#define LPIOC_GET_VID_PID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_VID_PID, len)
+/* Perform class specific soft reset */
+#define LPIOC_SOFT_RESET _IOC(_IOC_NONE, 'P', IOCNR_SOFT_RESET, 0);
/*
* A DEVICE_ID string may include the printer's serial number.
usblp->minor, twoints[0], twoints[1]);
break;
+ case IOCNR_SOFT_RESET:
+ if (_IOC_DIR(cmd) != _IOC_NONE) {
+ retval = -EINVAL;
+ goto done;
+ }
+ retval = usblp_reset(usblp);
+ break;
default:
retval = -ENOTTY;
}
usblp->minor, usblp->readurb->status);
usblp->readurb->dev = usblp->dev;
usblp->readcount = 0;
+ usblp->rcomplete = 0;
if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
dbg("error submitting urb");
count = -EIO;
bus = list_entry(buslist, struct usb_bus, bus_list);
/* recurse through all children of the root hub */
+ if (!bus->root_hub)
+ continue;
down(&bus->root_hub->serialize);
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
up(&bus->root_hub->serialize);
if (usbfs_snoop) {
dev_info(&dev->dev, "control read: data ");
for (j = 0; j < ctrl.wLength; ++j)
- printk ("%02x ", (unsigned char)((char *)ctrl.data)[j]);
+ printk ("%02x ", (unsigned char)(tbuf)[j]);
printk("\n");
}
if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) {
if (usbfs_snoop) {
dev_info(&dev->dev, "control write: data: ");
for (j = 0; j < ctrl.wLength; ++j)
- printk ("%02x ", (unsigned char)((char *)ctrl.data)[j]);
+ printk ("%02x ", (unsigned char)(tbuf)[j]);
printk("\n");
}
i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType,
static int proc_resetdevice(struct dev_state *ps)
{
- return usb_reset_device(ps->dev);
+ return __usb_reset_device(ps->dev);
}
isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb.number_of_packets;
if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
return -ENOMEM;
- if (copy_from_user(isopkt, &((struct usbdevfs_urb *)arg)->iso_frame_desc, isofrmlen)) {
+ if (copy_from_user(isopkt, &((struct usbdevfs_urb __user *)arg)->iso_frame_desc, isofrmlen)) {
kfree(isopkt);
return -EFAULT;
}
free_async(as);
if (ret)
return ret;
- if (put_user(addr, (void **)arg))
+ if (put_user(addr, (void __user * __user *)arg))
return -EFAULT;
return 0;
}
free_async(as);
if (ret)
return ret;
- if (put_user(addr, (void **)arg))
+ if (put_user(addr, (void __user * __user *)arg))
return -EFAULT;
return 0;
}
{
struct dev_state *ps = (struct dev_state *)file->private_data;
struct usb_device *dev = ps->dev;
+ void __user *p = (void __user *)arg;
int ret = -ENOTTY;
if (!(file->f_mode & FMODE_WRITE))
switch (cmd) {
case USBDEVFS_CONTROL:
snoop(&dev->dev, "%s: CONTROL\n", __FUNCTION__);
- ret = proc_control(ps, (void __user *)arg);
+ ret = proc_control(ps, p);
if (ret >= 0)
inode->i_mtime = CURRENT_TIME;
break;
case USBDEVFS_BULK:
snoop(&dev->dev, "%s: BULK\n", __FUNCTION__);
- ret = proc_bulk(ps, (void __user *)arg);
+ ret = proc_bulk(ps, p);
if (ret >= 0)
inode->i_mtime = CURRENT_TIME;
break;
case USBDEVFS_RESETEP:
snoop(&dev->dev, "%s: RESETEP\n", __FUNCTION__);
- ret = proc_resetep(ps, (void __user *)arg);
+ ret = proc_resetep(ps, p);
if (ret >= 0)
inode->i_mtime = CURRENT_TIME;
break;
case USBDEVFS_CLEAR_HALT:
snoop(&dev->dev, "%s: CLEAR_HALT\n", __FUNCTION__);
- ret = proc_clearhalt(ps, (void __user *)arg);
+ ret = proc_clearhalt(ps, p);
if (ret >= 0)
inode->i_mtime = CURRENT_TIME;
break;
case USBDEVFS_GETDRIVER:
snoop(&dev->dev, "%s: GETDRIVER\n", __FUNCTION__);
- ret = proc_getdriver(ps, (void __user *)arg);
+ ret = proc_getdriver(ps, p);
break;
case USBDEVFS_CONNECTINFO:
snoop(&dev->dev, "%s: CONNECTINFO\n", __FUNCTION__);
- ret = proc_connectinfo(ps, (void __user *)arg);
+ ret = proc_connectinfo(ps, p);
break;
case USBDEVFS_SETINTERFACE:
snoop(&dev->dev, "%s: SETINTERFACE\n", __FUNCTION__);
- ret = proc_setintf(ps, (void __user *)arg);
+ ret = proc_setintf(ps, p);
break;
case USBDEVFS_SETCONFIGURATION:
snoop(&dev->dev, "%s: SETCONFIGURATION\n", __FUNCTION__);
- ret = proc_setconfig(ps, (void __user *)arg);
+ ret = proc_setconfig(ps, p);
break;
case USBDEVFS_SUBMITURB:
snoop(&dev->dev, "%s: SUBMITURB\n", __FUNCTION__);
- ret = proc_submiturb(ps, (void __user *)arg);
+ ret = proc_submiturb(ps, p);
if (ret >= 0)
inode->i_mtime = CURRENT_TIME;
break;
case USBDEVFS_DISCARDURB:
snoop(&dev->dev, "%s: DISCARDURB\n", __FUNCTION__);
- ret = proc_unlinkurb(ps, (void __user *)arg);
+ ret = proc_unlinkurb(ps, p);
break;
case USBDEVFS_REAPURB:
snoop(&dev->dev, "%s: REAPURB\n", __FUNCTION__);
- ret = proc_reapurb(ps, (void __user *)arg);
+ ret = proc_reapurb(ps, p);
break;
case USBDEVFS_REAPURBNDELAY:
snoop(&dev->dev, "%s: REAPURBDELAY\n", __FUNCTION__);
- ret = proc_reapurbnonblock(ps, (void __user *)arg);
+ ret = proc_reapurbnonblock(ps, p);
break;
case USBDEVFS_DISCSIGNAL:
snoop(&dev->dev, "%s: DISCSIGNAL\n", __FUNCTION__);
- ret = proc_disconnectsignal(ps, (void __user *)arg);
+ ret = proc_disconnectsignal(ps, p);
break;
case USBDEVFS_CLAIMINTERFACE:
snoop(&dev->dev, "%s: CLAIMINTERFACE\n", __FUNCTION__);
- ret = proc_claiminterface(ps, (void __user *)arg);
+ ret = proc_claiminterface(ps, p);
break;
case USBDEVFS_RELEASEINTERFACE:
snoop(&dev->dev, "%s: RELEASEINTERFACE\n", __FUNCTION__);
- ret = proc_releaseinterface(ps, (void __user *)arg);
+ ret = proc_releaseinterface(ps, p);
break;
case USBDEVFS_IOCTL:
snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
- ret = proc_ioctl(ps, (void __user *) arg);
+ ret = proc_ioctl(ps, p);
break;
}
up(&dev->serialize);
void usb_hcd_pci_remove (struct pci_dev *dev)
{
struct usb_hcd *hcd;
- struct usb_device *hub;
hcd = pci_get_drvdata(dev);
if (!hcd)
if (in_interrupt ())
BUG ();
- hub = hcd->self.root_hub;
if (HCD_IS_RUNNING (hcd->state))
hcd->state = USB_STATE_QUIESCING;
dev_dbg (hcd->self.controller, "roothub graceful disconnect\n");
- usb_disconnect (&hub);
+ usb_disconnect (&hcd->self.root_hub);
hcd->driver->stop (hcd);
hcd_buffer_destroy (hcd);
*
* The USB host controller calls this function to register the root hub
* properly with the USB subsystem. It sets up the device properly in
- * the device model tree, and then calls usb_new_device() to register the
- * usb device. It also assigns the root hub's USB address (always 1).
+ * the device tree and stores the root_hub pointer in the bus structure,
+ * then calls usb_new_device() to register the usb device. It also
+ * assigns the root hub's USB address (always 1).
*/
int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev)
{
memset (&usb_dev->bus->devmap.devicemap, 0,
sizeof usb_dev->bus->devmap.devicemap);
set_bit (devnum, usb_dev->bus->devmap.devicemap);
- usb_dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
+
+ down (&usb_bus_list_lock);
+ usb_dev->bus->root_hub = usb_dev;
usb_dev->epmaxpacketin[0] = usb_dev->epmaxpacketout[0] = 64;
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
return (retval < 0) ? retval : -EMSGSIZE;
}
- (void) usb_get_dev (usb_dev);
down (&usb_dev->serialize);
retval = usb_new_device (usb_dev);
- if (retval)
+ up (&usb_dev->serialize);
+ if (retval) {
+ usb_dev->bus->root_hub = NULL;
dev_err (parent_dev, "can't register root hub for %s, %d\n",
usb_dev->dev.bus_id, retval);
- up (&usb_dev->serialize);
- usb_put_dev (usb_dev);
+ }
+ up (&usb_bus_list_lock);
return retval;
}
EXPORT_SYMBOL (usb_register_root_hub);
unsigned i;
/* hc's root hub is removed later removed in hcd->stop() */
- hub->state = USB_STATE_NOTATTACHED;
+ down (&hub->serialize);
+ usb_set_device_state(hub, USB_STATE_NOTATTACHED);
for (i = 0; i < hub->maxchild; i++) {
if (hub->children [i])
usb_disconnect (&hub->children [i]);
}
+ up (&hub->serialize);
}
/**
struct usb_bus *, unsigned port);
extern int usb_new_device(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);
-extern void usb_choose_address(struct usb_device *dev);
-extern void usb_release_address(struct usb_device *dev);
-/* exported to hub driver ONLY to support usb_reset_device () */
extern int usb_get_configuration(struct usb_device *dev);
extern void usb_destroy_configuration(struct usb_device *dev);
-/* use these only before the device's address has been set */
-#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30))
-#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | USB_DIR_IN)
-
/*-------------------------------------------------------------------------*/
/*
extern int usb_register_root_hub (struct usb_device *usb_dev,
struct device *parent_dev);
-static inline int hcd_register_root (struct usb_hcd *hcd)
+static inline int hcd_register_root (struct usb_device *usb_dev,
+ struct usb_hcd *hcd)
{
/* hcd->driver->start() reported can_wakeup, probably with
* assistance from board's boot firmware.
dev_dbg (hcd->self.controller, "supports USB remote wakeup\n");
hcd->remote_wakeup = hcd->can_wakeup;
- return usb_register_root_hub (
- hcd_to_bus (hcd)->root_hub, hcd->self.controller);
+ return usb_register_root_hub (usb_dev, hcd->self.controller);
}
/*-------------------------------------------------------------------------*/
*/
#include <linux/config.h>
+#ifdef CONFIG_USB_DEBUG
+ #define DEBUG
+#else
+ #undef DEBUG
+#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/ioctl.h>
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
#include <linux/suspend.h>
#include "hcd.h"
#include "hub.h"
+/* Protect all struct usb_device state members */
+static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED;
+
/* Wakes up khubd */
static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */
-static LIST_HEAD(hub_list); /* List of all hubs (for cleanup) */
static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
static pid_t khubd_pid = 0; /* PID of khubd */
{
struct usb_hub *hub = (struct usb_hub *)urb->context;
int status;
+ int i;
+ unsigned long bits;
spin_lock(&hub_event_lock);
hub->urb_active = 0;
/* let khubd handle things */
case 0: /* we got data: port status changed */
+ bits = 0;
+ for (i = 0; i < urb->actual_length; ++i)
+ bits |= ((unsigned long) ((*hub->buffer)[i]))
+ << (i*8);
+ hub->event_bits[0] = bits;
break;
}
/* Something happened, let khubd figure it out */
if (list_empty(&hub->event_list)) {
- list_add(&hub->event_list, &hub_event_list);
+ list_add_tail(&hub->event_list, &hub_event_list);
wake_up(&khubd_wait);
}
if ((status = usb_submit_urb (hub->urb, GFP_ATOMIC)) != 0
/* ENODEV means we raced disconnect() */
&& status != -ENODEV)
- dev_err (&hub->intf->dev, "resubmit --> %d\n", urb->status);
+ dev_err (&hub->intf->dev, "resubmit --> %d\n", status);
if (status == 0)
hub->urb_active = 1;
done:
{
struct usb_hub *hub = usb_get_intfdata (intf);
DECLARE_COMPLETION(urb_complete);
- unsigned long flags;
if (!hub)
return;
highspeed_hubs--;
usb_set_intfdata (intf, NULL);
- spin_lock_irqsave(&hub_event_lock, flags);
+ spin_lock_irq(&hub_event_lock);
hub->urb_complete = &urb_complete;
/* Delete it and then reset it */
list_del_init(&hub->event_list);
- list_del_init(&hub->hub_list);
- spin_unlock_irqrestore(&hub_event_lock, flags);
-
- down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
- up(&hub->khubd_sem);
+ spin_unlock_irq(&hub_event_lock);
/* assuming we used keventd, it must quiesce too */
if (hub->has_indicators)
struct usb_device *hdev;
struct usb_hub *hub;
struct device *hub_dev;
- unsigned long flags;
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);
}
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
- if (desc->desc.bNumEndpoints != 1) {
+ if (desc->desc.bNumEndpoints != 1)
goto descriptor_error;
- }
endpoint = &desc->endpoint[0].desc;
/* Output endpoint? Curiouser and curiouser.. */
- if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
+ if (!(endpoint->bEndpointAddress & USB_DIR_IN))
goto descriptor_error;
- }
/* If it's not an interrupt endpoint, we'd better punt! */
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- != USB_ENDPOINT_XFER_INT) {
+ != USB_ENDPOINT_XFER_INT)
goto descriptor_error;
- return -EIO;
- }
/* We found a hub */
dev_info (hub_dev, "USB hub found\n");
INIT_LIST_HEAD(&hub->event_list);
hub->intf = intf;
- init_MUTEX(&hub->khubd_sem);
INIT_WORK(&hub->leds, led_work, hub);
- /* Record the new hub's existence */
- spin_lock_irqsave(&hub_event_lock, flags);
- INIT_LIST_HEAD(&hub->hub_list);
- list_add(&hub->hub_list, &hub_list);
- spin_unlock_irqrestore(&hub_event_lock, flags);
-
usb_set_intfdata (intf, hub);
if (hdev->speed == USB_SPEED_HIGH)
return 0;
}
+/* FIXME! This routine should be subsumed into hub_reset */
static void hub_start_disconnect(struct usb_device *hdev)
{
struct usb_device *parent = hdev->parent;
dev_err(&hdev->dev, "cannot disconnect hub!\n");
}
+
+static void recursively_mark_NOTATTACHED(struct usb_device *udev)
+{
+ int i;
+
+ for (i = 0; i < udev->maxchild; ++i) {
+ if (udev->children[i])
+ recursively_mark_NOTATTACHED(udev->children[i]);
+ }
+ udev->state = USB_STATE_NOTATTACHED;
+}
+
+/**
+ * usb_set_device_state - change a device's current state (usbcore-internal)
+ * @udev: pointer to device whose state should be changed
+ * @new_state: new state value to be stored
+ *
+ * udev->state is _not_ protected by the udev->serialize semaphore. This
+ * is so that devices can be marked as disconnected as soon as possible,
+ * without having to wait for the semaphore to be released. Instead,
+ * changes to the state must be protected by the device_state_lock spinlock.
+ *
+ * Once a device has been added to the device tree, all changes to its state
+ * should be made using this routine. The state should _not_ be set directly.
+ *
+ * If udev->state is already USB_STATE_NOTATTACHED then no change is made.
+ * Otherwise udev->state is set to new_state, and if new_state is
+ * USB_STATE_NOTATTACHED then all of udev's descendant's states are also set
+ * to USB_STATE_NOTATTACHED.
+ */
+void usb_set_device_state(struct usb_device *udev,
+ enum usb_device_state new_state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&device_state_lock, flags);
+ if (udev->state == USB_STATE_NOTATTACHED)
+ ; /* do nothing */
+ else if (new_state != USB_STATE_NOTATTACHED)
+ udev->state = new_state;
+ else
+ recursively_mark_NOTATTACHED(udev);
+ spin_unlock_irqrestore(&device_state_lock, flags);
+}
+
+
+static void choose_address(struct usb_device *udev)
+{
+ int devnum;
+ struct usb_bus *bus = udev->bus;
+
+ /* If khubd ever becomes multithreaded, this will need a lock */
+
+ /* Try to allocate the next devnum beginning at bus->devnum_next. */
+ devnum = find_next_zero_bit(bus->devmap.devicemap, 128,
+ bus->devnum_next);
+ if (devnum >= 128)
+ devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1);
+
+ bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
+
+ if (devnum < 128) {
+ set_bit(devnum, bus->devmap.devicemap);
+ udev->devnum = devnum;
+ }
+}
+
+static void release_address(struct usb_device *udev)
+{
+ if (udev->devnum > 0) {
+ clear_bit(udev->devnum, udev->bus->devmap.devicemap);
+ udev->devnum = -1;
+ }
+}
+
+/**
+ * usb_disconnect - disconnect a device (usbcore-internal)
+ * @pdev: pointer to device being disconnected
+ * Context: !in_interrupt ()
+ *
+ * Something got disconnected. Get rid of it, and all of its children.
+ * If *pdev is a normal device then the parent hub should be locked.
+ * If *pdev is a root hub then this routine will acquire the
+ * usb_bus_list_lock on behalf of the caller.
+ *
+ * Only hub drivers (including virtual root hub drivers for host
+ * controllers) should ever call this.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ */
+void usb_disconnect(struct usb_device **pdev)
+{
+ struct usb_device *udev = *pdev;
+ int i;
+
+ if (!udev) {
+ pr_debug ("%s nodev\n", __FUNCTION__);
+ return;
+ }
+
+ /* mark the device as inactive, so any further urb submissions for
+ * this device will fail.
+ */
+ usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+
+ /* lock the bus list on behalf of HCDs unregistering their root hubs */
+ if (!udev->parent)
+ down(&usb_bus_list_lock);
+ down(&udev->serialize);
+
+ dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum);
+
+ /* Free up all the children before we remove this device */
+ for (i = 0; i < USB_MAXCHILDREN; i++) {
+ if (udev->children[i])
+ usb_disconnect(&udev->children[i]);
+ }
+
+ /* deallocate hcd/hardware state ... nuking all pending urbs and
+ * cleaning up all state associated with the current configuration
+ */
+ usb_disable_device(udev, 0);
+
+ /* Free the device number, remove the /proc/bus/usb entry and
+ * the sysfs attributes, and delete the parent's children[]
+ * (or root_hub) pointer.
+ */
+ dev_dbg (&udev->dev, "unregistering device\n");
+ release_address(udev);
+ usbfs_remove_device(udev);
+ usb_remove_sysfs_dev_files(udev);
+
+ /* Avoid races with recursively_mark_NOTATTACHED() */
+ spin_lock_irq(&device_state_lock);
+ *pdev = NULL;
+ spin_unlock_irq(&device_state_lock);
+
+ up(&udev->serialize);
+ if (!udev->parent)
+ up(&usb_bus_list_lock);
+
+ device_unregister(&udev->dev);
+}
+
+static int choose_configuration(struct usb_device *udev)
+{
+ int c, i;
+
+ /* NOTE: this should interact with hub power budgeting */
+
+ c = udev->config[0].desc.bConfigurationValue;
+ if (udev->descriptor.bNumConfigurations != 1) {
+ for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
+ struct usb_interface_descriptor *desc;
+
+ /* heuristic: Linux is more likely to have class
+ * drivers, so avoid vendor-specific interfaces.
+ */
+ desc = &udev->config[i].intf_cache[0]
+ ->altsetting->desc;
+ if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+ continue;
+ /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
+ if (desc->bInterfaceClass == USB_CLASS_COMM
+ && desc->bInterfaceSubClass == 2
+ && desc->bInterfaceProtocol == 0xff)
+ continue;
+ c = udev->config[i].desc.bConfigurationValue;
+ break;
+ }
+ dev_info(&udev->dev,
+ "configuration #%d chosen from %d choices\n",
+ c, udev->descriptor.bNumConfigurations);
+ }
+ return c;
+}
+
+#ifdef DEBUG
+static void show_string(struct usb_device *udev, char *id, int index)
+{
+ char *buf;
+
+ if (!index)
+ return;
+ if (!(buf = kmalloc(256, GFP_KERNEL)))
+ return;
+ if (usb_string(udev, index, buf, 256) > 0)
+ dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, buf);
+ kfree(buf);
+}
+
+#else
+static inline void show_string(struct usb_device *udev, char *id, int index)
+{}
+#endif
+
+/*
+ * usb_new_device - perform initial device setup (usbcore-internal)
+ * @udev: newly addressed device (in ADDRESS state)
+ *
+ * This is called with devices which have been enumerated, but not yet
+ * configured. The device descriptor is available, but not descriptors
+ * for any device configuration. The caller must have locked udev and
+ * either the parent hub (if udev is a normal device) or else the
+ * usb_bus_list_lock (if udev is a root hub). The parent's pointer to
+ * udev has already been installed, but udev is not yet visible through
+ * sysfs or other filesystem code.
+ *
+ * Returns 0 for success (device is configured and listed, with its
+ * interfaces, in sysfs); else a negative errno value.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Only the hub driver should ever call this; root hub registration
+ * uses it indirectly.
+ */
+int usb_new_device(struct usb_device *udev)
+{
+ int err;
+ int c;
+
+ err = usb_get_configuration(udev);
+ if (err < 0) {
+ dev_err(&udev->dev, "can't read configurations, error %d\n",
+ err);
+ goto fail;
+ }
+
+ /* Tell the world! */
+ dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, "
+ "SerialNumber=%d\n",
+ udev->descriptor.iManufacturer,
+ udev->descriptor.iProduct,
+ udev->descriptor.iSerialNumber);
+
+ if (udev->descriptor.iProduct)
+ show_string(udev, "Product",
+ udev->descriptor.iProduct);
+ if (udev->descriptor.iManufacturer)
+ show_string(udev, "Manufacturer",
+ udev->descriptor.iManufacturer);
+ if (udev->descriptor.iSerialNumber)
+ show_string(udev, "SerialNumber",
+ udev->descriptor.iSerialNumber);
+
+ /* put device-specific files into sysfs */
+ err = device_add (&udev->dev);
+ if (err) {
+ dev_err(&udev->dev, "can't device_add, error %d\n", err);
+ goto fail;
+ }
+ usb_create_sysfs_dev_files (udev);
+
+ /* choose and set the configuration. that registers the interfaces
+ * with the driver core, and lets usb device drivers bind to them.
+ */
+ c = choose_configuration(udev);
+ if (c < 0)
+ dev_warn(&udev->dev,
+ "can't choose an initial configuration\n");
+ else {
+ err = usb_set_configuration(udev, c);
+ if (err) {
+ dev_err(&udev->dev, "can't set config #%d, error %d\n",
+ c, err);
+ usb_remove_sysfs_dev_files(udev);
+ device_del(&udev->dev);
+ goto fail;
+ }
+ }
+
+ /* USB device state == configured ... usable */
+
+ /* add a /proc/bus/usb entry */
+ usbfs_add_device(udev);
+ return 0;
+
+fail:
+ usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+ return err;
+}
+
+
static int hub_port_status(struct usb_device *hdev, int port,
u16 *status, u16 *change)
{
/* Reset the port */
for (i = 0; i < PORT_RESET_TRIES; i++) {
- set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
+ status = set_port_feature(hdev, port + 1, USB_PORT_FEAT_RESET);
+ if (status)
+ dev_err(hub_dev, "cannot reset port %d (err = %d)\n",
+ port + 1, status);
+ else
+ status = hub_port_wait_reset(hdev, port, udev, delay);
/* return on disconnect or reset */
- status = hub_port_wait_reset(hdev, port, udev, delay);
if (status == -ENOTCONN || status == 0) {
clear_port_feature(hdev,
port + 1, USB_PORT_FEAT_C_RESET);
- udev->state = status
+ usb_set_device_state(udev, status
? USB_STATE_NOTATTACHED
- : USB_STATE_DEFAULT;
+ : USB_STATE_DEFAULT);
return status;
}
{
int ret;
+ if (hdev->children[port])
+ usb_set_device_state(hdev->children[port],
+ USB_STATE_NOTATTACHED);
ret = clear_port_feature(hdev, port + 1, USB_PORT_FEAT_ENABLE);
if (ret)
dev_err(hubdev(hdev), "cannot disable port %d (err = %d)\n",
/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
*
* Between connect detection and reset signaling there must be a delay
- * of 100ms at least for debounce and power-settling. The corresponding
+ * of 100ms at least for debounce and power-settling. The corresponding
* timer shall restart whenever the downstream port detects a disconnect.
*
- * Apparently there are some bluetooth and irda-dongles and a number
- * of low-speed devices which require longer delays of about 200-400ms.
+ * Apparently there are some bluetooth and irda-dongles and a number of
+ * low-speed devices for which this debounce period may last over a second.
* Not covered by the spec - but easy to deal with.
*
- * This implementation uses 400ms minimum debounce timeout and checks
- * every 25ms for transient disconnects to restart the delay.
+ * This implementation uses a 1500ms total debounce timeout; if the
+ * connection isn't stable by then it returns -ETIMEDOUT. It checks
+ * every 25ms for transient disconnects. When the port status has been
+ * unchanged for 100ms it returns the port status.
*/
-#define HUB_DEBOUNCE_TIMEOUT 400
-#define HUB_DEBOUNCE_STEP 25
-#define HUB_DEBOUNCE_STABLE 4
+#define HUB_DEBOUNCE_TIMEOUT 1500
+#define HUB_DEBOUNCE_STEP 25
+#define HUB_DEBOUNCE_STABLE 100
static int hub_port_debounce(struct usb_device *hdev, int port)
{
int ret;
- int delay_time, stable_count;
+ int total_time, stable_time = 0;
u16 portchange, portstatus;
- unsigned connection;
-
- connection = 0;
- stable_count = 0;
- for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; delay_time += HUB_DEBOUNCE_STEP) {
- msleep(HUB_DEBOUNCE_STEP);
+ unsigned connection = 0xffff;
+ for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
ret = hub_port_status(hdev, port, &portstatus, &portchange);
if (ret < 0)
return ret;
- if ((portstatus & USB_PORT_STAT_CONNECTION) == connection) {
- if (connection) {
- if (++stable_count == HUB_DEBOUNCE_STABLE)
- break;
- }
+ if (!(portchange & USB_PORT_STAT_C_CONNECTION) &&
+ (portstatus & USB_PORT_STAT_CONNECTION) == connection) {
+ stable_time += HUB_DEBOUNCE_STEP;
+ if (stable_time >= HUB_DEBOUNCE_STABLE)
+ break;
} else {
- stable_count = 0;
+ stable_time = 0;
+ connection = portstatus & USB_PORT_STAT_CONNECTION;
}
- connection = portstatus & USB_PORT_STAT_CONNECTION;
- if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
- clear_port_feature(hdev, port+1, USB_PORT_FEAT_C_CONNECTION);
+ if (portchange & USB_PORT_STAT_C_CONNECTION) {
+ clear_port_feature(hdev, port+1,
+ USB_PORT_FEAT_C_CONNECTION);
}
+
+ if (total_time >= HUB_DEBOUNCE_TIMEOUT)
+ break;
+ msleep(HUB_DEBOUNCE_STEP);
}
dev_dbg (hubdev (hdev),
- "debounce: port %d: delay %dms stable %d status 0x%x\n",
- port + 1, delay_time, stable_count, portstatus);
+ "debounce: port %d: total %dms stable %dms status 0x%x\n",
+ port + 1, total_time, stable_time, portstatus);
- return (portstatus & USB_PORT_STAT_CONNECTION) ? 0 : -ENOTCONN;
+ if (stable_time < HUB_DEBOUNCE_STABLE)
+ return -ETIMEDOUT;
+ return portstatus;
}
static int hub_set_address(struct usb_device *udev)
if (udev->state != USB_STATE_DEFAULT &&
udev->state != USB_STATE_ADDRESS)
return -EINVAL;
- retval = usb_control_msg(udev, usb_snddefctrl(udev),
+ retval = usb_control_msg(udev, (PIPE_CONTROL << 30) /* Address 0 */,
USB_REQ_SET_ADDRESS, 0, udev->devnum, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (retval == 0)
- udev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(udev, USB_STATE_ADDRESS);
return retval;
}
udev->epmaxpacketin [0] = i;
udev->epmaxpacketout[0] = i;
- /* set the address */
- if (udev->devnum <= 0) {
- usb_choose_address(udev);
- if (udev->devnum <= 0)
- goto fail;
-
- /* Set up TT records, if needed */
- if (hdev->tt) {
- udev->tt = hdev->tt;
- udev->ttport = hdev->ttport;
- } else if (udev->speed != USB_SPEED_HIGH
- && hdev->speed == USB_SPEED_HIGH) {
- struct usb_hub *hub;
-
- hub = usb_get_intfdata (hdev->actconfig
- ->interface[0]);
- udev->tt = &hub->tt;
- udev->ttport = port + 1;
- }
-
- /* force the right log message (below) at low speed */
- oldspeed = USB_SPEED_UNKNOWN;
- }
-
dev_info (&udev->dev,
"%s %s speed USB device using address %d\n",
- (oldspeed == USB_SPEED_UNKNOWN) ? "new" : "reset",
+ (udev->config) ? "reset" : "new",
({ char *speed; switch (udev->speed) {
case USB_SPEED_LOW: speed = "low"; break;
case USB_SPEED_FULL: speed = "full"; break;
default: speed = "?"; break;
}; speed;}),
udev->devnum);
+
+ /* Set up TT records, if needed */
+ if (hdev->tt) {
+ udev->tt = hdev->tt;
+ udev->ttport = hdev->ttport;
+ } else if (udev->speed != USB_SPEED_HIGH
+ && hdev->speed == USB_SPEED_HIGH) {
+ struct usb_hub *hub;
+
+ hub = usb_get_intfdata(hdev->actconfig->interface[0]);
+ udev->tt = &hub->tt;
+ udev->ttport = port + 1;
+ }
/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
* Because device hardware and firmware is sometimes buggy in
dev_err(&udev->dev,
"device not accepting address %d, error %d\n",
udev->devnum, retval);
- fail:
- hub_port_disable(hdev, port);
- usb_release_address(udev);
- usb_put_dev(udev);
- up(&usb_address0_sem);
- return retval;
+ goto fail;
}
/* cope with hardware quirkiness:
if (udev->speed == USB_SPEED_FULL
&& (udev->epmaxpacketin [0]
!= udev->descriptor.bMaxPacketSize0)) {
- usb_disable_endpoint(udev, 0);
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
usb_endpoint_running(udev, 0, 1);
usb_endpoint_running(udev, 0, 0);
udev->epmaxpacketin [0] = udev->descriptor.bMaxPacketSize0;
goto fail;
}
- /* now dev is visible to other tasks */
- hdev->children[port] = udev;
+ retval = 0;
+fail:
up(&usb_address0_sem);
- return 0;
+ return retval;
}
static void
}
return remaining;
}
-
+
+/* Handle physical or logical connection change events.
+ * This routine is called when:
+ * a port connection-change occurs;
+ * a port enable-change occurs (often caused by EMI);
+ * usb_reset_device() encounters changed descriptors (as from
+ * a firmware download)
+ */
static void hub_port_connect_change(struct usb_hub *hub, int port,
u16 portstatus, u16 portchange)
{
dev_dbg (hub_dev,
"port %d, status %04x, change %04x, %s\n",
port + 1, portstatus, portchange, portspeed (portstatus));
-
- /* Clear the connection change status */
- clear_port_feature(hdev, port + 1, USB_PORT_FEAT_C_CONNECTION);
if (hub->has_indicators) {
set_port_led(hdev, port + 1, HUB_LED_AUTO);
if (hdev->children[port])
usb_disconnect(&hdev->children[port]);
+ if (portchange & USB_PORT_STAT_C_CONNECTION) {
+ status = hub_port_debounce(hdev, port);
+ if (status < 0) {
+ dev_err (hub_dev,
+ "connect-debounce failed, port %d disabled\n",
+ port+1);
+ goto done;
+ }
+ portstatus = status;
+ }
+
/* Return now if nothing is connected */
if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
goto done;
return;
}
-
- if (hub_port_debounce(hdev, port)) {
- dev_err (hub_dev,
- "connect-debounce failed, port %d disabled\n",
- port+1);
- goto done;
- }
for (i = 0; i < SET_CONFIG_TRIES; i++) {
struct usb_device *udev;
"couldn't allocate port %d usb_device\n", port+1);
goto done;
}
- udev->state = USB_STATE_POWERED;
-
+
+ usb_set_device_state(udev, USB_STATE_POWERED);
+
/* hub can tell if it's lowspeed already: D- pullup (not D+) */
if (portstatus & USB_PORT_STAT_LOW_SPEED)
udev->speed = USB_SPEED_LOW;
else
udev->speed = USB_SPEED_UNKNOWN;
+
+ /* set the address */
+ choose_address(udev);
+ if (udev->devnum <= 0) {
+ status = -ENOTCONN; /* Don't retry */
+ goto loop;
+ }
- /* reset, set address, get descriptor, add to hub's children */
- down (&udev->serialize);
+ /* reset and get descriptor */
status = hub_port_init(hdev, udev, port);
- if (status == -ENOTCONN)
- break;
if (status < 0)
- continue;
+ goto loop;
/* consecutive bus-powered hubs aren't reliable; they can
* violate the voltage drop budget. if the new child has
&devstat);
if (status < 0) {
dev_dbg(&udev->dev, "get status %d ?\n", status);
- continue;
+ goto loop;
}
cpu_to_le16s(&devstat);
if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
INDICATOR_AMBER_BLINK;
schedule_work (&hub->leds);
}
- hdev->children[port] = NULL;
- usb_put_dev(udev);
- hub_port_disable(hdev, port);
- return;
+ status = -ENOTCONN; /* Don't retry */
+ goto loop;
}
}
&& highspeed_hubs != 0)
check_highspeed (hub, udev, port);
+ /* Store the parent's children[] pointer. At this point
+ * udev becomes globally accessible, although presumably
+ * no one will look at it until hdev is unlocked.
+ */
+ down (&udev->serialize);
+ status = 0;
+
+ /* We mustn't add new devices if the parent hub has
+ * been disconnected; we would race with the
+ * recursively_mark_NOTATTACHED() routine.
+ */
+ spin_lock_irq(&device_state_lock);
+ if (hdev->state == USB_STATE_NOTATTACHED)
+ status = -ENOTCONN;
+ else
+ hdev->children[port] = udev;
+ spin_unlock_irq(&device_state_lock);
+
/* Run it through the hoops (find a driver, etc) */
- status = usb_new_device(udev);
- if (status != 0) {
- hdev->children[port] = NULL;
- continue;
+ if (!status) {
+ status = usb_new_device(udev);
+ if (status) {
+ spin_lock_irq(&device_state_lock);
+ hdev->children[port] = NULL;
+ spin_unlock_irq(&device_state_lock);
+ }
}
+
up (&udev->serialize);
+ if (status)
+ goto loop;
status = hub_power_remaining(hub, hdev);
if (status)
2 * status);
return;
+
+loop:
+ hub_port_disable(hdev, port);
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ release_address(udev);
+ usb_put_dev(udev);
+ if (status == -ENOTCONN)
+ break;
}
done:
static void hub_events(void)
{
- unsigned long flags;
struct list_head *tmp;
struct usb_device *hdev;
struct usb_hub *hub;
u16 portstatus;
u16 portchange;
int i, ret;
+ int connect_change;
/*
* We restart the list every time to avoid a deadlock with
* Not the most efficient, but avoids deadlocks.
*/
while (1) {
- spin_lock_irqsave(&hub_event_lock, flags);
- if (list_empty(&hub_event_list))
+ /* Grab the first entry at the beginning of the list */
+ spin_lock_irq(&hub_event_lock);
+ if (list_empty(&hub_event_list)) {
+ spin_unlock_irq(&hub_event_lock);
break;
+ }
- /* Grab the next entry from the beginning of the list */
tmp = hub_event_list.next;
+ list_del_init(tmp);
hub = list_entry(tmp, struct usb_hub, event_list);
hdev = interface_to_usbdev(hub->intf);
hub_dev = &hub->intf->dev;
- list_del_init(tmp);
-
- if (unlikely(down_trylock(&hub->khubd_sem)))
- BUG(); /* never blocks, we were on list */
+ usb_get_dev(hdev);
+ spin_unlock_irq(&hub_event_lock);
- spin_unlock_irqrestore(&hub_event_lock, flags);
+ /* Lock the device, then check to see if we were
+ * disconnected while waiting for the lock to succeed. */
+ down(&hdev->serialize);
+ if (hdev->state != USB_STATE_CONFIGURED ||
+ !hdev->actconfig ||
+ hub != usb_get_intfdata(
+ hdev->actconfig->interface[0]))
+ goto loop;
if (hub->error) {
dev_dbg (hub_dev, "resetting for error %d\n",
if (hub_reset(hub)) {
dev_dbg (hub_dev,
"can't reset; disconnecting\n");
- up(&hub->khubd_sem);
hub_start_disconnect(hdev);
- continue;
+ goto loop;
}
hub->nerrors = 0;
hub->error = 0;
}
+ /* deal with port status changes */
for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
+ if (!test_and_clear_bit(i+1, hub->event_bits))
+ continue;
ret = hub_port_status(hdev, i, &portstatus, &portchange);
- if (ret < 0) {
+ if (ret < 0)
continue;
- }
+ connect_change = 0;
if (portchange & USB_PORT_STAT_C_CONNECTION) {
- hub_port_connect_change(hub, i, portstatus, portchange);
- } else if (portchange & USB_PORT_STAT_C_ENABLE) {
- dev_dbg (hub_dev,
- "port %d enable change, status %08x\n",
- i + 1, portstatus);
+ clear_port_feature(hdev,
+ i + 1, USB_PORT_FEAT_C_CONNECTION);
+ connect_change = 1;
+ }
+
+ if (portchange & USB_PORT_STAT_C_ENABLE) {
+ if (!connect_change)
+ dev_dbg (hub_dev,
+ "port %d enable change, "
+ "status %08x\n",
+ i + 1, portstatus);
clear_port_feature(hdev,
i + 1, USB_PORT_FEAT_C_ENABLE);
* Works at least with mouse driver.
*/
if (!(portstatus & USB_PORT_STAT_ENABLE)
- && (portstatus & USB_PORT_STAT_CONNECTION)
- && (hdev->children[i])) {
+ && !connect_change
+ && hdev->children[i]) {
dev_err (hub_dev,
"port %i "
"disabled by hub (EMI?), "
"re-enabling...",
i + 1);
- hub_port_connect_change(hub,
- i, portstatus, portchange);
+ connect_change = 1;
}
}
clear_port_feature(hdev,
i + 1, USB_PORT_FEAT_C_RESET);
}
+
+ if (connect_change)
+ hub_port_connect_change(hub, i,
+ portstatus, portchange);
} /* end for i */
/* deal with hub status changes */
- if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
+ if (test_and_clear_bit(0, hub->event_bits) == 0)
+ ; /* do nothing */
+ else if (hub_hub_status(hub, &hubstatus, &hubchange) < 0)
dev_err (hub_dev, "get_hub_status failed\n");
else {
if (hubchange & HUB_CHANGE_LOCAL_POWER) {
hub_power_on(hub);
}
}
- up(&hub->khubd_sem);
- } /* end while (1) */
- spin_unlock_irqrestore(&hub_event_lock, flags);
+loop:
+ up(&hdev->serialize);
+ usb_put_dev(hdev);
+
+ } /* end while (1) */
}
static int hub_thread(void *__unused)
.id_table = hub_id_table,
};
-/*
- * This should be a separate module.
- */
int usb_hub_init(void)
{
pid_t pid;
udev->actconfig->desc.bConfigurationValue, ret);
goto re_enumerate;
}
- udev->state = USB_STATE_CONFIGURED;
+ usb_set_device_state(udev, USB_STATE_CONFIGURED);
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = udev->actconfig->interface[i];
re_enumerate:
/* FIXME make some task re-enumerate; don't just mark unusable */
- udev->state = USB_STATE_NOTATTACHED;
+ hub_port_disable(parent, port);
return -ENODEV;
}
EXPORT_SYMBOL(__usb_reset_device);
int error; /* last reported error */
int nerrors; /* track consecutive errors */
- struct list_head hub_list; /* all hubs */
struct list_head event_list; /* hubs w/data or errs ready */
+ unsigned long event_bits[1]; /* status change bitmask */
+#if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
+#error event_bits[] is too short!
+#endif
struct usb_hub_descriptor *descriptor; /* class descriptor */
- struct semaphore khubd_sem;
struct usb_tt tt; /* Transaction Translator */
u8 power_budget; /* in 2mA units; or zero */
struct work_struct leds;
};
+/* use this for low-powered root hubs */
+static inline void
+hub_set_power_budget (struct usb_device *hubdev, unsigned mA)
+{
+ struct usb_hub *hub;
+
+ hub = (struct usb_hub *)
+ usb_get_intfdata (hubdev->actconfig->interface[0]);
+ hub->power_budget = min(mA,(unsigned)500)/2;
+}
+
#endif /* __LINUX_HUB_H */
*/
int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
{
- int i = 5;
+ int i;
int result;
memset(buf,0,size); // Make sure we parse really received data
- while (i--) {
+ for (i = 0; i < 3; ++i) {
/* retry on length 0 or stall; some devices are flakey */
- if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
- (type << 8) + index, 0, buf, size,
- HZ * USB_CTRL_GET_TIMEOUT)) > 0
- || result != -EPIPE)
+ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (type << 8) + index, 0, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT);
+ if (!(result == 0 || result == -EPIPE))
break;
-
- dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result);
- result = -ENOMSG;
}
return result;
}
interface = dev->actconfig->interface[i];
dev_dbg (&dev->dev, "unregistering interface %s\n",
interface->dev.bus_id);
+ usb_remove_sysfs_intf_files(interface);
device_del (&interface->dev);
}
}
dev->actconfig = 0;
if (dev->state == USB_STATE_CONFIGURED)
- dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
}
}
config->desc.bConfigurationValue, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (retval < 0) {
- dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
return retval;
}
dev->actconfig = cp;
if (!cp)
- dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
else {
- dev->state = USB_STATE_CONFIGURED;
+ usb_set_device_state(dev, USB_STATE_CONFIGURED);
/* Initialize the new interface structures and the
* hc/hcd/usbcore interface/endpoint state.
*/
err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
- if (err == -EPIPE) {
+ if (err == -EPIPE || err == 0) {
dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, 2);
err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
}
len=tbuf[0];
err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
- if (err == -EPIPE) {
+ if (err == -EPIPE || err == 0) {
dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, len);
err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
}
* drivers/usb/core/sysfs.c
*
* (C) Copyright 2002 David Brownell
- * (C) Copyright 2002 Greg Kroah-Hartman
- * (C) Copyright 2002 IBM Corp.
+ * (C) Copyright 2002,2004 Greg Kroah-Hartman
+ * (C) Copyright 2002,2004 IBM Corp.
*
* All of the sysfs file attributes for usb devices and interfaces.
*
usb_descriptor_attr (bDeviceProtocol, "%02x\n")
usb_descriptor_attr (bNumConfigurations, "%d\n")
+static struct attribute *dev_attrs[] = {
+ /* current configuration's attributes */
+ &dev_attr_bNumInterfaces.attr,
+ &dev_attr_bConfigurationValue.attr,
+ &dev_attr_bmAttributes.attr,
+ &dev_attr_bMaxPower.attr,
+ /* device attributes */
+ &dev_attr_idVendor.attr,
+ &dev_attr_idProduct.attr,
+ &dev_attr_bcdDevice.attr,
+ &dev_attr_bDeviceClass.attr,
+ &dev_attr_bDeviceSubClass.attr,
+ &dev_attr_bDeviceProtocol.attr,
+ &dev_attr_bNumConfigurations.attr,
+ &dev_attr_speed.attr,
+ &dev_attr_devnum.attr,
+ &dev_attr_version.attr,
+ &dev_attr_maxchild.attr,
+ NULL,
+};
+static struct attribute_group dev_attr_grp = {
+ .attrs = dev_attrs,
+};
void usb_create_sysfs_dev_files (struct usb_device *udev)
{
struct device *dev = &udev->dev;
- /* current configuration's attributes */
- device_create_file (dev, &dev_attr_bNumInterfaces);
- device_create_file (dev, &dev_attr_bConfigurationValue);
- device_create_file (dev, &dev_attr_bmAttributes);
- device_create_file (dev, &dev_attr_bMaxPower);
-
- /* device attributes */
- device_create_file (dev, &dev_attr_idVendor);
- device_create_file (dev, &dev_attr_idProduct);
- device_create_file (dev, &dev_attr_bcdDevice);
- device_create_file (dev, &dev_attr_bDeviceClass);
- device_create_file (dev, &dev_attr_bDeviceSubClass);
- device_create_file (dev, &dev_attr_bDeviceProtocol);
- device_create_file (dev, &dev_attr_bNumConfigurations);
-
- /* speed varies depending on how you connect the device */
- device_create_file (dev, &dev_attr_speed);
- // FIXME iff there are other speed configs, show how many
+ sysfs_create_group(&dev->kobj, &dev_attr_grp);
if (udev->descriptor.iManufacturer)
device_create_file (dev, &dev_attr_manufacturer);
device_create_file (dev, &dev_attr_product);
if (udev->descriptor.iSerialNumber)
device_create_file (dev, &dev_attr_serial);
+}
+
+void usb_remove_sysfs_dev_files (struct usb_device *udev)
+{
+ struct device *dev = &udev->dev;
- device_create_file (dev, &dev_attr_devnum);
- device_create_file (dev, &dev_attr_version);
- device_create_file (dev, &dev_attr_maxchild);
+ sysfs_remove_group(&dev->kobj, &dev_attr_grp);
+
+ if (udev->descriptor.iManufacturer)
+ device_remove_file(dev, &dev_attr_manufacturer);
+ if (udev->descriptor.iProduct)
+ device_remove_file(dev, &dev_attr_product);
+ if (udev->descriptor.iSerialNumber)
+ device_remove_file(dev, &dev_attr_serial);
}
/* Interface fields */
usb_intf_attr (bInterfaceProtocol, "%02x\n")
usb_intf_attr (iInterface, "%02x\n")
+static struct attribute *intf_attrs[] = {
+ &dev_attr_bInterfaceNumber.attr,
+ &dev_attr_bAlternateSetting.attr,
+ &dev_attr_bNumEndpoints.attr,
+ &dev_attr_bInterfaceClass.attr,
+ &dev_attr_bInterfaceSubClass.attr,
+ &dev_attr_bInterfaceProtocol.attr,
+ &dev_attr_iInterface.attr,
+ NULL,
+};
+static struct attribute_group intf_attr_grp = {
+ .attrs = intf_attrs,
+};
+
void usb_create_sysfs_intf_files (struct usb_interface *intf)
{
- device_create_file (&intf->dev, &dev_attr_bInterfaceNumber);
- device_create_file (&intf->dev, &dev_attr_bAlternateSetting);
- device_create_file (&intf->dev, &dev_attr_bNumEndpoints);
- device_create_file (&intf->dev, &dev_attr_bInterfaceClass);
- device_create_file (&intf->dev, &dev_attr_bInterfaceSubClass);
- device_create_file (&intf->dev, &dev_attr_bInterfaceProtocol);
- device_create_file (&intf->dev, &dev_attr_iInterface);
+ sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
+}
+
+void usb_remove_sysfs_intf_files (struct usb_interface *intf)
+{
+ sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
}
buslist != &usb_bus_list;
buslist = buslist->next) {
bus = container_of(buslist, struct usb_bus, bus_list);
+ if (!bus->root_hub)
+ continue;
dev = match_device(bus->root_hub, vendor_id, product_id);
if (dev)
goto exit;
return -1;
}
-/**
- * usb_disconnect - disconnect a device (usbcore-internal)
- * @pdev: pointer to device being disconnected
- * Context: !in_interrupt ()
- *
- * Something got disconnected. Get rid of it, and all of its children.
- *
- * Only hub drivers (including virtual root hub drivers for host
- * controllers) should ever call this.
- *
- * This call is synchronous, and may not be used in an interrupt context.
- */
-void usb_disconnect(struct usb_device **pdev)
-{
- struct usb_device *dev = *pdev;
- struct usb_bus *bus;
- struct usb_operations *ops;
- int i;
-
- might_sleep ();
-
- if (!dev) {
- pr_debug ("%s nodev\n", __FUNCTION__);
- return;
- }
- bus = dev->bus;
- if (!bus) {
- pr_debug ("%s nobus\n", __FUNCTION__);
- return;
- }
- ops = bus->op;
-
- *pdev = NULL;
-
- /* mark the device as inactive, so any further urb submissions for
- * this device will fail.
- */
- dev->state = USB_STATE_NOTATTACHED;
- down(&dev->serialize);
-
- dev_info (&dev->dev, "USB disconnect, address %d\n", dev->devnum);
-
- /* Free up all the children before we remove this device */
- for (i = 0; i < USB_MAXCHILDREN; i++) {
- struct usb_device **child = dev->children + i;
- if (*child)
- usb_disconnect(child);
- }
-
- /* deallocate hcd/hardware state ... nuking all pending urbs and
- * cleaning up all state associated with the current configuration
- */
- usb_disable_device(dev, 0);
-
- /* Free the device number and remove the /proc/bus/usb entry */
- dev_dbg (&dev->dev, "unregistering device\n");
- usb_release_address(dev);
- usbfs_remove_device(dev);
- up(&dev->serialize);
- device_unregister(&dev->dev);
-}
-
-/**
- * usb_choose_address - pick device address (usbcore-internal)
- * @dev: newly detected device (in DEFAULT state)
- *
- * Picks a device address. It's up to the hub (or root hub) driver
- * to handle and manage enumeration, starting from the DEFAULT state.
- * Only hub drivers (but not virtual root hub drivers for host
- * controllers) should ever call this.
- */
-void usb_choose_address(struct usb_device *dev)
-{
- int devnum;
- // FIXME needs locking for SMP!!
- /* why? this is called only from the hub thread,
- * which hopefully doesn't run on multiple CPU's simultaneously 8-)
- */
-
- /* Try to allocate the next devnum beginning at bus->devnum_next. */
- devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, dev->bus->devnum_next);
- if (devnum >= 128)
- devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
-
- dev->bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
-
- if (devnum < 128) {
- set_bit(devnum, dev->bus->devmap.devicemap);
- dev->devnum = devnum;
- }
-}
-
-/**
- * usb_release_address - deallocate device address (usbcore-internal)
- * @dev: newly removed device
- *
- * Removes and deallocates the address assigned to a device.
- * Only hub drivers (but not virtual root hub drivers for host
- * controllers) should ever call this.
- */
-void usb_release_address(struct usb_device *dev)
-{
- if (dev->devnum > 0) {
- clear_bit(dev->devnum, dev->bus->devmap.devicemap);
- dev->devnum = -1;
- }
-}
-
-
-static inline void usb_show_string(struct usb_device *dev, char *id, int index)
-{
- char *buf;
-
- if (!index)
- return;
- if (!(buf = kmalloc(256, GFP_KERNEL)))
- return;
- if (usb_string(dev, index, buf, 256) > 0)
- dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
- kfree(buf);
-}
-
-static int usb_choose_configuration(struct usb_device *dev)
-{
- int c, i;
-
- c = dev->config[0].desc.bConfigurationValue;
- if (dev->descriptor.bNumConfigurations != 1) {
- for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
- struct usb_interface_descriptor *desc;
-
- /* heuristic: Linux is more likely to have class
- * drivers, so avoid vendor-specific interfaces.
- */
- desc = &dev->config[i].intf_cache[0]
- ->altsetting->desc;
- if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
- continue;
- /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
- if (desc->bInterfaceClass == USB_CLASS_COMM
- && desc->bInterfaceSubClass == 2
- && desc->bInterfaceProtocol == 0xff)
- continue;
- c = dev->config[i].desc.bConfigurationValue;
- break;
- }
- dev_info(&dev->dev,
- "configuration #%d chosen from %d choices\n",
- c, dev->descriptor.bNumConfigurations);
- }
- return c;
-}
-
-/*
- * usb_new_device - perform initial device setup (usbcore-internal)
- * @dev: newly addressed device (in ADDRESS state)
- *
- * This is called with devices which have been enumerated, but not yet
- * configured. The device descriptor is available, but not descriptors
- * for any device configuration. The caller owns dev->serialize, and
- * the device is not visible through sysfs or other filesystem code.
- *
- * Returns 0 for success (device is configured and listed, with its
- * interfaces, in sysfs); else a negative errno value. On error, one
- * reference count to the device has been dropped.
- *
- * This call is synchronous, and may not be used in an interrupt context.
- *
- * Only the hub driver should ever call this; root hub registration
- * uses it only indirectly.
- */
-int usb_new_device(struct usb_device *dev)
-{
- int err;
- int c;
-
- err = usb_get_configuration(dev);
- if (err < 0) {
- dev_err(&dev->dev, "can't read configurations, error %d\n",
- err);
- goto fail;
- }
-
- /* Tell the world! */
- dev_dbg(&dev->dev, "new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
- dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber);
-
-#ifdef DEBUG
- if (dev->descriptor.iProduct)
- usb_show_string(dev, "Product", dev->descriptor.iProduct);
- if (dev->descriptor.iManufacturer)
- usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
- if (dev->descriptor.iSerialNumber)
- usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
-#endif
-
- /* put device-specific files into sysfs */
- err = device_add (&dev->dev);
- if (err) {
- dev_err(&dev->dev, "can't device_add, error %d\n", err);
- goto fail;
- }
- usb_create_sysfs_dev_files (dev);
-
- /* choose and set the configuration. that registers the interfaces
- * with the driver core, and lets usb device drivers bind to them.
- * NOTE: should interact with hub power budgeting.
- */
- c = usb_choose_configuration(dev);
- err = usb_set_configuration(dev, c);
- if (err) {
- dev_err(&dev->dev, "can't set config #%d, error %d\n", c, err);
- device_del(&dev->dev);
- goto fail;
- }
-
- /* USB device state == configured ... usable */
-
- /* add a /proc/bus/usb entry */
- usbfs_add_device(dev);
-
- return 0;
-fail:
- dev->state = USB_STATE_NOTATTACHED;
- usb_release_address(dev);
- usb_put_dev(dev);
- return err;
-}
-
/**
* usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
* @dev: device the buffer will be used with
/* Functions local to drivers/usb/core/ */
extern void usb_create_sysfs_dev_files (struct usb_device *dev);
+extern void usb_remove_sysfs_dev_files (struct usb_device *dev);
extern void usb_create_sysfs_intf_files (struct usb_interface *intf);
+extern void usb_remove_sysfs_intf_files (struct usb_interface *intf);
extern int usb_probe_interface (struct device *dev);
extern int usb_unbind_interface (struct device *dev);
unsigned int size);
extern int usb_set_configuration(struct usb_device *dev, int configuration);
+extern void usb_set_device_state(struct usb_device *udev,
+ enum usb_device_state new_state);
+
/* for labeling diagnostics */
extern const char *usbcore_name;
dum = container_of (hcd, struct dummy, hcd);
spin_lock_irqsave (&dum->lock, flags);
- if (!dum->hdev)
- dum->hdev = urb->dev->hcpriv;
+ dum->hdev = urb->dev->hcpriv;
urb->hcpriv = dum;
if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
urb->error_count = 1; /* mark as a new urb */
return limit;
}
+#define is_active(dum) ((dum->port_status & \
+ (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \
+ USB_PORT_STAT_SUSPEND)) \
+ == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE))
+
static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address)
{
int i;
+ if (!is_active (dum))
+ return NULL;
if ((address & ~USB_DIR_IN) == 0)
return &dum->ep [0];
for (i = 1; i < DUMMY_ENDPOINTS; i++) {
return NULL;
}
+#undef is_active
+
#define Dev_Request (USB_TYPE_STANDARD | USB_RECIP_DEVICE)
#define Dev_InRequest (Dev_Request | USB_DIR_IN)
#define Intf_Request (USB_TYPE_STANDARD | USB_RECIP_INTERFACE)
case USB_REQ_SET_ADDRESS:
if (setup.bRequestType != Dev_Request)
break;
- if (dum->address != 0) {
- maybe_set_status (urb, -ETIMEDOUT);
- urb->actual_length = 0;
- goto return_urb;
- }
dum->address = setup.wValue;
maybe_set_status (urb, 0);
dev_dbg (hardware, "set_address = %d\n",
break;
case USB_PORT_FEAT_POWER:
dum->port_status = 0;
- dum->address = 0;
- dum->hdev = 0;
dum->resuming = 0;
+ stop_activity(dum, dum->driver);
break;
default:
dum->port_status &= ~(1 << wValue);
INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (bus);
- bus->root_hub = root = usb_alloc_dev (0, bus, 0);
+ root = usb_alloc_dev (0, bus, 0);
if (!root) {
retval = -ENOMEM;
clean1:
root->speed = USB_SPEED_HIGH;
/* ...then configured, so khubd sees us. */
- if ((retval = hcd_register_root (&dum->hcd)) != 0) {
- bus->root_hub = 0;
+ if ((retval = hcd_register_root (root, &dum->hcd)) != 0) {
usb_put_dev (root);
clean2:
dum->hcd.state = USB_STATE_QUIESCING;
goto clean1;
}
+ /* only show a low-power port: just 8mA */
+ hub_set_power_budget (root, 8);
+
dum->started = 1;
if ((retval = dummy_register_udc (dum)) != 0) {
unsigned zlp:1;
unsigned cdc:1;
unsigned rndis:1;
+ unsigned suspended:1;
u16 cdc_filter;
unsigned long todo;
#define WORK_RX_MEMORY 0
static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
{
- struct eth_dev *dev = ep->driver_data;
-
if (req->status || req->actual != req->length)
DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
req->status, req->actual, req->length);
/* done sending after CDC_GET_ENCAPSULATED_RESPONSE */
- rndis_free_response (dev->rndis_config, req->buf);
}
static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
{
struct eth_dev *dev = ep->driver_data;
+ int status;
/* received RNDIS command from CDC_SEND_ENCAPSULATED_COMMAND */
spin_lock(&dev->lock);
- if (rndis_msg_parser (dev->rndis_config, (u8 *) req->buf))
- ERROR(dev, "%s: rndis parse error\n", __FUNCTION__ );
+ status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
+ if (status < 0)
+ ERROR(dev, "%s: rndis parse error %d\n", __FUNCTION__, status);
spin_unlock(&dev->lock);
}
if (buf) {
memcpy (req->buf, buf, value);
req->complete = rndis_response_complete;
+ rndis_free_response(dev->rndis_config, buf);
}
/* else stalls ... spec says to avoid that */
}
return &((struct eth_dev *) net->priv)->stats;
}
-static int eth_ethtool_ioctl (struct net_device *net, void *useraddr)
+static int eth_ethtool_ioctl (struct net_device *net, void __user *useraddr)
{
struct eth_dev *dev = (struct eth_dev *) net->priv;
u32 cmd;
- if (get_user (cmd, (u32 *)useraddr))
+ if (get_user (cmd, (u32 __user *)useraddr))
return -EFAULT;
switch (cmd) {
{
switch (cmd) {
case SIOCETHTOOL:
- return eth_ethtool_ioctl (net, (void *)rq->ifr_data);
+ return eth_ethtool_ioctl(net, rq->ifr_data);
default:
return -EOPNOTSUPP;
}
}
}
+static void rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
+{
+ if (req->status || req->actual != req->length)
+ DEBUG (dev, "rndis control ack complete --> %d, %d/%d\n",
+ req->status, req->actual, req->length);
+
+ usb_ep_free_buffer(ep, req->buf, req->dma, 8);
+ usb_ep_free_request(ep, req);
+}
+
static int rndis_control_ack (struct net_device *net)
{
struct eth_dev *dev = (struct eth_dev *) net->priv;
* CDC_NOTIFY_RESPONSE_AVAILABLE should work too
*/
resp->length = 8;
- resp->complete = rndis_response_complete;
+ resp->complete = rndis_control_ack_complete;
*((u32 *) resp->buf) = __constant_cpu_to_le32 (1);
*((u32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
if (length < 0) {
resp->status = 0;
- rndis_response_complete (dev->status_ep, resp);
+ rndis_control_ack_complete (dev->status_ep, resp);
}
return 0;
UTS_SYSNAME " " UTS_RELEASE "/%s",
gadget->name);
- /* CDC subset ... recognized by Linux since 2.4.10, but Windows
- * drivers aren't widely available.
- */
- if (!cdc) {
- device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
- device_desc.idVendor =
- __constant_cpu_to_le16(SIMPLE_VENDOR_NUM);
- device_desc.idProduct =
- __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM);
- }
-
/* If there's an RNDIS configuration, that's what Windows wants to
* be using ... so use these product IDs here and in the "linux.inf"
* needed to install MSFT drivers. Current Linux kernels will use
__constant_cpu_to_le16(RNDIS_PRODUCT_NUM);
snprintf (product_desc, sizeof product_desc,
"RNDIS/%s", driver_desc);
+
+ /* CDC subset ... recognized by Linux since 2.4.10, but Windows
+ * drivers aren't widely available.
+ */
+ } else if (!cdc) {
+ device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+ device_desc.idVendor =
+ __constant_cpu_to_le16(SIMPLE_VENDOR_NUM);
+ device_desc.idProduct =
+ __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM);
}
/* support optional vendor/distro customization */
/*-------------------------------------------------------------------------*/
+static void
+eth_suspend (struct usb_gadget *gadget)
+{
+ struct eth_dev *dev = get_gadget_data (gadget);
+
+ DEBUG (dev, "suspend\n");
+ dev->suspended = 1;
+}
+
+static void
+eth_resume (struct usb_gadget *gadget)
+{
+ struct eth_dev *dev = get_gadget_data (gadget);
+
+ DEBUG (dev, "resume\n");
+ dev->suspended = 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
static struct usb_gadget_driver eth_driver = {
#ifdef CONFIG_USB_GADGET_DUALSPEED
.speed = USB_SPEED_HIGH,
.setup = eth_setup,
.disconnect = eth_disconnect,
+ .suspend = eth_suspend,
+ .resume = eth_resume,
+
.driver = {
.name = (char *) shortname,
// .shutdown = ...
/* Store and send the Bulk-only CSW */
csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
csw->Tag = fsg->tag;
- csw->Residue = fsg->residue;
+ csw->Residue = cpu_to_le32(fsg->residue);
csw->Status = status;
bh->inreq->length = USB_BULK_CS_WRAP_LEN;
fsg->data_dir = DATA_DIR_TO_HOST;
else
fsg->data_dir = DATA_DIR_FROM_HOST;
- fsg->data_size = cbw->DataTransferLength;
+ fsg->data_size = le32_to_cpu(cbw->DataTransferLength);
if (fsg->data_size == 0)
fsg->data_dir = DATA_DIR_NONE;
fsg->lun = cbw->Lun;
}
/* Find all the endpoints we will use */
+ usb_ep_autoconfig_reset(gadget);
ep = usb_ep_autoconfig(gadget, &fs_bulk_in_desc);
if (!ep)
goto autoconf_fail;
#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
+enum NDIS_DEVICE_POWER_STATE {
+ NdisDeviceStateUnspecified = 0,
+ NdisDeviceStateD0,
+ NdisDeviceStateD1,
+ NdisDeviceStateD2,
+ NdisDeviceStateD3,
+ NdisDeviceStateMaximum
+};
+
+struct NDIS_PM_WAKE_UP_CAPABILITIES {
+ enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp;
+ enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp;
+ enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp;
+};
+
/* NDIS_PNP_CAPABILITIES.Flags constants */
#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001
#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002
#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004
+struct NDIS_PNP_CAPABILITIES {
+ u32 Flags;
+ struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities;
+};
+
+struct NDIS_PM_PACKET_PATTERN {
+ u32 Priority;
+ u32 Reserved;
+ u32 MaskSize;
+ u32 PatternOffset;
+ u32 PatternSize;
+ u32 PatternFlags;
+};
+
+
/* Required Object IDs (OIDs) */
#define OID_GEN_SUPPORTED_LIST 0x00010101
#define OID_GEN_HARDWARE_STATUS 0x00010102
, &dev->usb->stdrsp);
writel ( (1 << USB_ROOT_PORT_WAKEUP_ENABLE)
| (1 << SELF_POWERED_USB_DEVICE)
+ /* erratum 0102 workaround */
+ | ((dev->chiprev == 0100) ? 0 : 1) << SUSPEND_IMMEDIATELY
| (1 << REMOTE_WAKEUP_SUPPORT)
| (1 << USB_DETECT_ENABLE)
| (1 << SELF_POWERED_STATUS)
| (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE)
| (1 << VBUS_INTERRUPT_ENABLE)
| (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE)
+ | (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE)
, &dev->regs->pciirqenb1);
/* don't leave any writes posted */
return;
}
- /* NOTE: we don't actually suspend the hardware; that starts to
- * interact with PCI power management, and needs something like a
- * controller->suspend() call to clear SUSPEND_REQUEST_INTERRUPT.
- * we shouldn't see resume interrupts.
- * for rev 0100, this also avoids erratum 0102.
+ /* NOTE: chip stays in PCI D0 state for now, but it could
+ * enter D1 to save more power
*/
tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT);
if (stat & tmp) {
- if (dev->driver->suspend)
- dev->driver->suspend (&dev->gadget);
+ writel (tmp, &dev->regs->irqstat1);
+ if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) {
+ if (dev->driver->suspend)
+ dev->driver->suspend (&dev->gadget);
+ /* we use SUSPEND_IMMEDIATELY */
+ stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT);
+ } else {
+ if (dev->driver->resume)
+ dev->driver->resume (&dev->gadget);
+ /* at high speed, note erratum 0133 */
+ }
stat &= ~tmp;
}
- stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT);
/* clear any other status/irqs */
if (stat)
/* some status we can just ignore */
stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
+ | (1 << SUSPEND_REQUEST_INTERRUPT)
| (1 << RESUME_INTERRUPT)
| (1 << SOF_INTERRUPT));
if (!stat)
*
* 03/25/2004 Kai-Uwe Bloem <linux-development@auerswald.de>
* Fixed rndis_rm_hdr length bug.
+ *
+ * Copyright (C) 2004 by David Brownell
+ * updates to merge with Linux 2.6, better match RNDIS spec
*/
#include <linux/config.h>
#include <asm/byteorder.h>
#include <asm/system.h>
+
+#undef RNDIS_PM
+#undef VERBOSE
+
#include "rndis.h"
/* The driver for your USB chip needs to support ep0 OUT to work with
- * RNDIS, plus the same three descriptors as CDC Ethernet.
+ * RNDIS, plus all three CDC Ethernet endpoints (interrupt not optional).
*
* Windows hosts need an INF file like Documentation/usb/linux.inf
+ * and will be happier if you provide the host_addr module parameter.
*/
-#ifndef __LITTLE_ENDIAN
-#warning this code is missing all cpu_to_leXX() calls ...
-#endif
-
#if 0
-#define DEBUG if (rndis_debug) printk
+#define DEBUG(str,args...) do { \
+ if (rndis_debug) \
+ printk(KERN_DEBUG str , ## args ); \
+ } while (0)
static int rndis_debug = 0;
module_param (rndis_debug, bool, 0);
MODULE_PARM_DESC (rndis_debug, "enable debugging");
#else
-#define DEBUG(str,args...) do{}while(0)
+
+#define rndis_debug 0
+#define DEBUG(str,args...) do{}while(0)
#endif
#define RNDIS_MAX_CONFIGS 1
static rndis_resp_t *rndis_add_response (int configNr, u32 length);
-/* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
- * - power management (OID_PNP_CAPABILITIES, ...)
- * - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
- */
/* NDIS Functions */
static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
{
int retval = -ENOTSUPP;
u32 length = 0;
+ u32 *tmp;
+ int i, count;
rndis_query_cmplt_type *resp;
if (!r) return -ENOMEM;
if (!resp) return -ENOMEM;
switch (OID) {
+
+ /* general oids (table 4-1) */
+
/* mandatory */
case OID_GEN_SUPPORTED_LIST:
DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
length = sizeof (oid_supported_list);
- memcpy ((u8 *) resp + 24, oid_supported_list, length);
+ count = length / sizeof (u32);
+ tmp = (u32 *) ((u8 *)resp + 24);
+ for (i = 0; i < count; i++)
+ tmp[i] = cpu_to_le32 (oid_supported_list[i]);
retval = 0;
break;
* reddite ergo quae sunt Caesaris Caesari
* et quae sunt Dei Deo!
*/
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
case OID_GEN_MEDIA_SUPPORTED:
DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].medium);
retval = 0;
break;
DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
length = 4;
/* one medium, one transport... (maybe you do it better) */
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].medium;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].medium);
retval = 0;
break;
- case OID_GEN_MAXIMUM_LOOKAHEAD:
- DEBUG("%s: OID_GEN_MAXIMUM_LOOKAHEAD\n", __FUNCTION__);
- break;
-
/* mandatory */
case OID_GEN_MAXIMUM_FRAME_SIZE:
DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) {
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
- .dev->mtu;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].dev->mtu);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
length = 4;
if (rndis_per_dev_params [configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
else
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].speed;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].speed);
retval = 0;
break;
-
- case OID_GEN_TRANSMIT_BUFFER_SPACE:
- DEBUG("%s: OID_GEN_TRANSMIT_BUFFER_SPACE\n", __FUNCTION__);
- length = 4;
- *((u32 *) resp + 6) = 0;
- retval = 0;
- break;
-
- case OID_GEN_RECEIVE_BUFFER_SPACE:
- DEBUG("%s: OID_GEN_RECEIVE_BUFFER_SPACE\n", __FUNCTION__);
- break;
-
+
/* mandatory */
case OID_GEN_TRANSMIT_BLOCK_SIZE:
DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) {
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
- .dev->mtu;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].dev->mtu);
retval = 0;
}
break;
DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].dev) {
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
- .dev->mtu;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].dev->mtu);
retval = 0;
}
break;
case OID_GEN_VENDOR_ID:
DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].vendorID;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].vendorID);
retval = 0;
break;
retval = 0;
break;
+ case OID_GEN_VENDOR_DRIVER_VERSION:
+ DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
+ length = 4;
+ /* Created as LE */
+ *((u32 *) resp + 6) = rndis_driver_version;
+ retval = 0;
+ break;
+
/* mandatory */
case OID_GEN_CURRENT_PACKET_FILTER:
DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params[configNr].filter;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params[configNr].filter);
retval = 0;
break;
-
- case OID_GEN_CURRENT_LOOKAHEAD:
- DEBUG("%s: OID_GEN_CURRENT_LOOKAHEAD\n", __FUNCTION__);
- break;
-
- case OID_GEN_DRIVER_VERSION:
- DEBUG("%s: OID_GEN_DRIVER_VERSION\n", __FUNCTION__);
- break;
-
+
/* mandatory */
case OID_GEN_MAXIMUM_TOTAL_SIZE:
DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = RNDIS_MAX_TOTAL_SIZE;
- retval = 0;
- break;
-
- case OID_GEN_PROTOCOL_OPTIONS:
- DEBUG("%s: OID_GEN_PROTOCOL_OPTIONS\n", __FUNCTION__);
- break;
-
- case OID_GEN_MAC_OPTIONS:
- DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
- length = 4;
- *((u32 *) resp + 6) = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
- NDIS_MAC_OPTION_FULL_DUPLEX;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32(
+ RNDIS_MAX_TOTAL_SIZE);
retval = 0;
break;
-
+
/* mandatory */
case OID_GEN_MEDIA_CONNECT_STATUS:
DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
- .media_state;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .media_state);
retval = 0;
break;
-
- case OID_GEN_MAXIMUM_SEND_PACKETS:
- DEBUG("%s: OID_GEN_MAXIMUM_SEND_PACKETS\n", __FUNCTION__);
- break;
-
- /* mandatory */
- case OID_GEN_VENDOR_DRIVER_VERSION:
- DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
- length = 4;
- *((u32 *) resp + 6) = rndis_driver_version;
- retval = 0;
- break;
-
- case OID_GEN_SUPPORTED_GUIDS:
- DEBUG("%s: OID_GEN_SUPPORTED_GUIDS\n", __FUNCTION__);
- break;
-
- case OID_GEN_NETWORK_LAYER_ADDRESSES:
- DEBUG("%s: OID_GEN_NETWORK_LAYER_ADDRESSES\n", __FUNCTION__);
- break;
-
- case OID_GEN_TRANSPORT_HEADER_OFFSET:
- DEBUG("%s: OID_GEN_TRANSPORT_HEADER_OFFSET\n", __FUNCTION__);
- break;
-
- case OID_GEN_MACHINE_NAME:
- DEBUG("%s: OID_GEN_MACHINE_NAME\n", __FUNCTION__);
- break;
-
- case OID_GEN_RNDIS_CONFIG_PARAMETER:
- DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
+
+ case OID_GEN_PHYSICAL_MEDIUM:
+ DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
- case OID_GEN_VLAN_ID:
- DEBUG("%s: OID_GEN_VLAN_ID\n", __FUNCTION__);
- break;
-
- case OID_GEN_MEDIA_CAPABILITIES:
- DEBUG("%s: OID_GEN_MEDIA_CAPABILITIES\n", __FUNCTION__);
- break;
-
- case OID_GEN_PHYSICAL_MEDIUM:
- DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
+
+ /* The RNDIS specification is incomplete/wrong. Some versions
+ * of MS-Windows expect OIDs that aren't specified there. Other
+ * versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
+ */
+ case OID_GEN_MAC_OPTIONS: /* from WinME */
+ DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32(
+ NDIS_MAC_OPTION_RECEIVE_SERIALIZED
+ | NDIS_MAC_OPTION_FULL_DUPLEX);
retval = 0;
break;
-
+
+ /* statistics OIDs (table 4-2) */
+
/* mandatory */
case OID_GEN_XMIT_OK:
DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
- .stats->tx_packets -
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].stats->tx_packets -
rndis_per_dev_params [configNr].stats->tx_errors -
- rndis_per_dev_params [configNr].stats->tx_dropped;
+ rndis_per_dev_params [configNr].stats->tx_dropped);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
-
+
/* mandatory */
case OID_GEN_RCV_OK:
DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->rx_packets -
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr].stats->rx_packets -
rndis_per_dev_params [configNr].stats->rx_errors -
- rndis_per_dev_params [configNr].stats->rx_dropped;
+ rndis_per_dev_params [configNr].stats->rx_dropped);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->tx_errors;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->tx_errors);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_RCV_ERROR:
DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->rx_errors;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->rx_errors);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_RCV_NO_BUFFER:
DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->rx_dropped;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->rx_dropped);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
-
+
+#ifdef RNDIS_OPTIONAL_STATS
case OID_GEN_DIRECTED_BYTES_XMIT:
DEBUG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __FUNCTION__);
/*
*/
if (rndis_per_dev_params [configNr].stats) {
length = 4;
- *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].
- stats->tx_packets -
- rndis_per_dev_params [configNr].stats->tx_errors -
- rndis_per_dev_params [configNr].stats->tx_dropped)
- *123;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ (rndis_per_dev_params [configNr]
+ .stats->tx_packets -
+ rndis_per_dev_params [configNr]
+ .stats->tx_errors -
+ rndis_per_dev_params [configNr]
+ .stats->tx_dropped)
+ * 123);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
/* dito */
if (rndis_per_dev_params [configNr].stats) {
length = 4;
- *((u32 *) resp + 6) = (rndis_per_dev_params [configNr].
- stats->tx_packets -
- rndis_per_dev_params [configNr].stats->tx_errors -
- rndis_per_dev_params [configNr].stats->tx_dropped)
- /123;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ (rndis_per_dev_params [configNr]
+ .stats->tx_packets -
+ rndis_per_dev_params [configNr]
+ .stats->tx_errors -
+ rndis_per_dev_params [configNr]
+ .stats->tx_dropped)
+ / 123);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_MULTICAST_BYTES_XMIT:
DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->multicast*1234;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->multicast*1234);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_MULTICAST_FRAMES_XMIT:
DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->multicast;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->multicast);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_BROADCAST_BYTES_XMIT:
DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->tx_packets/42*255;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->tx_packets/42*255);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_BROADCAST_FRAMES_XMIT:
DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->tx_packets/42;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->tx_packets/42);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_DIRECTED_BYTES_RCV:
DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
case OID_GEN_DIRECTED_FRAMES_RCV:
DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
case OID_GEN_MULTICAST_BYTES_RCV:
DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->multicast*1111;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->multicast * 1111);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_MULTICAST_FRAMES_RCV:
DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->multicast;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->multicast);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_BROADCAST_BYTES_RCV:
DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->rx_packets/42*255;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->rx_packets/42*255);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_BROADCAST_FRAMES_RCV:
DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->rx_packets/42;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->rx_packets/42);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_RCV_CRC_ERROR:
DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats) {
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr].
- stats->rx_crc_errors;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->rx_crc_errors);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
case OID_GEN_TRANSMIT_QUEUE_LENGTH:
DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
-
- case OID_GEN_GET_TIME_CAPS:
- DEBUG("%s: OID_GEN_GET_TIME_CAPS\n", __FUNCTION__);
- break;
-
- case OID_GEN_GET_NETCARD_TIME:
- DEBUG("%s: OID_GEN_GET_NETCARD_TIME\n", __FUNCTION__);
- break;
-
- case OID_GEN_NETCARD_LOAD:
- DEBUG("%s: OID_GEN_NETCARD_LOAD\n", __FUNCTION__);
- break;
-
- case OID_GEN_DEVICE_PROFILE:
- DEBUG("%s: OID_GEN_DEVICE_PROFILE\n", __FUNCTION__);
- break;
-
- case OID_GEN_INIT_TIME_MS:
- DEBUG("%s: OID_GEN_INIT_TIME_MS\n", __FUNCTION__);
- break;
-
- case OID_GEN_RESET_COUNTS:
- DEBUG("%s: OID_GEN_RESET_COUNTS\n", __FUNCTION__);
- break;
-
- case OID_GEN_MEDIA_SENSE_COUNTS:
- DEBUG("%s: OID_GEN_MEDIA_SENSE_COUNTS\n", __FUNCTION__);
- break;
-
- case OID_GEN_FRIENDLY_NAME:
- DEBUG("%s: OID_GEN_FRIENDLY_NAME\n", __FUNCTION__);
- break;
-
- case OID_GEN_MINIPORT_INFO:
- DEBUG("%s: OID_GEN_MINIPORT_INFO\n", __FUNCTION__);
- break;
-
- case OID_GEN_RESET_VERIFY_PARAMETERS:
- DEBUG("%s: OID_GEN_RESET_VERIFY_PARAMETERS\n", __FUNCTION__);
- break;
-
+#endif /* RNDIS_OPTIONAL_STATS */
+
+ /* ieee802.3 OIDs (table 4-3) */
+
/* mandatory */
case OID_802_3_PERMANENT_ADDRESS:
DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
length);
retval = 0;
} else {
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
}
break;
DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
length = 4;
/* Multicast base address only */
- *((u32 *) resp + 6) = 0xE0000000;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000);
retval = 0;
break;
DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
length = 4;
/* Multicast base address only */
- *((u32 *) resp + 6) = 1;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (1);
retval = 0;
break;
case OID_802_3_MAC_OPTIONS:
DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__);
break;
-
+
+ /* ieee802.3 statistics OIDs (table 4-4) */
+
/* mandatory */
case OID_802_3_RCV_ERROR_ALIGNMENT:
DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
if (rndis_per_dev_params [configNr].stats)
{
length = 4;
- *((u32 *) resp + 6) = rndis_per_dev_params [configNr]
- .stats->rx_frame_errors;
+ *((u32 *) resp + 6) = cpu_to_le32 (
+ rndis_per_dev_params [configNr]
+ .stats->rx_frame_errors);
retval = 0;
}
break;
case OID_802_3_XMIT_ONE_COLLISION:
DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
case OID_802_3_XMIT_MORE_COLLISIONS:
DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
length = 4;
- *((u32 *) resp + 6) = 0;
+ *((u32 *) resp + 6) = __constant_cpu_to_le32 (0);
retval = 0;
break;
+#ifdef RNDIS_OPTIONAL_STATS
case OID_802_3_XMIT_DEFERRED:
DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__);
/* TODO */
DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__);
/* TODO */
break;
-
- default: printk (KERN_ERR "%s: unknown OID 0x%08X\n",
+#endif /* RNDIS_OPTIONAL_STATS */
+
+#ifdef RNDIS_PM
+ /* power management OIDs (table 4-5) */
+ case OID_PNP_CAPABILITIES:
+ DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
+
+ /* just PM, and remote wakeup on link status change
+ * (not magic packet or pattern match)
+ */
+ length = sizeof (struct NDIS_PNP_CAPABILITIES);
+ memset (resp, 0, length);
+ {
+ struct NDIS_PNP_CAPABILITIES *caps = (void *) resp;
+
+ caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
+ caps->WakeUpCapabilities.MinLinkChangeWakeUp
+ = NdisDeviceStateD3;
+
+ /* FIXME then use usb_gadget_wakeup(), and
+ * set USB_CONFIG_ATT_WAKEUP in config desc
+ */
+ }
+ retval = 0;
+ break;
+ case OID_PNP_QUERY_POWER:
+ DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__);
+ /* sure, handle any power state that maps to USB suspend */
+ retval = 0;
+ break;
+#endif
+
+ default:
+ printk (KERN_WARNING "%s: query unknown OID 0x%08X\n",
__FUNCTION__, OID);
}
- resp->InformationBufferOffset = 16;
- resp->InformationBufferLength = length;
- resp->MessageLength = 24 + length;
+ resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
+ resp->InformationBufferLength = cpu_to_le32 (length);
+ resp->MessageLength = cpu_to_le32 (24 + length);
r->length = 24 + length;
return retval;
}
{
rndis_set_cmplt_type *resp;
int i, retval = -ENOTSUPP;
- struct rndis_config_parameter *param;
struct rndis_params *params;
- u8 *cp;
if (!r)
return -ENOMEM;
if (!resp)
return -ENOMEM;
- cp = (u8 *)resp;
+ DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
+ for (i = 0; i < buf_len; i += 16) {
+ DEBUG ("%03d: "
+ " %02x %02x %02x %02x"
+ " %02x %02x %02x %02x"
+ " %02x %02x %02x %02x"
+ " %02x %02x %02x %02x"
+ "\n",
+ i,
+ buf[i], buf [i+1],
+ buf[i+2], buf[i+3],
+ buf[i+4], buf [i+5],
+ buf[i+6], buf[i+7],
+ buf[i+8], buf [i+9],
+ buf[i+10], buf[i+11],
+ buf[i+12], buf [i+13],
+ buf[i+14], buf[i+15]);
+ }
switch (OID) {
case OID_GEN_CURRENT_PACKET_FILTER:
params = &rndis_per_dev_params [configNr];
retval = 0;
- /* FIXME use this NDIS_PACKET_TYPE_* bitflags to
+ /* FIXME use these NDIS_PACKET_TYPE_* bitflags to
* filter packets in hard_start_xmit()
* NDIS_PACKET_TYPE_x == CDC_PACKET_TYPE_x for x in:
* PROMISCUOUS, DIRECTED,
* MULTICAST, ALL_MULTICAST, BROADCAST
*/
- params->filter = *(u32 *)buf;
+ params->filter = cpu_to_le32p((u32 *)buf);
DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
__FUNCTION__, params->filter);
DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
retval = 0;
break;
-
+#if 0
case OID_GEN_RNDIS_CONFIG_PARAMETER:
- DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__);
+ {
+ struct rndis_config_parameter *param;
param = (struct rndis_config_parameter *) buf;
- if (param) {
- for (i = 0; i < param->ParameterNameLength; i++) {
- DEBUG ("%c",
- *(buf + param->ParameterNameOffset + i));
- }
- DEBUG ("\n");
+ DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
+ __FUNCTION__,
+ min(cpu_to_le32(param->ParameterNameLength),80),
+ buf + param->ParameterNameOffset);
+ retval = 0;
}
-
+ break;
+#endif
+
+#ifdef RNDIS_PM
+ case OID_PNP_SET_POWER:
+ DEBUG ("OID_PNP_SET_POWER\n");
+ /* sure, handle any power state that maps to USB suspend */
retval = 0;
break;
-
- default: printk (KERN_ERR "%s: unknown OID 0x%08X\n",
- __FUNCTION__, OID);
+
+ case OID_PNP_ENABLE_WAKE_UP:
+ /* always-connected ... */
+ DEBUG ("OID_PNP_ENABLE_WAKE_UP\n");
+ retval = 0;
+ break;
+
+ // no PM resume patterns supported (specified where?)
+ // so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails
+#endif
+
+ default:
+ printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n",
+ __FUNCTION__, OID, buf_len);
}
return retval;
if (!resp) return -ENOMEM;
- resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
- resp->MessageLength = 52;
- resp->RequestID = buf->RequestID;
- resp->Status = RNDIS_STATUS_SUCCESS;
- resp->MajorVersion = RNDIS_MAJOR_VERSION;
- resp->MinorVersion = RNDIS_MINOR_VERSION;
- resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
- resp->Medium = RNDIS_MEDIUM_802_3;
- resp->MaxPacketsPerTransfer = 1;
- resp->MaxTransferSize = rndis_per_dev_params [configNr].dev->mtu
+ resp->MessageType = __constant_cpu_to_le32 (
+ REMOTE_NDIS_INITIALIZE_CMPLT);
+ resp->MessageLength = __constant_cpu_to_le32 (52);
+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION);
+ resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION);
+ resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS);
+ resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
+ resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
+ resp->MaxTransferSize = cpu_to_le32 (
+ rndis_per_dev_params [configNr].dev->mtu
+ sizeof (struct ethhdr)
+ sizeof (struct rndis_packet_msg_type)
- + 22;
- resp->PacketAlignmentFactor = 0;
- resp->AFListOffset = 0;
- resp->AFListSize = 0;
+ + 22);
+ resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0);
+ resp->AFListOffset = __constant_cpu_to_le32 (0);
+ resp->AFListSize = __constant_cpu_to_le32 (0);
if (rndis_per_dev_params [configNr].ack)
rndis_per_dev_params [configNr].ack (
rndis_query_cmplt_type *resp;
rndis_resp_t *r;
- DEBUG("%s: OID = %08X\n", __FUNCTION__, buf->OID);
+ // DEBUG("%s: OID = %08X\n", __FUNCTION__, cpu_to_le32(buf->OID));
if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
/*
if (!resp) return -ENOMEM;
- resp->MessageType = REMOTE_NDIS_QUERY_CMPLT;
- resp->MessageLength = 24;
- resp->RequestID = buf->RequestID;
+ resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
+ resp->MessageLength = __constant_cpu_to_le32 (24);
+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
- if (gen_ndis_query_resp (configNr, buf->OID, r)) {
+ if (gen_ndis_query_resp (configNr, cpu_to_le32 (buf->OID), r)) {
/* OID not supported */
- resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
- resp->InformationBufferLength = 0;
- resp->InformationBufferOffset = 0;
+ resp->Status = __constant_cpu_to_le32 (
+ RNDIS_STATUS_NOT_SUPPORTED);
+ resp->InformationBufferLength = __constant_cpu_to_le32 (0);
+ resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
} else
- resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
if (rndis_per_dev_params [configNr].ack)
rndis_per_dev_params [configNr].ack (
static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
{
+ u32 BufLength, BufOffset;
rndis_set_cmplt_type *resp;
rndis_resp_t *r;
- int i;
r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
if (!r) return -ENOMEM;
resp = (rndis_set_cmplt_type *) r->buf;
if (!resp) return -ENOMEM;
-
- DEBUG("%s: Length: %d\n", __FUNCTION__, buf->InformationBufferLength);
- DEBUG("%s: Offset: %d\n", __FUNCTION__, buf->InformationBufferOffset);
+
+ BufLength = cpu_to_le32 (buf->InformationBufferLength);
+ BufOffset = cpu_to_le32 (buf->InformationBufferOffset);
+
+#ifdef VERBOSE
+ DEBUG("%s: Length: %d\n", __FUNCTION__, BufLength);
+ DEBUG("%s: Offset: %d\n", __FUNCTION__, BufOffset);
DEBUG("%s: InfoBuffer: ", __FUNCTION__);
- for (i = 0; i < buf->InformationBufferLength; i++) {
- DEBUG ("%02x ", *(((u8 *) buf) + i + 12 +
- buf->InformationBufferOffset));
+ for (i = 0; i < BufLength; i++) {
+ DEBUG ("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
}
DEBUG ("\n");
+#endif
- resp->MessageType = REMOTE_NDIS_SET_CMPLT;
- resp->MessageLength = 16;
- resp->RequestID = buf->RequestID;
- if (gen_ndis_set_resp (configNr, buf->OID,
- ((u8 *) buf) + 28,
- buf->InformationBufferLength, r))
- resp->Status = RNDIS_STATUS_NOT_SUPPORTED;
- else resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
+ resp->MessageLength = __constant_cpu_to_le32 (16);
+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
+ if (gen_ndis_set_resp (configNr, cpu_to_le32 (buf->OID),
+ ((u8 *) buf) + 8 + BufOffset, BufLength, r))
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED);
+ else resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
if (rndis_per_dev_params [configNr].ack)
- rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev);
+ rndis_per_dev_params [configNr].ack (
+ rndis_per_dev_params [configNr].dev);
return 0;
}
resp = (rndis_reset_cmplt_type *) r->buf;
if (!resp) return -ENOMEM;
- resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
- resp->MessageLength = 16;
- resp->Status = RNDIS_STATUS_SUCCESS;
- resp->AddressingReset = 1; /* resent information */
+ resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
+ resp->MessageLength = __constant_cpu_to_le32 (16);
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
+ /* resent information */
+ resp->AddressingReset = __constant_cpu_to_le32 (1);
if (rndis_per_dev_params [configNr].ack)
rndis_per_dev_params [configNr].ack (
resp = (rndis_keepalive_cmplt_type *) r->buf;
if (!resp) return -ENOMEM;
- resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
- resp->MessageLength = 16;
- resp->RequestID = buf->RequestID;
- resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->MessageType = __constant_cpu_to_le32 (
+ REMOTE_NDIS_KEEPALIVE_CMPLT);
+ resp->MessageLength = __constant_cpu_to_le32 (16);
+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
+ resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
if (rndis_per_dev_params [configNr].ack)
rndis_per_dev_params [configNr].ack (
resp = (rndis_indicate_status_msg_type *) r->buf;
if (!resp) return -ENOMEM;
- resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
- resp->MessageLength = 20;
- resp->Status = status;
- resp->StatusBufferLength = 0;
- resp->StatusBufferOffset = 0;
+ resp->MessageType = __constant_cpu_to_le32 (
+ REMOTE_NDIS_INDICATE_STATUS_MSG);
+ resp->MessageLength = __constant_cpu_to_le32 (20);
+ resp->Status = cpu_to_le32 (status);
+ resp->StatusBufferLength = __constant_cpu_to_le32 (0);
+ resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
if (rndis_per_dev_params [configNr].ack)
rndis_per_dev_params [configNr].ack (
return -ENOMEM;
tmp = (u32 *) buf;
- MsgType = *tmp;
- MsgLength = *(tmp + 1);
+ MsgType = cpu_to_le32p(tmp++);
+ MsgLength = cpu_to_le32p(tmp++);
if (configNr >= RNDIS_MAX_CONFIGS)
return -ENOTSUPP;
switch (MsgType)
{
case REMOTE_NDIS_INITIALIZE_MSG:
- DEBUG(KERN_INFO "%s: REMOTE_NDIS_INITIALIZE_MSG\n",
+ DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
__FUNCTION__ );
params->state = RNDIS_INITIALIZED;
return rndis_init_response (configNr,
(rndis_init_msg_type *) buf);
case REMOTE_NDIS_HALT_MSG:
- DEBUG(KERN_INFO "%s: REMOTE_NDIS_HALT_MSG\n",
+ DEBUG("%s: REMOTE_NDIS_HALT_MSG\n",
__FUNCTION__ );
params->state = RNDIS_UNINITIALIZED;
if (params->dev) {
return 0;
case REMOTE_NDIS_QUERY_MSG:
- DEBUG(KERN_INFO "%s: REMOTE_NDIS_QUERY_MSG\n",
- __FUNCTION__ );
return rndis_query_response (configNr,
(rndis_query_msg_type *) buf);
case REMOTE_NDIS_SET_MSG:
- DEBUG(KERN_INFO "%s: REMOTE_NDIS_SET_MSG\n",
- __FUNCTION__ );
return rndis_set_response (configNr,
(rndis_set_msg_type *) buf);
case REMOTE_NDIS_RESET_MSG:
- DEBUG(KERN_INFO "%s: REMOTE_NDIS_RESET_MSG\n",
+ DEBUG("%s: REMOTE_NDIS_RESET_MSG\n",
__FUNCTION__ );
return rndis_reset_response (configNr,
(rndis_reset_msg_type *) buf);
case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
- DEBUG(KERN_INFO "%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+#ifdef VERBOSE
+ DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
__FUNCTION__ );
+#endif
return rndis_keepalive_response (configNr,
(rndis_keepalive_msg_type *)
buf);
default:
- printk (KERN_ERR "%s: unknown RNDIS Message Type 0x%08X\n",
- __FUNCTION__ , MsgType);
+ /* At least Windows XP emits some undefined RNDIS messages.
+ * In one case those messages seemed to relate to the host
+ * suspending itself.
+ */
+ printk (KERN_WARNING
+ "%s: unknown RNDIS message 0x%08X len %d\n",
+ __FUNCTION__ , MsgType, MsgLength);
+ {
+ unsigned i;
+ for (i = 0; i < MsgLength; i += 16) {
+ DEBUG ("%03d: "
+ " %02x %02x %02x %02x"
+ " %02x %02x %02x %02x"
+ " %02x %02x %02x %02x"
+ " %02x %02x %02x %02x"
+ "\n",
+ i,
+ buf[i], buf [i+1],
+ buf[i+2], buf[i+3],
+ buf[i+4], buf [i+5],
+ buf[i+6], buf[i+7],
+ buf[i+8], buf [i+9],
+ buf[i+10], buf[i+11],
+ buf[i+12], buf [i+13],
+ buf[i+14], buf[i+15]);
+ }
+ }
break;
}
int rndis_register (int (* rndis_control_ack) (struct net_device *))
{
u8 i;
- DEBUG("%s: ", __FUNCTION__ );
for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
if (!rndis_per_dev_params [i].used) {
rndis_per_dev_params [i].used = 1;
rndis_per_dev_params [i].ack = rndis_control_ack;
- DEBUG("configNr = %d\n", i);
+ DEBUG("%s: configNr = %d\n", __FUNCTION__, i);
return i;
}
}
if (!skb) return;
skb_push (skb, sizeof (struct rndis_packet_msg_type));
memset (skb->data, 0, sizeof (struct rndis_packet_msg_type));
- *((u32 *) skb->data) = 1;
- *((u32 *) skb->data + 1) = skb->len;
- *((u32 *) skb->data + 2) = 36;
- *((u32 *) skb->data + 3) = skb->len - 44;
+ *((u32 *) skb->data) = __constant_cpu_to_le32 (1);
+ *((u32 *) skb->data + 1) = cpu_to_le32(skb->len);
+ *((u32 *) skb->data + 2) = __constant_cpu_to_le32 (36);
+ *((u32 *) skb->data + 3) = cpu_to_le32(skb->len - 44);
return;
}
int rndis_rm_hdr (u8 *buf, u32 *length)
{
- u32 i, messageLen, dataOffset;
+ u32 i, messageLen, dataOffset, *tmp;
+ tmp = (u32 *) buf;
+
if (!buf || !length) return -1;
- if (*((u32 *) buf) != 1) return -1;
+ if (cpu_to_le32p(tmp++) != 1) return -1;
- messageLen = *((u32 *) buf + 1);
-
- dataOffset = *((u32 *) buf + 2) + 8;
+ messageLen = cpu_to_le32p(tmp++);
+ dataOffset = cpu_to_le32p(tmp++) + 8;
+
if (messageLen < dataOffset || messageLen > *length) return -1;
for (i = dataOffset; i < messageLen; i++)
#define RNDIS_MEDIUM_802_3 0x00000000U
+/* from drivers/net/sk98lin/h/skgepnmi.h */
+#define OID_PNP_CAPABILITIES 0xFD010100
+#define OID_PNP_SET_POWER 0xFD010101
+#define OID_PNP_QUERY_POWER 0xFD010102
+#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
+#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
+#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
+
+
/* supported OIDs */
static const u32 oid_supported_list [] =
{
- /* mandatory general */
/* the general stuff */
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_LINK_SPEED,
- OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DRIVER_VERSION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_MAXIMUM_TOTAL_SIZE,
- OID_GEN_MAC_OPTIONS,
OID_GEN_MEDIA_CONNECT_STATUS,
OID_GEN_PHYSICAL_MEDIUM,
+#if 0
OID_GEN_RNDIS_CONFIG_PARAMETER,
+#endif
/* the statistical stuff */
OID_GEN_XMIT_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
+#ifdef RNDIS_OPTIONAL_STATS
OID_GEN_DIRECTED_BYTES_XMIT,
OID_GEN_DIRECTED_FRAMES_XMIT,
OID_GEN_MULTICAST_BYTES_XMIT,
OID_GEN_BROADCAST_FRAMES_RCV,
OID_GEN_RCV_CRC_ERROR,
OID_GEN_TRANSMIT_QUEUE_LENGTH,
+#endif /* RNDIS_OPTIONAL_STATS */
/* mandatory 802.3 */
/* the general stuff */
/* the statistical stuff */
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
- OID_802_3_XMIT_MORE_COLLISIONS
+ OID_802_3_XMIT_MORE_COLLISIONS,
+#ifdef RNDIS_OPTIONAL_STATS
+ OID_802_3_XMIT_DEFERRED,
+ OID_802_3_XMIT_MAX_COLLISIONS,
+ OID_802_3_RCV_OVERRUN,
+ OID_802_3_XMIT_UNDERRUN,
+ OID_802_3_XMIT_HEARTBEAT_FAILURE,
+ OID_802_3_XMIT_TIMES_CRS_LOST,
+ OID_802_3_XMIT_LATE_COLLISIONS,
+#endif /* RNDIS_OPTIONAL_STATS */
+
+#ifdef RNDIS_PM
+ /* PM and wakeup are mandatory for USB: */
+
+ /* power management */
+ OID_PNP_CAPABILITIES,
+ OID_PNP_QUERY_POWER,
+ OID_PNP_SET_POWER,
+
+ /* wake up host */
+ OID_PNP_ENABLE_WAKE_UP,
+ OID_PNP_ADD_WAKE_UP_PATTERN,
+ OID_PNP_REMOVE_WAKE_UP_PATTERN,
+#endif
};
{
if (cap & (1 << 16)) {
int msec = 500;
+ struct pci_dev *pdev = to_pci_dev(ehci->hcd.self.controller);
/* request handoff to OS */
- cap &= 1 << 24;
- pci_write_config_dword (to_pci_dev(ehci->hcd.self.controller), where, cap);
+ cap |= 1 << 24;
+ pci_write_config_dword(pdev, where, cap);
/* and wait a while for it to happen */
do {
msleep(10);
msec -= 10;
- pci_read_config_dword (to_pci_dev(ehci->hcd.self.controller), where, &cap);
+ pci_read_config_dword(pdev, where, &cap);
} while ((cap & (1 << 16)) && msec);
if (cap & (1 << 16)) {
ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n",
dbg_hcc_params (ehci, "reset");
#ifdef CONFIG_PCI
+ writel(0, &ehci->regs->intr_enable);
/* EHCI 0.96 and later may have "extended capabilities" */
if (hcd->self.controller->bus == &pci_bus_type)
temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
/* wire up the root hub */
bus = hcd_to_bus (hcd);
- bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0);
+ udev = usb_alloc_dev (NULL, bus, 0);
if (!udev) {
done2:
ehci_mem_cleanup (ehci);
* and device drivers may start it running.
*/
udev->speed = USB_SPEED_HIGH;
- if (hcd_register_root (hcd) != 0) {
+ if (hcd_register_root (udev, hcd) != 0) {
if (hcd->state == USB_STATE_RUNNING)
ehci_ready (ehci);
ehci_reset (ehci);
- bus->root_hub = 0;
usb_put_dev (udev);
retval = -ENODEV;
goto done2;
qh->start = frame;
/* reset S-frame and (maybe) C-frame masks */
- qh->hw_info2 &= ~0xffff;
+ qh->hw_info2 &= ~__constant_cpu_to_le32(0xffff);
qh->hw_info2 |= cpu_to_le32 (1 << uframe) | c_mask;
} else
dbg ("reused previous qh %p schedule", qh);
static int rh_connect_rh (hci_t * hci)
{
struct usb_device *usb_dev;
+ int retval;
hci->rh.devnum = 0;
usb_dev = usb_alloc_dev (NULL, hci->bus, 0);
if (!usb_dev)
return -ENOMEM;
- hci->bus->root_hub = usb_dev;
usb_dev->devnum = 1;
usb_dev->bus->devnum_next = usb_dev->devnum + 1;
set_bit (usb_dev->devnum, usb_dev->bus->devmap.devicemap);
- if (usb_new_device (usb_dev) != 0) {
+ down (&usb_bus_list_lock);
+ hci->bus->root_hub = usb_dev;
+ retval = usb_new_device (usb_dev);
+ if (retval != 0)
+ hci->bus->root_hub = NULL;
+ up (&usb_bus_list_lock);
+ if (retval != 0) {
usb_put_dev (usb_dev);
return -ENODEV;
}
struct ohci_regs *regs = controller->regs;
u32 temp;
- temp = readl (®s->revision) & 0xff;
+ temp = ohci_readl (®s->revision) & 0xff;
ohci_dbg_sw (controller, next, size,
"OHCI %d.%d, %s legacy support registers\n",
0x03 & (temp >> 4), (temp & 0x0f),
(temp & 0x10) ? "with" : "NO");
- temp = readl (®s->control);
+ temp = ohci_readl (®s->control);
ohci_dbg_sw (controller, next, size,
"control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
temp,
temp & OHCI_CTRL_CBSR
);
- temp = readl (®s->cmdstatus);
+ temp = ohci_readl (®s->cmdstatus);
ohci_dbg_sw (controller, next, size,
"cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
(temp & OHCI_SOC) >> 16,
);
ohci_dump_intr_mask (controller, "intrstatus",
- readl (®s->intrstatus), next, size);
+ ohci_readl (®s->intrstatus), next, size);
ohci_dump_intr_mask (controller, "intrenable",
- readl (®s->intrenable), next, size);
+ ohci_readl (®s->intrenable), next, size);
// intrdisable always same as intrenable
maybe_print_eds (controller, "ed_periodcurrent",
- readl (®s->ed_periodcurrent), next, size);
+ ohci_readl (®s->ed_periodcurrent), next, size);
maybe_print_eds (controller, "ed_controlhead",
- readl (®s->ed_controlhead), next, size);
+ ohci_readl (®s->ed_controlhead), next, size);
maybe_print_eds (controller, "ed_controlcurrent",
- readl (®s->ed_controlcurrent), next, size);
+ ohci_readl (®s->ed_controlcurrent), next, size);
maybe_print_eds (controller, "ed_bulkhead",
- readl (®s->ed_bulkhead), next, size);
+ ohci_readl (®s->ed_bulkhead), next, size);
maybe_print_eds (controller, "ed_bulkcurrent",
- readl (®s->ed_bulkcurrent), next, size);
+ ohci_readl (®s->ed_bulkcurrent), next, size);
maybe_print_eds (controller, "donehead",
- readl (®s->donehead), next, size);
+ ohci_readl (®s->donehead), next, size);
}
#define dbg_port_sw(hc,num,value,next,size) \
"hcca frame 0x%04x\n", OHCI_FRAME_NO(ohci->hcca));
/* other registers mostly affect frame timings */
- rdata = readl (®s->fminterval);
+ rdata = ohci_readl (®s->fminterval);
temp = scnprintf (next, size,
"fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
rdata, (rdata >> 31) ? " FIT" : "",
size -= temp;
next += temp;
- rdata = readl (®s->fmremaining);
+ rdata = ohci_readl (®s->fmremaining);
temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
rdata, (rdata >> 31) ? " FRT" : "",
rdata & 0x3fff);
size -= temp;
next += temp;
- rdata = readl (®s->periodicstart);
+ rdata = ohci_readl (®s->periodicstart);
temp = scnprintf (next, size, "periodicstart 0x%04x\n",
rdata & 0x3fff);
size -= temp;
next += temp;
- rdata = readl (®s->lsthresh);
+ rdata = ohci_readl (®s->lsthresh);
temp = scnprintf (next, size, "lsthresh 0x%04x\n",
rdata & 0x3fff);
size -= temp;
*
* History:
*
+ * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer)
* 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net)
* 2003/02/24 show registers in sysfs (Kevin Brosius)
*
/* boot firmware should have set this up (5.1.1.3.1) */
if (!ohci->fminterval) {
- temp = readl (&ohci->regs->fminterval);
+ temp = ohci_readl (&ohci->regs->fminterval);
if (temp & 0x3fff0000)
ohci->fminterval = temp;
else
* On PA-RISC, PDC can leave IR set incorrectly; ignore it there.
*/
#ifndef __hppa__
- if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
/* this timeout is arbitrary. we make it long, so systems
writel (OHCI_INTR_OC, &ohci->regs->intrenable);
writel (OHCI_OCR, &ohci->regs->cmdstatus);
- while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ while (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
msleep (10);
if (--temp == 0) {
ohci_err (ohci, "USB HC TakeOver failed!\n");
writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
ohci_dbg (ohci, "reset, control = 0x%x\n",
- readl (&ohci->regs->control));
+ ohci_readl (&ohci->regs->control));
/* Reset USB (needed by some controllers); RemoteWakeupConnected
* saved if boot firmware (BIOS/SMM/...) told us it's connected
* (for OHCI integrated on mainboard, it normally is)
*/
- ohci->hc_control = readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (&ohci->regs->control);
ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */
if (ohci->hc_control)
ohci->hcd.can_wakeup = 1;
&ohci->regs->roothub.portstatus [temp]);
}
// flush those pci writes
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
msleep (50);
/* HC Reset requires max 10 us delay */
writel (OHCI_HCR, &ohci->regs->cmdstatus);
temp = 30; /* ... allow extra time */
- while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ while ((ohci_readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
if (--temp == 0) {
ohci_err (ohci, "USB HC reset timed out!\n");
return -1;
*/
writel (ohci->hc_control, &ohci->regs->control);
// flush those pci writes
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
return 0;
}
/* some OHCI implementations are finicky about how they init.
* bogus values here mean not even enumeration could work.
*/
- if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
- || !readl (&ohci->regs->periodicstart)) {
+ if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
+ || !ohci_readl (&ohci->regs->periodicstart)) {
ohci_err (ohci, "init err\n");
return -EOVERFLOW;
}
writel (RH_HS_LPSC, &ohci->regs->roothub.status);
writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b);
// flush those pci writes
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
// POTPGT delay is bits 24-31, in 2 ms units.
mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
}
/* connect the virtual root hub */
- bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0);
+ udev = usb_alloc_dev (NULL, bus, 0);
ohci->hcd.state = USB_STATE_RUNNING;
if (!udev) {
disable (ohci);
}
udev->speed = USB_SPEED_FULL;
- if (hcd_register_root (&ohci->hcd) != 0) {
+ if (hcd_register_root (udev, &ohci->hcd) != 0) {
usb_put_dev (udev);
- bus->root_hub = NULL;
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
writel (ohci->hc_control, &ohci->regs->control);
struct ohci_regs *regs = ohci->regs;
int ints;
- /* we can eliminate a (slow) readl() if _only_ WDH caused this irq */
+ /* we can eliminate a (slow) ohci_readl()
+ if _only_ WDH caused this irq */
if ((ohci->hcca->done_head != 0)
&& ! (le32_to_cpup (&ohci->hcca->done_head) & 0x01)) {
ints = OHCI_INTR_WDH;
/* cardbus/... hardware gone before remove() */
- } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) {
+ } else if ((ints = ohci_readl (®s->intrstatus)) == ~(u32)0) {
disable (ohci);
ohci_dbg (ohci, "device removed!\n");
return IRQ_HANDLED;
/* interrupt for some other device? */
- } else if ((ints &= readl (®s->intrenable)) == 0) {
+ } else if ((ints &= ohci_readl (®s->intrenable)) == 0) {
return IRQ_NONE;
}
writel (ints, ®s->intrstatus);
writel (OHCI_INTR_MIE, ®s->intrenable);
// flush those pci writes
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
}
return IRQ_HANDLED;
#include "ohci-omap.c"
#endif
-#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111) || defined(CONFIG_ARCH_OMAP))
+#ifdef CONFIG_ARCH_LH7A404
+#include "ohci-lh7a404.c"
+#endif
+
+#if !(defined(CONFIG_PCI) \
+ || defined(CONFIG_SA1111) \
+ || defined(CONFIG_ARCH_OMAP) \
+ || defined (CONFIG_ARCH_LH7A404) \
+ )
#error "missing bus glue for ohci-hcd"
#endif
* till some bits (mostly reserved) are clear; ok for all revs.
*/
#define read_roothub(hc, register, mask) ({ \
- u32 temp = readl (&hc->regs->roothub.register); \
+ u32 temp = ohci_readl (&hc->regs->roothub.register); \
if (temp == -1) \
disable (hc); \
else if (hc->flags & OHCI_QUIRK_AMD756) \
while (temp & mask) \
- temp = readl (&hc->regs->roothub.register); \
+ temp = ohci_readl (&hc->regs->roothub.register); \
temp; })
static u32 roothub_a (struct ohci_hcd *hc)
{ return read_roothub (hc, a, 0xfc0fe000); }
static inline u32 roothub_b (struct ohci_hcd *hc)
- { return readl (&hc->regs->roothub.b); }
+ { return ohci_readl (&hc->regs->roothub.b); }
static inline u32 roothub_status (struct ohci_hcd *hc)
- { return readl (&hc->regs->roothub.status); }
+ { return ohci_readl (&hc->regs->roothub.status); }
static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
spin_lock_irq (&ohci->lock);
- ohci->hc_control = readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (&ohci->regs->control);
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_RESUME:
ohci_dbg (ohci, "resume/suspend?\n");
ohci->hc_control &= ~OHCI_CTRL_HCFS;
ohci->hc_control |= OHCI_USB_RESET;
writel (ohci->hc_control, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
/* FALL THROUGH */
case OHCI_USB_RESET:
status = -EBUSY;
ohci->hc_control &= ~OHCI_SCHED_ENABLES;
writel (ohci->hc_control, &ohci->regs->control);
- ohci->hc_control = readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (&ohci->regs->control);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
/* sched disables take effect on the next frame,
while (limit > 0) {
udelay (250);
limit =- 250;
- if (readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
+ if (ohci_readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
break;
}
dl_done_list (ohci, 0);
}
dl_done_list (ohci, 0);
finish_unlinks (ohci, OHCI_FRAME_NO(ohci->hcca), 0);
- writel (readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
+ writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
/* maybe resume can wake root hub */
if (ohci->hcd.remote_wakeup)
ohci->hc_control &= ~OHCI_CTRL_HCFS;
ohci->hc_control |= OHCI_USB_SUSPEND;
writel (ohci->hc_control, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
/* no resumes until devices finish suspending */
ohci->next_statechange = jiffies + msecs_to_jiffies (5);
return -EAGAIN;
spin_lock_irq (&ohci->lock);
- ohci->hc_control = readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (&ohci->regs->control);
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_SUSPEND:
ohci->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES);
ohci->hc_control |= OHCI_USB_RESUME;
writel (ohci->hc_control, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
ohci_dbg (ohci, "resume root hub\n");
break;
case OHCI_USB_RESUME:
temp = roothub_a (ohci) & RH_A_NDP;
enables = 0;
while (temp--) {
- u32 stat = readl (&ohci->regs->roothub.portstatus [temp]);
+ u32 stat = ohci_readl (&ohci->regs->roothub.portstatus [temp]);
/* force global, not selective, resume */
if (!(stat & RH_PS_PSS))
ohci->hcd.state = USB_STATE_RESUMING;
mdelay (20 /* usb 11.5.1.10 */ + 15);
- temp = readl (&ohci->regs->control);
+ temp = ohci_readl (&ohci->regs->control);
temp &= OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
writel (OHCI_INTR_INIT, &ohci->regs->intrenable);
if (ohci->ed_rm_list)
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
- writel (readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
+ writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
/* Then re-enable operations */
writel (OHCI_USB_OPER, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
msleep (3);
temp = OHCI_CONTROL_INIT | OHCI_USB_OPER;
temp |= OHCI_CTRL_RWC;
ohci->hc_control = temp;
writel (temp, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
/* TRSMRCY */
msleep (10);
writel (ohci->hc_control, &ohci->regs->control);
if (temp)
writel (status, &ohci->regs->cmdstatus);
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
}
ohci->hcd.state = USB_STATE_RUNNING;
if (!HCD_IS_RUNNING(ohci->hcd.state))
return -ESHUTDOWN;
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
- ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
+ ports, ohci_readl (&ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
return 0;
}
goto error;
}
writel (temp, &ohci->regs->roothub.portstatus [wIndex]);
- // readl (&ohci->regs->roothub.portstatus [wIndex]);
+ // ohci_readl (&ohci->regs->roothub.portstatus [wIndex]);
break;
case GetHubDescriptor:
ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_RESET:
- temp = readl (&ohci->regs->roothub.portstatus [wIndex]);
+ temp = ohci_readl (&ohci->regs->roothub.portstatus [wIndex]);
if (temp & RH_PS_CCS)
writel (RH_PS_PRS,
&ohci->regs->roothub.portstatus [wIndex]);
*/
void usb_hcd_omap_remove (struct usb_hcd *hcd, struct omap_dev *dev)
{
- struct usb_device *hub;
void *base;
info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
if (in_interrupt ())
BUG ();
- hub = hcd->self.root_hub;
hcd->state = USB_STATE_QUIESCING;
dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
- usb_disconnect (&hub);
+ usb_disconnect (&hcd->self.root_hub);
hcd->driver->stop (hcd);
hcd_buffer_destroy (hcd);
if (!ed->hwNextED) {
ohci->hc_control &= ~OHCI_CTRL_CLE;
writel (ohci->hc_control, &ohci->regs->control);
- // a readl() later syncs CLE with the HC
+ // a ohci_readl() later syncs CLE with the HC
} else
writel (le32_to_cpup (&ed->hwNextED),
&ohci->regs->ed_controlhead);
if (!ed->hwNextED) {
ohci->hc_control &= ~OHCI_CTRL_BLE;
writel (ohci->hc_control, &ohci->regs->control);
- // a readl() later syncs BLE with the HC
+ // a ohci_readl() later syncs BLE with the HC
} else
writel (le32_to_cpup (&ed->hwNextED),
&ohci->regs->ed_bulkhead);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
// flush those writes, and get latest HCCA contents
- (void) readl (&ohci->regs->control);
+ (void) ohci_readl (&ohci->regs->control);
/* SF interrupt might get delayed; record the frame counter value that
* indicates when the HC isn't looking at it, so concurrent unlinks
*/
void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
{
- struct usb_device *hub;
void *base;
info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
if (in_interrupt ())
BUG ();
- hub = hcd->self.root_hub;
hcd->state = USB_STATE_QUIESCING;
dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
- usb_disconnect (&hub);
+ usb_disconnect (&hcd->self.root_hub);
hcd->driver->stop (hcd);
hcd->state = USB_STATE_HALT;
# define ohci_vdbg(ohci, fmt, args...) do { } while (0)
#endif
+#ifdef CONFIG_ARCH_LH7A404
+ /* Marc Singer: at the time this code was written, the LH7A404
+ * had a problem reading the USB host registers. This
+ * implementation of the ohci_readl function performs the read
+ * twice as a work-around.
+ */
+static inline unsigned int ohci_readl (void* regs)
+{
+ *(volatile unsigned int*) regs;
+ return *(volatile unsigned int*) regs;
+}
+#else
+ /* Standard version of ohci_readl uses standard, platform
+ * specific implementation. */
+static inline unsigned int ohci_readl (void* regs)
+{
+ return readl (regs);
+}
+#endif
static void hc_state_transitions(struct uhci_hcd *uhci);
/* If a transfer is still active after this much time, turn off FSBR */
-#define IDLE_TIMEOUT (HZ / 20) /* 50 ms */
-#define FSBR_DELAY (HZ / 20) /* 50 ms */
+#define IDLE_TIMEOUT msecs_to_jiffies(50)
+#define FSBR_DELAY msecs_to_jiffies(50)
/* When we timeout an idle transfer for FSBR, we'll switch it over to */
/* depth first traversal. We'll do it in groups of this number of TD's */
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
struct list_head list, *tmp, *head;
unsigned long flags;
+ int called_uhci_finish_completion = 0;
INIT_LIST_HEAD(&list);
uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) {
uhci_remove_pending_urbps(uhci);
uhci_finish_completion(hcd, NULL);
+ called_uhci_finish_completion = 1;
}
head = &uhci->urb_list;
}
spin_unlock_irqrestore(&uhci->schedule_lock, flags);
+ /* Wake up anyone waiting for an URB to complete */
+ if (called_uhci_finish_completion)
+ wake_up_all(&uhci->waitqh);
+
head = &list;
tmp = head->next;
while (tmp != head) {
init_timer(&uhci->stall_timer);
uhci->stall_timer.function = stall_callback;
uhci->stall_timer.data = (unsigned long)hcd;
- uhci->stall_timer.expires = jiffies + (HZ / 10);
+ uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100);
add_timer(&uhci->stall_timer);
return 0;
{
unsigned int io_addr = uhci->io_addr;
+ /* Turn off PIRQ, SMI, and all interrupts. This also turns off
+ * the BIOS's USB Legacy Support.
+ */
+ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+ outw(0, uhci->io_addr + USBINTR);
+
/* Global reset for 50ms */
uhci->state = UHCI_RESET;
outw(USBCMD_GRESET, io_addr + USBCMD);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((HZ*50+999) / 1000);
+ msleep(50);
outw(0, io_addr + USBCMD);
/* Another 10ms delay */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((HZ*10+999) / 1000);
+ msleep(10);
uhci->resume_detect = 0;
}
/* Global resume for >= 20ms */
outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD);
uhci->state = UHCI_RESUMING_1;
- uhci->state_end = jiffies + (20*HZ+999) / 1000;
+ uhci->state_end = jiffies + msecs_to_jiffies(20);
break;
case UHCI_RESUMING_1: /* End global resume */
}
}
- /* Turn on all interrupts */
+ /* Turn on PIRQ and all interrupts */
+ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+ USBLEGSUP_DEFAULT);
outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
io_addr + USBINTR);
uhci->io_addr = (unsigned long) hcd->regs;
- /* Turn off all interrupts */
- outw(0, uhci->io_addr + USBINTR);
-
- /* Maybe kick BIOS off this hardware. Then reset, so we won't get
+ /* Kick BIOS off this hardware and reset, so we won't get
* interrupts from any previous setup.
*/
reset_hc(uhci);
- pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
- USBLEGSUP_DEFAULT);
return 0;
}
uhci->rh_numports = port;
- hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self, 0);
+ udev = usb_alloc_dev(NULL, &hcd->self, 0);
if (!udev) {
dev_err(uhci_dev(uhci), "unable to allocate root hub\n");
goto err_alloc_root_hub;
udev->speed = USB_SPEED_FULL;
- if (usb_register_root_hub(udev, uhci_dev(uhci)) != 0) {
+ if (hcd_register_root(udev, &uhci->hcd) != 0) {
dev_err(uhci_dev(uhci), "unable to start root hub\n");
retval = -ENOMEM;
goto err_start_root_hub;
err_alloc_term_td:
usb_put_dev(udev);
- hcd->self.root_hub = NULL;
err_alloc_root_hub:
dma_pool_destroy(uhci->qh_pool);
/*
* Some systems don't maintain the UHCI register values
* during a PM suspend/resume cycle, so reinitialize
- * the Frame Number, the Framelist Base Address, and the
- * Interrupt Enable registers.
+ * the Frame Number, Framelist Base Address, Interrupt
+ * Enable, and Legacy Support registers.
*/
+ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+ 0);
outw(uhci->saved_framenumber, uhci->io_addr + USBFRNUM);
outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC |
USBINTR_SP, uhci->io_addr + USBINTR);
uhci->resume_detect = 1;
+ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+ USBLEGSUP_DEFAULT);
} else {
reset_hc(uhci);
start_hc(uhci);
#include <asm/atomic.h>
#include <linux/blkdev.h>
#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
#include "hpusbscsi.h"
/*
* The Device read callback Function
*/
-static ssize_t mdc800_device_read (struct file *file, char *buf, size_t len, loff_t *pos)
+static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t len, loff_t *pos)
{
size_t left=len, sts=len; /* single transfer size */
- char* ptr=buf;
+ char __user *ptr = buf;
long timeout;
DECLARE_WAITQUEUE(wait, current);
* After this the driver initiates the request for the answer or
* just waits until the camera becomes ready.
*/
-static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
+static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos)
{
size_t i=0;
DECLARE_WAITQUEUE(wait, current);
#include <asm/atomic.h>
#include <linux/blkdev.h>
#include "../../scsi/scsi.h"
-#include "../../scsi/hosts.h"
+#include <scsi/scsi_host.h>
#include "microtek.h"
module will be called xpad.
config USB_ATI_REMOTE
- tristate "ATI USB RF remote control"
+ tristate "ATI / X10 USB RF remote control"
depends on USB && INPUT
---help---
- Say Y here if you want to use one of ATI's USB remote controls.
- These are RF remotes with USB receivers. They come with many of ATI's
- All-In-Wonder video cards. This driver provides mouse pointer, left
- and right mouse buttons, and maps all the other remote buttons to
- keypress events.
+ Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
+ These are RF remotes with USB receivers.
+ The ATI remote comes with many of ATI's All-In-Wonder video cards.
+ The X10 "Lola" remote is available at:
+ http://www.x10.com/products/lola_sg1.htm
+ This driver provides mouse pointer, left and right mouse buttons,
+ and maps all the other remote buttons to keypress events.
To compile this driver as a module, choose M here: the module will be
called ati_remote.
*
* Feb 2004: Torrey Hoffman <thoffman@arnor.net>
* Version 2.2.0
+ * Jun 2004: Torrey Hoffman <thoffman@arnor.net>
+ * Version 2.2.1
+ * Added key repeat support contributed by:
+ * Vincent Vanackere <vanackere@lif.univ-mrs.fr>
+ * Added support for the "Lola" remote contributed by:
+ * Seth Cohn <sethcohn@yahoo.com>
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* "All-In-Wonder" video card packages. The receiver self-identifies as a
* "USB Receiver" with manufacturer "X10 Wireless Technology Inc".
*
+ * The "Lola" remote is available from X10. See:
+ * http://www.x10.com/products/lola_sg1.htm
+ * The Lola is similar to the ATI remote but has no mouse support, and slightly
+ * different keys.
+ *
* It is possible to use multiple receivers and remotes on multiple computers
* simultaneously by configuring them to use specific channels.
*
#define ATI_REMOTE_VENDOR_ID 0x0bc7
#define ATI_REMOTE_PRODUCT_ID 0x004
+#define LOLA_REMOTE_PRODUCT_ID 0x002
-#define DRIVER_VERSION "2.2.0"
+#define DRIVER_VERSION "2.2.1"
#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>"
#define DRIVER_DESC "ATI/X10 RF USB Remote Control"
static struct usb_device_id ati_remote_table[] = {
{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
+ { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
{} /* Terminating entry */
};
/* Duplicate event filtering time.
* Sequential, identical KIND_FILTERED inputs with less than
- * FILTER_TIME jiffies between them are dropped.
- * (HZ >> 4) == 1/16th of a second and works well for me.
+ * FILTER_TIME jiffies between them are considered as repeat
+ * events. The hardware generates 5 events for the first keypress
+ * and we have to take this into account for an accurate repeat
+ * behaviour.
+ * (HZ / 20) == 50 ms and works well for me.
*/
-#define FILTER_TIME (HZ >> 4)
+#define FILTER_TIME (HZ / 20)
static DECLARE_MUTEX(disconnect_sem);
unsigned char old_data[2]; /* Detect duplicate events */
unsigned long old_jiffies;
unsigned long acc_jiffies; /* handle acceleration */
+ unsigned int repeat_count;
char name[NAME_BUFSIZE];
char phys[NAME_BUFSIZE];
{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */
{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */
{KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */
+ {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */
+ {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */
+ {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */
+ {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */
+ {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */
+ {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */
{KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
};
if ((ati_remote->old_data[0] == data[1]) &&
(ati_remote->old_data[1] == data[2]) &&
((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
- ati_remote->old_jiffies = jiffies;
+ ati_remote->repeat_count++;
+ }
+ else {
+ ati_remote->repeat_count = 0;
+ }
+
+ ati_remote->old_data[0] = data[1];
+ ati_remote->old_data[1] = data[2];
+ ati_remote->old_jiffies = jiffies;
+
+ if ((ati_remote->repeat_count > 0)
+ && (ati_remote->repeat_count < 5))
return;
- }
+
input_regs(dev, regs);
input_event(dev, ati_remote_tbl[index].type,
ati_remote_tbl[index].code, 0);
input_sync(dev);
- ati_remote->old_data[0] = data[1];
- ati_remote->old_data[1] = data[2];
- ati_remote->old_jiffies = jiffies;
return;
}
/* See if the offered device matches what we can accept */
if ((udev->descriptor.idVendor != ATI_REMOTE_VENDOR_ID) ||
- (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID)) {
+ ( (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID) &&
+ (udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) ))
return -ENODEV;
- }
/* Allocate and clear an ati_remote struct */
if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-
}
err = 0;
- while ((ret = hid_wait_io(hid))) {
+ ret = hid_wait_io(hid);
+ while (ret) {
err |= ret;
if (test_bit(HID_CTRL_RUNNING, &hid->iofl))
usb_unlink_urb(hid->urbctrl);
if (test_bit(HID_OUT_RUNNING, &hid->iofl))
usb_unlink_urb(hid->urbout);
+ ret = hid_wait_io(hid);
}
if (err)
/*
* "write" file op
*/
-static ssize_t hiddev_write(struct file * file, const char * buffer, size_t count, loff_t *ppos)
+static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
{
return -EINVAL;
}
/*
* "read" file op
*/
-static ssize_t hiddev_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
+static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
{
DECLARE_WAITQUEUE(wait, current);
struct hiddev_list *list = file->private_data;
struct hiddev_devinfo dinfo;
struct hid_report *report;
struct hid_field *field;
+ void __user *user_arg = (void __user *)arg;
int i;
if (!hiddev->exist)
switch (cmd) {
case HIDIOCGVERSION:
- return put_user(HID_VERSION, (int *) arg);
+ return put_user(HID_VERSION, (int __user *)arg);
case HIDIOCAPPLICATION:
if (arg < 0 || arg >= hid->maxapplication)
dinfo.product = dev->descriptor.idProduct;
dinfo.version = dev->descriptor.bcdDevice;
dinfo.num_applications = hid->maxapplication;
- if (copy_to_user((void *) arg, &dinfo, sizeof(dinfo)))
+ if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
return -EFAULT;
return 0;
case HIDIOCGFLAG:
- if (put_user(list->flags, (int *) arg))
+ if (put_user(list->flags, (int __user *)arg))
return -EFAULT;
return 0;
case HIDIOCSFLAG:
{
int newflags;
- if (get_user(newflags, (int *) arg))
+ if (get_user(newflags, (int __user *)arg))
return -EFAULT;
if ((newflags & ~HIDDEV_FLAGS) != 0 ||
int idx, len;
char *buf;
- if (get_user(idx, (int *) arg))
+ if (get_user(idx, (int __user *)arg))
return -EFAULT;
if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
return -EINVAL;
}
- if (copy_to_user((void *) (arg+sizeof(int)), buf, len+1)) {
+ if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
kfree(buf);
return -EFAULT;
}
return 0;
case HIDIOCGREPORT:
- if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
+ if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
return -EFAULT;
if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
return 0;
case HIDIOCSREPORT:
- if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
+ if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
return -EFAULT;
if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
return 0;
case HIDIOCGREPORTINFO:
- if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
+ if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
return -EFAULT;
if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
rinfo.num_fields = report->maxfield;
- if (copy_to_user((void *) arg, &rinfo, sizeof(rinfo)))
+ if (copy_to_user(user_arg, &rinfo, sizeof(rinfo)))
return -EFAULT;
return 0;
case HIDIOCGFIELDINFO:
- if (copy_from_user(&finfo, (void *) arg, sizeof(finfo)))
+ if (copy_from_user(&finfo, user_arg, sizeof(finfo)))
return -EFAULT;
rinfo.report_type = finfo.report_type;
rinfo.report_id = finfo.report_id;
finfo.unit_exponent = field->unit_exponent;
finfo.unit = field->unit;
- if (copy_to_user((void *) arg, &finfo, sizeof(finfo)))
+ if (copy_to_user(user_arg, &finfo, sizeof(finfo)))
return -EFAULT;
return 0;
if (!uref_multi)
return -ENOMEM;
uref = &uref_multi->uref;
- if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
+ if (copy_from_user(uref, user_arg, sizeof(*uref)))
goto fault;
rinfo.report_type = uref->report_type;
uref->usage_code = field->usage[uref->usage_index].hid;
- if (copy_to_user((void *) arg, uref, sizeof(*uref)))
+ if (copy_to_user(user_arg, uref, sizeof(*uref)))
goto fault;
kfree(uref_multi);
return -ENOMEM;
uref = &uref_multi->uref;
if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
- if (copy_from_user(uref_multi, (void *) arg,
+ if (copy_from_user(uref_multi, user_arg,
sizeof(*uref_multi)))
goto fault;
} else {
- if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
+ if (copy_from_user(uref, user_arg, sizeof(*uref)))
goto fault;
}
switch (cmd) {
case HIDIOCGUSAGE:
uref->value = field->value[uref->usage_index];
- if (copy_to_user((void *) arg, uref, sizeof(*uref)))
+ if (copy_to_user(user_arg, uref, sizeof(*uref)))
goto fault;
goto goodreturn;
for (i = 0; i < uref_multi->num_values; i++)
uref_multi->values[i] =
field->value[uref->usage_index + i];
- if (copy_to_user((void *) arg, uref_multi,
+ if (copy_to_user(user_arg, uref_multi,
sizeof(*uref_multi)))
goto fault;
goto goodreturn;
return -EINVAL;
case HIDIOCGCOLLECTIONINFO:
- if (copy_from_user(&cinfo, (void *) arg, sizeof(cinfo)))
+ if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
return -EFAULT;
if (cinfo.index >= hid->maxcollection)
cinfo.usage = hid->collection[cinfo.index].usage;
cinfo.level = hid->collection[cinfo.index].level;
- if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(user_arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
len = strlen(hid->name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user((char *) arg, hid->name, len) ?
+ return copy_to_user(user_arg, hid->name, len) ?
-EFAULT : len;
}
len = strlen(hid->phys) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user((char *) arg, hid->phys, len) ?
+ return copy_to_user(user_arg, hid->phys, len) ?
-EFAULT : len;
}
}
config USB_PWC
tristate "USB Philips Cameras"
- depends on USB && VIDEO_DEV && BROKEN
+ depends on USB && VIDEO_DEV && CONFIG_BROKEN
---help---
Say Y or M here if you want to use one of these Philips & OEM
webcams:
return 0;
}
-static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t * ppos)
+static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
{
pdabusb_t s = (pdabusb_t) file->private_data;
unsigned long flags;
break;
}
- if (copy_from_user (pbulk, (void *) arg, sizeof (bulk_transfer_t))) {
+ if (copy_from_user (pbulk, (void __user *) arg, sizeof (bulk_transfer_t))) {
ret = -EFAULT;
kfree (pbulk);
break;
ret=dabusb_bulk (s, pbulk);
if(ret==0)
- if (copy_to_user((void *)arg, pbulk,
+ if (copy_to_user((void __user *)arg, pbulk,
sizeof(bulk_transfer_t)))
ret = -EFAULT;
kfree (pbulk);
break;
case IOCTL_DAB_OVERRUNS:
- ret = put_user (s->overruns, (unsigned int *) arg);
+ ret = put_user (s->overruns, (unsigned int __user *) arg);
break;
case IOCTL_DAB_VERSION:
- ret = put_user (version, (unsigned int *) arg);
+ ret = put_user (version, (unsigned int __user *) arg);
break;
default:
}
static ssize_t
-ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos)
+ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
{
struct video_device *vdev = file->private_data;
int noblock = file->f_flags&O_NONBLOCK;
#ifdef OV511_DEBUG
#define PDEBUG(level, fmt, args...) \
if (debug >= (level)) info("[%s:%d] " fmt, \
- __PRETTY_FUNCTION__, __LINE__ , ## args)
+ __FUNCTION__, __LINE__ , ## args)
#else
#define PDEBUG(level, fmt, args...) do {} while(0)
#endif
static int pwc_video_open(struct inode *inode, struct file *file);
static int pwc_video_close(struct inode *inode, struct file *file);
-static int pwc_video_release(struct video_device *);
-static ssize_t pwc_video_read(struct file *file, char *buf,
+static ssize_t pwc_video_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos);
static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
static int pwc_video_ioctl(struct inode *inode, struct file *file,
return 0;
}
-static int pwc_video_release(struct video_device *vfd)
-{
- Trace(TRACE_OPEN, "pwc_video_release() called. Now what?\n");
-}
-
-
/*
* FIXME: what about two parallel reads ????
* ANSWER: Not supported. You can't open the device more than once,
device is tricky anyhow.
*/
-static ssize_t pwc_video_read(struct file *file, char *buf,
+static ssize_t pwc_video_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct video_device *vdev = file->private_data;
}
}
- pdev->vdev.release = pwc_video_release;
+ pdev->vdev.release = video_device_release;
i = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
if (i < 0) {
Err("Failed to register as video device (%d).\n", i);
return video_usercopy(inode, file, cmd, arg, se401_do_ioctl);
}
-static ssize_t se401_read(struct file *file, char *buf,
+static ssize_t se401_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
int realcount=count, ret=0;
return 0;
}
-static ssize_t stv680_read (struct file *file, char *buf,
+static ssize_t stv680_read (struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct video_device *dev = file->private_data;
unsigned int cmd, unsigned long arg);
static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
static int usbvideo_v4l_open(struct inode *inode, struct file *file);
-static ssize_t usbvideo_v4l_read(struct file *file, char *buf,
+static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos);
static int usbvideo_v4l_close(struct inode *inode, struct file *file);
* 20-Oct-2000 Created.
* 01-Nov-2000 Added mutex (uvd->lock).
*/
-static ssize_t usbvideo_v4l_read(struct file *file, char *buf,
+static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct uvd *uvd = file->private_data;
}
static int
-vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long ul_arg)
+vicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg)
{
- void *arg = (void *)ul_arg;
+ void __user *user_arg = (void __user *)arg;
struct vicam_camera *cam = file->private_data;
int retval = 0;
b.minwidth = 320; /* VIDEOSIZE_48_48 */
b.minheight = 240;
- if (copy_to_user(arg, &b, sizeof (b)))
+ if (copy_to_user(user_arg, &b, sizeof(b)))
retval = -EFAULT;
break;
struct video_channel v;
DBG("VIDIOCGCHAN\n");
- if (copy_from_user(&v, arg, sizeof (v))) {
+ if (copy_from_user(&v, user_arg, sizeof(v))) {
retval = -EFAULT;
break;
}
v.type = VIDEO_TYPE_CAMERA;
v.norm = 0;
- if (copy_to_user(arg, &v, sizeof (v)))
+ if (copy_to_user(user_arg, &v, sizeof(v)))
retval = -EFAULT;
break;
}
{
int v;
- if (copy_from_user(&v, arg, sizeof (v)))
+ if (copy_from_user(&v, user_arg, sizeof(v)))
retval = -EFAULT;
DBG("VIDIOCSCHAN %d\n", v);
vp.brightness = cam->gain << 8;
vp.depth = 24;
vp.palette = VIDEO_PALETTE_RGB24;
- if (copy_to_user
- (arg, &vp, sizeof (struct video_picture)))
+ if (copy_to_user(user_arg, &vp, sizeof (struct video_picture)))
retval = -EFAULT;
break;
}
{
struct video_picture vp;
- if (copy_from_user(&vp, arg, sizeof(vp))) {
+ if (copy_from_user(&vp, user_arg, sizeof(vp))) {
retval = -EFAULT;
break;
}
DBG("VIDIOCGWIN\n");
- if (copy_to_user
- ((void *) arg, (void *) &vw, sizeof (vw)))
+ if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
retval = -EFAULT;
// I'm not sure what the deal with a capture window is, it is very poorly described
struct video_window vw;
- if (copy_from_user(&vw, arg, sizeof(vw))) {
+ if (copy_from_user(&vw, user_arg, sizeof(vw))) {
retval = -EFAULT;
break;
}
for (i = 0; i < VICAM_FRAMES; i++)
vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;
- if (copy_to_user
- ((void *) arg, (void *) &vm, sizeof (vm)))
+ if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
retval = -EFAULT;
break;
struct video_mmap vm;
// int video_size;
- if (copy_from_user
- ((void *) &vm, (void *) arg, sizeof (vm))) {
+ if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
retval = -EFAULT;
break;
}
{
int frame;
- if (copy_from_user((void *) &frame, arg, sizeof (int))) {
+ if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
retval = -EFAULT;
break;
}
}
static ssize_t
-vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos )
+vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos )
{
struct vicam_camera *cam = file->private_data;
static struct file_operations w9968cf_fops;
static int w9968cf_open(struct inode*, struct file*);
static int w9968cf_release(struct inode*, struct file*);
-static ssize_t w9968cf_read(struct file*, char*, size_t, loff_t*);
+static ssize_t w9968cf_read(struct file*, char __user *, size_t, loff_t*);
static int w9968cf_mmap(struct file*, struct vm_area_struct*);
static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, void*);
/* High-level CMOS sensor control functions */
static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
-static inline int w9968cf_sensor_cmd(struct w9968cf_device*,
- unsigned int cmd, void *arg);
+static int w9968cf_sensor_cmd(struct w9968cf_device*,
+ unsigned int cmd, void *arg);
static int w9968cf_sensor_init(struct w9968cf_device*);
static int w9968cf_sensor_update_settings(struct w9968cf_device*);
static int w9968cf_sensor_get_picture(struct w9968cf_device*);
static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
static inline u16 w9968cf_valid_palette(u16 palette);
-static inline u16 w9968cf_valid_depth(u16 palette);
+static u16 w9968cf_valid_depth(u16 palette);
static inline u8 w9968cf_need_decompression(u16 palette);
static int w9968cf_postprocess_frame(struct w9968cf_device*,
struct w9968cf_frame_t*);
Return the depth corresponding to the given palette.
Palette _must_ be supported !
--------------------------------------------------------------------------*/
-static inline u16 w9968cf_valid_depth(u16 palette)
+static u16 w9968cf_valid_depth(u16 palette)
{
u8 i=0;
while (w9968cf_formatlist[i].palette != palette)
}
-static inline int
+static int
w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
{
struct i2c_client* c = cam->sensor_client;
static ssize_t
-w9968cf_read(struct file* filp, char* buf, size_t count, loff_t* f_pos)
+w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
{
struct w9968cf_device* cam;
struct w9968cf_frame_t* fr;
unsigned int cmd, void* arg)
{
struct w9968cf_device* cam;
- static const char* v4l1_ioctls[] = {
+ void __user *user_arg = (void __user *)arg;
+ const char* v4l1_ioctls[] = {
"?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
"GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
"SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
"SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
"GVBIFMT", "SVBIFMT"
};
- struct video_tuner tuner;
- struct video_channel chan;
#define V4L1_IOCTL(cmd) \
((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
cap.maxheight = (cam->upscaling && w9968cf_vppmod_present)
? W9968CF_MAX_HEIGHT : cam->maxheight;
- if (copy_to_user(arg, &cap, sizeof(cap)))
+ if (copy_to_user(user_arg, &cap, sizeof(cap)))
return -EFAULT;
DBG(5, "VIDIOCGCAP successfully called.")
case VIDIOCGCHAN: /* get video channel informations */
{
- if (copy_from_user(&chan, arg, sizeof(chan)))
+ struct video_channel chan;
+ if (copy_from_user(&chan, user_arg, sizeof(chan)))
return -EFAULT;
if (chan.channel != 0)
chan.type = VIDEO_TYPE_CAMERA;
chan.norm = VIDEO_MODE_AUTO;
- if (copy_to_user(arg, &chan, sizeof(chan)))
+ if (copy_to_user(user_arg, &chan, sizeof(chan)))
return -EFAULT;
DBG(5, "VIDIOCGCHAN successfully called.")
case VIDIOCSCHAN: /* set active channel */
{
- if (copy_from_user(&chan, arg, sizeof(chan)))
+ struct video_channel chan;
+
+ if (copy_from_user(&chan, user_arg, sizeof(chan)))
return -EFAULT;
if (chan.channel != 0)
if (w9968cf_sensor_get_picture(cam))
return -EIO;
- if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
+ if (copy_to_user(user_arg, &cam->picture, sizeof(cam->picture)))
return -EFAULT;
DBG(5, "VIDIOCGPICT successfully called.")
struct video_picture pict;
int err = 0;
- if (copy_from_user(&pict, arg, sizeof(pict)))
+ if (copy_from_user(&pict, user_arg, sizeof(pict)))
return -EFAULT;
if ( (cam->force_palette || !w9968cf_vppmod_present)
struct video_window win;
int err = 0;
- if (copy_from_user(&win, arg, sizeof(win)))
+ if (copy_from_user(&win, user_arg, sizeof(win)))
return -EFAULT;
DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%d, "
case VIDIOCGWIN: /* get current window properties */
{
- if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
+ if (copy_to_user(user_arg, &cam->window, sizeof(struct video_window)))
return -EFAULT;
DBG(5, "VIDIOCGWIN successfully called.")
mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
(unsigned long)cam->frame[0].buffer;
- if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
+ if (copy_to_user(user_arg, &mbuf, sizeof(mbuf)))
return -EFAULT;
DBG(5, "VIDIOCGMBUF successfully called.")
struct w9968cf_frame_t* fr;
int err = 0;
- if (copy_from_user(&mmap, arg, sizeof(mmap)))
+ if (copy_from_user(&mmap, user_arg, sizeof(mmap)))
return -EFAULT;
DBG(6, "VIDIOCMCAPTURE called: frame #%d, format=%s, %dx%d",
struct w9968cf_frame_t* fr;
int err = 0;
- if (copy_from_user(&f_num, arg, sizeof(f_num)))
+ if (copy_from_user(&f_num, user_arg, sizeof(f_num)))
return -EFAULT;
if (f_num >= cam->nbuffers) {
.teletext = VIDEO_NO_UNIT,
};
- if (copy_to_user(arg, &unit, sizeof(unit)))
+ if (copy_to_user(user_arg, &unit, sizeof(unit)))
return -EFAULT;
DBG(5, "VIDIOCGUNIT successfully called.")
case VIDIOCGFBUF:
{
- if (clear_user(arg, sizeof(struct video_buffer)))
+ if (clear_user(user_arg, sizeof(struct video_buffer)))
return -EFAULT;
DBG(5, "VIDIOCGFBUF successfully called.")
case VIDIOCGTUNER:
{
- if (copy_from_user(&tuner, arg, sizeof(tuner)))
+ struct video_tuner tuner;
+ if (copy_from_user(&tuner, user_arg, sizeof(tuner)))
return -EFAULT;
if (tuner.tuner != 0)
tuner.mode = VIDEO_MODE_AUTO;
tuner.signal = 0xffff;
- if (copy_to_user(arg, &tuner, sizeof(tuner)))
+ if (copy_to_user(user_arg, &tuner, sizeof(tuner)))
return -EFAULT;
DBG(5, "VIDIOCGTUNER successfully called.")
case VIDIOCSTUNER:
{
- if (copy_from_user(&tuner, arg, sizeof(tuner)))
+ struct video_tuner tuner;
+ if (copy_from_user(&tuner, user_arg, sizeof(tuner)))
return -EFAULT;
if (tuner.tuner != 0)
warn(fmt, ## args); \
else if ((level) >= 5) \
info("[%s:%d] " fmt, \
- __PRETTY_FUNCTION__, __LINE__ , ## args); \
+ __FUNCTION__, __LINE__ , ## args); \
} \
}
#else
audevinfo_t devinfo;
pauerswald_t cp = NULL;
unsigned int u;
+ unsigned int __user *user_arg = (unsigned int __user *)arg;
+
dbg ("ioctl");
/* get the mutexes */
u = ccp->auerdev
&& (ccp->scontext.id != AUH_UNASSIGNED)
&& !list_empty (&cp->bufctl.free_buff_list);
- ret = put_user (u, (unsigned int *) arg);
+ ret = put_user (u, user_arg);
break;
/* return != 0 if connected to a service channel */
case IOCTL_AU_CONNECT:
dbg ("IOCTL_AU_CONNECT");
u = (ccp->scontext.id != AUH_UNASSIGNED);
- ret = put_user (u, (unsigned int *) arg);
+ ret = put_user (u, user_arg);
break;
/* return != 0 if Receive Data available */
u = 1;
}
}
- ret = put_user (u, (unsigned int *) arg);
+ ret = put_user (u, user_arg);
break;
/* return the max. buffer length for the device */
case IOCTL_AU_BUFLEN:
dbg ("IOCTL_AU_BUFLEN");
u = cp->maxControlLength;
- ret = put_user (u, (unsigned int *) arg);
+ ret = put_user (u, user_arg);
break;
/* requesting a service channel */
/* requesting a service means: release the previous one first */
auerswald_removeservice (cp, &ccp->scontext);
/* get the channel number */
- ret = get_user (u, (unsigned int *) arg);
+ ret = get_user (u, user_arg);
if (ret) {
break;
}
case IOCTL_AU_SLEN:
dbg ("IOCTL_AU_SLEN");
u = AUSI_DLEN;
- ret = put_user (u, (unsigned int *) arg);
+ ret = put_user (u, user_arg);
break;
default:
/* local function prototypes */
-static ssize_t tower_read (struct file *file, char *buffer, size_t count, loff_t *ppos);
-static ssize_t tower_write (struct file *file, const char *buffer, size_t count, loff_t *ppos);
+static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos);
+static ssize_t tower_write (struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
static inline void tower_delete (struct lego_usb_tower *dev);
static int tower_open (struct inode *inode, struct file *file);
static int tower_release (struct inode *inode, struct file *file);
/**
* tower_read
*/
-static ssize_t tower_read (struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct lego_usb_tower *dev;
size_t bytes_to_read;
/**
* tower_write
*/
-static ssize_t tower_write (struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t tower_write (struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct lego_usb_tower *dev;
size_t bytes_to_write;
*
* CAUTION: Generally you should use 0 < degrees < 180 as anything else
* is probably beyond the range of your servo and may damage it.
+ *
+ * Jun 16, 2004: Sean Young <sean@mess.org>
+ * - cleanups
+ * - was using memory after kfree()
*/
#include <linux/config.h>
#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
#define DRIVER_DESC "USB PhidgetServo Driver"
-#define VENDOR_ID_GLAB 0x06c2
-#define DEVICE_ID_4MOTOR_SERVO_30 0x0038
-#define DEVICE_ID_1MOTOR_SERVO_30 0x0039
+#define VENDOR_ID_GLAB 0x06c2
+#define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD 0x0038
+#define DEVICE_ID_GLAB_PHIDGETSERVO_UNI 0x0039
+
+#define VENDOR_ID_WISEGROUP 0x0925
+#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD 0x8101
+#define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI 0x8104
-#define VENDOR_ID_WISEGROUP 0x0925
-#define DEVICE_ID_1MOTOR_SERVO_20 0x8101
-#define DEVICE_ID_4MOTOR_SERVO_20 0x8104
+#define SERVO_VERSION_30 0x01
+#define SERVO_COUNT_QUAD 0x02
static struct usb_device_id id_table[] = {
- {USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_4MOTOR_SERVO_30)},
- {USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_1MOTOR_SERVO_30)},
- {USB_DEVICE(VENDOR_ID_WISEGROUP, DEVICE_ID_4MOTOR_SERVO_20)},
- {USB_DEVICE(VENDOR_ID_WISEGROUP, DEVICE_ID_1MOTOR_SERVO_20)},
+ {
+ USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD),
+ .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD
+ },
+ {
+ USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI),
+ .driver_info = SERVO_VERSION_30
+ },
+ {
+ USB_DEVICE(VENDOR_ID_WISEGROUP,
+ VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD),
+ .driver_info = SERVO_COUNT_QUAD
+ },
+ {
+ USB_DEVICE(VENDOR_ID_WISEGROUP,
+ VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI),
+ .driver_info = 0
+ },
{}
};
struct phidget_servo {
struct usb_device *udev;
- int version;
- int quad_servo;
+ ulong type;
int pulse[4];
int degrees[4];
int minutes[4];
};
-static void
+static int
change_position_v30(struct phidget_servo *servo, int servo_no, int degrees,
int minutes)
{
if (!buffer) {
dev_err(&servo->udev->dev, "%s - out of memory\n",
__FUNCTION__);
- return;
+ return -ENOMEM;
}
/*
retval = usb_control_msg(servo->udev,
usb_sndctrlpipe(servo->udev, 0),
0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2 * HZ);
- if (retval != 6)
- dev_err(&servo->udev->dev, "retval = %d\n", retval);
+
kfree(buffer);
+
+ return retval;
}
-static void
+static int
change_position_v20(struct phidget_servo *servo, int servo_no, int degrees,
int minutes)
{
if (!buffer) {
dev_err(&servo->udev->dev, "%s - out of memory\n",
__FUNCTION__);
- return;
+ return -ENOMEM;
}
/*
retval = usb_control_msg(servo->udev,
usb_sndctrlpipe(servo->udev, 0),
0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2 * HZ);
- if (retval != 2)
- dev_err(&servo->udev->dev, "retval = %d\n", retval);
+
kfree(buffer);
+
+ return retval;
}
#define show_set(value) \
static ssize_t set_servo##value (struct device *dev, \
const char *buf, size_t count) \
{ \
- int degrees, minutes; \
+ int degrees, minutes, retval; \
struct usb_interface *intf = to_usb_interface (dev); \
struct phidget_servo *servo = usb_get_intfdata (intf); \
\
return -EINVAL; \
} \
\
- if (servo->version >= 3) \
- change_position_v30 (servo, value, degrees, minutes); \
+ if (servo->type & SERVO_VERSION_30) \
+ retval = change_position_v30 (servo, value, degrees, \
+ minutes); \
else \
- change_position_v20 (servo, value, degrees, minutes); \
+ retval = change_position_v20 (servo, value, degrees, \
+ minutes); \
\
- return count; \
+ return retval < 0 ? retval : count; \
} \
\
static ssize_t show_servo##value (struct device *dev, char *buf) \
servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
- struct phidget_servo *dev = NULL;
+ struct phidget_servo *dev;
dev = kmalloc(sizeof (struct phidget_servo), GFP_KERNEL);
if (dev == NULL) {
memset(dev, 0x00, sizeof (*dev));
dev->udev = usb_get_dev(udev);
- switch (udev->descriptor.idVendor) {
- case VENDOR_ID_WISEGROUP:
- dev->version = 2;
- break;
- case VENDOR_ID_GLAB:
- dev->version = 3;
- break;
- }
- switch (udev->descriptor.idProduct) {
- case DEVICE_ID_4MOTOR_SERVO_20:
- case DEVICE_ID_4MOTOR_SERVO_30:
- dev->quad_servo = 1;
- break;
- case DEVICE_ID_1MOTOR_SERVO_20:
- case DEVICE_ID_1MOTOR_SERVO_30:
- dev->quad_servo = 0;
- break;
- }
-
+ dev->type = id->driver_info;
usb_set_intfdata(interface, dev);
device_create_file(&interface->dev, &dev_attr_servo0);
- if (dev->quad_servo) {
+ if (dev->type & SERVO_COUNT_QUAD) {
device_create_file(&interface->dev, &dev_attr_servo1);
device_create_file(&interface->dev, &dev_attr_servo2);
device_create_file(&interface->dev, &dev_attr_servo3);
}
dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n",
- dev->quad_servo ? 4 : 1, dev->version);
- if (dev->version == 2)
+ dev->type & SERVO_COUNT_QUAD ? 4 : 1,
+ dev->type & SERVO_VERSION_30 ? 3 : 2);
+
+ if(!(dev->type & SERVO_VERSION_30))
dev_info(&interface->dev,
"WARNING: v2.0 not tested! Please report if it works.\n");
usb_set_intfdata(interface, NULL);
device_remove_file(&interface->dev, &dev_attr_servo0);
- if (dev->quad_servo) {
+ if (dev->type & SERVO_COUNT_QUAD) {
device_remove_file(&interface->dev, &dev_attr_servo1);
device_remove_file(&interface->dev, &dev_attr_servo2);
device_remove_file(&interface->dev, &dev_attr_servo3);
usb_put_dev(dev->udev);
- kfree(dev);
-
dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n",
- dev->quad_servo ? 4 : 1, dev->version);
+ dev->type & SERVO_COUNT_QUAD ? 4 : 1,
+ dev->type & SERVO_VERSION_30 ? 3 : 2);
+
+ kfree(dev);
}
static struct usb_driver servo_driver = {
static int __init
phidget_servo_init(void)
{
- int retval = 0;
+ int retval;
retval = usb_register(&servo_driver);
if (retval)
static void udsl_atm_dev_close (struct atm_dev *dev);
static int udsl_atm_open (struct atm_vcc *vcc);
static void udsl_atm_close (struct atm_vcc *vcc);
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void __user *arg);
static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page);
dbg ("udsl_atm_close successful");
}
-static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void __user *arg)
{
switch (cmd) {
case ATM_QUERYLOOP:
- return put_user (ATM_LM_NONE, (int *) arg) ? -EFAULT : 0;
+ return put_user (ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
* or remote wakeup (which needs human interaction).
*/
-static int realworld = 1;
-MODULE_PARM (realworld, "i");
+static unsigned realworld = 1;
+module_param (realworld, uint, 0);
MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance");
static int get_altsetting (struct usbtest_dev *dev)
/*-------------------------------------------------------------------------*/
-static int force_interrupt = 0;
-MODULE_PARM (force_interrupt, "i");
+static unsigned force_interrupt = 0;
+module_param (force_interrupt, uint, 0);
MODULE_PARM_DESC (force_interrupt, "0 = test default; else interrupt");
#ifdef GENERIC
-static int vendor;
-MODULE_PARM (vendor, "h");
+static unsigned short vendor;
+module_param(vendor, ushort, 0);
MODULE_PARM_DESC (vendor, "vendor code (from usb-if)");
-static int product;
-MODULE_PARM (product, "h");
+static unsigned short product;
+module_param(product, ushort, 0);
MODULE_PARM_DESC (product, "product code (from vendor)");
#endif
struct catc *catc = dev->priv;
u32 cmd;
- if (get_user(cmd, (u32 *)useraddr))
+ if (get_user(cmd, (u32 __user *)useraddr))
return -EFAULT;
switch (cmd) {
{
switch(cmd) {
case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void __user *)rq->ifr_data);
+ return netdev_ethtool_ioctl(dev, rq->ifr_data);
default:
return -EOPNOTSUPP;
}
{
switch (cmd) {
case SIOCETHTOOL:
- return netdev_ethtool_ioctl(net, (void __user *)rq->ifr_data);
+ return netdev_ethtool_ioctl(net, rq->ifr_data);
}
return -EOPNOTSUPP;
}
int cmd;
pegasus = net->priv;
- if (get_user(cmd, (int *) uaddr))
+ if (get_user(cmd, (int __user *) uaddr))
return -EFAULT;
switch (cmd) {
case ETHTOOL_GDRVINFO:{
#endif
static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
{
- __u16 *data = (__u16 *) & rq->ifr_data;
+ __u16 *data = (__u16 *) & rq->ifr_ifru;
pegasus_t *pegasus = net->priv;
int res;
switch (cmd) {
case SIOCETHTOOL:
- res = pegasus_ethtool_ioctl(net, (void __user *)rq->ifr_data);
+ res = pegasus_ethtool_ioctl(net, rq->ifr_data);
break;
case SIOCDEVPRIVATE:
data[0] = pegasus->phy;
#define VENDOR_ADMTEK 0x07a6
#define VENDOR_AEILAB 0x3334
#define VENDOR_ALLIEDTEL 0x07c9
+#define VENDOR_ATEN 0x0557
#define VENDOR_BELKIN 0x050d
#define VENDOR_BILLIONTON 0x08dd
#define VENDOR_COMPAQ 0x049f
PEGASUS_DEV( "3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601,
DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c,
DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
PEGASUS_DEV( "USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104,
usb_unlink_urb(dev->ctrl_urb);
}
+static inline struct sk_buff *pull_skb(rtl8150_t *dev)
+{
+ struct sk_buff *skb;
+ int i;
+
+ for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
+ if (dev->rx_skb_pool[i]) {
+ skb = dev->rx_skb_pool[i];
+ dev->rx_skb_pool[i] = NULL;
+ return skb;
+ }
+ }
+ return NULL;
+}
+
static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
{
rtl8150_t *dev;
dev_kfree_skb(dev->rx_skb_pool[i]);
}
-static inline struct sk_buff *pull_skb(rtl8150_t *dev)
-{
- struct sk_buff *skb;
- int i;
-
- for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
- if (dev->rx_skb_pool[i]) {
- skb = dev->rx_skb_pool[i];
- dev->rx_skb_pool[i] = NULL;
- return skb;
- }
- }
- return NULL;
-}
-
static int enable_net_traffic(rtl8150_t * dev)
{
u8 cr, tcr, rcr, msr;
return res;
}
-static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr)
+static int rtl8150_ethtool_ioctl(struct net_device *netdev, void __user *uaddr)
{
rtl8150_t *dev;
int cmd;
dev = netdev->priv;
- if (get_user(cmd, (int *) uaddr))
+ if (get_user(cmd, (int __user *) uaddr))
return -EFAULT;
switch (cmd) {
int res;
dev = netdev->priv;
- data = (u16 *) & rq->ifr_data;
+ data = (u16 *) & rq->ifr_ifru;
res = 0;
switch (cmd) {
* disconnect; other cleanups. (db) Flush net1080 fifos
* after several sequential framing errors. (Johannes Erdfelt)
* 22-aug-2003 AX8817X support (Dave Hollis).
+ * 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
+ * (Neil Bortnak)
*
*-------------------------------------------------------------------------*/
status = get_ethernet_addr (dev, info->ether);
if (status < 0) {
+ usb_set_intfdata(info->data, NULL);
usb_driver_release_interface (&usbnet_driver, info->data);
return status;
}
struct usbnet *dev = (struct usbnet *)net->priv;
if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
- return generic_mii_ioctl(&dev->mii,
- (struct mii_ioctl_data *) &rq->ifr_data,
- cmd, NULL);
+ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
}
#endif
return -EOPNOTSUPP;
// ATEN UC210T
USB_DEVICE (0x0557, 0x2009),
.driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Buffalo LUA-U2-KTX
+ USB_DEVICE (0x0411, 0x003d),
+ .driver_info = (unsigned long) &ax8817x_info,
},
#endif
minor = port->number;
tty_register_device (usb_serial_tty_driver, minor, dev);
dev_info(&port->serial->dev->dev,
- "%s converter now attached to ttyUSB%d (or usb/tts/%d for devfs)\n",
- driver->name, minor, minor);
+ "%s converter now attached to ttyUSB%d\n",
+ driver->name, minor);
exit:
return retval;
short rdtodo; /* Bytes still to read */
unsigned char wrbuf[5*64]; /* Buffer for collecting data to write */
short wrfilled; /* Overall data size we already got */
- short wrsent; /* Data akready sent */
+ short wrsent; /* Data already sent */
};
/* do some startup allocations not currently performed by usb_serial_probe() */
dbg("%s - usb_clear_halt", __FUNCTION__ );
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
- usb_clear_halt(port->serial->dev, port->read_urb->pipe);
- usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe);
/* force low_latency on so that our tty_push actually forces
* the data through, otherwise it is scheduled, and with high
unsigned long flags;
int result;
int wrexpected;
- unsigned char localbuf[CYBERJACK_LOCAL_BUF_SIZE]; /* Buffer for collecting data to write */
dbg("%s - port %d", __FUNCTION__, port->number);
dbg("%s - from_user %d", __FUNCTION__, from_user);
spin_lock_irqsave(&priv->lock, flags);
- if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ||
- (count>sizeof(localbuf)) ) {
- /* To much data for buffer. Reset buffer. */
+ if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
+ /* To much data for buffer. Reset buffer. */
priv->wrfilled=0;
spin_unlock_irqrestore(&priv->lock, flags);
return (0);
}
- spin_unlock_irqrestore(&priv->lock, flags);
-
/* Copy data */
if (from_user) {
- if (copy_from_user(localbuf, buf, count)) {
+ if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
+ spin_unlock_irqrestore(&priv->lock, flags);
return -EFAULT;
}
} else {
- memcpy (localbuf, buf, count);
+ memcpy (priv->wrbuf+priv->wrfilled, buf, count);
}
- spin_lock_irqsave(&priv->lock, flags);
-
- memcpy (priv->wrbuf+priv->wrfilled, localbuf, count);
-
usb_serial_debug_data (__FILE__, __FUNCTION__, count,
priv->wrbuf+priv->wrfilled);
priv->wrfilled += count;
}
-static int get_serial_info(struct usb_serial_port * port, struct serial_struct * retinfo)
+static int get_serial_info(struct usb_serial_port * port, struct serial_struct __user * retinfo)
{
struct ftdi_private *priv = usb_get_serial_port_data(port);
struct serial_struct tmp;
} /* get_serial_info */
-static int set_serial_info(struct usb_serial_port * port, struct serial_struct * newinfo)
+static int set_serial_info(struct usb_serial_port * port, struct serial_struct __user * newinfo)
{ /* set_serial_info */
struct ftdi_private *priv = usb_get_serial_port_data(port);
struct serial_struct new_serial;
if (status) {
err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
count = status;
+ kfree (buffer);
}
/* we are done with this urb, so let the host driver
case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
dbg("%s TIOCMBIS", __FUNCTION__);
- if (get_user(mask, (unsigned long *) arg))
+ if (get_user(mask, (unsigned long __user *) arg))
return -EFAULT;
if (mask & TIOCM_DTR){
if ((ret = set_dtr(port, HIGH)) < 0) {
case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
dbg("%s TIOCMBIC", __FUNCTION__);
- if (get_user(mask, (unsigned long *) arg))
+ if (get_user(mask, (unsigned long __user *) arg))
return -EFAULT;
if (mask & TIOCM_DTR){
if ((ret = set_dtr(port, LOW)) < 0){
*/
case TIOCGSERIAL: /* gets serial port data */
- return get_serial_info(port, (struct serial_struct *) arg);
+ return get_serial_info(port, (struct serial_struct __user *) arg);
case TIOCSSERIAL: /* sets serial port data */
- return set_serial_info(port, (struct serial_struct *) arg);
+ return set_serial_info(port, (struct serial_struct __user *) arg);
/*
* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
* transmit holding register is empty. This functionality
* allows an RS485 driver to be written in user space.
*****************************************************************************/
-static int get_lsr_info(struct edgeport_port *edge_port, unsigned int *value)
+static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *value)
{
unsigned int result = 0;
return 0;
}
-static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int *value)
+static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int __user *value)
{
unsigned int result = 0;
struct tty_struct *tty = edge_port->port->tty;
return result;
}
-static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct * retinfo)
+static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
// tmp.hub6 = state->hub6;
// tmp.io_type = state->io_type;
-
if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
return -EFAULT;
return 0;
// return number of bytes available
case TIOCINQ:
dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number);
- return get_number_bytes_avail(edge_port, (unsigned int *) arg);
+ return get_number_bytes_avail(edge_port, (unsigned int __user *) arg);
break;
case TIOCSERGETLSR:
dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
- return get_lsr_info(edge_port, (unsigned int *) arg);
+ return get_lsr_info(edge_port, (unsigned int __user *) arg);
return 0;
case TIOCGSERIAL:
dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number);
- return get_serial_info(edge_port, (struct serial_struct *) arg);
+ return get_serial_info(edge_port, (struct serial_struct __user *) arg);
case TIOCSSERIAL:
dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number);
icount.buf_overrun = cnow.buf_overrun;
dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__, port->number, icount.rx, icount.tx );
- if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+ if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
return -EFAULT;
return 0;
}
return result;
}
-static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct * retinfo)
+static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
case TIOCGSERIAL:
dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number);
- return get_serial_info(edge_port, (struct serial_struct *) arg);
+ return get_serial_info(edge_port, (struct serial_struct __user *) arg);
break;
case TIOCSSERIAL:
case TIOCGICOUNT:
dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__,
port->number, edge_port->icount.rx, edge_port->icount.tx);
- if (copy_to_user((void *)arg, &edge_port->icount, sizeof(edge_port->icount)))
+ if (copy_to_user((void __user *)arg, &edge_port->icount, sizeof(edge_port->icount)))
return -EFAULT;
return 0;
}
unsigned int cmd, unsigned long arg)
{
struct klsi_105_private *priv = usb_get_serial_port_data(port);
+ void __user *user_arg = (void __user *)arg;
dbg("%scmd=0x%x", __FUNCTION__, cmd);
dbg("%s - TCGETS data faked/incomplete", __FUNCTION__);
- retval = verify_area(VERIFY_WRITE, (void *)arg,
+ retval = verify_area(VERIFY_WRITE, user_arg,
sizeof(struct termios));
-
if (retval)
- return(retval);
+ return retval;
- if (kernel_termios_to_user_termios((struct termios *)arg,
+ if (kernel_termios_to_user_termios((struct termios __user *)arg,
&priv->termios))
return -EFAULT;
return(0);
dbg("%s - TCSETS not handled", __FUNCTION__);
- retval = verify_area(VERIFY_READ, (void *)arg,
+ retval = verify_area(VERIFY_READ, user_arg,
sizeof(struct termios));
-
if (retval)
- return(retval);
+ return retval;
if (user_termios_to_kernel_termios(&priv->termios,
- (struct termios *)arg))
+ (struct termios __user *)arg))
return -EFAULT;
klsi_105_set_termios(port, &priv->termios);
return(0);
unsigned char *transfer_buffer;
int transfer_buffer_length = 8;
char *settings;
+ void __user *user_arg = (void __user *)arg;
priv = usb_get_serial_port_data(port);
if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
switch (cmd) {
case TCGETS: // 0x5401
- result = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct termios));
+ result = verify_area(VERIFY_WRITE, user_arg, sizeof(struct termios));
if (result) {
dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);
return(result);
}
- if (kernel_termios_to_user_termios((struct termios *)arg,
+ if (kernel_termios_to_user_termios((struct termios __user *)arg,
&priv->internal_termios))
return -EFAULT;
return 0;
dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
return -ENOTTY;
}
- result = verify_area(VERIFY_READ, (void *)arg, sizeof(struct termios));
+ result = verify_area(VERIFY_READ, user_arg, sizeof(struct termios));
if (result) {
dbg("%s - port %d Error in verify_area", __FUNCTION__, port->number);
return result;
}
if (user_termios_to_kernel_termios(&priv->internal_termios,
- (struct termios *)arg))
+ (struct termios __user *)arg))
return -EFAULT;
settings = (unsigned char *) kmalloc(50, GFP_KERNEL);
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
+ { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID),
+ .driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ }, /* optional parameter entry */
{ } /* Terminating entry */
};
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) },
{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
+ { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
{ }, /* optional parameter entry */
{ } /* Terminating entry */
};
dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
__FUNCTION__, status);
count = status;
+ kfree (buffer);
} else {
bytes_out += count;
}
dev_err(dev, "%s - error %d getting connection info\n",
__FUNCTION__, retval);
else
- usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
+ usb_serial_debug_data (__FILE__, __FUNCTION__, retval, transfer_buffer);
kfree (transfer_buffer);
return 0;
/* Only do this endpoint hack for the Handspring devices with
* interrupt in endpoints, which for now are the Treo devices. */
- if ((serial->dev->descriptor.idVendor != HANDSPRING_VENDOR_ID) ||
+ if (!((serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) ||
+ (serial->dev->descriptor.idVendor == KYOCERA_VENDOR_ID)) ||
(serial->num_interrupt_in == 0))
return 0;
dbg("%s", __FUNCTION__);
/*
- * It appears that Treos want to use the 1st interrupt endpoint to
- * communicate with the 2nd bulk out endpoint, so let's swap the 1st
- * and 2nd bulk in and interrupt endpoints. Note that swapping the
- * bulk out endpoints would break lots of apps that want to communicate
- * on the second port.
+ * It appears that Treos and Kyoceras want to use the
+ * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
+ * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
+ * Note that swapping the bulk out endpoints would break lots of
+ * apps that want to communicate on the second port.
*/
#define COPY_PORT(dest, src) \
dest->read_urb = src->read_urb; \
#define ACEECA_VENDOR_ID 0x4766
#define ACEECA_MEZ1000_ID 0x0001
+#define KYOCERA_VENDOR_ID 0x0C88
+#define KYOCERA_7135_ID 0x0021
+
/****************************************************************************
* Handspring Visor Vendor specific request codes (bRequest values)
* A big thank you to Handspring for providing the following information.
static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
{
struct serial_struct serstruct;
+ void __user *user_arg = (void __user *)arg;
dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
serstruct.close_delay = CLOSING_DELAY;
serstruct.closing_wait = CLOSING_DELAY;
- if (copy_to_user((void *)arg, &serstruct, sizeof(serstruct)))
+ if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
return -EFAULT;
break;
case TIOCSSERIAL:
- if (copy_from_user(&serstruct, (void *)arg, sizeof(serstruct)))
+ if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
return -EFAULT;
/*
Say Y here in order to have the USB Mass Storage code generate
verbose debugging messages.
+config USB_STORAGE_RW_DETECT
+ bool "USB Mass Storage Write-Protected Media Detection (EXPERIMENTAL)"
+ depends on USB_STORAGE && EXPERIMENTAL
+ help
+ Say Y here in order to have the USB Mass Storage code indicate to
+ the SCSI layer that using MODE SENSE(6) and MODE SENSE(10) to
+ determine if the media is write-protected is a good thing to do.
+
+ Many devices have historically had trouble with these commands,
+ hence the default 2.6.x behavior has been to suppress their use.
+ 2.4.x used these commands with (at best) mixed results, often
+ crashing the firmware of the device. However, the SCSI layer now
+ issues these commands in a manner more consistent with other
+ "popular" OSes, in an attempt to improve compatibility.
+
+ Saying Y here allows these commands to be sent to a USB device.
+ If you find a device this doesn't work for, switch to N and let
+ us know at usb-storage@lists.one-eyed-alien.net
+
+ If you say N here, the kernel will assume that all disk-like USB
+ devices are write-enabled.
+
config USB_STORAGE_DATAFAB
bool "Datafab Compact Flash Reader support (EXPERIMENTAL)"
depends on USB_STORAGE && EXPERIMENTAL
// build the reply
//
- ((u32 *) ptr)[0] = cpu_to_be32(info->sectors);
+ ((u32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
((u32 *) ptr)[1] = cpu_to_be32(info->ssize);
usb_stor_set_xfer_buf(ptr, 8, srb);
#include "usb.h"
#include "debug.h"
#include "transport.h"
+#include "protocol.h"
#include <linux/slab.h>
#include <linux/module.h>
#include <scsi/scsi_devinfo.h>
#include <scsi/scsi_host.h>
-
/***********************************************************************
* Host functions
***********************************************************************/
{
/*
* Set default bflags. These can be overridden for individual
- * models and vendors via the scsi devinfo mechanism.
+ * models and vendors via the scsi devinfo mechanism. The only
+ * flag we need is to force 36-byte INQUIRYs; we don't use any
+ * of the extra data and many devices choke if asked for more or
+ * less than 36 bytes.
*/
- sdev->sdev_bflags = (BLIST_MS_SKIP_PAGE_08 | BLIST_MS_SKIP_PAGE_3F |
- BLIST_USE_10_BYTE_MS);
+ sdev->sdev_bflags = BLIST_INQUIRY_36;
+
return 0;
}
* reduce the maximum transfer size to 64 KB = 128 sectors. */
#define USB_VENDOR_ID_GENESYS 0x05e3 // Needs a standard location
+
if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS &&
- us->pusb_dev->speed == USB_SPEED_HIGH)
+ us->pusb_dev->speed == USB_SPEED_HIGH &&
+ sdev->request_queue->max_sectors > 128)
blk_queue_max_sectors(sdev->request_queue, 128);
- /* this is to satisify the compiler, tho I don't think the
+ /* We can't put these settings in slave_alloc() because that gets
+ * called before the device type is known. Consequently these
+ * settings can't be overridden via the scsi devinfo mechanism. */
+ if (sdev->type == TYPE_DISK) {
+
+ /* Disk-type devices use MODE SENSE(6) if the protocol
+ * (SubClass) is Transparent SCSI, otherwise they use
+ * MODE SENSE(10). */
+ if (us->subclass != US_SC_SCSI)
+ sdev->use_10_for_ms = 1;
+
+ /* Many disks only accept MODE SENSE transfer lengths of
+ * 192 bytes (that's what Windows uses). */
+ sdev->use_192_bytes_for_3f = 1;
+
+ /* A number of devices have problems with MODE SENSE for
+ * page x08, so we will skip it. */
+ sdev->skip_ms_page_8 = 1;
+
+#ifndef CONFIG_USB_STORAGE_RW_DETECT
+ /* Some devices may not like MODE SENSE with page=0x3f.
+ * Now that we're using 192-byte transfers this may no
+ * longer be a problem. So this will be a configuration
+ * option. */
+ sdev->skip_ms_page_3f = 1;
+#endif
+
+ } else {
+
+ /* Non-disk-type devices don't need to blacklist any pages
+ * or to force 192-byte transfer lengths for MODE SENSE.
+ * But they do need to use MODE SENSE(10). */
+ sdev->use_10_for_ms = 1;
+ }
+
+ /* this is to satisfy the compiler, tho I don't think the
* return code is ever checked anywhere. */
return 0;
}
/* emulated HBA */
.emulated = TRUE,
+ /* we do our own delay after a device or bus reset */
+ .skip_settle_delay = 1,
+
/* sysfs device attributes */
.sdev_attrs = sysfs_device_attr_list,
USB_RECIP_INTERFACE,
0, us->ifnum, us->iobuf, 1, HZ);
+ US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
+ result, us->iobuf[0]);
+
+ /* if we have a successful request, return the result */
+ if (result == 1)
+ return us->iobuf[0];
+
/*
* Some devices (i.e. Iomega Zip100) need this -- apparently
* the bulk pipes get STALLed when the GetMaxLUN request is
* processed. This is, in theory, harmless to all other devices
* (regardless of if they stall or not).
*/
- if (result < 0) {
+ if (result == -EPIPE) {
usb_stor_clear_halt(us, us->recv_bulk_pipe);
usb_stor_clear_halt(us, us->send_bulk_pipe);
+ /* return the default -- no LUNs */
+ return 0;
}
- US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
- result, us->iobuf[0]);
-
- /* if we have a successful request, return the result */
- if (result == 1)
- return us->iobuf[0];
-
- /* return the default -- no LUNs */
- return 0;
+ /* An answer or a STALL are the only valid responses. If we get
+ * something else, return an indication of error */
+ return -1;
}
int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
goto Done;
}
- /* long wait for reset, so unlock to allow disconnects */
- up(&us->dev_semaphore);
- msleep(6000);
- down(&us->dev_semaphore);
+ /* Give the device some time to recover from the reset,
+ * but don't delay disconnect processing. */
+ wait_event_interruptible_timeout(us->dev_reset_wait,
+ test_bit(US_FLIDX_DISCONNECTING, &us->flags),
+ HZ*6);
if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
US_DEBUGP("Reset interrupted by disconnect\n");
goto Done;
UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0205,
"Shuttle",
"eUSB MMC Adapter",
- US_SC_SCSI, US_PR_CB, NULL,
+ US_SC_SCSI, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN),
UNUSUAL_DEV( 0x04e6, 0x0007, 0x0100, 0x0200,
UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210,
"Fujifilm",
"Digital Camera EX-20 DSC",
- US_SC_8070, US_PR_CBI, NULL, 0 ),
+ US_SC_8070, US_PR_DEVICE, NULL, 0 ),
UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200,
"LaCie",
"USB Hard Disk",
US_SC_RBC, US_PR_CB, NULL, 0 ),
+/* Submitted by Jol Bourquard <numlock@freesurf.ch> */
+UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110,
+ "In-System",
+ "PyroGate External CD-ROM Enclosure (FCD-523)",
+ US_SC_SCSI, US_PR_BULK, NULL, 0 ),
+
#ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,
"In-System",
UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
"Lexar",
"Jumpshot USB CF Reader",
- US_SC_DEVICE, US_PR_JUMPSHOT, NULL,
- US_FL_MODE_XLATE ),
+ US_SC_SCSI, US_PR_JUMPSHOT, NULL,
+ US_FL_NEED_OVERRIDE | US_FL_MODE_XLATE ),
#endif
/* Reported by Blake Matheny <bmatheny@purdue.edu> */
* - Some cameras with idProduct=0x1001 and bcdDevice=0x1000 have
* bInterfaceProtocol=0x00 (US_PR_CBI) while others have 0x01 (US_PR_CB).
* So don't remove the US_PR_CB override!
+ * - Cameras with bcdDevice=0x9009 require the US_SC_8070 override.
*/
-UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
+UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999,
"Casio",
"QV DigitalCamera",
- US_SC_DEVICE, US_PR_CB, NULL,
+ US_SC_8070, US_PR_CB, NULL,
US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ),
-/* Later Casio cameras apparently tell the truth */
-UNUSUAL_DEV( 0x07cf, 0x1001, 0x9010, 0x9999,
- "Casio",
- "QV DigitalCamera",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
-
/* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/
UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
"Samsung",
static int usb_stor_control_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
+ struct Scsi_Host *host = us->host;
lock_kernel();
complete(&(us->notify));
for(;;) {
- struct Scsi_Host *host;
US_DEBUGP("*** thread sleeping.\n");
if(down_interruptible(&us->sema))
break;
US_DEBUGP("*** thread awakened.\n");
+ /* lock the device pointers */
+ down(&(us->dev_semaphore));
+
/* if us->srb is NULL, we are being asked to exit */
if (us->srb == NULL) {
US_DEBUGP("-- exit command received\n");
+ up(&(us->dev_semaphore));
break;
}
- host = us->srb->device->host;
/* lock access to the state */
scsi_lock(host);
goto SkipForAbort;
}
- /* set the state and release the lock */
- us->sm_state = US_STATE_RUNNING;
- scsi_unlock(host);
-
- /* lock the device pointers */
- down(&(us->dev_semaphore));
-
/* don't do anything if we are disconnecting */
if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
US_DEBUGP("No command during disconnect\n");
- us->srb->result = DID_BAD_TARGET << 16;
+ goto SkipForDisconnect;
}
+ /* set the state and release the lock */
+ us->sm_state = US_STATE_RUNNING;
+ scsi_unlock(host);
+
/* reject the command if the direction indicator
* is UNKNOWN
*/
- else if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) {
+ if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) {
US_DEBUGP("UNKNOWN data direction\n");
us->srb->result = DID_ERROR << 16;
}
us->proto_handler(us->srb, us);
}
- /* unlock the device pointers */
- up(&(us->dev_semaphore));
-
/* lock access to the state */
scsi_lock(host);
us->srb->result);
us->srb->scsi_done(us->srb);
} else {
- SkipForAbort:
+SkipForAbort:
US_DEBUGP("scsi command aborted\n");
}
complete(&(us->notify));
/* empty the queue, reset the state, and release the lock */
+SkipForDisconnect:
us->srb = NULL;
us->sm_state = US_STATE_IDLE;
scsi_unlock(host);
+
+ /* unlock the device pointers */
+ up(&(us->dev_semaphore));
} /* for (;;) */
/* notify the exit routine that we're actually exiting now
us->pusb_intf = intf;
us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
- /* Store our private data in the interface and increment the
- * device's reference count */
+ /* Store our private data in the interface */
usb_set_intfdata(intf, us);
- usb_get_dev(us->pusb_dev);
/* Allocate the device-related DMA-mapped buffers */
us->cr = usb_buffer_alloc(us->pusb_dev, sizeof(*us->cr),
down(&us->dev_semaphore);
/* For bulk-only devices, determine the max LUN value */
- if (us->protocol == US_PR_BULK)
- us->max_lun = usb_stor_Bulk_max_lun(us);
+ if (us->protocol == US_PR_BULK) {
+ p = usb_stor_Bulk_max_lun(us);
+ if (p < 0) {
+ up(&us->dev_semaphore);
+ return p;
+ }
+ us->max_lun = p;
+ }
/* Just before we start our control thread, initialize
* the device if it needs initialization */
up(&us->dev_semaphore);
- /* Start up our control thread */
- us->sm_state = US_STATE_IDLE;
- p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
- if (p < 0) {
- printk(KERN_WARNING USB_STORAGE
- "Unable to start control thread\n");
- return p;
- }
- us->pid = p;
-
- /* Wait for the thread to start */
- wait_for_completion(&(us->notify));
-
/*
* Since this is a new device, we need to register a SCSI
* host definition with the higher SCSI layers.
us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us));
if (!us->host) {
printk(KERN_WARNING USB_STORAGE
- "Unable to register the scsi host\n");
+ "Unable to allocate the scsi host\n");
return -EBUSY;
}
/* Set the hostdata to prepare for scanning */
us->host->hostdata[0] = (unsigned long) us;
- return 0;
-}
-
-/* Dissociate from the USB device */
-static void dissociate_dev(struct us_data *us)
-{
- US_DEBUGP("-- %s\n", __FUNCTION__);
- down(&us->dev_semaphore);
-
- /* Free the device-related DMA-mapped buffers */
- if (us->cr) {
- usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
- us->cr_dma);
- us->cr = NULL;
- }
- if (us->iobuf) {
- usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
- us->iobuf_dma);
- us->iobuf = NULL;
+ /* Start up our control thread */
+ us->sm_state = US_STATE_IDLE;
+ p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
+ if (p < 0) {
+ printk(KERN_WARNING USB_STORAGE
+ "Unable to start control thread\n");
+ return p;
}
+ us->pid = p;
- /* Remove our private data from the interface and decrement the
- * device's reference count */
- usb_set_intfdata(us->pusb_intf, NULL);
- usb_put_dev(us->pusb_dev);
+ /* Wait for the thread to start */
+ wait_for_completion(&(us->notify));
- us->pusb_dev = NULL;
- us->pusb_intf = NULL;
- up(&us->dev_semaphore);
+ return 0;
}
-/* Release all our static and dynamic resources */
+/* Release all our dynamic resources */
void usb_stor_release_resources(struct us_data *us)
{
- /*
- * The host must already have been removed
- * and dissociate_dev() must have been called.
- */
-
- /* Finish the SCSI host removal sequence */
- if (us->host) {
- us->host->hostdata[0] = 0;
- scsi_host_put(us->host);
- }
+ US_DEBUGP("-- %s\n", __FUNCTION__);
- /* Kill the control thread
- *
- * Enqueue the command, wake up the thread, and wait for
- * notification that it has exited.
+ /* Kill the control thread. The SCSI host must already have been
+ * removed so it won't try to queue any more commands.
*/
if (us->pid) {
+
+ /* Wait for the thread to be idle */
+ down(&us->dev_semaphore);
US_DEBUGP("-- sending exit command to thread\n");
BUG_ON(us->sm_state != US_STATE_IDLE);
+
+ /* If the SCSI midlayer queued a final command just before
+ * scsi_remove_host() was called, us->srb might not be
+ * NULL. We can overwrite it safely, because the midlayer
+ * will not wait for the command to finish. Also the
+ * control thread will already have been awakened.
+ * That's okay, an extra up() on us->sema won't hurt.
+ *
+ * Enqueue the command, wake up the thread, and wait for
+ * notification that it has exited.
+ */
+ scsi_lock(us->host);
us->srb = NULL;
- up(&(us->sema));
- wait_for_completion(&(us->notify));
+ scsi_unlock(us->host);
+ up(&us->dev_semaphore);
+
+ up(&us->sema);
+ wait_for_completion(&us->notify);
}
/* Call the destructor routine, if it exists */
us->extra_destructor(us->extra);
}
+ /* Finish the host removal sequence */
+ if (us->host)
+ scsi_host_put(us->host);
+
/* Free the extra data and the URB */
if (us->extra)
kfree(us->extra);
if (us->current_urb)
usb_free_urb(us->current_urb);
+}
+
+/* Dissociate from the USB device */
+static void dissociate_dev(struct us_data *us)
+{
+ US_DEBUGP("-- %s\n", __FUNCTION__);
+
+ /* Free the device-related DMA-mapped buffers */
+ if (us->cr)
+ usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
+ us->cr_dma);
+ if (us->iobuf)
+ usb_buffer_free(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
+ us->iobuf_dma);
+
+ /* Remove our private data from the interface */
+ usb_set_intfdata(us->pusb_intf, NULL);
+
/* Free the structure itself */
kfree(us);
- US_DEBUGP("-- %s finished\n", __FUNCTION__);
}
/* Probe to see if we can drive a newly-connected USB device */
init_MUTEX(&(us->dev_semaphore));
init_MUTEX_LOCKED(&(us->sema));
init_completion(&(us->notify));
+ init_waitqueue_head(&us->dev_reset_wait);
/* Associate the us_data structure with the USB device */
result = associate_dev(us, intf);
/* We come here if there are any problems */
BadDevice:
US_DEBUGP("storage_probe() failed\n");
- dissociate_dev(us);
usb_stor_release_resources(us);
+ dissociate_dev(us);
return result;
}
US_DEBUGP("storage_disconnect() called\n");
- /* Prevent new USB transfers and stop the current command */
+ /* Prevent new USB transfers, stop the current command, and
+ * interrupt a device-reset delay */
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
usb_stor_stop_transport(us);
+ wake_up(&us->dev_reset_wait);
- /* Dissociate from the USB device */
- dissociate_dev(us);
-
+ /* Wait for the current command to finish, then remove the host */
+ down(&us->dev_semaphore);
+ up(&us->dev_semaphore);
scsi_remove_host(us->host);
- /* TODO: somehow, wait for the device to
- * be 'idle' (tasklet completion) */
-
- /* Release all our other resources */
+ /* Wait for everything to become idle and release all our resources */
usb_stor_release_resources(us);
+ dissociate_dev(us);
}
/***********************************************************************
*/
US_DEBUGP("-- calling usb_deregister()\n");
usb_deregister(&usb_storage_driver) ;
-
-#if 0
- /* While there are still virtual hosts, unregister them
- * Note that it's important to do this completely before removing
- * the structures because of possible races with the /proc
- * interface
- */
- for (next = us_list; next; next = next->next) {
- US_DEBUGP("-- calling scsi_unregister_host()\n");
- scsi_unregister_host(&usb_stor_host_template);
- }
-
- /* While there are still structures, free them. Note that we are
- * now race-free, since these structures can no longer be accessed
- * from either the SCSI command layer or the /proc interface
- */
- while (us_list) {
- /* keep track of where the next one is */
- next = us_list->next;
-
- /* If there's extra data in the us_data structure then
- * free that first */
- if (us_list->extra) {
- /* call the destructor routine, if it exists */
- if (us_list->extra_destructor) {
- US_DEBUGP("-- calling extra_destructor()\n");
- us_list->extra_destructor(us_list->extra);
- }
-
- /* destroy the extra data */
- US_DEBUGP("-- freeing the data structure\n");
- kfree(us_list->extra);
- }
-
- /* free the structure itself */
- kfree (us_list);
-
- /* advance the list pointer */
- us_list = next;
- }
-#endif
}
module_init(usb_stor_init);
dma_addr_t cr_dma; /* buffer DMA addresses */
dma_addr_t iobuf_dma;
- /* mutual exclusion structures */
+ /* mutual exclusion and synchronization structures */
struct semaphore sema; /* to sleep thread on */
- struct completion notify; /* thread begin/end */
+ struct completion notify; /* thread begin/end */
+ wait_queue_head_t dev_reset_wait; /* wait during reset */
/* subdriver information */
void *extra; /* Any extra data */
To compile this driver as a module, choose M here: the
module will be called rivafb.
+config FB_RIVA_I2C
+ bool "Enable DDC Support"
+ depends on FB_RIVA && I2C
+ help
+
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
depends on FB && AGP && AGP_INTEL && EXPERIMENTAL && PCI
return;
}
- vxres = info->var.xres;
- vyres = info->var.yres;
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
memcpy(&modded, region, sizeof(struct fb_fillrect));
return;
}
- vxres = info->var.xres;
- vyres = info->var.yres;
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
if(!modded.width || !modded.height ||
modded.sx >= vxres || modded.sy >= vyres ||
if (rinfo->asleep)
return 0;
+ radeon_fifo_wait(2);
OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
* var->bits_per_pixel / 8) & ~7);
return 0;
if (!rinfo->is_mobility)
return -EINVAL;
- rc = get_user(value, (__u32*)arg);
+ rc = get_user(value, (__u32 __user *)arg);
if (rc)
return rc;
+ radeon_fifo_wait(2);
if (value & 0x01) {
tmp = INREG(LVDS_GEN_CNTL);
if (CRTC_CRT_ON & tmp)
value |= 0x02;
- return put_user(value, (__u32*)arg);
+ return put_user(value, (__u32 __user *)arg);
default:
return -EINVAL;
}
break;
}
+ radeon_fifo_wait(1);
switch (rinfo->mon1_type) {
case MT_LCD:
OUTREG(LVDS_GEN_CNTL, val2);
if (!rinfo->asleep) {
u32 dac_cntl2, vclk_cntl = 0;
+ radeon_fifo_wait(9);
if (rinfo->is_mobility) {
vclk_cntl = INPLL(VCLK_ECP_CNTL);
OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
{
int i;
+ radeon_fifo_wait(20);
+
/* Workaround from XFree */
if (rinfo->is_mobility) {
/* A temporal workaround for the occational blanking on certain laptop panels.
{
struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
+ radeon_fifo_wait(3);
+
OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
if (rinfo->pending_pixclks_cntl) {
OUTPLL(PIXCLKS_CNTL, rinfo->pending_pixclks_cntl);
radeon_screen_blank(rinfo, VESA_POWERDOWN);
+ radeon_fifo_wait(31);
for (i=0; i<10; i++)
OUTREG(common_regs[i].reg, common_regs[i].val);
radeon_write_pll_regs(rinfo, mode);
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+ radeon_fifo_wait(10);
OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
radeon_screen_blank(rinfo, VESA_NO_BLANKING);
+ radeon_fifo_wait(2);
OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
return;
-static ssize_t radeonfb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+static ssize_t radeonfb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_dentry->d_inode;
return count;
}
-static ssize_t radeonfb_write(struct file *file, const char *buf, size_t count,
+static ssize_t radeonfb_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos)
{
unsigned long p = *ppos;
del_timer_sync(&rinfo->lvds_timer);
lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
+ radeon_fifo_wait(3);
if (on && (level > BACKLIGHT_OFF)) {
lvds_gen_cntl |= LVDS_DIGON;
if (!(lvds_gen_cntl & LVDS_ON)) {
u32 tom = INREG(NB_TOM);
tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
+ radeon_fifo_wait(6);
OUTREG(MC_FB_LOCATION, tom);
OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
int display_fg = (*default_mode)->vc_num;
int logo = 1, rows, cols, charcnt = 256;
unsigned short *save = NULL, *r, *q;
+ int cap = info->flags;
- if (vc->vc_num != display_fg || (info->flags & FBINFO_FLAG_MODULE) ||
+ if (vc->vc_num != display_fg || (info->flags & FBINFO_MODULE) ||
(info->fix.type == FB_TYPE_TEXT))
logo = 0;
rows = info->var.yres / vc->vc_font.height;
vc_resize(vc->vc_num, cols, rows);
- if (info->var.accel_flags)
- p->scrollmode = SCROLL_YNOMOVE;
- else
- p->scrollmode = SCROLL_YREDRAW;
+ if ((cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED))
+ p->scrollmode = SCROLL_ACCEL;
+ else /* default to something safe */
+ p->scrollmode = SCROLL_REDRAW;
/*
* ++guenther: console.c:vc_allocate() relies on initializing
{
struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
struct display *p = &fb_display[vc->vc_num];
- int scroll_partial = !(p->scrollmode & __SCROLL_YNOPARTIAL);
+ int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
if (!info->fbops->fb_blank && console_blanked)
return 0;
fbcon_softback_note(vc, t, count);
if (logo_shown >= 0)
goto redraw_up;
- switch (p->scrollmode & __SCROLL_YMASK) {
- case __SCROLL_YMOVE:
+ switch (p->scrollmode) {
+ case SCROLL_ACCEL:
accel_bmove(vc, info, t + count, 0, t, 0,
b - t - count, vc->vc_cols);
accel_clear(vc, info, b - count, 0, count,
vc->vc_cols);
break;
- case __SCROLL_YWRAP:
+ case SCROLL_WRAP:
if (b - t - count > 3 * vc->vc_rows >> 2) {
if (t > 0)
fbcon_bmove(vc, 0, 0, count, 0, t,
fbcon_bmove(vc, b - count, 0, b, 0,
vc->vc_rows - b,
vc->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_up;
- else
+ } else if (info->flags & FBINFO_READS_FAST)
fbcon_bmove(vc, t + count, 0, t, 0,
b - t - count, vc->vc_cols);
+ else
+ goto redraw_up;
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
break;
- case __SCROLL_YPAN:
+ case SCROLL_PAN:
if ((p->yscroll + count <=
2 * (p->vrows - vc->vc_rows))
&& ((!scroll_partial && (b - t == vc->vc_rows))
fbcon_bmove(vc, b - count, 0, b, 0,
vc->vc_rows - b,
vc->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_up;
- else
+ } else if (info->flags & FBINFO_READS_FAST)
fbcon_bmove(vc, t + count, 0, t, 0,
b - t - count, vc->vc_cols);
+ else
+ goto redraw_up;
fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
break;
- case __SCROLL_YREDRAW:
+ case SCROLL_REDRAW:
redraw_up:
fbcon_redraw(vc, p, t, b - t - count,
count * vc->vc_cols);
case SM_DOWN:
if (count > vc->vc_rows) /* Maximum realistic size */
count = vc->vc_rows;
- switch (p->scrollmode & __SCROLL_YMASK) {
- case __SCROLL_YMOVE:
+ switch (p->scrollmode) {
+ case SCROLL_ACCEL:
accel_bmove(vc, info, t, 0, t + count, 0,
b - t - count, vc->vc_cols);
accel_clear(vc, info, t, 0, count, vc->vc_cols);
break;
- case __SCROLL_YWRAP:
+ case SCROLL_WRAP:
if (b - t - count > 3 * vc->vc_rows >> 2) {
if (vc->vc_rows - b > 0)
fbcon_bmove(vc, b, 0, b - count, 0,
if (t > 0)
fbcon_bmove(vc, count, 0, 0, 0, t,
vc->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_down;
- else
+ } else if (info->flags & FBINFO_READS_FAST)
fbcon_bmove(vc, t, 0, t + count, 0,
b - t - count, vc->vc_cols);
+ else
+ goto redraw_down;
fbcon_clear(vc, t, 0, count, vc->vc_cols);
break;
- case __SCROLL_YPAN:
+ case SCROLL_PAN:
if ((count - p->yscroll <= p->vrows - vc->vc_rows)
&& ((!scroll_partial && (b - t == vc->vc_rows))
|| (scroll_partial
if (t > 0)
fbcon_bmove(vc, count, 0, 0, 0, t,
vc->vc_cols);
- } else if (p->scrollmode & __SCROLL_YPANREDRAW)
- goto redraw_down;
- else
+ } else if (info->flags & FBINFO_READS_FAST)
fbcon_bmove(vc, t, 0, t + count, 0,
b - t - count, vc->vc_cols);
+ else
+ goto redraw_down;
fbcon_clear(vc, t, 0, count, vc->vc_cols);
break;
- case __SCROLL_YREDRAW:
+ case SCROLL_REDRAW:
redraw_down:
fbcon_redraw(vc, p, b - 1, b - t - count,
-count * vc->vc_cols);
static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, struct vc_data *vc)
{
- int m;
-
- if (p->scrollmode & __SCROLL_YFIXED)
- return;
- if (divides(info->fix.ywrapstep, vc->vc_font.height) &&
- divides(vc->vc_font.height, info->var.yres_virtual))
- m = __SCROLL_YWRAP;
- else if (divides(info->fix.ypanstep, vc->vc_font.height) &&
- info->var.yres_virtual >= info->var.yres + vc->vc_font.height)
- m = __SCROLL_YPAN;
- else if (p->scrollmode & __SCROLL_YNOMOVE)
- m = __SCROLL_YREDRAW;
- else
- m = __SCROLL_YMOVE;
- p->scrollmode = (p->scrollmode & ~__SCROLL_YMASK) | m;
+ int cap = info->flags;
+ int good_pan = (cap & FBINFO_HWACCEL_YPAN)
+ && divides(info->fix.ypanstep, vc->vc_font.height)
+ && info->var.yres_virtual >= 2*info->var.yres;
+ int good_wrap = (cap & FBINFO_HWACCEL_YWRAP)
+ && divides(info->fix.ywrapstep, vc->vc_font.height)
+ && divides(vc->vc_font.height, info->var.yres_virtual);
+ int reading_fast = cap & FBINFO_READS_FAST;
+ int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED);
+
+ if (good_wrap || good_pan) {
+ if (reading_fast || fast_copyarea)
+ p->scrollmode = good_wrap ? SCROLL_WRAP : SCROLL_PAN;
+ else
+ p->scrollmode = SCROLL_REDRAW;
+ } else {
+ if (reading_fast || fast_copyarea)
+ p->scrollmode = SCROLL_ACCEL;
+ else
+ p->scrollmode = SCROLL_REDRAW;
+ }
}
static int fbcon_resize(struct vc_data *vc, unsigned int width,
if (!info->fbops->fb_set_par)
return -EINVAL;
- sprintf(mode, "%dx%d", var.xres, var.yres);
- err = fb_find_mode(&var, info, mode, NULL, 0, NULL,
- info->var.bits_per_pixel);
+ snprintf(mode, 40, "%ix%i", var.xres, var.yres);
+ err = fb_find_mode(&var, info, mode, info->monspecs.modedb,
+ info->monspecs.modedb_len, NULL,
+ info->var.bits_per_pixel);
if (!err || width > var.xres/fw || height > var.yres/fh)
return -EINVAL;
DPRINTK("resize now %ix%i\n", var.xres, var.yres);
}
if (info)
info->var.yoffset = p->yscroll = 0;
- fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
- switch (p->scrollmode & __SCROLL_YMASK) {
- case __SCROLL_YWRAP:
+ fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
+ switch (p->scrollmode) {
+ case SCROLL_WRAP:
scrollback_phys_max = p->vrows - vc->vc_rows;
break;
- case __SCROLL_YPAN:
+ case SCROLL_PAN:
scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
if (scrollback_phys_max < 0)
scrollback_phys_max = 0;
offset = p->yscroll - scrollback_current;
limit = p->vrows;
- switch (p->scrollmode && __SCROLL_YMASK) {
- case __SCROLL_YWRAP:
+ switch (p->scrollmode) {
+ case SCROLL_WRAP:
info->var.vmode |= FB_VMODE_YWRAP;
break;
- case __SCROLL_YPAN:
+ case SCROLL_PAN:
limit -= vc->vc_rows;
info->var.vmode &= ~FB_VMODE_YWRAP;
break;
* Scroll Method
*/
-/* Internal flags */
-#define __SCROLL_YPAN 0x001
-#define __SCROLL_YWRAP 0x002
-#define __SCROLL_YMOVE 0x003
-#define __SCROLL_YREDRAW 0x004
-#define __SCROLL_YMASK 0x00f
-#define __SCROLL_YFIXED 0x010
-#define __SCROLL_YNOMOVE 0x020
-#define __SCROLL_YPANREDRAW 0x040
-#define __SCROLL_YNOPARTIAL 0x080
-
-/* Only these should be used by the drivers */
-/* Which one should you use? If you have a fast card and slow bus,
- then probably just 0 to indicate fbcon should choose between
- YWRAP/YPAN+MOVE/YMOVE. On the other side, if you have a fast bus
- and even better if your card can do fonting (1->8/32bit painting),
- you should consider either SCROLL_YREDRAW (if your card is
- able to do neither YPAN/YWRAP), or SCROLL_YNOMOVE.
- The best is to test it with some real life scrolling (usually, not
- all lines on the screen are filled completely with non-space characters,
- and REDRAW performs much better on such lines, so don't cat a file
- with every line covering all screen columns, it would not be the right
- benchmark).
+/* There are several methods fbcon can use to move text around the screen:
+ *
+ * + use the hardware engine to move the text
+ * (hw-accelerated copyarea() and fillrect())
+ * + use hardware-supported panning on a large virtual screen
+ * + amifb can not only pan, but also wrap the display by N lines
+ * (i.e. visible line i = physical line (i+N) % yres).
+ * + read what's already rendered on the screen and
+ * write it in a different place (this is cfb_copyarea())
+ * + re-render the text to the screen
+ *
+ * Whether to use wrapping or panning can only be figured out at
+ * runtime (when we know whether our font height is a multiple
+ * of the pan/wrap step)
+ *
*/
-#define SCROLL_YREDRAW (__SCROLL_YFIXED|__SCROLL_YREDRAW)
-#define SCROLL_YNOMOVE (__SCROLL_YNOMOVE|__SCROLL_YPANREDRAW)
-/* SCROLL_YNOPARTIAL, used in combination with the above, is for video
- cards which can not handle using panning to scroll a portion of the
- screen without excessive flicker. Panning will only be used for
- whole screens.
- */
-/* Namespace consistency */
-#define SCROLL_YNOPARTIAL __SCROLL_YNOPARTIAL
+#define SCROLL_ACCEL 0x001
+#define SCROLL_PAN 0x002
+#define SCROLL_WRAP 0x003
+#define SCROLL_REDRAW 0x004
extern int fb_console_init(void);
#include <linux/pci.h>
#include <linux/font.h>
-#include <asm/pgalloc.h>
#include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/cacheflush.h>
p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
lines * c->vc_size_row;
st = (c->vc_origin - vga_vram_base - ul + we) % we;
+ if (st < 2 * margin)
+ margin = 0;
if (p < margin)
p = 0;
if (p > st - margin)
extern int kyrofb_setup(char*);
extern int mc68x328fb_init(void);
extern int mc68x328fb_setup(char *);
+extern int asiliantfb_init(void);
static struct {
const char *name;
#ifdef CONFIG_FB_68328
{ "68328fb", mc68x328fb_init, mc68x328fb_setup },
#endif
+#ifdef CONFIG_FB_ASILIANT
+ { "asiliantfb", asiliantfb_init, NULL },
+#endif
/*
* Generic drivers that don't use resource management (yet)
}
static ssize_t
-fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_dentry->d_inode;
}
static ssize_t
-fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
struct inode *inode = file->f_dentry->d_inode;
if (cursor.set & FB_CUR_SETSHAPE) {
int size = ((cursor.image.width + 7) >> 3) * cursor.image.height;
+ char *data, *mask;
+
if ((cursor.image.height != info->cursor.image.height) ||
(cursor.image.width != info->cursor.image.width))
cursor.set |= FB_CUR_SETSIZE;
- cursor.image.data = kmalloc(size, GFP_KERNEL);
- if (!cursor.image.data)
+ data = kmalloc(size, GFP_KERNEL);
+ if (!data)
return -ENOMEM;
- cursor.mask = kmalloc(size, GFP_KERNEL);
- if (!cursor.mask) {
- kfree(cursor.image.data);
+ mask = kmalloc(size, GFP_KERNEL);
+ if (!mask) {
+ kfree(data);
return -ENOMEM;
}
- if (copy_from_user(cursor.image.data, sprite->image.data, size) ||
- copy_from_user(cursor.mask, sprite->mask, size)) {
- kfree(cursor.image.data);
- kfree(cursor.mask);
+ if (copy_from_user(data, sprite->image.data, size) ||
+ copy_from_user(mask, sprite->mask, size)) {
+ kfree(data);
+ kfree(mask);
return -EFAULT;
}
+ cursor.image.data = data;
+ cursor.mask = mask;
}
info->cursor.set = cursor.set;
info->cursor.rop = cursor.rop;
u_long arg, struct fb_info *info)
{
struct imstt_par *par = (struct imstt_par *) info->par;
+ void __user *argp = (void __user *)arg;
__u32 reg[2];
__u8 idx[2];
switch (cmd) {
case FBIMSTT_SETREG:
- if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+ if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
write_reg_le32(par->dc_regs, reg[0], reg[1]);
return 0;
case FBIMSTT_GETREG:
- if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+ if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
reg[1] = read_reg_le32(par->dc_regs, reg[0]);
- if (copy_to_user((void *)(arg + 4), ®[1], 4))
+ if (copy_to_user((void __user *)(arg + 4), ®[1], 4))
return -EFAULT;
return 0;
case FBIMSTT_SETCMAPREG:
- if (copy_from_user(reg, (void *)arg, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+ if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
write_reg_le32(((u_int *)par->cmap_regs), reg[0], reg[1]);
return 0;
case FBIMSTT_GETCMAPREG:
- if (copy_from_user(reg, (void *)arg, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
+ if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
return -EFAULT;
reg[1] = read_reg_le32(((u_int *)par->cmap_regs), reg[0]);
- if (copy_to_user((void *)(arg + 4), ®[1], 4))
+ if (copy_to_user((void __user *)(arg + 4), ®[1], 4))
return -EFAULT;
return 0;
case FBIMSTT_SETIDXREG:
- if (copy_from_user(idx, (void *)arg, 2))
+ if (copy_from_user(idx, argp, 2))
return -EFAULT;
par->cmap_regs[PIDXHI] = 0; eieio();
par->cmap_regs[PIDXLO] = idx[0]; eieio();
par->cmap_regs[PIDXDATA] = idx[1]; eieio();
return 0;
case FBIMSTT_GETIDXREG:
- if (copy_from_user(idx, (void *)arg, 1))
+ if (copy_from_user(idx, argp, 1))
return -EFAULT;
par->cmap_regs[PIDXHI] = 0; eieio();
par->cmap_regs[PIDXLO] = idx[0]; eieio();
idx[1] = par->cmap_regs[PIDXDATA];
- if (copy_to_user((void *)(arg + 1), &idx[1], 1))
+ if (copy_to_user((void __user *)(arg + 1), &idx[1], 1))
return -EFAULT;
return 0;
default:
{
overlay_create ol_create;
overlay_viewport_set ol_viewport_set;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case KYRO_IOCTL_OVERLAY_CREATE:
- copy_from_user((void *) &ol_create, (void *) arg,
- sizeof(overlay_create));
+ copy_from_user(&ol_create, argp, sizeof(overlay_create));
if (kyro_dev_overlay_create(ol_create.ulWidth,
ol_create.ulHeight, 0) < 0) {
}
break;
case KYRO_IOCTL_OVERLAY_VIEWPORT_SET:
- copy_from_user((void *) &ol_viewport_set, (void *) arg,
+ copy_from_user(&ol_viewport_set, argp,
sizeof(overlay_viewport_set));
if (kyro_dev_overlay_viewport_set(ol_viewport_set.xOrgin,
}
break;
case KYRO_IOCTL_UVSTRIDE:
- copy_to_user((void *)arg, (void *)&deviceInfo.ulOverlayUVStride, sizeof(unsigned long));
+ copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long));
break;
case KYRO_IOCTL_STRIDE:
- copy_to_user((void *)arg, (void *)&deviceInfo.ulOverlayStride, sizeof(unsigned long));
+ copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long));
break;
case KYRO_IOCTL_OVERLAY_OFFSET:
- copy_to_user((void *)arg, (void *)&deviceInfo.ulOverlayOffset, sizeof(unsigned long));
+ copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long));
break;
}
unsigned int cmd, unsigned long arg,
struct fb_info *info)
{
+ void __user *argp = (void __user *)arg;
MINFO_FROM_INFO(info);
DBG(__FUNCTION__)
err = matroxfb_get_vblank(PMINFO &vblank);
if (err)
return err;
- if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))
+ if (copy_to_user(argp, &vblank, sizeof(vblank)))
return -EFAULT;
return 0;
}
{
u_int32_t crt;
- if (get_user(crt, (u_int32_t *)arg))
+ if (get_user(crt, (u_int32_t __user *)arg))
return -EFAULT;
return matroxfb_wait_for_sync(PMINFO crt);
struct matrox_altout *oproc;
int val;
- if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))
+ if (copy_from_user(&mom, argp, sizeof(mom)))
return -EFAULT;
if (mom.output >= MATROXFB_MAX_OUTPUTS)
return -ENXIO;
struct matrox_altout *oproc;
int val;
- if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))
+ if (copy_from_user(&mom, argp, sizeof(mom)))
return -EFAULT;
if (mom.output >= MATROXFB_MAX_OUTPUTS)
return -ENXIO;
up_read(&ACCESS_FBINFO(altout.lock));
if (val)
return val;
- if (copy_to_user((struct matroxioc_output_mode*)arg, &mom, sizeof(mom)))
+ if (copy_to_user(argp, &mom, sizeof(mom)))
return -EFAULT;
return 0;
}
int i;
int changes;
- if (copy_from_user(&tmp, (u_int32_t*)arg, sizeof(tmp)))
+ if (copy_from_user(&tmp, argp, sizeof(tmp)))
return -EFAULT;
for (i = 0; i < 32; i++) {
if (tmp & (1 << i)) {
conn |= 1 << i;
}
}
- if (put_user(conn, (u_int32_t*)arg))
+ if (put_user(conn, (u_int32_t __user *)arg))
return -EFAULT;
return 0;
}
if (conn & MATROXFB_OUTPUT_CONN_SECONDARY)
conn &= ~MATROXFB_OUTPUT_CONN_DFP;
}
- if (put_user(conn, (u_int32_t*)arg))
+ if (put_user(conn, (u_int32_t __user *)arg))
return -EFAULT;
return 0;
}
conn |= 1 << i;
}
}
- if (put_user(conn, (u_int32_t*)arg))
+ if (put_user(conn, (u_int32_t __user *)arg))
return -EFAULT;
return 0;
}
sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev)));
r.version = KERNEL_VERSION(1,0,0);
r.capabilities = V4L2_CAP_VIDEO_OUTPUT;
- if (copy_to_user((void*)arg, &r, sizeof(r)))
+ if (copy_to_user(argp, &r, sizeof(r)))
return -EFAULT;
return 0;
struct v4l2_queryctrl qctrl;
int err;
- if (copy_from_user(&qctrl, (struct v4l2_queryctrl*)arg, sizeof(qctrl)))
+ if (copy_from_user(&qctrl, argp, sizeof(qctrl)))
return -EFAULT;
down_read(&ACCESS_FBINFO(altout).lock);
}
up_read(&ACCESS_FBINFO(altout).lock);
if (err >= 0 &&
- copy_to_user((struct v4l2_queryctrl*)arg, &qctrl, sizeof(qctrl)))
+ copy_to_user(argp, &qctrl, sizeof(qctrl)))
return -EFAULT;
return err;
}
struct v4l2_control ctrl;
int err;
- if (copy_from_user(&ctrl, (struct v4l2_control*)arg, sizeof(ctrl)))
+ if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
return -EFAULT;
down_read(&ACCESS_FBINFO(altout).lock);
}
up_read(&ACCESS_FBINFO(altout).lock);
if (err >= 0 &&
- copy_to_user((struct v4l2_control*)arg, &ctrl, sizeof(ctrl)))
+ copy_to_user(argp, &ctrl, sizeof(ctrl)))
return -EFAULT;
return err;
}
struct v4l2_control ctrl;
int err;
- if (copy_from_user(&ctrl, (struct v4l2_control*)arg, sizeof(ctrl)))
+ if (copy_from_user(&ctrl, argp, sizeof(ctrl)))
return -EFAULT;
down_read(&ACCESS_FBINFO(altout).lock);
err = matroxfb_dh_get_vblank(m2info, &vblank);
if (err)
return err;
- if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))
+ if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
return -EFAULT;
return 0;
}
{
u_int32_t crt;
- if (get_user(crt, (u_int32_t *)arg))
+ if (get_user(crt, (u_int32_t __user *)arg))
return -EFAULT;
if (crt != 0)
int out;
int changes;
- if (get_user(tmp, (u_int32_t*)arg))
+ if (get_user(tmp, (u_int32_t __user *)arg))
return -EFAULT;
for (out = 0; out < 32; out++) {
if (tmp & (1 << out)) {
conn |= 1 << out;
}
}
- if (put_user(conn, (u_int32_t*)arg))
+ if (put_user(conn, (u_int32_t __user *)arg))
return -EFAULT;
return 0;
}
tmp = 0;
}
}
- if (put_user(tmp, (u_int32_t*)arg))
+ if (put_user(tmp, (u_int32_t __user *)arg))
return -EFAULT;
return 0;
}
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
int yres_specified = 0;
+ u32 best = -1, diff = -1;
for (i = namelen-1; i >= 0; i--) {
switch (name[i]) {
}
done:
for (i = refresh_specified; i >= 0; i--) {
- DPRINTK("Trying specified video mode%s\n",
- i ? "" : " (ignoring refresh rate)");
+ DPRINTK("Trying specified video mode%s %ix%i\n",
+ i ? "" : " (ignoring refresh rate)", xres, yres);
for (j = 0; j < dbsize; j++)
if ((name_matches(db[j], name, namelen) ||
(res_specified && res_matches(db[j], xres, yres))) &&
!fb_try_mode(var, info, &db[j], bpp))
return 2-i;
}
+ DPRINTK("Trying best-fit modes\n");
+ for (i = 0; i < dbsize; i++) {
+ if (xres <= db[i].xres && yres <= db[i].yres) {
+ DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres);
+ if (!fb_try_mode(var, info, &db[i], bpp)) {
+ if (diff > (db[i].xres - xres) + (db[i].yres - yres)) {
+ diff = (db[i].xres - xres) + (db[i].yres - yres);
+ best = i;
+ }
+ }
+ }
+ }
+ if (best != -1) {
+ fb_try_mode(var, info, &db[best], bpp);
+ return 5;
+ }
}
DPRINTK("Trying default video mode\n");
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <asm/arch/bitfield.h>
#include <asm/arch/pxafb.h>
u_int val, ret = 1;
if (regno < fbi->palette_size) {
- val = ((red >> 0) & 0xf800);
- val |= ((green >> 5) & 0x07e0);
- val |= ((blue >> 11) & 0x001f);
-
+ if (fbi->fb.var.grayscale) {
+ val = ((blue >> 8) & 0x00ff);
+ } else {
+ val = ((red >> 0) & 0xf800);
+ val |= ((green >> 5) & 0x07e0);
+ val |= ((blue >> 11) & 0x001f);
+ }
fbi->palette_cpu[regno] = val;
ret = 0;
}
switch (fbi->fb.fix.visual) {
case FB_VISUAL_TRUECOLOR:
/*
- * 12 or 16-bit True Colour. We encode the RGB value
+ * 16-bit True Colour. We encode the RGB value
* according to the RGB bitfield information.
*/
if (regno < 16) {
* The pixel packing format is described on page 7-11 of the
* PXA2XX Developer's Manual.
*/
- if ( var->bits_per_pixel == 16 ) {
+ if (var->bits_per_pixel == 16) {
var->red.offset = 11; var->red.length = 5;
var->green.offset = 5; var->green.length = 6;
var->blue.offset = 0; var->blue.length = 5;
fbi->fb.fix.line_length = var->xres_virtual *
var->bits_per_pixel / 8;
- fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
+ if (var->bits_per_pixel == 16)
+ fbi->palette_size = 0;
+ else
+ fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
palette_mem_size = fbi->palette_size * sizeof(u16);
*/
pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
+ if (fbi->fb.var.bits_per_pixel == 16)
+ fb_dealloc_cmap(&fbi->fb.cmap);
+ else
+ fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
+
pxafb_activate_var(var, fbi);
return 0;
/*
* pxafb_blank():
* Blank the display by setting all palette values to zero. Note, the
- * 12 and 16 bpp modes don't really use the palette, so this will not
+ * 16 bpp mode does not really use the palette, so this will not
* blank the display in all modes.
*/
static int pxafb_blank(int blank, struct fb_info *info)
* the YRES parameter.
*/
lines_per_panel = var->yres;
- if (fbi->lccr0 & LCCR0_SDS)
+ if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual)
lines_per_panel /= 2;
new_regs.lccr2 =
fbi->dmadesc_palette_cpu->fidr = 0;
fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
- if( var->bits_per_pixel < 12)
- {
- /* assume any mode with <12 bpp is palette driven */
- fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
- fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
- fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
- }
- else
- {
+ if (var->bits_per_pixel == 16) {
/* palette shouldn't be loaded in true-color mode */
fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
/* init it to something, even though we won't be using it */
fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_palette_dma;
+ } else {
+ fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
+ fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
+ fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
}
#if 0
}
else {
- printk( KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
+ printk(KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
}
}
res_specified = 1;
}
done:
- if ( res_specified ) {
- dev_info(dev, "overriding resolution: %dx%x\n", xres, yres);
+ if (res_specified) {
+ dev_info(dev, "overriding resolution: %dx%d\n", xres, yres);
inf->xres = xres; inf->yres = yres;
}
- if ( bpp_specified )
+ if (bpp_specified)
switch (bpp) {
case 1:
case 2:
}
} else if (!strncmp(this_opt, "pixclock:", 9)) {
inf->pixclock = simple_strtoul(this_opt+9, NULL, 0);
- dev_info(dev, "override pixclock: %u\n", inf->pixclock);
+ dev_info(dev, "override pixclock: %ld\n", inf->pixclock);
} else if (!strncmp(this_opt, "left:", 5)) {
inf->left_margin = simple_strtoul(this_opt+5, NULL, 0);
dev_info(dev, "override left: %u\n", inf->left_margin);
inf->vsync_len = simple_strtoul(this_opt+9, NULL, 0);
dev_info(dev, "override vsynclen: %u\n", inf->vsync_len);
} else if (!strncmp(this_opt, "hsync:", 6)) {
- if ( simple_strtoul(this_opt+6, NULL, 0) == 0 ) {
+ if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
dev_info(dev, "override hsync: Active Low\n");
inf->sync &= ~FB_SYNC_HOR_HIGH_ACT;
} else {
inf->sync |= FB_SYNC_HOR_HIGH_ACT;
}
} else if (!strncmp(this_opt, "vsync:", 6)) {
- if ( simple_strtoul(this_opt+6, NULL, 0) == 0 ) {
+ if (simple_strtoul(this_opt+6, NULL, 0) == 0) {
dev_info(dev, "override vsync: Active Low\n");
inf->sync &= ~FB_SYNC_VERT_HIGH_ACT;
} else {
inf->sync |= FB_SYNC_VERT_HIGH_ACT;
}
} else if (!strncmp(this_opt, "dpc:", 4)) {
- if ( simple_strtoul(this_opt+4, NULL, 0) == 0 ) {
+ if (simple_strtoul(this_opt+4, NULL, 0) == 0) {
dev_info(dev, "override double pixel clock: false\n");
inf->lccr3 &= ~LCCR3_DPC;
} else {
inf->lccr3 |= LCCR3_DPC;
}
} else if (!strncmp(this_opt, "outputen:", 9)) {
- if ( simple_strtoul(this_opt+9, NULL, 0) == 0 ) {
+ if (simple_strtoul(this_opt+9, NULL, 0) == 0) {
dev_info(dev, "override output enable: active low\n");
- inf->lccr3 = ( inf->lccr3 & ~LCCR3_OEP ) | LCCR3_OutEnL;
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnL;
} else {
dev_info(dev, "override output enable: active high\n");
- inf->lccr3 = ( inf->lccr3 & ~LCCR3_OEP ) | LCCR3_OutEnH;
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_OEP) | LCCR3_OutEnH;
}
} else if (!strncmp(this_opt, "pixclockpol:", 12)) {
- if ( simple_strtoul(this_opt+12, NULL, 0) == 0 ) {
+ if (simple_strtoul(this_opt+12, NULL, 0) == 0) {
dev_info(dev, "override pixel clock polarity: falling edge\n");
- inf->lccr3 = ( inf->lccr3 & ~LCCR3_PCP ) | LCCR3_PixFlEdg;
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixFlEdg;
} else {
dev_info(dev, "override pixel clock polarity: rising edge\n");
- inf->lccr3 = ( inf->lccr3 & ~LCCR3_PCP ) | LCCR3_PixRsEdg;
+ inf->lccr3 = (inf->lccr3 & ~LCCR3_PCP) | LCCR3_PixRsEdg;
}
} else if (!strncmp(this_opt, "color", 5)) {
inf->lccr0 = (inf->lccr0 & ~LCCR0_CMS) | LCCR0_Color;
#ifdef CONFIG_FB_PXA_PARAMETERS
ret = pxafb_parse_options(dev, g_options);
- if ( ret < 0 )
+ if (ret < 0)
goto failed;
#endif
/* Check for various illegal bit-combinations. Currently only
* a warning is given. */
- if ( inf->lccr0 & LCCR0_INVALID_CONFIG_MASK )
+ if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
dev_warn(dev, "machine LCCR0 setting contains illegal bits: %08x\n",
inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
- if ( inf->lccr3 & LCCR3_INVALID_CONFIG_MASK )
+ if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
dev_warn(dev, "machine LCCR3 setting contains illegal bits: %08x\n",
inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
- if ( inf->lccr0 & LCCR0_DPD &&
- ( ( inf->lccr0 & LCCR0_PAS ) != LCCR0_Pas ||
- ( inf->lccr0 & LCCR0_SDS ) != LCCR0_Sngl ||
- ( inf->lccr0 & LCCR0_CMS ) != LCCR0_Mono ) )
+ if (inf->lccr0 & LCCR0_DPD &&
+ ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
+ (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
+ (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
dev_warn(dev, "Double Pixel Data (DPD) mode is only valid in passive mono"
" single panel mode\n");
- if ( (inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
- ( inf->lccr0 & LCCR0_SDS ) == LCCR0_Dual )
+ if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
+ (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
dev_warn(dev, "Dual panel only valid in passive mode\n");
- if ( (inf->lccr0 & LCCR0_PAS ) == LCCR0_Pas &&
- (inf->upper_margin || inf->lower_margin) )
+ if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
+ (inf->upper_margin || inf->lower_margin))
dev_warn(dev, "Upper and lower margins must be 0 in passive mode\n");
#endif
break;
}
- rc = get_user(value, (__u32*)arg);
+ rc = get_user(value, (__u32 __user *)arg);
if (rc)
return rc;
if (CRTC_CRT_ON & tmp)
value |= 0x02;
- return put_user(value, (__u32*)arg);
+ return put_user(value, (__u32 __user *)arg);
default:
return -EINVAL;
}
# Makefile for the Riva framebuffer driver
#
-obj-$(CONFIG_FB_RIVA) += rivafb.o
+obj-$(CONFIG_FB_RIVA) += rivafb.o
-rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+rivafb-objs := fbdev.o riva_hw.o nv_driver.o
+
+ifdef CONFIG_FB_RIVA_I2C
+ rivafb-objs += rivafb-i2c.o
+endif
static int nomtrr __initdata = 0;
#endif
-#ifndef MODULE
static char *mode_option __initdata = NULL;
-#endif
+static int strictmode = 0;
static struct fb_fix_screeninfo rivafb_fix = {
.id = "nVidia",
* rivafb_cursor()
*/
static void rivafb_load_cursor_image(struct riva_par *par, u8 *data8,
- u8 *mask8, u16 bg, u16 fg, u32 w, u32 h)
+ u16 bg, u16 fg, u32 w, u32 h)
{
int i, j, k = 0;
- u32 b, m, tmp;
+ u32 b, tmp;
u32 *data = (u32 *)data8;
- u32 *mask = (u32 *)mask8;
for (i = 0; i < h; i++) {
b = *data++;
- m = *mask++;
reverse_order(&b);
for (j = 0; j < w/2; j++) {
tmp = 0;
#if defined (__BIG_ENDIAN)
- if (m & (1 << 31)) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
b <<= 1;
- m <<= 1;
-
- if (m & (1 << 31)) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp |= (b & (1 << 31)) ? fg : bg;
b <<= 1;
- m <<= 1;
#else
- if (m & 1) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp = (b & 1) ? fg : bg;
b >>= 1;
- m >>= 1;
-
- if (m & 1) {
- fg |= 1 << 15;
- bg |= 1 << 15;
- }
tmp |= (b & 1) ? fg << 16 : bg << 16;
b >>= 1;
- m >>= 1;
#endif
- writel(tmp, par->riva.CURSOR + k++);
+ writel(tmp, &par->riva.CURSOR[k++]);
}
k += (MAX_CURS - w)/2;
}
rivafb_blank(0, info);
}
+static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
+{
+ var->xres = var->xres_virtual = modedb->xres;
+ var->yres = modedb->yres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+ var->xoffset = var->yoffset = 0;
+ var->pixclock = modedb->pixclock;
+ var->left_margin = modedb->left_margin;
+ var->right_margin = modedb->right_margin;
+ var->upper_margin = modedb->upper_margin;
+ var->lower_margin = modedb->lower_margin;
+ var->hsync_len = modedb->hsync_len;
+ var->vsync_len = modedb->vsync_len;
+ var->sync = modedb->sync;
+ var->vmode = modedb->vmode;
+}
+
/**
* rivafb_do_maximize -
* @info: pointer to fb_info object containing info for current riva board
"using maximum available virtual resolution\n");
for (i = 0; modes[i].xres != -1; i++) {
if (modes[i].xres * nom / den * modes[i].yres <
- info->fix.smem_len / 2)
+ info->fix.smem_len)
break;
}
if (modes[i].xres == -1) {
"virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
return -EINVAL;
}
+ if (var->xres_virtual > 0x7fff)
+ var->xres_virtual = 0x7fff;
+ if (var->yres_virtual > 0x7fff)
+ var->yres_virtual = 0x7fff;
return 0;
}
+static void
+riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1)
+{
+ RIVA_FIFO_FREE(par->riva, Patt, 4);
+ par->riva.Patt->Color0 = clr0;
+ par->riva.Patt->Color1 = clr1;
+ par->riva.Patt->Monochrome[0] = pat0;
+ par->riva.Patt->Monochrome[1] = pat1;
+}
+
/* acceleration routines */
inline void wait_for_idle(struct riva_par *par)
{
while (par->riva.Busy(&par->riva));
}
-/* set copy ROP, no mask */
-static void riva_setup_ROP(struct riva_par *par)
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static void
+riva_set_rop_solid(struct riva_par *par, int rop)
{
- RIVA_FIFO_FREE(par->riva, Patt, 5);
- par->riva.Patt->Shape = 0;
- par->riva.Patt->Color0 = 0xffffffff;
- par->riva.Patt->Color1 = 0xffffffff;
- par->riva.Patt->Monochrome[0] = 0xffffffff;
- par->riva.Patt->Monochrome[1] = 0xffffffff;
-
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = 0xCC;
+ riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+ RIVA_FIFO_FREE(par->riva, Rop, 1);
+ par->riva.Rop->Rop3 = rop;
+
}
void riva_setup_accel(struct riva_par *par)
{
RIVA_FIFO_FREE(par->riva, Clip, 2);
par->riva.Clip->TopLeft = 0x0;
- par->riva.Clip->WidthHeight = 0x80008000;
- riva_setup_ROP(par);
+ par->riva.Clip->WidthHeight = 0x7fff7fff;
+ riva_set_rop_solid(par, 0xcc);
wait_for_idle(par);
}
static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
+ struct fb_monspecs *specs = &info->monspecs;
int nom, den; /* translating from pixels->bytes */
+ int mode_valid = 0;
switch (var->bits_per_pixel) {
case 1 ... 8:
return -EINVAL;
}
+ if (!strictmode) {
+ if (!fb_validate_mode(var, info))
+ mode_valid = 1;
+ }
+
+ /* find best mode from modedb */
+ if (!mode_valid && specs->modedb_len) {
+ int i, best, best_refresh, best_x, best_y, diff_x, diff_y;
+
+ best_refresh = best = best_x = best_y = 0;
+ diff_x = diff_y = -1;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (var->xres <= specs->modedb[i].xres &&
+ !(specs->modedb[i].flag & FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].xres - var->xres < diff_x) {
+ best_x = specs->modedb[i].xres;
+ diff_x = best_x - var->xres;
+ }
+ if (!diff_x) break;
+ }
+
+ if (diff_x != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ var->yres <= specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].yres-var->yres < diff_y) {
+ best_y = specs->modedb[i].yres;
+ diff_y = best_y - var->yres;
+ }
+ if (!diff_y) break;
+ }
+ }
+
+ if (diff_y != -1) {
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (best_x == specs->modedb[i].xres &&
+ best_y == specs->modedb[i].yres &&
+ !(specs->modedb[i].flag &
+ FB_MODE_IS_CALCULATED) &&
+ specs->modedb[i].refresh > best_refresh) {
+ best_refresh=specs->modedb[i].refresh;
+ best = i;
+ }
+ }
+ }
+
+ if (best_refresh) {
+ riva_update_var(var, &specs->modedb[best]);
+ mode_valid = 1;
+ }
+ }
+
+ /* calculate modeline if supported by monitor */
+ if (!mode_valid && info->monspecs.gtf) {
+ if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ mode_valid = 1;
+ }
+ if (!mode_valid && info->monspecs.modedb_len)
+ return -EINVAL;
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual <= var->yres)
+ var->yres_virtual = -1;
if (rivafb_do_maximize(info, var, nom, den) < 0)
return -EINVAL;
break;
}
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = rop;
+ riva_set_rop_solid(par, rop);
RIVA_FIFO_FREE(par->riva, Bitmap, 1);
par->riva.Bitmap->Color1A = color;
RIVA_FIFO_FREE(par->riva, Bitmap, 2);
par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
(rect->dx << 16) | rect->dy;
+ mb();
par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
(rect->width << 16) | rect->height;
- RIVA_FIFO_FREE(par->riva, Rop, 1);
- par->riva.Rop->Rop3 = 0xCC; // back to COPY
+ mb();
+ riva_set_rop_solid(par, 0xcc);
+
}
/**
RIVA_FIFO_FREE(par->riva, Blt, 3);
par->riva.Blt->TopLeftSrc = (region->sy << 16) | region->sx;
par->riva.Blt->TopLeftDst = (region->dy << 16) | region->dx;
+ mb();
par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
- wait_for_idle(par);
+ mb();
}
static inline void convert_bgcolor_16(u32 *col)
| ((*col & 0x000003E0) << 6)
| ((*col & 0x0000001F) << 3)
| 0xFF000000;
+ mb();
}
/**
{
struct riva_par *par = (struct riva_par *) info->par;
u8 data[MAX_CURS * MAX_CURS/8];
- u8 mask[MAX_CURS * MAX_CURS/8];
u16 fg, bg;
int i;
info->cursor.image.fg_color = cursor->image.fg_color;
}
- if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETCUR)) {
u32 bg_idx = info->cursor.image.bg_color;
u32 fg_idx = info->cursor.image.fg_color;
u32 s_pitch = (info->cursor.image.width+7) >> 3;
u8 *msk = (u8 *) info->cursor.mask;
u8 src[64];
+ info->cursor.image.data = cursor->image.data;
switch (info->cursor.rop) {
case ROP_XOR:
- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
- src[i] = dat[i] ^ msk[i];
+ for (i = 0; i < s_pitch * info->cursor.image.height;
+ i++)
+ src[i] = dat[i] ^ msk[i];
break;
case ROP_COPY:
default:
- for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-
- src[i] = dat[i] & msk[i];
+ for (i = 0; i < s_pitch * info->cursor.image.height;
+ i++)
+ src[i] = dat[i] & msk[i];
break;
}
- fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src, s_pitch, info->cursor.image.height);
-
- fb_move_buf_aligned(info, &info->sprite, mask, d_pitch, msk, s_pitch, info->cursor.image.height);
+ fb_move_buf_aligned(info, &info->sprite, data, d_pitch, src,
+ s_pitch, info->cursor.image.height);
bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
((info->cmap.green[bg_idx] & 0xf8) << 2) |
- ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
+ ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
((info->cmap.green[fg_idx] & 0xf8) << 2) |
- ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
+ ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
par->riva.LockUnlock(&par->riva, 0);
- rivafb_load_cursor_image(par, data, mask, bg, fg,
+ rivafb_load_cursor_image(par, data, bg, fg,
info->cursor.image.width,
info->cursor.image.height);
}
static int __devinit riva_set_fbinfo(struct fb_info *info)
{
- struct riva_par *par = (struct riva_par *) info->par;
unsigned int cmap_len;
- info->flags = FBINFO_FLAG_DEFAULT;
+ info->flags = FBINFO_DEFAULT
+ | FBINFO_HWACCEL_XPAN
+ | FBINFO_HWACCEL_YPAN
+ | FBINFO_HWACCEL_COPYAREA
+ | FBINFO_HWACCEL_FILLRECT
+ | FBINFO_HWACCEL_IMAGEBLIT;
info->var = rivafb_default_var;
- info->fix = rivafb_fix;
- info->fbops = &riva_fb_ops;
+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
info->pseudo_palette = pseudo_palette;
-#ifndef MODULE
- if (mode_option)
- fb_find_mode(&info->var, info, mode_option,
- NULL, 0, NULL, 8);
-#endif
- if (par->use_default_var)
- /* We will use the modified default var */
- info->var = rivafb_default_var;
-
cmap_len = riva_get_cmap_len(&info->var);
fb_alloc_cmap(&info->cmap, cmap_len, 0);
info->pixmap.buf_align = 4;
info->pixmap.scan_align = 4;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
- return 0;
+ info->var.yres_virtual = -1;
+ return (rivafb_check_var(&info->var, info));
}
#ifdef CONFIG_PPC_OF
struct riva_par *par = (struct riva_par *) info->par;
struct device_node *dp;
unsigned char *pedid = NULL;
+ unsigned char *disptype = NULL;
+ static char *propnames[] = {
+ "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
+ int i;
dp = pci_device_to_OF_node(pd);
- pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
-
- if (pedid) {
+ for (; dp != NULL; dp = dp->child) {
+ disptype = (unsigned char *)get_property(dp, "display-type", NULL);
+ if (disptype == NULL)
+ continue;
+ if (strncmp(disptype, "LCD", 3) != 0)
+ continue;
+ for (i = 0; propnames[i] != NULL; ++i) {
+ pedid = (unsigned char *)
+ get_property(dp, propnames[i], NULL);
+ if (pedid != NULL) {
par->EDID = pedid;
return 1;
- } else
+ }
+ }
+ }
return 0;
}
#endif /* CONFIG_PPC_OF */
-static int riva_dfp_parse_EDID(struct riva_par *par)
+static void riva_update_default_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- unsigned char *block = par->EDID;
-
- if (!block)
- return 0;
-
- /* jump to detailed timing block section */
- block += 54;
-
- par->clock = (block[0] + (block[1] << 8));
- par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
- par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
- par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
- par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
- par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
- par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
- par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
- par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
- par->interlaced = ((block[17] & 0x80) >> 7);
- par->synct = ((block[17] & 0x18) >> 3);
- par->misc = ((block[17] & 0x06) >> 1);
- par->hAct_high = par->vAct_high = 0;
- if (par->synct == 3) {
- if (par->misc & 2)
- par->hAct_high = 1;
- if (par->misc & 1)
- par->vAct_high = 1;
+ struct fb_monspecs *specs = &info->monspecs;
+ struct fb_videomode modedb;
+
+ /* respect mode options */
+ if (mode_option) {
+ fb_find_mode(var, info, mode_option,
+ specs->modedb, specs->modedb_len,
+ NULL, 8);
+ } else if (specs->modedb != NULL) {
+ /* get preferred timing */
+ if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
+ int i;
+
+ for (i = 0; i < specs->modedb_len; i++) {
+ if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
+ modedb = specs->modedb[i];
+ break;
+ }
+ }
+ } else {
+ /* otherwise, get first mode in database */
+ modedb = specs->modedb[0];
+ }
+ var->bits_per_pixel = 8;
+ riva_update_var(var, &modedb);
}
-
- printk(KERN_INFO PFX
- "detected DFP panel size from EDID: %dx%d\n",
- par->panel_xres, par->panel_yres);
- par->got_dfpinfo = 1;
- return 1;
-}
-
-static void riva_update_default_var(struct fb_info *info)
-{
- struct fb_var_screeninfo *var = &rivafb_default_var;
- struct riva_par *par = (struct riva_par *) info->par;
-
- var->xres = par->panel_xres;
- var->yres = par->panel_yres;
- var->xres_virtual = par->panel_xres;
- var->yres_virtual = par->panel_yres;
- var->xoffset = var->yoffset = 0;
- var->bits_per_pixel = 8;
- var->pixclock = 100000000 / par->clock;
- var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
- var->right_margin = par->hOver_plus;
- var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
- var->lower_margin = par->vOver_plus;
- var->hsync_len = par->hSync_width;
- var->vsync_len = par->vSync_width;
- var->sync = 0;
-
- if (par->synct == 3) {
- if (par->hAct_high)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (par->vAct_high)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- }
-
- var->vmode = 0;
- if (par->interlaced)
- var->vmode |= FB_VMODE_INTERLACED;
-
var->accel_flags |= FB_ACCELF_TEXT;
-
- par->use_default_var = 1;
}
printk("rivafb: could not retrieve EDID from OF\n");
#else
/* XXX use other methods later */
+#ifdef CONFIG_FB_RIVA_I2C
+ struct riva_par *par = (struct riva_par *) info->par;
+
+ riva_create_i2c_busses(par);
+ riva_probe_i2c_connector(par, 1, &par->EDID);
+ riva_delete_i2c_busses(par);
+#endif
#endif
}
-static void riva_get_dfpinfo(struct fb_info *info)
+static void riva_get_edidinfo(struct fb_info *info)
{
+ struct fb_var_screeninfo *var = &rivafb_default_var;
struct riva_par *par = (struct riva_par *) info->par;
- if (riva_dfp_parse_EDID(par))
- riva_update_default_var(info);
+ fb_edid_to_monspecs(par->EDID, &info->monspecs);
+ riva_update_default_var(var, info);
/* if user specified flatpanel, we respect that */
- if (par->got_dfpinfo == 1)
+ if (info->monspecs.input & FB_DISP_DDI)
par->FlatPanel = 1;
}
memset(info, 0, sizeof(struct fb_info));
memset(default_par, 0, sizeof(struct riva_par));
+ default_par->pdev = pd;
info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
info->par = default_par;
- riva_get_EDID(info, pd);
-
- riva_get_dfpinfo(info);
-
switch (default_par->riva.Architecture) {
case NV_ARCH_03:
/* Riva128's PRAMIN is in the "framebuffer" space
}
#endif /* CONFIG_MTRR */
+ info->fbops = &riva_fb_ops;
+ info->fix = rivafb_fix;
+ riva_get_EDID(info, pd);
+ riva_get_edidinfo(info);
+
if (riva_set_fbinfo(info) < 0) {
printk(KERN_ERR PFX "error setting initial video mode\n");
goto err_out_iounmap_fb;
} else if (!strncmp(this_opt, "nomtrr", 6)) {
nomtrr = 1;
#endif
+ } else if (!strncmp(this_opt, "strictmode", 10)) {
+ strictmode = 1;
} else
mode_option = this_opt;
}
#ifdef CONFIG_MTRR
MODULE_PARM(nomtrr, "i");
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
+MODULE_PARM(strictmode, "i");
+MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");
#endif
#endif /* MODULE */
#include <linux/config.h>
#include <linux/fb.h>
#include <video/vga.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
#include "riva_hw.h"
/* GGI compatibility macros */
#define NUM_GRC_REGS 0x09
#define NUM_ATC_REGS 0x15
+/* I2C */
+#define DDC_SCL_READ_MASK (1 << 2)
+#define DDC_SCL_WRITE_MASK (1 << 5)
+#define DDC_SDA_READ_MASK (1 << 3)
+#define DDC_SDA_WRITE_MASK (1 << 4)
+
/* holds the state of the VGA core and extended Riva hw state from riva_hw.c.
* From KGI originally. */
struct riva_regs {
RIVA_HW_STATE ext;
};
+struct riva_par;
+
+struct riva_i2c_chan {
+ struct riva_par *par;
+ unsigned long ddc_base;
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
struct riva_par {
RIVA_HW_INST riva; /* interface to riva_hw.c */
u32 cursor_data[32 * 32/4];
int cursor_reset;
unsigned char *EDID;
-
- int panel_xres, panel_yres;
- int hOver_plus, hSync_width, hblank;
- int vOver_plus, vSync_width, vblank;
- int hAct_high, vAct_high, interlaced;
- int synct, misc, clock;
-
- int use_default_var;
- int got_dfpinfo;
unsigned int Chipset;
int forceCRTC;
Bool SecondCRTC;
int FlatPanel;
+ struct pci_dev *pdev;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
#endif
+ struct riva_i2c_chan chan[3];
};
void riva_common_setup(struct riva_par *);
unsigned long riva_get_memlen(struct riva_par *);
unsigned long riva_get_maxdclk(struct riva_par *);
+void riva_delete_i2c_busses(struct riva_par *par);
+void riva_create_i2c_busses(struct riva_par *par);
+int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid);
#endif /* __RIVAFB_H */
cmap.red = &red;
cmap.green = &green;
cmap.blue = &blue;
+ cmap.transp = NULL;
for (i = 0; i < count; i++) {
int err;
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Register settings for SiS 300 series
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
*
*/
-typedef struct _SiS300_StStruct
-{
- UCHAR St_ModeID;
- USHORT St_ModeFlag;
- UCHAR St_StTableIndex;
- UCHAR St_CRT2CRTC;
- UCHAR St_ResInfo;
- UCHAR VB_StTVFlickerIndex;
- UCHAR VB_StTVEdgeIndex;
- UCHAR VB_StTVYFilterIndex;
- UCHAR St_PDC;
-} SiS300_StStruct;
-
-static const SiS300_StStruct SiS300_SModeIDTable[] =
+static const SiS_StStruct SiS300_SModeIDTable[] =
{
{0x01,0x9208,0x01,0x00,0x00,0x00,0x00,0x00, 0},
{0x01,0x1210,0x14,0x01,0x01,0x00,0x00,0x00, 0},
{0xff, 0, 0, 0, 0, 0, 0, 0, 0}
};
-typedef struct _SiS300_ExtStruct
-{
- UCHAR Ext_ModeID;
- USHORT Ext_ModeFlag;
- UCHAR Ext_ModeOffset;
- USHORT Ext_VESAID;
- UCHAR Ext_RESINFO;
- UCHAR VB_ExtTVFlickerIndex;
- UCHAR VB_ExtTVEdgeIndex;
- UCHAR VB_ExtTVYFilterIndex;
- UCHAR VB_ExtTVYFilterIndexROM661;
- UCHAR REFindex;
-} SiS300_ExtStruct;
-
-static const SiS300_ExtStruct SiS300_EModeIDTable[] =
-{
- {0x6a,0x2212,0x04,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00}, /* 800x600x? */
- {0x2e,0x0a1b,0x03,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08},
- {0x2f,0x021b,0x03,0x0100,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10}, /* 640x400x8 */
- {0x30,0x2a1b,0x04,0x0103,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00},
- {0x31,0x0a1b,0x0a,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11}, /* 720x480x8 */
- {0x32,0x2a1b,0x0a,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12}, /* 720x576x8 */
- {0x33,0x0a1d,0x0a,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11}, /* 720x480x16 */
- {0x34,0x2a1d,0x0a,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12}, /* 720x576x16 */
- {0x35,0x0a1f,0x0a,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11}, /* 720x480x32 */
- {0x36,0x2a1f,0x0a,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12}, /* 720x576x32 */
- {0x37,0x0212,0x05,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13}, /* 1024x768x? */
- {0x38,0x0a1b,0x05,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13}, /* 1024x768x8 */
- {0x3a,0x0e3b,0x06,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
- {0x3c,0x063b,0x07,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
- {0x3d,0x067d,0x07,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
- {0x40,0x921c,0x00,0x010d,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23}, /* 320x200x15 */
- {0x41,0x921d,0x00,0x010e,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23}, /* 320x200x16 */
- {0x43,0x0a1c,0x03,0x0110,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08},
- {0x44,0x0a1d,0x03,0x0111,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08},
- {0x46,0x2a1c,0x04,0x0113,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00}, /* 800x600x15 */
- {0x47,0x2a1d,0x04,0x0114,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00}, /* 800x600x16 */
- {0x49,0x0a3c,0x05,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
- {0x4a,0x0a3d,0x05,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
- {0x4c,0x0e7c,0x06,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
- {0x4d,0x0e7d,0x06,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
- {0x50,0x921b,0x00,0x0132,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24}, /* 320x240x8 */
- {0x51,0xb21b,0x01,0x0133,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25}, /* 400x300x8 */
- {0x52,0x921b,0x02,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26}, /* 512x384x8 */
- {0x56,0x921d,0x00,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24}, /* 320x240x16 */
- {0x57,0xb21d,0x01,0x0136,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25}, /* 400x300x16 */
- {0x58,0x921d,0x02,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26}, /* 512x384x16 */
- {0x59,0x921b,0x00,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23}, /* 320x200x8 */
- {0x5c,0x921f,0x02,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26}, /* 512x384x32 */
- {0x5d,0x021d,0x03,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10}, /* 640x400x16 */
- {0x5e,0x021f,0x03,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10}, /* 640x400x32 */
- {0x62,0x0a3f,0x03,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08},
- {0x63,0x2a3f,0x04,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00}, /* 800x600x32 */
- {0x64,0x0a7f,0x05,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13},
- {0x65,0x0eff,0x06,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
- {0x66,0x06ff,0x07,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e},
- {0x68,0x067b,0x08,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
- {0x69,0x06fd,0x08,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
- {0x6b,0x07ff,0x08,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27},
- {0x6c,0x067b,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28}, /* 2048x1536x8 - not in BIOS! */
- {0x6d,0x06fd,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28}, /* 2048x1536x16 - not in BIOS! */
- {0x70,0x2a1b,0x04,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d}, /* 800x480x8 */
- {0x71,0x0a1b,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30}, /* 1024x576x8 */
- {0x74,0x0a1d,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30}, /* 1024x576x16 */
- {0x75,0x0e3d,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33}, /* 1280x720x16 */
- {0x76,0x2a1f,0x04,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d}, /* 800x480x32 */
- {0x77,0x0a3f,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30}, /* 1024x576x32 */
- {0x78,0x0eff,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33}, /* 1280x720x32 */
- {0x79,0x0e3b,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33}, /* 1280x720x8 */
- {0x7a,0x2a1d,0x04,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d}, /* 800x480x16 */
- {0x7c,0x0a3b,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29}, /* 1280x960x8 */
- {0x7d,0x0a7d,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29}, /* 1280x960x16 */
- {0x7e,0x0aff,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29}, /* 1280x960x32 */
- {0x20,0x0a1b,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b}, /* 1024x600 */
- {0x21,0x0a3d,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},
- {0x22,0x0a7f,0x05,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b},
- {0x23,0x0a1b,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c}, /* 1152x768 */
- {0x24,0x0a3d,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},
- {0x25,0x0a7f,0x0c,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c},
- {0x29,0x0e1b,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36}, /* 1152x864 */
- {0x2a,0x0e3d,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},
- {0x2b,0x0e7f,0x0c,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36},
- {0x39,0x2a1b,0x0d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x38}, /* 848x480 */
- {0x3b,0x2a3d,0x0d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x38},
- {0x3e,0x2a7f,0x0d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x38},
- {0x3f,0x2a1b,0x0d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3a}, /* 856x480 */
- {0x42,0x2a3d,0x0d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3a},
- {0x45,0x2a7f,0x0d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3a},
- {0x48,0x223b,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c}, /* 1360x768 */
- {0x4b,0x227d,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},
- {0x4e,0x22ff,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c},
- {0x4f,0x921f,0x00,0x0000,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23}, /* 320x200x32 */
- {0x53,0x921f,0x00,0x0000,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24}, /* 320x240x32 */
- {0x54,0xb21f,0x01,0x0000,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25}, /* 400x300x32 */
- {0x55,0x2e3b,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x768 */
- {0x5a,0x2e7d,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},
- {0x5b,0x2eff,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d},
- {0x5f,0x2a1b,0x0f,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3e}, /* 768x576x8 */
- {0x60,0x2a1d,0x0f,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3e}, /* 768x576x16 */
- {0x61,0x2a1f,0x0f,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3e}, /* 768x576x32 */
- {0x67,0x2e3b,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f}, /* 1360x1024x8 (BARCO) */
- {0x6f,0x2e7d,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f}, /* 1360x1024x16 (BARCO) */
- {0x72,0x2eff,0x0e,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f}, /* 1360x1024x32 (BARCO) */
- {0xff,0x0000,0x00,0xffff,0, 0x00,0x00,0x00,0x00,0x00}
-};
-
-typedef struct _SiS300_Ext2Struct
-{
- USHORT Ext_InfoFlag;
- UCHAR Ext_CRT1CRTC; /* Index in SiS300_CRT1Table */
- UCHAR Ext_CRTVCLK; /* Index in VCLK array */
- UCHAR Ext_CRT2CRTC; /* Index in LCD Paneltype arrays (&3f) */
- UCHAR ModeID;
- USHORT XRes;
- USHORT YRes;
- UCHAR Ext_PDC;
-} SiS300_Ext2Struct;
-
-static const SiS300_Ext2Struct SiS300_RefIndex[] =
-{
- {0x085f,0x0d,0x03,0x05,0x6a, 800, 600, 0}, /* 00 */
- {0x0467,0x0e,0x44,0x05,0x6a, 800, 600, 0}, /* 01 */
- {0x0067,0x0f,0x07,0x48,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
- {0x0067,0x10,0x06,0x8b,0x6a, 800, 600, 0}, /* 03 */
- {0x0147,0x11,0x08,0x00,0x6a, 800, 600, 0}, /* 04 */
- {0x0147,0x12,0x0c,0x00,0x6a, 800, 600, 0}, /* 05 */
- {0x0047,0x11,0x4e,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
- {0x0047,0x11,0x13,0x00,0x6a, 800, 600, 0}, /* 07 */
- {0xc85f,0x05,0x00,0x04,0x2e, 640, 480, 0}, /* 08 */
- {0xc067,0x06,0x02,0x04,0x2e, 640, 480, 0}, /* 09 */
- {0xc067,0x07,0x02,0x47,0x2e, 640, 480, 0}, /* 0a */
- {0xc067,0x08,0x03,0x8a,0x2e, 640, 480, 0}, /* 0b */
- {0xc047,0x09,0x05,0x00,0x2e, 640, 480, 0}, /* 0c */
- {0xc047,0x0a,0x08,0x00,0x2e, 640, 480, 0}, /* 0d */
- {0xc047,0x0b,0x0a,0x00,0x2e, 640, 480, 0}, /* 0e */
- {0xc047,0x0c,0x10,0x00,0x2e, 640, 480, 0}, /* 0f */
- {0x487f,0x04,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
- {0xc04f,0x31,0x01,0x06,0x31, 720, 480, 0}, /* 11 */
- {0x004f,0x32,0x03,0x06,0x32, 720, 576, 0}, /* 12 */
- {0x0187,0x15,0x05,0x00,0x37,1024, 768, 0}, /* 13 */
- {0xc877,0x16,0x09,0x06,0x37,1024, 768, 0}, /* 14 */
- {0xc067,0x17,0x0b,0x49,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
- {0x0267,0x18,0x0d,0x00,0x37,1024, 768, 0}, /* 16 */
- {0x0047,0x19,0x11,0x8c,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
- {0x0047,0x1a,0x52,0x00,0x37,1024, 768, 0}, /* 18 */
- {0x0007,0x1b,0x16,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
- {0x0387,0x1c,0x4d,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
- {0x0077,0x1d,0x14,0x07,0x3a,1280,1024, 0}, /* 1b */
- {0x0047,0x1e,0x17,0x00,0x3a,1280,1024, 0}, /* 1c */
- {0x0007,0x1f,0x98,0x00,0x3a,1280,1024, 0}, /* 1d */
- {0x0007,0x20,0x59,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
- {0x0007,0x21,0x5a,0x00,0x3c,1600,1200, 0}, /* 1f */
- {0x0007,0x22,0x1b,0x00,0x3c,1600,1200, 0}, /* 20 */
- {0x0007,0x23,0x1d,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
- {0x0007,0x24,0x1e,0x00,0x3c,1600,1200, 0}, /* 22 */
- {0x407f,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
- {0xc07f,0x01,0x00,0x04,0x50, 320, 240, 0}, /* 24 */
- {0x0077,0x02,0x04,0x05,0x51, 400, 300, 0}, /* 25 */
- {0xc877,0x03,0x09,0x06,0x52, 512, 384, 0}, /* 26 */ /* was c077 */
- {0x8207,0x25,0x1f,0x00,0x68,1920,1440, 0}, /* 27 */
- {0x0007,0x26,0x20,0x00,0x6c,2048,1536, 0}, /* 28 */
- {0x0067,0x27,0x14,0x08,0x6e,1280, 960, 0}, /* 29 - TW: 1280x960-60 */
- {0x0027,0x45,0x3c,0x08,0x6e,1280, 960, 0}, /* 2a - TW: 1280x960-85 */
- {0xc077,0x33,0x09,0x06,0x20,1024, 600, 0}, /* 2b */
- {0xc077,0x34,0x0b,0x06,0x23,1152, 768, 0}, /* 2c */ /* VCLK 0x09 */
- {0x0057,0x35,0x27,0x08,0x70, 800, 480, 0}, /* 2d */
- {0x0047,0x36,0x37,0x08,0x70, 800, 480, 0}, /* 2e */
- {0x0047,0x37,0x08,0x08,0x70, 800, 480, 0}, /* 2f */
- {0x0057,0x38,0x09,0x09,0x71,1024, 576, 0}, /* 30 */
- {0x0047,0x39,0x38,0x09,0x71,1024, 576, 0}, /* 31 */
- {0x0047,0x3a,0x11,0x09,0x71,1024, 576, 0}, /* 32 */
- {0x0057,0x3b,0x39,0x0a,0x75,1280, 720, 0}, /* 33 */
- {0x0047,0x3c,0x3a,0x0a,0x75,1280, 720, 0}, /* 34 */
- {0x0007,0x3d,0x3b,0x0a,0x75,1280, 720, 0}, /* 35 */
- {0x0047,0x3e,0x34,0x06,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
- {0x0047,0x44,0x3a,0x06,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
- {0x00c7,0x3f,0x28,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
- {0xc067,0x40,0x3d,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz */
- {0x00c7,0x41,0x28,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
- {0xc047,0x42,0x28,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz */
- {0x0067,0x43,0x3e,0x0c,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
- {0x0077,0x46,0x3f,0x08,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
- {0x004f,0x47,0x03,0x06,0x5f, 768, 576, 0}, /* 3e 768x576 */
- {0x0027,0x48,0x13,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
- {0xffff, 0, 0, 0, 0, 0, 0, 0}
-};
-
-typedef struct _SiS_VBModeIDTableStruct
-{
- UCHAR ModeID;
- UCHAR VB_TVDelayIndex;
- UCHAR VB_TVFlickerIndex;
- UCHAR VB_TVPhaseIndex;
- UCHAR VB_TVYFilterIndex;
- UCHAR VB_LCDDelayIndex;
- UCHAR _VB_LCDHIndex;
- UCHAR _VB_LCDVIndex;
-}SiS_VBModeIDTableStruct;
-
-static const SiS_VBModeIDTableStruct SiS300_VBModeIDTable[] =
+static const SiS_ExtStruct SiS300_EModeIDTable[] =
+{
+ {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x? */
+ {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
+ {0x2f,0x021b,0x0100,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x8 */
+ {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1},
+ {0x31,0x0a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x8 */
+ {0x32,0x2a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x8 */
+ {0x33,0x0a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x16 */
+ {0x34,0x2a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x16 */
+ {0x35,0x0a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x00,0x00,0x11,-1}, /* 720x480x32 */
+ {0x36,0x2a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x00,0x00,0x12,-1}, /* 720x576x32 */
+ {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, /* 1024x768x? */
+ {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1}, /* 1024x768x8 */
+ {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1}, /* 1280x1024x8 */
+ {0x3c,0x063b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
+ {0x3d,0x067d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
+ {0x40,0x921c,0x010d,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x15 */
+ {0x41,0x921d,0x010e,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x16 */
+ {0x43,0x0a1c,0x0110,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
+ {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
+ {0x46,0x2a1c,0x0113,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x15 */
+ {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x16 */
+ {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
+ {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
+ {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
+ {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
+ {0x50,0x921b,0x0132,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x8 */
+ {0x51,0xb21b,0x0133,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x8 */
+ {0x52,0x921b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x8 */
+ {0x56,0x921d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x16 */
+ {0x57,0xb21d,0x0136,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x16 */
+ {0x58,0x921d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x16 */
+ {0x59,0x921b,0x0138,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x8 */
+ {0x5c,0x921f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x26,-1}, /* 512x384x32 */
+ {0x5d,0x021d,0x0139,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x16 */
+ {0x5e,0x021f,0x0000,SIS_RI_640x400, 0x00,0x00,0x00,0x00,0x10,-1}, /* 640x400x32 */
+ {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x00,0x00,0x08,-1},
+ {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x00,0x00,0x00,-1}, /* 800x600x32 */
+ {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x00,0x13,-1},
+ {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a,-1},
+ {0x66,0x06ff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,-1},
+ {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
+ {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
+ {0x6b,0x07ff,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x27,-1},
+ {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x8 - not in BIOS! */
+ {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x28,-1}, /* 2048x1536x16 - not in BIOS! */
+ {0x70,0x2a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x8 */
+ {0x71,0x0a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x8 */
+ {0x74,0x0a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x16 */
+ {0x75,0x0e3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x16 */
+ {0x76,0x2a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x32 */
+ {0x77,0x0a3f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x30,-1}, /* 1024x576x32 */
+ {0x78,0x0eff,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x32 */
+ {0x79,0x0e3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1280x720x8 */
+ {0x7a,0x2a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x00,0x2d,-1}, /* 800x480x16 */
+ {0x7c,0x0a3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x8 */
+ {0x7d,0x0a7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x16 */
+ {0x7e,0x0aff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x29,-1}, /* 1280x960x32 */
+ {0x20,0x0a1b,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1}, /* 1024x600 */
+ {0x21,0x0a3d,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+ {0x22,0x0a7f,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x00,0x2b,-1},
+ {0x23,0x0a1b,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1}, /* 1152x768 */
+ {0x24,0x0a3d,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+ {0x25,0x0a7f,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x00,0x2c,-1},
+ {0x29,0x0e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1}, /* 1152x864 */
+ {0x2a,0x0e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+ {0x2b,0x0e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x36,-1},
+ {0x39,0x2a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x38,-1}, /* 848x480 */
+ {0x3b,0x2a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x38,-1},
+ {0x3e,0x2a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x38,-1},
+ {0x3f,0x2a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3a,-1}, /* 856x480 */
+ {0x42,0x2a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3a,-1},
+ {0x45,0x2a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x3a,-1},
+ {0x48,0x223b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1}, /* 1360x768 */
+ {0x4b,0x227d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
+ {0x4e,0x22ff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x3c,-1},
+ {0x4f,0x921f,0x0000,SIS_RI_320x200, 0x00,0x00,0x00,0x00,0x23,-1}, /* 320x200x32 */
+ {0x53,0x921f,0x0000,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x24,-1}, /* 320x240x32 */
+ {0x54,0xb21f,0x0000,SIS_RI_400x300, 0x00,0x00,0x00,0x00,0x25,-1}, /* 400x300x32 */
+ {0x55,0x2e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x768 */
+ {0x5a,0x2e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
+ {0x5b,0x2eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x3d,-1},
+ {0x5f,0x2a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3e,-1}, /* 768x576x8 */
+ {0x60,0x2a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3e,-1}, /* 768x576x16 */
+ {0x61,0x2a1f,0x0000,SIS_RI_768x576, 0x00,0x00,0x00,0x00,0x3e,-1}, /* 768x576x32 */
+ {0x67,0x2e3b,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1}, /* 1360x1024x8 (BARCO) */
+ {0x6f,0x2e7d,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1}, /* 1360x1024x16 (BARCO) */
+ {0x72,0x2eff,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x00,0x3f,-1}, /* 1360x1024x32 (BARCO) */
+ {0xff,0x0000,0xffff,0, 0x00,0x00,0x00,0x00,0x00}
+};
+
+static const SiS_Ext2Struct SiS300_RefIndex[] =
+{
+ {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0}, /* 00 */
+ {0x0467,0x0e,0x44,0x05,0x05,0x6a, 800, 600, 0}, /* 01 */
+ {0x0067,0x0f,0x07,0x48,0x00,0x6a, 800, 600, 0}, /* 02 - CRT1CRTC was 0x4f */
+ {0x0067,0x10,0x06,0x8b,0x00,0x6a, 800, 600, 0}, /* 03 */
+ {0x0147,0x11,0x08,0x00,0x00,0x6a, 800, 600, 0}, /* 04 */
+ {0x0147,0x12,0x0c,0x00,0x00,0x6a, 800, 600, 0}, /* 05 */
+ {0x0047,0x11,0x4e,0x00,0x00,0x6a, 800, 600, 0}, /* 06 - CRT1CRTC was 0x51 */
+ {0x0047,0x11,0x13,0x00,0x00,0x6a, 800, 600, 0}, /* 07 */
+ {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0}, /* 08 */
+ {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0}, /* 09 */
+ {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0}, /* 0a */
+ {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0}, /* 0b */
+ {0xc047,0x09,0x05,0x00,0x00,0x2e, 640, 480, 0}, /* 0c */
+ {0xc047,0x0a,0x08,0x00,0x00,0x2e, 640, 480, 0}, /* 0d */
+ {0xc047,0x0b,0x0a,0x00,0x00,0x2e, 640, 480, 0}, /* 0e */
+ {0xc047,0x0c,0x10,0x00,0x00,0x2e, 640, 480, 0}, /* 0f */
+ {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0}, /* 10 */
+ {0xc04f,0x31,0x01,0x06,0x00,0x31, 720, 480, 0}, /* 11 */
+ {0x004f,0x32,0x03,0x06,0x00,0x32, 720, 576, 0}, /* 12 */
+ {0x0187,0x15,0x05,0x00,0x00,0x37,1024, 768, 0}, /* 13 */
+ {0xc877,0x16,0x09,0x06,0x06,0x37,1024, 768, 0}, /* 14 */
+ {0xc067,0x17,0x0b,0x49,0x06,0x37,1024, 768, 0}, /* 15 - CRT1CRTC was 0x97 */
+ {0x0267,0x18,0x0d,0x00,0x06,0x37,1024, 768, 0}, /* 16 */
+ {0x0047,0x19,0x11,0x8c,0x00,0x37,1024, 768, 0}, /* 17 - CRT1CRTC was 0x59 */
+ {0x0047,0x1a,0x52,0x00,0x00,0x37,1024, 768, 0}, /* 18 */
+ {0x0007,0x1b,0x16,0x00,0x00,0x37,1024, 768, 0}, /* 19 - CRT1CRTC was 0x5b */
+ {0x0387,0x1c,0x4d,0x00,0x00,0x3a,1280,1024, 0}, /* 1a - CRT1CRTC was 0x5c */
+ {0x0077,0x1d,0x14,0x07,0x00,0x3a,1280,1024, 0}, /* 1b */
+ {0x0047,0x1e,0x17,0x00,0x00,0x3a,1280,1024, 0}, /* 1c */
+ {0x0007,0x1f,0x98,0x00,0x00,0x3a,1280,1024, 0}, /* 1d */
+ {0x0007,0x20,0x59,0x00,0x00,0x3c,1600,1200, 0}, /* 1e - CRT1CRTC was 0x60 */
+ {0x0007,0x21,0x5a,0x00,0x00,0x3c,1600,1200, 0}, /* 1f */
+ {0x0007,0x22,0x1b,0x00,0x00,0x3c,1600,1200, 0}, /* 20 */
+ {0x0007,0x23,0x1d,0x00,0x00,0x3c,1600,1200, 0}, /* 21 - CRT1CRTC was 0x63 */
+ {0x0007,0x24,0x1e,0x00,0x00,0x3c,1600,1200, 0}, /* 22 */
+ {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0}, /* 23 */
+ {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0}, /* 24 */
+ {0x0077,0x02,0x04,0x05,0x05,0x51, 400, 300, 0}, /* 25 */
+ {0xc877,0x03,0x09,0x06,0x06,0x52, 512, 384, 0}, /* 26 */ /* was c077 */
+ {0x8207,0x25,0x1f,0x00,0x00,0x68,1920,1440, 0}, /* 27 */
+ {0x0007,0x26,0x20,0x00,0x00,0x6c,2048,1536, 0}, /* 28 */
+ {0x0067,0x27,0x14,0x08,0x0a,0x6e,1280, 960, 0}, /* 29 - 1280x960-60 */
+ {0x0027,0x45,0x3c,0x08,0x0a,0x6e,1280, 960, 0}, /* 2a - 1280x960-85 */
+ {0xc077,0x33,0x09,0x06,0x00,0x20,1024, 600, 0}, /* 2b */
+ {0xc077,0x34,0x0b,0x06,0x00,0x23,1152, 768, 0}, /* 2c */ /* VCLK 0x09 */
+ {0x0057,0x35,0x27,0x08,0x00,0x70, 800, 480, 0}, /* 2d */
+ {0x0047,0x36,0x37,0x08,0x00,0x70, 800, 480, 0}, /* 2e */
+ {0x0047,0x37,0x08,0x08,0x00,0x70, 800, 480, 0}, /* 2f */
+ {0x0057,0x38,0x09,0x09,0x00,0x71,1024, 576, 0}, /* 30 */
+ {0x0047,0x39,0x38,0x09,0x00,0x71,1024, 576, 0}, /* 31 */
+ {0x0047,0x3a,0x11,0x09,0x00,0x71,1024, 576, 0}, /* 32 */
+ {0x0057,0x3b,0x39,0x0a,0x00,0x75,1280, 720, 0}, /* 33 */
+ {0x0047,0x3c,0x3a,0x0a,0x00,0x75,1280, 720, 0}, /* 34 */
+ {0x0007,0x3d,0x3b,0x0a,0x00,0x75,1280, 720, 0}, /* 35 */
+ {0x0047,0x3e,0x34,0x06,0x00,0x29,1152, 864, 0}, /* 36 1152x864-75Hz */
+ {0x0047,0x44,0x3a,0x06,0x00,0x29,1152, 864, 0}, /* 37 1152x864-85Hz */
+ {0x00c7,0x3f,0x28,0x00,0x00,0x39, 848, 480, 0}, /* 38 848x480-38Hzi */
+ {0xc067,0x40,0x3d,0x0b,0x0b,0x39, 848, 480, 0}, /* 39 848x480-60Hz */
+ {0x00c7,0x41,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3a 856x480-38Hzi */
+ {0xc047,0x42,0x28,0x00,0x00,0x3f, 856, 480, 0}, /* 3b 856x480-60Hz */
+ {0x0067,0x43,0x3e,0x0c,0x0b,0x48,1360, 768, 0}, /* 3c 1360x768-60Hz */
+ {0x0077,0x46,0x3f,0x08,0x00,0x55,1280, 768, 0}, /* 3d 1280x768-60Hz */
+ {0x004f,0x47,0x03,0x06,0x00,0x5f, 768, 576, 0}, /* 3e 768x576 */
+ {0x0027,0x48,0x13,0x08,0x08,0x67,1360,1024, 0}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+ {0xffff, 0, 0, 0, 0, 0, 0, 0, 0}
+};
+
+static const SiS_VBModeStruct SiS300_VBModeIDTable[] =
{
{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
-typedef struct _SiS300_CRT1TableStruct
-{
- UCHAR CR[17];
-} SiS300_CRT1TableStruct;
-
-static const SiS300_CRT1TableStruct SiS300_CRT1Table[] =
+static const SiS_CRT1TableStruct SiS300_CRT1Table[] =
{
#if 1
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, /* 0x00 - 320x200 */
0x00}} /* 0x48 */
};
-typedef struct _SiS300_MCLKDataStruct
-{
- UCHAR SR28,SR29,SR2A;
- USHORT CLOCK;
-} SiS300_MCLKDataStruct;
-
-static const SiS300_MCLKDataStruct SiS300_MCLKData_630[] =
+static const SiS_MCLKDataStruct SiS300_MCLKData_630[] =
{
{ 0x5a,0x64,0x80, 66},
{ 0xb3,0x45,0x80, 83},
{ 0x37,0x61,0x80,100}
};
-static const SiS300_MCLKDataStruct SiS300_MCLKData_300[] =
+static const SiS_MCLKDataStruct SiS300_MCLKData_300[] =
{
{ 0x68,0x43,0x80,125},
{ 0x68,0x43,0x80,125},
{ 0x37,0x61,0x80,100}
};
-typedef struct _SiS300_VCLKDataStruct
-{
- UCHAR SR2B,SR2C;
- USHORT CLOCK;
-} SiS300_VCLKDataStruct;
-
-static const SiS300_VCLKDataStruct SiS300_VCLKData[] =
+static SiS_VCLKDataStruct SiS300_VCLKData[] =
{
{ 0x1b,0xe1, 25}, /* 0x00 */
{ 0x4e,0xe4, 28}, /* 0x01 */
{ 0x37,0x61,100}, /* 0x43 */ /* 1280x960 LCD */
{ 0xe3,0x9a,106}, /* 0x44 */ /* 1360x1024 - special for Barco iQ R300 */
{ 0xe2,0x46,135}, /* 0x45 */ /* 1280x1024-75, better clock for VGA2 */
- { 0xff,0x00, 0}
-};
-
-static const UCHAR SiS300_ScreenOffset[] =
-{
- 0x14,0x19,0x20,0x28,0x32,0x40,0x50,
- 0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
- 0x55,0x30,0xff
+ { 0, 0, 0} /* 0x46 custom (will be filled out) */
};
#ifndef LINUX_XF86
static UCHAR SiS300_CR49[2];
#endif
-typedef struct _SiS300_PanelDelayTblStruct
-{
- UCHAR timer[2];
-} SiS300_PanelDelayTblStruct;
-
-static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
+static const SiS_PanelDelayTblStruct SiS300_PanelDelayTbl[] =
{
{{0x05,0xaa}},
{{0x05,0x14}},
};
#if 0
-static const SiS300_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
+static const SiS_PanelDelayTblStruct SiS300_PanelDelayTblLVDS[] =
{
{{0x05,0xaa}},
{{0x05,0x14}},
/* SIS VIDEO BRIDGE ----------------------------------------- */
/**************************************************************/
-typedef struct _SiS300_LCDDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS300_LCDDataStruct;
-
-static const SiS300_LCDDataStruct SiS300_StLCD1024x768Data[] =
+static const SiS_LCDDataStruct SiS300_St2LCD1024x768Data[] =
{
- { 66, 31, 992, 510,1320, 816},
- { 66, 31, 992, 510,1320, 816},
- { 176, 75, 900, 510,1320, 816},
- { 176, 75, 900, 510,1320, 816},
- { 66, 31, 992, 510,1320, 816},
- { 27, 16,1024, 650,1350, 832},
+ { 62, 25, 800, 546,1344, 806},
+ { 32, 15, 930, 546,1344, 806},
+ { 32, 15, 930, 546,1344, 806},
+ { 104, 45, 945, 496,1344, 806},
+ { 62, 25, 800, 546,1344, 806},
+ { 31, 18,1008, 624,1344, 806},
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS300_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
+static const SiS_LCDDataStruct SiS300_ExtLCD1024x768Data[] =
{
{ 12, 5, 896, 512,1344, 806},
{ 12, 5, 896, 510,1344, 806},
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS300_LCDDataStruct SiS300_St2LCD1024x768Data[] =
-{
- { 62, 25, 800, 546,1344, 806},
- { 32, 15, 930, 546,1344, 806},
- { 32, 15, 930, 546,1344, 806},
- { 104, 45, 945, 496,1344, 806},
- { 62, 25, 800, 546,1344, 806},
- { 31, 18,1008, 624,1344, 806},
- { 1, 1,1344, 806,1344, 806}
-};
-
-static const SiS300_LCDDataStruct SiS300_StLCD1280x1024Data[] =
+static const SiS_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
{
- { 4, 1, 880, 510,1650,1088},
- { 4, 1, 880, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
{ 176, 45, 900, 510,1650,1088},
{ 176, 45, 900, 510,1650,1088},
- { 4, 1, 880, 510,1650,1088},
+ { 22, 5, 800, 510,1650,1088},
{ 13, 5,1024, 675,1560,1152},
{ 16, 9,1266, 804,1688,1072},
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS300_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
+static const SiS_LCDDataStruct SiS300_ExtLCD1280x1024Data[] =
{
{ 211, 60,1024, 501,1688,1066},
{ 211, 60,1024, 508,1688,1066},
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS300_LCDDataStruct SiS300_St2LCD1280x1024Data[] =
-{
- { 22, 5, 800, 510,1650,1088},
- { 22, 5, 800, 510,1650,1088},
- { 176, 45, 900, 510,1650,1088},
- { 176, 45, 900, 510,1650,1088},
- { 22, 5, 800, 510,1650,1088},
- { 13, 5,1024, 675,1560,1152},
- { 16, 9,1266, 804,1688,1072},
- { 1, 1,1688,1066,1688,1066}
-};
-
-static const SiS300_LCDDataStruct SiS300_NoScaleData1024x768[] =
-{
- { 1, 1, 800, 449, 800, 449},
- { 1, 1, 800, 449, 800, 449},
- { 1, 1, 900, 449, 900, 449},
- { 1, 1, 900, 449, 900, 449},
- { 1, 1, 800, 525, 800, 525},
- { 1, 1,1056, 628,1056, 628},
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1688,1066,1688,1066}
-};
-
-static const SiS300_LCDDataStruct SiS300_NoScaleData1280x1024[] = /* TW: Fake */
-{
- { 1, 1, 800, 449, 800, 449},
- { 1, 1, 800, 449, 800, 449},
- { 1, 1, 900, 449, 900, 449},
- { 1, 1, 900, 449, 900, 449},
- { 1, 1, 800, 525, 800, 525},
- { 1, 1,1056, 628,1056, 628},
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1688,1066,1688,1066}
-};
-
-typedef struct _SiS300_Part2PortTblStruct
-{
- UCHAR CR[12];
-} SiS300_Part2PortTblStruct;
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_1[] =
{ /* VESA Timing */
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
- {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x2c,0x12,0x9a,0xae,0x88,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x21,0x12,0xbf,0xe4,0xc0,0x21,0x45,0x09,0x00,0xa9,0x09,0x04}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}},
+ {{0x22,0x13,0xfe,0x25,0xff,0x21,0x45,0x0a,0x00,0xa9,0x0d,0x04}}
};
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
-{ /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_1[] =
-{ /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_1[] =
-{ /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_2[] =
{ /* Non-VESA */
{{0x28,0x12,0xa3,0xd0,0xaa,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
{{0x2c,0x12,0x9a,0xae,0x88,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}},
{{0x36,0x13,0x13,0x25,0xff,0x5a,0x45,0x0a,0x07,0xfa,0x0a,0x24}}
};
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
{
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
};
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_2[] =
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_1[] =
{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_2[] =
-{ /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1024x768_3[] =
-{ /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
-{ /* TW: Temporary data, invalid */
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
};
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1400x1050_3[] =
-{ /* TW: Temporary data, invalid */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_2[] =
+{
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
};
-static const SiS300_Part2PortTblStruct SiS300_CRT2Part2_1600x1200_3[] =
-{ /* TW: Temporary data, invalid */
+static const SiS_Part2PortTblStruct SiS300_CRT2Part2_1280x1024_3[] =
+{
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
};
/* LVDS/Chrontel -------------------------------------------- */
/**************************************************************/
-typedef struct _SiS300_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS300_LVDSDataStruct;
-
-static const SiS300_LVDSDataStruct SiS300_CHTVUPALData[] =
+static const SiS_LVDSDataStruct SiS300_CHTVUPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{ 936, 836, 936, 836}
};
-static const SiS300_LVDSDataStruct SiS300_CHTVOPALData[] =
+static const SiS_LVDSDataStruct SiS300_CHTVOPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{ 960, 750, 960, 750}
};
-static const SiS300_LVDSDataStruct SiS300_CHTVSOPALData[] =
+static const SiS_LVDSDataStruct SiS300_CHTVSOPALData[] =
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{ 944, 625, 944, 625}
};
-typedef struct _SiS300_LVDSDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDVDES;
-} SiS300_LVDSDesStruct;
-static const SiS300_LVDSDesStruct SiS300_PanelType00_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType00_1[] =
{
{ 1059, 626 }, /* 2.08 */
{ 1059, 624 },
#endif
};
-static const SiS300_LVDSDesStruct SiS300_PanelType01_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType01_1[] =
{
{ 0, 0 }, /* 2.08 */
{ 0, 0 },
#endif
};
-static const SiS300_LVDSDesStruct SiS300_PanelType02_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType02_1[] =
{
{ 1059, 626 }, /* 2.08 */
{ 1059, 624 },
#endif
};
-static const SiS300_LVDSDesStruct SiS300_PanelType03_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType03_1[] =
{
{ 8, 436},
{ 8, 440},
{1343, 794}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */
+static const SiS_LVDSDesStruct SiS300_PanelType04_1[] = /* 1280x1024 */
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType05_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType05_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType06_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType06_1[] = /* Clevo Trumpion 1024x768 */
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType07_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType07_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType08_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType08_1[] =
{
{1059, 626},
{1059, 624},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType09_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType09_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0a_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0a_1[] =
{
{1059, 626},
{1059, 624},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0b_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0b_1[] =
{
{1343, 0},
{1343, 0},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0c_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0c_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0d_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0d_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0e_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0e_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0} /* 1280x960 - not applicable */
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0f_1[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0f_1[] =
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType00_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType00_2[] =
{
{976, 527},
{976, 502},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType01_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType01_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType02_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType02_2[] =
{
{976, 527},
{976, 502},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType03_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType03_2[] =
{
{1152, 622},
{1152, 597},
{1152, 597}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType04_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType04_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType05_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType05_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType06_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType06_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType07_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType07_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType08_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType08_2[] =
{
{976, 527},
{976, 502},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType09_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType09_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0a_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0a_2[] =
{
{976, 527},
{976, 502},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0b_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0b_2[] =
{
{ 1152, 700},
{ 1152, 675},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0c_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0c_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0d_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0d_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0e_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0e_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS300_LVDSDesStruct SiS300_PanelType0f_2[] =
+static const SiS_LVDSDesStruct SiS300_PanelType0f_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
+static const SiS_LVDSDesStruct SiS300_PanelTypeNS_1[]=
+{
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 805},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0}
+};
+
+static const SiS_LVDSDesStruct SiS300_PanelTypeNS_2[] =
+{
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
-static const SiS300_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
+static const SiS_LVDSDesStruct SiS300_PanelType04_1a[] = /* 1280x1024 (1366x1024) */
{
{1330, 798}, /* 320x200 */
{1330, 794},
{ 0, 0} /* 1360x1024 */
};
-static const SiS300_LVDSDesStruct SiS300_PanelType04_2a[] =
+static const SiS_LVDSDesStruct SiS300_PanelType04_2a[] =
{
{1152, 622},
{1152, 597},
};
/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
-static const SiS300_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
+static const SiS_LVDSDesStruct SiS300_PanelType04_1b[] = /* 1024x768 */
{
{1330, 798}, /* 320x200 */
{1330, 794},
{ 0, 805} /* 1024x768 / 512x384 */
};
-static const SiS300_LVDSDesStruct SiS300_PanelType04_2b[] =
+static const SiS_LVDSDesStruct SiS300_PanelType04_2b[] =
{
{1152, 622},
{1152, 597},
/* CRT1 CRTC for slave modes */
-typedef struct _SiS300_LVDSCRT1DataStruct
-{
-UCHAR CR[15];
-} SiS300_LVDSCRT1DataStruct;
-
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1[] =
{
{{0x65,0x4f,0x89,0x56,0x83,0xaf,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_1_H[] =
{
{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1[] =
{
{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
0x01}}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_1_H[] =
{
{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
#endif
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1[] =
{
{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_1_H[] =
{
{{0x2f,0x27,0x93,0x2b,0x90,0xb4,0x1f,
0x92,0x89,0x8f,0xb5,0x30,0x00,0x04,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2[] =
{
{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
0xf4,0x88,0x8f,0x73,0x20,0x00,0x06,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1800x600_2_H[] =
{
{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2[] =
{
{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11024x768_2_H[] =
{
{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2[] =
{
{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT11280x1024_2_H[] =
{
{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
0x01}}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+ 0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+ 0x01}},
+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct SiS300_LVDSCRT1XXXxXXX_1_H[] =
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+ 0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+
+static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UNTSC[] =
{
{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
+static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1ONTSC[] =
{
{{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
+static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1UPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
+static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1OPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
0x01 }}
};
-static const SiS300_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
+static const SiS_LVDSCRT1DataStruct SiS300_CHTVCRT1SOPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
0x01 }}
};
-typedef struct _SiS300_CHTVRegDataStruct
-{
- UCHAR Reg[16];
-} SiS300_CHTVRegDataStruct;
-
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UNTSC[] =
{
{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
{{0x4a,0x94,0x00,0x48,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
{{0x8d,0xc4,0x00,0x3b,0xfb,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 24: 800x600 NTSC 7/10 */
};
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_ONTSC[] =
{
{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
{{0x49,0x94,0x00,0x34,0xfe,0,0,0,0,0,0,0,0,0,0,0}},
{{0x8c,0xb4,0x00,0x32,0xf9,0,0,0,0,0,0,0,0,0,0,0}} /* Mode 23: 800x600 NTSC 3/4 */
};
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_UPAL[] =
{
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
};
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_OPAL[] =
{
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
};
-static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
+static const SiS_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
{
{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Register settings for SiS 315/330 series
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
*
*/
-typedef struct _SiS310_StStruct
-{
- UCHAR St_ModeID;
- USHORT St_ModeFlag;
- UCHAR St_StTableIndex;
- UCHAR St_CRT2CRTC;
- UCHAR St_ResInfo;
- UCHAR VB_StTVFlickerIndex;
- UCHAR VB_StTVEdgeIndex;
- UCHAR VB_StTVYFilterIndex;
- UCHAR St_PDC;
-} SiS310_StStruct;
-
-static const SiS310_StStruct SiS310_SModeIDTable[]=
+static const SiS_StStruct SiS310_SModeIDTable[]=
{
{0x01,0x9208,0x01,0x00,0x00,0x00,0x01,0x00, 0x40},
{0x01,0x1210,0x14,0x01,0x01,0x00,0x01,0x00, 0x40},
{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00, 0x40}
};
-typedef struct _SiS310_ExtStruct
-{
- UCHAR Ext_ModeID;
- USHORT Ext_ModeFlag;
- UCHAR Ext_ModeOffset;
- USHORT Ext_VESAID;
- UCHAR Ext_RESINFO;
- UCHAR VB_ExtTVFlickerIndex;
- UCHAR VB_ExtTVEdgeIndex;
- UCHAR VB_ExtTVYFilterIndex;
- UCHAR VB_ExtTVYFilterIndexROM661;
- UCHAR REFindex;
-} SiS310_ExtStruct;
-
-static const SiS310_ExtStruct SiS310_EModeIDTable[]=
-{
- {0x6a,0x2212,0x04,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00}, /* 800x600x? */
- {0x2e,0x0a1b,0x03,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08}, /* 640x480x8 */
- {0x2f,0x0a1b,0x03,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10}, /* 640x400x8 */
- {0x30,0x2a1b,0x04,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00}, /* 800x600x8 */
- {0x31,0x0a1b,0x0a,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11}, /* 720x480x8 */
- {0x32,0x0a1b,0x0a,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12}, /* 720x576x8 */
- {0x33,0x0a1d,0x0a,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11}, /* 720x480x16 */
- {0x34,0x2a1d,0x0a,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12}, /* 720x576x16 */
- {0x35,0x0a1f,0x0a,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11}, /* 720x480x32 */
- {0x36,0x2a1f,0x0a,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12}, /* 720x576x32 */
- {0x37,0x0212,0x05,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x? */
- {0x38,0x0a1b,0x05,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x8 */
- {0x3a,0x0e3b,0x06,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
- {0x3c,0x0e3b,0x07,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
- {0x3d,0x0e7d,0x07,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
- {0x40,0x9a1c,0x00,0x010d,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25}, /* 320x200x15 */
- {0x41,0x9a1d,0x00,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25}, /* 320x200x16 */
- {0x43,0x0a1c,0x03,0x0110,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08},
- {0x44,0x0a1d,0x03,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08}, /* 640x480x16 */
- {0x46,0x2a1c,0x04,0x0113,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00},
- {0x47,0x2a1d,0x04,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00}, /* 800x600x16 */
- {0x49,0x0a3c,0x05,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13},
- {0x4a,0x0a3d,0x05,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x16 */
- {0x4c,0x0e7c,0x06,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a},
- {0x4d,0x0e7d,0x06,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
- {0x50,0x9a1b,0x00,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26}, /* 320x240x8 */
- {0x51,0xba1b,0x01,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27}, /* 400x300x8 */
- {0x52,0xba1b,0x02,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28}, /* 512x384x8 */
- {0x56,0x9a1d,0x00,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26}, /* 320x240x16 */
- {0x57,0xba1d,0x01,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27}, /* 400x300x16 */
- {0x58,0xba1d,0x02,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28}, /* 512x384x16 */
- {0x59,0x9a1b,0x00,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25}, /* 320x200x8 */
- {0x5a,0x021b,0x00,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f}, /* 320x240x8 fstn */
- {0x5b,0x0a1d,0x00,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f}, /* 320x240x16 fstn */
- {0x5c,0xba1f,0x02,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28}, /* 512x384x32 */
- {0x5d,0x0a1d,0x03,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10},
- {0x5e,0x0a1f,0x03,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10}, /* 640x400x32 */
- {0x62,0x0a3f,0x03,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08}, /* 640x480x32 */
- {0x63,0x2a3f,0x04,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00}, /* 800x600x32 */
- {0x64,0x0a7f,0x05,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13}, /* 1024x768x32 */
- {0x65,0x0eff,0x06,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
- {0x66,0x0eff,0x07,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
- {0x68,0x067b,0x08,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
- {0x69,0x06fd,0x08,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
- {0x6b,0x07ff,0x08,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
- {0x6c,0x067b,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
- {0x6d,0x06fd,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
- {0x6e,0x07ff,0x09,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
- {0x70,0x2a1b,0x04,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34}, /* 800x480x8 */
- {0x71,0x0a1b,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x8 */
- {0x74,0x0a1d,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x16 */
- {0x75,0x0a3d,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
- {0x76,0x2a1f,0x04,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34}, /* 800x480x32 */
- {0x77,0x0a1f,0x05,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37}, /* 1024x576x32 */
- {0x78,0x0a3f,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
- {0x79,0x0a3b,0x06,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
- {0x7a,0x2a1d,0x04,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34}, /* 800x480x16 */
- {0x7c,0x0e3b,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
- {0x7d,0x0e7d,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
- {0x7e,0x0eff,0x06,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
- {0x23,0x0e3b,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x8 */
- {0x24,0x0e7d,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x16 */
- {0x25,0x0eff,0x06,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40}, /* 1280x768x32 */
- {0x26,0x0e3b,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
- {0x27,0x0e7d,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
- {0x28,0x0eff,0x0c,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
- {0x29,0x0e1b,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43}, /* 1152x864 */
- {0x2a,0x0e3d,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43},
- {0x2b,0x0e7f,0x0d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43},
- {0x39,0x2a1b,0x0b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x45}, /* 848x480 */
- {0x3b,0x2a3d,0x0b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x45},
- {0x3e,0x2a7f,0x0b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x45},
- {0x3f,0x2a1b,0x0b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x47}, /* 856x480 */
- {0x42,0x2a3d,0x0b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x47},
- {0x45,0x2a7f,0x0b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x47},
- {0x48,0x2a1b,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49}, /* 1360x768 */
- {0x4b,0x2a3d,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49},
- {0x4e,0x2a7f,0x0e,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49},
- {0x4f,0x9a1f,0x00,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25}, /* 320x200x32 */
- {0x53,0x9a1f,0x00,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26}, /* 320x240x32 */
- {0x54,0xba1f,0x01,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27}, /* 400x300x32 */
- {0x5f,0x2a1b,0x0f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4a}, /* 768x576x8 */
- {0x60,0x2a1d,0x0f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4a}, /* 768x576x16 */
- {0x61,0x2a1f,0x0f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4a}, /* 768x576x32 */
- {0xff,0x0000,0x00,0x0000,0, 0x00,0x00,0x00,0x00,0x00}
-};
-
-typedef struct _SiS310_Ext2Struct
-{
- USHORT Ext_InfoFlag;
- UCHAR Ext_CRT1CRTC;
- UCHAR Ext_CRTVCLK;
- UCHAR Ext_CRT2CRTC;
- UCHAR ModeID;
- USHORT XRes;
- USHORT YRes;
- UCHAR Ext_PDC;
-} SiS310_Ext2Struct;
-
-static const SiS310_Ext2Struct SiS310_RefIndex[]=
-{
- {0x085f,0x0d,0x03,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
- {0x0067,0x0e,0x04,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
- {0x0067,0x0f,0x08,0x48,0x6a, 800, 600, 0x40}, /* 0x2 */
- {0x0067,0x10,0x07,0x8b,0x6a, 800, 600, 0x40}, /* 0x3 */
- {0x0047,0x11,0x0a,0x00,0x6a, 800, 600, 0x40}, /* 0x4 */
- {0x0047,0x12,0x0d,0x00,0x6a, 800, 600, 0x40}, /* 0x5 */
- {0x0047,0x13,0x13,0x00,0x6a, 800, 600, 0x20}, /* 0x6 */
- {0x0107,0x14,0x1c,0x00,0x6a, 800, 600, 0x20}, /* 0x7 */
- {0xc85f,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
- {0xc067,0x06,0x02,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
- {0xc067,0x07,0x02,0x47,0x2e, 640, 480, 0x40}, /* 0xa */
- {0xc067,0x08,0x03,0x8a,0x2e, 640, 480, 0x40}, /* 0xb */
- {0xc047,0x09,0x05,0x00,0x2e, 640, 480, 0x40}, /* 0xc */
- {0xc047,0x0a,0x09,0x00,0x2e, 640, 480, 0x40}, /* 0xd */
- {0xc047,0x0b,0x0e,0x00,0x2e, 640, 480, 0x40}, /* 0xe */
- {0xc047,0x0c,0x15,0x00,0x2e, 640, 480, 0x40}, /* 0xf */
- {0x487f,0x04,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
- {0xc04f,0x3c,0x01,0x06,0x31, 720, 480, 0x30}, /* 0x11 */
- {0x004f,0x3d,0x03,0x06,0x32, 720, 576, 0x30}, /* 0x12 */
- {0x0087,0x15,0x06,0x00,0x37,1024, 768, 0x30}, /* 0x13 */
- {0xc877,0x16,0x0b,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
- {0xc067,0x17,0x0f,0x49,0x37,1024, 768, 0x20}, /* 0x15 */
- {0x0067,0x18,0x11,0x00,0x37,1024, 768, 0x20}, /* 0x16 */
- {0x0047,0x19,0x16,0x8c,0x37,1024, 768, 0x20}, /* 0x17 */
- {0x0107,0x1a,0x1b,0x00,0x37,1024, 768, 0x10}, /* 0x18 */
- {0x0107,0x1b,0x1f,0x00,0x37,1024, 768, 0x10}, /* 0x19 */
- {0x0087,0x1c,0x11,0x00,0x3a,1280,1024, 0x30}, /* 0x1a */
- {0x0137,0x1d,0x19,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
- {0x0107,0x1e,0x1e,0x00,0x3a,1280,1024, 0x00}, /* 0x1c */
- {0x0207,0x1f,0x20,0x00,0x3a,1280,1024, 0x00}, /* 0x1d */
- {0x0227,0x20,0x21,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
- {0x0407,0x21,0x22,0x00,0x3c,1600,1200, 0x00}, /* 0x1f */
- {0x0407,0x22,0x23,0x00,0x3c,1600,1200, 0x00}, /* 0x20 */
- {0x0407,0x23,0x25,0x00,0x3c,1600,1200, 0x00}, /* 0x21 */
- {0x0007,0x24,0x26,0x00,0x3c,1600,1200, 0x00}, /* 0x22 */
- {0x0007,0x25,0x2c,0x00,0x3c,1600,1200, 0x00}, /* 0x23 */
- {0x0007,0x26,0x34,0x00,0x3c,1600,1200, 0x00}, /* 0x24 */
- {0x407f,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
- {0xc07f,0x01,0x00,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
- {0x007f,0x02,0x04,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
- {0xc077,0x03,0x0b,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
- {0x8007,0x27,0x27,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
- {0x4007,0x28,0x29,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
- {0x4007,0x29,0x2e,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
- {0x4007,0x2a,0x30,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
- {0x4007,0x2b,0x35,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
- {0x4005,0x2c,0x39,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
- {0x4007,0x2d,0x2b,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
- {0x4007,0x2e,0x31,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
- {0x4007,0x2f,0x33,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
- {0x4007,0x30,0x37,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
- {0x4005,0x31,0x38,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
- {0x0057,0x32,0x40,0x08,0x70, 800, 480, 0x30}, /* 0x34 */
- {0x0047,0x33,0x07,0x08,0x70, 800, 480, 0x30}, /* 0x35 */
- {0x0047,0x34,0x0a,0x08,0x70, 800, 480, 0x30}, /* 0x36 */
- {0x0057,0x35,0x0b,0x09,0x71,1024, 576, 0x30}, /* 0x37 */
- {0x0047,0x36,0x11,0x09,0x71,1024, 576, 0x30}, /* 0x38 */
- {0x0047,0x37,0x16,0x09,0x71,1024, 576, 0x30}, /* 0x39 */
- {0x0117,0x38,0x19,0x0a,0x75,1280, 720, 0x30}, /* 0x3a */
- {0x0107,0x39,0x1e,0x0a,0x75,1280, 720, 0x30}, /* 0x3b */
- {0x0207,0x3a,0x20,0x0a,0x75,1280, 720, 0x30}, /* 0x3c */
- {0x0127,0x3b,0x19,0x08,0x7c,1280, 960, 0x30}, /* 0x3d */
- {0x0227,0x4c,0x59,0x08,0x7c,1280, 960, 0x20}, /* 0x3e */
- {0xc07f,0x4e,0x00,0x06,0x5a, 320, 240, 0x30}, /* 0x3f */ /* FSTN 320x240 */
- {0x0077,0x42,0x5b,0x08,0x23,1280, 768, 0x30}, /* 0x40 */ /* TW: 0x5b was 0x12 */
- {0x0127,0x43,0x4d,0x08,0x26,1400,1050, 0x30}, /* 0x41 */
- {0x0207,0x4b,0x5a,0x08,0x26,1400,1050, 0x30}, /* 0x42 Non-BIOS, new */
- {0x0107,0x44,0x19,0x00,0x29,1152, 864, 0x30}, /* 0x43 Non-BIOS, new */
- {0x0107,0x4a,0x1e,0x00,0x29,1152, 864, 0x30}, /* 0x44 Non-BIOS, new */
- {0x0087,0x45,0x57,0x00,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi - Non-BIOS, new */
- {0xc067,0x46,0x55,0x0b,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz - Non-BIOS, new */
- {0x0087,0x47,0x57,0x00,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi - Non-BIOS, new */
- {0xc047,0x48,0x57,0x00,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz - Non-BIOS, new */
- {0x0067,0x49,0x58,0x0c,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz - Non-BIOS, new */
- {0x004f,0x4d,0x03,0x06,0x5f, 768, 576, 0x30}, /* 0x4a 768x576 */
- {0xffff,0x00,0x00,0x00,0x00, 0, 0, 0}
-};
-
-typedef struct _SiS310_CRT1TableStruct
-{
- UCHAR CR[17];
-} SiS310_CRT1TableStruct;
-
-static const SiS310_CRT1TableStruct SiS310_CRT1Table[]=
+static const SiS_ExtStruct SiS310_EModeIDTable[]=
+{
+ {0x6a,0x2212,0x0102,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x? */
+ {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */
+ {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */
+ {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */
+ {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */
+ {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */
+ {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */
+ {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */
+ {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */
+ {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */
+ {0x37,0x0212,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x? */
+ {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */
+ {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x8 */
+ {0x3c,0x0e3b,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x8 */
+ {0x3d,0x0e7d,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x16 */
+ {0x40,0x9a1c,0x010d,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x15 */
+ {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x16 */
+ {0x43,0x0a1c,0x0110,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2},
+ {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */
+ {0x46,0x2a1c,0x0113,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3},
+ {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */
+ {0x49,0x0a3c,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x07,0x13, 4},
+ {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */
+ {0x4c,0x0e7c,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8},
+ {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x16 */
+ {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x8 */
+ {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x8 */
+ {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x8 */
+ {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x16 */
+ {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x16 */
+ {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x16 */
+ {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x8 */
+ {0x5a,0x021b,0x0138,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x8 fstn */
+ {0x5b,0x0a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x00,0x00,0x3f, 2}, /* 320x240x16 fstn */
+ {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x28, 4}, /* 512x384x32 */
+ {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0},
+ {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */
+ {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */
+ {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */
+ {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */
+ {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x1a, 8}, /* 1280x1024x32 */
+ {0x66,0x0eff,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x00,0x1e,10}, /* 1600x1200x32 */
+ {0x68,0x067b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x8 */
+ {0x69,0x06fd,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x16 */
+ {0x6b,0x07ff,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x00,0x29,-1}, /* 1920x1440x32 */
+ {0x6c,0x067b,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x8 */
+ {0x6d,0x06fd,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x16 */
+ {0x6e,0x07ff,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x00,0x2f,-1}, /* 2048x1536x32 */
+ {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x8 */
+ {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x8 */
+ {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x16 */
+ {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x16 */
+ {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x32 */
+ {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x37,-1}, /* 1024x576x32 */
+ {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x32 */
+ {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x3a, 5}, /* 1280x720x8 */
+ {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x34,-1}, /* 800x480x16 */
+ {0x7c,0x0e3b,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x8 */
+ {0x7d,0x0e7d,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x16 */
+ {0x7e,0x0eff,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x00,0x3d,-1}, /* 1280x960x32 */
+ {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x8 */
+ {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x16 */
+ {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x40, 6}, /* 1280x768x32 */
+ {0x26,0x0e3b,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x8 */
+ {0x27,0x0e7d,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x16 */
+ {0x28,0x0eff,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x00,0x41, 9}, /* 1400x1050x32*/
+ {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1}, /* 1152x864 */
+ {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
+ {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x43,-1},
+ {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x45,-1}, /* 848x480 */
+ {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x45,-1},
+ {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x45,-1},
+ {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x47,-1}, /* 856x480 */
+ {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x47,-1},
+ {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x47,-1},
+ {0x48,0x6a3b,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1}, /* 1360x768 */
+ {0x4b,0x6a7d,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
+ {0x4e,0x6aff,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x00,0x49,-1},
+ {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x25, 0}, /* 320x200x32 */
+ {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x26, 2}, /* 320x240x32 */
+ {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x27, 3}, /* 400x300x32 */
+ {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4a,-1}, /* 768x576 */
+ {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4a,-1},
+ {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x4a,-1},
+ {0x14,0x0e3b,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7}, /* 1280x800 */
+ {0x15,0x0e7d,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
+ {0x16,0x0eff,0x0000,SIS_RI_1280x800, 0x00,0x00,0x00,0x00,0x4b, 7},
+ {0x17,0x0e3b,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9}, /* 1680x1050 */
+ {0x18,0x0e7d,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
+ {0x19,0x0eff,0x0000,SIS_RI_1680x1050,0x00,0x00,0x00,0x00,0x4c, 9},
+ {0x2c,0x267b,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1}, /* 1920x1080(i) */
+ {0x2d,0x26fd,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
+ {0x73,0x27ff,0x0000,SIS_RI_1920x1080,0x00,0x00,0x00,0x00,0x4d,-1},
+ {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4e,-1}, /* 960x540 */
+ {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4e,-1},
+ {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x4e,-1},
+ {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1}
+};
+
+static const SiS_Ext2Struct SiS310_RefIndex[]=
+{
+ {0x085f,0x0d,0x03,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x0 */
+ {0x0067,0x0e,0x04,0x05,0x05,0x6a, 800, 600, 0x40}, /* 0x1 */
+ {0x0067,0x0f,0x08,0x48,0x05,0x6a, 800, 600, 0x40}, /* 0x2 */
+ {0x0067,0x10,0x07,0x8b,0x05,0x6a, 800, 600, 0x40}, /* 0x3 */
+ {0x0047,0x11,0x0a,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x4 */
+ {0x0047,0x12,0x0d,0x00,0x05,0x6a, 800, 600, 0x40}, /* 0x5 */
+ {0x0047,0x13,0x13,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x6 */
+ {0x0107,0x14,0x1c,0x00,0x05,0x6a, 800, 600, 0x20}, /* 0x7 */
+ {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x8 */
+ {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40}, /* 0x9 */
+ {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40}, /* 0xa */
+ {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40}, /* 0xb */
+ {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xc */
+ {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xd */
+ {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xe */
+ {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40}, /* 0xf */
+ {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30}, /* 0x10 */
+ {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30}, /* 0x11 */
+ {0x006f,0x3d,0x03,0x06,0x14,0x32, 720, 576, 0x30}, /* 0x12 */
+ {0x0087,0x15,0x06,0x00,0x06,0x37,1024, 768, 0x30}, /* 0x13 */
+ {0xc877,0x16,0x0b,0x06,0x06,0x37,1024, 768, 0x20}, /* 0x14 */
+ {0xc067,0x17,0x0f,0x49,0x06,0x37,1024, 768, 0x20}, /* 0x15 */
+ {0x0067,0x18,0x11,0x00,0x06,0x37,1024, 768, 0x20}, /* 0x16 */
+ {0x0047,0x19,0x16,0x8c,0x06,0x37,1024, 768, 0x20}, /* 0x17 */
+ {0x0107,0x1a,0x1b,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x18 */
+ {0x0107,0x1b,0x1f,0x00,0x06,0x37,1024, 768, 0x10}, /* 0x19 */
+ {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30}, /* 0x1a */
+ {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00}, /* 0x1b */
+ {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1c */
+ {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00}, /* 0x1d */
+ {0x0227,0x20,0x21,0x09,0x09,0x3c,1600,1200, 0x00}, /* 0x1e */
+ {0x0407,0x21,0x22,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x1f */
+ {0x0407,0x22,0x23,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x20 */
+ {0x0407,0x23,0x25,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x21 */
+ {0x0007,0x24,0x26,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x22 */
+ {0x0007,0x25,0x2c,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x23 */
+ {0x0007,0x26,0x34,0x00,0x09,0x3c,1600,1200, 0x00}, /* 0x24 */
+ {0x407f,0x00,0x00,0x00,0x00,0x40, 320, 200, 0x30}, /* 0x25 */
+ {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30}, /* 0x26 */
+ {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30}, /* 0x27 */
+ {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30}, /* 0x28 */
+ {0x8007,0x27,0x27,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x29 */
+ {0x4007,0x28,0x29,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2a */
+ {0x4007,0x29,0x2e,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2b */
+ {0x4007,0x2a,0x30,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2c */
+ {0x4007,0x2b,0x35,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2d */
+ {0x4005,0x2c,0x39,0x00,0x00,0x68,1920,1440, 0x00}, /* 0x2e */
+ {0x4007,0x2d,0x2b,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x2f */
+ {0x4007,0x2e,0x31,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x30 */
+ {0x4007,0x2f,0x33,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x31 */
+ {0x4007,0x30,0x37,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x32 */
+ {0x4005,0x31,0x38,0x00,0x00,0x6c,2048,1536, 0x00}, /* 0x33 */
+ {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x34 */
+ {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x35 */
+ {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30}, /* 0x36 */
+ {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x37 */
+ {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x38 */
+ {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30}, /* 0x39 */
+ {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3a */
+ {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3b */
+ {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30}, /* 0x3c */
+ {0x0127,0x3b,0x19,0x08,0x0a,0x7c,1280, 960, 0x30}, /* 0x3d */
+ {0x0227,0x4c,0x59,0x08,0x0a,0x7c,1280, 960, 0x20}, /* 0x3e */
+ {0xc07f,0x4e,0x00,0x06,0x04,0x5a, 320, 240, 0x30}, /* 0x3f */ /* FSTN 320x240 */
+ {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30}, /* 0x40 */ /* 0x5b was 0x12 */
+ {0x0127,0x43,0x4d,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x41 */
+ {0x0207,0x4b,0x5a,0x08,0x0b,0x26,1400,1050, 0x30}, /* 0x42 1400x1050-75Hz */
+ {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x43 1152x864-75Hz */
+ {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30}, /* 0x44 1152x864-85Hz */
+ {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30}, /* 0x45 848x480-38Hzi */
+ {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30}, /* 0x46 848x480-60Hz */
+ {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x47 856x480-38Hzi */
+ {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30}, /* 0x48 856x480-60Hz */
+ {0x0067,0x49,0x58,0x0c,0x1b,0x48,1360, 768, 0x30}, /* 0x49 1360x768-60Hz */
+ {0x006f,0x4d,0x03,0x06,0x15,0x5f, 768, 576, 0x30}, /* 0x4a 768x576-56Hz */
+ {0x0067,0x4f,0x5c,0x08,0x0d,0x14,1280, 800, 0x30}, /* 0x4b 1280x800-60Hz */
+ {0x0067,0x50,0x5d,0x0c,0x0e,0x17,1680,1050, 0x30}, /* 0x4c 1680x1050-60Hz */
+ {0x0087,0x51,0x69,0x00,0x00,0x2c,1920,1080, 0x30}, /* 0x4d 1920x1080 60Hzi */
+ {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30}, /* 0x4e 960x540 60Hz */
+ {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0}
+};
+
+static const SiS_CRT1TableStruct SiS310_CRT1Table[]=
{
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
{{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
0x00}}, /* 0x5 */
-#endif
+#endif
{{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, /* 0x05 - corrected 640x480-60 */
0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
0x00}},
0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05,
0x00}}, /* 0x8 */
{{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f,
- 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* TW: Corrected VBE */
+ 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, /* Corrected VBE */
0x61}}, /* 0x9 */
{{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e,
0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05,
0x61}}, /* 0xa */
{{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e,
- 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* TW: Corrected VBE */
+ 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, /* Corrected VBE */
0x61}}, /* 0xb */
{{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f,
- 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* TW: Corrected VDE, VBE */
+ 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, /* Corrected VDE, VBE */
0x00}}, /* 0xc */
{{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0,
0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05,
{{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
0x01}}, /* 0x36 */
- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* TW: 95 was 15 - illegal HBE! */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, /* 95 was 15 - illegal HBE! */
0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
0x01}}, /* 0x37 */
{{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
{{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e,
0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02,
0x00}}, /* 0x3f */
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, /* TW: The following from 650/LVDS BIOS */
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,
0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
0x01}}, /* 0x40 */
{{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
{{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10,
0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03,
0x00}}, /* 0x43 */
- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* New, 1152x864-75, not in BIOS */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, /* 1152x864-75 */
0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
0x01}}, /* 0x44 */
- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* New, 848x480-38i, not in BIOS */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, /* 848x480-38i */
0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
0x00}}, /* 0x45 */
- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* New, 848x480-60, not in BIOS */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, /* 848x480-60 */
0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
0x00}}, /* 0x46 */
- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* New, 856x480-38i, not in BIOS */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, /* 856x480-38i */
0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
0x00}}, /* 0x47 */
- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* New, 856x480-60, not in BIOS */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, /* 856x480-60 */
0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
0x00}}, /* 0x48 */
- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* New, 1360x768-60, not in BIOS */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, /* 1360x768-60 */
0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
0x01}}, /* 0x49 */
- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* New, 1152x864-84, not in any BIOS */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, /* 1152x864-84 */
0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
0x01}}, /* 0x4a */
- {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* New, 1400x1050-75, not in any BIOS */
+ {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, /* 1400x1050-75 */
0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03,
0x00}}, /* 0x4b */
- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* New, 1280x960-85, not in any BIOS */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* 1280x960-85 */
0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
0x01}}, /* 0x4c */
{{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
0x01}}, /* 0x4d */
{{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
- 0x00}} /* 0x4e */
-};
-
-typedef struct _SiS310_MCLKDataStruct
-{
- UCHAR SR28,SR29,SR2A;
- USHORT CLOCK;
-} SiS310_MCLKDataStruct;
-
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
+ 0x00}}, /* 0x4e */
+ {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, /* 1280x800-60 */
+ 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07,
+ 0x21}}, /* 0x4f */
+ {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, /* 1680x1050-60 */
+ 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c,
+ 0x20}}, /* 0x50 */
+ {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, /* 1920x1080-60i */
+ 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00,
+ 0x61}}, /* 0x51 */
+ {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, /* 960x540-60 */
+ 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02,
+ 0x41}} /* 0x52 */
+};
+
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_315[] =
{
{ 0x3b,0x22,0x01,143},
{ 0x5c,0x23,0x01,166},
{ 0x5c,0x23,0x01,166}
};
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_650[] =
{
{ 0x5a,0x64,0x82, 66},
{ 0xb3,0x45,0x82, 83},
{ 0x37,0x22,0x82,133}
};
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_330[] =
{
{ 0x5c,0x23,0x01,166},
{ 0x5c,0x23,0x01,166},
{ 0x79,0x06,0x01,250}
};
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] = /* TODO */
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_660[] =
{
{ 0x5c,0x23,0x82,166},
{ 0x5c,0x23,0x82,166},
{ 0x37,0x21,0x82,200}
};
-static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
+static const SiS_MCLKDataStruct SiS310_MCLKData_0_760[] =
+{
+ { 0x37,0x22,0x82,133},
+ { 0x5c,0x23,0x82,166},
+ { 0x65,0x23,0x82,183},
+ { 0x7c,0x08,0x82,200},
+ { 0x29,0x21,0x82,150},
+ { 0x5c,0x23,0x82,166},
+ { 0x65,0x23,0x82,183},
+ { 0x37,0x21,0x82,200}
+};
+
+static const SiS_MCLKDataStruct SiS310_MCLKData_1[] = /* ECLK */
{
{ 0x29,0x21,0x82,150},
{ 0x5c,0x23,0x82,166},
{ 0x37,0x22,0x82,133}
};
-typedef struct _SiS310_VCLKDataStruct
-{
- UCHAR SR2B,SR2C;
- USHORT CLOCK;
-} SiS310_VCLKDataStruct;
-
-static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
+static SiS_VCLKDataStruct SiS310_VCLKData[]=
{
{ 0x1b,0xe1, 25}, /* 0x00 */
{ 0x4e,0xe4, 28}, /* 0x01 */
{ 0x53,0xe2, 50}, /* 0x08 */
{ 0x74,0x67, 52}, /* 0x09 */
{ 0x6d,0x66, 56}, /* 0x0a */
- { 0x5a,0x64, 65}, /* 0x0b */ /* TW: was 6c c3 - WRONG */
+ { 0x5a,0x64, 65}, /* 0x0b */ /* was 6c c3 - WRONG */
{ 0x46,0x44, 67}, /* 0x0c */
{ 0xb1,0x46, 68}, /* 0x0d */
{ 0xd3,0x4a, 72}, /* 0x0e */
{ 0xea,0x08,340}, /* 0x37 */
{ 0xe8,0x07,376}, /* 0x38 */
{ 0xde,0x06,389}, /* 0x39 */
- { 0x52,0x2a, 54}, /* 0x3a */ /* 301 TV */
- { 0x52,0x6a, 27}, /* 0x3b */ /* 301 TV */
- { 0x62,0x24, 70}, /* 0x3c */ /* 301 TV */
- { 0x62,0x64, 70}, /* 0x3d */ /* 301 TV */
- { 0xa8,0x4c, 30}, /* 0x3e */ /* 301 TV */
- { 0x20,0x26, 33}, /* 0x3f */ /* 301 TV */
+ { 0x52,0x2a, 54}, /* 0x3a 301 TV */
+ { 0x52,0x6a, 27}, /* 0x3b 301 TV */
+ { 0x62,0x24, 70}, /* 0x3c 301 TV */
+ { 0x62,0x64, 70}, /* 0x3d 301 TV */
+ { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
+ { 0x20,0x26, 33}, /* 0x3f 301 TV */
{ 0x31,0xc2, 39}, /* 0x40 */
- { 0x60,0x36, 30}, /* 0x41 */ /* Chrontel */
- { 0x40,0x4a, 28}, /* 0x42 */ /* Chrontel */
- { 0x9f,0x46, 44}, /* 0x43 */ /* Chrontel */
+ { 0x60,0x36, 30}, /* 0x41 Chrontel */
+ { 0x40,0x4a, 28}, /* 0x42 Chrontel */
+ { 0x9f,0x46, 44}, /* 0x43 Chrontel */
{ 0x97,0x2c, 26}, /* 0x44 */
- { 0x44,0xe4, 25}, /* 0x45 */ /* Chrontel */
- { 0x7e,0x32, 47}, /* 0x46 */ /* Chrontel */
- { 0x8a,0x24, 31}, /* 0x47 */ /* Chrontel */
- { 0x97,0x2c, 26}, /* 0x48 */ /* Chrontel */
+ { 0x44,0xe4, 25}, /* 0x45 Chrontel */
+ { 0x7e,0x32, 47}, /* 0x46 Chrontel */
+ { 0x8a,0x24, 31}, /* 0x47 Chrontel */
+ { 0x97,0x2c, 26}, /* 0x48 Chrontel */
{ 0xce,0x3c, 39}, /* 0x49 */
- { 0x52,0x4a, 36}, /* 0x4a */ /* Chrontel */
+ { 0x52,0x4a, 36}, /* 0x4a Chrontel */
{ 0x34,0x61, 95}, /* 0x4b */
{ 0x78,0x27,108}, /* 0x4c - was 102 */
- { 0x66,0x43,123}, /* 0x4d */ /* Modes 0x26-0x28 (1400x1050) */
+ { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */
{ 0x41,0x4e, 21}, /* 0x4e */
- { 0xa1,0x4a, 29}, /* 0x4f */ /* Chrontel */
+ { 0xa1,0x4a, 29}, /* 0x4f Chrontel */
{ 0x19,0x42, 42}, /* 0x50 */
- { 0x54,0x46, 58}, /* 0x51 */ /* Chrontel */
+ { 0x54,0x46, 58}, /* 0x51 Chrontel */
{ 0x25,0x42, 61}, /* 0x52 */
- { 0x44,0x44, 66}, /* 0x53 */ /* Chrontel */
- { 0x3a,0x62, 70}, /* 0x54 */ /* Chrontel */
- { 0x62,0xc6, 34}, /* 0x55 - added for 848x480-60 (not in any BIOS) */
- { 0x6a,0xc6, 37}, /* 0x56 - added for 848x480-75 (not in any BIOS) - TEMP */
- { 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
- { 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
- { 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
- { 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
- { 0x70,0x29, 81} /* 0x5b - added for 1280x768 LCD */
-};
-
-typedef struct _SiS310_VBVCLKDataStruct
-{
- UCHAR Part4_A,Part4_B;
- USHORT CLOCK;
-} SiS310_VBVCLKDataStruct;
-
-static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
+ { 0x44,0x44, 66}, /* 0x53 Chrontel */
+ { 0x3a,0x62, 70}, /* 0x54 Chrontel */
+ { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+ { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */
+ { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
+ { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */
+ { 0x52,0x07,149}, /* 0x59 1280x960-85 */
+ { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
+ { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+ { 0x45,0x25, 83}, /* 0x5c 1280x800 */
+ { 0x70,0x0a,147}, /* 0x5d 1680x1050 */
+ { 0x70,0x24,162}, /* 0x5e 1600x1200 */
+ { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */
+ { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
+ { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+ { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
+ { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+ { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
+ { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
+ { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
+ { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
+ { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
+ { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */
+ { 0x7c,0x6b, 38} /* 0x6a 960x540@60 */
+};
+
+static SiS_VBVCLKDataStruct SiS310_VBVCLKData[]=
{
{ 0x1b,0xe1, 25}, /* 0x00 */
{ 0x4e,0xe4, 28}, /* 0x01 */
{ 0x53,0x47, 50}, /* 0x08 */
{ 0x74,0x67, 52}, /* 0x09 */
{ 0x6d,0x66, 56}, /* 0x0a */
- { 0x35,0x62, 65}, /* 0x0b */ /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62 */
+ { 0x35,0x62, 65}, /* 0x0b */ /* Was 0x5a,0x64 - 650/LVDS+301: 35,62 */
{ 0x46,0x44, 67}, /* 0x0c */
{ 0xb1,0x46, 68}, /* 0x0d */
{ 0xd3,0x4a, 72}, /* 0x0e */
{ 0xea,0x08,340}, /* 0x37 */
{ 0xe8,0x07,376}, /* 0x38 */
{ 0xde,0x06,389}, /* 0x39 */
- { 0x52,0x2a, 54}, /* 0x3a */ /* 301 TV */
- { 0x52,0x6a, 27}, /* 0x3b */ /* 301 TV */
- { 0x62,0x24, 70}, /* 0x3c */ /* 301 TV */
- { 0x62,0x64, 70}, /* 0x3d */ /* 301 TV */
- { 0xa8,0x4c, 30}, /* 0x3e */ /* 301 TV */
- { 0x20,0x26, 33}, /* 0x3f */ /* 301 TV */
+ { 0x52,0x2a, 54}, /* 0x3a 301 TV - start */
+ { 0x52,0x6a, 27}, /* 0x3b 301 TV */
+ { 0x62,0x24, 70}, /* 0x3c 301 TV */
+ { 0x62,0x64, 70}, /* 0x3d 301 TV */
+ { 0xa8,0x4c, 30}, /* 0x3e 301 TV */
+ { 0x20,0x26, 33}, /* 0x3f 301 TV */
{ 0x31,0xc2, 39}, /* 0x40 */
- { 0x2e,0x48, 25}, /* 0x41 */ /* Replacement for LCD on 315 for index 0 */
- { 0x24,0x46, 25}, /* 0x42 */ /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
- { 0x26,0x64, 28}, /* 0x43 */ /* Replacement for LCD on 315 for index 1 */
- { 0x37,0x64, 40}, /* 0x44 */ /* Replacement for LCD on 315 for index 4 */
- { 0xa1,0x42,108}, /* 0x45 */ /* 1280x960 LCD */
- { 0x37,0x61,100}, /* 0x46 */ /* 1280x960 LCD */
+ { 0x2e,0x48, 25}, /* 0x41 Replacement for LCD on 315 for index 0 */
+ { 0x24,0x46, 25}, /* 0x42 Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
+ { 0x26,0x64, 28}, /* 0x43 Replacement for LCD on 315 for index 1 */
+ { 0x37,0x64, 40}, /* 0x44 Replacement for LCD on 315 for index 4 */
+ { 0xa1,0x42,108}, /* 0x45 1280x960 LCD */
+ { 0x37,0x61,100}, /* 0x46 1280x960 LCD */
{ 0x78,0x27,108}, /* 0x47 */
- { 0x97,0x2c, 26}, /* 0x48 */ /* UNUSED - Entries from here new, not in any BIOS */
- { 0xce,0x3c, 39}, /* 0x49 */ /* UNUSED */
- { 0x52,0x4a, 36}, /* 0x4a */ /* UNUSED */
- { 0x34,0x61, 95}, /* 0x4b */ /* UNUSED */
- { 0x78,0x27,108}, /* 0x4c */ /* UNUSED */
- { 0x66,0x43,123}, /* 0x4d */ /* 1400x1050-60 */
- { 0x41,0x4e, 21}, /* 0x4e */ /* UNUSED */
- { 0xa1,0x4a, 29}, /* 0x4f */ /* UNUSED */
- { 0x19,0x42, 42}, /* 0x50 */ /* UNUSED */
- { 0x54,0x46, 58}, /* 0x51 */ /* UNUSED */
- { 0x25,0x42, 61}, /* 0x52 */ /* UNUSED */
- { 0x44,0x44, 66}, /* 0x53 */ /* UNUSED */
- { 0x3a,0x62, 70}, /* 0x54 */ /* UNUSED */
- { 0x62,0xc6, 34}, /* 0x55 */ /* 848x480-60 */
- { 0x6a,0xc6, 37}, /* 0x56 */ /* 848x480-75 - TEMP, UNUSED */
- { 0xbf,0xc8, 35}, /* 0x57 */ /* 856x480-38i,60 */
- { 0x30,0x23, 88}, /* 0x58 */ /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
- { 0x52,0x07,149}, /* 0x59 */ /* 1280x960-85 */
- { 0x56,0x07,156}, /* 0x5a */ /* 1400x1050-75 */
- { 0x70,0x29, 81} /* 0x5b */ /* 1280x768 LCD */
-};
-
-static const UCHAR SiS310_ScreenOffset[] =
-{
- 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
- 0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
- 0xff
+ { 0x97,0x2c, 26}, /* 0x48 UNUSED */
+ { 0xce,0x3c, 39}, /* 0x49 UNUSED */
+ { 0x52,0x4a, 36}, /* 0x4a UNUSED */
+ { 0x34,0x61, 95}, /* 0x4b UNUSED */
+ { 0x78,0x27,108}, /* 0x4c UNUSED */
+ { 0x66,0x43,123}, /* 0x4d 1400x1050-60 */
+ { 0x41,0x4e, 21}, /* 0x4e UNUSED */
+ { 0xa1,0x4a, 29}, /* 0x4f UNUSED */
+ { 0x19,0x42, 42}, /* 0x50 UNUSED */
+ { 0x54,0x46, 58}, /* 0x51 UNUSED */
+ { 0x25,0x42, 61}, /* 0x52 UNUSED */
+ { 0x44,0x44, 66}, /* 0x53 UNUSED */
+ { 0x3a,0x62, 70}, /* 0x54 UNUSED */
+ { 0x62,0xc6, 34}, /* 0x55 848x480-60 */
+ { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP, UNUSED */
+ { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */
+ { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) TEMP, UNUSED */
+ { 0x52,0x07,149}, /* 0x59 1280x960-85 */
+ { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */
+ { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */
+ { 0x45,0x25, 83}, /* 0x5c 1280x800 LCD - (was 0x9c,0x62, 69 - wrong?) */
+ { 0xbe,0x44,121}, /* 0x5d 1680x1050 LCD */
+ { 0x70,0x24,162}, /* 0x5e 1600x1200 LCD */
+ { 0x52,0x27, 75}, /* 0x5f 1280x720 LCD TMDS + HDTV (correct) */
+ { 0x63,0x46, 68}, /* 0x60 1280x768_2 */
+ { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */
+ { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */
+ { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */
+ { 0x70,0x28, 90}, /* 0x64 1152x864@60 */
+ { 0x41,0xc4, 32}, /* 0x65 848x480@60 */
+ { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */
+ { 0x76,0xe7, 27}, /* 0x67 720x480@60 */
+ { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */
+ { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced (UNUSED) */
+ { 0x7c,0x6b, 38} /* 0x6a 960x540@60 */
};
static const DRAM4Type SiS310_SR15[8] = {
static const USHORT SiS310_YCSenseData2 = 0x016b;
#endif
-typedef struct _SiS310_PanelDelayTblStruct
-{
- UCHAR timer[2];
-} SiS310_PanelDelayTblStruct;
-
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
+static const SiS_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
{
{{0x10,0x40}},
{{0x10,0x40}},
{{0x10,0x40}}
};
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
+static const SiS_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
{
{{0x28,0xc8}},
{{0x28,0xc8}},
/* SIS VIDEO BRIDGE ----------------------------------------- */
/**************************************************************/
-typedef struct _SiS310_LCDDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS310_LCDDataStruct;
-
-static const SiS310_LCDDataStruct SiS310_StLCD1024x768Data[]=
+static const SiS_LCDDataStruct SiS310_St2LCD1024x768Data[] =
{
{ 62, 25, 800, 546,1344, 806},
{ 32, 15, 930, 546,1344, 806},
- { 32, 15, 930, 546,1344, 806},
+ { 62, 25, 800, 546,1344, 806},
{ 104, 45, 945, 496,1344, 806},
{ 62, 25, 800, 546,1344, 806},
{ 31, 18,1008, 624,1344, 806},
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS310_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
+static const SiS_LCDDataStruct SiS310_ExtLCD1024x768Data[] =
{
{ 42, 25,1536, 419,1344, 806},
{ 48, 25,1536, 369,1344, 806},
{ 48, 25,1536, 369,1344, 806},
{ 12, 5, 896, 500,1344, 806},
{ 42, 25,1024, 625,1344, 806},
- { 1, 1,1344, 806,1344, 806},
- { 12, 5, 896, 500,1344, 806},
- { 42, 25,1024, 625,1344, 806},
- { 1, 1,1344, 806,1344, 806},
- { 12, 5, 896, 500,1344, 806},
- { 42, 25,1024, 625,1344, 806},
- { 1, 1,1344, 806,1344, 806}
-
-};
-
-static const SiS310_LCDDataStruct SiS310_St2LCD1024x768Data[] =
-{
- { 62, 25, 800, 546,1344, 806},
- { 32, 15, 930, 546,1344, 806},
- { 62, 25, 800, 546,1344, 806},
- { 104, 45, 945, 496,1344, 806},
- { 62, 25, 800, 546,1344, 806},
- { 31, 18,1008, 624,1344, 806},
{ 1, 1,1344, 806,1344, 806}
};
-static const SiS310_LCDDataStruct SiS310_StLCD1280x1024Data[] =
+static const SiS_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
{
{ 22, 5, 800, 510,1650,1088},
{ 22, 5, 800, 510,1650,1088},
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS310_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
+static const SiS_LCDDataStruct SiS310_ExtLCD1280x1024Data[] =
{
{ 211, 60,1024, 501,1688,1066},
{ 211, 60,1024, 508,1688,1066},
{ 211, 60,1024, 500,1688,1066},
{ 211, 75,1024, 625,1688,1066},
{ 211, 120,1280, 798,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1800,1000,1688,1066} /* 1280x960 - does not work, use panel scaler instead */
-};
-
-static const SiS310_LCDDataStruct SiS310_St2LCD1280x1024Data[] =
-{
- { 22, 5, 800, 510,1650,1088},
- { 22, 5, 800, 510,1650,1088},
- { 176, 45, 900, 510,1650,1088},
- { 176, 45, 900, 510,1650,1088},
- { 22, 5, 800, 510,1650,1088},
- { 13, 5,1024, 675,1560,1152},
- { 16, 9,1266, 804,1688,1072},
{ 1, 1,1688,1066,1688,1066}
};
-static const SiS310_LCDDataStruct SiS310_NoScaleData1024x768[] =
-{
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1344, 806,1344, 806}, /* 640x400 - does not work */
- { 1, 1,1344, 806,1344, 806}, /* 640x480 - does not work */
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1344, 806,1344, 806},
- { 1, 1,1344, 806,1344, 806}
-};
-
-static const SiS310_LCDDataStruct SiS310_NoScaleData1280x1024[] =
-{
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066},
- { 1, 1,1688,1066,1688,1066}
-};
-
-typedef struct _SiS310_Part2PortTblStruct
-{
- UCHAR CR[12];
-} SiS310_Part2PortTblStruct;
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_1024x768_1[] =
{
{{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
{{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
{{0x38,0x13,0x16,0x0c,0xe6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
{{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
};
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
-{
- {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x2c,0x12,0x38,0x55,0x2f,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
- {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
- {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}, /* others */
-/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24 my */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
+/* *** LCDA *** */
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
-{
-#if 1 /* Data from 650/301LVx 1.10.6s and others */
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+#if 0
+static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]=
+{ /* Clevo, 651+301C */
+ {1200, 450, 2048,1250},
+ {1200, 400, 2048,1250},
+ {1280, 450, 2048,1250},
+ {1280, 400, 2048,1250},
+ {1200, 530, 2048,1250},
+ {1360, 650, 2048,1250},
+ {1584, 818, 2048,1250},
+ {1688,1066, 2048,1250},
+ {1688,1066, 2048,1250},
+#if 0
+ {2048,1250, 2048,1250} /* this should be correct */
#endif
-#if 0 /* Data from my 301LV */
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}, /* TEST */
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
- {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
+#if 1
+ {2160,1250, 2048,1250} /* ? */
#endif
};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
-{ /* Acer; BIOS data invalid, last row taken from _3 */
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
- {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
-{ /* Acer */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-};
-
-/* 1 2 4 5 6 1c 1d 1f 20 21 23 25 */
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
-{ /* Acer */
- {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
-{
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
-{
- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
- {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
- {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
-{
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
-{
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
-{
- {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x3A,0x1B,0x54,0x7A,0x48,0x80,0x24,0x52,0x30,0xA3,0x3A,0x02}},
- {{0x36,0x1B,0x90,0xB6,0x84,0xA8,0x24,0x7A,0x30,0xCB,0x62,0x02}},
- {{0x3A,0x1C,0xE4,0x0A,0xD8,0xE0,0x24,0xB2,0x30,0x03,0x9A,0x02}},
- {{0x4A,0x24,0x64,0x8A,0x58,0x20,0x34,0xF2,0x30,0x43,0xDA,0x52}},
- {{0x47,0x24,0x71,0x97,0x65,0x3E,0x34,0x10,0x40,0x61,0xF8,0x02}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
-{
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
- {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
-};
-
-/* CRT1 CRTC for LCDA */
-
-typedef struct _SiS310_LCDACRT1DataStruct
-{
- UCHAR CR[17];
-}SiS310_LCDACRT1DataStruct;
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1[]=
-{
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
- 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
- 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x04,0x3e,
- 0xE2,0x89,0xdf,0xdf,0x05,0x00,0x00,0x05,
- 0x00}},
- {{0x87,0x63,0x63,0x8B,0x6D,0x18,0x7c,0xf0,
- 0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x06,
- 0x01}},
- {{0xA3,0x7f,0x7f,0x87,0x89,0x94,0x24,0xf5,
- 0x02,0x89,0xff,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_1_H[]=
-{
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
- 0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
- 0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x04,0x3e,
- 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
- 0x00}},
- {{0x55,0x31,0x31,0x99,0x3b,0x06,0x7c,0xf0,
- 0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x01,
- 0x01}},
- {{0x63,0x3F,0x3F,0x87,0x49,0x94,0x24,0xF5,
- 0x02,0x89,0xFF,0xFF,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2[]=
-{
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
- 0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
- 0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
- 0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
- 0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
- 0x01}},
- {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xb3,
- 0x72,0x89,0xdf,0x03,0x02,0x30,0x00,0x06,
- 0x01}},
- {{0xa3,0x63,0x63,0x98,0x78,0x19,0x24,0xf1,
- 0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x02,
- 0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x89,0x94,0x24,0xf5,
- 0x02,0x89,0xff,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11024x768_2_H[]=
-{
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
- 0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
- 0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
- 0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
- 0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xb3,
- 0x72,0x89,0xdf,0x03,0x02,0x30,0x00,0x01,
- 0x01 }},
- {{0x71,0x31,0x31,0x98,0x46,0x17,0x24,0xf1,
- 0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x02,
- 0x01 }},
- {{0x63,0x3f,0x3f,0x87,0x4c,0x97,0x24,0xf5,
- 0x0f,0x86,0xff,0xff,0x25,0x30,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1[]=
-{ /* Acer */
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
- 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
- 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x08,0x3e,
- 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
- 0x00}},
- {{0x92,0x63,0x63,0x96,0x6c,0x18,0x80,0xf0,
- 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
- 0x01}},
- {{0xae,0x7f,0x7f,0x92,0x88,0x94,0x28,0xf5,
- 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
- 0x01}},
- {{0xce,0x9f,0x9f,0x92,0xa8,0x14,0x28,0x5a,
- 0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
- 0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_1_H[]=
-{ /* Acer */
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x86,0x1f,
- 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x05,
- 0x00}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x86,0x1f,
- 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x05,
- 0x01}},
- {{0x56,0x27,0x27,0x9a,0x31,0x1c,0x08,0x3e,
- 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
- 0x00}},
- {{0x60,0x31,0x31,0x84,0x3a,0x86,0x80,0xf0,
- 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
- 0x01}},
- {{0x6e,0x3f,0x3f,0x92,0x48,0x94,0x28,0xf5,
- 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2[]=
-{ /* Illegal data in BIOS (Acer, Compaq) */
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
- 0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11280x1024_2_H[]=
-{ /* Illegal data in BIOS (Acer, Compaq) */
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
- 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1,
- 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,
- 0x01 }},
- {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
- 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
- 0x01 }}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1[]=
-{
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
- 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
- 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
- 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
- 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
- 0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
- 0x00}},
- {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0,
- 0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06,
- 0x01}},
- {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
- 0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02,
- 0x01}},
- {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
- 0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07,
- 0x01}},
- {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
- 0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_1_H[]=
-{
- {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
- 0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
- 0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
- 0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
- 0x00}},
- {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
- 0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
- 0x00}},
- {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0,
- 0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01,
- 0x01}},
- {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
- 0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01,
- 0x01}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
- 0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05,
- 0x01}},
- {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10,
- 0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2[]=
-{
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
- 0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
- 0x01}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
- 0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
- 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x03,
- 0x00}},
- {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9e,
- 0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x03,
- 0x00}},
- {{0xce,0x63,0x63,0x92,0x96,0x04,0x28,0xd4,
- 0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x07,
- 0x01}},
- {{0xce,0x7f,0x7f,0x92,0xa4,0x12,0x28,0xd4,
- 0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x9f,0x92,0xb4,0x02,0x28,0x5a,
- 0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x03,
- 0x01}},
- {{0xce,0xae,0xae,0x92,0xbc,0x0a,0x28,0x10,
- 0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x03,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11400x1050_2_H[]=
-{
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
- 0xc2,0x86,0x5d,0x5d,0x29,0x01,0x00,0x06,
- 0x00}},
- {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9e,
- 0x03,0x87,0xdf,0xdf,0x29,0x01,0x00,0x06,
- 0x00}},
- {{0x9c,0x31,0x31,0x80,0x64,0x92,0x28,0xd4,
- 0x3f,0x83,0x57,0x57,0x29,0x01,0x00,0x06,
- 0x01}},
- {{0x8e,0x3f,0x3f,0x92,0x64,0x12,0x28,0xd4,
- 0x93,0x87,0xff,0xff,0x29,0x21,0x00,0x06,
- 0x01}},
- {{0x7e,0x4f,0x4f,0x82,0x64,0x12,0x28,0x5a,
- 0x13,0x87,0xff,0xff,0x29,0x29,0x00,0x06,
- 0x01}},
- {{0x76,0x56,0x56,0x9a,0x64,0x92,0x28,0x10,
- 0x20,0x84,0x19,0x19,0x29,0x0f,0x00,0x05,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_1[]=
-{
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0xC0,0x1F,
- 0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
- 0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0xC0,0x1F,
- 0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
- 0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
- 0x00}},
- {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x10,0x3E,
- 0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x06,
- 0x00}},
- {{0x97,0x63,0x63,0x9B,0x65,0x1D,0x88,0xF0,
- 0x58,0x8C,0x57,0x57,0x89,0x20,0x00,0x06,
- 0x01}},
- {{0xB3,0x7F,0x7F,0x97,0x81,0x99,0x30,0xF5,
- 0x00,0x84,0xFF,0xFF,0x31,0x10,0x00,0x02,
- 0x01}},
- {{0xD3,0x9F,0x9F,0x97,0xA1,0x19,0x30,0x5A,
- 0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x07,
- 0x01}},
- {{0xE2,0xAE,0xAE,0x86,0xB0,0x88,0x4A,0x10,
- 0x1A,0x8E,0x19,0x19,0x4B,0x2F,0x00,0x03,
- 0x00}},
- {{0xFB,0xC7,0xC7,0x9F,0xC9,0x81,0xE0,0x10,
- 0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x07,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_1_H[]=
-{
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
- 0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
- 0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
- 0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
- 0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
- 0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
- 0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
- 0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
- 0x00}},
- {{0x69,0x27,0x27,0x8D,0x30,0x88,0x10,0x3E,
- 0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x01,
- 0x00}},
- {{0x73,0x31,0x31,0x97,0x3A,0x92,0x88,0xF0,
- 0x58,0x8C,0x57,0x57,0x89,0x20,0x00,0x01,
- 0x01}},
- {{0x81,0x3F,0x3F,0x85,0x48,0x00,0x30,0xF5,
- 0x00,0x84,0xFF,0xFF,0x31,0x10,0x00,0x06,
- 0x01}},
- {{0x91,0x4F,0x4F,0x95,0x58,0x10,0x30,0x5A,
- 0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x06,
- 0x01}},
- {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
- 0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
- 0x01}},
- {{0xA5,0x63,0x63,0x89,0x6C,0x84,0xE0,0x10,
- 0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x02,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_2[]=
-{
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
- 0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x01,0x04,
- 0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
- 0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x01,0x04,
- 0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
- 0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x01,0x04,
- 0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
- 0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x01,0x04,
- 0x00}},
- {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
- 0x5F,0x83,0xDF,0xDF,0xE1,0x01,0x01,0x04,
- 0x00}},
- {{0x09,0x63,0x63,0x8D,0xAD,0x05,0xE0,0xD4,
- 0x9B,0x8F,0x57,0x57,0xE1,0x21,0x01,0x00,
- 0x01}},
- {{0x09,0x7F,0x7F,0x8D,0xBB,0x13,0xE0,0xD4,
- 0xEF,0x83,0xFF,0xFF,0xE1,0x21,0x01,0x00,
- 0x01}},
- {{0x09,0x9F,0x9F,0x8D,0xCB,0x03,0xE0,0x5A,
- 0x6F,0x83,0xFF,0xFF,0xE1,0x29,0x01,0x04,
- 0x01}},
- {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
- 0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
- 0x01}},
- {{0x09,0xC7,0xC7,0x8D,0xDF,0x17,0xE0,0x10,
- 0xC7,0x8B,0xAF,0xAF,0xE1,0x0F,0x01,0x04,
- 0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct SiS310_LCDACRT11600x1200_2_H[]=
-{
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
- 0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x00,0x03,
- 0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
- 0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x00,0x03,
- 0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
- 0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x00,0x03,
- 0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
- 0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x00,0x03,
- 0x00}},
- {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
- 0x5F,0x83,0xDF,0xDF,0xE1,0x01,0x00,0x03,
- 0x00}},
- {{0xD7,0x31,0x31,0x9B,0x7B,0x13,0xE0,0xD4,
- 0x9B,0x8F,0x57,0x57,0xE1,0x21,0x00,0x03,
- 0x01}},
- {{0xC9,0x3F,0x3F,0x8D,0x7B,0x13,0xE0,0xD4,
- 0xEF,0x83,0xFF,0xFF,0xE1,0x21,0x00,0x03,
- 0x01}},
- {{0xB9,0x4F,0x4F,0x9D,0x7B,0x93,0xE0,0x5A,
- 0x6F,0x83,0xFF,0xFF,0xE1,0x29,0x00,0x02,
- 0x01}},
- {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
- 0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
- 0x01}},
- {{0xA5,0x63,0x63,0x89,0x7B,0x93,0xE0,0x10,
- 0xC7,0x8B,0xAF,0xAF,0xE1,0x0F,0x00,0x02,
- 0x00}}
-};
-
+#endif
/**************************************************************/
/* LVDS, CHRONTEL ------------------------------------------- */
/**************************************************************/
-typedef struct _SiS310_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} SiS310_LVDSDataStruct;
-
-static const SiS310_LVDSDataStruct SiS310_CHTVUPALData[]=
+static const SiS_LVDSDataStruct SiS310_CHTVUPALData[]=
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{1400,1000,1400,1000}
};
-static const SiS310_LVDSDataStruct SiS310_CHTVOPALData[]=
+static const SiS_LVDSDataStruct SiS310_CHTVOPALData[]=
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{1400, 875,1400, 875}
};
-static const SiS310_LVDSDataStruct SiS310_CHTVUPALMData[]=
+static const SiS_LVDSDataStruct SiS310_CHTVUPALMData[]=
{
{ 840, 600, 840, 600},
{ 840, 600, 840, 600},
{1160, 945,1160, 945}
};
-static const SiS310_LVDSDataStruct SiS310_CHTVOPALMData[]=
+static const SiS_LVDSDataStruct SiS310_CHTVOPALMData[]=
{
{ 840, 525, 840, 525},
{ 840, 525, 840, 525},
{1160, 840,1160, 840}
};
-static const SiS310_LVDSDataStruct SiS310_CHTVUPALNData[]=
+static const SiS_LVDSDataStruct SiS310_CHTVUPALNData[]=
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{1400,1000,1400,1000}
};
-static const SiS310_LVDSDataStruct SiS310_CHTVOPALNData[]=
+static const SiS_LVDSDataStruct SiS310_CHTVOPALNData[]=
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{1400, 875,1400, 875}
};
-static const SiS310_LVDSDataStruct SiS310_CHTVSOPALData[]= /* TW: (super overscan - no effect on 7019) */
+static const SiS_LVDSDataStruct SiS310_CHTVSOPALData[]= /* (super overscan - no effect on 7019) */
{
{1008, 625,1008, 625},
{1008, 625,1008, 625},
{1400, 875,1400, 875}
};
-typedef struct _SiS310_LVDSDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDVDES;
-} SiS310_LVDSDesStruct;
-static const SiS310_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */
+static const SiS_LVDSDesStruct SiS310_PanelType00_1[]= /* 800x600 */
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */
+static const SiS_LVDSDesStruct SiS310_PanelType01_1[]= /* 1024x768 */
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */
+static const SiS_LVDSDesStruct SiS310_PanelType02_1[]= /* 1280x1024 */
{
{ 0, 0},
{ 0, 0},
};
-static const SiS310_LVDSDesStruct SiS310_PanelType03_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType03_1[]=
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType04_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType04_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType05_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType05_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType06_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType06_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType07_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType07_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType08_1[]= /* 1400x1050 */
+static const SiS_LVDSDesStruct SiS310_PanelType08_1[]= /* 1400x1050 */
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType09_1[]= /* 1280x768 */
+static const SiS_LVDSDesStruct SiS310_PanelType09_1[]= /* 1280x768 */
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0a_1[]= /* 1600x1200 */
+static const SiS_LVDSDesStruct SiS310_PanelType0a_1[]= /* 1600x1200 */
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */
+static const SiS_LVDSDesStruct SiS310_PanelType0b_1[]= /* 640x480_2 */
{
{ 0, 524},
{ 0, 524},
{ 0, 524}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */
+static const SiS_LVDSDesStruct SiS310_PanelType0c_1[]= /* 640x480_3 */
{
{ 0, 524},
{ 0, 524},
{ 0, 524}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0d_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType0d_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0e_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType0e_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0f_1[]=
+static const SiS_LVDSDesStruct SiS310_PanelType0f_1[]=
{
{1343, 798},
{1343, 794},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType00_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType00_2[]=
{
{980, 528},
{980, 503},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType01_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType01_2[]=
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType02_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType02_2[]=
{
{1368, 754},
{1368, 729},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType03_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType03_2[]=
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType04_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType04_2[]=
{
{ 0, 0},
{ 0, 0},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType05_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType05_2[]=
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType06_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType06_2[]=
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType07_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType07_2[]=
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType08_2[]= /* 1400x1050 */
+static const SiS_LVDSDesStruct SiS310_PanelType08_2[]= /* 1400x1050 */
{
{1308, 741},
{1308, 716},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType09_2[]= /* 1280x768 */
+static const SiS_LVDSDesStruct SiS310_PanelType09_2[]= /* 1280x768 */
{
{1083, 622},
{1083, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0a_2[]= /* 1600x1200 */
+static const SiS_LVDSDesStruct SiS310_PanelType0a_2[]= /* 1600x1200 */
{
{1568, 920},
{1568, 895},
#endif
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */
+static const SiS_LVDSDesStruct SiS310_PanelType0b_2[]= /* 640x480_2 */
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */
+static const SiS_LVDSDesStruct SiS310_PanelType0c_2[]= /* 640x480_3 */
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0d_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType0d_2[]=
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0e_2[]=
+static const SiS_LVDSDesStruct SiS310_PanelType0e_2[]=
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-static const SiS310_LVDSDesStruct SiS310_PanelType0f_2[] =
+static const SiS_LVDSDesStruct SiS310_PanelType0f_2[] =
{
{1152, 622},
{1152, 597},
{ 0, 0}
};
-/* CRT1 CRTC for SlaveModes and LCDA */
+static const SiS_LVDSDesStruct SiS310_PanelTypeNS_1[]=
+{
+ { 8, 0},
+ { 8, 0},
+ { 8, 0},
+ { 8, 0},
+ { 8, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 0},
+ { 0, 806},
+ { 0, 0}
+};
-typedef struct _SiS310_LVDSCRT1DataStruct
+static const SiS_LVDSDesStruct SiS310_PanelTypeNS_2[] =
{
- UCHAR CR[15];
-} SiS310_LVDSCRT1DataStruct;
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0},
+ { 0 , 0}
+};
+
+/* CRT1 CRTC for SlaveModes and LCDA */
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1[] =
{
{{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_1_H[] =
{
{{0x43,0x27,0x87,0x2d,0x1d,0xaa,0x1f,
0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]=
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2[]=
{
{{0x7f,0x4f,0x83,0x62,0x12,0x72,0x3e,
0xff,0x84,0x8f,0x73,0x00,0x00,0x06,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1800x600_2_H[] =
{
{{0x57,0x27,0x9b,0x3a,0x0a,0x72,0x3e,
0xff,0x84,0x8f,0x73,0x00,0x00,0x01,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1[] =
{
{{0x73,0x4f,0x97,0x53,0x84,0xb4,0x1f,
0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_1_H[] =
{
{{0x4b,0x27,0x8f,0x2b,0x1c,0xb4,0x1f,
0x92,0x89,0x8f,0xb5,0x30,0x00,0x05,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2[] =
{
{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
0x57,0x8e,0x8f,0x25,0x30,0x00,0x06,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11024x768_2_H[] =
{
{{0x7b,0x27,0x9f,0x46,0x97,0x24,0xbb,
0x57,0x8e,0x8f,0x25,0x30,0x00,0x01,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1[] =
{
{{0x7e,0x4f,0x82,0x58,0x04,0xb8,0x1f,
0x90,0x84,0x8f,0xb9,0x30,0x00,0x06,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_1_H[] =
{
{{0x56,0x27,0x9a,0x31,0x1c,0xb8,0x1f,
0x90,0x84,0x8f,0xb9,0x30,0x00,0x05,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2[] =
{
{{0xce,0x72,0x91,0x81,0x8f,0x28,0x92,
0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x02,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11280x1024_2_H[] =
{
{{0xa6,0x4a,0x89,0x59,0x07,0x28,0x92,
0xc8,0x8c,0x5d,0x5c,0x01,0x00,0x06,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1[] =
{
{{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_1_H[] =
{
{{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2[] =
{
{{0xce,0x72,0x91,0x84,0x92,0x28,0x92,
0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x02,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11400x1050_2_H[] =
{
{{0xa6,0x4a,0x89,0x5c,0x0a,0x28,0x92,
0xd7,0x8b,0x5d,0x5c,0x21,0x00,0x06,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1[] =
{
{{0x83,0x4F,0x87,0x5B,0x13,0x06,0x3E,
0xB3,0x86,0x8F,0x07,0x20,0x00,0x06,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_1_H[] =
{
{{0x5B,0x27,0x9F,0x33,0x0B,0x06,0x2E,
0xB3,0x86,0x8F,0x07,0x20,0x00,0x01,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2[] =
{
{{0xFB,0x87,0x86,0x97,0x0F,0x26,0x97,
0x43,0x86,0xDB,0xDA,0x11,0x00,0x07,
#endif
};
-static const SiS310_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] =
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT11600x1200_2_H[] =
{
{{0xD3,0x5F,0x9E,0x6F,0x07,0x26,0x97,
0x43,0x86,0xDB,0xDA,0x11,0x00,0x02,
#endif
};
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+ 0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+ 0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+ 0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+ 0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+ 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+ 0x01}},
+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+ 0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct SiS310_LVDSCRT1XXXxXXX_1_H[] =
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+ 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+ 0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+ 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+ 0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+ 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+ 0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+ 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+ 0x01}}
+};
+
+
/* CRT1 CRTC for Chrontel TV slave modes */
-static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
+static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UNTSC[] =
{
{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
+static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1ONTSC[] =
{
{{0x63,0x4f,0x87,0x5a,0x9f,0x0b,0x3e,
0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,
0x01 }}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
+static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1UPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,
0x01}}
};
-static const SiS310_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
+static const SiS_LVDSCRT1DataStruct SiS310_CHTVCRT1OPAL[] =
{
{{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,
0x01 }}
};
-typedef struct _SiS310_CHTVRegDataStruct
-{
- UCHAR Reg[16];
-} SiS310_CHTVRegDataStruct;
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UNTSC[] =
{
{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0x4a,0x77,0xbb,0x94,0x84,0x48,0xfe,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
for PAL-M and PAL-N all above is corrected.
*/
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_ONTSC[] =
{
{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0x49,0x77,0xbb,0x7b,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0xed,0x77,0xbb,0x66,0x8c,0x21,0x02,0x5a,0x04,0x00,0x80,0x1f,0x9f,0xc1,0x0c,0x00}}
};
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPAL[] =
{
{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0xe5,0x7f,0xb7,0x1d,0xa7,0x3e,0x04,0x5a,0x05,0x00,0x80,0x20,0x3e,0xe4,0x22,0x00}}
};
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPAL[] =
{
{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0xe4,0x7f,0xb7,0x1e,0xaf,0x29,0x37,0x5a,0x05,0x00,0x80,0x25,0x8c,0xb2,0x2a,0x00}}
};
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALM[] =
{
{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0x52,0x77,0xbb,0x94,0x84,0x48,0xfe,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
#endif
};
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALM[] =
{
{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
{{0x51,0x77,0xbb,0x7b,0x84,0x34,0x00,0x83,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01}},
#endif
};
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_UPALN[] =
{
{{0x41,0x7f,0xb7,0x34,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
{{0x41,0x7f,0xb7,0x80,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
#endif
};
-static const SiS310_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
+static const SiS_CHTVRegDataStruct SiS310_CHTVReg_OPALN[] =
{
{{0x41,0x7f,0xb7,0x36,0xad,0x50,0x34,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
{{0x41,0x7f,0xb7,0x86,0x85,0x50,0x00,0x6e,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x03}},
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Mode initializing code (CRT1 section) for
* for SiS 300/305/540/630/730 and
- * SiS 315/550/650/M650/651/661FX/M661FX/740/741/M741/330/660/M660/760/M760
+ * SiS 315/550/650/M650/651/661FX/M661FX/740/741(GX)/M741/330/660/M660/760/M760
* (Universal module for Linux kernel framebuffer and XFree86 4.x)
*
* Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(PAGE,SiSSetMode)
-#pragma alloc_text(PAGE,SiSInit)
#endif
/*********************************************/
/* POINTER INITIALIZATION */
/*********************************************/
+#if defined(SIS300) || defined(SIS315H)
static void
InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
SiS_Pr->pSiS_SoftSetting = &SiS_SoftSetting;
+ SiS_Pr->SiS_LCD1280x720Data = SiS_LCD1280x720Data;
+ SiS_Pr->SiS_StLCD1280x768_2Data = SiS_StLCD1280x768_2Data;
+ SiS_Pr->SiS_ExtLCD1280x768_2Data = SiS_ExtLCD1280x768_2Data;
+ SiS_Pr->SiS_LCD1280x768_3Data = SiS_LCD1280x768_3Data;
+ SiS_Pr->SiS_LCD1280x800Data = SiS_LCD1280x800Data;
SiS_Pr->SiS_LCD1280x960Data = SiS_LCD1280x960Data;
- SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
- SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
SiS_Pr->SiS_StLCD1400x1050Data = SiS_StLCD1400x1050Data;
+ SiS_Pr->SiS_ExtLCD1400x1050Data = SiS_ExtLCD1400x1050Data;
+ SiS_Pr->SiS_LCD1680x1050Data = SiS_LCD1680x1050Data;
SiS_Pr->SiS_StLCD1600x1200Data = SiS_StLCD1600x1200Data;
- SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
- SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
- SiS_Pr->SiS_ExtLCD1280x768Data = SiS_ExtLCD1280x768Data;
- SiS_Pr->SiS_StLCD1280x768Data = SiS_StLCD1280x768Data;
- SiS_Pr->SiS_NoScaleData1280x768 = SiS_NoScaleData1280x768;
+ SiS_Pr->SiS_ExtLCD1600x1200Data = SiS_ExtLCD1600x1200Data;
SiS_Pr->SiS_NoScaleData = SiS_NoScaleData;
SiS_Pr->SiS_LVDS320x480Data_1 = SiS_LVDS320x480Data_1;
SiS_Pr->SiS_LVDS640x480Data_1 = SiS_LVDS640x480Data_1;
SiS_Pr->SiS_LVDS640x480Data_2 = SiS_LVDS640x480Data_2;
- SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
- SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
- SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
- SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
SiS_Pr->SiS_LVDS848x480Data_1 = SiS_LVDS848x480Data_1;
SiS_Pr->SiS_LVDS848x480Data_2 = SiS_LVDS848x480Data_2;
-
- SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
- SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
-
- SiS_Pr->SiS_LCDA1024x768Data_1 = SiS_LCDA1024x768Data_1;
- SiS_Pr->SiS_LCDA1024x768Data_2 = SiS_LCDA1024x768Data_2;
- SiS_Pr->SiS_LCDA1280x1024Data_1 = SiS_LCDA1280x1024Data_1;
- SiS_Pr->SiS_LCDA1280x1024Data_2 = SiS_LCDA1280x1024Data_2;
- SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
- SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
- SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
- SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
-
- SiS_Pr->LVDS1024x768Des_1 = SiS_PanelType1076_1;
- SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
- SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
- SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
- SiS_Pr->LVDS1024x768Des_2 = SiS_PanelType1076_2;
- SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
- SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
- SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
-
- SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
- SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
-
- SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
- SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
- SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData;
- SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData;
+ SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
+ SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
+ SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
+ SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
SiS_Pr->SiS_LVDSCRT11280x768_1 = SiS_LVDSCRT11280x768_1;
SiS_Pr->SiS_LVDSCRT11024x600_1 = SiS_LVDSCRT11024x600_1;
SiS_Pr->SiS_LVDSCRT11024x600_2_H = SiS_LVDSCRT11024x600_2_H;
SiS_Pr->SiS_LVDSCRT11152x768_2_H = SiS_LVDSCRT11152x768_2_H;
SiS_Pr->SiS_LVDSCRT1320x480_1 = SiS_LVDSCRT1320x480_1;
- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS_LVDSCRT1XXXxXXX_1;
- SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS_LVDSCRT1XXXxXXX_1_H;
SiS_Pr->SiS_LVDSCRT1640x480_1 = SiS_LVDSCRT1640x480_1;
SiS_Pr->SiS_LVDSCRT1640x480_1_H = SiS_LVDSCRT1640x480_1_H;
SiS_Pr->SiS_LVDSCRT1640x480_2 = SiS_LVDSCRT1640x480_2;
SiS_Pr->SiS_LVDSCRT1640x480_2_H = SiS_LVDSCRT1640x480_2_H;
SiS_Pr->SiS_LVDSCRT1640x480_3 = SiS_LVDSCRT1640x480_3;
SiS_Pr->SiS_LVDSCRT1640x480_3_H = SiS_LVDSCRT1640x480_3_H;
+
+ SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
+ SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
+
+ SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
+ SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
+ SiS_Pr->SiS_CHTVUPALDesData = SiS_CHTVUPALDesData;
+ SiS_Pr->SiS_CHTVOPALDesData = SiS_CHTVOPALDesData;
+
+ SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */
+ SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
}
+#endif
#ifdef SIS300
static void
SiS_StandTable[0x1c].CRTC[4] = 0x54;
SiS_StandTable[0x1c].CRTC[5] = 0x80;
- SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS300_SModeIDTable;
- SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
- SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS300_EModeIDTable;
- SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS300_RefIndex;
- SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
+ SiS_Pr->SiS_SModeIDTable = SiS300_SModeIDTable;
+ SiS_Pr->SiS_VBModeIDTable = SiS300_VBModeIDTable;
+ SiS_Pr->SiS_EModeIDTable = SiS300_EModeIDTable;
+ SiS_Pr->SiS_RefIndex = SiS300_RefIndex;
+ SiS_Pr->SiS_CRT1Table = SiS300_CRT1Table;
if(HwInfo->jChipType == SIS_300) {
- SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */
+ SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_300; /* 300 */
} else {
- SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
+ SiS_Pr->SiS_MCLKData_0 = SiS300_MCLKData_630; /* 630, 730 */
}
- SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS300_VCLKData;
+ SiS_Pr->SiS_VCLKData = SiS300_VCLKData;
SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
- SiS_Pr->SiS_ScreenOffset = SiS300_ScreenOffset;
SiS_Pr->SiS_SR15 = SiS300_SR15;
SiS_Pr->pSiS_YCSenseData2 = &SiS300_YCSenseData2;
#endif
- SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
- SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
- SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
- SiS_Pr->SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_StLCD1280x1024Data;
- SiS_Pr->SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_ExtLCD1280x1024Data;
- SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
- SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
- SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
-
- SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
- SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
-#if 0
- SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
-#endif
-
- SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
- SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
- SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
-
- SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
- SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
- SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
- SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS300_PanelType03_1;
- SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1;
- SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS300_PanelType05_1;
- SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS300_PanelType06_1;
- SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS300_PanelType07_1;
- SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS300_PanelType08_1;
- SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS300_PanelType09_1;
- SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_1;
- SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_1;
- SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_1;
- SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_1;
- SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_1;
- SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_1;
- SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS300_PanelType00_2;
- SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS300_PanelType01_2;
- SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS300_PanelType02_2;
- SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS300_PanelType03_2;
- SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2;
- SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS300_PanelType05_2;
- SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS300_PanelType06_2;
- SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS300_PanelType07_2;
- SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS300_PanelType08_2;
- SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS300_PanelType09_2;
- SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0a_2;
- SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0b_2;
- SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0c_2;
- SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
- SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
- SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
+ SiS_Pr->SiS_PanelDelayTbl = SiS300_PanelDelayTbl;
+ SiS_Pr->SiS_PanelDelayTblLVDS = SiS300_PanelDelayTbl;
+
+ SiS_Pr->SiS_ExtLCD1024x768Data = SiS300_ExtLCD1024x768Data;
+ SiS_Pr->SiS_St2LCD1024x768Data = SiS300_St2LCD1024x768Data;
+ SiS_Pr->SiS_ExtLCD1280x1024Data = SiS300_ExtLCD1280x1024Data;
+ SiS_Pr->SiS_St2LCD1280x1024Data = SiS300_St2LCD1280x1024Data;
+
+ SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS300_CRT2Part2_1024x768_1;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_1 = SiS300_CRT2Part2_1280x1024_1;
+ SiS_Pr->SiS_CRT2Part2_1024x768_2 = SiS300_CRT2Part2_1024x768_2;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_2 = SiS300_CRT2Part2_1280x1024_2;
+ SiS_Pr->SiS_CRT2Part2_1024x768_3 = SiS300_CRT2Part2_1024x768_3;
+ SiS_Pr->SiS_CRT2Part2_1280x1024_3 = SiS300_CRT2Part2_1280x1024_3;
+
+ SiS_Pr->SiS_CHTVUPALData = SiS300_CHTVUPALData;
+ SiS_Pr->SiS_CHTVOPALData = SiS300_CHTVOPALData;
+ SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVUPALNData = SiS300_CHTVUPALData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVOPALNData = SiS300_CHTVOPALData; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVSOPALData = SiS300_CHTVSOPALData;
+
+ SiS_Pr->SiS_PanelType00_1 = SiS300_PanelType00_1;
+ SiS_Pr->SiS_PanelType01_1 = SiS300_PanelType01_1;
+ SiS_Pr->SiS_PanelType02_1 = SiS300_PanelType02_1;
+ SiS_Pr->SiS_PanelType03_1 = SiS300_PanelType03_1;
+ SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1;
+ SiS_Pr->SiS_PanelType05_1 = SiS300_PanelType05_1;
+ SiS_Pr->SiS_PanelType06_1 = SiS300_PanelType06_1;
+ SiS_Pr->SiS_PanelType07_1 = SiS300_PanelType07_1;
+ SiS_Pr->SiS_PanelType08_1 = SiS300_PanelType08_1;
+ SiS_Pr->SiS_PanelType09_1 = SiS300_PanelType09_1;
+ SiS_Pr->SiS_PanelType0a_1 = SiS300_PanelType0a_1;
+ SiS_Pr->SiS_PanelType0b_1 = SiS300_PanelType0b_1;
+ SiS_Pr->SiS_PanelType0c_1 = SiS300_PanelType0c_1;
+ SiS_Pr->SiS_PanelType0d_1 = SiS300_PanelType0d_1;
+ SiS_Pr->SiS_PanelType0e_1 = SiS300_PanelType0e_1;
+ SiS_Pr->SiS_PanelType0f_1 = SiS300_PanelType0f_1;
+ SiS_Pr->SiS_PanelType00_2 = SiS300_PanelType00_2;
+ SiS_Pr->SiS_PanelType01_2 = SiS300_PanelType01_2;
+ SiS_Pr->SiS_PanelType02_2 = SiS300_PanelType02_2;
+ SiS_Pr->SiS_PanelType03_2 = SiS300_PanelType03_2;
+ SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2;
+ SiS_Pr->SiS_PanelType05_2 = SiS300_PanelType05_2;
+ SiS_Pr->SiS_PanelType06_2 = SiS300_PanelType06_2;
+ SiS_Pr->SiS_PanelType07_2 = SiS300_PanelType07_2;
+ SiS_Pr->SiS_PanelType08_2 = SiS300_PanelType08_2;
+ SiS_Pr->SiS_PanelType09_2 = SiS300_PanelType09_2;
+ SiS_Pr->SiS_PanelType0a_2 = SiS300_PanelType0a_2;
+ SiS_Pr->SiS_PanelType0b_2 = SiS300_PanelType0b_2;
+ SiS_Pr->SiS_PanelType0c_2 = SiS300_PanelType0c_2;
+ SiS_Pr->SiS_PanelType0d_2 = SiS300_PanelType0d_2;
+ SiS_Pr->SiS_PanelType0e_2 = SiS300_PanelType0e_2;
+ SiS_Pr->SiS_PanelType0f_2 = SiS300_PanelType0f_2;
+ SiS_Pr->SiS_PanelTypeNS_1 = SiS300_PanelTypeNS_1;
+ SiS_Pr->SiS_PanelTypeNS_2 = SiS300_PanelTypeNS_2;
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
- SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
- SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
+ SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1a;
+ SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2a;
}
if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
- SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
- SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
+ SiS_Pr->SiS_PanelType04_1 = SiS300_PanelType04_1b;
+ SiS_Pr->SiS_PanelType04_2 = SiS300_PanelType04_2b;
}
- SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
- SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
- SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
- SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
- SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
- SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
- SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
- SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
- SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
- SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
- SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
- SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
- SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
- SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1OPAL;
- SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1SOPAL;
- SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC;
- SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC;
- SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL;
- SiS_Pr->SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL;
- SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UNTSC; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_ONTSC; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_UPAL; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_OPAL; /* not supported on 300 series */
- SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS300_CHTVReg_SOPAL;
+ SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS300_LVDSCRT1800x600_1;
+ SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS300_LVDSCRT1800x600_1_H;
+ SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS300_LVDSCRT1800x600_2;
+ SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS300_LVDSCRT1800x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS300_LVDSCRT11024x768_1;
+ SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS300_LVDSCRT11024x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS300_LVDSCRT11024x768_2;
+ SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS300_LVDSCRT11024x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS300_LVDSCRT11280x1024_1;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS300_LVDSCRT11280x1024_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS300_LVDSCRT11280x1024_2;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS300_LVDSCRT11280x1024_2_H;
+ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS300_LVDSCRT1XXXxXXX_1;
+ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS300_LVDSCRT1XXXxXXX_1_H;
+
+ SiS_Pr->SiS_CHTVCRT1UNTSC = SiS300_CHTVCRT1UNTSC;
+ SiS_Pr->SiS_CHTVCRT1ONTSC = SiS300_CHTVCRT1ONTSC;
+ SiS_Pr->SiS_CHTVCRT1UPAL = SiS300_CHTVCRT1UPAL;
+ SiS_Pr->SiS_CHTVCRT1OPAL = SiS300_CHTVCRT1OPAL;
+ SiS_Pr->SiS_CHTVCRT1SOPAL = SiS300_CHTVCRT1SOPAL;
+ SiS_Pr->SiS_CHTVReg_UNTSC = SiS300_CHTVReg_UNTSC;
+ SiS_Pr->SiS_CHTVReg_ONTSC = SiS300_CHTVReg_ONTSC;
+ SiS_Pr->SiS_CHTVReg_UPAL = SiS300_CHTVReg_UPAL;
+ SiS_Pr->SiS_CHTVReg_OPAL = SiS300_CHTVReg_OPAL;
+ SiS_Pr->SiS_CHTVReg_UPALM = SiS300_CHTVReg_UNTSC; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_OPALM = SiS300_CHTVReg_ONTSC; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_UPALN = SiS300_CHTVReg_UPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_OPALN = SiS300_CHTVReg_OPAL; /* not supported on 300 series */
+ SiS_Pr->SiS_CHTVReg_SOPAL = SiS300_CHTVReg_SOPAL;
SiS_Pr->SiS_CHTVVCLKUNTSC = SiS300_CHTVVCLKUNTSC;
SiS_Pr->SiS_CHTVVCLKONTSC = SiS300_CHTVVCLKONTSC;
SiS_Pr->SiS_CHTVVCLKUPAL = SiS300_CHTVVCLKUPAL;
SiS_Pr->SiS_CHTVVCLKUPALN = SiS300_CHTVVCLKUPAL; /* not supported on 300 series */
SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL; /* not supported on 300 series */
SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
-
- SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
- SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
- SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
- SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_1;
- SiS_Pr->SiS_CRT2Part2_1024x768_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_2;
- SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_2;
- SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_2;
- SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_2;
- SiS_Pr->SiS_CRT2Part2_1024x768_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_3;
- SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_3;
- SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
- SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
-
- /* LCDResInfo will on 300 series be translated to 315 series definitions */
- SiS_Pr->SiS_Panel320x480 = Panel_320x480;
- SiS_Pr->SiS_Panel640x480 = Panel_640x480;
- SiS_Pr->SiS_Panel800x600 = Panel_800x600;
- SiS_Pr->SiS_Panel1024x768 = Panel_1024x768;
- SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
- SiS_Pr->SiS_Panel1280x960 = Panel_1280x960;
- SiS_Pr->SiS_Panel1024x600 = Panel_1024x600;
- SiS_Pr->SiS_Panel1152x768 = Panel_1152x768;
- SiS_Pr->SiS_Panel1280x768 = Panel_1280x768;
- SiS_Pr->SiS_Panel1600x1200 = 255; /* Something illegal */
- SiS_Pr->SiS_Panel1400x1050 = 255;
- SiS_Pr->SiS_Panel640x480_2 = 255;
- SiS_Pr->SiS_Panel640x480_3 = 255;
- SiS_Pr->SiS_Panel1152x864 = 255;
- SiS_Pr->SiS_PanelMax = Panel_320x480; /* highest value */
- SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* Lowest value LVDS */
- SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
- SiS_Pr->SiS_PanelCustom = Panel_Custom;
- SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
}
#endif
SiS_StandTable[0x1c].CRTC[4] = 0x55;
SiS_StandTable[0x1c].CRTC[5] = 0x81;
- SiS_Pr->SiS_SModeIDTable = (SiS_StStruct *)SiS310_SModeIDTable;
- SiS_Pr->SiS_EModeIDTable = (SiS_ExtStruct *)SiS310_EModeIDTable;
+ SiS_Pr->SiS_SModeIDTable = SiS310_SModeIDTable;
+ SiS_Pr->SiS_EModeIDTable = SiS310_EModeIDTable;
SiS_Pr->SiS_RefIndex = (SiS_Ext2Struct *)SiS310_RefIndex;
- SiS_Pr->SiS_CRT1Table = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
- if(HwInfo->jChipType >= SIS_661) {
- SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660; /* 661/741/760 */
+ SiS_Pr->SiS_CRT1Table = SiS310_CRT1Table;
+ if(HwInfo->jChipType >= SIS_760) {
+ SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_760; /* 760 */
+ } else if(HwInfo->jChipType >= SIS_661) {
+ SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_660; /* 661/741 */
} else if(HwInfo->jChipType == SIS_330) {
- SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330; /* 330 */
+ SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_330; /* 330 */
} else if(HwInfo->jChipType > SIS_315PRO) {
- SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650; /* 550, 650, 740 */
+ SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_650; /* 550, 650, 740 */
} else {
- SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315; /* 315 */
+ SiS_Pr->SiS_MCLKData_0 = SiS310_MCLKData_0_315; /* 315 */
}
- SiS_Pr->SiS_MCLKData_1 = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
- SiS_Pr->SiS_VCLKData = (SiS_VCLKDataStruct *)SiS310_VCLKData;
- SiS_Pr->SiS_VBVCLKData = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
- SiS_Pr->SiS_ScreenOffset = SiS310_ScreenOffset;
+ SiS_Pr->SiS_MCLKData_1 = SiS310_MCLKData_1;
+ SiS_Pr->SiS_VCLKData = SiS310_VCLKData;
+ SiS_Pr->SiS_VBVCLKData = SiS310_VBVCLKData;
SiS_Pr->SiS_SR15 = SiS310_SR15;
SiS_Pr->pSiS_YCSenseData2 = &SiS310_YCSenseData2;
#endif
- SiS_Pr->SiS_StLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
- SiS_Pr->SiS_ExtLCD1024x768Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
- SiS_Pr->SiS_St2LCD1024x768Data = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
- SiS_Pr->SiS_StLCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_StLCD1280x1024Data;
- SiS_Pr->SiS_ExtLCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_ExtLCD1280x1024Data;
- SiS_Pr->SiS_St2LCD1280x1024Data = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
- SiS_Pr->SiS_NoScaleData1024x768 = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
- SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
-
- SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
- SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
-
- SiS_Pr->SiS_CHTVUPALData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
- SiS_Pr->SiS_CHTVOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
- SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
- SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALMData;
- SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
- SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
- SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
-
- SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
- SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
- SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
- SiS_Pr->SiS_PanelType03_1 = (SiS_LVDSDesStruct *)SiS310_PanelType03_1;
- SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS310_PanelType04_1;
- SiS_Pr->SiS_PanelType05_1 = (SiS_LVDSDesStruct *)SiS310_PanelType05_1;
- SiS_Pr->SiS_PanelType06_1 = (SiS_LVDSDesStruct *)SiS310_PanelType06_1;
- SiS_Pr->SiS_PanelType07_1 = (SiS_LVDSDesStruct *)SiS310_PanelType07_1;
- SiS_Pr->SiS_PanelType08_1 = (SiS_LVDSDesStruct *)SiS310_PanelType08_1;
- SiS_Pr->SiS_PanelType09_1 = (SiS_LVDSDesStruct *)SiS310_PanelType09_1;
- SiS_Pr->SiS_PanelType0a_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_1;
- SiS_Pr->SiS_PanelType0b_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_1;
- SiS_Pr->SiS_PanelType0c_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_1;
- SiS_Pr->SiS_PanelType0d_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_1;
- SiS_Pr->SiS_PanelType0e_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_1;
- SiS_Pr->SiS_PanelType0f_1 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_1;
- SiS_Pr->SiS_PanelType00_2 = (SiS_LVDSDesStruct *)SiS310_PanelType00_2;
- SiS_Pr->SiS_PanelType01_2 = (SiS_LVDSDesStruct *)SiS310_PanelType01_2;
- SiS_Pr->SiS_PanelType02_2 = (SiS_LVDSDesStruct *)SiS310_PanelType02_2;
- SiS_Pr->SiS_PanelType03_2 = (SiS_LVDSDesStruct *)SiS310_PanelType03_2;
- SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS310_PanelType04_2;
- SiS_Pr->SiS_PanelType05_2 = (SiS_LVDSDesStruct *)SiS310_PanelType05_2;
- SiS_Pr->SiS_PanelType06_2 = (SiS_LVDSDesStruct *)SiS310_PanelType06_2;
- SiS_Pr->SiS_PanelType07_2 = (SiS_LVDSDesStruct *)SiS310_PanelType07_2;
- SiS_Pr->SiS_PanelType08_2 = (SiS_LVDSDesStruct *)SiS310_PanelType08_2;
- SiS_Pr->SiS_PanelType09_2 = (SiS_LVDSDesStruct *)SiS310_PanelType09_2;
- SiS_Pr->SiS_PanelType0a_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0a_2;
- SiS_Pr->SiS_PanelType0b_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0b_2;
- SiS_Pr->SiS_PanelType0c_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0c_2;
- SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
- SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
- SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
-
- SiS_Pr->SiS_CRT2Part2_1024x768_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
- SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
- SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
- SiS_Pr->SiS_CRT2Part2_1600x1200_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_1;
- SiS_Pr->SiS_CRT2Part2_1024x768_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_2;
- SiS_Pr->SiS_CRT2Part2_1280x1024_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_2;
- SiS_Pr->SiS_CRT2Part2_1400x1050_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_2;
- SiS_Pr->SiS_CRT2Part2_1600x1200_2 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_2;
- SiS_Pr->SiS_CRT2Part2_1024x768_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_3;
- SiS_Pr->SiS_CRT2Part2_1280x1024_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_3;
- SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
- SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
-
- SiS_Pr->SiS_LVDSCRT1800x600_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
- SiS_Pr->SiS_LVDSCRT11024x768_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
- SiS_Pr->SiS_LVDSCRT11280x1024_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
- SiS_Pr->SiS_LVDSCRT11400x1050_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
- SiS_Pr->SiS_LVDSCRT11600x1200_1 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
- SiS_Pr->SiS_LVDSCRT1800x600_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
- SiS_Pr->SiS_LVDSCRT11024x768_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
- SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
- SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
- SiS_Pr->SiS_LVDSCRT1800x600_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
- SiS_Pr->SiS_LVDSCRT11024x768_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
- SiS_Pr->SiS_LVDSCRT11280x1024_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
- SiS_Pr->SiS_LVDSCRT11400x1050_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
- SiS_Pr->SiS_LVDSCRT11600x1200_2 = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
- SiS_Pr->SiS_LVDSCRT1800x600_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
- SiS_Pr->SiS_LVDSCRT11024x768_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
- SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
- SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
- SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
- SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
- SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
- SiS_Pr->SiS_CHTVCRT1UPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
- SiS_Pr->SiS_CHTVCRT1OPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
- SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
-
- SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
- SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
- SiS_Pr->SiS_CHTVReg_UPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
- SiS_Pr->SiS_CHTVReg_OPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
- SiS_Pr->SiS_CHTVReg_UPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALM;
- SiS_Pr->SiS_CHTVReg_OPALM = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALM;
- SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
- SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
- SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPAL;
-
- SiS_Pr->SiS_LCDACRT11024x768_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
- SiS_Pr->SiS_LCDACRT11280x1024_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
- SiS_Pr->SiS_LCDACRT11400x1050_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1;
- SiS_Pr->SiS_LCDACRT11600x1200_1 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1;
- SiS_Pr->SiS_LCDACRT11024x768_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H;
- SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H;
- SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H;
- SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H;
- SiS_Pr->SiS_LCDACRT11024x768_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2;
- SiS_Pr->SiS_LCDACRT11280x1024_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2;
- SiS_Pr->SiS_LCDACRT11400x1050_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2;
- SiS_Pr->SiS_LCDACRT11600x1200_2 = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2;
- SiS_Pr->SiS_LCDACRT11024x768_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H;
- SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
- SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
- SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
+ SiS_Pr->SiS_PanelDelayTbl = SiS310_PanelDelayTbl;
+ SiS_Pr->SiS_PanelDelayTblLVDS = SiS310_PanelDelayTblLVDS;
+
+ SiS_Pr->SiS_St2LCD1024x768Data = SiS310_St2LCD1024x768Data;
+ SiS_Pr->SiS_ExtLCD1024x768Data = SiS310_ExtLCD1024x768Data;
+ SiS_Pr->SiS_St2LCD1280x1024Data = SiS310_St2LCD1280x1024Data;
+ SiS_Pr->SiS_ExtLCD1280x1024Data = SiS310_ExtLCD1280x1024Data;
+
+ SiS_Pr->SiS_CRT2Part2_1024x768_1 = SiS310_CRT2Part2_1024x768_1;
+
+ SiS_Pr->SiS_PanelType00_1 = SiS310_PanelType00_1;
+ SiS_Pr->SiS_PanelType01_1 = SiS310_PanelType01_1;
+ SiS_Pr->SiS_PanelType02_1 = SiS310_PanelType02_1;
+ SiS_Pr->SiS_PanelType03_1 = SiS310_PanelType03_1;
+ SiS_Pr->SiS_PanelType04_1 = SiS310_PanelType04_1;
+ SiS_Pr->SiS_PanelType05_1 = SiS310_PanelType05_1;
+ SiS_Pr->SiS_PanelType06_1 = SiS310_PanelType06_1;
+ SiS_Pr->SiS_PanelType07_1 = SiS310_PanelType07_1;
+ SiS_Pr->SiS_PanelType08_1 = SiS310_PanelType08_1;
+ SiS_Pr->SiS_PanelType09_1 = SiS310_PanelType09_1;
+ SiS_Pr->SiS_PanelType0a_1 = SiS310_PanelType0a_1;
+ SiS_Pr->SiS_PanelType0b_1 = SiS310_PanelType0b_1;
+ SiS_Pr->SiS_PanelType0c_1 = SiS310_PanelType0c_1;
+ SiS_Pr->SiS_PanelType0d_1 = SiS310_PanelType0d_1;
+ SiS_Pr->SiS_PanelType0e_1 = SiS310_PanelType0e_1;
+ SiS_Pr->SiS_PanelType0f_1 = SiS310_PanelType0f_1;
+ SiS_Pr->SiS_PanelType00_2 = SiS310_PanelType00_2;
+ SiS_Pr->SiS_PanelType01_2 = SiS310_PanelType01_2;
+ SiS_Pr->SiS_PanelType02_2 = SiS310_PanelType02_2;
+ SiS_Pr->SiS_PanelType03_2 = SiS310_PanelType03_2;
+ SiS_Pr->SiS_PanelType04_2 = SiS310_PanelType04_2;
+ SiS_Pr->SiS_PanelType05_2 = SiS310_PanelType05_2;
+ SiS_Pr->SiS_PanelType06_2 = SiS310_PanelType06_2;
+ SiS_Pr->SiS_PanelType07_2 = SiS310_PanelType07_2;
+ SiS_Pr->SiS_PanelType08_2 = SiS310_PanelType08_2;
+ SiS_Pr->SiS_PanelType09_2 = SiS310_PanelType09_2;
+ SiS_Pr->SiS_PanelType0a_2 = SiS310_PanelType0a_2;
+ SiS_Pr->SiS_PanelType0b_2 = SiS310_PanelType0b_2;
+ SiS_Pr->SiS_PanelType0c_2 = SiS310_PanelType0c_2;
+ SiS_Pr->SiS_PanelType0d_2 = SiS310_PanelType0d_2;
+ SiS_Pr->SiS_PanelType0e_2 = SiS310_PanelType0e_2;
+ SiS_Pr->SiS_PanelType0f_2 = SiS310_PanelType0f_2;
+ SiS_Pr->SiS_PanelTypeNS_1 = SiS310_PanelTypeNS_1;
+ SiS_Pr->SiS_PanelTypeNS_2 = SiS310_PanelTypeNS_2;
+
+ SiS_Pr->SiS_CHTVUPALData = SiS310_CHTVUPALData;
+ SiS_Pr->SiS_CHTVOPALData = SiS310_CHTVOPALData;
+ SiS_Pr->SiS_CHTVUPALMData = SiS310_CHTVUPALMData;
+ SiS_Pr->SiS_CHTVOPALMData = SiS310_CHTVOPALMData;
+ SiS_Pr->SiS_CHTVUPALNData = SiS310_CHTVUPALNData;
+ SiS_Pr->SiS_CHTVOPALNData = SiS310_CHTVOPALNData;
+ SiS_Pr->SiS_CHTVSOPALData = SiS310_CHTVSOPALData;
+
+ SiS_Pr->SiS_LVDSCRT1800x600_1 = SiS310_LVDSCRT1800x600_1;
+ SiS_Pr->SiS_LVDSCRT11024x768_1 = SiS310_LVDSCRT11024x768_1;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1 = SiS310_LVDSCRT11280x1024_1;
+ SiS_Pr->SiS_LVDSCRT11400x1050_1 = SiS310_LVDSCRT11400x1050_1;
+ SiS_Pr->SiS_LVDSCRT11600x1200_1 = SiS310_LVDSCRT11600x1200_1;
+ SiS_Pr->SiS_LVDSCRT1800x600_1_H = SiS310_LVDSCRT1800x600_1_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_1_H = SiS310_LVDSCRT11024x768_1_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_1_H = SiS310_LVDSCRT11280x1024_1_H;
+ SiS_Pr->SiS_LVDSCRT11400x1050_1_H = SiS310_LVDSCRT11400x1050_1_H;
+ SiS_Pr->SiS_LVDSCRT11600x1200_1_H = SiS310_LVDSCRT11600x1200_1_H;
+ SiS_Pr->SiS_LVDSCRT1800x600_2 = SiS310_LVDSCRT1800x600_2;
+ SiS_Pr->SiS_LVDSCRT11024x768_2 = SiS310_LVDSCRT11024x768_2;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2 = SiS310_LVDSCRT11280x1024_2;
+ SiS_Pr->SiS_LVDSCRT11400x1050_2 = SiS310_LVDSCRT11400x1050_2;
+ SiS_Pr->SiS_LVDSCRT11600x1200_2 = SiS310_LVDSCRT11600x1200_2;
+ SiS_Pr->SiS_LVDSCRT1800x600_2_H = SiS310_LVDSCRT1800x600_2_H;
+ SiS_Pr->SiS_LVDSCRT11024x768_2_H = SiS310_LVDSCRT11024x768_2_H;
+ SiS_Pr->SiS_LVDSCRT11280x1024_2_H = SiS310_LVDSCRT11280x1024_2_H;
+ SiS_Pr->SiS_LVDSCRT11400x1050_2_H = SiS310_LVDSCRT11400x1050_2_H;
+ SiS_Pr->SiS_LVDSCRT11600x1200_2_H = SiS310_LVDSCRT11600x1200_2_H;
+ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1 = SiS310_LVDSCRT1XXXxXXX_1;
+ SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H = SiS310_LVDSCRT1XXXxXXX_1_H;
+ SiS_Pr->SiS_CHTVCRT1UNTSC = SiS310_CHTVCRT1UNTSC;
+ SiS_Pr->SiS_CHTVCRT1ONTSC = SiS310_CHTVCRT1ONTSC;
+ SiS_Pr->SiS_CHTVCRT1UPAL = SiS310_CHTVCRT1UPAL;
+ SiS_Pr->SiS_CHTVCRT1OPAL = SiS310_CHTVCRT1OPAL;
+ SiS_Pr->SiS_CHTVCRT1SOPAL = SiS310_CHTVCRT1OPAL;
+
+ SiS_Pr->SiS_CHTVReg_UNTSC = SiS310_CHTVReg_UNTSC;
+ SiS_Pr->SiS_CHTVReg_ONTSC = SiS310_CHTVReg_ONTSC;
+ SiS_Pr->SiS_CHTVReg_UPAL = SiS310_CHTVReg_UPAL;
+ SiS_Pr->SiS_CHTVReg_OPAL = SiS310_CHTVReg_OPAL;
+ SiS_Pr->SiS_CHTVReg_UPALM = SiS310_CHTVReg_UPALM;
+ SiS_Pr->SiS_CHTVReg_OPALM = SiS310_CHTVReg_OPALM;
+ SiS_Pr->SiS_CHTVReg_UPALN = SiS310_CHTVReg_UPALN;
+ SiS_Pr->SiS_CHTVReg_OPALN = SiS310_CHTVReg_OPALN;
+ SiS_Pr->SiS_CHTVReg_SOPAL = SiS310_CHTVReg_OPAL;
SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
SiS_Pr->SiS_CHTVVCLKUPALM = SiS310_CHTVVCLKUPALM;
SiS_Pr->SiS_CHTVVCLKOPALM = SiS310_CHTVVCLKOPALM;
SiS_Pr->SiS_CHTVVCLKUPALN = SiS310_CHTVVCLKUPALN;
- SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
+ SiS_Pr->SiS_CHTVVCLKOPALN = SiS310_CHTVVCLKOPALN;
SiS_Pr->SiS_CHTVVCLKSOPAL = SiS310_CHTVVCLKOPAL;
-
- SiS_Pr->SiS_Panel320x480 = Panel_320x480;
- SiS_Pr->SiS_Panel640x480 = Panel_640x480;
- SiS_Pr->SiS_Panel800x600 = Panel_800x600;
- SiS_Pr->SiS_Panel1024x768 = Panel_1024x768;
- SiS_Pr->SiS_Panel1280x1024 = Panel_1280x1024;
- SiS_Pr->SiS_Panel1280x960 = Panel_1280x960;
- SiS_Pr->SiS_Panel1600x1200 = Panel_1600x1200;
- SiS_Pr->SiS_Panel1400x1050 = Panel_1400x1050;
- SiS_Pr->SiS_Panel1152x768 = Panel_1152x768;
- SiS_Pr->SiS_Panel1152x864 = Panel_1152x864;
- SiS_Pr->SiS_Panel1280x768 = Panel_1280x768;
- SiS_Pr->SiS_Panel1024x600 = Panel_1024x600;
- SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
- SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
- SiS_Pr->SiS_PanelMax = Panel_320x480; /* highest value */
- SiS_Pr->SiS_PanelMinLVDS = Panel_800x600; /* lowest value LVDS/LCDA */
- SiS_Pr->SiS_PanelMin301 = Panel_1024x768; /* lowest value 301 */
- SiS_Pr->SiS_PanelCustom = Panel_Custom;
- SiS_Pr->SiS_PanelBarco1366 = 255;
}
#endif
/*********************************************/
USHORT
-SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN)
+SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
{
USHORT ModeIndex = 0;
else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
break;
case 720:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
- else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
- }
+ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+ else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
break;
case 768:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
- }
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
break;
case 800:
- if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
- else if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
- }
+ if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+ else if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
break;
case 848:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
- }
+ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
break;
case 856:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ break;
+ case 960:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
}
break;
case 1024:
- if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
- else if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
- else if(VGAEngine == SIS_300_VGA) {
- if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
- }
+ if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+ else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+ else if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
+ if(VDisplay == 600) ModeIndex = ModeIndex_1024x600[Depth];
}
break;
case 1152:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
- else if(VGAEngine == SIS_300_VGA) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
- }
+ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+ if((!(VBFlags & CRT1_LCDA)) && (VGAEngine == SIS_300_VGA)) {
+ if(VDisplay == 768) ModeIndex = ModeIndex_1152x768[Depth];
}
break;
case 1280:
- if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
- else if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
- else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
+ if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+ else if(VDisplay == 800) {
+ if(VGAEngine == SIS_315_VGA) {
+ if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 800)) {
+ ModeIndex = ModeIndex_1280x800[Depth];
+ } else if(!(VBFlags & CRT1_LCDA)) {
+ ModeIndex = ModeIndex_1280x800[Depth];
+ }
+ }
+ } else if(VDisplay == 720) {
+ if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
+ ModeIndex = ModeIndex_1280x720[Depth];
+ } else if(!(VBFlags & CRT1_LCDA)) {
+ ModeIndex = ModeIndex_1280x720[Depth];
+ }
+ } else if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
else if(VDisplay == 768) {
if(VGAEngine == SIS_300_VGA) {
ModeIndex = ModeIndex_300_1280x768[Depth];
}
break;
case 1360:
+ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
- else if(VGAEngine == SIS_300_VGA) {
+ if(VGAEngine == SIS_300_VGA) {
if(VDisplay == 1024) ModeIndex = ModeIndex_300_1360x1024[Depth];
}
}
break;
case 1400:
if(VGAEngine == SIS_315_VGA) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+ if(VDisplay == 1050) {
+ if((VBFlags & CRT1_LCDA) &&
+ (((LCDwidth == 1400) && (LCDheight == 1050)) ||
+ ((LCDwidth == 1600) && (LCDheight == 1200)))) {
+ ModeIndex = ModeIndex_1400x1050[Depth];
+ } else if(!(VBFlags & CRT1_LCDA)) {
+ ModeIndex = ModeIndex_1400x1050[Depth];
+ }
+ }
}
break;
case 1600:
if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
break;
+ case 1680:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+ }
+ break;
case 1920:
if(!(VBFlags & CRT1_LCDA)) {
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 1080) ModeIndex = ModeIndex_1920x1080[Depth];
+ }
if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
}
break;
break;
case 400:
if(CustomT != CUT_PANEL848) {
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ }
}
break;
case 512:
if(CustomT != CUT_PANEL848) {
- if(VDisplay == 384) {
+ if(!((VGAEngine == SIS_300_VGA) && (VBFlags & VB_TRUMPION))) {
if(LCDwidth != 1024 || LCDheight != 600) {
- ModeIndex = ModeIndex_512x384[Depth];
+ if(VDisplay == 384) {
+ ModeIndex = ModeIndex_512x384[Depth];
+ }
}
}
}
if((VDisplay == 768) && (LCDheight == 768)) {
ModeIndex = ModeIndex_310_1280x768[Depth];
}
+ if((VDisplay == 800) && (LCDheight == 800)) {
+ ModeIndex = ModeIndex_310_1280x768[Depth];
+ }
}
break;
case 1360:
if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
break;
+ case 720:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+ else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+ }
+ break;
+ case 768:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+ }
+ break;
case 800:
if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+ }
+ break;
+ case 848:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+ }
+ break;
+ case 856:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ }
+ break;
+ case 960:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+ }
break;
case 1024:
if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+ }
+ break;
+ case 1152:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+ }
break;
case 1280:
if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
else if(VDisplay == 768) {
- if((LCDheight == 768) ||
- ((LCDheight == 1024) && (VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)))) {
+ if((LCDheight == 768) || (LCDwidth == 1680) ||
+ (VBFlags & VB_SISTMDS)) {
if(VGAEngine == SIS_300_VGA) {
ModeIndex = ModeIndex_300_1280x768[Depth];
} else {
}
}
} else if(VDisplay == 960) {
- if((LCDheight == 960) ||
- ((LCDheight == 1024) && (VBFlags & (VB_301|VB_301B|VB_301C|VB_302B)))) {
+ if((LCDheight == 960) || (VBFlags & VB_SISTMDS)) {
ModeIndex = ModeIndex_1280x960[Depth];
}
+ } else if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 800) {
+ if((LCDheight == 800) || (LCDwidth == 1680) ||
+ (VBFlags & VB_SISTMDS)) {
+ ModeIndex = ModeIndex_1280x800[Depth];
+ }
+ } else if(VDisplay == 720) {
+ if((LCDheight == 720) || (LCDwidth == 1680) || (LCDwidth == 1400) ||
+ (VBFlags & VB_SISTMDS)) {
+ ModeIndex = ModeIndex_1280x720[Depth];
+ }
+ }
+ }
+ break;
+ case 1360:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
}
break;
case 1400:
if(VGAEngine == SIS_315_VGA) {
if(VBFlags & (VB_301B | VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
- if(LCDheight != 1200) {
- if(VDisplay == 1050) ModeIndex = ModeIndex_1400x1050[Depth];
+ if((LCDwidth == 1400) || (LCDwidth == 1600) || (LCDwidth == 1680)) {
+ ModeIndex = ModeIndex_1400x1050[Depth];
}
}
}
break;
case 1600:
- if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+ if(VGAEngine == SIS_315_VGA) {
+ if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+ if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+ }
+ }
+ break;
+ case 1680:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VBFlags & (VB_301C | VB_302B | VB_302LV | VB_302ELV)) {
+ if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+ }
}
break;
}
if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
break;
case 512:
- if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I))) ||
- (VBFlags & TV_HIVISION) ||
+ if( ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR750P | TV_YPBPR1080I))) ||
+ (VBFlags & TV_HIVISION) ||
((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
}
case 720:
if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
if(VDisplay == 480) {
- if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM)))
+ /* if((VBFlags & TV_YPBPR) || (VBFlags & (TV_NTSC | TV_PALM))) */
ModeIndex = ModeIndex_720x480[Depth];
} else if(VDisplay == 576) {
- if((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL))
+ if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
+ ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) )
ModeIndex = ModeIndex_720x576[Depth];
}
}
break;
case 768:
if((!(VBFlags & TV_HIVISION)) && (!((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I)))) {
- if((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) {
+ if( ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR750P)) ||
+ ((!(VBFlags & (TV_YPBPR | TV_PALM))) && (VBFlags & TV_PAL)) ) {
if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
}
}
}
break;
case 1280:
- if((VBFlags & TV_HIVISION) || ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
- if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
- else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+ if(VDisplay == 720) {
+ if((VBFlags & TV_HIVISION) ||
+ ((VBFlags & TV_YPBPR) && (VBFlags & (TV_YPBPR1080I | TV_YPBPR750P)))) {
+ ModeIndex = ModeIndex_1280x720[Depth];
+ }
+ } else if(VDisplay == 1024) {
+ if((VBFlags & TV_HIVISION) ||
+ ((VBFlags & TV_YPBPR) && (VBFlags & TV_YPBPR1080I))) {
+ ModeIndex = ModeIndex_1280x1024[Depth];
+ }
}
break;
}
case 856:
if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
break;
+ case 960:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth];
+ }
+ break;
case 1024:
if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
else if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
}
} else if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
else if(VDisplay == 720) ModeIndex = ModeIndex_1280x720[Depth];
+ else if(VDisplay == 800) ModeIndex = ModeIndex_1280x800[Depth];
else if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
break;
case 1360:
}
}
break;
+ case 1680:
+ if(VGAEngine == SIS_315_VGA) {
+ if(VBFlags & (VB_301B|VB_301C|VB_302B)) {
+ if(VDisplay == 1050) ModeIndex = ModeIndex_1680x1050[Depth];
+ }
+ }
+ break;
}
return ModeIndex;
void
SiS_DisplayOn(SiS_Private *SiS_Pr)
{
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xDF);
}
void
SiS_DisplayOff(SiS_Private *SiS_Pr)
{
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);
}
/* (SR11 is used for DDC and in enable/disablebridge) */
SiS_Pr->SiS_SensibleSR11 = FALSE;
SiS_Pr->SiS_MyCR63 = 0x63;
- if(HwInfo->jChipType >= SIS_661) {
- SiS_Pr->SiS_SensibleSR11 = TRUE;
+ if(HwInfo->jChipType >= SIS_330) {
SiS_Pr->SiS_MyCR63 = 0x53;
+ if(HwInfo->jChipType >= SIS_661) {
+ SiS_Pr->SiS_SensibleSR11 = TRUE;
+ }
}
/* You should use the macros, not these flags directly */
}
}
}
+ if(HwInfo->jChipType == SIS_760) {
+ temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78);
+ if(temp1 & 0x30) SiS_Pr->SiS_SysFlags |= SF_760LFB;
+ }
}
/*********************************************/
void
SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- ULONG temp;
+ USHORT temp;
SiS_Pr->SiS_IF_DEF_LVDS = 0;
SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
SiS_Pr->SiS_ChrontelInit = 0;
+ /* Check for SiS30x first */
+ temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+ if((temp == 1) || (temp == 2)) return;
+
switch(HwInfo->jChipType) {
#ifdef SIS300
case SIS_540:
case SIS_630:
case SIS_730:
- /* Check for SiS30x first */
- temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
- if((temp == 1) || (temp == 2)) return;
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
temp = (temp & 0x0E) >> 1;
- if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
- if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
+ if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
if((temp == 4) || (temp == 5)) {
/* Save power status (and error check) - UNUSED */
SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
case SIS_330:
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
temp = (temp & 0x0E) >> 1;
- if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
- if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+ if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
break;
case SIS_661:
case SIS_741:
case SIS_760:
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
temp = (temp & 0xe0) >> 5;
- if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
- if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
- if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
+ if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+ if(temp == 3) SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+ if(temp == 4) SiS_Pr->SiS_IF_DEF_CONEX = 1; /* Not yet supported */
break;
#endif
default:
/* HELPER: Determine ROM usage */
/*********************************************/
+BOOLEAN
+SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ USHORT romversoffs, romvmaj = 1, romvmin = 0;
+
+ if(HwInfo->jChipType >= SIS_661) {
+ if((ROMAddr[0x1a] == 'N') &&
+ (ROMAddr[0x1b] == 'e') &&
+ (ROMAddr[0x1c] == 'w') &&
+ (ROMAddr[0x1d] == 'V')) {
+ return TRUE;
+ }
+ romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
+ if(romversoffs) {
+ if((ROMAddr[romversoffs+1] == '.') || (ROMAddr[romversoffs+4] == '.')) {
+ romvmaj = ROMAddr[romversoffs] - '0';
+ romvmin = ((ROMAddr[romversoffs+2] -'0') * 10) + (ROMAddr[romversoffs+3] - '0');
+ }
+ }
+ if((romvmaj != 0) || (romvmin >= 92)) {
+ return TRUE;
+ }
+ } else if(IS_SIS650740) {
+ if((ROMAddr[0x1a] == 'N') &&
+ (ROMAddr[0x1b] == 'e') &&
+ (ROMAddr[0x1c] == 'w') &&
+ (ROMAddr[0x1d] == 'V')) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void
SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ USHORT romptr = 0;
+
+ SiS_Pr->SiS_UseROM = FALSE;
+ SiS_Pr->SiS_ROMNew = FALSE;
if((ROMAddr) && (HwInfo->UseROM)) {
- if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
- SiS_Pr->SiS_UseROM = FALSE;
- } else if(HwInfo->jChipType == SIS_300) {
- /* 300: We check if the code starts below 0x220 by
- * checking the jmp instruction at the beginning
- * of the BIOS image.
- */
- if((ROMAddr[3] == 0xe9) &&
- ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
+ if(HwInfo->jChipType == SIS_300) {
+ /* 300: We check if the code starts below 0x220 by
+ * checking the jmp instruction at the beginning
+ * of the BIOS image.
+ */
+ if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
SiS_Pr->SiS_UseROM = TRUE;
- else
- SiS_Pr->SiS_UseROM = FALSE;
} else if(HwInfo->jChipType < SIS_315H) {
-#if 0
- /* Rest of 300 series: We don't use the ROM image if
- * the BIOS version < 2.0.0 as such old BIOSes don't
- * have the needed data at the expected locations.
- */
- if(ROMAddr[0x06] < '2') SiS_Pr->SiS_UseROM = FALSE;
- else SiS_Pr->SiS_UseROM = TRUE;
-#else
- /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
- * the others do as well
- */
+ /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
+ * the others do as well
+ */
SiS_Pr->SiS_UseROM = TRUE;
-#endif
} else {
- /* 315/330 series stick to the standard */
+ /* 315/330 series stick to the standard(s) */
SiS_Pr->SiS_UseROM = TRUE;
+ if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr, HwInfo))) {
+ /* Find out about LCD data table entry size */
+ if((romptr = SISGETROMW(0x0102))) {
+ if(ROMAddr[romptr + (32 * 16)] == 0xff)
+ SiS_Pr->SiS661LCD2TableSize = 32;
+ else if(ROMAddr[romptr + (34 * 16)] == 0xff)
+ SiS_Pr->SiS661LCD2TableSize = 34;
+ else if(ROMAddr[romptr + (36 * 16)] == 0xff)
+ SiS_Pr->SiS661LCD2TableSize = 36; /* 0.94 final */
+ }
+ }
}
- } else SiS_Pr->SiS_UseROM = FALSE;
-
+ }
}
/*********************************************/
SiS_Pr->SiS_VBType = 0;
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
+ if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX))
+ return;
flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
if(flag >= 2) {
SiS_Pr->SiS_VBType = VB_SIS302B;
} else if(flag == 1) {
- SiS_Pr->SiS_VBType = VB_SIS301;
if(rev >= 0xC0) {
SiS_Pr->SiS_VBType = VB_SIS301C;
} else if(rev >= 0xB0) {
/* Check if 30xB DH version (no LCD support, use Panel Link instead) */
nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
+ } else {
+ SiS_Pr->SiS_VBType = VB_SIS301;
}
}
if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
- if(rev >= 0xD0) {
- SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS301C | VB_SIS302B | VB_NoLCD);
- if(rev >= 0xE0) {
- flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
- if(flag == 0xff)
- SiS_Pr->SiS_VBType |= VB_SIS302LV;
- else
- SiS_Pr->SiS_VBType |= VB_SIS302ELV;
- } else {
- SiS_Pr->SiS_VBType |= VB_SIS301LV;
- }
+ if(rev >= 0xE0) {
+ flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39);
+ if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV;
+ else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */
+ } else if(rev >= 0xD0) {
+ SiS_Pr->SiS_VBType = VB_SIS301LV;
}
}
}
-/*********************************************/
-/* HELPER: GetDRAMSize */
-/*********************************************/
-
-#ifndef LINUX_XF86
-static ULONG
-GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
-{
- ULONG AdapterMemorySize = 0;
-#ifdef SIS315H
- USHORT counter;
-#endif
-
- switch(HwInfo->jChipType) {
-#ifdef SIS315H
- case SIS_315H:
- case SIS_315:
- case SIS_315PRO:
- counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
- counter >>= 2;
- counter &= 0x03;
- if(counter == 0x02) {
- AdapterMemorySize += (AdapterMemorySize / 2); /* DDR asymetric */
- } else if(counter != 0) {
- AdapterMemorySize <<= 1; /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
- }
- AdapterMemorySize *= (1024*1024);
- break;
-
- case SIS_330:
- counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
- AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
- counter &= 0x0c;
- if(counter != 0) {
- AdapterMemorySize <<= 1;
- }
- AdapterMemorySize *= (1024*1024);
- break;
-
- case SIS_550:
- case SIS_650:
- case SIS_740:
- counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
- counter++;
- AdapterMemorySize = counter * 4;
- AdapterMemorySize *= (1024*1024);
- break;
-
- case SIS_661:
- case SIS_741:
- case SIS_660:
- case SIS_760:
- counter = (SiS_GetReg(SiS_Pr->SiS_P3c4,0x79) & 0xf0) >> 4;
- AdapterMemorySize = 1 << counter;
- AdapterMemorySize *= (1024*1024);
- break;
-#endif
-
-#ifdef SIS300
- case SIS_300:
- case SIS_540:
- case SIS_630:
- case SIS_730:
- AdapterMemorySize = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
- AdapterMemorySize++;
- AdapterMemorySize *= (1024*1024);
- break;
-#endif
- default:
- break;
- }
-
- return AdapterMemorySize;
-}
-#endif
-
/*********************************************/
/* HELPER: Check RAM size */
/*********************************************/
SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
USHORT ModeNo, USHORT ModeIdIndex)
{
+ USHORT AdapterMemSize = HwInfo->ulVideoMemorySize / (1024*1024);
USHORT memorysize,modeflag;
- ULONG temp;
if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
memorysize >>= MemorySizeShift; /* Get required memory size */
memorysize++;
- temp = GetDRAMSize(SiS_Pr, HwInfo); /* Get adapter memory size (in MB) */
- temp /= (1024*1024);
-
- if(temp < memorysize) return(FALSE);
- else return(TRUE);
+ if(AdapterMemSize < memorysize) return FALSE;
+ return TRUE;
}
#endif
{
UCHAR data, temp;
- if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
- data = *SiS_Pr->pSiS_SoftSetting & 0x03;
+ if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) {
+ data = (*SiS_Pr->pSiS_SoftSetting) & 0x03;
} else {
if(HwInfo->jChipType >= SIS_661) {
data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07;
+ if(SiS_Pr->SiS_ROMNew) {
+ data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
+ }
} else if(IS_SIS550650740) {
data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
} else { /* 315, 330 */
USHORT
SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT index;
index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->SiS_ROMNew) {
+ return((USHORT)(SISGETROMW((0x90 + (index * 5) + 3))));
+ }
return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
} else if(index >= 4) {
index -= 4;
if(SiS_Pr->SiS_ModeType >= ModeEGA) {
if(ModeNo > 0x13) {
- AdapterMemorySize = GetDRAMSize(SiS_Pr, HwInfo);
- SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
+ SiS_SetMemory(VideoMemoryAddress, AdapterMemorySize, 0);
} else {
pBuffer = (USHORT *)VideoMemoryAddress;
- for(i=0; i<0x4000; i++)
- pBuffer[i] = 0x0000;
+ for(i=0; i<0x4000; i++) pBuffer[i] = 0x0000;
}
} else {
- pBuffer = (USHORT *)VideoMemoryAddress;
if(SiS_Pr->SiS_ModeType < ModeCGA) {
- for(i=0; i<0x4000; i++)
- pBuffer[i] = 0x0720;
+ pBuffer = (USHORT *)VideoMemoryAddress;
+ for(i=0; i<0x4000; i++) pBuffer[i] = 0x0720;
} else {
- SiS_SetMemory(VideoMemoryAddress,0x8000,0);
+ SiS_SetMemory(VideoMemoryAddress, 0x8000, 0);
}
}
}
UCHAR index;
if(ModeNo <= 0x13) {
- index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+ index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
} else {
- if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B; /* 02 -> ModeEGA */
- else index = 0x0F;
+ if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B;
+ else index = 0x0F;
}
return index;
}
USHORT temp,temp1,temp2;
if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
- return(1);
+ return(TRUE);
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
if((HwInfo->jChipType >= SIS_315H) ||
(HwInfo->jChipType == SIS_300)) {
- if(temp2 == 0x55) return(0);
- else return(1);
+ if(temp2 == 0x55) return(FALSE);
+ else return(TRUE);
} else {
- if(temp2 != 0x55) return(1);
+ if(temp2 != 0x55) return(TRUE);
else {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
- return(0);
+ return(FALSE);
}
}
}
}
}
+/*********************************************/
+/* HELPER: ENABLE CRT1 */
+/*********************************************/
+
+static void
+SiS_SetupCR5x(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(IS_SIS650) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+ if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+ } else if(IS_SIS661741660760) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+ if(!SiS_Pr->SiS_ROMNew) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
+ }
+ }
+ }
+}
+
+static void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
+{
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
+#if 0
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
+ if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
+ (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
+ }
+ }
+#endif
+}
+
/*********************************************/
/* HELPER: GetColorDepth */
/*********************************************/
SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
{
- USHORT temp,colordepth,infoflag;
+ USHORT xres, temp, colordepth, infoflag;
if(SiS_Pr->UseCustomMode) {
infoflag = SiS_Pr->CInfoFlag;
- temp = SiS_Pr->CHDisplay / 16;
+ xres = SiS_Pr->CHDisplay;
} else {
infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- temp = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeOffset;
- temp = SiS_Pr->SiS_ScreenOffset[temp];
+ xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
}
colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
+ temp = xres / 16;
if(infoflag & InterlaceMode) temp <<= 1;
-
temp *= colordepth;
-
- if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
- ModeNo == 0x3f ||
- ModeNo == 0x42 ||
- ModeNo == 0x45 ) ||
- (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+ if(xres % 16) {
colordepth >>= 1;
temp += colordepth;
}
CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata); /* Set CRTC(3d4) */
}
- if( ( (HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ) &&
- (HwInfo->jChipRevision >= 0x30) ) { /* for 630S0 */
+ if(HwInfo->jChipType >= SIS_661) {
+ SiS_SetupCR5x(SiS_Pr, HwInfo);
+ for(i = 0x13; i <= 0x14; i++) {
+ CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+ SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);
+ }
+ } else if( ( (HwInfo->jChipType == SIS_630) ||
+ (HwInfo->jChipType == SIS_730) ) &&
+ (HwInfo->jChipRevision >= 0x30) ) { /* for 630S0 */
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
/*********************************************/
static void
-SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
{
USHORT i;
if(HwInfo->jChipType >= SIS_315H) {
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+ if(ModeNo <= 0x13) {
+ if(ModeNo == 0x06 || ModeNo >= 0x0e) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e,0x20);
+ }
+ }
}
}
/* CRTC/2 */
/*********************************************/
-#ifdef SIS315H
-static void
-SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, USHORT *ResIndex,
- USHORT *DisplayType)
- {
- USHORT modeflag = 0;
-
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- *ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- *ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- *ResIndex &= 0x3F;
-
- *DisplayType = SiS_Pr->SiS_LCDResInfo;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 32;
- if(modeflag & HalfDCLK) *DisplayType += 16;
-
- if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- *DisplayType = 100;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 2;
- if(modeflag & HalfDCLK) *DisplayType += 1;
- }
- } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- *DisplayType = 104;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 2;
- if(modeflag & HalfDCLK) *DisplayType += 1;
- }
- }
-
-}
-#endif
-
static void
SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
USHORT RefreshRateTableIndex,
{
UCHAR index;
USHORT temp,i,j,modeflag;
-#ifdef SIS315H
- USHORT ResIndex,DisplayType;
- const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
-#endif
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /* unlock cr0-7 */
modeflag = SiS_Pr->CModeFlag;
- for(i=0,j=0;i<=07;i++,j++) {
+ for(i=0,j=0;i<=7;i++,j++) {
SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
}
for(j=0x10;i<=10;i++,j++) {
temp = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
if(modeflag & DoubleScanMode) temp |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
}
- if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-
-#ifdef SIS315H
-
- SiS_GetLCDACRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, &ResIndex, &DisplayType);
-
- switch(DisplayType) {
- case Panel_1024x768 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break;
- case Panel_1280x1024 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1; break;
- case Panel_1400x1050 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1; break;
- case Panel_1600x1200 : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1; break;
- case Panel_1024x768 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H; break;
- case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H; break;
- case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H; break;
- case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H; break;
- case Panel_1024x768 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2; break;
- case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2; break;
- case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2; break;
- case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2; break;
- case Panel_1024x768 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H; break;
- case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H; break;
- case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H; break;
- case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H; break;
- case 100: LCDACRT1Ptr = Compaq1280x1024_LCDACRT1_1; break;
- case 101: LCDACRT1Ptr = Compaq1280x1024_LCDACRT1_1_H; break;
- case 102: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2; break;
- case 103: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H; break;
- case 104: LCDACRT1Ptr = Clevo1024x768_LCDACRT1_1; break;
- case 105: LCDACRT1Ptr = Clevo1024x768_LCDACRT1_1_H; break;
- case 106: LCDACRT1Ptr = Clevo1024x768_LCDACRT1_2; break;
- case 107: LCDACRT1Ptr = Clevo1024x768_LCDACRT1_2_H; break;
- default: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1; break;
- }
+ index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- for(i=0, j=0; i<=0x07; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
- }
- for(i=0x10, j=8; i<=0x12; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
- }
- for(i=0x15, j=11; i<=0x16; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
- }
- for(i=0x0A, j=13; i<=0x0C; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,i,(LCDACRT1Ptr+ResIndex)->CR[j]);
- }
-
- temp = (LCDACRT1Ptr+ResIndex)->CR[16] & 0xE0;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
-
- temp = ((LCDACRT1Ptr+ResIndex)->CR[16] & 0x01) << 5;
- if(modeflag & DoubleScanMode) temp |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
-
-#endif
-
- } else {
-
- index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
- for(i=0,j=0;i<=07;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
- for(j=0x10;i<=10;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
- for(j=0x15;i<=12;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
- for(j=0x0A;i<=15;i++,j++) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
- }
+ for(i=0,j=0;i<=7;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->SiS_CRT1Table[index].CR[i]);
+ }
- temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
+ temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0;
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,temp);
- temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
- if(modeflag & DoubleScanMode) temp |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,temp);
+ temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5;
+ if(modeflag & DoubleScanMode) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,temp);
- }
}
if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
DisplayUnit <<= 5;
temp = (DisplayUnit & 0xff00) >> 8;
- if (DisplayUnit & 0xff) temp++;
+ if(DisplayUnit & 0xff) temp++;
temp++;
SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
}
{
USHORT modeflag;
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE); /* disable auto-threshold */
+ /* disable auto-threshold */
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);
if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
}
- if(HwInfo->jChipType >= SIS_661) {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
- if(ModeNo > 0x13) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+ if(ModeNo > 0x13) {
+ if(HwInfo->jChipType >= SIS_661) {
if(!(modeflag & HalfDCLK)) {
SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
- if(ModeNo != 0x38) {
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
- }
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
}
- }
- } else {
- if(ModeNo > 0x13) {
- if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+ } else {
+ if((!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
- }
- } else {
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+ }
}
}
}
USHORT ModeNo, USHORT RefreshRateTableIndex,
USHORT ModeIdIndex)
{
- USHORT data, data2=0;
- USHORT VCLK, index=0;
+ USHORT data=0, VCLK=0, index=0;
- if(ModeNo <= 0x13) VCLK = 0;
- else {
+ if(ModeNo > 0x13) {
if(SiS_Pr->UseCustomMode) {
VCLK = SiS_Pr->CSRClock;
} else {
index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
+ RefreshRateTableIndex,HwInfo);
VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
}
}
- if(HwInfo->jChipType < SIS_315H) { /* 300 series */
+ if(HwInfo->jChipType < SIS_315H) {
- data2 = 0x00;
- if(VCLK > 150) data2 |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2);
+ if(VCLK > 150) data |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
- data2 = 0x00;
- if(VCLK >= 150) data2 |= 0x08;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+ data = 0x00;
+ if(VCLK >= 150) data |= 0x08;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
- } else { /* 315 series */
+ } else {
- data = 0;
if(VCLK >= 166) data |= 0x0c;
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
}
}
- data2 = 0x03;
- if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
- else if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
- else if(VCLK >= 260) data2 = 0x00;
+ /* DAC speed */
+ if(HwInfo->jChipType >= SIS_661) {
- if(HwInfo->jChipType == SIS_540) {
- if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
- }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xE8,0x10);
- if(HwInfo->jChipType < SIS_315H) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2); /* DAC speed */
} else {
- if(HwInfo->jChipType > SIS_315PRO) {
- /* This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */
- if(ModeNo > 0x13) data2 &= 0xfc;
+
+ data = 0x03;
+ if((VCLK >= 135) && (VCLK < 160)) data = 0x02;
+ else if((VCLK >= 160) && (VCLK < 260)) data = 0x01;
+ else if(VCLK >= 260) data = 0x00;
+
+ if(HwInfo->jChipType == SIS_540) {
+ if((VCLK == 203) || (VCLK < 234)) data = 0x02;
+ }
+
+ if(HwInfo->jChipType < SIS_315H) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data);
+ } else {
+ if(HwInfo->jChipType > SIS_315PRO) {
+ if(ModeNo > 0x13) data &= 0xfc;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data);
}
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2); /* DAC speed */
+
}
}
SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
{
- USHORT data,data2;
- USHORT infoflag=0,modeflag;
+ USHORT data,infoflag=0,modeflag;
USHORT resindex,xres;
#ifdef SIS315H
- USHORT data3;
+ USHORT data2,data3;
ULONG longdata;
-#if 0
- resinfo = 0;
-#endif
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
#endif
if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
infoflag = SiS_Pr->CInfoFlag;
+ xres = SiS_Pr->CHDisplay;
} else {
+ resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
if(ModeNo > 0x13) {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-#ifdef SIS315H
-#if 0
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-#endif
-#endif
+ xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
} else {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
}
}
/* Disable DPMS */
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1F,0x3F);
- if(ModeNo > 0x13) data = infoflag;
- else data = 0;
-
- data2 = 0;
+ data = 0;
if(ModeNo > 0x13) {
- if(SiS_Pr->SiS_ModeType > 0x02) {
- data2 |= 0x02;
- data2 |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
- }
- }
-
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n",
- data, HwInfo->jChipType);
-#endif
-
- if(data & InterlaceMode) data2 |= 0x20;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2);
-
- if(SiS_Pr->UseCustomMode) {
- xres = SiS_Pr->CHDisplay;
- } else {
- resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
- if(ModeNo <= 0x13) {
- xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
- } else {
- xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+ if(SiS_Pr->SiS_ModeType > ModeEGA) {
+ data |= 0x02;
+ data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2);
}
+ if(infoflag & InterlaceMode) data |= 0x20;
}
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data);
if(HwInfo->jChipType != SIS_300) {
- data = 0x0000;
+ data = 0;
if(infoflag & InterlaceMode) {
- if(xres <= 800) data = 0x0020;
+ if(xres <= 800) data = 0x0020;
else if(xres <= 1024) data = 0x0035;
- else data = 0x0048;
+ else data = 0x0048;
}
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0x00FF));
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,(data & 0xFF));
SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,(data >> 8));
}
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
}
+ data = 0;
+ if(modeflag & LineCompareOff) data = 0x08;
if(HwInfo->jChipType == SIS_300) {
- if(modeflag & LineCompareOff) {
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
- } else {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
- }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xF7,data);
} else {
- if(modeflag & LineCompareOff) {
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
- } else {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
- }
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
if(SiS_Pr->SiS_ModeType == ModeEGA) {
if(ModeNo > 0x13) {
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
}
}
+ if(HwInfo->jChipType >= SIS_661) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
+ }
+
#ifdef SIS315H
- /* 315 BIOS sets SR17 at this point */
if(HwInfo->jChipType == SIS_315PRO) {
+
data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
data = SiS_Pr->SiS_SR15[2][data];
if(SiS_Pr->SiS_ModeType == ModeText) {
}
}
SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
- }
- /* 330 BIOS sets SR17 at this point */
- if(HwInfo->jChipType == SIS_330) {
+ } else if( (HwInfo->jChipType == SIS_330) ||
+ ((HwInfo->jChipType == SIS_760) && (SiS_Pr->SiS_SysFlags & SF_760LFB))) {
+
data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
- data = SiS_Pr->SiS_SR15[2][data];
+ if(HwInfo->jChipType == SIS_330) {
+ data = SiS_Pr->SiS_SR15[2][data];
+ } else {
+ if(SiS_Pr->SiS_ROMNew) data = ROMAddr[0xf6];
+ else if(SiS_Pr->SiS_UseROM) data = ROMAddr[0x100 + data];
+ else data = 0xba;
+ }
if(SiS_Pr->SiS_ModeType <= ModeEGA) {
data &= 0xc7;
} else {
}
data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex) >> 1;
- if(!data3) data3++;
-
- data2 *= data3;
+ if(data3) data2 *= data3;
longdata = SiS_GetMCLK(SiS_Pr, HwInfo) * 1024;
data2 = longdata / data2;
- if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
- if(data2 >= 0x19c) data = 0xba;
- else if(data2 >= 0x140) data = 0x7a;
- else if(data2 >= 0x101) data = 0x3a;
- else if(data2 >= 0xf5) data = 0x32;
- else if(data2 >= 0xe2) data = 0x2a;
- else if(data2 >= 0xc4) data = 0x22;
- else if(data2 >= 0xac) data = 0x1a;
- else if(data2 >= 0x9e) data = 0x12;
- else if(data2 >= 0x8e) data = 0x0a;
+ if(HwInfo->jChipType == SIS_330) {
+ if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+ if (data2 >= 0x19c) data = 0xba;
+ else if(data2 >= 0x140) data = 0x7a;
+ else if(data2 >= 0x101) data = 0x3a;
+ else if(data2 >= 0xf5) data = 0x32;
+ else if(data2 >= 0xe2) data = 0x2a;
+ else if(data2 >= 0xc4) data = 0x22;
+ else if(data2 >= 0xac) data = 0x1a;
+ else if(data2 >= 0x9e) data = 0x12;
+ else if(data2 >= 0x8e) data = 0x0a;
+ else data = 0x02;
+ } else {
+ if(data2 >= 0x127) data = 0xba;
+ else data = 0x7a;
+ }
+ } else { /* 760+LFB */
+ if (data2 >= 0x190) data = 0xba;
+ else if(data2 >= 0xff) data = 0x7a;
+ else if(data2 >= 0xd3) data = 0x3a;
+ else if(data2 >= 0xa9) data = 0x1a;
+ else if(data2 >= 0x93) data = 0x0a;
else data = 0x02;
- } else {
- if(data2 >= 0x127) data = 0xba;
- else data = 0x7a;
- }
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
}
#endif
} else {
SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
}
-#if 0 /* What is SR0E[D5:6]? */
- if(HwInfo->jChipType >= SIS_661) {
- data = 0;
- if((ModeNo == 6) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
- data |= 0x20;
- }
- if(SiS_Pr->SiS_ModeType != ModeVGA) {
- if(SiS_Pr->UseCustomMode) {
- if((xres >= 640) && (SiS_Pr->CVDisplay >= 480)) {
- data |= 0x40;
- }
- if((xres > 1280) && (SiS_Pr->CVDisplay > 1024)) {
- data |= 0x60;
- }
- }
- } else if(ModeNo > 0x13) { /* These are in the CRT1 table, and set by CRT1CRTC */
- if(resinfo >= SIS_RI_640x480) {
- if(resinfo <= SIS_RI_2048x1536) {
- data |= 0x40;
- if(resinfo > SIS_RI_1280x1024) {
- data |= 0x60;
- if(resinfo != SIS_RI_1600x1200) {
- data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x0e);
- data += 0x60;
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x0e);
- data = 0;
- }
- }
- }
- if(resinfo == SIS_RI_1152x864) {
- data = 0x40;
- }
- if(resinfo == SIS_RI_1400x1050) { /* TW */
- data = 0x60;
- }
- }
- }
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0e,data);
- }
-#endif
}
#endif
}
SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex);
SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo);
SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
- SiS_ClearExt1Regs(SiS_Pr,HwInfo);
+ SiS_ClearExt1Regs(SiS_Pr, HwInfo, ModeNo);
SiS_ResetCRT1VCLK(SiS_Pr, HwInfo);
SiS_Pr->SiS_SelectCRT2Rate = 0;
}
/*********************************************/
-/* HELPER: ENABLE CRT1 */
+/* HELPER: RESET VIDEO BRIDGE */
/*********************************************/
static void
-SiS_HandleCRT1(SiS_Private *SiS_Pr)
+SiS_ResetVB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0xbf);
-#if 0
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
- if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
- (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,SiS_Pr->SiS_MyCR63,0x40);
- }
- }
-#endif
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ USHORT temp;
+
+ if(SiS_Pr->SiS_UseROM) {
+ if(HwInfo->jChipType < SIS_330) {
+ temp = ROMAddr[VB310Data_1_2_Offset] | 0x40;
+ if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80] | 0x40;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+ } else if(HwInfo->jChipType >= SIS_661) {
+ temp = ROMAddr[0x7e];
+ if(SiS_Pr->SiS_ROMNew) temp = ROMAddr[0x80];
+ if(HwInfo->jChipType >= SIS_660) temp |= 0x40;
+ else if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+ }
+ }
}
/*********************************************/
SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
#endif
{
- ULONG temp;
USHORT ModeIdIndex;
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
unsigned char backupreg=0;
#ifndef LINUX_XF86
USHORT KeepLockReg;
+ ULONG temp;
SiS_Pr->UseCustomMode = FALSE;
SiS_Pr->CRT1UsesCustomMode = FALSE;
SiSRegInit(SiS_Pr, BaseAddr);
SiS_GetSysFlags(SiS_Pr, HwInfo);
-#ifdef LINUX_XF86
+#if defined(LINUX_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
else
#endif
SiSSetLVDSetc(SiS_Pr, HwInfo);
SiSDetermineROMUsage(SiS_Pr, HwInfo);
- if(!SiS_Pr->UseCustomMode) {
- ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
- }
+ SiS_Pr->SiS_flag_clearbuffer = 0;
-#ifdef LINUX_XF86
- /* We never clear the buffer in X */
- ModeNo |= 0x8000;
+ if(!SiS_Pr->UseCustomMode) {
+#ifndef LINUX_XF86
+ if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
#endif
-
- if(ModeNo & 0x8000) {
- ModeNo &= 0x7fff;
- SiS_Pr->SiS_flag_clearbuffer = 0;
- } else {
- SiS_Pr->SiS_flag_clearbuffer = 1;
+ ModeNo &= 0x7f;
}
#ifndef LINUX_XF86
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
if(HwInfo->jChipType >= SIS_315H) {
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
- if(ROMAddr && SiS_Pr->SiS_UseROM) {
- if(HwInfo->jChipType < SIS_330) {
- temp = ROMAddr[VB310Data_1_2_Offset];
- temp |= 0x40;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
- }
- if(HwInfo->jChipType > SIS_330) {
- temp = ROMAddr[0x7e];
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
- }
- }
+ SiS_ResetVB(SiS_Pr, HwInfo);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
-
SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
-
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
} else {
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
#endif
if(HwInfo->jChipType >= SIS_315H) {
-#if 0
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode;
- } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
- SiS_Pr->SiS_SetFlag |= SetDOSMode;
- }
- }
-#endif
-
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(IS_SIS650) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
- if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
- } else if(IS_SIS661741660760) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
- }
- }
+ SiS_SetupCR5x(SiS_Pr, HwInfo);
}
if(SiS_Pr->UseCustomMode) {
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
if(HwInfo->jChipType >= SIS_315H) {
- if(HwInfo->jChipType < SIS_661) {
+ if(!SiS_Pr->SiS_ROMNew) {
if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
} else {
SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
DisplayModePtr mode, BOOLEAN IsCustom)
{
- ULONG temp;
USHORT ModeIdIndex;
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
UShort ModeNo = 0;
unsigned char backupreg=0;
SiSRegInit(SiS_Pr, BaseAddr);
SiSInitPtr(SiS_Pr, HwInfo);
SiS_GetSysFlags(SiS_Pr, HwInfo);
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+#else
+ SiS_Pr->SiS_VGAINFO = 0x11;
+#endif
SiSInitPCIetc(SiS_Pr, HwInfo);
SiSSetLVDSetc(SiS_Pr, HwInfo);
SiSDetermineROMUsage(SiS_Pr, HwInfo);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
if(HwInfo->jChipType >= SIS_315H) {
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
- if(ROMAddr && SiS_Pr->SiS_UseROM) {
- if(HwInfo->jChipType < SIS_330) {
- temp = ROMAddr[VB310Data_1_2_Offset];
- temp |= 0x40;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
- }
- if(HwInfo->jChipType > SIS_330) {
- temp = ROMAddr[0x7e];
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x7b) >= 100) temp |= 0x40;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
- }
- }
+ SiS_ResetVB(SiS_Pr, HwInfo);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
-
SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
-
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
} else {
backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
if(HwInfo->jChipType >= SIS_315H) {
- if(HwInfo->jChipType < SIS_661) {
+ if(!SiS_Pr->SiS_ROMNew) {
if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
} else {
SiSInitPtr(SiS_Pr, HwInfo);
SiSRegInit(SiS_Pr, BaseAddr);
SiS_GetSysFlags(SiS_Pr, HwInfo);
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+#else
+ SiS_Pr->SiS_VGAINFO = 0x11;
+#endif
SiSInitPCIetc(SiS_Pr, HwInfo);
SiSSetLVDSetc(SiS_Pr, HwInfo);
SiSDetermineROMUsage(SiS_Pr, HwInfo);
SiS_SetLowModeTest(SiS_Pr, ModeNo, HwInfo);
if(HwInfo->jChipType >= SIS_315H) {
-#if 0
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(ModeNo != 0x10) SiS_Pr->SiS_SetFlag |= SetDOSMode;
- } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
- SiS_Pr->SiS_SetFlag |= SetDOSMode;
- }
- }
-#endif
-
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- if(IS_SIS650) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
- if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
- } else if(IS_SIS661741660760) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef);
- }
- }
+ SiS_SetupCR5x(SiS_Pr, HwInfo);
}
/* Set mode on CRT1 */
}
#endif
+#ifndef GETBITSTR
+#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
+#define GENMASK(mask) BITMASK(1?mask,0?mask)
+#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
+#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
+#endif
+
+static void
+SiS_CalcCRRegisters(SiS_Private *SiS_Pr, int depth)
+{
+ SiS_Pr->CCRT1CRTC[0] = ((SiS_Pr->CHTotal >> 3) - 5) & 0xff; /* CR0 */
+ SiS_Pr->CCRT1CRTC[1] = (SiS_Pr->CHDisplay >> 3) - 1; /* CR1 */
+ SiS_Pr->CCRT1CRTC[2] = (SiS_Pr->CHBlankStart >> 3) - 1; /* CR2 */
+ SiS_Pr->CCRT1CRTC[3] = (((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80; /* CR3 */
+ SiS_Pr->CCRT1CRTC[4] = (SiS_Pr->CHSyncStart >> 3) + 3; /* CR4 */
+ SiS_Pr->CCRT1CRTC[5] = ((((SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | /* CR5 */
+ (((SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
+
+ SiS_Pr->CCRT1CRTC[6] = (SiS_Pr->CVTotal - 2) & 0xFF; /* CR6 */
+ SiS_Pr->CCRT1CRTC[7] = (((SiS_Pr->CVTotal - 2) & 0x100) >> 8) /* CR7 */
+ | (((SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
+ | ((SiS_Pr->CVSyncStart & 0x100) >> 6)
+ | (((SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
+ | 0x10
+ | (((SiS_Pr->CVTotal - 2) & 0x200) >> 4)
+ | (((SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
+ | ((SiS_Pr->CVSyncStart & 0x200) >> 2);
+
+ SiS_Pr->CCRT1CRTC[16] = ((((SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* CR9 */
+
+ if(depth != 8) {
+ if(SiS_Pr->CHDisplay >= 1600) SiS_Pr->CCRT1CRTC[16] |= 0x60; /* SRE */
+ else if(SiS_Pr->CHDisplay >= 640) SiS_Pr->CCRT1CRTC[16] |= 0x40;
+ }
+
+#if 0
+ if (mode->VScan >= 32)
+ regp->CRTC[9] |= 0x1F;
+ else if (mode->VScan > 1)
+ regp->CRTC[9] |= mode->VScan - 1;
+#endif
+
+ SiS_Pr->CCRT1CRTC[8] = (SiS_Pr->CVSyncStart ) & 0xFF; /* CR10 */
+ SiS_Pr->CCRT1CRTC[9] = ((SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* CR11 */
+ SiS_Pr->CCRT1CRTC[10] = (SiS_Pr->CVDisplay - 1) & 0xFF; /* CR12 */
+ SiS_Pr->CCRT1CRTC[11] = (SiS_Pr->CVBlankStart - 1) & 0xFF; /* CR15 */
+ SiS_Pr->CCRT1CRTC[12] = (SiS_Pr->CVBlankEnd - 1) & 0xFF; /* CR16 */
+
+ SiS_Pr->CCRT1CRTC[13] = /* SRA */
+ GETBITSTR((SiS_Pr->CVTotal -2), 10:10, 0:0) |
+ GETBITSTR((SiS_Pr->CVDisplay -1), 10:10, 1:1) |
+ GETBITSTR((SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
+ GETBITSTR((SiS_Pr->CVSyncStart ), 10:10, 3:3) |
+ GETBITSTR((SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
+ GETBITSTR((SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
+
+ SiS_Pr->CCRT1CRTC[14] = /* SRB */
+ GETBITSTR((SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
+ GETBITSTR((SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
+ GETBITSTR((SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
+ GETBITSTR((SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
+
+
+ SiS_Pr->CCRT1CRTC[15] = /* SRC */
+ GETBITSTR((SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
+ GETBITSTR((SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
+}
+
+void
+SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
+{
+ USHORT modeflag, tempax, tempbx, VGAHDE = SiS_Pr->SiS_VGAHDE;
+ int i,j;
+
+ /* 1:1 data: use data set by setcrt1crtc() */
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) return;
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ } else {
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ if(modeflag & HalfDCLK) VGAHDE >>= 1;
+
+ SiS_Pr->CHDisplay = VGAHDE;
+ SiS_Pr->CHBlankStart = VGAHDE;
+
+ SiS_Pr->CVDisplay = SiS_Pr->SiS_VGAVDE;
+ SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
+
+ tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
+ tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempax = SiS_Pr->PanelXRes;
+ }
+ tempbx += tempax;
+ if(modeflag & HalfDCLK) tempbx -= VGAHDE;
+ SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
+
+ tempax = VGAHDE;
+ tempbx = SiS_Pr->CHTotal;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempbx = SiS_Pr->PanelXRes;
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+ tempax += ((tempbx - tempax) >> 1);
+ }
+
+ tempax += SiS_Pr->PanelHRS;
+ SiS_Pr->CHSyncStart = tempax;
+ tempax += SiS_Pr->PanelHRE;
+ SiS_Pr->CHSyncEnd = tempax;
+
+ tempbx = SiS_Pr->PanelVT - SiS_Pr->PanelYRes;
+ tempax = SiS_Pr->SiS_VGAVDE;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempax = SiS_Pr->PanelYRes;
+ }
+ SiS_Pr->CVTotal = SiS_Pr->CVBlankEnd = tempbx + tempax;
+
+ tempax = SiS_Pr->SiS_VGAVDE;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempax += (SiS_Pr->PanelYRes - tempax) >> 1;
+ }
+ tempax += SiS_Pr->PanelVRS;
+ SiS_Pr->CVSyncStart = tempax;
+ tempax += SiS_Pr->PanelVRE;
+ SiS_Pr->CVSyncEnd = tempax;
+
+ SiS_CalcCRRegisters(SiS_Pr, 8);
+ SiS_Pr->CCRT1CRTC[16] &= ~0xE0;
+
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
+
+ for(i=0,j=0;i<=7;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
+ }
+
+ tempax = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1F,tempax);
+
+ tempax = (SiS_Pr->CCRT1CRTC[16] & 0x01) << 5;
+ if(modeflag & DoubleScanMode) tempax |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
+ SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
+ SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
+ SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
+
+ xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+ SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
+ SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
+ SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
+ SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
+ xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
+ SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
+ SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
+ SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
+ SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
+ xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
+#endif
+}
/* ================ XFREE86 ================= */
/* Helper functions */
#ifdef LINUX_XF86
+
USHORT
SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags)
{
pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
- pSiS->SiS_Pr->CCRT1CRTC[0] = ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
- pSiS->SiS_Pr->CCRT1CRTC[1] = (pSiS->SiS_Pr->CHDisplay >> 3) - 1;
- pSiS->SiS_Pr->CCRT1CRTC[2] = (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
- pSiS->SiS_Pr->CCRT1CRTC[3] = (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
- pSiS->SiS_Pr->CCRT1CRTC[4] = (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
- pSiS->SiS_Pr->CCRT1CRTC[5] = ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
- (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
-
- pSiS->SiS_Pr->CCRT1CRTC[6] = (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
- pSiS->SiS_Pr->CCRT1CRTC[7] = (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
- | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
- | ((pSiS->SiS_Pr->CVSyncStart & 0x100) >> 6)
- | (((pSiS->SiS_Pr->CVBlankStart - 1) & 0x100) >> 5)
- | 0x10
- | (((pSiS->SiS_Pr->CVTotal - 2) & 0x200) >> 4)
- | (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
- | ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
-
- pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); /* cr9 */
-
-#if 0
- if (mode->VScan >= 32)
- regp->CRTC[9] |= 0x1F;
- else if (mode->VScan > 1)
- regp->CRTC[9] |= mode->VScan - 1;
-#endif
-
- pSiS->SiS_Pr->CCRT1CRTC[8] = (pSiS->SiS_Pr->CVSyncStart ) & 0xFF; /* cr10 */
- pSiS->SiS_Pr->CCRT1CRTC[9] = ((pSiS->SiS_Pr->CVSyncEnd ) & 0x0F) | 0x80; /* cr11 */
- pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF; /* cr12 */
- pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF; /* cr15 */
- pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF; /* cr16 */
-
- pSiS->SiS_Pr->CCRT1CRTC[13] =
- GETBITSTR((pSiS->SiS_Pr->CVTotal -2), 10:10, 0:0) |
- GETBITSTR((pSiS->SiS_Pr->CVDisplay -1), 10:10, 1:1) |
- GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
- GETBITSTR((pSiS->SiS_Pr->CVSyncStart ), 10:10, 3:3) |
- GETBITSTR((pSiS->SiS_Pr->CVBlankEnd -1), 8:8, 4:4) |
- GETBITSTR((pSiS->SiS_Pr->CVSyncEnd ), 4:4, 5:5) ;
-
- pSiS->SiS_Pr->CCRT1CRTC[14] =
- GETBITSTR((pSiS->SiS_Pr->CHTotal >> 3) - 5, 9:8, 1:0) |
- GETBITSTR((pSiS->SiS_Pr->CHDisplay >> 3) - 1, 9:8, 3:2) |
- GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
- GETBITSTR((pSiS->SiS_Pr->CHSyncStart >> 3) + 3, 9:8, 7:6) ;
-
-
- pSiS->SiS_Pr->CCRT1CRTC[15] =
- GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
- GETBITSTR((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3, 5:5, 2:2) ;
+ SiS_CalcCRRegisters(pSiS->SiS_Pr, depth);
switch(depth) {
- case 8:
- pSiS->SiS_Pr->CModeFlag |= 0x223b;
- break;
- case 16:
- pSiS->SiS_Pr->CModeFlag |= 0x227d;
- break;
- case 32:
- pSiS->SiS_Pr->CModeFlag |= 0x22ff;
- break;
- default:
- return 0;
- }
-
- if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
+ case 8: pSiS->SiS_Pr->CModeFlag |= 0x223b; break;
+ case 16: pSiS->SiS_Pr->CModeFlag |= 0x227d; break;
+ case 32: pSiS->SiS_Pr->CModeFlag |= 0x22ff; break;
+ default: return 0;
+ }
+
+ if(pSiS->SiS_Pr->CFlags & V_DBLSCAN)
pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
if((pSiS->SiS_Pr->CVDisplay >= 1024) ||
pSiS->SiS_Pr->UseCustomMode = TRUE;
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n",
+ xf86DrvMsg(0, X_INFO, "Custom mode %dx%d:\n",
pSiS->SiS_Pr->CHDisplay,pSiS->SiS_Pr->CVDisplay);
xf86DrvMsg(0, X_INFO, "Modeflag %04x, Infoflag %04x\n",
pSiS->SiS_Pr->CModeFlag, pSiS->SiS_Pr->CInfoFlag);
xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- pSiS->SiS_Pr->CCRT1CRTC[0],
- pSiS->SiS_Pr->CCRT1CRTC[1],
- pSiS->SiS_Pr->CCRT1CRTC[2],
- pSiS->SiS_Pr->CCRT1CRTC[3],
- pSiS->SiS_Pr->CCRT1CRTC[4],
- pSiS->SiS_Pr->CCRT1CRTC[5],
- pSiS->SiS_Pr->CCRT1CRTC[6],
- pSiS->SiS_Pr->CCRT1CRTC[7]);
+ pSiS->SiS_Pr->CCRT1CRTC[0], pSiS->SiS_Pr->CCRT1CRTC[1],
+ pSiS->SiS_Pr->CCRT1CRTC[2], pSiS->SiS_Pr->CCRT1CRTC[3],
+ pSiS->SiS_Pr->CCRT1CRTC[4], pSiS->SiS_Pr->CCRT1CRTC[5],
+ pSiS->SiS_Pr->CCRT1CRTC[6], pSiS->SiS_Pr->CCRT1CRTC[7]);
xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- pSiS->SiS_Pr->CCRT1CRTC[8],
- pSiS->SiS_Pr->CCRT1CRTC[9],
- pSiS->SiS_Pr->CCRT1CRTC[10],
- pSiS->SiS_Pr->CCRT1CRTC[11],
- pSiS->SiS_Pr->CCRT1CRTC[12],
- pSiS->SiS_Pr->CCRT1CRTC[13],
- pSiS->SiS_Pr->CCRT1CRTC[14],
- pSiS->SiS_Pr->CCRT1CRTC[15]);
+ pSiS->SiS_Pr->CCRT1CRTC[8], pSiS->SiS_Pr->CCRT1CRTC[9],
+ pSiS->SiS_Pr->CCRT1CRTC[10], pSiS->SiS_Pr->CCRT1CRTC[11],
+ pSiS->SiS_Pr->CCRT1CRTC[12], pSiS->SiS_Pr->CCRT1CRTC[13],
+ pSiS->SiS_Pr->CCRT1CRTC[14], pSiS->SiS_Pr->CCRT1CRTC[15]);
xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", pSiS->SiS_Pr->CCRT1CRTC[16]);
xf86DrvMsg(0, X_INFO, "Clock: 0x%02x, 0x%02x, %d\n",
- pSiS->SiS_Pr->CSR2B,
- pSiS->SiS_Pr->CSR2C,
- pSiS->SiS_Pr->CSRClock);
+ pSiS->SiS_Pr->CSR2B, pSiS->SiS_Pr->CSR2C, pSiS->SiS_Pr->CSRClock);
#endif
return 1;
}
/* Horizontal display enable end */
HDE = (cr_data & 0xff) |
((unsigned short) (sr_data & 0x0C) << 6);
- E = HDE + 1;
+ E = HDE + 1; /* 0x80 0x64 */
cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[4];
/* inSISIDXREG(SISCR, 0x04, cr_data); */
/* Horizontal retrace (=sync) start */
HRS = (cr_data & 0xff) |
((unsigned short) (sr_data & 0xC0) << 2);
- F = HRS - E - 3;
+ F = HRS - E - 3; /* 0x06 0x06 */
cr_data = pSiS->SiS_Pr->SiS_CRT1Table[index].CR[2];
/* inSISIDXREG(SISCR, 0x02, cr_data); */
B = (temp > 0) ? temp : (temp + 256);
temp = HRE - ((E + F + 3) & 63);
- C = (temp > 0) ? temp : (temp + 64);
+ C = (temp > 0) ? temp : (temp + 64); /* 0x0b 0x0b */
D = B - F - C;
int
sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
unsigned char modeno, unsigned char rateindex,
- ULONG *left_margin, ULONG *right_margin,
- ULONG *upper_margin, ULONG *lower_margin,
- ULONG *hsync_len, ULONG *vsync_len,
- ULONG *sync, ULONG *vmode)
+ struct fb_var_screeninfo *var)
{
USHORT ModeNo = modeno;
USHORT ModeIdIndex = 0, index = 0;
return 0;
#endif
}
-
+
if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
/* Terrible hack, but the correct CRTC data for
* these modes only produces a black screen...
*/
- *left_margin = (400 - 376);
- *right_margin = (328 - 320);
- *hsync_len = (376 - 328);
+ var->left_margin = (400 - 376);
+ var->right_margin = (328 - 320);
+ var->hsync_len = (376 - 328);
} else {
- *left_margin = D * 8;
- *right_margin = F * 8;
- *hsync_len = C * 8;
+ var->left_margin = D * 8;
+ var->right_margin = F * 8;
+ var->hsync_len = C * 8;
}
D = B - F - C;
- *upper_margin = D;
- *lower_margin = F;
- *vsync_len = C;
+ var->upper_margin = D;
+ var->lower_margin = F;
+ var->vsync_len = C;
if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
- *sync &= ~FB_SYNC_VERT_HIGH_ACT;
+ var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
else
- *sync |= FB_SYNC_VERT_HIGH_ACT;
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
- *sync &= ~FB_SYNC_HOR_HIGH_ACT;
+ var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
else
- *sync |= FB_SYNC_HOR_HIGH_ACT;
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
- *vmode = FB_VMODE_NONINTERLACED;
+ var->vmode = FB_VMODE_NONINTERLACED;
if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
- *vmode = FB_VMODE_INTERLACED;
+ var->vmode = FB_VMODE_INTERLACED;
else {
- j = 0;
- while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
+ j = 0;
+ while(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID != 0xff) {
if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeID ==
SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID) {
if(SiS_Pr->SiS_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
- *vmode = FB_VMODE_DOUBLE;
+ var->vmode = FB_VMODE_DOUBLE;
}
break;
}
j++;
- }
+ }
}
- if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
#if 0 /* Do this? */
- *upper_margin <<= 1;
- *lower_margin <<= 1;
- *vsync_len <<= 1;
+ var->upper_margin <<= 1;
+ var->lower_margin <<= 1;
+ var->vsync_len <<= 1;
#endif
- } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- *upper_margin >>= 1;
- *lower_margin >>= 1;
- *vsync_len >>= 1;
+ } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ var->upper_margin >>= 1;
+ var->lower_margin >>= 1;
+ var->vsync_len >>= 1;
}
return 1;
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Data and prototypes for init.c
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
const USHORT ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63};
const USHORT ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e};
const USHORT ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45};
+const USHORT ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; /* 315 series only */
const USHORT ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64};
const USHORT ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77};
const USHORT ModeIndex_1024x600[] = {0x20, 0x21, 0x00, 0x22}; /* 300 series only */
const USHORT ModeIndex_300_1280x768[] = {0x55, 0x5a, 0x00, 0x5b};
const USHORT ModeIndex_310_1280x768[] = {0x23, 0x24, 0x00, 0x25};
const USHORT ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78};
+const USHORT ModeIndex_1280x800[] = {0x14, 0x15, 0x00, 0x16};
const USHORT ModeIndex_1360x768[] = {0x48, 0x4b, 0x00, 0x4e};
const USHORT ModeIndex_300_1360x1024[]= {0x67, 0x6f, 0x00, 0x72}; /* 300 series, BARCO only */
const USHORT ModeIndex_1400x1050[] = {0x26, 0x27, 0x00, 0x28}; /* 315 series only */
+const USHORT ModeIndex_1680x1050[] = {0x17, 0x18, 0x00, 0x19}; /* 315 series only */
const USHORT ModeIndex_1600x1200[] = {0x3c, 0x3d, 0x00, 0x66};
+const USHORT ModeIndex_1920x1080[] = {0x2c, 0x2d, 0x00, 0x73}; /* 315 series only */
const USHORT ModeIndex_1920x1440[] = {0x68, 0x69, 0x00, 0x6b};
const USHORT ModeIndex_300_2048x1536[]= {0x6c, 0x6d, 0x00, 0x00};
const USHORT ModeIndex_310_2048x1536[]= {0x6c, 0x6d, 0x00, 0x6e};
{ 1024, 600, 8,16}, /* 0x19 */
{ 1152, 768, 8,16}, /* 0x1a */
{ 768, 576, 8,16}, /* 0x1b */
- { 1360,1024, 8,16} /* 0x1c */
+ { 1360,1024, 8,16}, /* 0x1c */
+ { 1680,1050, 8,16}, /* 0x1d */
+ { 1280, 800, 8,16}, /* 0x1e */
+ { 1920,1080, 8,16}, /* 0x1f */
+ { 960, 540, 8,16} /* 0x20 */
};
+#if defined(SIS300) || defined(SIS315H)
static SiS_StandTableStruct SiS_StandTable[]=
{
/* 0x00: MD_0_200 */
0xff}
}
};
+#endif
/**************************************************************/
/* SIS VIDEO BRIDGE ----------------------------------------- */
{ 36, 25,1060, 648,1270, 530, 438, 0, 438,0xeb,0x05,0x25,0x16}, /* 800x600, 400x300 - better */
{ 3, 2,1080, 619,1270, 540, 438, 0, 438,0xf3,0x00,0x1d,0x20}, /* 720x576 */
{ 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 */
- { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20} /* 1024x768 (for NTSC equ) */
+ { 1, 1,1170, 821,1270, 520, 686, 0, 686,0xF3,0x00,0x1D,0x20}, /* 1024x768 (for NTSC equ) */
+ { 9, 4, 848, 528,1270, 530, 0, 0, 50,0xf5,0xfb,0x1b,0x2a} /* 720x480 test */
};
static const SiS_TVDataStruct SiS_StNTSCData[] =
static const SiS_TVDataStruct SiS_Ext750pData[] =
{
+#if 1
+ { 143, 65, 0x35a,0x1bb,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00},
+ { 88, 35, 0x35a,0x189,0x4f6,0x1b8,0x0ab, 0, 0x0ab, 0x00,0x00,0x00,0x00},
+ { 18, 5, 0x339,0x1ae,0x500,0x2d0,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00},
+ { 143, 70, 0x39c,0x189,0x4f6,0x1b8,0x05c, 0, 0x05c, 0x00,0x00,0x00,0x00},
+ { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
+ { 5, 4, 0x5d8,0x29e,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
+#if 0
+ { 2, 1, 0x35a,0x1f7,0x4f6,0x1e0, 0,128, 0, 0x00,0x00,0x00,0x00}, /* 720x480 */
+#endif
+ { 99, 32, 0x320,0x1fe,0x500,0x2d0, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 720x480 test WORKS */
+ { 68, 64, 0x55f,0x346,0x500,0x2a8,0x27e, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
+ { 5, 2, 0x3a7,0x226,0x500,0x2a8, 0,128, 0, 0x00,0x00,0x00,0x00}, /* 720x576 */
+ { 25, 24, 0x5d8,0x2f3,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 WORKS */
+#endif
+#if 0
{ 3, 1, 0x3a7,0x1d6,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00},
{ 24, 7, 0x3a7,0x1a4,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00},
{ 3, 1, 0x3a7,0x1d6,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00},
{ 5, 4, 0x5d8,0x29e,0x500,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
{ 2, 1, 0x35a,0x1f7,0x4f6,0x1e0, 0,128, 0, 0x00,0x00,0x00,0x00}, /* 720x480 */
{ 68, 64, 0x55f,0x346,0x500,0x2a8,0x27e, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
+ { 25, 24, 0x5d8,0x2f3,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00} /* 1280x720 */
+#endif
+#if 0
+ { 136, 35, 0x339,0x181,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* TEST (0.93) BAD */
+ { 17, 6, 0x339,0x203,0x460,0x2a8, 50, 0, 50, 0x00,0x00,0x00,0x00},
+ { 136, 35, 0x339,0x181,0x460,0x2a8, 50, 0, 50, 0x00,0x00,0x00,0x00},
+ { 17, 6, 0x339,0x203,0x460,0x2a8, 50, 0, 50, 0x00,0x00,0x00,0x00},
+ { 85, 46, 0x3f4,0x27b,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 640x480 */
+ { 17, 16, 0x55f,0x323,0x460,0x2a8,0x2b6, 0, 0, 0x00,0x00,0x00,0x00}, /* 800x600 */
+ { 136, 35, 0x339,0x181,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 720x480 */
+ { 187, 74, 0x39d,0x203,0x460,0x2a8, 50, 0, 0, 0x00,0x00,0x00,0x00}, /* 1024x768 */
+ { 25, 24, 0x5d8,0x2f3,0x460,0x2a8, 50, 0, 50, 0x00,0x00,0x00,0x00} /* 1280x720 */
+#endif
};
-static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
+static const SiS_LCDDataStruct SiS_LCD1280x720Data[] =
{
- { 9, 2, 800, 500,1800,1000},
- { 9, 2, 800, 500,1800,1000},
- { 4, 1, 900, 500,1800,1000},
- { 4, 1, 900, 500,1800,1000},
- { 9, 2, 800, 500,1800,1000},
- { 30, 11,1056, 625,1800,1000},
- { 5, 3,1350, 800,1800,1000},
- { 1, 1,1576,1050,1576,1050},
- { 1, 1,1800,1000,1800,1000}
+ { 14, 5, 864, 432, 1344, 806 }, /* 640x400 */
+ { 16, 5, 864, 378, 1344, 806 },
+ { 14, 5, 864, 432, 1344, 806 },
+ { 16, 5, 864, 378, 1344, 806 },
+ { 24, 11, 924, 523, 1344, 806 }, /* 640x480 */
+ { 7, 5, 1152, 664, 1344, 806 }, /* 800x600 */
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1344, 806, 1344, 806 } /* 1280x720 */
};
-/* 1280x768 panel data from Fujitsu 7911 (VL-17WDX8).
- * Other 1280x768 panels (with clock != 81000, HTxVT != 1688x802)
- * will be treated as custom panels.
+/* About 1280x768: For TMDS, Panel_1280x768 will only be set if
+ * the panel is a Fujitsu 7911 (VL-17WDX8) (with clock 81, 1688x802)
+ * Other TMDS panels of this resolution will be treated as custom.
+ * For LVDS, we know two types. Data follows:
*/
-static const SiS_LCDDataStruct SiS_StLCD1280x768Data[] =
+static const SiS_LCDDataStruct SiS_StLCD1280x768_2Data[] =
+{
+ { 64, 21, 858, 434, 1408, 806 }, /* 640x400 */
+ { 32, 9, 858, 372, 1408, 806 },
+ { 64, 21, 858, 434, 1408, 806 },
+ { 32, 9, 858, 372, 1408, 806 },
+ { 143, 68, 1024, 527, 1408, 806 }, /* 640x480 */
+ { 64, 51, 1364, 663, 1408, 806 }, /* 800x600 */
+ { 88, 81, 1296, 806, 1408, 806 }, /* 1024x768 */
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1408, 806, 1408, 806 } /* 1280x768 */
+};
+
+static const SiS_LCDDataStruct SiS_ExtLCD1280x768_2Data[] =
+{
+ { 64, 25, 1056, 422, 1408, 806 }, /*, 664 */
+ { 128, 39, 884, 396, 1408, 806 }, /*, 640 */
+ { 64, 25, 1056, 422, 1408, 806 }, /*, 664 */
+ { 128, 39, 884, 396, 1408, 806 }, /*, 640 */
+ { 32, 15, 1056, 513, 1408, 806 }, /*, 664 */
+ { 176, 125, 1280, 640, 1408, 806 }, /*, 768 */
+ { 88, 81, 1296, 806, 1408, 806 },
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1408, 806, 1408, 806 }
+};
+
+static const SiS_LCDDataStruct SiS_LCD1280x768_3Data[] =
{
- { 211, 100, 2100, 408, 1688, 802 }, /* These values are *wrong* */
- { 211, 64, 1536, 358, 1688, 802 }, /* (which is why they aren't used yet) */
- { 211, 100, 2100, 408, 1688, 802 },
- { 211, 64, 1536, 358, 1688, 802 },
- { 211, 48, 840, 488, 1688, 802 },
- { 211, 72, 1008, 609, 1688, 802 },
- { 211, 128, 1400, 776, 1688, 802 },
- { 211, 205, 1680, 1041, 1688, 802 },
- { 1, 1, 1688, 802, 1688, 802 } /* That's the only one that is correct */
+ { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
+ { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
+ { 64, 25, 1056, 422, 1664, 798 }, /* 640x400 */
+ { 128, 39, 884, 396, 1408, 806 }, /* ,640 */
+ { 32, 15, 1056, 513, 1408, 806 }, /* ,664 */ /* 640x480 */
+ { 176, 125, 1280, 640, 1408, 806 }, /* ,768 */ /* 800x600 */
+ { 64, 61, 1342, 806, 1408, 806 }, /* 1024x768 */
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1408, 806, 1408, 806 } /* 1280x768 */
};
-static const SiS_LCDDataStruct SiS_ExtLCD1280x768Data[] =
+static const SiS_LCDDataStruct SiS_LCD1280x800Data[] =
{
- { 211, 100, 2100, 408, 1688, 802 }, /* These values are *wrong* */
- { 211, 64, 1536, 358, 1688, 802 }, /* (which is why they aren't used yet) */
- { 211, 100, 2100, 408, 1688, 802 },
- { 211, 64, 1536, 358, 1688, 802 },
- { 211, 48, 840, 488, 1688, 802 },
- { 211, 72, 1008, 609, 1688, 802 },
- { 211, 128, 1400, 776, 1688, 802 },
- { 211, 205, 1680, 1041, 1688, 802 },
- { 1, 1, 1688, 802, 1688, 802 } /* That's the only one that is correct */
+ { 128, 51, 1122, 412, 1408, 816 }, /* 640x400 */
+ { 128, 49, 1232, 361, 1408, 816 },
+ { 128, 51, 1122, 412, 1408, 816 },
+ { 128, 49, 1232, 361, 1408, 816 },
+ { 8, 3, 880, 491, 1408, 816 }, /* 640x480 */
+ { 11, 6, 1024, 612, 1408, 816 }, /* 800x600 */
+ { 22, 21, 1400, 784, 1408, 816 }, /* 1024x768 */
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1408, 816, 1408, 816 } /* 1280x800 */
};
-static const SiS_LCDDataStruct SiS_NoScaleData1280x768[] =
+static const SiS_LCDDataStruct SiS_LCD1280x960Data[] =
{
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802},
- { 1, 1, 1688, 802, 1688, 802}
+ { 9, 2, 800, 500, 1800, 1000 },
+ { 9, 2, 800, 500, 1800, 1000 },
+ { 4, 1, 900, 500, 1800, 1000 },
+ { 4, 1, 900, 500, 1800, 1000 },
+ { 9, 2, 800, 500, 1800, 1000 },
+ { 30, 11, 1056, 625, 1800, 1000 },
+ { 5, 3, 1350, 800, 1800, 1000 },
+ { 1, 1, 1576, 1050, 1576, 1050 },
+ { 1, 1, 1800, 1000, 1800, 1000 }
};
static const SiS_LCDDataStruct SiS_StLCD1400x1050Data[] =
static const SiS_LCDDataStruct SiS_ExtLCD1400x1050Data[] =
{
- { 211, 100, 2100, 408, 1688, 1066 },
+/* { 211, 60, 1260, 410, 1688, 1066 }, 640x400 (6330) */
+ { 211, 100, 2100, 408, 1688, 1066 }, /* 640x400 (6325) WORKS */
{ 211, 64, 1536, 358, 1688, 1066 },
{ 211, 100, 2100, 408, 1688, 1066 },
{ 211, 64, 1536, 358, 1688, 1066 },
- { 211, 48, 840, 488, 1688, 1066 },
- { 211, 72, 1008, 609, 1688, 1066 },
- { 211, 128, 1400, 776, 1688, 1066 },
- { 211, 205, 1680, 1041, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS_LCDDataStruct SiS_NoScaleData1400x1050[] =
-{
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 },
- { 1, 1, 1688, 1066, 1688, 1066 }
+/* { 211, 80, 1400, 490, 1688, 1066 }, 640x480 (6330) */
+ { 211, 48, 840, 488, 1688, 1066 }, /* 640x480 (6325) WORKS */
+/* { 211, 117, 1638, 613, 1688, 1066 }, 800x600 (6330) */
+ { 211, 72, 1008, 609, 1688, 1066 }, /* 800x600 (6325) WORKS */
+ { 211, 128, 1400, 776, 1688, 1066 }, /* 1024x768 */
+ { 211, 205, 1680, 1041, 1688, 1066 }, /* 1280x1024 - not used (always unscaled) */
+ { 1, 1, 1688, 1066, 1688, 1066 }, /* 1400x1050 */
+ { 0, 0, 0, 0, 0, 0 }, /* kludge */
+ { 211, 120, 1400, 730, 1688, 1066 } /* 1280x720 */
+};
+
+static const SiS_LCDDataStruct SiS_LCD1680x1050Data[] =
+{
+ { 95, 24, 1260, 410, 1900, 1066 }, /* 0 640x400 */
+ { 10, 3, 1710, 362, 1900, 1066 },
+ { 95, 24, 1260, 410, 1900, 1066 },
+ { 10, 3, 1710, 362, 1900, 1066 },
+ { 95, 32, 1400, 490, 1900, 1066 }, /* 4 640x480 */
+ { 95, 42, 1470, 610, 1900, 1066 }, /* 5 800x600 */
+ { 95, 64, 1750, 784, 1900, 1066 }, /* 6 1024x768 */
+ { 95, 94, 1900, 1055, 1900, 1066 }, /* 7 1280x1024 */
+ { 41, 31, 1900, 806, 1900, 1066 }, /* 8 1280x768 */
+ { 95, 69, 1800, 817, 1900, 1066 }, /* 9 1280x800 patch */
+ { 13, 9, 1900, 739, 1900, 1066 }, /* 10 1280x720 */
+ { 95, 94, 1880, 1066, 1900, 1066 }, /* 11 1400x1050 patch */
+ { 1, 1, 1900, 1066, 1900, 1066 } /* 12 1680x1050 */
};
static const SiS_LCDDataStruct SiS_StLCD1600x1200Data[] =
{ 4, 1,1080, 625, 2160, 1250 },
{ 5, 2,1350, 800, 2160, 1250 },
{135,88,1600,1100, 2160, 1250 },
- {135,88,1600,1100, 2160, 1250 },
+ {72, 49,1680,1092, 2160, 1250 },
{ 1, 1,2160,1250, 2160, 1250 }
};
static const SiS_LCDDataStruct SiS_ExtLCD1600x1200Data[] =
{
- {27, 4, 800, 500, 2160, 1250 },
+ {72,11, 990, 422, 2160, 1250 }, /* 640x400 (6330) WORKS */
+/* {27, 4, 800, 500, 2160, 1250 }, 640x400 (6235) */
{27, 4, 800, 500, 2160, 1250 },
{ 6, 1, 900, 500, 2160, 1250 },
{ 6, 1, 900, 500, 2160, 1250 },
- {27, 1, 800, 500, 2160, 1250 },
+ {45, 8, 960, 505, 2160, 1250 }, /* 640x480 (6330) WORKS */
+/* {27, 1, 800, 500, 2160, 1250 }, 640x480 (6325) */
{ 4, 1,1080, 625, 2160, 1250 },
{ 5, 2,1350, 800, 2160, 1250 },
- {27,16,1500,1064, 2160, 1250 },
- {27,16,1500,1064, 2160, 1250 },
+ {27,16,1500,1064, 2160, 1250 }, /* 1280x1024 */
+ {72,49,1680,1092, 2160, 1250 }, /* 1400x1050 (6330, was not supported on 6325) */
{ 1, 1,2160,1250, 2160, 1250 }
};
-static const SiS_LCDDataStruct SiS_NoScaleData1600x1200[] =
-{
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
- {1, 1, 2160, 1250, 2048, 1250},
-};
-
static const SiS_LCDDataStruct SiS_NoScaleData[] =
{
- { 1, 1, 800, 449, 800, 449 },
+ { 1, 1, 800, 449, 800, 449 }, /* 0x00: 320x200, 640x400 */
{ 1, 1, 800, 449, 800, 449 },
{ 1, 1, 900, 449, 900, 449 },
{ 1, 1, 900, 449, 900, 449 },
- { 1, 1, 800, 525, 800, 525 },
- { 1, 1,1056, 628,1056, 628 },
- { 1, 1,1344, 806,1344, 806 },
- { 1, 1,1688,1066,1688,1066 },
- { 1, 1,1688, 802,1688, 802 }, /* 1280x768: 802 was 806 in both cases */
- { 1, 1,2160,1250,2160,1250 }, /* 1600x1200 */
- { 1, 1,1800,1000,1800,1000 } /* 1280x960 */
-};
-
-/* *** LCDA *** */
-
-static const SiS_LVDSDataStruct SiS_LCDA1024x768Data_1[]=
-{
- { 960, 438,1344, 806},
- { 960, 388,1344, 806},
- { 1040, 438,1344, 806},
- { 1040, 388,1344, 806},
- { 960, 518,1344, 806}, /* 640x480 */
- { 1120, 638,1344, 806}, /* 800x600 */
- { 1344, 806,1344, 806}, /* 1024x768 */
-#if 0
- { 840, 438,1344, 806},
- { 840, 409,1344, 806},
- { 840, 438,1344, 806},
- { 840, 409,1344, 806},
- { 840, 518,1344, 806}, /* 640x480 */
- {1050, 638,1344, 806}, /* 800x600 */
- {1344, 806,1344, 806}, /* 1024x768 */
-#endif
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1024x768Data_2[]=
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1280x1024Data_1[]=
-{ /* Acer, Compaq */
- {1048, 442,1688,1066},
- {1048, 392,1688,1066},
- {1128, 442,1688,1066},
- {1128, 392,1688,1066},
- {1048, 522,1688,1066},
- {1208, 642,1688,1066},
- {1432, 810,1688,1066},
- {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1280x1024Data_2[]=
-{ /* Corrected (illegal in Acer, correct in Compaq) */
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1400x1050Data_1[]=
-{ /* Clevo */
- { 928, 416, 1688,1066},
- { 928, 366, 1688,1066},
- {1008, 416, 1688,1066},
- {1008, 366, 1688,1066},
- {1200, 530, 1688,1066},
- {1088, 616, 1688,1066},
- {1312, 784, 1688,1066},
- {1568,1040, 1688,1066},
- {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1400x1050Data_2[]=
-{ /* Clevo */
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066},
- {1688,1066, 1688,1066}
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_1[]=
-{ /* Clevo (Temporary data) */
- {1200, 450, 2048,1250},
- {1200, 400, 2048,1250},
- {1280, 450, 2048,1250},
- {1280, 400, 2048,1250},
- {1200, 530, 2048,1250},
- {1360, 650, 2048,1250},
- {1584, 818, 2048,1250},
- {1688,1066, 2048,1250},
- {1688,1066, 2048,1250},
- {2048,1250, 2048,1250} /* this should be correct */
-#if 0
- {2160,1250, 2048,1250} /* ? */
-#endif
-};
-
-static const SiS_LVDSDataStruct SiS_LCDA1600x1200Data_2[]=
-{ /* Clevo (Temporary data. Seems invalid.) */
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250},
- {2160,1250, 2160,1250}
-};
-
-/* LVDS SKEW for LCDA */
-
-static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
-{ /* 1024x768 */
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}, /* 805; was 0, 0 -> top line cut away (26/09/03) */
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
-{ /* 1024x768; not expanded */
- { 1184, 622 },
- { 1184, 597 },
- { 1184, 622 },
- { 1184, 597 },
- { 1152, 650 }, /* 622 */
- { 1232, 722 },
- { 0, 0 }, /* 805; was 0, 0 -> top line cut away (26/09/03) */
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
-{ /* 1280x1024 */
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 1065}, /* Acer */
- { 0 , 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
-{ /* 1280x1024; not expanded */
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
-{ /* 1400x1050 */
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 1065} /* Was 0,0 */
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
-{ /* 1400x1050; not expanded */
- { 1308, 741 },
- { 1308, 716 },
- { 1308, 741 },
- { 1308, 716 },
- { 1308, 781 },
- { 1388, 841 },
- { 1500, 925 },
- { 1628,1053 },
- { 0,1065 }
-#if 0
- { 808 , 740},
- { 0 , 715},
- { 632 , 740},
- { 632 , 715},
- { 1307, 780},
- { 1387,1157},
- { 1499, 924},
- { 1627,1052},
- { 0 , 0}
-#endif
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
-{ /* 1600x1200 */
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
-{ /* 1600x1200; not expanded */
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}
-};
-
-#ifdef SIS315H
-
-/* LCDA CRT1 custom data */
-
-static const SiS_LCDACRT1DataStruct Compaq1280x1024_LCDACRT1_1[]=
-{
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
- 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
- 0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
- 0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
- 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
- 0x00}},
- {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0,
- 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
- 0x01}},
- {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5,
- 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
- 0x01}},
- {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a,
- 0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
- 0x01}}
+ { 1, 1, 800, 525, 800, 525 }, /* 0x04: 320x240, 640x480 */
+ { 1, 1,1056, 628,1056, 628 }, /* 0x05: 400x300, 800x600 */
+ { 1, 1,1344, 806,1344, 806 }, /* 0x06: 512x384, 1024x768 */
+ { 1, 1,1688,1066,1688,1066 }, /* 0x07: 1280x1024 */
+ { 1, 1,1688, 802,1688, 802 }, /* 0x08: 1280x768: Fujitsu, TMDS only */
+ { 1, 1,2160,1250,2160,1250 }, /* 0x09: 1600x1200 */
+ { 1, 1,1800,1000,1800,1000 }, /* 0x0a: 1280x960 */
+ { 1, 1,1688,1066,1688,1066 }, /* 0x0b: 1400x1050 */
+ { 1, 1,1650, 750,1650, 750 }, /* 0x0c: 1280x720 (TMDS, projector) */
+ { 1, 1,1656, 841,1656, 841 }, /* 0x0d: 1280x800 (was: 1408, 816) */
+ { 1, 1,1900,1066,1900,1066 }, /* 0x0e: 1680x1050 (LVDS) */
+ { 1, 1,1408, 806,1408, 806 }, /* 0x0f: 1280x768_2 */
+ { 1, 1,1664, 798,1664, 798 }, /* 0x10: 1280x768_3 */
+ { 1, 1,1688, 802,1688, 802 }, /* 0x11: 1280x768: Std, TMDS only */
+ { 1, 1,1344, 806,1344, 806 }, /* 0x12: 1280x720 (LVDS) */
+ { 1, 1, 896, 497, 896, 497 }, /* 0x13: 720x480 */
+ { 1, 1, 912, 597, 912, 597 }, /* 0x14: 720x576 */
+ { 1, 1, 912, 597, 912, 597 }, /* 0x15: 768x576 */
+ { 1, 1,1056, 497,1056, 497 }, /* 0x16: 848x480 */
+ { 1, 1,1064, 497,1064, 497 }, /* 0x17: 856x480 */
+ { 1, 1,1056, 497,1056, 497 }, /* 0x18: 800x480 */
+ { 1, 1,1328, 739,1328, 739 }, /* 0x19: 1024x576 */
+ { 1, 1,1680, 892,1680, 892 }, /* 0x1a: 1152x864 */
+ { 1, 1,1808, 808,1808, 808 }, /* 0x1b: 1360x768 */
+ { 1, 1,1104, 563,1104, 563 } /* 0x1c: 960x540 */
};
-static const SiS_LCDACRT1DataStruct Compaq1280x1024_LCDACRT1_1_H[]=
-{
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
- 0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
- 0x01}},
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
- 0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
- 0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
- 0x01}},
- {{0x56,0x27,0x27,0x9a,0x30,0x1e,0x08,0x3e,
- 0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x05,
- 0x00}},
- {{0x60,0x31,0x31,0x84,0x3a,0x88,0x80,0xf0,
- 0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x01,
- 0x01}},
- {{0x6e,0x3f,0x3f,0x92,0x48,0x96,0x28,0xf5,
- 0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct Clevo1024x768_LCDACRT1_1[]=
-{
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
- 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x97,0x1f,
- 0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
- 0x00}},
- {{0x73,0x4f,0x4f,0x97,0x55,0x86,0x04,0x3e,
- 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
- 0x00}},
- {{0x87,0x63,0x63,0x8B,0x69,0x1A,0x7c,0xf0,
- 0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x26,
- 0x01}},
- {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct Clevo1024x768_LCDACRT1_1_H[]=
-{
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
- 0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
- 0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
- 0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
- 0x00}},
- {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
- 0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
- 0x00}},
- {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
- 0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
- 0x01}},
- {{0x63,0x3F,0x3F,0x87,0x4A,0x93,0x24,0xF5,
- 0x02,0x88,0xFF,0xFF,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct Clevo1024x768_LCDACRT1_2[]=
-{
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
- 0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
- 0x00}},
- {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
- 0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
- 0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
- 0x01}}
-};
-
-static const SiS_LCDACRT1DataStruct Clevo1024x768_LCDACRT1_2_H[]=
-{
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x57,0x8e,0x8f,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x3e,0x85,0x5d,0x5d,0x25,0x10,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x57,0x8e,0x8f,0x8f,0x25,0x30,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x3e,0x85,0x5d,0x5d,0x25,0x10,0x00,0x01,
- 0x00 }},
- {{0x7b,0x27,0x27,0x9f,0x46,0x97,0x24,0xbb,
- 0x7f,0x86,0xdf,0xdf,0x25,0x10,0x00,0x01,
- 0x00 }},
- {{0x71,0x31,0x31,0x95,0x46,0x97,0x24,0xf1,
- 0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x01,
- 0x01 }},
- {{0x63,0x3f,0x3f,0x87,0x46,0x97,0x24,0xf5,
- 0x0f,0x86,0xff,0xff,0x25,0x30,0x00,0x01,
- 0x01 }}
-};
-
-#endif /* 315 */
/**************************************************************/
/* LVDS ----------------------------------------------------- */
{ 848, 389,1060, 629},
{ 848, 518,1060, 629},
{1056, 628,1056, 628},
- {1056, 628,1056, 628},
- { 800, 449,1000, 644},
- { 800, 525,1000, 635}
+ {1056, 628,1056, 628}
};
static const SiS_LVDSDataStruct SiS_LVDS800x600Data_2[]=
{1056, 628,1056, 628},
{1056, 628,1056, 628},
{1056, 628,1056, 628},
- {1056, 628,1056, 628},
- { 800, 449,1000, 644},
- { 800, 525,1000, 635}
+ {1056, 628,1056, 628}
};
static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_1[]=
{ 840, 518,1344, 806}, /* 640x480 */
{1050, 638,1344, 806}, /* 800x600 */
{1344, 806,1344, 806}, /* 1024x768 */
- { 800, 449,1280, 801},
- { 800, 525,1280, 813}
};
static const SiS_LVDSDataStruct SiS_LVDS1024x768Data_2[]=
{1344, 806,1344, 806},
{1344, 806,1344, 806},
{1344, 806,1344, 806},
- { 800, 449,1280, 801},
- { 800, 525,1280, 813}
};
-
static const SiS_LVDSDataStruct SiS_LVDS1280x1024Data_1[]=
{
{1048, 442,1688,1066},
{ 840, 560,1344, 800},
{ 840, 689,1344, 800},
{1050, 800,1344, 800},
- {1344, 800,1344, 800},
- { 800, 449,1280, 789},
- { 800, 525,1280, 785}
+ {1344, 800,1344, 800}
};
static const SiS_LVDSDataStruct SiS_LVDS1024x600Data_2[] =
{1344, 800,1344, 800},
{1344, 800,1344, 800},
{1344, 800,1344, 800},
- {1344, 800,1344, 800},
- { 800, 449,1280, 801},
- { 800, 525,1280, 813}
+ {1344, 800,1344, 800}
};
static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_1[] =
{ 840, 409,1344, 806},
{ 840, 518,1344, 806},
{1050, 638,1344, 806},
- {1344, 806,1344, 806},
- { 800, 449,1280, 801},
- { 800, 525,1280, 813}
+ {1344, 806,1344, 806}
};
static const SiS_LVDSDataStruct SiS_LVDS1152x768Data_2[] =
{1344, 806,1344, 806},
{1344, 806,1344, 806},
{1344, 806,1344, 806},
- {1344, 806,1344, 806},
- { 800, 449,1280, 801},
- { 800, 525,1280, 813}
+ {1344, 806,1344, 806}
};
/* Pass 1:1 data */
{ 800, 525, 800, 525}, /* 640x480 */
{1056, 628, 1056, 628}, /* 800x600 */
{1344, 806, 1344, 806}, /* 1024x768 */
- {1344,1066, 1344,1066}, /* 1280x1024 */ /* INSERTED ! */
+ {1688,1066, 1688,1066}, /* 1280x1024 */ /* INSERTED ! */
{1688, 806, 1688, 806}, /* 1280x768 */
/* No other panels ! */
};
{1160, 840,1160, 840}
};
-/* LVDS Skew */
-
-static const SiS_LVDSDesStruct SiS_PanelTypeNS_1[]=
-{
- { 8, 0},
- { 8, 0},
- { 8, 0},
- { 8, 0},
- { 8, 0},
- { 0, 0},
- { 0, 0},
- { 0, 0},
- { 0, 806},
- { 0, 0}
-};
-
-static const SiS_LVDSDesStruct SiS_PanelTypeNS_2[] =
-{
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0},
- { 0 , 0}
-};
-
/* Chrontel TV Skew */
static const SiS_LVDSDesStruct SiS_CHTVUNTSCDesData[]=
0x01}}
};
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1XXXxXXX_1[] =
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
- 0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
- 0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
- 0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x02,
- 0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
- 0x00,0x84,0xff,0x29,0x09,0x00,0x07,
- 0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x07,
- 0x01}}
-};
-
-static const SiS_LVDSCRT1DataStruct SiS_LVDSCRT1XXXxXXX_1_H[] =
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
- 0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
- 0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
- 0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
- 0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
- 0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
- 0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
- 0x02,0x88,0xff,0x25,0x10,0x00,0x01,
- 0x01}}
-};
-
-
/**************************************************************/
/* COMMON --------------------------------------------------- */
/**************************************************************/
{ 0x0000 }
};
-USHORT SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
+USHORT SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay,
+ int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
USHORT SiS_GetModeID_LCD(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN,
USHORT CustomT, int LCDwith, int LCDheight);
USHORT SiS_GetModeID_TV(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth);
void SiS_DisplayOff(SiS_Private *SiS_Pr);
void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
void SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
USHORT SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo);
void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
+void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
#ifdef LINUX_XF86
BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
unsigned char modeno, unsigned char rateindex);
int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
unsigned char modeno, unsigned char rateindex,
- ULONG *left_margin, ULONG *right_margin,
- ULONG *upper_margin, ULONG *lower_margin,
- ULONG *hsync_len, ULONG *vsync_len,
- ULONG *sync, ULONG *vmode);
+ struct fb_var_screeninfo *var);
BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
#endif
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Mode initializing code (CRT2 section)
* for SiS 300/305/540/630/730 and
- * SiS 315/550/650/M650/651/661FX/M661xX/740/741/M741/330/660/M660/760/M760
- * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ * SiS 315/550/650/M650/651/661FX/M661xX/740/741(GX)/M741/330/660/M660/760/M760
+ * (Universal module for Linux kernel framebuffer and XFree86/X.org 4.x)
*
* Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#include "init301.h"
-#if 0
-#define TWNEWPANEL
-#endif
-
#ifdef SIS300
#include "oem300.h"
#endif
#define SiS_I2CDELAY 1000
#define SiS_I2CDELAYSHORT 150
+static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr);
+
/*********************************************/
/* HELPER: Lock/Unlock CRT2 */
/*********************************************/
void
SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- if(HwInfo->jChipType >= SIS_315H)
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
- else
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+ if(HwInfo->jChipType >= SIS_315H)
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+ else
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
}
void
SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- if(HwInfo->jChipType >= SIS_315H)
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
- else
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
-}
-
-/*********************************************/
-/* HELPER: Enable CRT2 */
-/*********************************************/
-
-void
-SiS_EnableCRT2(SiS_Private *SiS_Pr)
-{
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+ if(HwInfo->jChipType >= SIS_315H)
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+ else
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
}
/*********************************************/
static void
SiS_SetRegSR11ANDOR(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DataAND, USHORT DataOR)
{
- if(HwInfo->jChipType >= SIS_661) DataAND &= 0x0f;
+ if(HwInfo->jChipType >= SIS_661) {
+ DataAND &= 0x0f;
+ DataOR &= 0x0f;
+ }
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,DataAND,DataOR);
}
/* HELPER: Get Pointer to LCD structure */
/*********************************************/
-/* For 661 series only */
#ifdef SIS315H
-#if 0 /* Need to wait until hardware using this really exists */
static UCHAR *
-GetLCDPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int tabletype,
- USHORT ModeNo, USHORT ModeIdIndex, USHORT RRTI)
+GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- UCHAR *tableptr = NULL;
- UCHAR tablelengths[] = { 8, 7, 6, 6, 8, 6, 0, 0, 0 };
- USHORT modeflag, CRT2Index, tablelength, lcdid, myid, tableptri;
-
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- CRT2Index = SiS_Pr->SiS_RefIndex[RRTI].Ext_CRT2CRTC;
- /* This is total bullshit: */
- if(SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO == SIS_RI_720x576) CRT2Index = 10;
- }
-
- if(tabletype <= 1) {
-#if 0 /* Not yet implemented */
- if(ModeNo <= 0x13) {
- CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex]. + 5;
- } else {
- CRT2Index = SiS_Pr->SiS_RefIndex[RRTI]. + 5;
- }
- if(tabletype & 1) CRT2Index >>= 4;
-#endif
- }
-
- CRT2Index &= 0x0f;
-
- tablelength = tablelengths[tabletype];
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- if((tabletype == 5) || (tabletype == 7)) tablelength = 8;
- if((tabletype == 3) || (tabletype == 8)) tablelength = 8;
- }
-
- if(!tablelength) return NULL;
-
- tableptri = ROMAddr[0x222] | (ROMAddr[0x223] << 8);
- tableptri += (tabletype << 1);
- if(!tableptri) return NULL;
- tableptr = &ROMAddr[tableptri];
-
- do {
- lcdid = tableptr[0];
- if(lcdid == 0xff) break;
- myid = SiS_Pr->SiS_LCDResInfo;
- if((lcdid & 0x80) && (lcdid != 0x80)) {
- lcdid &= 0x7f;
- myid = SiS_Pr->SiS_LCDTypeInfo;
- }
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) myid &= ~0x1f;
-
- if(myid == lcdid) {
- lcdid = tableptr[1] | (tableptr[2] << 8);
- myid = SiS_Pr->SiS_LCDInfo661;
- if(modeflag & HalfDCLK) myid |= 0x200;
- if(ModeNo <= 0x13) myid |= 0x400;
- lcdid &= myid;
- myid = tableptr[3] | (tableptr[4] << 8);
- if(lcdid == myid) break;
- }
- tableptr += 7;
- } while (1);
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ UCHAR *myptr = NULL;
+ USHORT romindex = 0;
- if(lcdid == myid) {
- lcdid = tableptr[5] | (tableptr[6] << 8);
- lcdid += (tablelength * CRT2Index);
- return((UCHAR *)&ROMAddr[lcdid]);
- }
+ /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+ * due to the variaty of panels the BIOS doesn't know about.
+ */
- return NULL;
+ if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ myptr = (UCHAR *)SiS_LCDStruct661;
+ romindex = SISGETROMW(0x100);
+ if(romindex) {
+ romindex += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x7d) & 0x1f) * 26);
+ myptr = &ROMAddr[romindex];
+ }
+ }
+ return myptr;
}
-#endif
-static UCHAR *
-GetLCDStructPtr661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+static USHORT
+GetLCDStructPtr661_2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT lcdres = SiS_Pr->SiS_LCDResInfo;
- USHORT lcdtype = SiS_Pr->SiS_LCDTypeInfo;
- USHORT romindex=0;
- UCHAR *myptr = NULL;
- UCHAR lcdid;
+ USHORT romptr = 0;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- romindex = ROMAddr[0x256] | (ROMAddr[0x257] << 8);
- }
- if(romindex) {
- myptr = &ROMAddr[romindex];
- } else {
- myptr = (UCHAR *)SiS_LCDStruct661;
- }
+ /* Use the BIOS tables only for LVDS panels; DVI is unreliable
+ * due to the variaty of panels the BIOS doesn't know about.
+ */
- while(myptr[0] != 0xff) {
- lcdid = myptr[0];
- if((lcdid & 0x80) && (lcdid != 0x80)) {
- lcdres = lcdtype;
- lcdid &= 0x7f;
- }
- if(lcdid == lcdres) break;
- myptr += 26;
+ if((SiS_Pr->SiS_ROMNew) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ romptr = SISGETROMW(0x102);
+ romptr += ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) * SiS_Pr->SiS661LCD2TableSize);
}
- if(myptr[0] == 0xff) return NULL;
- return myptr;
+ return(romptr);
}
#endif
USHORT RefreshRateTableIndex, USHORT *i,
PSIS_HW_INFO HwInfo)
{
- USHORT tempax,tempbx,infoflag;
-
- tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+ USHORT checkmask=0,modeid,infoflag;
- tempax = 0;
+ modeid = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
if(SiS_Pr->SiS_VBType & VB_SISVB) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
- tempax |= SupportRAMDAC2;
+ checkmask |= SupportRAMDAC2;
if(HwInfo->jChipType >= SIS_315H) {
- tempax |= SupportRAMDAC2_135;
+ checkmask |= SupportRAMDAC2_135;
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- tempax |= SupportRAMDAC2_162;
+ checkmask |= SupportRAMDAC2_162;
if(SiS_Pr->SiS_VBType & VB_SIS301C) {
- tempax |= SupportRAMDAC2_202;
+ checkmask |= SupportRAMDAC2_202;
}
}
}
} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- tempax |= SupportLCD;
+ checkmask |= SupportLCD;
if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(tempbx == 0x2e) { /* 640x480 */
- tempax |= Support64048060Hz;
- }
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(modeid == 0x2e) checkmask |= Support64048060Hz;
}
}
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- tempax |= SupportHiVision;
+ checkmask |= SupportHiVision;
} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750|SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
- tempax |= SupportTV;
+ checkmask |= SupportTV;
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- tempax |= SupportTV1024;
+ checkmask |= SupportTV1024;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+ checkmask |= SupportYPbPr750p;
+ }
+ }
}
}
- } else { /* for LVDS */
+ } else { /* LVDS */
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- tempax |= SupportCHTV;
+ checkmask |= SupportCHTV;
}
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- tempax |= SupportLCD;
+ checkmask |= SupportLCD;
}
}
/* Look backwards in table for matching CRT2 mode */
- for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+ for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == modeid; (*i)--) {
infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
- if(infoflag & tempax) return(1);
+ if(infoflag & checkmask) return TRUE;
if((*i) == 0) break;
}
* for a matching CRT2 mode if no mode was found yet.
*/
for((*i) = 0; ; (*i)++) {
- if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
- return(0);
+ if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != modeid) {
+ return FALSE;
}
infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
- if(infoflag & tempax) return(1);
+ if(infoflag & checkmask) return TRUE;
}
- return(1);
+ return TRUE;
}
/*********************************************/
-/* Get rate pointer */
+/* Get rate index */
/*********************************************/
USHORT
/* Do NOT check for UseCustomMode here, will skrew up FIFO */
if(ModeNo == 0xfe) return 0;
- if(ModeNo <= 0x13)
+ if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- else
+ } else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(modeflag & HalfDCLK) return(0);
+ if(modeflag & HalfDCLK) return 0;
}
}
- if(ModeNo < 0x14) return(0xFFFF);
-
- /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4]. */
+ if(ModeNo < 0x14) return 0xFFFF;
index = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x33) >> SiS_Pr->SiS_SelectCRT2Rate) & 0x0F;
backupindex = index;
}
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
- temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+ temp = LCDRefreshIndex[SiS_GetBIOSLCDResInfo(SiS_Pr)];
if(index > temp) index = temp;
}
}
/* HELPER: GET SOME DATA FROM BIOS ROM */
/*********************************************/
+#ifdef SIS300
static BOOLEAN
SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
+ UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
USHORT temp,temp1;
- UCHAR *ROMAddr;
- if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
- temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
- if(temp1 & temp) return(1);
+ temp1 = SISGETROMW(0x23b);
+ if(temp1 & temp) return TRUE;
}
}
- return(0);
+ return FALSE;
}
static BOOLEAN
SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
+ UCHAR *ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase;
USHORT temp,temp1;
- UCHAR *ROMAddr;
- if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff) >> 4);
- temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
- if(temp1 & temp) return(1);
+ temp1 = SISGETROMW(0x23d);
+ if(temp1 & temp) return TRUE;
}
}
- return(0);
+ return FALSE;
}
+#endif
/*********************************************/
/* HELPER: DELAY FUNCTIONS */
}
}
+#if defined(SIS300) || defined(SIS315H)
static void
SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
{
delay--;
}
}
+#endif
#ifdef SIS315H
static void
}
#endif
+#if defined(SIS300) || defined(SIS315H)
static void
SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
{
SiS_GenericDelay(SiS_Pr,0x42);
}
}
+#endif
static void
SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT DelayTime)
{
+#if defined(SIS300) || defined(SIS315H)
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT PanelID, DelayIndex, Delay=0;
+#endif
if(HwInfo->jChipType < SIS_315H) {
Delay = 3;
} else {
if(DelayTime >= 2) DelayTime -= 2;
-
if(!(DelayTime & 0x01)) {
Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
} else {
Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
}
- if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x220] & 0x40) {
- if(!(DelayTime & 0x01)) {
- Delay = (USHORT)ROMAddr[0x225];
- } else {
- Delay = (USHORT)ROMAddr[0x226];
- }
+ if(!(DelayTime & 0x01)) Delay = (USHORT)ROMAddr[0x225];
+ else Delay = (USHORT)ROMAddr[0x226];
}
}
}
- SiS_ShortDelay(SiS_Pr,Delay);
+ SiS_ShortDelay(SiS_Pr, Delay);
#endif /* SIS300 */
#ifdef SIS315H
- if(HwInfo->jChipType >= SIS_330) return;
+ if((HwInfo->jChipType >= SIS_661) ||
+ (HwInfo->jChipType <= SIS_315PRO) ||
+ (HwInfo->jChipType == SIS_330)) {
+
+ if(!(DelayTime & 0x01)) {
+ SiS_DDC2Delay(SiS_Pr, 0x1000);
+ } else {
+ SiS_DDC2Delay(SiS_Pr, 0x4000);
+ }
- if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+ } else if((SiS_Pr->SiS_IF_DEF_LVDS == 1) /* ||
(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) { /* 315 series, LVDS; Special */
+ (SiS_Pr->SiS_CustomT == CUT_CLEVO1400) */ ) { /* 315 series, LVDS; Special */
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
} else {
Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
}
- if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+ if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
if(ROMAddr[0x13c] & 0x40) {
if(!(DelayTime & 0x01)) {
Delay = (USHORT)ROMAddr[0x17e];
}
}
}
- SiS_ShortDelay(SiS_Pr,Delay);
+ SiS_ShortDelay(SiS_Pr, Delay);
}
} else if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 315 series, all bridges */
USHORT watchdog;
if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-
if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
watchdog = 65535;
while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
}
+#if defined(SIS300) || defined(SIS315H)
static void
SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
{
watchdog = 65535;
while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
}
+#endif
static void
SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
if(temp & 0x01) {
if((tempal & 0x08)) continue;
- if(!(tempal & 0x08)) break;
+ else break;
} else {
if(!(tempal & 0x08)) continue;
- if((tempal & 0x08)) break;
+ else break;
}
}
temp ^= 0x01;
/* HELPER: MISC */
/*********************************************/
+#ifdef SIS300
static BOOLEAN
SiS_Is301B(SiS_Private *SiS_Pr)
{
- USHORT flag;
-
- flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
- if(flag >= 0xb0) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
return FALSE;
}
+#endif
static BOOLEAN
SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
return FALSE;
}
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsVAorLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+ if(SiS_IsVAMode(SiS_Pr,HwInfo)) return TRUE;
+ if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) return TRUE;
+ return FALSE;
+}
+#endif
+
static BOOLEAN
SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
SiS_TVEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
- if(SiS_Pr->SiS_VBType & (VB_301C | VB_SIS301LV302LV)) {
+ if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV302LV)) {
if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
}
return FALSE;
static BOOLEAN
SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- USHORT flag;
-
if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
- flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
- if(flag & 0x10) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
}
return FALSE;
}
USHORT flag;
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- return FALSE;
+ return TRUE;
} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
- if((flag == 1) || (flag == 2)) return FALSE;
+ if((flag == 1) || (flag == 2)) return TRUE;
}
- return TRUE;
+ return FALSE;
}
static BOOLEAN
{
USHORT flag;
- if(!(SiS_BridgeIsOn(SiS_Pr))) {
+ if(SiS_BridgeIsOn(SiS_Pr)) {
flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
if(HwInfo->jChipType < SIS_315H) {
flag &= 0xa0;
- if((flag == 0x80) || (flag == 0x20)) return FALSE;
+ if((flag == 0x80) || (flag == 0x20)) return TRUE;
} else {
flag &= 0x50;
- if((flag == 0x40) || (flag == 0x10)) return FALSE;
+ if((flag == 0x40) || (flag == 0x10)) return TRUE;
}
}
- return TRUE;
+ return FALSE;
}
static BOOLEAN
-SiS_BridgeInSlave(SiS_Private *SiS_Pr)
+SiS_BridgeInSlavemode(SiS_Private *SiS_Pr)
{
USHORT flag1;
if(!(SiS_Pr->SiS_ChSW)) return;
#ifndef LINUX_XF86
- SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
+ SiS_SetRegLong(0xcf8,0x80000874); /* get ACPI base */
acpibase = SiS_GetRegLong(0xcfc);
#else
acpibase = pciReadLong(0x00000800, 0x74);
}
void
-SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
- USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
- int checkcrt2mode)
+SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ PSIS_HW_INFO HwInfo, int checkcrt2mode)
{
USHORT tempax,tempbx,temp;
USHORT modeflag, resinfo=0;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
} else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
}
SiS_Pr->SiS_SetFlag = 0;
SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
tempbx = 0;
- if(SiS_BridgeIsOn(SiS_Pr) == 0) {
+ if(SiS_BridgeIsOn(SiS_Pr)) {
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
#if 0
if(HwInfo->jChipType < SIS_661) {
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
}
if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
- /* Reset LCDA setting */
+ /* Reset LCDA setting if not driver mode */
SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
}
if(IS_SIS650) {
tempbx |= SetCRT2ToLCDA;
}
}
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)) {
+ tempbx &= ~(SetCRT2ToRAMDAC);
+ }
+
if(HwInfo->jChipType >= SIS_661) {
tempbx &= ~(SetCRT2ToYPbPr525750 | SetCRT2ToHiVision);
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
SetPALTV |
SwitchCRT2 |
SetSimuScanMode );
- if(tempbx & SetCRT2ToLCDA) {
- tempbx &= (clearmask | SetCRT2ToLCDA);
- }
- if(tempbx & SetCRT2ToRAMDAC) {
- tempbx &= (clearmask | SetCRT2ToRAMDAC);
- }
- if(tempbx & SetCRT2ToLCD) {
- tempbx &= (clearmask | SetCRT2ToLCD);
- }
- if(tempbx & SetCRT2ToSCART) {
- tempbx &= (clearmask | SetCRT2ToSCART);
- }
- if(tempbx & SetCRT2ToHiVision) {
- tempbx &= (clearmask | SetCRT2ToHiVision);
- }
- if(tempbx & SetCRT2ToYPbPr525750) {
- tempbx &= (clearmask | SetCRT2ToYPbPr525750);
- }
+ if(tempbx & SetCRT2ToLCDA) tempbx &= (clearmask | SetCRT2ToLCDA);
+ if(tempbx & SetCRT2ToRAMDAC) tempbx &= (clearmask | SetCRT2ToRAMDAC);
+ if(tempbx & SetCRT2ToLCD) tempbx &= (clearmask | SetCRT2ToLCD);
+ if(tempbx & SetCRT2ToSCART) tempbx &= (clearmask | SetCRT2ToSCART);
+ if(tempbx & SetCRT2ToHiVision) tempbx &= (clearmask | SetCRT2ToHiVision);
+ if(tempbx & SetCRT2ToYPbPr525750) tempbx &= (clearmask | SetCRT2ToYPbPr525750);
} else {
if(HwInfo->jChipType >= SIS_315H) {
if(tempbx & SetCRT2ToLCDA) {
}
}
- if(!(tempbx & DriverMode)){
- tempbx |= SetSimuScanMode;
- }
+ if(!(tempbx & DriverMode)) tempbx |= SetSimuScanMode;
/* LVDS/CHRONTEL (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
if(SiS_Pr->SiS_ModeType <= ModeVGA) {
if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
- ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
+ ((SiS_Pr->SiS_VBType & VB_NoLCD) && (tempbx & SetCRT2ToLCD)) ) {
modeflag &= (~CRT2Mode);
}
}
}
}
} else {
- if(!(SiS_BridgeIsEnabled(SiS_Pr,HwInfo))) {
+ if(SiS_BridgeIsEnabled(SiS_Pr,HwInfo)) {
if(!(tempbx & DriverMode)) {
- if(SiS_BridgeInSlave(SiS_Pr)) {
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
tempbx |= SetSimuScanMode;
}
}
if(HwInfo->jChipType >= SIS_330) romindex = 0x11b;
}
if(temp) {
- if(romindex && ROMAddr && SiS_Pr->SiS_UseROM) {
+ if(romindex && SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
OutputSelect = ROMAddr[romindex];
if(!(OutputSelect & EnablePALMN)) {
SiS_SetRegAND(SiS_Pr->SiS_P3d4,temp,0x3F);
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
SiS_Pr->SiS_TVMode |= (TVSetHiVision | TVSetPAL);
}
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToYPbPr525750 | SetCRT2ToHiVision)) {
+ if(resinfo == SIS_RI_800x480 || resinfo == SIS_RI_1024x576 || resinfo == SIS_RI_1280x720) {
+ SiS_Pr->SiS_TVMode |= TVAspect169;
+ } else {
+ temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
+ if(temp1 & 0x02) {
+ if(SiS_Pr->SiS_TVMode & (TVSetYPbPr750p | TVSetHiVision)) {
+ SiS_Pr->SiS_TVMode |= TVAspect169;
+ } else {
+ SiS_Pr->SiS_TVMode |= TVAspect43LB;
+ }
+ } else {
+ SiS_Pr->SiS_TVMode |= TVAspect43;
+ }
+ }
+ }
}
}
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
#endif
-
}
/*********************************************/
/* GET LCD INFO */
/*********************************************/
+static USHORT
+SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr)
+{
+ USHORT temp = SiS_Pr->SiS_LCDResInfo;
+ /* Translate my LCDResInfo to BIOS value */
+ if(temp == Panel_1280x768_2) temp = Panel_1280x768;
+ if(temp == Panel_1280x768_3) temp = Panel_1280x768;
+ return temp;
+}
+
+static void
+SiS_GetLCDInfoBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+ UCHAR *ROMAddr;
+ USHORT temp;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
+ SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+ SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
+ SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
+ SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
+ SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
+ SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
+#endif
+
+ if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+ if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
+ SiS_Pr->SiS_NeedRomModeData = TRUE;
+ SiS_Pr->PanelHT = temp;
+ }
+ if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
+ SiS_Pr->SiS_NeedRomModeData = TRUE;
+ SiS_Pr->PanelVT = temp;
+ }
+ SiS_Pr->PanelHRS = SISGETROMW(10);
+ SiS_Pr->PanelHRE = SISGETROMW(12);
+ SiS_Pr->PanelVRS = SISGETROMW(14);
+ SiS_Pr->PanelVRE = SISGETROMW(16);
+ SiS_Pr->PanelVCLKIdx315 = VCLK_CUSTOM_315;
+ SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].CLOCK =
+ SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].CLOCK = (USHORT)((UCHAR)ROMAddr[18]);
+ SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2B =
+ SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_A = ROMAddr[19];
+ SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
+ SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
+ SiS_Pr->PanelHT, SiS_Pr->PanelVT,
+ SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
+ SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
+ SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
+ SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
+ SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
+#endif
+
+ }
+#endif
+}
+
void
SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
PSIS_HW_INFO HwInfo)
{ 0, 1, 2, 3, 7, 4, 5, 8,
0, 0, 10, 0, 0, 0, 0, 15 };
- SiS_Pr->SiS_LCDResInfo = 0;
+ SiS_Pr->SiS_LCDResInfo = 0;
SiS_Pr->SiS_LCDTypeInfo = 0;
- SiS_Pr->SiS_LCDInfo = 0;
+ SiS_Pr->SiS_LCDInfo = 0;
+ SiS_Pr->PanelHRS = 999; /* HSync start */
+ SiS_Pr->PanelHRE = 999; /* HSync end */
+ SiS_Pr->PanelVRS = 999; /* VSync start */
+ SiS_Pr->PanelVRE = 999; /* VSync end */
+ SiS_Pr->SiS_NeedRomModeData = FALSE;
- if(SiS_Pr->UseCustomMode) {
+ if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
+
+ if(ModeNo <= 0x13) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else if(SiS_Pr->UseCustomMode) {
modeflag = SiS_Pr->CModeFlag;
} else {
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
}
- if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
-
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+ if(!temp) return;
- if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
+ if((HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
+ SiS_Pr->SiS_LCDTypeInfo = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x7c) >> 2;
+ } else if((HwInfo->jChipType < SIS_315H) || (HwInfo->jChipType >= SIS_661)) {
SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
} else {
SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
}
temp &= 0x0f;
if(HwInfo->jChipType < SIS_315H) {
- /* Translate 300 series LCDRes to 315 series for unified usage */
- temp = SiS300SeriesLCDRes[temp];
+ /* Translate 300 series LCDRes to 315 series for unified usage */
+ temp = SiS300SeriesLCDRes[temp];
}
- SiS_Pr->SiS_LCDResInfo = temp;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
- SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
- } else {
- if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
- SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+ if(HwInfo->jChipType == SIS_550) {
+ if(temp == Panel310_640x480_2) temp = Panel_640x480_2;
+ if(temp == Panel310_640x480_3) temp = Panel_640x480_3;
}
- if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
- if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
- SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* SiS LVDS */
+ if(temp == Panel310_1280x768) {
+ temp = Panel_1280x768_2;
+#ifdef SIS315H
+ if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+ if((myptr[8] | (myptr[9] << 8)) == 798) temp = Panel_1280x768_3;
+ }
+#endif
+ }
}
+ SiS_Pr->SiS_LCDResInfo = temp;
+
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
}
}
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
+ SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+ }
+
+ SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
+
switch(SiS_Pr->SiS_LCDResInfo) {
- case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600; break;
- case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; break;
- case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
- case Panel_640x480_3:
+ case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480;
+ SiS_Pr->PanelHT = 400; SiS_Pr->PanelVT = 525;
+ SiS_Pr->PanelVCLKIdx300 = VCLK28;
+ SiS_Pr->PanelVCLKIdx315 = VCLK28;
+ break;
case Panel_640x480_2:
- case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480; break;
- case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600; break;
- case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864; break;
- case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960; break;
- case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768; break;
- case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
- case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768; break;
- case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
- case Panel_320x480: SiS_Pr->PanelXRes = 320; SiS_Pr->PanelYRes = 480; break;
- case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
- SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
- break;
- case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
- case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480; break;
- default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768; break;
+ case Panel_640x480_3: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
+ SiS_Pr->PanelVRS = 24; SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVCLKIdx300 = VCLK28;
+ SiS_Pr->PanelVCLKIdx315 = VCLK28;
+ break;
+ case Panel_640x480: SiS_Pr->PanelXRes = 640; SiS_Pr->PanelYRes = 480;
+ SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVCLKIdx300 = VCLK28;
+ SiS_Pr->PanelVCLKIdx315 = VCLK28;
+ break;
+ case Panel_800x600: SiS_Pr->PanelXRes = 800; SiS_Pr->PanelYRes = 600;
+ SiS_Pr->PanelHT = 1056; SiS_Pr->PanelVT = 628;
+ SiS_Pr->PanelHRS = 40; SiS_Pr->PanelHRE = 128;
+ SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 4;
+ SiS_Pr->PanelVCLKIdx300 = VCLK40;
+ SiS_Pr->PanelVCLKIdx315 = VCLK40;
+ break;
+ case Panel_1024x600: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 600;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 800;
+ SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
+ SiS_Pr->PanelVRS = 2 /* 88 */ ; SiS_Pr->PanelVRE = 6;
+ SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
+ break;
+ case Panel_1024x768: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHRS = 24; SiS_Pr->PanelHRE = 136;
+ SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
+ if(HwInfo->jChipType < SIS_315H) {
+ SiS_Pr->PanelHRS = 23;
+ SiS_Pr->PanelVRE = 5;
+ }
+ SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1152x768: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 768;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHRS = 24;
+ SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
+ if(HwInfo->jChipType < SIS_315H) {
+ SiS_Pr->PanelHRS = 23;
+ SiS_Pr->PanelVRE = 5;
+ }
+ SiS_Pr->PanelVCLKIdx300 = VCLK65_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK65_315;
+ break;
+ case Panel_1152x864: SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes = 864;
+ break;
+ case Panel_1280x720: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 720;
+ SiS_Pr->PanelHT = 1650; SiS_Pr->PanelVT = 750;
+ SiS_Pr->PanelHRS = 110; SiS_Pr->PanelHRE = 40;
+ SiS_Pr->PanelVRS = 5; SiS_Pr->PanelVRE = 5;
+ SiS_Pr->PanelVCLKIdx315 = VCLK_1280x720;
+ /* Data above for TMDS (projector); get from BIOS for LVDS */
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1280x768: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 802;
+ SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRS = 112;
+ SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
+ SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
+ break;
+ case Panel_1280x768_2: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
+ SiS_Pr->PanelHT = 1408; SiS_Pr->PanelVT = 806;
+ SiS_Pr->PanelHRS = 16; SiS_Pr->PanelHRE = 64;
+ SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
+ SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_2;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1280x768_3: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 768;
+ SiS_Pr->PanelHT = 1664; SiS_Pr->PanelVT = 798;
+ SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 128;
+ SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 7;
+ SiS_Pr->PanelVCLKIdx315 = VCLK_1280x768_3;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1280x800: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 800;
+ SiS_Pr->PanelHT = 1656; SiS_Pr->PanelVT = 841; /* 1408, 816 */
+ SiS_Pr->PanelHRS = 32; SiS_Pr->PanelHRE = 312; /* 16, 64 */
+ SiS_Pr->PanelVRS = 16; SiS_Pr->PanelVRE = 8; /* 4, 3 */
+ SiS_Pr->PanelVCLKIdx315 = VCLK83_315;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1280x960: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 960;
+ SiS_Pr->PanelHT = 1800; SiS_Pr->PanelVT = 1000;
+ SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK108_3_315;
+ if(resinfo == SIS_RI_1280x1024) {
+ SiS_Pr->PanelVCLKIdx300 = VCLK100_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK100_315;
+ }
+ break;
+ case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
+ SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112;
+ SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVCLKIdx300 = VCLK108_3_300;
+ SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
+ SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 112; /* HRE OK for LVDS, not for LCDA */
+ SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVCLKIdx315 = VCLK108_2_315;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200;
+ SiS_Pr->PanelHT = 2160; SiS_Pr->PanelVT = 1250;
+ SiS_Pr->PanelHRS = 64; SiS_Pr->PanelHRE = 192;
+ SiS_Pr->PanelVRS = 1; SiS_Pr->PanelVRE = 3;
+ SiS_Pr->PanelVCLKIdx315 = VCLK162_315;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_1680x1050: SiS_Pr->PanelXRes = 1680; SiS_Pr->PanelYRes = 1050;
+ SiS_Pr->PanelHT = 1900; SiS_Pr->PanelVT = 1066;
+ SiS_Pr->PanelHRS = 26; SiS_Pr->PanelHRE = 76;
+ SiS_Pr->PanelVRS = 3; SiS_Pr->PanelVRE = 6;
+ SiS_Pr->PanelVCLKIdx315 = VCLK121_315;
+ SiS_GetLCDInfoBIOS(SiS_Pr, HwInfo);
+ break;
+ case Panel_Custom: SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
+ SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
+ SiS_Pr->PanelHT = SiS_Pr->CHTotal;
+ SiS_Pr->PanelVT = SiS_Pr->CVTotal;
+ if(SiS_Pr->CP_PreferredIndex != -1) {
+ SiS_Pr->PanelXRes = SiS_Pr->CP_HDisplay[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelYRes = SiS_Pr->CP_VDisplay[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelHT = SiS_Pr->CP_HTotal[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelVT = SiS_Pr->CP_VTotal[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelHRS = SiS_Pr->CP_HSyncStart[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelHRE = SiS_Pr->CP_HSyncEnd[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelVRS = SiS_Pr->CP_VSyncStart[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelVRE = SiS_Pr->CP_VSyncEnd[SiS_Pr->CP_PreferredIndex];
+ SiS_Pr->PanelHRS -= SiS_Pr->PanelXRes;
+ SiS_Pr->PanelHRE -= SiS_Pr->PanelHRS;
+ SiS_Pr->PanelVRS -= SiS_Pr->PanelYRes;
+ SiS_Pr->PanelVRE -= SiS_Pr->PanelVRS;
+ }
+ break;
+ case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024;
+ SiS_Pr->PanelHT = 1688; SiS_Pr->PanelVT = 1066;
+ break;
+ case Panel_848x480: SiS_Pr->PanelXRes = 848; SiS_Pr->PanelYRes = 480;
+ SiS_Pr->PanelHT = 1088; SiS_Pr->PanelVT = 525;
+ break;
+ default: SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes = 768;
+ SiS_Pr->PanelHT = 1344; SiS_Pr->PanelVT = 806;
+ break;
}
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
- if(HwInfo->jChipType < SIS_661) {
- temp &= ~0xe;
- } else {
+ SiS_Pr->SiS_LCDInfo = temp & ~0x000e;
+
+ if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+ else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+
#ifdef SIS315H
- if(!(temp & 0x10)) {
- if(temp & 0x08) temp |= LCDPass11;
+ if(HwInfo->jChipType >= SIS_661) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
}
- temp &= ~0xe;
if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
- if(myptr) {
- if(myptr[2] & 0x01) temp |= LCDDualLink;
- }
+ if(SiS_Pr->SiS_ROMNew) {
+ if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+ } else if((myptr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+ if(myptr[2] & 0x01) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+ }
+ }
+ } else if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ }
+ if((SiS_Pr->SiS_ROMNew) && (!(SiS_Pr->PanelSelfDetected))) {
+ SiS_Pr->SiS_LCDInfo &= ~(LCDRGB18Bit);
+ temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+ if(temp & 0x01) SiS_Pr->SiS_LCDInfo |= LCDRGB18Bit;
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(temp & 0x02) SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+ }
}
+ }
#endif
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ /* Always center screen on LVDS (if scaling is disabled) */
+ SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ /* Always center screen on SiS LVDS (if scaling is disabled) */
+ SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ } else {
+ /* By default, pass 1:1 on SiS TMDS (if scaling is disabled) */
+ SiS_Pr->SiS_LCDInfo |= LCDPass11;
+ if(SiS_Pr->CenterScreen == 1) SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
+ }
}
- SiS_Pr->SiS_LCDInfo = temp;
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
- SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24 */
+ SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
}
}
- if(!(SiS_Pr->UsePanelScaler)) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
- else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-
if(SiS_Pr->SiS_VBType & VB_SISVB) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
- /* For non-standard LCD resolution, we let the panel scale */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
- /* We do not scale to 1280x960 (B/C bridges only) */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- if(((HwInfo->jChipType >= SIS_315H) && (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
- ((HwInfo->jChipType < SIS_315H) && (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
- /* We do not scale to 1280x768 (B/C bridges only) */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- /* No non-scaling data available for LV bridges */
- SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- /* No idea about the timing and zoom factors */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
- /* We do not scale to 1280x1024 (all bridges) */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
- /* No idea about the timing and zoom factors (C bridge only) */
- SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
- }
+ if(modeflag & NoSupportLCDScale) {
+ /* No scaling for this mode on any panel */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
}
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
- }
- }
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_Custom:
+ /* For non-standard LCD resolution, we let the panel scale */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ break;
+ case Panel_1280x720:
+ if(SiS_Pr->PanelHT == 1650) {
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ case Panel_1280x768: /* TMDS only */
+ /* No idea about the timing and zoom factors */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ break;
+ case Panel_1280x960:
+ SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+ break;
+ case Panel_1280x1024:
+ if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
+ if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
+ ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
+ ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16) {
+ /* We do not scale to 1280x720/800/960 (B/C bridges only) */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ if(((HwInfo->jChipType >= SIS_315H) &&
+ (ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25)) ||
+ ((HwInfo->jChipType < SIS_315H) &&
+ (ModeNo == 0x55 || ModeNo == 0x5a || ModeNo == 0x5b))) {
+ /* We do not scale to 1280x768 (B/C bridges only) */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ }
+ break;
+ case Panel_1400x1050:
+ if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
+ if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e ||
+ ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78 ||
+ ModeNo == 0x14 || ModeNo == 0x15 || ModeNo == 0x16 ||
+ ModeNo == 0x23 || ModeNo == 0x24 || ModeNo == 0x25) {
+ /* Do not scale to 1280x720/768/800/960 (B/C bridges only) */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(ModeNo == 0x79 || ModeNo == 0x75 || ModeNo == 0x78) {
+ if(SiS_Pr->UsePanelScaler == -1) {
+ /* Do not scale to 1280x720 by default (LVDS bridges) */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ }
+ }
+ if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+ /* Do not scale to 1280x1024 (all bridges) */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
+ case Panel_1600x1200:
+ if(SiS_Pr->SiS_VBType & VB_SISTMDS) {
+ /* No idea about the timing and zoom factors (C bridge only) */
+ SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+ }
+ break;
}
}
}
- if(HwInfo->jChipType >= SIS_315H) {
-#ifdef SIS315H
- if(HwInfo->jChipType < SIS_661) {
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
- SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
- SiS_Pr->SiS_LCDInfo |= LCDPass11;
- }
- }
-#endif
- } else {
#ifdef SIS300
+ if(HwInfo->jChipType < SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
if(!(ROMAddr[0x235] & 0x02)) {
SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
}
}
+ }
#endif
+
+ /* Special cases */
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+ SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
}
- /* Trumpion: Assume non-expanding */
- if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
- SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
+ SiS_Pr->SiS_LCDInfo |= LCDPass11;
}
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- SiS_Pr->SiS_LCDInfo &= (~LCDPass11);
+ if(SiS_Pr->UseCustomMode) {
+ SiS_Pr->SiS_LCDInfo |= (DontExpandLCD | LCDPass11);
}
-#ifdef SIS315H
- if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- /* Enable 302LV/302ELV dual link mode.
- * For 661, this is done above.
- */
- if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)) {
- /* (Sets this in SenseLCD; new paneltypes) */
- SiS_Pr->SiS_LCDInfo |= LCDDualLink;
- }
- if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
- SiS_Pr->SiS_LCDInfo |= LCDDualLink;
- }
- }
+ /* (In)validate LCDPass11 flag */
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
}
-#endif
- if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+ /* Special cases */
+ if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+ (SiS_Pr->SiS_IF_DEF_DSTN) ||
+ (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+ (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+ SiS_Pr->PanelHRS = 999;
+ SiS_Pr->PanelHRE = 999;
+ }
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- if(ModeNo > 0x13) {
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
- SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- }
- }
- }
+ if( (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+ (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+ SiS_Pr->PanelVRS = 999;
+ SiS_Pr->PanelVRE = 999;
+ }
+
+#ifdef SIS315H
+ if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+ if(!(SiS_Pr->SiS_ROMNew)) {
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ /* Enable 302LV/302ELV dual link mode.
+ * For 661, this is done above.
+ */
+ if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1024x768)) {
+ /* (Sets this in SenseLCD; new paneltypes) */
+ SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+ }
+ if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1680x1050)) {
+ SiS_Pr->SiS_LCDInfo |= LCDDualLink;
+ }
}
- if(ModeNo == 0x12) {
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
+#endif
+
+ if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+ if(ModeNo == 0x12) {
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ } else if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x600) {
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
+ }
}
}
}
if(modeflag & HalfDCLK) {
- if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwInfo->jChipType < SIS_315H)) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
- if(ModeNo > 0x13) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
- if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- }
- }
- } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
- } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION == 1) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) {
+ SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else if(ModeNo > 0x13) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_800x600) {
+ if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+ }
+ }
}
}
SiS_Pr->SiS_SetFlag |= LCDVESATiming;
}
- SiS_Pr->SiS_LCDInfo661 = 0;
- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) SiS_Pr->SiS_LCDInfo661 |= 0x0001;
- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) SiS_Pr->SiS_LCDInfo661 |= 0x0002;
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) SiS_Pr->SiS_LCDInfo661 |= 0x0008;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) SiS_Pr->SiS_LCDInfo661 |= 0x0010;
- SiS_Pr->SiS_LCDInfo661 |= (SiS_Pr->SiS_LCDInfo & 0xe0);
- if(SiS_Pr->SiS_LCDInfo & LCDDualLink) SiS_Pr->SiS_LCDInfo661 |= 0x0100;
-
#ifdef LINUX_KERNEL
#ifdef TWDEBUG
printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
{
- USHORT tempbx;
- const USHORT LCDXlat0VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
- const USHORT LVDSXlat1VCLK[4] = {VCLK40, VCLK40, VCLK40, VCLK40};
- const USHORT LVDSXlat4VCLK[4] = {VCLK28, VCLK28, VCLK28, VCLK28};
-#ifdef SIS300
- const USHORT LCDXlat1VCLK300[4] = {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300};
- const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
- const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300};
- const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300, VCLK65_300, VCLK65_300, VCLK65_300};
-#endif
-#ifdef SIS315H
- const USHORT LCDXlat1VCLK310[4] = {VCLK65_315, VCLK65_315, VCLK65_315, VCLK65_315};
- const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
- const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315, VCLK65_315, VCLK65_315, VCLK65_315};
- const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
-#endif
- USHORT CRT2Index,VCLKIndex=0;
- USHORT modeflag,resinfo;
- const UCHAR *CHTVVCLKPtr = NULL;
- const USHORT *LCDXlatVCLK1 = NULL;
- const USHORT *LCDXlatVCLK2 = NULL;
- const USHORT *LVDSXlatVCLK2 = NULL;
- const USHORT *LVDSXlatVCLK3 = NULL;
-
- if(HwInfo->jChipType >= SIS_315H) {
-#ifdef SIS315H
- LCDXlatVCLK1 = LCDXlat1VCLK310;
- LCDXlatVCLK2 = LCDXlat2VCLK310;
- LVDSXlatVCLK2 = LVDSXlat2VCLK310;
- LVDSXlatVCLK3 = LVDSXlat3VCLK310;
-#endif
- } else {
-#ifdef SIS300
- LCDXlatVCLK1 = LCDXlat1VCLK300;
- LCDXlatVCLK2 = LCDXlat2VCLK300;
- LVDSXlatVCLK2 = LVDSXlat2VCLK300;
- LVDSXlatVCLK3 = LVDSXlat3VCLK300;
-#endif
- }
+ USHORT CRT2Index,VCLKIndex=0,VCLKIndexGEN=0;
+ USHORT modeflag,resinfo,tempbx;
+ const UCHAR *CHTVVCLKPtr = NULL;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ VCLKIndexGEN = (SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02)) >> 2) & 0x03;
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ VCLKIndexGEN = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ if(HwInfo->jChipType < SIS_315H) VCLKIndexGEN &= 0x3f;
}
if(SiS_Pr->SiS_VBType & VB_SISVB) { /* 30x/B/LV */
if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
CRT2Index >>= 6;
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* LCD */
if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
- VCLKIndex = LCDXlat0VCLK[CRT2Index];
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- VCLKIndex = LCDXlatVCLK1[CRT2Index];
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- VCLKIndex = LCDXlatVCLK1[CRT2Index];
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
- VCLKIndex = LCDXlatVCLK1[CRT2Index];
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- VCLKIndex = VCLK81_300; /* guessed */
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
- VCLKIndex = VCLK108_3_300;
- if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
- } else {
- VCLKIndex = LCDXlatVCLK2[CRT2Index];
- }
+ VCLKIndex = SiS_Pr->PanelVCLKIdx300;
} else {
- if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
- (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- VCLKIndex = VCLK108_2_315;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- VCLKIndex = VCLK81_315; /* guessed */
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- VCLKIndex = VCLK108_2_315;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- VCLKIndex = VCLK162_315;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
- VCLKIndex = VCLK108_3_315;
- if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- VCLKIndex = LCDXlatVCLK1[CRT2Index];
- } else {
- VCLKIndex = LCDXlatVCLK2[CRT2Index];
- }
- } else {
- VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02)); /* Port 3cch */
- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
- if(ModeNo > 0x13) {
- VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- }
+ VCLKIndex = SiS_Pr->PanelVCLKIdx315;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ VCLKIndex = VCLKIndexGEN;
+ switch(resinfo) {
+ /* Only those whose IndexGEN doesn't match VBVCLK array: */
+ case SIS_RI_1280x720: VCLKIndex = VCLK_1280x720;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
+ if(SiS_Pr->PanelHT == 1344) {
+ VCLKIndex = VCLK_1280x720_2;
+ }
+ }
+ break;
+ case SIS_RI_720x480: VCLKIndex = VCLK_720x480; break;
+ case SIS_RI_720x576: VCLKIndex = VCLK_720x576; break;
+ case SIS_RI_768x576: VCLKIndex = VCLK_768x576; break;
+ case SIS_RI_848x480: VCLKIndex = VCLK_848x480; break;
+ case SIS_RI_856x480: VCLKIndex = VCLK_856x480; break;
+ case SIS_RI_800x480: VCLKIndex = VCLK_800x480; break;
+ case SIS_RI_1024x576: VCLKIndex = VCLK_1024x576; break;
+ case SIS_RI_1152x864: VCLKIndex = VCLK_1152x864; break;
+ case SIS_RI_1360x768: VCLKIndex = VCLK_1360x768; break;
+ }
+
if(ModeNo <= 0x13) {
if(HwInfo->jChipType <= SIS_315PRO) {
if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
}
}
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* TV */
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
- else VCLKIndex = HiTVVCLK;
+ if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
+ else VCLKIndex = HiTVVCLK;
if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
- else VCLKIndex = HiTVTextVCLK;
+ if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
+ else VCLKIndex = HiTVTextVCLK;
}
- } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK - TVCLKBASE_315;
- else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
- else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
- else VCLKIndex = TVVCLK;
+ } else if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) VCLKIndex = YPbPr750pVCLK;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) VCLKIndex = TVVCLKDIV2;
+ else if(SiS_Pr->SiS_TVMode & TVRPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
+ else VCLKIndex = TVVCLK;
- if(HwInfo->jChipType < SIS_315H) {
- VCLKIndex += TVCLKBASE_300;
- } else {
- VCLKIndex += TVCLKBASE_315;
- }
+ if(HwInfo->jChipType < SIS_315H) VCLKIndex += TVCLKBASE_300;
+ else VCLKIndex += TVCLKBASE_315;
- } else { /* VGA2 */
+ } else { /* VGA2 */
- VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
- if(ModeNo > 0x13) {
- VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwInfo->jChipType < SIS_315H) {
- VCLKIndex &= 0x3f;
+ VCLKIndex = VCLKIndexGEN;
+ if(HwInfo->jChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
if( (HwInfo->jChipType == SIS_630) &&
(HwInfo->jChipRevision >= 0x30)) {
if(VCLKIndex == 0x14) VCLKIndex = 0x34;
} else { /* If not programming CRT2 */
- VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
- if(ModeNo > 0x13) {
- VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwInfo->jChipType < SIS_315H) {
- VCLKIndex &= 0x3f;
+ VCLKIndex = VCLKIndexGEN;
+ if(HwInfo->jChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
if( (HwInfo->jChipType != SIS_630) &&
(HwInfo->jChipType != SIS_300) ) {
if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
VCLKIndex = CRT2Index;
- if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) { /* programming CRT2 */
+ if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- VCLKIndex >>= 6;
- if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
- VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
- VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
- VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
- VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
- VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)
- VCLKIndex = VCLK68_315;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
- VCLKIndex = VCLK162_315;
- else
- VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
-
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
- /* Special Timing: Barco iQ Pro R series */
- VCLKIndex = 0x44;
+ if(HwInfo->jChipType < SIS_315H) {
+ VCLKIndex = SiS_Pr->PanelVCLKIdx300;
+ } else {
+ VCLKIndex = SiS_Pr->PanelVCLKIdx315;
}
+ /* Special Timing: Barco iQ Pro R series */
+ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
+
+ /* Special Timing: 848x480 parallel lvds */
if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
if(HwInfo->jChipType < SIS_315H) {
VCLKIndex = VCLK34_300;
} else {
- VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
- if(ModeNo > 0x13) {
- VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwInfo->jChipType < SIS_315H) {
- VCLKIndex &= 0x3F;
+ VCLKIndex = VCLKIndexGEN;
+ if(HwInfo->jChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
+ if( (HwInfo->jChipType == SIS_630) &&
+ (HwInfo->jChipRevision >= 0x30) ) {
+ if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+ }
}
- if( (HwInfo->jChipType == SIS_630) &&
- (HwInfo->jChipRevision >= 0x30) ) {
- if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
- }
}
}
} else { /* if not programming CRT2 */
- VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
- if(ModeNo > 0x13) {
- VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- if(HwInfo->jChipType < SIS_315H) {
- VCLKIndex &= 0x3F;
+ VCLKIndex = VCLKIndexGEN;
+ if(HwInfo->jChipType < SIS_315H) {
+ if(ModeNo > 0x13) {
if( (HwInfo->jChipType != SIS_630) &&
(HwInfo->jChipType != SIS_300) ) {
if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
{
USHORT i,j,modeflag;
USHORT tempcl,tempah=0;
-#ifdef SIS300
- USHORT temp;
+#if defined(SIS300) || defined(SIS315H)
+ USHORT tempbl;
#endif
#ifdef SIS315H
- USHORT tempbl, tempah2, tempbl2;
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ USHORT tempah2, tempbl2;
#endif
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
} else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
}
/* BIOS does not do this (neither 301 nor LVDS) */
} else {
for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
+ if(HwInfo->jChipType >= SIS_315H) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0x7F);
+ }
tempcl = SiS_Pr->SiS_ModeType;
/* For 301BDH: (with LCD via LVDS) */
if(SiS_Pr->SiS_VBType & VB_NoLCD) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
- temp &= 0xef;
- temp |= 0x02;
+ tempbl = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
+ tempbl &= 0xef;
+ tempbl |= 0x02;
if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
- temp |= 0x10;
- temp &= 0xfd;
+ tempbl |= 0x10;
+ tempbl &= 0xfd;
}
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,tempbl);
}
if(ModeNo > 0x13) {
}
if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
- if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x960)) {
tempah |= 0x80;
}
} else {
}
}
- if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) ||
- ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
+ if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x960) ||
+ ((SiS_Pr->SiS_LCDResInfo == Panel_Custom) &&
(SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
tempah |= 0x80;
}
* in a 650 box (Jake). What is the criteria?
*/
- if((IS_SIS740) || (HwInfo->jChipType >= SIS_661)) {
+ if((IS_SIS740) || (HwInfo->jChipType >= SIS_661) || (SiS_Pr->SiS_ROMNew)) {
tempah = 0x30;
tempbl = 0xc0;
- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+ if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+ ((SiS_Pr->SiS_ROMNew) && (!(ROMAddr[0x5b] & 0x04)))) {
tempah = 0x00;
tempbl = 0x00;
}
if(IS_SIS740) {
tempah = 0x80;
- if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
- tempah = 0x00;
- }
+ if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) tempah = 0x00;
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,0x7f,tempah);
} else {
tempah = 0x00;
tempbl = 0x7f;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
tempbl = 0xff;
- if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
- tempah = 0x80;
- }
+ if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) tempah = 0x80;
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
}
- /* 661: Sets p4 27 and 34 here, done in SetGroup4 here */
+#if 0
+ if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0xc0);
+ }
+#endif
#endif /* SIS315H */
tempbl = 0xfb;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
tempah = 0x00;
- if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
- tempbl = 0xff;
- }
+ if(SiS_IsDualEdge(SiS_Pr, HwInfo)) tempbl = 0xff;
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
USHORT
SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
{
- USHORT resindex;
-
- if(ModeNo <= 0x13)
- resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
- else
- resindex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-
- return(resindex);
+ if(ModeNo <= 0x13) return((USHORT)SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo);
+ else return((USHORT)SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO);
}
static void
USHORT xres,yres,modeflag=0,resindex;
if(SiS_Pr->UseCustomMode) {
- SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
- SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+ xres = SiS_Pr->CHDisplay;
+ if(SiS_Pr->CModeFlag & HalfDCLK) xres *= 2;
+ SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+ yres = SiS_Pr->CVDisplay;
+ if(SiS_Pr->CModeFlag & DoubleScanMode) yres *= 2;
+ SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
return;
}
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
}
- if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
+ if(!SiS_Pr->SiS_IF_DEF_DSTN && !SiS_Pr->SiS_IF_DEF_FSTN) {
if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
}
}
- if(ModeNo > 0x13) {
- if(modeflag & HalfDCLK) xres *= 2;
- if(modeflag & DoubleScanMode) yres *= 2;
- }
+ if(modeflag & HalfDCLK) xres *= 2;
+ if(modeflag & DoubleScanMode) yres *= 2;
}
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+
+#if 0
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCDA | SetCRT2ToLCD | SetCRT2ToHiVision)) {
if(xres == 720) xres = 640;
- } else {
- if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* 301BDH */
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
- if(xres == 720) xres = 640;
- }
- if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- yres = 400;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
- } else {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
- }
- }
- } else {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
- if(xres == 720) xres = 640;
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(yres == 1024) yres = 1056;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- /* BIOS bug - does this regardless of scaling */
- if(yres == 400) yres = 405;
- }
- if(yres == 350) yres = 360;
- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
- if(yres == 360) yres = 375;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- if(yres == 350) yres = 357;
- if(yres == 400) yres = 420;
- if(yres == 480) yres = 525;
- }
- }
- }
+ }
+#endif
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_1024x768:
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ if(yres == 350) yres = 357;
+ if(yres == 400) yres = 420;
+ if(yres == 480) yres = 525;
+ }
+ }
+ break;
+ case Panel_1280x1024:
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ /* BIOS bug - does this regardless of scaling */
+ if(yres == 400) yres = 405;
}
+ if(yres == 350) yres = 360;
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ if(yres == 360) yres = 375;
+ }
+ break;
+ case Panel_1600x1200:
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(yres == 1024) yres = 1056;
+ }
+ break;
}
}
+
} else {
- if(xres == 720) xres = 640;
- if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- yres = 400;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
- } else {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
- }
- if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
- yres = 480;
- }
+
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVision)) {
+ if(xres == 720) xres = 640;
}
+ } else if(xres == 720) xres = 640;
+
+ if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+ yres = 400;
+ if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+ } else {
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+ }
+ if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) yres = 480;
+ }
+
}
SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
USHORT RefreshRateTableIndex, USHORT *ResIndex,
USHORT *DisplayType)
{
- USHORT tempbx,modeflag=0;
- USHORT Flag,CRT2CRTC;
+ USHORT modeflag=0;
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
}
} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
} else
return FALSE;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
}
- Flag = 1;
- tempbx = 0;
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- Flag = 0;
- tempbx = 18;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- tempbx += 2;
- if(SiS_Pr->SiS_ModeType > ModeVGA) {
- if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
- }
- if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- tempbx = 18; /* PALM uses NTSC data */
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
- } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
- tempbx = 20; /* PALN uses PAL data */
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx++;
- }
- }
- }
- }
- if(Flag) {
- tempbx = SiS_Pr->SiS_LCDResInfo;
- tempbx -= SiS_Pr->SiS_PanelMinLVDS;
- if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6;
- if(modeflag & HalfDCLK) tempbx += 3;
- } else {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- tempbx = 14;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- tempbx = 23;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
- tempbx = 27;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- tempbx = 36;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- tempbx = 40;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
- tempbx = 54;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
- tempbx = 52;
- if(modeflag & HalfDCLK) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
- tempbx = 50;
- if(modeflag & HalfDCLK) tempbx++;
- }
+ (*ResIndex) &= 0x3F;
+ if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ (*DisplayType) = 18;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ (*DisplayType) += 2;
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ if(SiS_Pr->SiS_CHSOverScan) (*DisplayType) = 99;
+ }
+ if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+ (*DisplayType) = 18; /* PALM uses NTSC data */
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+ } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+ (*DisplayType) = 20; /* PALN uses PAL data */
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*DisplayType)++;
+ }
+ }
+ } else {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_640x480: (*DisplayType) = 50; break;
+ case Panel_640x480_2: (*DisplayType) = 52; break;
+ case Panel_640x480_3: (*DisplayType) = 54; break;
+ case Panel_800x600: (*DisplayType) = 0; break;
+ case Panel_1024x600: (*DisplayType) = 23; break;
+ case Panel_1024x768: (*DisplayType) = 4; break;
+ case Panel_1152x768: (*DisplayType) = 27; break;
+ case Panel_1280x768: (*DisplayType) = 40; break;
+ case Panel_1280x1024: (*DisplayType) = 8; break;
+ case Panel_1400x1050: (*DisplayType) = 14; break;
+ case Panel_1600x1200: (*DisplayType) = 36; break;
+ default: return FALSE;
+ }
+
+ if(modeflag & HalfDCLK) (*DisplayType)++;
+
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_640x480:
+ case Panel_640x480_2:
+ case Panel_640x480_3:
+ break;
+ default:
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) (*DisplayType) += 2;
}
+
if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- tempbx = 12;
- if(modeflag & HalfDCLK) tempbx++;
+ (*DisplayType) = 12;
+ if(modeflag & HalfDCLK) (*DisplayType)++;
}
}
#if 0
if(SiS_Pr->SiS_IF_DEF_FSTN) {
if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
- tempbx = 22;
+ (*DisplayType) = 22;
}
}
#endif
- *ResIndex = CRT2CRTC & 0x3F;
- *DisplayType = tempbx;
return TRUE;
}
USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
PSIS_HW_INFO HwInfo)
{
- USHORT tempbx=0,tempal=0;
- USHORT Flag,resinfo=0;
+ USHORT tempbx=0,tempal=0,resinfo=0;
if(ModeNo <= 0x13) {
tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) { /* LCD */
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
- tempbx = 15;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- tempbx = 20;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 21;
- else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- tempbx = 23;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 24;
- else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
-#if 0
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- tempbx = 26;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 27;
- else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
-#endif
- } else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx = 13;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
- else {
- tempbx = 29;
- if(ModeNo >= 0x13) {
- /* see below */
- if(resinfo == SIS_RI_1280x960) tempal = 10;
- }
- }
- } else {
- tempbx = 29;
- if(ModeNo >= 0x13) {
- /* 1280x768 and 1280x960 have same CRT2CRTC,
- * so we change it here if 1280x960 is chosen
- */
- if(resinfo == SIS_RI_1280x960) tempal = 10;
+ tempbx = SiS_Pr->SiS_LCDResInfo;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 32;
+
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1680x1050) {
+ if (resinfo == SIS_RI_1280x800) tempal = 9;
+ else if(resinfo == SIS_RI_1400x1050) tempal = 11;
+ }
+
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { /* Pass 1:1 only (center-screen handled outside) */
+ tempbx = 100;
+ if(ModeNo >= 0x13) {
+ tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
+ if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+ (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 768)) {
+ /* Special for Fujitsu 7911 (VL-17WDX8), others custom */
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) tempal = 0x08;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) tempal = 0x0f;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) tempal = 0x10;
}
- }
- } else {
- tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- tempbx += 10;
- }
+ }
}
#ifdef SIS315H
if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- tempbx = 50;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 51;
- else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+ if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ tempbx = 200;
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx++;
+ }
}
}
#endif
(resinfo == SIS_RI_720x576) ||
(resinfo == SIS_RI_768x576)) {
tempal = 6;
+ if(SiS_Pr->SiS_TVMode & (TVSetPAL | TVSetPALN)) {
+ if(resinfo == SIS_RI_720x480) tempal = 9;
+ }
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
- if(resinfo == SIS_RI_1024x768) {
+ if(resinfo == SIS_RI_1024x768) tempal = 8;
+ }
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+ if((resinfo == SIS_RI_720x576) ||
+ (resinfo == SIS_RI_768x576)) {
tempal = 8;
}
+ if(resinfo == SIS_RI_1280x720) tempal = 9;
}
}
}
} else { /* LVDS, 301B-DH (if running on LCD) */
- Flag = 1;
tempbx = 0;
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- Flag = 0;
- tempbx = 10;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- tempbx += 2;
- if(SiS_Pr->SiS_ModeType > ModeVGA) {
- if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
- }
- if(SiS_Pr->SiS_TVMode & TVSetPALM) {
- tempbx = 90;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
- tempbx = 92;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
- }
- }
+ if((SiS_Pr->SiS_IF_DEF_CH70xx) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ tempbx = 10;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ tempbx += 2;
+ if(SiS_Pr->SiS_ModeType > ModeVGA) {
+ if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+ }
+ if(SiS_Pr->SiS_TVMode & TVSetPALM) {
+ tempbx = 90;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+ } else if(SiS_Pr->SiS_TVMode & TVSetPALN) {
+ tempbx = 92;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+ }
}
- }
-
- if(Flag) {
-
- if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
- tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
+ } else {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_640x480: tempbx = 6; break;
+ case Panel_640x480_2: tempbx = 30; break;
+ case Panel_640x480_3: tempbx = 30; break;
+ case Panel_800x600: tempbx = 0; break;
+ case Panel_1024x600: tempbx = 15; break;
+ case Panel_1024x768: tempbx = 2; break;
+ case Panel_1152x768: tempbx = 17; break;
+ case Panel_1280x768: tempbx = 18; break;
+ case Panel_1280x1024: tempbx = 4; break;
+ case Panel_1400x1050: tempbx = 8; break;
+ case Panel_1600x1200: tempbx = 21; break;
+ case Panel_Barco1366: tempbx = 80; break;
+ }
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
- tempbx = 82;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
- tempbx = 18;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
- tempbx = 6;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
- tempbx = 30;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
- tempbx = 30;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- tempbx = 15;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
- tempbx = 16;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- tempbx = 8;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- tempbx = 21;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
- tempbx = 80;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_640x480:
+ case Panel_640x480_2:
+ case Panel_640x480_3:
+ break;
+ default:
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
}
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- tempbx = 7;
- }
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 7;
- if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+ if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+ tempbx = 82;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+ } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
tempbx = 84;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
}
}
if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
+ if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempal = 7;
if(HwInfo->jChipType < SIS_315H) {
if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
}
}
- *CRT2Index = tempbx;
- *ResIndex = tempal & 0x1F;
+ (*CRT2Index) = tempbx;
+ (*ResIndex) = tempal & 0x1F;
}
}
-#ifdef SIS315H
-static void
-SiS_GetCRT2PtrA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,USHORT *CRT2Index,
- USHORT *ResIndex)
-{
- USHORT tempbx,tempal;
-
- tempbx = SiS_Pr->SiS_LCDResInfo;
-
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 4;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3;
- else tempbx -= SiS_Pr->SiS_Panel1024x768;
-
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 5;
-
- if(ModeNo <= 0x13)
- tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- else
- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
- /* No customs required yet (Clevo, Compaq, etc) */
-
- *CRT2Index = tempbx;
- *ResIndex = tempal & 0x1F;
-}
-#endif
-
static void
SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
static void
SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
+ USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
{
USHORT CRT2Index, ResIndex;
const SiS_LVDSDataStruct *LVDSData = NULL;
SiS_Pr->SiS_RY4COE = 0;
}
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
#ifdef SIS315H
- SiS_GetCRT2PtrA(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
- &CRT2Index,&ResIndex);
-
- switch (CRT2Index) {
- case 0: LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1; break;
- case 1: LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_1; break;
- case 3: LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1; break;
- case 4: LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1; break;
- case 5: LVDSData = SiS_Pr->SiS_LCDA1024x768Data_2; break;
- case 6: LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_2; break;
- case 8: LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2; break;
- case 9: LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2; break;
- default: LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1; break;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ if(SiS_Pr->UseCustomMode) {
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->CVTotal;
+ } else {
+ if(ModeNo < 0x13) {
+ ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else {
+ ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC_NS;
+ /* Special for our 3 types, others custom (works with default) */
+ if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+ (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 768)) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768) ResIndex = 0x08;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_2) ResIndex = 0x0f;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x768_3) ResIndex = 0x10;
+ }
+ /* Special for 1280x720 TMDS <> LVDS */
+ if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+ (SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 720)) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x720) {
+ if(SiS_Pr->PanelHT == 1344) ResIndex = 0x12;
+ }
+ }
+ }
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAHT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_NoScaleData[ResIndex].VGAVT;
+ SiS_Pr->SiS_HT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDHT;
+ SiS_Pr->SiS_VT = SiS_Pr->SiS_NoScaleData[ResIndex].LCDVT;
+ }
+ } else {
+ SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ }
+ } else {
+ /* This handles custom modes and custom panels */
+ SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+ SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+ SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT - (SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE);
+ SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT - (SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE);
}
+
+ SiS_CalcLCDACRT1Timing(SiS_Pr,ModeNo,ModeIdIndex);
+
#endif
} else {
}
SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &CRT2Index, &ResIndex, HwInfo);
+ &CRT2Index, &ResIndex, HwInfo);
/* 301BDH needs LVDS Data */
if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
}
switch (CRT2Index) {
- case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
- case 1: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
- case 2: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
- case 3: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
- case 4: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
- case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
- case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
- case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
- case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
- case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
- case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
- case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
- case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
- case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
- case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
- case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
- case 16: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
- case 17: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
- case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
- case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
- case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
- case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
- case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
- case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
- case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
- case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
- case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
- case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
- case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
- case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
- case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
- case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
- case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
- case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
- case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
- default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
- }
- }
-
- SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
- SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
- SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
- SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
-
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
- SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+ case 0: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
+ case 1: LVDSData = SiS_Pr->SiS_LVDS800x600Data_2; break;
+ case 2: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
+ case 3: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2; break;
+ case 4: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1; break;
+ case 5: LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2; break;
+ case 6: LVDSData = SiS_Pr->SiS_LVDS640x480Data_1; break;
+ case 7: LVDSData = SiS_Pr->SiS_LVDSXXXxXXXData_1; break;
+ case 8: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_1; break;
+ case 9: LVDSData = SiS_Pr->SiS_LVDS1400x1050Data_2; break;
+ case 10: LVDSData = SiS_Pr->SiS_CHTVUNTSCData; break;
+ case 11: LVDSData = SiS_Pr->SiS_CHTVONTSCData; break;
+ case 12: LVDSData = SiS_Pr->SiS_CHTVUPALData; break;
+ case 13: LVDSData = SiS_Pr->SiS_CHTVOPALData; break;
+ case 14: LVDSData = SiS_Pr->SiS_LVDS320x480Data_1; break;
+ case 15: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
+ case 16: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_2; break;
+ case 17: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_1; break;
+ case 18: LVDSData = SiS_Pr->SiS_LVDS1152x768Data_2; break;
+ case 19: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_1; break;
+ case 20: LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2; break;
+ case 21: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1; break;
+ case 22: LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2; break;
+ case 30: LVDSData = SiS_Pr->SiS_LVDS640x480Data_2; break;
+ case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
+ case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
+ case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
+ case 83: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2; break;
+ case 84: LVDSData = SiS_Pr->SiS_LVDS848x480Data_1; break;
+ case 85: LVDSData = SiS_Pr->SiS_LVDS848x480Data_2; break;
+ case 90: LVDSData = SiS_Pr->SiS_CHTVUPALMData; break;
+ case 91: LVDSData = SiS_Pr->SiS_CHTVOPALMData; break;
+ case 92: LVDSData = SiS_Pr->SiS_CHTVUPALNData; break;
+ case 93: LVDSData = SiS_Pr->SiS_CHTVOPALNData; break;
+ case 99: LVDSData = SiS_Pr->SiS_CHTVSOPALData; break; /* Super Overscan */
+ default: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
}
- } else {
+ SiS_Pr->SiS_VGAHT = (LVDSData+ResIndex)->VGAHT;
+ SiS_Pr->SiS_VGAVT = (LVDSData+ResIndex)->VGAVT;
+ SiS_Pr->SiS_HT = (LVDSData+ResIndex)->LCDHT;
+ SiS_Pr->SiS_VT = (LVDSData+ResIndex)->LCDVT;
- if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+ if(!(SiS_Pr->SiS_VBType & VB_SISVB)) {
if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
- SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
- SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
- if(ResIndex < 0x08) {
- SiS_Pr->SiS_HDE = 1280;
- SiS_Pr->SiS_VDE = 1024;
- }
- }
+ if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+ SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+ SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+ if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+ if(ResIndex < 0x08) {
+ SiS_Pr->SiS_HDE = 1280;
+ SiS_Pr->SiS_VDE = 1024;
+ }
}
}
}
USHORT RefreshRateTableIndex,
PSIS_HW_INFO HwInfo)
{
- USHORT tempax,tempbx,modeflag;
- USHORT resinfo;
- USHORT CRT2Index,ResIndex;
+ UCHAR *ROMAddr = NULL;
+ USHORT tempax,tempbx,modeflag,romptr=0;
+ USHORT resinfo,CRT2Index,ResIndex;
const SiS_LCDDataStruct *LCDPtr = NULL;
const SiS_TVDataStruct *TVPtr = NULL;
+#ifdef SIS315H
+ SHORT resinfo661;
+#endif
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ resinfo = 0;
} else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- resinfo = 0;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
- }
-
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+#ifdef SIS315H
+ resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
+ if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+ (SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
+ (resinfo661 >= 0) &&
+ (SiS_Pr->SiS_NeedRomModeData) ) {
+ if((ROMAddr = GetLCDStructPtr661(SiS_Pr, HwInfo))) {
+ if((romptr = (SISGETROMW(21)))) {
+ romptr += (resinfo661 * 10);
+ ROMAddr = HwInfo->pjVirtualRomBase;
+ }
+ }
+ }
+#endif
+ }
+
SiS_Pr->SiS_NewFlickerMode = 0;
SiS_Pr->SiS_RVBHRS = 50;
SiS_Pr->SiS_RY1COE = 0;
} else {
SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
&CRT2Index,&ResIndex,HwInfo);
switch(CRT2Index) {
- case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
- case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
- case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
- case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
- case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
- case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
- case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
- case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
- case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
- case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
- case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
- case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
- case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
- default: TVPtr = SiS_Pr->SiS_StPALData; break;
+ case 2: TVPtr = SiS_Pr->SiS_ExtHiTVData; break;
+ case 3: TVPtr = SiS_Pr->SiS_ExtPALData; break;
+ case 4: TVPtr = SiS_Pr->SiS_ExtNTSCData; break;
+ case 5: TVPtr = SiS_Pr->SiS_Ext525iData; break;
+ case 6: TVPtr = SiS_Pr->SiS_Ext525pData; break;
+ case 7: TVPtr = SiS_Pr->SiS_Ext750pData; break;
+ case 8: TVPtr = SiS_Pr->SiS_StPALData; break;
+ case 9: TVPtr = SiS_Pr->SiS_StNTSCData; break;
+ case 10: TVPtr = SiS_Pr->SiS_St525iData; break;
+ case 11: TVPtr = SiS_Pr->SiS_St525pData; break;
+ case 12: TVPtr = SiS_Pr->SiS_St750pData; break;
+ case 13: TVPtr = SiS_Pr->SiS_St1HiTVData; break;
+ case 14: TVPtr = SiS_Pr->SiS_St2HiTVData; break;
+ default: TVPtr = SiS_Pr->SiS_StPALData; break;
}
SiS_Pr->SiS_RVBHCMAX = (TVPtr+ResIndex)->RVBHCMAX;
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SiS_Pr->SiS_RVBHCMAX = 1;
+ SiS_Pr->SiS_RVBHCFACT = 1;
+
if(SiS_Pr->UseCustomMode) {
- SiS_Pr->SiS_RVBHCMAX = 1;
- SiS_Pr->SiS_RVBHCFACT = 1;
SiS_Pr->SiS_VGAHT = SiS_Pr->CHTotal;
SiS_Pr->SiS_VGAVT = SiS_Pr->CVTotal;
SiS_Pr->SiS_HT = SiS_Pr->CHTotal;
} else {
- SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
- &CRT2Index,&ResIndex,HwInfo);
-
- switch(CRT2Index) {
- case 0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break; /* VESA Timing */
- case 1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break; /* VESA Timing */
- case 5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data; break; /* Obviously unused */
- case 6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data; break; /* Obviously unused */
- case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break; /* Non-VESA Timing */
- case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break; /* Non-VESA Timing */
- case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768; break; /* Non-expanding */
- case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break; /* Non-expanding */
- case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break; /* 1280x960 */
- case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break; /* VESA Timing */
- case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050; break; /* Non-expanding (let panel scale) */
- case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break; /* Non-VESA Timing (let panel scale) */
- case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break; /* VESA Timing */
- case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200; break; /* Non-expanding */
- case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break; /* Non-VESA Timing */
- case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data; break; /* VESA Timing */
- case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768; break; /* Non-expanding */
- case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data; break; /* Non-VESA Timing */
- case 29: LCDPtr = SiS_Pr->SiS_NoScaleData; break; /* Generic no-scale data */
+ BOOLEAN gotit = FALSE;
+
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+
+ SiS_Pr->SiS_VGAHT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
+ SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
+ SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
+ gotit = TRUE;
+
+ } else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
+
#ifdef SIS315H
- case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data; break;
- case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024; break;
- case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
+ SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
+ SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
+ SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
+ SiS_Pr->SiS_VGAVT = ROMAddr[romptr+4] | ((ROMAddr[romptr+3] & 0xf0) << 4);
+ SiS_Pr->SiS_HT = ROMAddr[romptr+5] | ((ROMAddr[romptr+6] & 0x0f) << 8);
+ SiS_Pr->SiS_VT = ROMAddr[romptr+7] | ((ROMAddr[romptr+6] & 0xf0) << 4);
+ if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
#endif
- default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
- }
- SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
- SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
- SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
- SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
- SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
- SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
+ }
+
+ if(!gotit) {
+
+ SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+ &CRT2Index,&ResIndex,HwInfo);
+
+ switch(CRT2Index) {
+ case Panel_1024x768 : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
+ case Panel_1024x768 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data; break;
+ case Panel_1280x720 :
+ case Panel_1280x720 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x720Data; break;
+ case Panel_1280x768_2 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x768_2Data; break;
+ case Panel_1280x768_2+ 32: LCDPtr = SiS_Pr->SiS_StLCD1280x768_2Data; break;
+ case Panel_1280x768_3 :
+ case Panel_1280x768_3+ 32: LCDPtr = SiS_Pr->SiS_LCD1280x768_3Data; break;
+ case Panel_1280x800 :
+ case Panel_1280x800 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x800Data; break;
+ case Panel_1280x960 :
+ case Panel_1280x960 + 32: LCDPtr = SiS_Pr->SiS_LCD1280x960Data; break;
+ case Panel_1280x1024 : LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data; break;
+ case Panel_1280x1024 + 32: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
+ case Panel_1400x1050 : LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data; break;
+ case Panel_1400x1050 + 32: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data; break;
+ case Panel_1600x1200 : LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data; break;
+ case Panel_1600x1200 + 32: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data; break;
+ case Panel_1680x1050 :
+ case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
+ case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
+#ifdef SIS315H
+ case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
+ case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
+#endif
+ default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
+ }
#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO,
- "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+ xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
#endif
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- tempax = 1024;
+ SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
+ SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+ SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
+ SiS_Pr->SiS_VGAVT = (LCDPtr+ResIndex)->VGAVT;
+ SiS_Pr->SiS_HT = (LCDPtr+ResIndex)->LCDHT;
+ SiS_Pr->SiS_VT = (LCDPtr+ResIndex)->LCDVT;
+
+ }
+
+ tempax = SiS_Pr->PanelXRes;
+ tempbx = SiS_Pr->PanelYRes;
+
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
if(HwInfo->jChipType < SIS_315H) {
if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
- else tempbx = 768;
- } else {
- tempbx = 768;
}
} else {
if (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
- else tempbx = 768;
}
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- tempax = 1280;
- if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
- else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
- else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
- else tempbx = 1024;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
- tempax = 1280;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) {
if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 700;
else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 800;
else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
- else tempbx = 960;
- } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) &&
- (HwInfo->jChipType >= SIS_661)) {
- tempax = 1400;
- tempbx = 1050;
- if(SiS_Pr->SiS_VGAVDE == 1024) {
- tempax = 1280;
- tempbx = 1024;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- tempax = 1600;
- tempbx = 1200;
- if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))) {
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+ if (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+ else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+ else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) {
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
if (SiS_Pr->SiS_VGAVDE == 350) tempbx = 875;
else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 1000;
}
- } else {
- tempax = SiS_Pr->PanelXRes;
- tempbx = SiS_Pr->PanelYRes;
- }
+ }
+
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
tempax = SiS_Pr->SiS_VGAHDE;
tempbx = SiS_Pr->SiS_VGAVDE;
}
+
SiS_Pr->SiS_HDE = tempax;
SiS_Pr->SiS_VDE = tempbx;
}
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-
- SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
- } else {
-
- if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-
- /* Need LVDS Data for LCD on 301B-DH */
- SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
- } else {
-
- SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
- }
-
- }
-
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
} else {
-
- SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
-
+ if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+ /* Need LVDS Data for LCD on 301B-DH */
+ SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ } else {
+ SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ }
}
} else {
}
/*********************************************/
-/* GET LVDS DES DATA */
+/* GET LVDS DES (SKEW) DATA */
/*********************************************/
static void
USHORT RefreshRateTableIndex, USHORT *PanelIndex,
USHORT *ResIndex, PSIS_HW_INFO HwInfo)
{
- USHORT tempbx,tempal,modeflag;
+ USHORT modeflag;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
}
- tempbx = 0;
+ (*ResIndex) &= 0x1F;
+ (*PanelIndex) = 0;
+
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- tempbx = 50;
- if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) tempbx += 2;
- if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) tempbx += 1;
+ (*PanelIndex) = 50;
+ if((SiS_Pr->SiS_TVMode & TVSetPAL) && (!(SiS_Pr->SiS_TVMode & TVSetPALM))) (*PanelIndex) += 2;
+ if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) (*PanelIndex) += 1;
/* Nothing special needed for SOverscan */
- /* PALM uses NTSC data, PALN uses PAL data */
+ /* PALM uses NTSC data, PALN uses PAL data */
}
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- tempbx = SiS_Pr->SiS_LCDTypeInfo;
+ *PanelIndex = SiS_Pr->SiS_LCDTypeInfo;
if(HwInfo->jChipType >= SIS_661) {
/* As long as we don's use the BIOS tables, we
* need to convert the TypeInfo as for 315 series
*/
- tempbx = SiS_Pr->SiS_LCDResInfo - 1;
+ (*PanelIndex) = SiS_Pr->SiS_LCDResInfo - 1;
}
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- tempbx = 32;
- if(modeflag & HalfDCLK) tempbx++;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ (*PanelIndex) += 16;
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ (*PanelIndex) = 32;
+ if(modeflag & HalfDCLK) (*PanelIndex)++;
+ }
}
}
if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- tempal = 0x07;
+ if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
+ (*ResIndex) = 7;
if(HwInfo->jChipType < SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) (*ResIndex)++;
}
}
}
-
- *PanelIndex = tempbx;
- *ResIndex = tempal & 0x1F;
-}
-
-#ifdef SIS315H
-static void
-SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, USHORT *PanelIndex, USHORT *ResIndex,
- PSIS_HW_INFO HwInfo)
-{
- USHORT tempbx=0,tempal;
-
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 2;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3;
- else tempbx = SiS_Pr->SiS_LCDResInfo - 2;
-
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 4;
-
- if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
- tempbx = 80;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- }
- }
- }
- if((SiS_Pr->SiS_CustomT == CUT_UNIWILL1024) ||
- (SiS_Pr->SiS_CustomT == CUT_UNIWILL10242)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- tempbx = 82;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- }
- }
- if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- tempbx = 84;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- }
- }
- if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- tempbx = 86;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
- }
- }
-
- if(ModeNo <= 0x13)
- tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- else
- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
- *PanelIndex = tempbx;
- *ResIndex = tempal & 0x1F;
}
-#endif
static void
SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
USHORT PanelIndex,ResIndex;
const SiS_LVDSDesStruct *PanelDesPtr = NULL;
- if((SiS_Pr->UseCustomMode) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) ||
- (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
- SiS_Pr->SiS_LCDHDES = 0;
- SiS_Pr->SiS_LCDVDES = 0;
+ SiS_Pr->SiS_LCDHDES = 0;
+ SiS_Pr->SiS_LCDVDES = 0;
+
+ if( (SiS_Pr->UseCustomMode) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_Custom) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ||
+ ((SiS_Pr->SiS_VBType & VB_SISVB) &&
+ (SiS_Pr->SiS_LCDInfo & DontExpandLCD) &&
+ (SiS_Pr->SiS_LCDInfo & LCDPass11)) ) {
return;
}
if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
#ifdef SIS315H
- SiS_GetLVDSDesPtrA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &PanelIndex, &ResIndex, HwInfo);
-
- switch (PanelIndex)
- {
- case 0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1; break; /* --- expanding --- */
- case 1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1; break;
- case 2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1; break;
- case 3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1; break;
- case 4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2; break; /* --- non expanding --- */
- case 5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2; break;
- case 6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2; break;
- case 7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2; break;
- case 80: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_1; break; /* custom */
- case 81: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_2; break;
- case 82: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_1; break;
- case 83: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_2; break;
- case 84: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_1; break;
- case 85: PanelDesPtr = (SiS_LVDSDesStruct *)Compaq1280x1024Des_2; break;
- case 86: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_1; break; /* custom */
- case 87: PanelDesPtr = (SiS_LVDSDesStruct *)Asus1024x768Des_2; break;
- default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1; break;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ /* non-pass 1:1 only, see above */
+ if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_VGAHDE) / 2);
+ }
+ if(SiS_Pr->SiS_VGAVDE != SiS_Pr->PanelYRes) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VGAVDE) / 2);
+ }
+ }
+ if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
+ switch(SiS_Pr->SiS_CustomT) {
+ case CUT_UNIWILL1024:
+ case CUT_UNIWILL10242:
+ case CUT_CLEVO1400:
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ }
+ break;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+ if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
+ SiS_Pr->SiS_LCDVDES = SiS_Pr->PanelVT - 1;
+ }
+ }
}
#endif
SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
&PanelIndex, &ResIndex, HwInfo);
- switch (PanelIndex)
- {
- case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
- case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
- case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
- case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
- case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
- case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
- case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
- case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
- case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
- case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
- case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
- case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
- case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
- case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
- case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
- case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
- case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
- case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
- case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
- case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
- case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
- case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
- case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
- case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
- case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
- case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
- case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
- case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
- case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
- case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
- case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
- case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
- case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
- case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
- case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
- case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
- case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
- case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
- default:
- if(HwInfo->jChipType < SIS_315H)
- PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
- else
- PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
- break;
- }
- }
- SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
- SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
-
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- if(!(modeflag & HalfDCLK)) {
- SiS_Pr->SiS_LCDHDES = 632;
- }
- }
- } else {
- if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
- if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768) {
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- if(HwInfo->jChipType < SIS_315H) {
- if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
- } else {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
- SiS_Pr->SiS_LCDHDES = 480;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
- SiS_Pr->SiS_LCDHDES = 804;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
- SiS_Pr->SiS_LCDHDES = 704;
- if(!(modeflag & HalfDCLK)) {
- SiS_Pr->SiS_LCDHDES = 320;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
- SiS_Pr->SiS_LCDHDES = 632;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
- SiS_Pr->SiS_LCDHDES = 542;
- }
+ switch(PanelIndex) {
+ case 0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1; break; /* --- */
+ case 1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1; break;
+ case 2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1; break;
+ case 3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1; break;
+ case 4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1; break;
+ case 5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1; break;
+ case 6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1; break;
+ case 7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1; break;
+ case 8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1; break;
+ case 9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1; break;
+ case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1; break;
+ case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1; break;
+ case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1; break;
+ case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1; break;
+ case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1; break;
+ case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1; break;
+ case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2; break; /* --- */
+ case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2; break;
+ case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2; break;
+ case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2; break;
+ case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2; break;
+ case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2; break;
+ case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2; break;
+ case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2; break;
+ case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2; break;
+ case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2; break;
+ case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2; break;
+ case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2; break;
+ case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2; break;
+ case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2; break;
+ case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2; break;
+ case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2; break;
+ case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1; break; /* pass 1:1 */
+ case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2; break;
+ case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData; break; /* TV */
+ case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData; break;
+ case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData; break;
+ case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData; break;
+ default: return;
+ }
+
+ SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+ SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
+
+ if((ModeNo <= 0x13) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+ modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 632;
+ } else if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) {
+ if(SiS_Pr->SiS_LCDResInfo >= Panel_1024x768) {
+ if(HwInfo->jChipType < SIS_315H) {
+ if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
+ } else {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
+ if(!(modeflag & HalfDCLK)) {
+ SiS_Pr->SiS_LCDHDES = 320;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 632;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 542;
}
}
}
}
}
-/*********************************************/
-/* SET CRT2 AUTO-THRESHOLD */
-/*********************************************/
-
-#ifdef SIS315H
-static void
-SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr)
-{
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
-}
-#endif
-
/*********************************************/
/* DISABLE VIDEO BRIDGE */
/*********************************************/
if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ===== For 30xB/LV ===== */
if(HwInfo->jChipType < SIS_315H) {
#ifdef SIS300 /* 300 series */
- if(HwInfo->jChipType == SIS_300) { /* For 300+301LV (A907) */
-
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
- }
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+ } else {
+ SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
}
+ SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ }
+ if(SiS_Is301B(SiS_Pr)) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
SiS_ShortDelay(SiS_Pr,1);
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
- SiS_DisplayOff(SiS_Pr);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
- (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
- }
- }
-
- } else {
-
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
- }
- if(SiS_Is301B(SiS_Pr)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
- SiS_ShortDelay(SiS_Pr,1);
- }
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
- SiS_DisplayOff(SiS_Pr);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+ SiS_DisplayOff(SiS_Pr);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
- if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
- (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
+ }
+ if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+ (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+ } else {
+ SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
}
}
#ifdef SIS315H /* 315 series */
- if(IS_SIS550650740660) { /* 550, 650, 740, 660 */
+ BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+ (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
+
+ modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
- modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* LV */
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
- }
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
}
+ }
#endif
- if( (modenum <= 0x13) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
- (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
- if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
- }
- }
+ if( (modenum <= 0x13) ||
+ (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+ (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+ if(custom1) SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ }
- if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
- SiS_DDC2Delay(SiS_Pr,0xff00);
- SiS_DDC2Delay(SiS_Pr,0xe000);
+ if(!custom1) {
+ SiS_DDC2Delay(SiS_Pr,0xff00);
+ SiS_DDC2Delay(SiS_Pr,0xe000);
+ SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+ pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+ if(IS_SIS740) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+ }
+ SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ }
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+ }
- pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+ if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+ tempah = 0xef;
+ if(SiS_IsVAMode(SiS_Pr,HwInfo)) tempah = 0xf7;
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+ }
- if(IS_SIS740) {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
- }
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,~0x10);
+ }
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+ tempah = 0x3f;
+ if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+ tempah = 0x7f;
+ if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) tempah = 0xbf;
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
- if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
- tempah = 0xef;
- if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
- tempah = 0xf7;
- }
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
- }
- }
+ if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+ ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
- } else if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* B-DH */
+ SiS_DisplayOff(SiS_Pr);
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ }
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
- }
+ }
- }
+ if((!(SiS_IsVAMode(SiS_Pr,HwInfo))) ||
+ ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
- if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
+ if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+ SiS_DisplayOff(SiS_Pr);
}
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- tempah = 0x3f;
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
- tempah = 0x7f;
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- tempah = 0xbf;
- }
- }
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 2);
}
- if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
-
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
- SiS_DisplayOff(SiS_Pr);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- } else {
- SiS_DisplayOff(SiS_Pr);
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
- if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) {
- SiS_DisplayOff(SiS_Pr);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
- }
- }
-
- } else {
-
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
- SiS_DisplayOff(SiS_Pr);
- }
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
- } else {
- SiS_DisplayOff(SiS_Pr);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- }
-
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
-
- }
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+ temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
- if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
- (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+ }
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);
+ if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+ }
- tempah = 0x3f;
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
- tempah = 0x7f;
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- tempah = 0xbf;
- }
- }
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
- }
+ if(!custom1) {
if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+ if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 20);
}
}
- } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-
- /* NIL */
-
- } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+ } else {
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- tempah = 0xef;
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
- if(modenum > 0x13) {
- tempah = 0xf7;
- }
- }
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
- }
- if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
- if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
- (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
- SiS_PanelDelay(SiS_Pr, HwInfo, 4);
- }
+ if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+ (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
+ if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
+ (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+ SiS_PanelDelay(SiS_Pr, HwInfo, 4);
}
}
}
-
- } else { /* 315, 330 - all bridge types */
-
- if(SiS_Is301B(SiS_Pr)) {
- tempah = 0x3f;
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
- tempah = 0x7f;
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- tempah = 0xbf;
- }
- }
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
- if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
- SiS_DisplayOff(SiS_Pr);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
- }
- }
- if( (!(SiS_Is301B(SiS_Pr))) ||
- (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
-
- if( (!(SiS_Is301B(SiS_Pr))) ||
- (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
-
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
- SiS_DisplayOff(SiS_Pr);
-
- }
-
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
-
- }
-
- } /* 315/330 */
+ }
#endif /* SIS315H */
}
- } else { /* ============ For 301 ================ */
+ } else { /* ============ For 301 ================ */
if(HwInfo->jChipType < SIS_315H) {
+#ifdef SIS300
if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x08);
SiS_PanelDelay(SiS_Pr, HwInfo, 3);
}
+#endif
}
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF); /* disable VB */
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
} else {
+#ifdef SIS300
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
SiS_PanelDelay(SiS_Pr, HwInfo, 2);
SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x04);
}
+#endif
}
}
#ifdef SIS315H /* 315 series */
+ if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,~0x18);
+ }
+
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(HwInfo->jChipType == SIS_740) {
BOOLEAN delaylong = FALSE;
#endif
-
if(SiS_Pr->SiS_VBType & VB_SISVB) {
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* ====== For 301B et al ====== */
#ifdef SIS300 /* 300 series */
- if(HwInfo->jChipType == SIS_300) {
-
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
- if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
- }
+ if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+ SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
+ }
+ if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV | VB_NoLCD)) {
+ if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 0);
}
}
+ }
+
+ if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
+ (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
+
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
+ SiS_DisplayOn(SiS_Pr);
+ SiS_UnLockCRT2(SiS_Pr,HwInfo);
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+ }
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+ if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+ }
+ SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
+ }
+ }
+
+ } else {
+
temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
- if(SiS_BridgeInSlave(SiS_Pr)) {
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
}
SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
SiS_DisplayOn(SiS_Pr);
- if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
SiS_PanelDelay(SiS_Pr, HwInfo, 1);
}
}
- } else {
+ }
- if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
- /* This is only for LCD output on 301B-DH via LVDS */
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
- if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
- }
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* Enable CRT2 */
- SiS_DisplayOn(SiS_Pr);
- SiS_UnLockCRT2(SiS_Pr,HwInfo);
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
- if(SiS_BridgeInSlave(SiS_Pr)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
- }
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
- if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- }
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
- SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xF7,0x00);
- }
- }
- } else {
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
- if(SiS_BridgeInSlave(SiS_Pr)) {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20); /* enable VB processor */
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
- SiS_DisplayOn(SiS_Pr);
- }
- }
#endif /* SIS300 */
} else {
#ifdef SIS315H /* 315 series */
- if(IS_SIS550650740660) { /* 550, 650, 740, 660 */
-
- UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
-
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+#ifdef SET_EMI
+ UCHAR r30=0, r31=0, r32=0, r33=0, cr36=0;
+ /* USHORT emidelay=0; */
+#endif
- if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
- }
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+ }
#endif
- }
+ }
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- tempah = 0x10;
- if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
- if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
- else tempah = 0x08;
- }
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
- }
+ if(!(SiS_IsNotM650orLater(SiS_Pr, HwInfo))) {
+ tempah = 0x10;
+ if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
+ if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
+ else tempah = 0x08;
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+ }
- if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
- SiS_DisplayOff(SiS_Pr);
- pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
- if(IS_SIS740) {
- SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
- }
- }
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
- if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
- if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_GenericDelay(SiS_Pr, 0x4500);
- }
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
- } else {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
- SiS_PanelDelay(SiS_Pr, HwInfo, 0);
- }
- }
- }
+ SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+ SiS_DisplayOff(SiS_Pr);
+ pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+ if(IS_SIS740) {
+ SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+ }
- if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
- if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
- delaylong = TRUE;
+ if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ SiS_GenericDelay(SiS_Pr, 0x4500);
}
}
+ }
- } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+ if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+ delaylong = TRUE;
+ }
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
- }
+ }
- } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+ if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
- tempah = 0x10;
- if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
- if(SiS_TVEnabled(SiS_Pr, HwInfo)) tempah = 0x18;
- else tempah = 0x08;
- }
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+ temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
+ tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+ if(!(tempah & SetCRT2ToRAMDAC)) {
+ if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
}
+ }
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
- }
-
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
- if(SiS_BridgeInSlave(SiS_Pr)) {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) {
- if(!(SiS_LCDAEnabled(SiS_Pr, HwInfo))) temp |= 0x20;
- }
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
- if(!(temp & 0x80)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- }
- } else {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- }
- } else {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ SiS_PanelDelay(SiS_Pr, HwInfo, 2);
}
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+ } else {
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
- if(!(temp & 0x80)) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- }
- }
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
- tempah = 0xc0;
- if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
- tempah = 0x80;
- if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) {
- tempah = 0x40;
- }
- }
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+ }
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
- (((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) &&
- (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
- }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ tempah = 0xc0;
+ if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+ tempah = 0x80;
+ if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) tempah = 0x40;
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
- if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- }
-#ifdef COMPAQ_HACK
- if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- }
-#endif
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+
+ SiS_PanelDelay(SiS_Pr, HwInfo, 2);
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+ if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
- SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
- }
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+ }
#endif
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
#ifdef SET_EMI
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
-
- cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
-
- /* (P4_30|0x40) */
- /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
- /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
- /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
- /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
- /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
- /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
- /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
- /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
- /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
-
- if(SiS_Pr->HaveEMI) {
- r30 = SiS_Pr->EMI_30;
- r31 = SiS_Pr->EMI_31;
- r32 = SiS_Pr->EMI_32;
- r33 = SiS_Pr->EMI_33;
- } else {
- r30 = 0;
+ cr36 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+
+ if(SiS_Pr->SiS_ROMNew) {
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ USHORT romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo);
+ if(romptr) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+ SiS_Pr->EMI_30 = 0;
+ SiS_Pr->EMI_31 = ROMAddr[romptr + 14];
+ SiS_Pr->EMI_32 = ROMAddr[romptr + 15];
+ SiS_Pr->EMI_33 = ROMAddr[romptr + 16];
+ if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
+ /* emidelay = SISGETROMW((romptr + 0x22)); */
+ SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
}
+ }
- /* EMI_30 is read at driver start; however, the BIOS sets this
- * (if it is used) only if the LCD is in use. In case we caught
- * the machine while on TV output, this bit is not set and we
- * don't know if it should be set - hence our detection is wrong.
- * Work-around this here:
- */
-
- if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
- if((cr36 & 0x0f) == 0x02) { /* 1024x768 */
- r30 |= 0x40;
- if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
- r30 &= ~0x40;
- }
- } else if((cr36 & 0x0f) == 0x03) { /* 1280x1024 */
- r30 |= 0x40;
- if(SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) {
- r30 &= ~0x40;
- }
- } else if((cr36 & 0x0f) == 0x09) { /* 1400x1050 */
- r30 |= 0x40;
- } else if((cr36 & 0x0f) == 0x0b) { /* 1600x1200 - unknown */
- r30 |= 0x40;
- }
- }
+ /* (P4_30|0x40) */
+ /* Compal 1400x1050: 0x05, 0x60, 0x00 YES (1.10.7w; CR36=69) */
+ /* Compal 1400x1050: 0x0d, 0x70, 0x40 YES (1.10.7x; CR36=69) */
+ /* Acer 1280x1024: 0x12, 0xd0, 0x6b NO (1.10.9k; CR36=73) */
+ /* Compaq 1280x1024: 0x0d, 0x70, 0x6b YES (1.12.04b; CR36=03) */
+ /* Clevo 1024x768: 0x05, 0x60, 0x33 NO (1.10.8e; CR36=12, DL!) */
+ /* Clevo 1024x768: 0x0d, 0x70, 0x40 (if type == 3) YES (1.10.8y; CR36=?2) */
+ /* Clevo 1024x768: 0x05, 0x60, 0x33 (if type != 3) YES (1.10.8y; CR36=?2) */
+ /* Asus 1024x768: ? ? (1.10.8o; CR36=?2) */
+ /* Asus 1024x768: 0x08, 0x10, 0x3c (problematic) YES (1.10.8q; CR36=22) */
+
+ if(SiS_Pr->HaveEMI) {
+ r30 = SiS_Pr->EMI_30; r31 = SiS_Pr->EMI_31;
+ r32 = SiS_Pr->EMI_32; r33 = SiS_Pr->EMI_33;
+ } else {
+ r30 = 0;
+ }
- if(!SiS_Pr->HaveEMI) {
- if((cr36 & 0x0f) == 0x02) {
+ /* EMI_30 is read at driver start; however, the BIOS sets this
+ * (if it is used) only if the LCD is in use. In case we caught
+ * the machine while on TV output, this bit is not set and we
+ * don't know if it should be set - hence our detection is wrong.
+ * Work-around this here:
+ */
+
+ if((!SiS_Pr->HaveEMI) || (!SiS_Pr->HaveEMILCD)) {
+ switch((cr36 & 0x0f)) {
+ case 2:
+ r30 |= 0x40;
+ if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) r30 &= ~0x40;
+ if(!SiS_Pr->HaveEMI) {
+ r31 = 0x05; r32 = 0x60; r33 = 0x33;
if((cr36 & 0xf0) == 0x30) {
r31 = 0x0d; r32 = 0x70; r33 = 0x40;
- } else {
- r31 = 0x05; r32 = 0x60; r33 = 0x33;
}
- } else if((cr36 & 0x0f) == 0x03) {
+ }
+ break;
+ case 3: /* 1280x1024 */
+ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) r30 |= 0x40;
+ if(!SiS_Pr->HaveEMI) {
+ r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
r31 = 0x0d; r32 = 0x70; r33 = 0x6b;
- } else {
- r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
}
- } else if((cr36 & 0x0f) == 0x09) {
+ }
+ break;
+ case 9: /* 1400x1050 */
+ r30 |= 0x40;
+ if(!SiS_Pr->HaveEMI) {
+ r31 = 0x05; r32 = 0x60; r33 = 0x00;
if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
r31 = 0x0d; r32 = 0x70; r33 = 0x40; /* BIOS values */
- } else {
- r31 = 0x05; r32 = 0x60; r33 = 0x00;
}
- } else {
+ }
+ break;
+ case 11: /* 1600x1200 - unknown */
+ r30 |= 0x40;
+ if(!SiS_Pr->HaveEMI) {
r31 = 0x05; r32 = 0x60; r33 = 0x00;
}
}
+ }
- /* BIOS values don't work so well sometimes */
- if(!SiS_Pr->OverruleEMI) {
+ /* BIOS values don't work so well sometimes */
+ if(!SiS_Pr->OverruleEMI) {
#ifdef COMPAL_HACK
- if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
- if((cr36 & 0x0f) == 0x09) {
- r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
- }
- }
+ if(SiS_Pr->SiS_CustomT == CUT_COMPAL1400_2) {
+ if((cr36 & 0x0f) == 0x09) {
+ r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x00;
+ }
+ }
#endif
#ifdef COMPAQ_HACK
- if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- if((cr36 & 0x0f) == 0x03) {
- r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b; /* rev 1 */
- }
+ if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+ if((cr36 & 0x0f) == 0x03) {
+ r30 = 0x20; r31 = 0x12; r32 = 0xd0; r33 = 0x6b;
}
+ }
#endif
#ifdef ASUS_HACK
- if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
- if((cr36 & 0x0f) == 0x02) {
- /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
- /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
- /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
- /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
- }
+ if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+ if((cr36 & 0x0f) == 0x02) {
+ /* r30 = 0x60; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 2 */
+ /* r30 = 0x20; r31 = 0x05; r32 = 0x60; r33 = 0x33; */ /* rev 3 */
+ /* r30 = 0x60; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 4 */
+ /* r30 = 0x20; r31 = 0x0d; r32 = 0x70; r33 = 0x40; */ /* rev 5 */
}
-#endif
- }
- if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
}
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
- if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
- } else {
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x00);
- }
- if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
- if(r30 & 0x40) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
- if(delaylong) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
- delaylong = FALSE;
- }
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
- if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
- SiS_GenericDelay(SiS_Pr, 0x500);
- }
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
- }
- }
- }
#endif
- }
-
- if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
-
- if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
- SiS_DisplayOn(SiS_Pr);
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_WaitVBRetrace(SiS_Pr, HwInfo);
- SiS_PanelDelay(SiS_Pr, HwInfo, 3);
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
- }
- }
-
- } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
+ }
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
- (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
- SiS_DisplayOn(SiS_Pr);
- SiS_PanelDelay(SiS_Pr, HwInfo, 1);
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
- }
+ if(!(SiS_Pr->OverruleEMI && (!r30) && (!r31) && (!r32) && (!r33))) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
}
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,r31);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,r32);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,r33);
+#endif /* SET_EMI */
- } else {
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
- ((SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
- if(delaylong) {
- SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
- }
- SiS_WaitVBRetrace(SiS_Pr,HwInfo);
- if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+#ifdef SET_EMI
+ if( (SiS_LCDAEnabled(SiS_Pr, HwInfo)) ||
+ (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+ if(r30 & 0x40) {
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+ if(delaylong) {
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 5);
+ delaylong = FALSE;
+ }
+ SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
SiS_GenericDelay(SiS_Pr, 0x500);
}
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
}
- }
-
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
- SiS_DisplayOn(SiS_Pr);
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
-
- if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
- }
-
+ }
+#endif
}
-
}
- } else { /* 315, 330 */
-
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
- if(SiS_BridgeInSlave(SiS_Pr)) {
- tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
- }
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
-
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20); /* enable CRT2 */
-
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
- if(!(temp & 0x80))
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
- }
-
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
-
- if(SiS_Is301B(SiS_Pr)) {
-
- temp=SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
- if(!(temp & 0x80))
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-
- tempah = 0xc0;
- if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
- tempah = 0x80;
- if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
- tempah = 0x40;
- }
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+ if(SiS_IsVAorLCD(SiS_Pr, HwInfo)) {
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+ if(delaylong) {
+ SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+ }
+ SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+ if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
+ SiS_GenericDelay(SiS_Pr, 0x500);
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
}
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
-
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-
- } else {
+ }
- SiS_VBLongWait(SiS_Pr);
- SiS_DisplayOn(SiS_Pr);
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
- SiS_VBLongWait(SiS_Pr);
+ SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+ SiS_DisplayOn(SiS_Pr);
+ SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
- }
+ }
- } /* 315, 330 */
+ if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+ }
#endif /* SIS315H */
}
temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF; /* lock mode */
- if(SiS_BridgeInSlave(SiS_Pr)) {
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
+ if(!(tempah & SetCRT2ToRAMDAC)) temp |= 0x20;
}
SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
}
}
- SiS_EnableCRT2(SiS_Pr);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_DisplayOn(SiS_Pr);
SiS_UnLockCRT2(SiS_Pr,HwInfo);
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
- if(SiS_BridgeInSlave(SiS_Pr)) {
+ if(SiS_BridgeInSlavemode(SiS_Pr)) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
} else {
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
#ifdef SIS315H /* 315 series */
+ if(!(SiS_IsNotM650orLater(SiS_Pr,HwInfo))) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x18);
+ }
+
if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
SiS_SetRegSR11ANDOR(SiS_Pr,HwInfo,0xFB,0x00);
}
}
- SiS_EnableCRT2(SiS_Pr);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_UnLockCRT2(SiS_Pr,HwInfo);
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
/* SET PART 1 REGISTER GROUP */
/*********************************************/
-/********** Set CRT2 OFFSET / PITCH **********/
+/* Set CRT2 OFFSET / PITCH */
static void
-SiS_SetCRT2Offset(SiS_Private *SiS_Pr,USHORT ModeNo,
- USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
- PSIS_HW_INFO HwInfo)
+SiS_SetCRT2Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RRTI, PSIS_HW_INFO HwInfo)
{
USHORT offset;
UCHAR temp;
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
- offset = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwInfo);
+ offset = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,RRTI,HwInfo);
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
+ if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
+ offset >>= 1;
+ }
- temp = (UCHAR)(offset & 0xFF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,temp);
- temp = (UCHAR)(offset >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(offset & 0xFF));
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,(offset >> 8));
temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
if(offset % 8) temp++;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
}
-/************* Set CRT2 Sync *************/
+/* Set CRT2 sync and PanelLink mode */
static void
SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
PSIS_HW_INFO HwInfo)
} else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
tempah = SiS_Pr->SiS_LCDInfo;
} else tempah = infoflag >> 8;
-
tempah &= 0xC0;
-
tempah |= 0x20;
if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- tempah |= 0xc0;
+ tempah |= 0xf0;
+ }
+ if( (SiS_Pr->SiS_IF_DEF_FSTN) ||
+ (SiS_Pr->SiS_IF_DEF_DSTN) ||
+ (SiS_Pr->SiS_IF_DEF_TRUMPION) ||
+ (SiS_Pr->SiS_CustomT == CUT_PANEL848) ) {
+ tempah |= 0x30;
}
}
-
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
if(HwInfo->jChipType >= SIS_315H) {
tempah >>= 3;
+ tempah &= 0x18;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
+ /* Don't care about 12/18/24 bit mode - TV is via VGA, not PL */
} else {
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,0xe0);
}
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) { /* 630 - 301B(-DH) */
tempah = infoflag >> 8;
+ tempbl = 0;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
if(SiS_Pr->SiS_LCDInfo & LCDSync) {
tempah = SiS_Pr->SiS_LCDInfo;
+ tempbl = (tempah >> 6) & 0x03;
}
}
tempah &= 0xC0;
-
tempah |= 0x20;
if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-
- tempah &= 0x3f;
- tempah |= tempbl;
+ tempah |= 0xc0;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+ }
} else { /* 630 - 301 */
#ifdef SIS315H /* ------- 315 series ------ */
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - 30xLV */
+ if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { /* 315 - LVDS */
- if(((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) ||
- ((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050))) {
+ tempbl = 0;
+ if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
tempah = infoflag >> 8;
+ if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+ tempbl = ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
+ }
+ } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050)) {
+ tempah = infoflag >> 8;
+ tempbl = 0x03;
} else {
tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+ tempbl = (tempah >> 6) & 0x03;
+ tempbl |= 0x08;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempbl |= 0x04;
}
tempah &= 0xC0;
-
tempah |= 0x20;
if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) tempah |= 0xc0;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+ }
+ }
- } else { /* 315 - 301, 301B */
+ } else { /* 315 - TMDS */
- tempah = infoflag >> 8;
+ tempah = tempbl = infoflag >> 8;
if(!SiS_Pr->UseCustomMode) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempbl = 0;
+ if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ if(ModeNo <= 0x13) {
+ tempah = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
if(SiS_Pr->SiS_LCDInfo & LCDSync) {
tempah = SiS_Pr->SiS_LCDInfo;
+ tempbl = (tempah >> 6) & 0x03;
}
}
}
tempah &= 0xC0;
-
tempah |= 0x20;
if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-
- if(SiS_Pr->SiS_VBType & VB_NoLCD) { /* TEST, imitate BIOS bug */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- tempah |= 0xc0;
+ if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+ /* Imitate BIOS bug */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempah |= 0xc0;
+ }
+ if((SiS_Pr->SiS_VBType & VB_SIS301C) && (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+ tempah >>= 3;
+ tempah &= 0x18;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xe7,tempah);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xf0,tempbl);
+ }
}
}
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
}
#endif /* SIS315H */
}
}
-/******** Set CRT2 FIFO on 300/630/730 *******/
+/* Set CRT2 FIFO on 300/630/730 */
#ifdef SIS300
static void
SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
if(!SiS_Pr->CRT1UsesCustomMode) {
- CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
+ CRT1ModeNo = SiS_Pr->SiS_CRT1Mode; /* get CRT1 ModeNo */
SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
SiS_Pr->SiS_SelectCRT2Rate = 0;
if(CRT1ModeNo >= 0x13) {
index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
index &= 0x3F;
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); /* Get colordepth */
colorth >>= 1;
} else {
CRT1ModeNo = 0xfe;
- VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
+ VCLK = SiS_Pr->CSRClock_CRT1; /* Get VCLK */
data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
- switch(data2) { /* Get color depth */
+ switch(data2) { /* Get color depth */
case 0 : colorth = 1; break;
case 1 : colorth = 1; break;
case 2 : colorth = 2; break;
index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
refreshratetableindex,HwInfo);
- VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
+ VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; /* Get VCLK */
if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x220] & 0x01) {
VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
}
} else {
CRT2ModeNo = 0xfe;
- VCLK = SiS_Pr->CSRClock; /* Get VCLK */
+ VCLK = SiS_Pr->CSRClock; /* Get VCLK */
}
- colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
+ colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex); /* Get colordepth */
colorth >>= 1;
if(!colorth) colorth++;
if(HwInfo->jChipType == SIS_300) {
if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
else temp = (temp & (~0x1F)) | 0x16;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- temp = (temp & (~0x1F)) | 0x13;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+ temp = (temp & (~0x1F)) | 0x13;
}
} else {
if( ( (HwInfo->jChipType == SIS_630) ||
}
#endif
-/**** Set CRT2 FIFO on 315/330 series ****/
+/* Set CRT2 FIFO on 315/330 series */
#ifdef SIS315H
static void
-SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr)
+SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
+ if( (HwInfo->jChipType == SIS_760) &&
+ (SiS_Pr->SiS_SysFlags & SF_760LFB) &&
+ (SiS_Pr->SiS_ModeType == Mode32Bpp) &&
+ (SiS_Pr->SiS_VGAHDE >= 1280) &&
+ (SiS_Pr->SiS_VGAVDE >= 1024) ) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x03);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3b);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4d,0xc0);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,0x6e);
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3f,0x04);
+ }
+
}
#endif
-/*************** Set LCD-A ***************/
-#ifdef SIS315H
-static void
-SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+static USHORT
+SiS_GetVGAHT2(SiS_Private *SiS_Pr)
{
- USHORT modeflag,resinfo;
- USHORT push2,tempax,tempbx,tempcx,temp;
- ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+ ULONG tempax,tempbx;
- /* This is not supported with LCDA */
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
- if(SiS_Pr->UseCustomMode) return;
+ tempbx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX;
+ tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
+ tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
+ return((USHORT)tempax);
+}
- if(IS_SIS330) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* Xabre 1.01.03 */
- } else if(IS_SIS740) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 740/LVDS */
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); /* 740/LVDS */
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
- } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10); /* 740/301LV, 301BDH */
- }
- } else {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) { /* 650/LVDS */
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04); /* 650/LVDS */
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00); /* 650/LVDS 1.10.07 */
- } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f); /* 650/30xLv 1.10.6s */
- }
- }
+/* Set Part 1 / SiS bridge slave mode */
+static void
+SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
+ PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
+{
+ USHORT push1,push2;
+ USHORT tempax,tempbx,tempcx,temp;
+ USHORT resinfo,modeflag,xres=0;
+ unsigned char p1_7, p1_8;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ resinfo = 0;
+ xres = SiS_Pr->CHDisplay;
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ xres = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes;
}
- tempax = SiS_Pr->SiS_LCDHDES;
-
- temp = (tempax & 0x0007); /* BPLHDESKEW[2:0] */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah */
- temp = (tempax >> 3) & 0x00FF; /* BPLHDESKEW[10:3] */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h */
+ /* The following is only done if bridge is in slave mode: */
- tempbx = SiS_Pr->SiS_HDE;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- tempbx = SiS_Pr->PanelXRes;
+ if((HwInfo->jChipType >= SIS_661) && (ModeNo > 0x13)) {
+ if(xres >= 1600) {
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x31,0x04);
+ }
}
- tempax += tempbx; /* HDE + HSKEW = lcdhdee */
- if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
-
- temp = tempax;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- if(temp & 0x07) temp += 8;
- }
- temp >>= 3; /* BPLHDEE */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
- tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2; /* (HT-HDE) / 4 */
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
- /* 650/30xLV 1.10.6s, 740/LVDS */
- if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
- ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x28;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 0x18;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40;
- else tempcx = 0x30;
- }
- }
+ if(modeflag & Charx8Dot) tempcx = 0x08;
+ else tempcx = 0x09;
- tempcx += tempax; /* lcdhrs */
- if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
+ tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ tempax = ((tempax / tempcx) - 1) & 0xff;
+ tempbx = tempax;
- temp = (tempcx >> 3) & 0x00FF; /* BPLHRS */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h */
+ temp = tempax;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
- temp += 10;
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- temp += 6;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
- temp++;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
- temp += 7;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
- temp -= 10;
- }
- }
- }
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ temp += 2;
}
}
- temp &= 0x1F;
- temp |= ((tempcx & 0x07) << 5);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h */
-
- if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
- tempax = SiS_Pr->PanelYRes;
- } else {
- tempax = SiS_Pr->SiS_VGAVDE;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ if(resinfo == SIS_RI_800x600) temp -= 2;
}
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
- tempbx = SiS_Pr->SiS_LCDVDES + tempax;
- if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
- push2 = tempbx;
-
- tempcx = (SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 2;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
- if( ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
- ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 1;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 3;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 3;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 1;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 1;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 1;
- else tempcx = 0x0057;
- }
- }
-
- tempbx += tempcx;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- tempbx++; /* BPLVRS */
- }
- if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h */
-
- tempcx >>= 3;
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 3;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempcx = 5;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 5;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 5;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 2;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 2;
- }
- }
- }
- tempcx += tempbx;
- tempcx++; /* BPLVRE */
- temp = tempcx & 0x000F;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- temp |= 0xC0;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* Part1_19h */
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
- }
-
- temp = ((tempbx >> 8) & 0x07) << 3;
- if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- /* Don't check Part1Port,0x00 -> is not being set if LCDA! */
- /* We check SR06 instead here: */
- if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
- }
- } else {
- if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
- }
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x07,temp); /* Part1_1Ah */
-
- tempbx = push2; /* BPLVDEE */
-
- tempcx = SiS_Pr->SiS_LCDVDES; /* NPLVDES */
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
- if(resinfo == SIS_RI_800x600) tempcx++;
- }
- }
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
- tempbx = tempcx = SiS_Pr->SiS_VGAVDE;
- tempbx--;
- }
-
- temp = ((tempbx >> 8) & 0x07) << 3;
- temp = temp | ((tempcx >> 8) & 0x07);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh */
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch */
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh */
-
- tempeax = SiS_Pr->SiS_VGAVDE << 18;
- tempebx = SiS_Pr->SiS_VDE;
- temp = (USHORT)(tempeax % tempebx);
- tempeax = tempeax / tempebx;
- if(temp) tempeax++;
- tempvcfact = tempeax;
-
- temp = (USHORT)(tempeax & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
-
- temp = (USHORT)((tempeax & 0x00FF00) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
-
- temp = (USHORT)((tempeax & 0x00030000) >> 16);
- if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
-
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
- temp = (USHORT)(tempeax & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
- temp = (USHORT)((tempeax & 0x00FF00) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
- temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
- temp = 0;
- if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
- }
-
- tempeax = SiS_Pr->SiS_VGAHDE << 16;
- tempebx = SiS_Pr->SiS_HDE;
- temp = tempeax % tempebx;
- tempeax /= tempebx;
- if(temp) tempeax++;
- if(tempebx == SiS_Pr->SiS_VGAHDE) tempeax = 0xFFFF;
- tempecx = tempeax;
- tempeax = ((SiS_Pr->SiS_VGAHDE << 16) / tempecx) - 1;
- tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
- temp = (USHORT)(tempecx & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh */
-
- tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
- tempbx = (USHORT)(tempeax & 0x0FFFF);
-
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
-
- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempbx = 1;
-
- temp = ((tempbx >> 8) & 0x07) << 3;
- temp = temp | ((tempecx >> 8) & 0x07);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h */
-
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h */
-
- tempecx >>= 16; /* BPLHCFACT */
- if(modeflag & HalfDCLK) tempecx >>= 1;
- temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h */
-
- temp = (USHORT)(tempecx & 0x000000FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
-
- if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
- }
-}
-#endif /* SIS 315 */
-
-static USHORT
-SiS_GetVGAHT2(SiS_Private *SiS_Pr)
-{
- ULONG tempax,tempbx;
-
- tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
- tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
- tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
- return((USHORT) tempax);
-}
-
-/******* Set Part 1 / SiS bridge *********/
-static void
-SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
-{
- USHORT push1,push2;
- USHORT tempax,tempbx,tempcx,temp;
- USHORT resinfo,modeflag;
- unsigned char p1_7, p1_8;
-
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
- } else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- resinfo = 0;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
- }
-
- /* The following is only done if bridge is in slave mode: */
-
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff); /* set MAX HT */
-
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) modeflag |= Charx8Dot;
-
- if(modeflag & Charx8Dot) tempcx = 0x08;
- else tempcx = 0x09;
-
- tempax = SiS_Pr->SiS_VGAHDE; /* 0x04 Horizontal Display End */
- if(modeflag & HalfDCLK) tempax >>= 1;
- tempax = ((tempax / tempcx) - 1) & 0xff;
- tempbx = tempax;
-
- temp = tempax;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
-
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
- temp += 2;
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(resinfo == SIS_RI_800x600) temp -= 2;
- }
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp); /* 0x05 Horizontal Display Start */
-
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03); /* 0x06 Horizontal Blank end */
-
- tempax = 0xFFFF;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
- if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
- if(modeflag & HalfDCLK) tempax >>= 1;
- tempax = (tempax / tempcx) - 5;
- tempcx = tempax;
+ tempax = 0xFFFF;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempax = SiS_GetVGAHT2(SiS_Pr);
+ if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ tempax = (tempax / tempcx) - 5;
+ tempcx = tempax;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
temp = tempcx - 1;
} else {
if(!(modeflag & HalfDCLK)) {
temp -= 4;
- if((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) &&
- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200)) {
+ if((SiS_Pr->SiS_LCDResInfo != Panel_1280x960) &&
+ (SiS_Pr->SiS_LCDResInfo != Panel_1600x1200)) {
if(SiS_Pr->SiS_VGAHDE >= 800) {
temp -= 7;
if(HwInfo->jChipType < SIS_315H) {
- /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
if(SiS_Pr->SiS_ModeType == ModeEGA) {
if(SiS_Pr->SiS_VGAVDE == 1024) {
temp += 15;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024)
temp += 7;
}
}
}
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
if(SiS_Pr->SiS_VGAHDE >= 1280) {
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
}
p1_7 = 0xab;
}
}
+ } else {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) {
+ if(modeflag & HalfDCLK) p1_7 = 0x30;
+ }
}
}
else if(tempbx == 525) tempbx = 480;
push2 = tempbx;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
if (tempbx == 350) tempbx += 5;
else if(tempbx == 480) tempbx += 5;
tempbx += (tempax << 1);
}
} else if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1400x1050) {
tempbx += (tempax << 1);
}
}
}
}
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* 0x1A SR0E */
+
+ temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
}
-/*********** Set Part 1 / LVDS ***********/
+/* Setup panel link
+ * This is used for LVDS, LCDA and Chrontel TV output
+ * 300/LVDS+TV, 300/301B-DH, 315/LVDS+TV, 315/LCDA
+ */
static void
SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+ PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
{
- USHORT modeflag, resinfo;
- USHORT push1, push2, tempax, tempbx, tempcx, temp;
+ USHORT modeflag,resinfo;
+ USHORT push2,tempax,tempbx,tempcx,temp;
+ ULONG tempeax=0,tempebx,tempecx,tempvcfact=0;
+ BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
+#ifdef SIS300
+ USHORT crt2crtc;
+#endif
#ifdef SIS315H
USHORT pushcx;
#endif
- ULONG tempeax=0, tempebx, tempecx, tempvcfact=0;
-
- /* This is not supported on LVDS */
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
- if(SiS_Pr->UseCustomMode) return;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+#ifdef SIS300
+ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+#endif
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ resinfo = 0;
+#ifdef SIS300
+ crt2crtc = 0;
+#endif
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+#ifdef SIS300
+ crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+#endif
}
- /* Set up Panel Link */
-
- /* 1. Horizontal setup */
-
- tempax = SiS_Pr->SiS_LCDHDES;
-
- if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
- if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
- (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
- tempax -= 8;
- }
+ /* is lvds if really LVDS, or SiS 301B-DH with external LVDS transmitter */
+ if((SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+ ((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ islvds = TRUE;
}
- tempcx = SiS_Pr->SiS_HT; /* Horiz. Total */
-
- tempbx = SiS_Pr->SiS_HDE; /* Horiz. Display End */
+ /* is really sis if sis bridge, but not 301B-DH */
+ if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+ issis = TRUE;
+ }
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
- tempbx >>= 1;
+ if((HwInfo->jChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
+ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+ chkdclkfirst = TRUE;
+ }
}
- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
- tempbx = SiS_Pr->PanelXRes;
- } else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- tempbx = SiS_Pr->PanelXRes;
- if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
- tempbx = 800;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
- tempbx = 1024;
+#ifdef SIS315H
+ if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+ if(IS_SIS330) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
+ } else if(IS_SIS740) {
+ if(islvds) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
+ }
+ } else {
+ if(islvds) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);
+ } else if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);
+ if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_1024x768) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x20);
}
}
}
}
}
- tempcx = (tempcx - tempbx) >> 2; /* HT-HDE / 4 */
-
- push1 = tempax;
-
- tempax += tempbx;
-
- if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+#endif
- push2 = tempax;
+ /* Horizontal */
- if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
- (!SiS_Pr->SiS_IF_DEF_DSTN) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
- (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
- if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0028;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0018;
- else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- tempcx = 0x0017; /* A901; sometimes 0x0018; */
- } else {
- tempcx = 0x0017;
-#ifdef TWNEWPANEL
- tempcx = 0x0018;
-#endif
- }
- } else {
- tempcx = 0x0018;
- }
- }
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0028;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+ tempax = SiS_Pr->SiS_LCDHDES;
+ if(islvds) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) &&
+ (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+ tempax -= 8;
}
- }
+ }
}
}
- tempcx += tempax; /* lcdhrs */
- if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
-
- tempax = tempcx >> 3; /* BPLHRS */
- temp = tempax & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* Part1_14h; Panel Link Horizontal Retrace Start */
+ temp = (tempax & 0x0007);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* BPLHDESKEW[2:0] */
+ temp = (tempax >> 3) & 0x00FF;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* BPLHDESKEW[10:3] */
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- temp = (tempax & 0x00FF) + 2;
- } else {
- temp = (tempax & 0x00FF) + 10;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
- (!SiS_Pr->SiS_IF_DEF_FSTN) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
- (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- temp += 6;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
- temp++;
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
- temp += 7;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
- temp -= 0x14;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) {
- temp -= 10;
- }
- }
- }
- }
- }
- }
- }
+ tempbx = SiS_Pr->SiS_HDE;
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_640x480_2) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_640x480_3)) {
+ tempbx >>= 1;
+ }
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ tempbx = SiS_Pr->PanelXRes;
}
}
- temp &= 0x1F;
- temp |= ((tempcx & 0x0007) << 5);
-#if 0
- if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
-#endif
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
-
- tempbx = push2;
- tempcx = push1; /* lcdhdes */
+ tempax += tempbx;
+ if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
- temp = (tempcx & 0x0007); /* BPLHDESKEW */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp); /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
+ temp = tempax;
+ if(temp & 0x07) temp += 8;
+ temp >>= 3;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* BPLHDEE */
- tempcx >>= 3; /* BPLHDES */
- temp = (tempcx & 0x00FF);
-#if 0 /* Not 550 FSTN */
- if(HwInfo->jChipType >= SIS_315H) {
- if(ModeNo == 0x5b) temp--; */
- }
-#endif
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp); /* Part1_16h; Panel Link Horizontal Display Enable Start */
+ tempcx = (SiS_Pr->SiS_HT - tempbx) >> 2;
- if((HwInfo->jChipType < SIS_315H) ||
- (SiS_Pr->SiS_IF_DEF_FSTN) ||
- (SiS_Pr->SiS_IF_DEF_DSTN)) {
- if(tempbx & 0x07) tempbx += 8;
- }
- tempbx >>= 3; /* BPLHDEE */
- temp = tempbx & 0x00FF;
-#if 0 /* Not 550 FSTN */
- if(HwInfo->jChipType >= SIS_315H) {
- if(ModeNo == 0x5b) temp--;
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(SiS_Pr->PanelHRS != 999) tempcx = SiS_Pr->PanelHRS;
+ }
}
-#endif
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp); /* Part1_17h; Panel Link Horizontal Display Enable End */
- /* 2. Vertical setup */
+ tempcx += tempax;
+ if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
- if(HwInfo->jChipType < SIS_315H) {
- tempcx = SiS_Pr->SiS_VGAVT;
- tempbx = SiS_Pr->SiS_VGAVDE;
- if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- tempbx = SiS_Pr->PanelYRes;
+ temp = (tempcx >> 3) & 0x00FF;
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ switch(ModeNo) {
+ case 0x04:
+ case 0x05:
+ case 0x0d: temp = 0x56; break;
+ case 0x10: temp = 0x60; break;
+ case 0x13: temp = 0x5f; break;
+ case 0x40:
+ case 0x41:
+ case 0x4f:
+ case 0x43:
+ case 0x44:
+ case 0x62:
+ case 0x56:
+ case 0x53:
+ case 0x5d:
+ case 0x5e: temp = 0x54; break;
}
- }
+ }
}
- tempcx -= tempbx;
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp); /* BPLHRS */
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ temp += 2;
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ temp += 8;
+ if(SiS_Pr->PanelHRE != 999) {
+ temp = tempcx + SiS_Pr->PanelHRE;
+ if(temp >= SiS_Pr->SiS_HT) temp -= SiS_Pr->SiS_HT;
+ temp >>= 3;
+ }
+ }
} else {
-
- tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE; /* VGAVT-VGAVDE */
-
+ temp += 10;
}
- tempbx = SiS_Pr->SiS_LCDVDES; /* VGAVDES */
- push1 = tempbx;
+ temp &= 0x1F;
+ temp |= ((tempcx & 0x07) << 5);
+#if 0
+ if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20; /* WRONG? BIOS loads cl, not ah */
+#endif
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp); /* BPLHRE */
- tempax = SiS_Pr->SiS_VGAVDE;
+ /* Vertical */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- tempax = 600;
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
- tempax = 768;
- }
- }
- } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0) &&
- (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
- ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
- (SiS_Pr->SiS_IF_DEF_FSTN) ||
- (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
+ tempax = SiS_Pr->SiS_VGAVDE;
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
tempax = SiS_Pr->PanelYRes;
}
}
- tempbx += tempax;
+ tempbx = SiS_Pr->SiS_LCDVDES + tempax;
if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
push2 = tempbx;
- tempcx >>= 1;
-
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
- (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
- tempcx = 0x0017;
- } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003;
- else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
- else tempcx = 0x0057;
- } else {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0001;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0001;
- else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- tempcx = 0x0002; /* A901; sometimes 0x0003; */
- } else {
- tempcx = 0x0002;
-#ifdef TWNEWPANEL
- tempcx = 0x0003;
-#endif
- }
- } else tempcx = 0x0003;
- }
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0003;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
- else tempcx = 0x0057;
+ tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;
+ if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->PanelYRes;
}
}
}
+ if(islvds) tempcx >>= 1;
+ else tempcx >>= 2;
- tempbx += tempcx; /* BPLVRS */
-
- if((HwInfo->jChipType < SIS_315H) ||
- (SiS_Pr->SiS_IF_DEF_FSTN) ||
- (SiS_Pr->SiS_IF_DEF_DSTN)) {
- tempbx++;
+ if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+ (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+ (SiS_Pr->PanelVRS != 999) ) {
+ tempcx = SiS_Pr->PanelVRS;
+ tempbx += tempcx;
+ if(issis) tempbx++;
+ } else {
+ tempbx += tempcx;
+ if(HwInfo->jChipType < SIS_315H) tempbx++;
+ else if(issis) tempbx++;
}
- if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+ if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT; /* BPLVRS */
temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp); /* Part1_18h; Panel Link Vertical Retrace Start */
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(ModeNo == 0x10) temp = 0xa9;
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
tempcx >>= 3;
+ tempcx++;
- if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
- (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
- (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if( (HwInfo->jChipType < SIS_315H) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) ) tempcx = 0x0001;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) tempcx = 0x0002;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempcx = 0x0002;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) tempcx = 0x0003;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempcx = 0x0005;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempcx = 0x0005;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) tempcx = 0x0011;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0005;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0002;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0011;
- else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- tempcx = 0x0004; /* A901; Other BIOS sets 0x0005; */
- } else {
- tempcx = 0x0004;
-#ifdef TWNEWPANEL
- tempcx = 0x0005;
-#endif
- }
- } else {
- tempcx = 0x0005;
- }
- }
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if(SiS_Pr->PanelVRE != 999) tempcx = SiS_Pr->PanelVRE;
}
}
- tempcx = tempcx + tempbx + 1; /* BPLVRE */
+ tempcx += tempbx;
temp = tempcx & 0x000F;
- if(SiS_Pr->SiS_IF_DEF_FSTN ||
- SiS_Pr->SiS_IF_DEF_DSTN ||
- (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
- (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
- (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
- temp |= 0x30;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc. */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp); /* BPLVRE */
- temp = ((tempbx & 0x0700) >> 8) << 3; /* BPLDESKEW =0 */
+ temp = ((tempbx >> 8) & 0x07) << 3;
if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
if(SiS_Pr->SiS_HDE != 640) {
- if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+ if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+ }
+ } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
+ tempbx = 0x87;
+ if((HwInfo->jChipType >= SIS_315H) ||
+ (HwInfo->jChipRevision >= 0x30)) {
+ tempbx = 0x07;
+ if((SiS_Pr->SiS_IF_DEF_CH70xx == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x03) temp |= 0x80;
+ }
+ /* Chrontel 701x operates in 24bit mode (8-8-8, 2x12bit mutliplexed) via VGA2 */
+ if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x10) temp |= 0x80;
+ } else {
+ if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+ }
}
- } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE) temp |= 0x40;
- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) temp |= 0x40;
- if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
- if(HwInfo->jChipType >= SIS_315H) {
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
- temp |= 0x80;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,tempbx,temp);
+
+ tempbx = push2; /* BPLVDEE */
+
+ tempcx = SiS_Pr->SiS_LCDVDES; /* BPLVDES */
+
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ switch(SiS_Pr->SiS_LCDResInfo) {
+ case Panel_640x480:
+ tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ tempcx = SiS_Pr->SiS_VGAVDE;
+ break;
+ case Panel_800x600:
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == SIS_RI_800x600) tempcx++;
}
- } else {
- if( (HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ) {
- if(HwInfo->jChipRevision >= 0x30) {
- temp |= 0x80;
+ break;
+ case Panel_1024x600:
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == SIS_RI_1024x600) tempcx++;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(resinfo == SIS_RI_800x600) tempcx++;
}
- }
+ }
+ break;
+ case Panel_1024x768:
+ if(HwInfo->jChipType < SIS_315H) {
+ if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ if(resinfo == SIS_RI_1024x768) tempcx++;
+ }
+ }
+ break;
}
}
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp); /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
- if (HwInfo->jChipType < SIS_315H) {
+ temp = ((tempbx >> 8) & 0x07) << 3;
+ temp = temp | ((tempcx >> 8) & 0x07);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);
+ /* if(SiS_Pr->SiS_IF_DEF_FSTN) tempbx++; */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,tempbx);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,tempcx);
-#ifdef SIS300 /* 300 series */
+ /* Vertical scaling */
- tempeax = SiS_Pr->SiS_VGAVDE << 6;
- temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
- tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
- if(temp != 0) tempeax++;
- tempebx = tempeax; /* BPLVCFACT */
+ if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
- tempebx = 0x003F;
- }
+#ifdef SIS300 /* 300 series */
+ tempeax = SiS_Pr->SiS_VGAVDE << 6;
+ temp = (tempeax % (ULONG)SiS_Pr->SiS_VDE);
+ tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
+ if(temp) tempeax++;
- temp = (USHORT)(tempebx & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* Part1_1Eh; Panel Link Vertical Scaling Factor */
+ if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) tempeax = 0x3F;
+ temp = (USHORT)(tempeax & 0x00FF);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
+ tempvcfact = temp;
#endif /* SIS300 */
} else {
#ifdef SIS315H /* 315 series */
+ tempeax = SiS_Pr->SiS_VGAVDE << 18;
+ tempebx = SiS_Pr->SiS_VDE;
+ temp = (tempeax % tempebx);
+ tempeax = tempeax / tempebx;
+ if(temp) tempeax++;
+ tempvcfact = tempeax;
- if(HwInfo->jChipType == SIS_740) {
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
- } else {
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,0x23);
- }
-
- tempeax = SiS_Pr->SiS_VGAVDE << 18;
- temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
- tempeax = tempeax / SiS_Pr->SiS_VDE;
- if(temp != 0) tempeax++;
- tempebx = tempeax; /* BPLVCFACT */
- tempvcfact = tempeax;
- temp = (USHORT)(tempebx & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp); /* Part1_37h; Panel Link Vertical Scaling Factor */
- temp = (USHORT)((tempebx & 0x00FF00) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp); /* Part1_36h; Panel Link Vertical Scaling Factor */
- temp = (USHORT)((tempebx & 0x00030000) >> 16);
- temp &= 0x03;
- if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp); /* Part1_35h; Panel Link Vertical Scaling Factor */
-
-#endif /* SIS315H */
-
- }
-
- tempbx = push2; /* BPLVDEE */
- tempcx = push1;
-
- push1 = temp;
-
- if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
- if(resinfo == SIS_RI_1024x600) tempcx++;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(resinfo == SIS_RI_800x600) tempcx++;
- }
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
- if(resinfo == SIS_RI_800x600) tempcx++;
- if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
- } else if(resinfo == SIS_RI_1024x768) tempcx++;
- } else {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
- if(resinfo == SIS_RI_800x600) tempcx++;
- }
- }
- }
- }
+ temp = (USHORT)(tempeax & 0x00FF);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
+ temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
+ temp = (USHORT)((tempeax & 0x00030000) >> 16);
+ if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
- if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
- tempcx = SiS_Pr->SiS_VGAVDE;
- tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
+ temp = (USHORT)(tempeax & 0x00FF);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3c,temp);
+ temp = (USHORT)((tempeax & 0x00FF00) >> 8);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x3b,temp);
+ temp = (USHORT)(((tempeax & 0x00030000) >> 16) << 6);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0x3f,temp);
+ temp = 0;
+ if(SiS_Pr->SiS_VDE != SiS_Pr->SiS_VGAVDE) temp |= 0x08;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x30,0xf3,temp);
}
- }
-
- temp = ((tempbx & 0x0700) >> 8) << 3;
- temp |= ((tempcx & 0x0700) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp); /* Part1_1Dh; Vertical Display Overflow; Control Signal */
-
- temp = tempbx & 0x00FF;
- /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++; */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp); /* Part1_1Ch; Panel Link Vertical Display Enable End */
+#endif
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp); /* Part1_1Bh; Panel Link Vertical Display Enable Start */
+ }
- /* 3. Additional horizontal setup (scaling, etc) */
+ /* Horizontal scaling */
- tempecx = SiS_Pr->SiS_VGAHDE;
- if(HwInfo->jChipType >= SIS_315H) {
- if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
- if(modeflag & HalfDCLK) tempecx >>= 1;
- }
+ tempeax = SiS_Pr->SiS_VGAHDE; /* 1f = ( (VGAHDE * 65536) / ( (VGAHDE * 65536) / HDE ) ) - 1*/
+ if(chkdclkfirst) {
+ if(modeflag & HalfDCLK) tempeax >>= 1;
}
- tempebx = SiS_Pr->SiS_HDE;
- if(tempecx == tempebx) tempeax = 0xFFFF;
- else {
- tempeax = tempecx;
- tempeax <<= 16;
- temp = (USHORT)(tempeax % tempebx);
- tempeax = tempeax / tempebx;
+ tempebx = tempeax << 16;
+ if(SiS_Pr->SiS_HDE == tempeax) {
+ tempecx = 0xFFFF;
+ } else {
+ tempecx = tempebx / SiS_Pr->SiS_HDE;
if(HwInfo->jChipType >= SIS_315H) {
- if(temp) tempeax++;
+ if(tempebx % SiS_Pr->SiS_HDE) tempecx++;
}
}
- tempecx = tempeax;
if(HwInfo->jChipType >= SIS_315H) {
- tempeax = SiS_Pr->SiS_VGAHDE;
- if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
- if(modeflag & HalfDCLK) tempeax >>= 1;
- }
- tempeax <<= 16;
- tempeax = (tempeax / tempecx) - 1;
+ tempeax = (tempebx / tempecx) - 1;
} else {
tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
}
- tempecx <<= 16;
- tempecx |= (tempeax & 0xFFFF);
+ tempecx = (tempecx << 16) | (tempeax & 0xFFFF);
temp = (USHORT)(tempecx & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp); /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);
- tempbx = SiS_Pr->SiS_VDE;
if(HwInfo->jChipType >= SIS_315H) {
tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
- tempbx = (USHORT)(tempeax & 0x0FFFF);
+ tempbx = (USHORT)(tempeax & 0xFFFF);
} else {
tempeax = SiS_Pr->SiS_VGAVDE << 6;
- tempbx = push1 & 0x3f;
+ tempbx = tempvcfact & 0x3f;
if(tempbx == 0) tempbx = 64;
tempeax /= tempbx;
- tempbx = (USHORT)(tempeax & 0x0FFFF);
+ tempbx = (USHORT)(tempeax & 0xFFFF);
}
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tempbx--;
if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
- else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempbx = 1;
+ else if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) tempbx = 1;
}
- temp = ((tempbx & 0xFF00) >> 8) << 3;
- temp |= (USHORT)((tempecx & 0x0700) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp); /* Part1_20h; Overflow register */
-
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp); /* Part1_21h; Panel Link Vertical Accumulator Register */
+ temp = ((tempbx >> 8) & 0x07) << 3;
+ temp = temp | ((tempecx >> 8) & 0x07);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,tempbx);
- tempecx >>= 16; /* BPLHCFACT */
- if((HwInfo->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
+ tempecx >>= 16; /* BPLHCFACT */
+ if(!chkdclkfirst) {
if(modeflag & HalfDCLK) tempecx >>= 1;
}
temp = (USHORT)((tempecx & 0xFF00) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp); /* Part1_22h; Panel Link Horizontal Scaling Factor High */
-
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);
temp = (USHORT)(tempecx & 0x00FF);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp); /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
+
+#ifdef SIS315H
+ if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+ }
+ } else {
+ if(islvds) {
+ if(HwInfo->jChipType == SIS_740) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
+ } else {
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x23);
+ }
+ }
+ }
+ }
+#endif
- /* 630/301B and 630/LVDS do something for 640x480 panels here */
+#ifdef SIS300
+ if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
+ int i;
+ UCHAR TrumpMode13[4] = { 0x01, 0x10, 0x2c, 0x00 };
+ UCHAR TrumpMode10_1[4] = { 0x01, 0x10, 0x27, 0x00 };
+ UCHAR TrumpMode10_2[4] = { 0x01, 0x16, 0x10, 0x00 };
+
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xbf);
+ for(i=0; i<5; i++) {
+ SiS_SetTrumpionBlock(SiS_Pr, &SiS300_TrumpionData[crt2crtc][0]);
+ }
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(ModeNo == 0x13) {
+ for(i=0; i<4; i++) {
+ SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode13[0]);
+ }
+ } else if(ModeNo == 0x10) {
+ for(i=0; i<4; i++) {
+ SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_1[0]);
+ SiS_SetTrumpionBlock(SiS_Pr, &TrumpMode10_2[0]);
+ }
+ }
+ }
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+ }
+#endif
#ifdef SIS315H
if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x07,0x03);
tempax = SiS_Pr->SiS_HDE; /* Blps = lcdhdee(lcdhdes+HDE) + 64 */
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
tempax += 64;
temp = tempax & 0x00FF;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
tempax = SiS_Pr->SiS_VDE;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
tempax >>= 1;
temp = tempax & 0x00FF;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
tempeax = SiS_Pr->SiS_HDE;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempeax >>= 1;
tempeax <<= 2; /* BDxFIFOSTOP = (HDE*4)/128 */
tempebx = 128;
temp = (USHORT)(tempeax % tempebx);
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
tempax = SiS_Pr->SiS_HDE;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
tempax >>= 4; /* BDxWadroff = HDE*4/8/8 */
pushcx = tempax;
temp = tempax & 0x00FF;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
tempax = SiS_Pr->SiS_VDE; /* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
- SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480_2 ||
+ SiS_Pr->SiS_LCDResInfo == Panel_640x480_3) tempax >>= 1;
tempeax = (tempax * pushcx);
tempebx = 0x00100000 + tempeax;
temp = (USHORT)tempebx & 0x000000FF;
}
}
#endif /* SIS315H */
-
}
-/************** Set Part 1 ***************/
+/* Set Part 1 */
static void
SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT temp=0, tempax=0, tempbx=0, tempcx=0;
- USHORT pushbx=0, CRT1Index=0;
+#if defined(SIS300) || defined(SIS315H)
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+#endif
+ USHORT temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
+ USHORT pushbx=0, CRT1Index=0, modeflag, resinfo=0;
#ifdef SIS315H
USHORT tempbl=0;
#endif
- USHORT modeflag, resinfo=0;
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ return;
+ }
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
} else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
}
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-
-#ifdef SIS315H
- SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
- SiS_SetGroup1_LCDA(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
-#endif
-
- } else {
+ SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- if( (HwInfo->jChipType >= SIS_315H) &&
+ if( ! ((HwInfo->jChipType >= SIS_315H) &&
(SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
- (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
-
- SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+ (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
- } else {
-
- SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, HwInfo);
-
- if (HwInfo->jChipType < SIS_315H ) {
+ if(HwInfo->jChipType < SIS_315H ) {
#ifdef SIS300
- SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
+ SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
#endif
- } else {
+ } else {
#ifdef SIS315H
- SiS_SetCRT2FIFO_310(SiS_Pr);
+ SiS_SetCRT2FIFO_310(SiS_Pr, HwInfo);
#endif
- }
-
- SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+ }
- /* 1. Horizontal setup */
+ /* 1. Horizontal setup */
- if(HwInfo->jChipType < SIS_315H ) {
+ if(HwInfo->jChipType < SIS_315H ) {
#ifdef SIS300 /* ------------- 300 series --------------*/
- temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
-
- temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
+ temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
- temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
+ temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp); /* CRT2 Horizontal Total Overflow [7:4] */
- pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA@HRS 0x0B,0x0C */
- tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
- tempbx = pushbx + tempcx;
- tempcx <<= 1;
- tempcx += tempbx;
+ temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
- if(SiS_Pr->UseCustomMode) {
- tempbx = SiS_Pr->CHSyncStart + 12;
- tempcx = SiS_Pr->CHSyncEnd + 12;
- }
+ pushbx = SiS_Pr->SiS_VGAHDE + 12; /* bx BTVGA2HRS 0x0B,0x0C */
+ tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+ tempbx = pushbx + tempcx;
+ tempcx <<= 1;
+ tempcx += tempbx;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
- unsigned char cr4, cr14, cr5, cr15;
- if(SiS_Pr->UseCustomMode) {
- cr4 = SiS_Pr->CCRT1CRTC[4];
- cr14 = SiS_Pr->CCRT1CRTC[14];
- cr5 = SiS_Pr->CCRT1CRTC[5];
- cr15 = SiS_Pr->CCRT1CRTC[15];
- } else {
- cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
- cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
- cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
- cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
- }
- tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
- tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
- }
-
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)){
- tempbx = 1040;
- tempcx = 1042;
- }
- }
- }
+ bridgeadd = 12;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp); /* CRT2 Horizontal Retrace Start */
#endif /* SIS300 */
- } else {
+ } else {
#ifdef SIS315H /* ------------------- 315/330 series --------------- */
- tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
- if(modeflag & HalfDCLK) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- tempcx >>= 1;
- } else {
- tempax = SiS_Pr->SiS_VGAHDE >> 1;
- tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- tempcx = SiS_Pr->SiS_HT - tempax;
- }
- }
- }
- tempcx--;
+ tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
+ if(modeflag & HalfDCLK) {
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ tempcx >>= 1;
+ } else {
+ tempax = SiS_Pr->SiS_VGAHDE >> 1;
+ tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ tempcx = SiS_Pr->SiS_HT - tempax;
+ }
+ }
+ }
+ tempcx--;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,tempcx); /* CRT2 Horizontal Total */
+ temp = (tempcx >> 4) & 0xF0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
+
+ tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
+ tempbx = SiS_Pr->SiS_VGAHDE;
+ tempcx -= tempbx;
+ tempcx >>= 2;
+ if(modeflag & HalfDCLK) {
+ tempbx >>= 1;
+ tempcx >>= 1;
+ }
+ tempbx += 16;
- temp = tempcx & 0xff;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,tempbx); /* CRT2 Horizontal Display Enable End */
- temp = ((tempcx & 0xff00) >> 8) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp); /* CRT2 Horizontal Total Overflow [7:4] */
+ pushbx = tempbx;
+ tempcx >>= 1;
+ tempbx += tempcx;
+ tempcx += tempbx;
- tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HDEE 0x0A,0x0C */
- tempbx = SiS_Pr->SiS_VGAHDE;
- tempcx -= tempbx;
- tempcx >>= 2;
- if(modeflag & HalfDCLK) {
- tempbx >>= 1;
- tempcx >>= 1;
- }
- tempbx += 16;
-
- temp = tempbx & 0xff;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp); /* CRT2 Horizontal Display Enable End */
-
- pushbx = tempbx;
- tempcx >>= 1;
- tempbx += tempcx;
- tempcx += tempbx;
-
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
- if(HwInfo->jChipType >= SIS_661) {
- if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
- if(resinfo == SIS_RI_1280x1024) {
- tempcx = 0x30;
- } else if(resinfo == SIS_RI_1600x1200) {
- tempcx = 0xff;
- }
- }
- }
+ bridgeadd = 16;
- if(SiS_Pr->UseCustomMode) {
- tempbx = SiS_Pr->CHSyncStart + 16;
- tempcx = SiS_Pr->CHSyncEnd + 16;
- tempax = SiS_Pr->SiS_VGAHT;
- if(modeflag & HalfDCLK) tempax >>= 1;
- tempax--;
- if(tempcx > tempax) tempcx = tempax;
- }
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(HwInfo->jChipType >= SIS_661) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)) {
+ if(resinfo == SIS_RI_1280x1024) {
+ tempcx = (tempcx & 0xff00) | 0x30;
+ } else if(resinfo == SIS_RI_1600x1200) {
+ tempcx = (tempcx & 0xff00) | 0xff;
+ }
+ }
+ }
+ }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
- unsigned char cr4, cr14, cr5, cr15;
- if(SiS_Pr->UseCustomMode) {
- cr4 = SiS_Pr->CCRT1CRTC[4];
- cr14 = SiS_Pr->CCRT1CRTC[14];
- cr5 = SiS_Pr->CCRT1CRTC[5];
- cr15 = SiS_Pr->CCRT1CRTC[15];
- } else {
- cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
- cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
- cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
- cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
- }
- tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
- tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
- tempcx &= 0x00FF;
- tempcx |= (tempbx & 0xFF00);
- tempbx += 16;
- tempcx += 16;
- tempax = SiS_Pr->SiS_VGAHT;
- if(modeflag & HalfDCLK) tempax >>= 1;
- tempax--;
- if(tempcx > tempax) tempcx = tempax;
- }
-
- if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
- tempbx = 1040;
- tempcx = 1042;
- }
-
- }
-
- temp = tempbx & 0xff;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp); /* CRT2 Horizontal Retrace Start */
#endif /* SIS315H */
- } /* 315/330 series */
+ } /* 315/330 series */
+
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
- /* The following is done for all bridge/chip types/series */
+ if(SiS_Pr->UseCustomMode) {
+ tempbx = SiS_Pr->CHSyncStart + bridgeadd;
+ tempcx = SiS_Pr->CHSyncEnd + bridgeadd;
+ tempax = SiS_Pr->SiS_VGAHT;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ tempax--;
+ if(tempcx > tempax) tempcx = tempax;
+ }
- tempax = tempbx & 0xFF00;
- tempbx = pushbx;
- tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
- tempax |= (tempbx & 0xFF00);
- temp = (tempax & 0xFF00) >> 8;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ unsigned char cr4, cr14, cr5, cr15;
+ if(SiS_Pr->UseCustomMode) {
+ cr4 = SiS_Pr->CCRT1CRTC[4];
+ cr14 = SiS_Pr->CCRT1CRTC[14];
+ cr5 = SiS_Pr->CCRT1CRTC[5];
+ cr15 = SiS_Pr->CCRT1CRTC[15];
+ } else {
+ cr4 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+ cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+ cr5 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+ cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+ }
+ tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; /* (VGAHRE-3)*8 */
+ tempcx &= 0x00FF;
+ tempcx |= (tempbx & 0xFF00);
+ tempbx += bridgeadd;
+ tempcx += bridgeadd;
+ tempax = SiS_Pr->SiS_VGAHT;
+ if(modeflag & HalfDCLK) tempax >>= 1;
+ tempax--;
+ if(tempcx > tempax) tempcx = tempax;
+ }
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp); /* CRT2 Horizontal Retrace End */
+ if(SiS_Pr->SiS_TVMode & TVSetNTSC1024) {
+ tempbx = 1040;
+ tempcx = 1044; /* HWCursor bug! */
+ }
- /* 2. Vertical setup */
+ }
- tempcx = SiS_Pr->SiS_VGAVT - 1;
- temp = tempcx & 0x00FF;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,tempbx); /* CRT2 Horizontal Retrace Start */
- if(HwInfo->jChipType < SIS_661) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
- temp--;
- }
- }
- } else {
- temp--;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,tempcx); /* CRT2 Horizontal Retrace End */
+
+ temp = ((tempbx >> 8) & 0x0F) | ((pushbx >> 4) & 0xF0);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp); /* Overflow */
+
+ /* 2. Vertical setup */
+
+ tempcx = SiS_Pr->SiS_VGAVT - 1;
+ temp = tempcx & 0x00FF;
+
+ if(HwInfo->jChipType < SIS_661) {
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
+ temp--;
+ }
}
- } else if(HwInfo->jChipType >= SIS_315H) {
- temp--;
- }
- }
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
-
- tempbx = SiS_Pr->SiS_VGAVDE - 1;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,temp); /* CRT2 Vertical Display Enable End */
-
- temp = ((tempbx & 0xFF00) << 3) >> 8;
- temp |= ((tempcx & 0xFF00) >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow (and HWCursor Test Mode) */
-
- if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
- tempbx++;
- tempax = tempbx;
- tempcx++;
- tempcx -= tempax;
- tempcx >>= 2;
- tempbx += tempcx;
- if(tempcx < 4) tempcx = 4;
- tempcx >>= 2;
- tempcx += tempbx;
- tempcx++;
- } else {
- tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
- tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+ } else {
+ temp--;
+ }
+ } else if(HwInfo->jChipType >= SIS_315H) {
+ temp--;
}
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp); /* CRT2 Vertical Total */
+
+ tempbx = SiS_Pr->SiS_VGAVDE - 1;
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,tempbx); /* CRT2 Vertical Display Enable End */
+
+ temp = ((tempbx >> 5) & 0x38) | ((tempcx >> 8) & 0x07);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp); /* Overflow */
+
+ if((HwInfo->jChipType >= SIS_315H) && (HwInfo->jChipType < SIS_661)) {
+ tempbx++;
+ tempax = tempbx;
+ tempcx++;
+ tempcx -= tempax;
+ tempcx >>= 2;
+ tempbx += tempcx;
+ if(tempcx < 4) tempcx = 4;
+ tempcx >>= 2;
+ tempcx += tempbx;
+ tempcx++;
+ } else {
+ tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+ tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+ }
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if(SiS_Pr->UseCustomMode) {
+ tempbx = SiS_Pr->CVSyncStart;
+ tempcx = SiS_Pr->CVSyncEnd;
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+ unsigned char cr8, cr7, cr13;
if(SiS_Pr->UseCustomMode) {
- tempbx = SiS_Pr->CVSyncStart;
- tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
+ cr8 = SiS_Pr->CCRT1CRTC[8];
+ cr7 = SiS_Pr->CCRT1CRTC[7];
+ cr13 = SiS_Pr->CCRT1CRTC[13];
+ tempcx = SiS_Pr->CCRT1CRTC[9];
+ } else {
+ cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+ cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+ cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+ tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
}
+ tempbx = cr8;
+ if(cr7 & 0x04) tempbx |= 0x0100;
+ if(cr7 & 0x80) tempbx |= 0x0200;
+ if(cr13 & 0x08) tempbx |= 0x0400;
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,tempbx); /* CRT2 Vertical Retrace Start */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
- unsigned char cr8, cr7, cr13, cr9;
- if(SiS_Pr->UseCustomMode) {
- cr8 = SiS_Pr->CCRT1CRTC[8];
- cr7 = SiS_Pr->CCRT1CRTC[7];
- cr13 = SiS_Pr->CCRT1CRTC[13];
- cr9 = SiS_Pr->CCRT1CRTC[9];
- } else {
- cr8 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
- cr7 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
- cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
- cr9 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
- }
- tempbx = cr8;
- if(cr7 & 0x04) tempbx |= 0x0100;
- if(cr7 & 0x80) tempbx |= 0x0200;
- if(cr13 & 0x08) tempbx |= 0x0400;
- tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
- }
- }
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp); /* CRT2 Vertical Retrace Start */
-
- temp = ((tempbx & 0xFF00) >> 8) << 4;
- temp |= (tempcx & 0x000F);
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+ temp = ((tempbx >> 4) & 0x70) | (tempcx & 0x0F);
+ SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp); /* CRT2 Vert. Retrace End; Overflow */
- /* 3. Panel compensation delay */
+ /* 3. Panel delay compensation */
- if(HwInfo->jChipType < SIS_315H) {
+ if(HwInfo->jChipType < SIS_315H) {
#ifdef SIS300 /* ---------- 300 series -------------- */
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- temp = 0x20;
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ temp = 0x20;
+ if(HwInfo->jChipType == SIS_300) {
+ temp = 0x10;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) temp = 0x2c;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
+ }
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) temp = 0x20;
+ }
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x960) temp = 0x24;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) temp = 0x2c;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
+ else temp = 0x20;
+ }
+ if(SiS_Pr->SiS_UseROM) {
+ if(ROMAddr[0x220] & 0x80) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
+ temp = ROMAddr[0x221];
+ else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
+ temp = ROMAddr[0x222];
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024)
+ temp = ROMAddr[0x223];
+ else
+ temp = ROMAddr[0x224];
+ temp &= 0x3c;
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
+ }
- if(HwInfo->jChipType == SIS_300) {
- temp = 0x10;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
- }
- if(SiS_Pr->SiS_VBType & VB_SIS301) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
- }
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) temp = 0x2c;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x08;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
- else temp = 0x20;
- }
- if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
- if(ROMAddr[0x220] & 0x80) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision)
- temp = ROMAddr[0x221];
- else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision)
- temp = ROMAddr[0x222];
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
- temp = ROMAddr[0x223];
- else
- temp = ROMAddr[0x224];
- temp &= 0x3c;
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->PDC) {
- temp = SiS_Pr->PDC & 0x3c;
- }
- }
- } else {
- temp = 0x20;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
- }
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- if(ROMAddr[0x220] & 0x80) {
- temp = ROMAddr[0x220] & 0x3c;
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->PDC) {
- temp = SiS_Pr->PDC & 0x3c;
- }
- }
+ } else {
+ temp = 0x20;
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_640x480) temp = 0x04;
+ }
+ if(SiS_Pr->SiS_UseROM) {
+ if(ROMAddr[0x220] & 0x80) {
+ temp = ROMAddr[0x220] & 0x3c;
+ }
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->PDC != -1) temp = SiS_Pr->PDC & 0x3c;
}
+ }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
#endif /* SIS300 */
- } else {
+ } else {
#ifdef SIS315H /* --------------- 315/330 series ---------------*/
- if(HwInfo->jChipType < SIS_661) {
+ if(HwInfo->jChipType < SIS_661) {
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
-
- temp = 0x10;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) temp = 0x2c;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) temp = 0x24;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) temp = 0x2c;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- temp = 0x08;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) temp = 0x2c;
- else temp = 0x20;
- }
- }
- if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
- tempbl = 0x00;
- if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
- if(HwInfo->jChipType < SIS_330) {
- if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
- } else {
- if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0;
- }
- }
- } else { /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */
- tempbl = 0xF0;
- }
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(SiS_Pr->PDC) {
- temp = SiS_Pr->PDC;
- tempbl = 0;
- }
- }
- }
+ if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- } else { /* LVDS */
+ if(HwInfo->jChipType == SIS_740) temp = 0x03;
+ else temp = 0x00;
- if(HwInfo->jChipType == SIS_740) {
- temp = 0x03;
- } else {
- temp = 0x00;
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
- tempbl = 0xF0;
- if(HwInfo->jChipType == SIS_650) {
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
+ tempbl = 0xF0;
+ if(HwInfo->jChipType == SIS_650) {
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
}
+ }
- if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
- temp = 0x08;
- tempbl = 0;
- if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
- if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
- }
+ if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
+ temp = 0x08;
+ tempbl = 0;
+ if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
+ if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
}
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp); /* Panel Link Delay Compensation */
+ }
- } /* < 661 */
+ } /* < 661 */
- tempax = 0;
- if (modeflag & DoubleScanMode) tempax |= 0x80;
- if (modeflag & HalfDCLK) tempax |= 0x40;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
+ tempax = 0;
+ if(modeflag & DoubleScanMode) tempax |= 0x80;
+ if(modeflag & HalfDCLK) tempax |= 0x40;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
#endif /* SIS315H */
- }
-
- } /* Slavemode */
+ }
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ } /* Slavemode */
+ if(SiS_Pr->SiS_VBType & VB_SISVB) {
+ if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
/* For 301BDH with LCD, we set up the Panel Link */
- if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
-
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
- HwInfo, RefreshRateTableIndex);
-
- } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-
- SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex,
- HwInfo, RefreshRateTableIndex);
- }
-
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ }
+ } else {
+ if(HwInfo->jChipType < SIS_315H) {
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
} else {
-
- if(HwInfo->jChipType < SIS_315H) {
-
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
- HwInfo, RefreshRateTableIndex);
+ if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+ if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
+ }
} else {
-
- if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
- if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
- HwInfo,RefreshRateTableIndex);
- }
- } else {
- SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
- HwInfo,RefreshRateTableIndex);
- }
-
+ SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex, HwInfo,RefreshRateTableIndex);
}
-
}
- } /* LCDA */
+ }
}
/*********************************************/
static UCHAR *
SiS_GetGroup2CLVXPtr(SiS_Private *SiS_Pr, int tabletype, PSIS_HW_INFO HwInfo)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
const UCHAR *tableptr = NULL;
- USHORT a, b, p = 0;
+ USHORT a, b, p = 0;
a = SiS_Pr->SiS_VGAHDE;
b = SiS_Pr->SiS_HDE;
b = SiS_Pr->SiS_VDE;
}
- if((HwInfo->jChipType >= SIS_661) && (ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-
- if(a < b) {
- p = ROMAddr[0x278] | (ROMAddr[0x279] << 8);
- } else if(a == b) {
- p = ROMAddr[0x27a] | (ROMAddr[0x27b] << 8);
- } else {
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- p = ROMAddr[0x27e] | (ROMAddr[0x27f] << 8);
- } else {
- p = ROMAddr[0x27c] | (ROMAddr[0x27d] << 8);
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) p = ROMAddr[0x280] | (ROMAddr[0x281] << 8);
- else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) p = ROMAddr[0x282] | (ROMAddr[0x283] << 8);
- else p = ROMAddr[0x284] | (ROMAddr[0x285] << 8);
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- p = ROMAddr[0x286] | (ROMAddr[0x287] << 8);
- }
- do {
- if((ROMAddr[p] | ROMAddr[p+1] << 8) == a) break;
- p += 0x42;
- } while((ROMAddr[p] | ROMAddr[p+1] << 8) != 0xffff);
- if((ROMAddr[p] | ROMAddr[p+1] << 8) == 0xffff) p -= 0x42;
- }
- p += 2;
- return(&ROMAddr[p]);
-
+ if(a < b) {
+ tableptr = SiS_Part2CLVX_1;
+ } else if(a == b) {
+ tableptr = SiS_Part2CLVX_2;
} else {
-
- if(a < b) {
- tableptr = SiS_Part2CLVX_1;
- } else if(a == b) {
- tableptr = SiS_Part2CLVX_2;
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) {
+ tableptr = SiS_Part2CLVX_4;
} else {
- if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- tableptr = SiS_Part2CLVX_4;
- } else {
- tableptr = SiS_Part2CLVX_3;
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
- else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
- else tableptr = SiS_Part2CLVX_5;
-
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
- tableptr = SiS_Part2CLVX_6;
- }
- do {
- if((tableptr[p] | tableptr[p+1] << 8) == a) break;
- p += 0x42;
- } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
- if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
+ tableptr = SiS_Part2CLVX_3;
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) tableptr = SiS_Part2CLVX_3;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) tableptr = SiS_Part2CLVX_3;
+ else tableptr = SiS_Part2CLVX_5;
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ tableptr = SiS_Part2CLVX_6;
}
- p += 2;
- return((UCHAR *)&tableptr[p]);
+ do {
+ if((tableptr[p] | tableptr[p+1] << 8) == a) break;
+ p += 0x42;
+ } while((tableptr[p] | tableptr[p+1] << 8) != 0xffff);
+ if((tableptr[p] | tableptr[p+1] << 8) == 0xffff) p -= 0x42;
}
+ p += 2;
+ return((UCHAR *)&tableptr[p]);
}
-
static void
SiS_SetGroup2_C_ELV(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
}
-static void
+static BOOLEAN
SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
USHORT RefreshRateTableIndex,USHORT *CRT2Index,
USHORT *ResIndex,PSIS_HW_INFO HwInfo)
{
- USHORT tempbx,tempal;
+
+ if(HwInfo->jChipType < SIS_315H) return FALSE;
if(ModeNo <= 0x13)
- tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ (*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
else
- tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ (*ResIndex) = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- tempbx = SiS_Pr->SiS_LCDResInfo;
+ (*ResIndex) &= 0x3f;
+ (*CRT2Index) = 0;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
- else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
-
- if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- tempbx = 100;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 101;
- else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102;
- }
- } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
- tempbx = 103;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx = 104;
- else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 105;
- }
- }
- } else if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 106;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ (*CRT2Index) = 200;
}
}
- *CRT2Index = tempbx;
- *ResIndex = tempal & 0x3F;
+ if(SiS_Pr->SiS_CustomT == CUT_ASUSA2H_2) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) (*CRT2Index) = 206;
+ }
+ }
+ return(((*CRT2Index) != 0));
}
#endif
#ifdef SIS300
+static void
+SiS_Group2LCDSpecial(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT crt2crtc)
+{
+ USHORT tempcx;
+ const UCHAR atable[] = {
+ 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
+ 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
+ };
+
+ if(!SiS_Pr->UseCustomMode) {
+ if( ( ( (HwInfo->jChipType == SIS_630) ||
+ (HwInfo->jChipType == SIS_730) ) &&
+ (HwInfo->jChipRevision > 2) ) &&
+ (SiS_Pr->SiS_LCDResInfo == Panel_1024x768) &&
+ (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
+ (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+ if(ModeNo == 0x13) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+ } else {
+ if((crt2crtc & 0x3F) == 4) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
+ }
+ }
+ }
+
+ if(HwInfo->jChipType < SIS_315H) {
+ if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+ crt2crtc &= 0x1f;
+ tempcx = 0;
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ tempcx += 7;
+ }
+ }
+ tempcx += crt2crtc;
+ if(crt2crtc >= 4) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
+ }
+
+ if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+ if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+ if(crt2crtc == 4) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
+ }
+ }
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+ }
+ }
+ }
+}
+
/* For ECS A907. Highly preliminary. */
static void
SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750)) {
if(SiS_Pr->SiS_TVMode & TVSetPALM) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
} else {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x15);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14); /* 15 */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1a); /* 1b */
}
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
}
}
} else {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x21);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x5a);
+ if((ModeNo == 0x38) || (ModeNo == 0x4a) || (ModeNo == 0x64) ||
+ (ModeNo == 0x52) || (ModeNo == 0x58) || (ModeNo == 0x5c)) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 21 */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 5a */
+ } else {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1a); /* 21 */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x53); /* 5a */
+ }
+ }
+}
+
+static void
+SiS_SetGroup2_Tail(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+ USHORT temp;
+
+ if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+ if(SiS_Pr->SiS_VGAVDE == 525) {
+ temp = 0xc3;
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ temp++;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
+ } else if(SiS_Pr->SiS_VGAVDE == 420) {
+ temp = 0x4d;
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ temp++;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
+ }
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+ }
+ }
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+ SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x1a,0x03);
+ /* Not always for LV, see SetGrp2 */
+ }
+ temp = 1;
+ if(ModeNo <= 0x13) temp = 3;
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
+ }
+#if 0
+ /* 651+301C, for 1280x768 - do I really need that? */
+ if((SiS_Pr->SiS_PanelXRes == 1280) && (SiS_Pr->SiS_PanelYRes == 768)) {
+ if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+ if(((SiS_Pr->SiS_HDE == 640) && (SiS_Pr->SiS_VDE == 480)) ||
+ ((SiS_Pr->SiS_HDE == 320) && (SiS_Pr->SiS_VDE == 240))) {
+ SiS_SetReg(SiS_Part2Port,0x01,0x2b);
+ SiS_SetReg(SiS_Part2Port,0x02,0x13);
+ SiS_SetReg(SiS_Part2Port,0x04,0xe5);
+ SiS_SetReg(SiS_Part2Port,0x05,0x08);
+ SiS_SetReg(SiS_Part2Port,0x06,0xe2);
+ SiS_SetReg(SiS_Part2Port,0x1c,0x21);
+ SiS_SetReg(SiS_Part2Port,0x1d,0x45);
+ SiS_SetReg(SiS_Part2Port,0x1f,0x0b);
+ SiS_SetReg(SiS_Part2Port,0x20,0x00);
+ SiS_SetReg(SiS_Part2Port,0x21,0xa9);
+ SiS_SetReg(SiS_Part2Port,0x23,0x0b);
+ SiS_SetReg(SiS_Part2Port,0x25,0x04);
+ }
+ }
+ }
+#endif
}
}
SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
PSIS_HW_INFO HwInfo)
{
- USHORT i, j, tempax, tempbx, tempcx, temp;
- USHORT push1, push2, modeflag, crt2crtc;
- ULONG longtemp, tempeax;
+ USHORT i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
+ USHORT push2, modeflag, crt2crtc, bridgeoffset;
+ ULONG longtemp;
const UCHAR *PhasePoint;
const UCHAR *TimingPoint;
#ifdef SIS315H
USHORT resindex, CRT2Index;
const SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
-#endif
-#ifdef SIS300
- const UCHAR atable[] = {
- 0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
- 0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
- };
-#endif
-#ifdef SIS315H
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
#endif
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ crt2crtc = 0;
} else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- crt2crtc = 0;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
}
temp = 0;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempax = 950;
else if(SiS_Pr->SiS_TVMode & TVSetPAL) tempax = 520;
- else tempax = 440;
+ else tempax = 440; /* NTSC, YPbPr 525, 750 */
if( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision)) && (SiS_Pr->SiS_VDE <= tempax) ) ||
( (SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) &&
temp = tempax + (USHORT)TimingPoint[1];
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
- if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) && (SiS_Pr->SiS_VGAHDE >= 1024)) {
if(SiS_Pr->SiS_TVMode & TVSetPAL) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x52);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x1b); /* 19 */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x54); /* 52 */
} else {
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
tempcx--;
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx--;
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,temp);
- temp = (tempcx & 0xFF00) >> 8;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
-
- tempcx++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) tempcx++;
- tempcx >>= 1;
-
- push1 = tempcx;
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,tempcx);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,((tempcx >> 8) & 0x0f));
+ tempcx = SiS_Pr->SiS_HT >> 1;
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
tempcx += 7;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
- temp = (tempcx & 0x00FF) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,((tempcx << 4) & 0xf0));
- tempbx = TimingPoint[j] | ((TimingPoint[j+1]) << 8);
+ tempbx = TimingPoint[j] | (TimingPoint[j+1] << 8);
tempbx += tempcx;
-
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,temp);
- temp = ((tempbx & 0xFF00) >> 8) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,tempbx);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,((tempbx >> 4) & 0xf0));
tempbx += 8;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
tempbx -= 4;
tempcx = tempbx;
}
- temp = (tempbx & 0x00FF) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,((tempbx << 4) & 0xf0));
j += 2;
- tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,temp);
- temp = ((tempcx & 0xFF00) >> 8) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
+ tempcx += (TimingPoint[j] | (TimingPoint[j+1] << 8));
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,tempcx);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,((tempcx >> 4) & 0xf0));
tempcx += 8;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) tempcx -= 4;
- temp = (tempcx & 0x00FF) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,temp);
-
- tempcx = push1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2A,0x0F,((tempcx << 4) & 0xf0));
+ tempcx = SiS_Pr->SiS_HT >> 1;
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempcx >>= 1;
j += 2;
tempcx -= (TimingPoint[j] | ((TimingPoint[j+1]) << 8));
- temp = (tempcx & 0x00FF) << 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2D,0x0F,((tempcx << 4) & 0xf0));
tempcx -= 11;
if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
tempcx = SiS_GetVGAHT2(SiS_Pr) - 1;
}
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,tempcx);
tempbx = SiS_Pr->SiS_VDE;
- if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
- if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
- if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
- } else {
- if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
- (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
- tempbx >>= 1;
- if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
- if(ModeNo <= 0x13) {
- if(crt2crtc == 1) tempbx++;
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
+ if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
+ if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
+ } else if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
+ (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p|TVSetYPbPr750p))) ) {
+ tempbx >>= 1;
+ if(HwInfo->jChipType >= SIS_315H) {
+ if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
+ if((ModeNo <= 0x13) && (crt2crtc == 1)) tempbx++;
} else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(crt2crtc == 4) {
- if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+ if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+ if(crt2crtc == 4) tempbx++;
}
}
}
- }
- tempbx -= 2;
- temp = tempbx & 0x00FF;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
- }
- }
-
- if(HwInfo->jChipType < SIS_661) {
- /* From 1.10.7w - doesn't make sense */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) { /* SetFlag?? */
- if(ModeNo == 0x03) temp++;
- }
- }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) tempbx++;
+ }
+ if(!(SiS_Pr->SiS_TVMode & TVSetPAL)) {
+ if(ModeNo == 0x03) tempbx++; /* From 1.10.7w - doesn't make sense */
}
}
}
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,temp);
+ tempbx -= 2;
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,tempbx);
temp = (tempcx >> 8) & 0x0F;
- temp |= (((tempbx >> 8) << 6) & 0xC0);
- if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750 | SetCRT2ToSCART))) {
+ temp |= ((tempbx >> 2) & 0xC0);
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
temp |= 0x10;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO)) temp |= 0x20;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToAVIDEO) temp |= 0x20;
}
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
- if((HwInfo->jChipType > SIS_315H) && (HwInfo->jChipType < SIS_661)) {
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
- if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
- SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
- }
- }
+ if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xdf,((tempbx & 0x0400) >> 5));
+ }
+
+#if 0
+ /* TEST qqqq */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
+ for(i=0x01, j=0; i<=0x2D; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
+ }
+ for(i=0x39; i<=0x45; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
}
}
+#endif
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
tempbx = SiS_Pr->SiS_VDE;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) {
- tempbx >>= 1;
- }
+ if( (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) &&
+ (!(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p))) ) {
+ tempbx >>= 1;
}
tempbx -= 3;
- if(HwInfo->jChipType >= SIS_661) {
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) { /* Why not 301B/LV? */
- temp = 0;
- if(tempcx & 0x0400) temp |= 0x20;
- if(tempbx & 0x0400) temp |= 0x40;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x10,temp);
- }
- }
- tempbx &= 0x03ff;
- temp = ((tempbx & 0xFF00) >> 8) << 5;
- temp |= 0x18;
+ temp = ((tempbx >> 3) & 0x60) | 0x18;
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,tempbx);
+ if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302LV | VB_SIS302ELV)) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,0xbf,((tempbx & 0x0400) >> 4));
+ }
}
tempbx = 0;
if(!(modeflag & HalfDCLK)) {
if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
tempax = 0;
- tempbx |= 0x2000;
+ tempbx |= 0x20;
}
}
- tempcx = 0x0101;
+ tempch = tempcl = 0x01;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
if(SiS_Pr->SiS_VGAHDE >= 1024) {
if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
- tempcx = 0x1920;
+ tempch = 0x19;
+ tempcl = 0x20;
if(SiS_Pr->SiS_VGAHDE >= 1280) {
- tempcx = 0x1420;
- tempbx &= ~0x2000;
+ tempch = 0x14;
+ tempbx &= ~0x20;
}
}
}
}
- if(!(tempbx & 0x2000)) {
- if(modeflag & HalfDCLK) {
- tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
- }
- longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
- longtemp <<= 13;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- longtemp <<= 3;
- }
- tempeax = longtemp / SiS_Pr->SiS_HDE;
- if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
- tempax = (USHORT)tempeax;
- tempbx |= (tempax & 0x1F00);
- tempcx = (tempax & 0xFF00) >> (8 + 5);
+ if(!(tempbx & 0x20)) {
+ if(modeflag & HalfDCLK) tempcl <<= 1;
+ longtemp = ((SiS_Pr->SiS_VGAHDE * tempch) / tempcl) << 13;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) longtemp <<= 3;
+ tempax = longtemp / SiS_Pr->SiS_HDE;
+ if(longtemp % SiS_Pr->SiS_HDE) tempax++;
+ tempbx |= ((tempax >> 8) & 0x1F);
+ tempcx = tempax >> 13;
}
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,tempax);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,(tempbx >> 8));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,tempbx);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- temp = tempcx & 0x0007;
- if(tempbx & 0x2000) temp = 0;
- if((HwInfo->jChipType < SIS_661) || (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD))) {
- temp |= 0x18;
- }
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+ tempcx &= 0x07;
+ if(tempbx & 0x20) tempcx = 0;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xF8,tempcx);
if(SiS_Pr->SiS_TVMode & TVSetPAL) {
tempbx = 0x0382;
tempbx = 0x0369;
tempcx = 0x0061;
}
- temp = (tempbx & 0x00FF) ;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,temp);
- temp = (tempcx & 0x00FF) ;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,temp);
- temp = (tempcx & 0x0300) >> (8 - 2);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,tempbx);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,tempcx);
+ temp = (tempcx & 0x0300) >> 6;
temp |= ((tempbx >> 8) & 0x03);
if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
temp |= 0x10;
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(temp - 3));
SiS_SetTVSpecial(SiS_Pr, ModeNo);
if(SiS_Pr->SiS_TVMode & TVSetPALM) {
if(!(SiS_Pr->SiS_TVMode & TVSetNTSC1024)) {
temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,(temp - 1));
}
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
}
tempbx = SiS_Pr->SiS_HDE;
if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
tempbx--; /* RHACTE = HDE - 1 */
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,temp);
- temp = (tempbx & 0xFF00) >> 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,tempbx);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,((tempbx >> 4) & 0xf0));
temp = 0x01;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
if(SiS_Pr->SiS_ModeType == ModeEGA) {
if(SiS_Pr->SiS_VGAHDE >= 1024) {
temp = 0x02;
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
tempbx = SiS_Pr->SiS_VDE - 1;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,temp);
- temp = ((tempbx & 0xFF00) >> 8) & 0x07;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,tempbx);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,((tempbx >> 8) & 0x07));
tempcx = SiS_Pr->SiS_VT - 1;
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,temp);
-
- temp = ((tempcx & 0xFF00) >> 8) << 5;
-
- /* Enable dithering; only do this for 32bpp mode */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,tempcx);
+ temp = (tempcx >> 3) & 0xE0;
if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+ /* Enable dithering; only do this for 32bpp mode */
if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
temp |= 0x10;
}
}
-
- /* Must do special for Compaq1280; Acer1280 OK, Clevo1400 OK, COMPAL1400 OK */
- /* Compaq1280 panel loses sync if using CR37 sync info. */
- if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
- if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) {
- if(SiS_Pr->SiS_LCDInfo & LCDSync) {
- temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
- }
- } else if((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)) {
- temp |= 0x03;
- } else {
- temp |= (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) >> 6);
- temp |= 0x08;
- if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04;
- }
- } else {
- if(SiS_Pr->SiS_LCDInfo & LCDSync) {
- temp |= ((SiS_Pr->SiS_LCDInfo & 0xc0) >> 6);
- }
- }
- }
-
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1A,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1A,0x0f,temp);
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
-#if 0 /* Use the 315/330 series code for now */
- if((HwInfo->jChipType >= SIS_661) &&
- (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
- (ROMAddr && SiS_Pr->SiS_UseROM)) {
-
- /* This is done for the LVDS bridges only, since
- * the TMDS panels already work correctly with
- * the old code. Besides, we only do that if
- * we can get the data from the ROM, I am tired
- * of carrying a lot of tables around.
- */
-
-#ifdef SIS315H /* ------------ 661/741/760 series --------- */
- UCHAR *myptr = NULL, myptr1 = NULL;
-
- myptr = (UCHAR *)GetLCDPtr661(SiS_Pr, HwInfo, 6, ModeNo, ModeIdIndex, RefreshRateTableIndex);
- myptr1 = (UCHAR *)GetLCDStructPtr661(SiS_Pr, HwInfo);
-
- tempbx = (myptr[3] | (myptr[4] << 8)) & 0x0fff;
- tempcx = SiS_Pr->PanelYRes;
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- tempcx = SiS_Pr->SiS_VDE;
- }
-
- tempcx += tempbx;
- if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
-
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempbx);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempcx);
-
- tempcx &= 0x07ff;
- tempbx &= 0x07ff;
- temp = (tempcx >> 8) << 3;
- temp |= (tempbx >> 8);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
-
- tempbx = (myptr[4] | (myptr[5] << 8)) >> 4;
- tempcx = myptr1[6];
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = myptr[7];
-
- tempcx += tempbx;
- if(tempcx >= SiS_Pr->SiS_VT) tempcx -= SiS_Pr->SiS_VT;
-
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx);
- temp = tempcx & 0x000f;
- temp |= ((tempbx & 0x0f00) >> 4);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
-
- tempax = SiS_Pr->SiS_HT;
- tempbx = (myptr[0] | (myptr[1] << 8)) & 0x0fff;
- tempcx = SiS_Pr->PanelXRes;
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempcx = SiS_Pr->SiS_HDE;
-
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
- tempax >>= 1;
- tempbx >>= 1;
- tempcx >>= 1;
- }
- if(SiS_Pr->SiS_VBType & VB_SIS302LV) tempbx++;
- if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) tempbx++;
-
- tempcx += tempbx;
- if(tempcx >= tempax) tempcx -= tempax;
-
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,tempbx);
- temp = ((tempbx & 0xff00) >> 8) << 4;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,temp);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempcx);
- temp = tempcx >> 8;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x25,temp);
-
- tempax = SiS_Pr->SiS_HT;
- tempbx = (myptr[1] | (myptr[2] << 8)) >> 4;
- tempcx = myptr1[5];
- if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
- tempcx = myptr[6];
- }
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
- tempax >>= 1;
- tempbx >>= 1;
- tempcx >>= 1;
- }
- if(SiS_Pr->SiS_VBType & VB_SIS302LV) tempbx++;
-
- tempcx += tempbx;
- if(tempcx >= tempax) tempcx -= tempax;
-
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,tempbx);
- temp = (tempbx & 0x0f00) >> 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1d,0x0f,temp);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempcx);
-
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(SiS_Pr->SiS_VGAVDE == 525) {
- temp = 0xc3;
- if(SiS_Pr->SiS_ModeType <= ModeVGA) {
- temp++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
- } else if(SiS_Pr->SiS_VGAVDE == 420) {
- temp = 0x4d;
- if(SiS_Pr->SiS_ModeType <= ModeVGA) {
- temp++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
- }
- }
-
-#endif
-
- } else
-#endif
- if((HwInfo->jChipType >= SIS_315H) &&
- (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
- ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) {
-
-#ifdef SIS315H /* ------------- 315/330 series ------------ */
-
- SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &CRT2Index, &resindex, HwInfo);
-
+#ifdef SIS315H
+ if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ &CRT2Index, &resindex, HwInfo)) {
switch(CRT2Index) {
- case Panel_1024x768 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break; /* "Normal" */
- case Panel_1280x1024 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_1; break;
- case Panel_1400x1050 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_1; break;
- case Panel_1600x1200 : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_1; break;
- case Panel_1024x768 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2; break; /* Non-Expanding */
- case Panel_1280x1024 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_2; break;
- case Panel_1400x1050 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_2; break;
- case Panel_1600x1200 + 16: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_2; break;
- case Panel_1024x768 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break; /* VESA Timing */
- case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
- case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
- case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
- case 100: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break; /* Custom */
- case 101: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break;
- case 102: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break;
- case 103: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_1; break; /* Custom */
- case 104: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_2; break;
- case 105: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_3; break;
- case 106: CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Asus1024x768_3; break;
- default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
+ case 200: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1; break;
+ case 206: CRT2Part2Ptr = SiS310_CRT2Part2_Asus1024x768_3; break;
+ default: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3; break;
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(SiS_Pr->SiS_VGAVDE == 525) {
- temp = 0xc3;
- if(SiS_Pr->SiS_ModeType <= ModeVGA) {
- temp++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
- } else if(SiS_Pr->SiS_VGAVDE == 420) {
- temp = 0x4d;
- if(SiS_Pr->SiS_ModeType <= ModeVGA) {
- temp++;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
- }
- }
-
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- /* See Sync above, 0x1a */
- temp = 1;
- if(ModeNo <= 0x13) temp = 3;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
- }
- }
-#endif
+ SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
- } else { /* ------ 300 series and other bridges, other LCD resolutions ------ */
- /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) makes
- * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding,
- * the bridge scales all modes to 1024.
- * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
- */
+ } else {
+#endif
- tempcx = SiS_Pr->SiS_VT;
- tempbx = SiS_Pr->PanelYRes;
+ /* Checked for 1024x768, 1280x1024, 1400x1050, 1600x1200 */
+ /* Clevo dual-link 1024x768 */
+ /* Compaq 1280x1024 has HT 1696 sometimes (calculation OK, if given HT is correct) */
+ /* Acer: OK, but uses different setting for VESA timing at 640/800/1024 and 640x400 */
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- tempbx = SiS_Pr->SiS_VDE - 1;
- tempcx--;
- }
-
- tempax = 1;
- if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
- if(tempbx != SiS_Pr->SiS_VDE) {
- tempax = tempbx;
- if(tempax < SiS_Pr->SiS_VDE) {
- tempax = 0;
- tempcx = 0;
+ if((SiS_Pr->SiS_LCDInfo & LCDPass11) || (SiS_Pr->PanelYRes == SiS_Pr->SiS_VDE)) {
+ tempbx = SiS_Pr->SiS_VDE - 1;
+ tempcx = SiS_Pr->SiS_VT - 1;
+ } else {
+ tempbx = SiS_Pr->SiS_VDE + ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
+ tempcx = SiS_Pr->SiS_VT - ((SiS_Pr->PanelYRes - SiS_Pr->SiS_VDE) / 2);
+ }
+ } else {
+ tempbx = SiS_Pr->PanelYRes;
+ tempcx = SiS_Pr->SiS_VT;
+ tempax = 1;
+ if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
+ tempax = SiS_Pr->PanelYRes;
+ /* if(SiS_Pr->SiS_VGAVDE == 525) tempax += 0x3c; */ /* 651+301C */
+ if(SiS_Pr->PanelYRes < SiS_Pr->SiS_VDE) {
+ tempax = tempcx = 0;
} else {
tempax -= SiS_Pr->SiS_VDE;
}
tempbx -= tempax; /* lcdvdee */
}
- /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
+ /* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
#endif
- temp = tempcx & 0x00FF; /* RVEQ1EQ=lcdvdes */
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,temp);
- temp = tempbx & 0x00FF; /* RVEQ2EQ=lcdvdee */
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
- temp = ((tempbx & 0xFF00) >> 8) << 3;
- temp |= ((tempcx & 0xFF00) >> 8);
+ temp = (tempbx >> 5) & 0x38;
+ temp |= ((tempcx >> 8) & 0x07);
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
- tempbx = SiS_Pr->SiS_VT; /* push2; */
- tempax = SiS_Pr->SiS_VDE; /* push1; */
- tempcx = (tempbx - tempax) >> 4;
- tempbx += tempax;
- tempbx >>= 1;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx -= 10;
+ tempax = SiS_Pr->SiS_VDE;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ tempax = SiS_Pr->PanelYRes;
+ }
+ tempcx = (SiS_Pr->SiS_VT - tempax) >> 4;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
+ tempcx = (SiS_Pr->SiS_VT - tempax) / 10;
+ }
+ }
+
+ tempbx = ((SiS_Pr->SiS_VT + SiS_Pr->SiS_VDE) >> 1) - 1;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(SiS_Pr->PanelYRes != SiS_Pr->SiS_VDE) {
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { /* ? */
+ tempax = SiS_Pr->SiS_VT - SiS_Pr->PanelYRes;
+ if(tempax % 4) { tempax >>= 2; tempax++; }
+ else { tempax >>= 2; }
+ tempbx -= (tempax - 1);
+ } else {
+ tempbx -= 10;
+ if(tempbx <= SiS_Pr->SiS_VDE) tempbx = SiS_Pr->SiS_VDE + 1;
+ }
+ }
+ }
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
+ tempbx++;
+ if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (crt2crtc == 6)) {
+ if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+ tempbx = 770;
+ tempcx = 3;
+ }
+ }
+ }
- /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
+ /* non-expanding: lcdvrs = ((VT + VDE) / 2) - 10 */
if(SiS_Pr->UseCustomMode) {
tempbx = SiS_Pr->CVSyncStart;
xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
#endif
- temp = tempbx & 0x00FF; /* RTVACTEE = lcdvrs */
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
- temp = ((tempbx & 0xFF00) >> 8) << 4;
+ temp = (tempbx >> 4) & 0xF0;
tempbx += (tempcx + 1);
- temp |= (tempbx & 0x000F);
+ temp |= (tempbx & 0x0F);
if(SiS_Pr->UseCustomMode) {
temp &= 0xf0;
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
- /* Code from 630/301B (I+II) BIOS */
-
#ifdef SIS300
- if(!SiS_Pr->UseCustomMode) {
- if( ( ( (HwInfo->jChipType == SIS_630) ||
- (HwInfo->jChipType == SIS_730) ) &&
- (HwInfo->jChipRevision > 2) ) &&
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
- (!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) &&
- (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
- if(ModeNo == 0x13) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
- } else {
- if((crt2crtc & 0x3F) == 4) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
- }
- }
- }
+ SiS_Group2LCDSpecial(SiS_Pr, HwInfo, ModeNo, crt2crtc);
+#endif
- if(HwInfo->jChipType < SIS_315H) {
- if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
- crt2crtc &= 0x1f;
- tempcx = 0;
- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- tempcx += 7;
- }
- }
- tempcx += crt2crtc;
- if(crt2crtc >= 4) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
- }
+ bridgeoffset = 7;
+ if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) bridgeoffset += 2;
+ if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) bridgeoffset++;
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) bridgeoffset++;
- if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
- if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
- if(crt2crtc == 4) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
- }
- }
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
- }
+ temp = 0;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
+ temp = SiS_Pr->SiS_HT - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp >>= 1;
}
}
-#endif
-
- tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2; /* (HT - HDE) >> 2 */
- tempbx = SiS_Pr->SiS_HDE + 7; /* lcdhdee */
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- tempbx += 2;
+ temp += bridgeoffset;
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* lcdhdes */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0F,((temp >> 4) & 0xf0));
+
+ tempcx = SiS_Pr->SiS_HT;
+ tempax = tempbx = SiS_Pr->SiS_HDE;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) {
+ tempax = SiS_Pr->PanelXRes;
+ tempbx = SiS_Pr->PanelXRes - ((SiS_Pr->PanelXRes - SiS_Pr->SiS_HDE) / 2);
+ }
+ }
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+ tempcx >>= 1;
+ tempbx >>= 1;
+ tempax >>= 1;
}
- push1 = tempbx;
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
#endif
- temp = tempbx & 0x00FF; /* RHEQPLE = lcdhdee */
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,temp);
- temp = (tempbx & 0xFF00) >> 8;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
+ tempbx += bridgeoffset;
- temp = 7;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- temp += 2;
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp); /* RHBLKE = lcdhdes[7:0] */
- SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F); /* lcdhdes [11:8] */
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,((tempbx >> 8) & 0x0f));
+
+ tempcx = (tempcx - tempax) >> 2;
tempbx += tempcx;
push2 = tempbx;
- if(SiS_Pr->UseCustomMode) {
- tempbx = SiS_Pr->CHSyncStart + 7;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- tempbx += 2;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ if(SiS_Pr->SiS_HDE == 1280) tempbx = (tempbx & 0xff00) | 0x47;
+ }
}
}
+ if(SiS_Pr->UseCustomMode) {
+ tempbx = SiS_Pr->CHSyncStart;
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ tempbx += bridgeoffset;
+ }
+
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
#endif
- temp = tempbx & 0x00FF; /* RHBURSTS = lcdhrs */
- if(!SiS_Pr->UseCustomMode) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
- if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
- }
- }
- }
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,temp);
- temp = (tempbx & 0x0F00) >> 4;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
tempbx = push2;
+
tempcx <<= 1;
+ if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ if(SiS_Pr->PanelXRes != SiS_Pr->SiS_HDE) tempcx >>= 2;
+ }
tempbx += tempcx;
if(SiS_Pr->UseCustomMode) {
- tempbx = SiS_Pr->CHSyncEnd + 7;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- tempbx += 2;
- }
+ tempbx = SiS_Pr->CHSyncEnd;
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+ tempbx += bridgeoffset;
}
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
#endif
- temp = tempbx & 0x00FF; /* RHSYEXP2S = lcdhre */
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,temp);
-
- if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
- if(SiS_Pr->SiS_VGAVDE == 525) {
- if(SiS_Pr->SiS_ModeType <= ModeVGA)
- temp=0xC6;
- else
- temp=0xC3;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xB3);
- } else if(SiS_Pr->SiS_VGAVDE == 420) {
- if(SiS_Pr->SiS_ModeType <= ModeVGA)
- temp=0x4F;
- else
- temp=0x4D;
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
- }
- }
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
+
+ SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
#ifdef SIS300
- SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex,
- RefreshRateTableIndex, ModeNo);
+ SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex, RefreshRateTableIndex, ModeNo);
+#endif
+#ifdef SIS315H
+ } /* CRT2-LCD from table */
#endif
-
- } /* HwInfo */
}
/*********************************************/
SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
PSIS_HW_INFO HwInfo)
{
- USHORT modeflag, i;
- const UCHAR *tempdi;
+ USHORT i;
+ const UCHAR *tempdi;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
- if(ModeNo<=0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
- }
-
#ifndef SIS_CP
SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
-#endif
-
-#ifdef SIS_CP
+#else
SIS_CP_INIT301_CP
#endif
tempdi = SiS_Pr->SiS_HiTVGroup3Data;
if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) {
tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
-#if 0
- if(!(modeflag & Charx8Dot)) {
- tempdi = SiS_Pr->SiS_HiTVGroup3Text;
- }
-#endif
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToYPbPr525750) {
if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
}
}
if(tempdi) {
- for(i=0; i<=0x3E; i++){
+ for(i=0; i<=0x3E; i++) {
SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
}
if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV)) {
}
}
- if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) {
#ifdef SIS_CP
- SIS_CP_INIT301_CP2
+ SIS_CP_INIT301_CP2
#endif
- }
}
/*********************************************/
#ifdef SIS315H
static void
-SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+SiS_ShiftXPos(SiS_Private *SiS_Pr, int shift)
{
- USHORT temp, temp1;
+ USHORT temp, temp1, temp2;
- if(!(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS302ELV))) return;
+ temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x1f);
+ temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x20);
+ temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x20,0x0f,((temp >> 4) & 0xf0));
+ temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x2b) & 0x0f;
+ temp = (USHORT)((int)(temp) + shift);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2b,0xf0,(temp & 0x0f));
+ temp1 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
+ temp2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x42);
+ temp = (USHORT)((int)((temp1 | ((temp2 & 0xf0) << 4))) + shift);
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x42,0x0f,((temp >> 4) & 0xf0));
+}
+
+static void
+SiS_SetGroup4_C_ELV(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+ USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT temp, temp1, resinfo = 0;
+
+ if(!(SiS_Pr->SiS_VBType & VB_SIS301C)) return;
+ if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToHiVision | SetCRT2ToYPbPr525750))) return;
+
+ if(ModeNo > 0x13) {
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x3a,0x08);
temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x3a);
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x25,0xf8);
}
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0xfb);
- temp = 0;
- if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr750p)) {
- temp |= 0x0002;
- if(!(SiS_Pr->SiS_TVMode & TVSetYPbPr525p)) {
- temp ^= 0x0402;
- if(!(SiS_Pr->SiS_TVMode & TVSetHiVision)) {
- temp ^= 0x0002;
- }
- }
- }
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) temp = 0x0000;
+ else if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) temp = 0x0002;
+ else if(SiS_Pr->SiS_TVMode & TVSetHiVision) temp = 0x0400;
+ else temp = 0x0402;
if(HwInfo->jChipType >= SIS_661) {
- temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x39);
- if(temp1 & 0x01) temp |= 0x10;
- if(temp1 & 0x02) temp |= 0x01;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xec,(temp & 0xff));
+ temp1 = 0;
+ if(SiS_Pr->SiS_TVMode & TVAspect43) temp1 = 4;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0f,0xfb,temp1);
+ if(SiS_Pr->SiS_TVMode & TVAspect43LB) temp |= 0x01;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0x7c,(temp & 0xff));
} else {
temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x3b) & 0x03;
if(temp1 == 0x01) temp |= 0x01;
if(temp1 == 0x03) temp |= 0x04; /* ? why not 0x10? */
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xea,(temp & 0xff));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xf8,(temp & 0xff));
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x3a,0xfb,(temp >> 8));
+
+ if(HwInfo->jChipType >= SIS_661) { /* ? */
+ if(SiS_Pr->SiS_TVMode & TVAspect43) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) {
+ if(resinfo == SIS_RI_1024x768) {
+ SiS_ShiftXPos(SiS_Pr, 97);
+ } else {
+ SiS_ShiftXPos(SiS_Pr, 111);
+ }
+ } else if(SiS_Pr->SiS_TVMode & TVSetHiVision) {
+ SiS_ShiftXPos(SiS_Pr, 136);
+ }
+ }
+ }
}
}
#endif
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
}
-/* Set 301 VGA2 registers */
static void
SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
{
- USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
+ USHORT tempax,tempcx,tempbx,modeflag,temp,resinfo;
ULONG tempebx,tempeax,templong;
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+ } else if(SiS_Pr->UseCustomMode) {
+ modeflag = SiS_Pr->CModeFlag;
+ resinfo = 0;
} else {
- if(SiS_Pr->UseCustomMode) {
- modeflag = SiS_Pr->CModeFlag;
- resinfo = 0;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
+ modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
}
if(HwInfo->jChipType >= SIS_315H) {
if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
}
-#ifdef SET_EMI
+
if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
}
-#endif
}
return;
}
}
- temp = SiS_Pr->SiS_RVBHCFACT;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,SiS_Pr->SiS_RVBHCFACT);
tempbx = SiS_Pr->SiS_RVBHCMAX;
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,tempbx);
- temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
+ temp = (tempbx >> 1) & 0x80;
tempcx = SiS_Pr->SiS_VGAHT - 1;
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,tempcx);
- temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
- temp2 |= temp;
+ temp |= ((tempcx >> 5) & 0x78);
tempcx = SiS_Pr->SiS_VGAVT - 1;
- if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
-
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,temp);
+ if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempcx -= 5;
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,tempcx);
- temp = temp2 | ((tempcx & 0xFF00) >> 8);
+ temp |= ((tempcx >> 8) & 0x07);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
tempbx = SiS_Pr->SiS_VGAHDE;
- if(modeflag & HalfDCLK) tempbx >>= 1;
- if(HwInfo->jChipType >= SIS_661) {
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
- }
+ if(modeflag & HalfDCLK) tempbx >>= 1;
+ if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
- temp = 0xA0;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
temp = 0;
- if(tempbx > 800) {
- temp = 0xA0;
- if(tempbx != 1024) {
- temp = 0xC0;
- if(tempbx != 1280) temp = 0;
- }
- }
- } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(tempbx <= 800) {
- temp = 0x80;
- }
+ if(tempbx > 800) temp = 0x60;
+ } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
+ temp = 0;
+ if(tempbx == 1024) temp = 0xA0;
+ else if(tempbx > 1024) temp = 0xC0;
+ } else if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
+ temp = 0;
+ if(tempbx >= 1280) temp = 0x40;
+ else if(tempbx >= 1024) temp = 0x20;
} else {
temp = 0x80;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- temp = 0;
- if(tempbx > 800) temp = 0x60;
- }
- }
-
- if(SiS_Pr->SiS_TVMode & (TVSetYPbPr525p | TVSetYPbPr750p)) {
- temp = 0;
- if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
- }
-
- if(HwInfo->jChipType < SIS_661) {
- if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp = 0;
+ if(tempbx >= 1024) temp = 0xA0;
}
if(SiS_Pr->SiS_VBType & VB_SIS301) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
- temp |= 0x0A;
+ if(SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) temp |= 0x0A;
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0E,0x10,temp);
+ tempeax = SiS_Pr->SiS_VGAVDE;
tempebx = SiS_Pr->SiS_VDE;
-
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
if(!(temp & 0xE0)) tempebx >>=1;
}
tempcx = SiS_Pr->SiS_RVBHRS;
- temp = tempcx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,temp);
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,tempcx);
+ tempcx >>= 8;
+ tempcx |= 0x40;
- tempeax = SiS_Pr->SiS_VGAVDE;
- tempcx |= 0x4000;
if(tempeax <= tempebx) {
- tempcx ^= 0x4000;
+ tempcx ^= 0x40;
} else {
tempeax -= tempebx;
}
- templong = (tempeax * 256 * 1024) % tempebx;
- tempeax = (tempeax * 256 * 1024) / tempebx;
- tempebx = tempeax;
- if(templong != 0) tempebx++;
+ tempeax *= (256 * 1024);
+ templong = tempeax % tempebx;
+ tempeax /= tempebx;
+ if(templong) tempeax++;
- temp = (USHORT)(tempebx & 0x000000FF);
+ temp = (USHORT)(tempeax & 0x000000FF);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
- temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+ temp = (USHORT)((tempeax & 0x0000FF00) >> 8);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
-
- tempbx = (USHORT)(tempebx >> 16);
- temp = tempbx & 0x00FF;
- temp <<= 4;
- temp |= ((tempcx & 0xFF00) >> 8);
+ temp = (USHORT)((tempeax >> 12) & 0x70); /* sic! */
+ temp |= (tempcx & 0x4F);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
+ /* Calc Linebuffer max address and set/clear decimode */
tempbx = 0;
+ if(SiS_Pr->SiS_TVMode & (TVSetHiVision | TVSetYPbPr750p)) tempbx = 0x08;
tempax = SiS_Pr->SiS_VGAHDE;
- if(modeflag & HalfDCLK) tempax >>= 1;
+ if(modeflag & HalfDCLK) tempax >>= 1;
if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- if(tempax > 800) tempax -= 800;
- } else {
- if(tempax > 800) {
- tempbx = 8;
- if(tempax == 1024)
- tempax *= 25;
- else
- tempax *= 20;
-
+ if(tempax > 800) {
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ tempax -= 800;
+ } else { /* 651+301C: Only if TVNoHiviNoYPbPr */
+ tempbx = 0x08;
+ if(tempax == 1024) tempax *= 25;
+ else tempax *= 20;
temp = tempax % 32;
- tempax /= 32;
- tempax--;
- if (temp!=0) tempax++;
- }
+ tempax /= 32;
+ if(temp) tempax++;
+ tempax++;
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToTVNoYPbPrHiVision) ||
+ (SiS_Pr->SiS_TVMode & TVSetYPbPr525i)) {
+ if(resinfo == SIS_RI_1024x768) {
+ /* Otherwise white line at right edge */
+ tempax = (tempax & 0xff00) | 0x20;
+ }
+ }
+ }
}
tempax--;
- temp = ((tempax & 0xFF00) >> 8) & 0x03;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* From 1.10.7w */
- if(ModeNo > 0x13) { /* From 1.10.7w */
- if(resinfo == SIS_RI_1024x768) tempax = 0x1f; /* From 1.10.7w */
- } /* From 1.10.7w */
- } /* From 1.10.7w */
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
- temp <<= 4;
- temp |= tempbx;
+ temp = ((tempax >> 4) & 0x30) | tempbx;
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax);
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
- if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
- if(IS_SIS550650740660) {
- temp = 0x0026; /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
- } else {
- temp = 0x0036;
- }
- } else {
- temp = 0x0036;
+ temp = 0x0036; tempbx = 0xD0;
+ if((IS_SIS550650740660) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+ temp = 0x0026; tempbx = 0xC0; /* See En/DisableBridge() */
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
if(!(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetHiVision | TVSetYPbPr750p | TVSetYPbPr525p))) {
temp |= 0x01;
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
if(!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
- temp &= 0xFE;
+ temp &= ~0x01;
}
}
}
}
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,tempbx,temp);
- tempbx = SiS_Pr->SiS_HT;
+ tempbx = SiS_Pr->SiS_HT >> 1;
if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
- tempbx >>= 1;
tempbx -= 2;
- temp = ((tempbx & 0x0700) >> 8) << 3;
+ SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,tempbx);
+ temp = (tempbx >> 5) & 0x38;
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
- temp = tempbx & 0x00FF;
- SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,temp);
if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
}
}
-#ifdef SET_EMI
if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
}
-#endif
}
} /* 301B */
/* SET PART 5 REGISTER GROUP */
/*********************************************/
-/* Set 301 Palette address port registers */
static void
SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
PSIS_HW_INFO HwInfo)
if(SiS_Pr->SiS_ModeType == ModeVGA) {
if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))) {
- SiS_EnableCRT2(SiS_Pr);
+ SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
}
}
USHORT ResIndex,DisplayType;
const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
- if(ModeNo <= 0x13) {
- modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
+ if(ModeNo <= 0x13) modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
(SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
return;
if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
- &ResIndex, &DisplayType))) return;
+ &ResIndex, &DisplayType))) {
+ return;
+ }
if(HwInfo->jChipType < SIS_315H) {
if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
switch(DisplayType) {
case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1; break;
- case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
- case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
- case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
- case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
- case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
- case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
- case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
- case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
- case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
- case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
+ case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H; break;
+ case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2; break;
+ case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H; break;
+ case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
+ case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H; break;
+ case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2; break;
+ case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H; break;
+ case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1; break;
+ case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H; break;
+ case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2; break;
case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H; break;
case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1; break;
case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H; break;
default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1; break;
}
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f); /*unlock cr0-7 */
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
tempah <<= 5;
if(modeflag & DoubleScanMode) tempah |= 0x080;
SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
-
- /* 650/LVDS BIOS - doesn't make sense */
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- if(modeflag & HalfDCLK)
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
- }
}
/*********************************************/
USHORT clkbase, vclkindex=0;
UCHAR sr2b, sr2c;
- if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+ if((SiS_Pr->SiS_LCDResInfo == Panel_640x480) || (SiS_Pr->SiS_LCDInfo & LCDPass11)) {
SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
RefreshRateTableIndex--;
sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x220] & 0x01) {
sr2b = ROMAddr[0x227];
sr2c = ROMAddr[0x228];
}
}
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
USHORT RefreshRateTableIndex)
{
- USHORT temp, tempbx, tempcl;
+#if defined(SIS300) || defined(SIS315H)
+ USHORT temp, tempbx;
+#endif
+ USHORT tempcl;
USHORT TVType, resindex;
const SiS_CHTVRegDataStruct *CHTVRegData = NULL;
if(ModeNo <= 0x13)
- tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ tempcl = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
else
- tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ tempcl = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
TVType = 0;
if(SiS_Pr->SiS_TVMode & TVSetCHOverScan) TVType += 1;
}
}
switch(TVType) {
- case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
- case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
- case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
- case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
- case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
- case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
- case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
- case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
- case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
- default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
+ case 0: CHTVRegData = SiS_Pr->SiS_CHTVReg_UNTSC; break;
+ case 1: CHTVRegData = SiS_Pr->SiS_CHTVReg_ONTSC; break;
+ case 2: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPAL; break;
+ case 3: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
+ case 4: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALM; break;
+ case 5: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALM; break;
+ case 6: CHTVRegData = SiS_Pr->SiS_CHTVReg_UPALN; break;
+ case 7: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPALN; break;
+ case 8: CHTVRegData = SiS_Pr->SiS_CHTVReg_SOPAL; break;
+ default: CHTVRegData = SiS_Pr->SiS_CHTVReg_OPAL; break;
}
resindex = tempcl & 0x3F;
/* Set up Power up/down timing */
if(HwInfo->jChipType == SIS_740) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
else tableptr = table1024_740;
- } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+ } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
else tableptr = table1400_740;
} else return;
} else {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
tableptr = table1024_650;
- } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
- (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+ } else if((SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) ||
+ (SiS_Pr->SiS_LCDResInfo == Panel_1600x1200)) {
tableptr = table1400_650;
} else return;
}
int i;
if(HwInfo->jChipType == SIS_740) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- tableptr = table1024_740;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- tableptr = table1280_740;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- tableptr = table1400_740;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- tableptr = table1600_740;
- } else return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_740;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_740;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_740;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_740;
+ else return;
} else {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
- tableptr = table1024_650;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
- tableptr = table1280_650;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
- tableptr = table1400_650;
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
- tableptr = table1600_650;
- } else return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) tableptr = table1024_650;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) tableptr = table1280_650;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) tableptr = table1400_650;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) tableptr = table1600_650;
+ else return;
}
tempbh = SiS_GetCH701x(SiS_Pr,0x74);
if((tempbh == 0xf6) || (tempbh == 0xc7)) {
tempbh = SiS_GetCH701x(SiS_Pr,0x73);
if(tempbh == 0xc8) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) return;
} else if(tempbh == 0xdb) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) return;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) return;
} else if(tempbh == 0xde) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) return;
}
}
- if(HwInfo->jChipType == SIS_740) {
- tempbh = 0x0d;
- } else {
- tempbh = 0x0c;
- }
+ if(HwInfo->jChipType == SIS_740) tempbh = 0x0d;
+ else tempbh = 0x0c;
+
for(i = 0; i < tempbh; i++) {
SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
}
SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- /* Set up Panel Link for LVDS, 301BDH and 30xLV(for LCDA) */
+ /* Set up Panel Link for LVDS and LCDA */
+ SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- } else {
- SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
}
#ifdef LINUX_XF86
SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
#ifdef SIS315H
- SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo);
+ SiS_SetGroup4_C_ELV(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
#endif
SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+ SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+
/* For 301BDH (Panel link initialization): */
if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+ if(SiS_Pr->SiS_LCDResInfo != Panel_640x480) {
if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10)))) {
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
} else {
- if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
- if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
- SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
- }
+ SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
}
- SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
+ SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwInfo);
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
}
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
- SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex);
+ SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex);
}
}
}
if(HwInfo->jChipType < SIS_315H) {
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
if(SiS_Pr->SiS_UseOEM) {
- if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+ if((SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_UseOEM == -1)) {
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
RefreshRateTableIndex);
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
if(HwInfo->jChipType < SIS_661) {
SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
- if(SiS_Pr->SiS_UseOEM) {
- SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
- }
+ SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
} else {
SiS_OEM661Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
- SiS_CRT2AutoThreshold(SiS_Pr);
+ SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
}
}
#endif
}
}
+#ifdef SIS300
+static UCHAR *
+SiS_SetTrumpBlockLoop(SiS_Private *SiS_Pr, UCHAR *dataptr)
+{
+ int i, j, num;
+ USHORT tempah,temp;
+ UCHAR *mydataptr;
+
+ for(i=0; i<20; i++) { /* Do 20 attempts to write */
+ mydataptr = dataptr;
+ num = *mydataptr++;
+ if(!num) return mydataptr;
+ if(i) {
+ SiS_SetStop(SiS_Pr);
+ SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT*2);
+ }
+ if(SiS_SetStart(SiS_Pr)) continue; /* Set start condition */
+ tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write DAB (S0=0=write) */
+ if(temp) continue; /* (ERROR: no ack) */
+ tempah = *mydataptr++;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah); /* Write register number */
+ if(temp) continue; /* (ERROR: no ack) */
+ for(j=0; j<num; j++) {
+ tempah = *mydataptr++;
+ temp = SiS_WriteDDC2Data(SiS_Pr,tempah);/* Write DAB (S0=0=write) */
+ if(temp) break;
+ }
+ if(temp) continue;
+ if(SiS_SetStop(SiS_Pr)) continue;
+ return mydataptr;
+ }
+ return NULL;
+}
+
+static BOOLEAN
+SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr)
+{
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
+ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_SetupDDCN(SiS_Pr);
+
+ SiS_SetSwitchDDC2(SiS_Pr);
+
+ while(*dataptr) {
+ dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
+ if(!dataptr) return FALSE;
+ }
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
+#endif
+ return TRUE;
+}
+#endif
+
/* The Chrontel 700x is connected to the 630/730 via
* the 630/730's DDC/I2C port.
*
return FALSE;
}
+#ifdef SIS300
+/* Write Trumpion register */
+void
+SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
+ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_SetupDDCN(SiS_Pr);
+ SiS_SetChReg(SiS_Pr, tempbx, 0);
+}
+#endif
+
/* Write to Chrontel 700x */
/* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
void
SiS_Pr->SiS_DDC_Clk = 0x04; /* Bitmask in IndexReg for Clk */
SiS_SetupDDCN(SiS_Pr);
SiS_Pr->SiS_DDC_DeviceAddr = 0xEA; /* DAB (Device Address Byte) */
-
SiS_SetChReg(SiS_Pr, tempbx, 0);
}
void
SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
{
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
- SiS_SetCH700x(SiS_Pr,tempbx);
- else
- SiS_SetCH701x(SiS_Pr,tempbx);
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+ SiS_SetCH700x(SiS_Pr,tempbx);
+ else
+ SiS_SetCH701x(SiS_Pr,tempbx);
}
static USHORT
return 0xFFFF;
}
+#ifdef SIS300
+/* Read from Trumpion */
+USHORT
+SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+ SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB */
+ SiS_Pr->SiS_DDC_Index = 0x11; /* Bit 0 = SC; Bit 1 = SD */
+ SiS_Pr->SiS_DDC_Data = 0x02; /* Bitmask in IndexReg for Data */
+ SiS_Pr->SiS_DDC_Clk = 0x01; /* Bitmask in IndexReg for Clk */
+ SiS_SetupDDCN(SiS_Pr);
+ SiS_Pr->SiS_DDC_ReadAddr = tempbx;
+ return(SiS_GetChReg(SiS_Pr,0));
+}
+#endif
+
/* Read from Chrontel 700x */
/* Parameter is [Register no (S7-S0)] */
USHORT
USHORT
SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
{
- if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
- return(SiS_GetCH700x(SiS_Pr, tempbx));
- else
- return(SiS_GetCH701x(SiS_Pr, tempbx));
+ if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+ return(SiS_GetCH700x(SiS_Pr, tempbx));
+ else
+ return(SiS_GetCH701x(SiS_Pr, tempbx));
}
/* Our own DDC functions */
for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
SiS_Pr->CP_HaveCustomData = FALSE;
SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
+ SiS_Pr->CP_PreferredX = SiS_Pr->CP_PreferredY = 0;
+ SiS_Pr->CP_PreferredIndex = -1;
if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
if(pSiS->VBFlags & VB_30xBDH) return 0;
SiS_Pr->CP_PreferredY = yres;
switch(xres) {
+#if 0 /* Treat as custom */
case 800:
if(yres == 600) {
paneltype = Panel_800x600;
checkexpand = TRUE;
}
break;
+#endif
case 1024:
if(yres == 768) {
paneltype = Panel_1024x768;
#if 0 /* Treat this as custom, as we have no valid timing data yet */
case 1600:
if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1200) {
- paneltype = Panel310_1600x1200;
- checkexpand = TRUE;
+ if(pSiS->VBFlags & VB_301C) {
+ if(yres == 1200) {
+ paneltype = Panel310_1600x1200;
+ checkexpand = TRUE;
+ }
}
}
break;
if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
+ if((SiS_Pr->CP_PreferredX == xres) && (SiS_Pr->CP_PreferredY == yres)) {
+ SiS_Pr->CP_PreferredIndex = i;
+ }
+
SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
switch(xres) {
+#if 0
case 800:
if(yres == 600) {
paneltype = Panel_800x600;
checkexpand = TRUE;
}
break;
+#endif
case 1024:
if(yres == 768) {
paneltype = Panel_1024x768;
checkexpand = TRUE;
}
break;
- case 1152:
- if(yres == 768) {
- if(pSiS->VGAEngine == SIS_300_VGA) {
- paneltype = Panel300_1152x768;
- } else {
- paneltype = Panel310_1152x768;
- }
- checkexpand = TRUE;
- }
- break;
case 1280:
if(yres == 960) {
if(pSiS->VGAEngine == SIS_315_VGA) {
#if 0 /* Treat this one as custom since we have no timing data yet */
case 1600:
if(pSiS->VGAEngine == SIS_315_VGA) {
- if(yres == 1200) {
- paneltype = Panel310_1600x1200;
- checkexpand = TRUE;
+ if(pSiS->VBFlags & VB_301C) {
+ if(yres == 1200) {
+ paneltype = Panel310_1600x1200;
+ checkexpand = TRUE;
+ }
}
}
break;
if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
+ if((SiS_Pr->CP_MaxX == xres) && (SiS_Pr->CP_MaxY == yres)) {
+ SiS_Pr->CP_PreferredIndex = i;
+ }
+
SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
SiS_Pr->CP_SyncValid[i] = TRUE;
if(paneltype) {
if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
- cr37 &= 0xf1;
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
- SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xf1,cr37);
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,paneltype);
+ cr37 &= 0xf1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0x0c,cr37);
+ SiS_Pr->PanelSelfDetected = TRUE;
#ifdef TWDEBUG
xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3,
- "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
+ "CRT2: [DDC LCD results: 0x%02x, 0x%02x]\n", paneltype, cr37);
#endif
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x32,~0x08);
+ SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,0x00);
}
return 0;
}
USHORT romptr;
if(HwInfo->jChipType < SIS_330) {
- romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
+ romptr = SISGETROMW(0x128);
if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
- romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
+ romptr = SISGETROMW(0x12a);
} else {
- romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
+ romptr = SISGETROMW(0x1a8);
if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
- romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
+ romptr = SISGETROMW(0x1aa);
}
return(romptr);
}
USHORT romptr;
if(HwInfo->jChipType < SIS_330) {
- romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
+ romptr = SISGETROMW(0x120);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
- romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+ romptr = SISGETROMW(0x122);
} else {
- romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
+ romptr = SISGETROMW(0x1a0);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
- romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
+ romptr = SISGETROMW(0x1a2);
}
return(romptr);
}
USHORT romptr;
if(HwInfo->jChipType < SIS_330) {
- romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+ romptr = SISGETROMW(0x114);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
- romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+ romptr = SISGETROMW(0x11a);
} else {
- romptr = ROMAddr[0x194] | (ROMAddr[0x195] << 8);
+ romptr = SISGETROMW(0x194);
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
- romptr = ROMAddr[0x19a] | (ROMAddr[0x19b] << 8);
+ romptr = SISGETROMW(0x19a);
}
return(romptr);
}
}
}
- index = SiS_Pr->SiS_LCDResInfo & 0x0F;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) index -= 5;
- else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
+ index = SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) index -= 5;
+ else if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) index -= 6;
index--;
index *= 3;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
{
USHORT index;
- index = SiS_Pr->SiS_LCDResInfo & 0x0F;
- index--;
- index *= 3;
- if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+ index = ((SiS_GetBIOSLCDResInfo(SiS_Pr) & 0x0F) - 1) * 3;
+ if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
-
return index;
}
}
static ULONG
-GetOEMTVPtr661_2(SiS_Private *SiS_Pr)
+GetOEMTVPtr661_2_GEN(SiS_Private *SiS_Pr, int addme)
{
USHORT index = 0, temp = 0;
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
(SiS_Pr->SiS_TVMode & TVSetTVSimuMode)) {
- index += 8;
+ index += addme;
temp++;
}
temp += 0x0100;
return(ULONG)(index | (temp << 16));
}
+static ULONG
+GetOEMTVPtr661_2_OLD(SiS_Private *SiS_Pr)
+{
+ return(GetOEMTVPtr661_2_GEN(SiS_Pr, 8));
+}
+
+#if 0
+static ULONG
+GetOEMTVPtr661_2_NEW(SiS_Private *SiS_Pr)
+{
+ return(GetOEMTVPtr661_2_GEN(SiS_Pr, 6));
+}
+#endif
+
static int
GetOEMTVPtr661(SiS_Private *SiS_Pr)
{
int index = 0;
- if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
- if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
- if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
+ if(SiS_Pr->SiS_TVMode & TVSetPAL) index = 2;
+ if(SiS_Pr->SiS_ROMNew) {
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 4;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 6;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 8;
+ if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 10;
+ } else {
+ if(SiS_Pr->SiS_TVMode & TVSetHiVision) index = 4;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525i) index = 6;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr525p) index = 8;
+ if(SiS_Pr->SiS_TVMode & TVSetYPbPr750p) index = 10;
+ }
if(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) index++;
USHORT delay=0,index,myindex,temp,romptr=0;
BOOLEAN dochiptest = TRUE;
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
+ } else {
+ SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x35,0x7f);
+ }
+
/* Find delay (from ROM, internal tables, PCI subsystem) */
if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) { /* ------------ VGA */
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
- if(!romptr) return;
- delay = ROMAddr[romptr];
- } else {
+ }
+ if(romptr) delay = ROMAddr[romptr];
+ else {
delay = 0x04;
if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
if(IS_SIS650) {
} else {
delay = 0x0c;
}
- }
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+ } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
delay = 0x00;
}
}
BOOLEAN gotitfrompci = FALSE;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+ /* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
- /* Could we detect a PDC for LCD? If yes, use it */
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ if(SiS_Pr->PDC != -1) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((SiS_Pr->PDC >> 1) & 0x0f));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((SiS_Pr->PDC & 0x01) << 7));
+ return;
+ }
+ } else {
+ if(SiS_Pr->PDCA != -1) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDCA << 3) & 0xf0));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((SiS_Pr->PDCA & 0x01) << 6));
+ return;
+ }
+ }
+
+ /* Custom Panel? */
- if(SiS_Pr->PDC) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((SiS_Pr->PDC & 0x0f) << 4));
+ delay = 0x00;
+ if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
+ delay = 0x20;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,delay);
+ } else {
+ delay = 0x0c;
+ if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x03;
+ else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+ if(IS_SIS740) delay = 0x01;
+ else delay = 0x03;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,delay);
}
return;
}
switch(SiS_Pr->SiS_CustomT) {
case CUT_COMPAQ1280:
case CUT_COMPAQ12802:
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
gotitfrompci = TRUE;
dochiptest = FALSE;
delay = 0x03;
break;
case CUT_CLEVO1400:
case CUT_CLEVO14002:
- /* if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { */
- gotitfrompci = TRUE;
- dochiptest = FALSE;
- delay = 0x02;
- /* } */
+ gotitfrompci = TRUE;
+ dochiptest = FALSE;
+ delay = 0x02;
break;
case CUT_CLEVO1024:
case CUT_CLEVO10242:
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
gotitfrompci = TRUE;
dochiptest = FALSE;
delay = 0x33;
if(SiS_IsNotM650orLater(SiS_Pr, HwInfo)) {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
/* Always use the second pointer on 650; some BIOSes */
/* still carry old 301 data at the first location */
- /* romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); */
+ /* romptr = SISGETROMW(0x120); */
/* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
- romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+ romptr = SISGETROMW(0x122);
if(!romptr) return;
delay = ROMAddr[(romptr + index)];
} else {
}
- } else if((ROMAddr) && SiS_Pr->SiS_UseROM &&
- (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
+ } else if(SiS_Pr->SiS_UseROM &&
+ (!(SiS_Pr->SiS_ROMNew)) &&
+ (SiS_Pr->SiS_LCDResInfo != Panel_1280x1024) &&
+ (SiS_Pr->SiS_LCDResInfo != Panel_1280x768) &&
+ (SiS_Pr->SiS_LCDResInfo != Panel_1280x960)) {
- /* Data for 1280x1024 wrong in BIOS */
+ /* Data for 1280x1024 wrong in 301B BIOS */
romptr = GetLCDromptr(SiS_Pr, HwInfo);
if(!romptr) return;
delay = ROMAddr[(romptr + index)];
delay = SiS310_LCDDelayCompensation_301[myindex];
if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
if(IS_SIS740) delay = 0x01;
+ else if(HwInfo->jChipType <= SIS_315PRO) delay = SiS310_LCDDelayCompensation_3xx301LV[myindex];
else delay = SiS310_LCDDelayCompensation_650301LV[myindex];
+ } else if(SiS_Pr->SiS_VBType & VB_SIS301C) {
+ if(IS_SIS740) delay = 0x01; /* ? */
+ else delay = 0x03;
} else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
if(IS_SIS740) delay = 0x01;
else delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
if(SiS_IsNotM650orLater(SiS_Pr,HwInfo)) {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
/* Always use the second pointer on 650; some BIOSes */
/* still carry old 301 data at the first location */
- /* romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8); */
- /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
- romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+ /* romptr = SISGETROMW(0x114); */
+ /* if(SiS_Pr->SiS_VBType & VB_SIS302LV) */
+ romptr = SISGETROMW(0x11a);
if(!romptr) return;
delay = ROMAddr[romptr + index];
}
}
- } else if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ } else if((SiS_Pr->SiS_UseROM) && (!(SiS_Pr->SiS_ROMNew))) {
romptr = GetTVromptr(SiS_Pr, HwInfo);
if(!romptr) return;
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
if(IS_SIS740) {
delay = SiS310_TVDelayCompensation_740301B[index];
+ /* LV: use 301 data? BIOS bug? */
} else {
delay = SiS310_TVDelayCompensation_301B[index];
+ if(SiS_Pr->SiS_VBType & VB_SIS301C) delay = 0x02;
}
}
}
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) { /* LCDA */
+ if(SiS_LCDAEnabled(SiS_Pr, HwInfo)) {
delay &= 0x0f;
dochiptest = FALSE;
}
temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
temp1 = temp;
- if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
if(HwInfo->jChipType >= SIS_661) {
- romptr = ROMAddr[0x260] | (ROMAddr[0x261] << 8);
- temp1 = GetOEMTVPtr661(SiS_Pr);
+ temp1 = GetOEMTVPtr661(SiS_Pr);
temp1 >>= 1;
+ romptr = SISGETROMW(0x260);
+ if(HwInfo->jChipType >= SIS_760) {
+ romptr = SISGETROMW(0x360);
+ }
} else if(HwInfo->jChipType >= SIS_330) {
- romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
+ romptr = SISGETROMW(0x192);
} else {
- romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
+ romptr = SISGETROMW(0x112);
}
}
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT index,temp,temp1,romptr=0;
- temp = GetTVPtrIndex(SiS_Pr);
- temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
- temp1 = temp;
+ temp = temp1 = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
- if(ModeNo<=0x13)
+ if(ModeNo <= 0x13)
index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
else
index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
- if(ROMAddr && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM && (!(SiS_Pr->SiS_ROMNew))) {
if(HwInfo->jChipType >= SIS_661) {
- romptr = ROMAddr[0x26c] | (ROMAddr[0x26d] << 8);
+ romptr = SISGETROMW(0x26c);
+ if(HwInfo->jChipType >= SIS_760) {
+ romptr = SISGETROMW(0x36c);
+ }
temp1 = GetOEMTVPtr661(SiS_Pr);
temp1 >>= 1;
} else if(HwInfo->jChipType >= SIS_330) {
- romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
+ romptr = SISGETROMW(0x1a4);
} else {
- romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
+ romptr = SISGETROMW(0x124);
}
}
SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
USHORT ModeNo,USHORT ModeIdIndex)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
- USHORT index, myindex, oldindex,temp, i, j, flag1 = 0, flag2 = 0, romptr = 0;
- ULONG lindex;
+ USHORT index, temp, i, j;
- if(ModeNo<=0x13) {
- index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+ if(ModeNo <= 0x13) {
+ index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
} else {
- index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
- }
-
- oldindex = index;
-
- if((HwInfo->jChipType >= SIS_661) && ROMAddr && SiS_Pr->SiS_UseROM) {
- if(ModeNo > 0x13) {
- index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndexROM661;
- }
- lindex = GetOEMTVPtr661_2(SiS_Pr);
- if(lindex & 0x00ff0000) flag1 = 1;
- if(lindex & 0xff000000) flag2 = 1;
- lindex &= 0xffff;
-
- /* NTSC-J: Use PAL filters */
- if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) lindex = 1;
-
- romptr = ROMAddr[0x268] | (ROMAddr[0x269] << 8);
- if(flag1) myindex = index * 7;
- else myindex = index << 2;
-
- if(romptr) {
- romptr += (lindex << 1);
- romptr = (ROMAddr[romptr] | (ROMAddr[romptr+1] << 8)) + myindex;
- if(romptr) {
- if((!flag1) && (flag2)) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,0x00);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,0x00);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,0x00);
- SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,ROMAddr[romptr++]);
- } else {
- for(i=0x35; i<=0x38; i++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
- }
- }
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- for(j=0, i=0x48; i<=0x4a; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr++]);
- }
- }
- return;
- }
- }
+ index = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
}
- index = oldindex;
-
- temp = GetTVPtrIndex(SiS_Pr);
- temp >>= 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
+ temp = GetTVPtrIndex(SiS_Pr) >> 1; /* 0: NTSC/YPbPr, 1: PAL, 2: HiTV */
if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) temp = 1; /* NTSC-J uses PAL */
else if(SiS_Pr->SiS_TVMode & TVSetPALM) temp = 3; /* PAL-M */
/* NTSC-J data not in BIOS, and already set in SetGroup2 */
if(SiS_Pr->SiS_TVMode & TVSetNTSCJ) return;
- if(HwInfo->jChipType >= SIS_661) {
- lindex = GetOEMTVPtr661_2(SiS_Pr) & 0xffff;
+ if((HwInfo->jChipType >= SIS_661) || SiS_Pr->SiS_ROMNew) {
+ lindex = GetOEMTVPtr661_2_OLD(SiS_Pr) & 0xffff;
lindex <<= 2;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- romptr = ROMAddr[0x264] | (ROMAddr[0x265] << 8);
- }
- if(romptr) {
- romptr += lindex;
- for(j=0, i=0x31; i<=0x34; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
- }
- } else {
- for(j=0, i=0x31; i<=0x34; i++, j++) {
- SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
- }
+ for(j=0, i=0x31; i<=0x34; i++, j++) {
+ SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS661_TVPhase[lindex + j]);
}
return;
}
/* 0: NTSC Graphics, 1: NTSC Text, 2: PAL Graphics,
* 3: PAL Text, 4: HiTV Graphics 5: HiTV Text
*/
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+ if(SiS_Pr->SiS_UseROM) {
+ romptr = SISGETROMW(0x116);
if(HwInfo->jChipType >= SIS_330) {
- romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+ romptr = SISGETROMW(0x196);
}
if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
+ romptr = SISGETROMW(0x11c);
if(HwInfo->jChipType >= SIS_330) {
- romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
+ romptr = SISGETROMW(0x19c);
}
if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_TVMode & TVSetTVSimuMode))) {
- romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
+ romptr = SISGETROMW(0x116);
if(HwInfo->jChipType >= SIS_330) {
- romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
+ romptr = SISGETROMW(0x196);
}
}
}
SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
}
}
SetDelayComp661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo,
USHORT ModeIdIndex, USHORT RTI)
{
- UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT delay = 0, romptr = 0, index;
- UCHAR *myptr = NULL;
- UCHAR temp;
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToRAMDAC)))
return;
- delay = SiS_Pr->SiS_RefIndex[RTI].Ext_PDC;
+ /* 1. New ROM: VGA2 and LCD/LCDA-Pass1:1 */
+
+ if(SiS_Pr->SiS_ROMNew) {
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) ||
+ ((SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+ (SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+ index = 25;
+ if(SiS_Pr->UseCustomMode) {
+ index = SiS_Pr->CSRClock;
+ } else if(ModeNo > 0x13) {
+ index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RTI,HwInfo);
+ index = SiS_Pr->SiS_VCLKData[index].CLOCK;
+ }
+ if(index < 25) index = 25;
+ index = ((index / 25) - 1) << 1;
+ if((ROMAddr[0x5b] & 0x80) || (SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD))) {
+ index++;
+ }
+ romptr = SISGETROMW(0x104); /* 0x4ae */
+ delay = ROMAddr[romptr + index];
+ if(SiS_Pr->SiS_VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD)) {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
+ }
+ return;
+ }
+ }
+
+ /* 2. Old ROM: VGA2 and LCD/LCDA-Pass 1:1 */
- delay &= 0xf0;
- delay >>= 4;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) delay <<= 12; /* BIOS: 8, wrong */
+ if(SiS_Pr->UseCustomMode) delay = 0x04;
+ else if(ModeNo <= 0x13) delay = 0x04;
+ else delay = (SiS_Pr->SiS_RefIndex[RTI].Ext_PDC >> 4);
+ delay |= (delay << 8);
if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+ /* 3. TV */
+
index = GetOEMTVPtr661(SiS_Pr);
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- romptr = ROMAddr[0x25c] | (ROMAddr[0x25d] << 8);
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- romptr = ROMAddr[0x25e] | (ROMAddr[0x25f] << 8);
- }
- }
- if(romptr) myptr = &ROMAddr[romptr];
- if(!myptr) {
- myptr = (UCHAR *)SiS_TVDelay661_301;
- if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
- myptr = (UCHAR *)SiS_TVDelay661_301B;
- }
+ if(SiS_Pr->SiS_ROMNew) {
+ romptr = SISGETROMW(0x106); /* 0x4ba */
+ delay = ROMAddr[romptr + index];
+ } else {
+ delay = 0x04;
}
- delay = myptr[index];
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) delay >>= 4; /* Should test dual edge */
+
} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(SiS_Pr->PDC) {
- delay = SiS_Pr->PDC & 0x0f;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- delay |= (delay << 12);
+
+ /* 4. LCD, LCDA (for new ROM only LV and non-Pass 1:1) */
+
+ if( (SiS_Pr->SiS_LCDResInfo != Panel_Custom) &&
+ ((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) ) {
+
+ /* For LV, the BIOS must know about the correct value */
+ delay = ROMAddr[romptr + 0x0d]; /* LCD */
+ delay |= (ROMAddr[romptr + 0x0c] << 8); /* LCDA */
+
+ } else {
+
+ /* TMDS: Set our own, since BIOS has no idea - TODO: Find out about values */
+ if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+ if((SiS_Pr->PanelXRes <= 1024) && (SiS_Pr->PanelYRes <= 768)) {
+ delay = 0x0404;
+ } else if((SiS_Pr->PanelXRes <= 1280) && (SiS_Pr->PanelYRes <= 1024)) {
+ delay = 0x0404;
+ } else if((SiS_Pr->PanelXRes <= 1400) && (SiS_Pr->PanelYRes <= 1050)) {
+ delay = 0x1004;
+ } else
+ delay = 0x0000;
+ }
+
+ /* Override by detected or user-set values */
+ /* (but only if, for some reason, we can't read value from BIOS) */
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->PDC != -1)) {
+ delay = SiS_Pr->PDC & 0x1f;
}
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
- delay = 0x4444; /* TEST THIS */
- } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
- myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
- if(myptr) delay = myptr[4];
- else delay = 0x44;
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- delay |= (delay << 8);
+ if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) && (SiS_Pr->PDCA != -1)) {
+ delay = (SiS_Pr->PDCA & 0x1f) << 8;
}
+
}
- }
- temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2d);
- if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToRAMDAC)) {
- temp &= 0xf0;
- temp |= (delay & 0x000f);
}
+
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- temp &= 0x0f;
- temp |= ((delay & 0xf000) >> 8);
+ delay >>= 8;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((delay << 3) & 0xf0));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x20,0xbf,((delay & 0x01) << 6));
+ } else {
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0xf0,((delay >> 1) & 0x0f));
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,0x7f,((delay & 0x01) << 7));
}
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,temp);
}
static void
USHORT infoflag;
UCHAR temp;
- infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
- if(ModeNo <= 0x13) {
- infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
- }
- infoflag &= 0xc0;
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+
+ if(ModeNo <= 0x13) {
+ infoflag = SiS_GetRegByte(SiS_Pr->SiS_P3ca+2);
+ } else if(SiS_Pr->UseCustomMode) {
+ infoflag = SiS_Pr->CInfoFlag;
+ } else {
+ infoflag = SiS_Pr->SiS_RefIndex[RTI].Ext_InfoFlag;
+ }
+ infoflag &= 0xc0;
+
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
- if(temp & 0x20) infoflag = temp;
+ if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+ temp &= 0x3f;
+ temp |= infoflag;
+ } else {
+ if(temp & 0x20) infoflag = temp;
+ }
if(temp & 0x01) infoflag |= 0x01;
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
- temp = 0x0c;
- if(infoflag & 0x01) temp ^= 0x14; /* BIOS: 18, wrong */
- temp |= (infoflag >> 6);
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- temp = 0;
- if(infoflag & 0x01) temp |= 0x80;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
- temp = 0x30;
- if(infoflag & 0x01) temp = 0x20;
- infoflag &= 0xc0;
- temp |= infoflag;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ temp = 0x0c;
+ if(infoflag & 0x01) temp ^= 0x14; /* BIOS: 18, wrong */
+ temp |= (infoflag >> 6);
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xe0,temp);
+ } else {
+ temp = 0;
+ if(infoflag & 0x01) temp |= 0x80;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0x7f,temp);
+ temp = 0x30;
+ if(infoflag & 0x01) temp = 0x20;
+ infoflag &= 0xc0;
+ temp |= infoflag;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,temp);
+ }
+
}
}
static void
SetPanelParms661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
{
- UCHAR *myptr;
+ UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
+ USHORT romptr, temp1, temp2;
if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
if(SiS_Pr->LVDSHL != -1) {
}
}
- myptr = GetLCDStructPtr661(SiS_Pr, HwInfo);
- if(myptr) {
- if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
- if(SiS_Pr->LVDSHL == -1) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE0,myptr[1] & 0x1f);
- } else {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xE3,myptr[1] & 0x1c);
+ if(SiS_Pr->SiS_ROMNew) {
+
+ if((romptr = GetLCDStructPtr661_2(SiS_Pr, HwInfo))) {
+ if(SiS_Pr->SiS_VBType & (VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) {
+ temp1 = (ROMAddr[romptr] & 0x03) | 0x0c;
+ temp2 = 0xfc;
+ if(SiS_Pr->LVDSHL != -1) {
+ temp1 &= 0xfc;
+ temp2 = 0xf3;
+ }
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,temp2,temp1);
+ }
+ if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+ temp1 = (ROMAddr[romptr + 1] & 0x80) >> 1;
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0xbf,temp1);
}
}
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d,0x3f,myptr[2] & 0xc0);
+
}
}
SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
- if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+ if(SiS_Pr->SiS_VBType & VB_SIS301) {
SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
}
}
}
}
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
if(SiS_Pr->UseCustomMode) return;
switch(SiS_Pr->SiS_CustomT) {
}
if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
/* Maybe all panels? */
if(SiS_Pr->LVDSHL == -1) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(SiS_Pr->LVDSHL == -1) {
/* Maybe all panels? */
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
}
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-#ifdef SET_EMI
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(SiS_Pr->SiS_VBType & (VB_SIS302LV | VB_SIS302ELV)) {
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+#ifdef SET_EMI
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x30,0x0c);
+#endif
SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
}
-#endif
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
if(SiS_Pr->LVDSHL == -1) {
/* Maybe ACER only? */
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
}
tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
- } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ } else if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(tempch == 0x03) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
tempbh >>= 4;
tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
tempbx = (tempbh << 8) | tempbl;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
tempbx = 770;
tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+ if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
}
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(ROMAddr[0x235] & 0x80) {
tempbx = SiS_Pr->SiS_LCDTypeInfo;
if(Flag) {
- romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
- if(romptr) {
- tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
- } else {
- tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
- }
+ romptr = SISGETROMW(0x255);
+ if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+ else tempbx = customtable300[SiS_Pr->SiS_LCDTypeInfo];
if(tempbx == 0xFF) return 0xFFFF;
}
tempbx <<= 1;
} else {
if(Flag) {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
- romptr = ROMAddr[0x255] | (ROMAddr[0x256] << 8);
- if(romptr) {
- tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
- } else {
- tempbx = 0xff;
- }
+ if(SiS_Pr->SiS_UseROM) {
+ romptr = SISGETROMW(0x255);
+ if(romptr) tempbx = ROMAddr[romptr + SiS_Pr->SiS_LCDTypeInfo];
+ else tempbx = 0xff;
} else {
tempbx = customtable630[SiS_Pr->SiS_LCDTypeInfo];
}
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT index,temp,romptr=0;
- if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+ if(SiS_Pr->SiS_LCDResInfo == Panel_Custom) return;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x237] & 0x01)) return;
if(!(ROMAddr[0x237] & 0x02)) return;
- romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
+ romptr = SISGETROMW(0x24b);
}
/* The Panel Compensation Delay should be set according to tables
* Thus we don't set this if the user select a custom pdc or if
* we otherwise detected a valid pdc.
*/
- if(SiS_Pr->PDC) return;
+ if(SiS_Pr->PDC != -1) return;
temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
if(HwInfo->jChipType != SIS_300) {
if(romptr) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += index;
temp = ROMAddr[romptr];
} else {
}
}
} else {
- if((ROMAddr) && SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
+ if(SiS_Pr->SiS_UseROM && (ROMAddr[0x235] & 0x80)) {
if(romptr) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += index;
temp = ROMAddr[romptr];
} else {
temp = SiS300_OEMLCDDelay5[temp][index];
}
} else {
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
romptr = ROMAddr[0x249] | (ROMAddr[0x24a] << 8);
if(romptr) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += index;
temp = ROMAddr[romptr];
} else {
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT index,temp;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if((SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x237] & 0x01)) return;
if(!(ROMAddr[0x237] & 0x04)) return;
/* No rom pointer in BIOS header! */
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT index,temp,romptr=0;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x238] & 0x01)) return;
if(!(ROMAddr[0x238] & 0x02)) return;
- romptr = ROMAddr[0x241] | (ROMAddr[0x242] << 8);
+ romptr = SISGETROMW(0x241);
}
temp = GetOEMTVPtr(SiS_Pr);
if(romptr) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += index;
temp = ROMAddr[romptr];
} else {
}
}
temp &= 0x3c;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* index 0A D[6:4] */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp);
}
static void
UCHAR *ROMAddr = HwInfo->pjVirtualRomBase;
USHORT index,temp,romptr=0;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x238] & 0x01)) return;
if(!(ROMAddr[0x238] & 0x04)) return;
- romptr = ROMAddr[0x243] | (ROMAddr[0x244] << 8);
+ romptr = SISGETROMW(0x243);
}
temp = GetOEMTVPtr(SiS_Pr);
if(romptr) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += index;
temp = ROMAddr[romptr];
} else {
temp = SiS300_OEMTVFlicker[temp][index];
}
temp &= 0x70;
- SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp); /* index 0A D[6:4] */
+ SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0A,0x8F,temp);
}
static void
if(SiS_Pr->SiS_TVMode & (TVSetNTSC1024 | TVSetNTSCJ | TVSetPALM | TVSetPALN)) return;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x238] & 0x01)) return;
if(!(ROMAddr[0x238] & 0x08)) return;
- romptr = ROMAddr[0x245] | (ROMAddr[0x246] << 8);
+ romptr = SISGETROMW(0x245);
}
temp = GetOEMTVPtr(SiS_Pr);
} else {
if(romptr) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += (index * 4);
for(i=0x31, j=0; i<=0x34; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVision | SetCRT2ToYPbPr525750)) return;
- if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+ if(SiS_Pr->SiS_UseROM) {
if(!(ROMAddr[0x238] & 0x01)) return;
if(!(ROMAddr[0x238] & 0x10)) return;
- romptr = ROMAddr[0x247] | (ROMAddr[0x248] << 8);
+ romptr = SISGETROMW(0x247);
}
temp = GetOEMTVPtr(SiS_Pr);
} else {
if((romptr) && (!(SiS_Pr->SiS_TVMode & (TVSetPALM|TVSetPALN)))) {
romptr += (temp * 2);
- romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
+ romptr = SISGETROMW(romptr);
romptr += (index * 4);
for(i=0x35, j=0; i<=0x38; i++, j++) {
SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Data and prototypes for init301.c
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
- 0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
- 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53,
+ 0x03,0x0a,0x65,0x9d /*0x8d*/,0x08,0x92,0x8f,0x40,
+ 0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x53 /*0x50*/,
0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
},
{
0x1d,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
- 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
+ 0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4c /*0x4f*/,0x13,
0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
- 0x51,0x5e,0x60,0x49,0x7d,0x92,0x0f,0x40,
+ 0x51,0x5e,0x60,0x57 /*0x49*/,0x7b /*0x7d*/,0x92,0x0f,0x40,
0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x4b,
0x43,0x41,0x11,0x00,0xfc,0xff,0x32,0x00
},
{
+#if 1
0x13,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
- 0xed,0x50,0x70,0x9f,0x16,0x59,0x2b,0x13,
+ 0xed,0x50,0x70,0x9f,0x16,0x59,0x21 /*0x2b*/,0x13,
0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
- 0x4b,0x4b,0x6f,0x2f,0x63,0x92,0x0f,0x40,
+ 0x4b,0x4b,0x65 /*0x6f*/,0x2f,0x63,0x92,0x0f,0x40,
0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x27,
0x00,0x40,0x11,0x00,0xfc,0xff,0x32,0x00
+#endif
+#if 0
+ 0x2a,0x14,0xe8,0x09,0x09,0xed,0x0c,0x0c, /* TEST (0.93) - BAD */
+ 0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
+ 0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
+ 0xed,0x50,0x70,0x9e,0x16,0x57,0x6c,0x13,
+ 0x27,0x0b,0x27,0xfb,0x30,0x27,0x15,0xb0,
+ 0x3b,0xdb,0x61,0x24,0x78,0x92,0x0f,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x14,0x6f,
+ 0x00,0x52,0xbb,0x00,0xd5,0xf7,0xa2,0x00
+#endif
}
};
0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
};
-/* 301C / 302ELV (?) extended Part2 TV registers */
+/* 301C / 302ELV extended Part2 TV registers */
static const UCHAR SiS_Part2CLVX_1[] = {
0x00,0x00,
0x00,0x04,
0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E,0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D,
0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D,0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C,
- 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x1D /* 0x7D? */ ,0x7C,0x0D,0x18,0x7F,
+ 0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D,0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F,
0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00,0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02,
0xFF,0xFF,
};
-
#ifdef SIS315H
-/* 661 et al LCD data structure */
+/* 661 et al LCD data structure (0.94.0) */
static const UCHAR SiS_LCDStruct661[] = {
- /* 1600x1200 */
- 0x0B,0xEA,0x81,0x10,0x00,0xC0,0x03,0x21,0x5A,0x23,0x5A,0x23,0x02,
- 0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
- /* 1400x1050 */
- 0x09,0xEA,0x81,0x80,0xA3,0x70,0x03,0x19,0xD2,0x2A,0xF8,0x2F,0x02,
- 0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
- /* 1280x1024 */
- 0x03,0xEA,0x81,0x40,0xA1,0x70,0x03,0x19,0xD2,0x2A,0xF8,0x2F,0x02,
- 0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x30,0x10,
/* 1024x768 */
- 0x02,0xEA,0x80,0x00,0x11,0x88,0x06,0x0B,0xF5,0x6C,0x35,0x62,0x02,
- 0x14,0x0A,0x02,0x00,0x30,0x10,0x5A,0x10,0x10,0x0A,0xC0,0x28,0x10,
- 0xFF,
+/* type|CR37| HDE | VDE | HT | VT | hss | hse */
+ 0x02,0xC0,0x00,0x04,0x00,0x03,0x40,0x05,0x26,0x03,0x10,0x00,0x88,
+ 0x00,0x02,0x00,0x06,0x00,0x41,0x5A,0x64,0x00,0x00,0x00,0x00,0x04,
+ /* | vss | vse |clck| clock |CRT2DataP|CRT2DataP|idx */
+ /* VESA non-VESA noscale */
+ /* 1280x1024 */
+ 0x03,0xC0,0x00,0x05,0x00,0x04,0x98,0x06,0x2A,0x04,0x30,0x00,0x70,
+ 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x08,
+ /* 1400x1050 */
+ 0x09,0x20,0x78,0x05,0x1A,0x04,0x98,0x06,0x2A,0x04,0x18,0x00,0x38,
+ 0x00,0x01,0x00,0x03,0x00,0x6C,0xF8,0x2F,0x00,0x00,0x00,0x00,0x09,
+ /* 1600x1200 */
+ 0x0B,0xC0,0x40,0x06,0xB0,0x04,0x70,0x08,0xE2,0x04,0x40,0x00,0xC0,
+ 0x00,0x01,0x00,0x03,0x00,0xA2,0x70,0x24,0x00,0x00,0x00,0x00,0x0B,
+ /* 1280x768 */
+ 0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x05,0x26,0x03,0x10,0x00,0x40,
+ 0x00,0x03,0x00,0x06,0x00,0x44,0x63,0x46,0x00,0x00,0x00,0x00,0x06,
+ /* 1280x720 */
+ 0x0E,0xE0,0x00,0x05,0xD0,0x02,0x80,0x05,0x26,0x03,0x10,0x00,0x02,
+ 0x00,0x01,0x00,0x06,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x05,
+ /* 1280x800 */
+ 0x0C,0xE0,0x00,0x05,0x20,0x03,0x80,0x05,0x30,0x03,0x10,0x00,0x40,
+ 0x00,0x04,0x00,0x03,0x00,0x45,0x9C,0x62,0x00,0x00,0x00,0x00,0x07,
+ /* 1680x1050 */
+ 0x0D,0xE0,0x90,0x06,0x1A,0x04,0x6C,0x07,0x2A,0x04,0x1A,0x00,0x4C,
+ 0x00,0x03,0x00,0x06,0x00,0x79,0xBE,0x44,0x00,0x00,0x00,0x00,0x06,
+ /* 1280x768 (not in 0.93) */
+ 0x0A,0xC0,0x00,0x05,0x00,0x03,0x80,0x06,0x1E,0x03,0x40,0x00,0x80,
+ 0x00,0x03,0x00,0x07,0x00,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x06
+};
+#endif
+
+#ifdef SIS300
+static UCHAR SiS300_TrumpionData[7][80] = {
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+ 0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
+ 0x00,0x00,0x03,0x28,0x03,0x10,0x05,0x08,0x40,0x10,0x00,0x10,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xBC,0x01,0xFF,0x03,0xFF,0x19,0x01,0x00,0x05,0x09,0x04,0x04,0x05,
+ 0x04,0x0C,0x09,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5A,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x27,0x00,0x80,0x02,
+ 0x20,0x03,0x07,0x00,0x5E,0x01,0x0D,0x02,0x60,0x0C,0x30,0x11,0x00,0x00,0x04,0x23,
+ 0x00,0x00,0x03,0x80,0x03,0x28,0x06,0x08,0x40,0x11,0x00,0x11,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0x90,0x01,0xFF,0x0F,0xF4,0x19,0x01,0x00,0x05,0x01,0x00,0x04,0x05,
+ 0x04,0x0C,0x02,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xEC,0x57,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x8A,0x00,0xD8,0x02,
+ 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+ 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xD9,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+ 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x59,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x72,0x00,0xD8,0x02,
+ 0x84,0x03,0x16,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x1C,0x00,0x20,0x04,0x23,
+ 0x00,0x01,0x03,0x53,0x03,0x28,0x06,0x08,0x40,0x1C,0x00,0x16,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xDA,0x01,0xFF,0x0F,0xF4,0x18,0x07,0x05,0x05,0x13,0x04,0x04,0x05,
+ 0x01,0x0B,0x13,0x0A,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x55,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x02,0x00,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
+ 0x20,0x03,0x16,0x00,0xE0,0x01,0x0D,0x02,0x60,0x0C,0x30,0x98,0x00,0x00,0x04,0x23,
+ 0x00,0x01,0x03,0x45,0x03,0x48,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0xF4,0x01,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x05,0x01,0x00,0x05,0x05,
+ 0x04,0x0C,0x08,0x05,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x02,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xBF,0x00,0x20,0x03,
+ 0x20,0x04,0x0D,0x00,0x58,0x02,0x71,0x02,0x80,0x0C,0x30,0x9A,0x00,0xFA,0x03,0x1D,
+ 0x00,0x01,0x03,0x22,0x03,0x28,0x06,0x08,0x40,0x98,0x00,0x98,0x04,0x1D,0x00,0x1D,
+ 0x03,0x11,0x60,0x39,0x03,0x40,0x05,0xF4,0x18,0x07,0x02,0x06,0x04,0x01,0x06,0x0B,
+ 0x02,0x0A,0x20,0x19,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 },
+ { 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0xEF,0x00,0x00,0x04,
+ 0x40,0x05,0x13,0x00,0x00,0x03,0x26,0x03,0x88,0x0C,0x30,0x90,0x00,0x00,0x04,0x23,
+ 0x00,0x01,0x03,0x24,0x03,0x28,0x06,0x08,0x40,0x90,0x00,0x90,0x04,0x23,0x00,0x23,
+ 0x03,0x11,0x60,0x40,0x05,0xFF,0x0F,0xF4,0x18,0x01,0x00,0x08,0x01,0x00,0x08,0x01,
+ 0x00,0x08,0x01,0x01,0x02,0xB0,0x00,0x00,0x02,0xBA,0xF0,0x5B,0x01,0xBE,0x01,0x00 }
};
#endif
void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
#endif /* 315 */
+#ifdef SIS300
+void SiS_SetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+USHORT SiS_GetTrumpReg(SiS_Private *SiS_Pr, USHORT tempbx);
+static BOOLEAN SiS_SetTrumpionBlock(SiS_Private *SiS_Pr, UCHAR *dataptr);
+#endif
-USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
-void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
-USHORT SiS_SetStart(SiS_Private *SiS_Pr);
-USHORT SiS_SetStop(SiS_Private *SiS_Pr);
-void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr);
-USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
-USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT SiS_CheckACK(SiS_Private *SiS_Pr);
+USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
+void SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+USHORT SiS_SetStart(SiS_Private *SiS_Pr);
+USHORT SiS_SetStop(SiS_Private *SiS_Pr);
+void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+USHORT SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+USHORT SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+USHORT SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT SiS_CheckACK(SiS_Private *SiS_Pr);
-USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr);
-USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
-USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr);
-void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
-USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr);
-USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr);
-USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
-USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
- USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+USHORT SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+ USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+USHORT SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+USHORT SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+USHORT SiS_PrepareDDC(SiS_Private *SiS_Pr);
+void SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+USHORT SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+USHORT SiS_ProbeDDC(SiS_Private *SiS_Pr);
+USHORT SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
+USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+ USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
#ifdef LINUX_XF86
-USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
#endif
#ifdef SIS315H
-void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex);
-void SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
-void SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
+void SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+ USHORT ModeNo,USHORT ModeIdIndex);
+void SiS_OEM661Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+ USHORT ModeNo,USHORT ModeIdIndex, USHORT RRTI);
+void SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
#endif
#ifdef SIS300
-void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
-void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+void SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+ USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
+void SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+ USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
#endif
extern void SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
extern void SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO,USHORT ModeNo,
USHORT ModeIdIndex);
+extern void SiS_CalcLCDACRT1Timing(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
#endif
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* Global definitions for init.c and init301.c
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#define IS_SIS650740660 (IS_SIS650 || IS_SIS740 || IS_SIS661741660760)
#define IS_SIS550650740660 (IS_SIS550 || IS_SIS650740660)
+#define SISGETROMW(x) (ROMAddr[(x)] | (ROMAddr[(x)+1] << 8))
+
/* SiS_VBType */
#define VB_SIS301 0x0001
#define VB_SIS301B 0x0002
#define VB_SIS301B302B (VB_SIS301B|VB_SIS301C|VB_SIS302B)
#define VB_SIS301LV302LV (VB_SIS301LV|VB_SIS302LV|VB_SIS302ELV)
#define VB_SISVB (VB_SIS301 | VB_SIS301BLV302BLV)
+#define VB_SISTMDS (VB_SIS301 | VB_SIS301B302B)
+#define VB_SISLVDS VB_SIS301LV302LV
/* VBInfo */
#define SetSimuScanMode 0x0001 /* CR 30 */
#define CRT2Mode 0x0800
#define HalfDCLK 0x1000
#define NoSupportSimuTV 0x2000
+#define NoSupportLCDScale 0x4000 /* TMDS: No scaling possible (no matter what panel) */
#define DoubleScanMode 0x8000
/* Infoflag */
#define SupportCHTV 0x0800
#define Support64048060Hz 0x0800 /* Special for 640x480 LCD */
#define SupportHiVision 0x0010
-#define SupportYPbPr 0x1000 /* TODO */
+#define SupportYPbPr750p 0x1000
#define SupportLCD 0x0020
#define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */
#define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */
#define TVSetPALM 0x0004
#define TVSetPALN 0x0008
#define TVSetCHOverScan 0x0010
-#define TVSetYPbPr525i 0x0020
-#define TVSetYPbPr525p 0x0040
-#define TVSetYPbPr750p 0x0080
-#define TVSetHiVision 0x0100 /* = 1080i, software-wise identical */
-#define TVSetTVSimuMode 0x0800
-#define TVRPLLDIV2XO 0x1000
-#define TVSetNTSC1024 0x2000
-
-/* YPbPr flag (>=315, <661) */
-#define YPbPr525p 0x0001 /* 525p */
-#define YPbPr750p 0x0002 /* 750p */
-#define YPbPr525i 0x0004 /* 525p */
-#define YPbPrHiVision 0x0008 /* HiVision or 1080i (bridge type dependent) */
+#define TVSetYPbPr525i 0x0020 /* new 0x10 */
+#define TVSetYPbPr525p 0x0040 /* new 0x20 */
+#define TVSetYPbPr750p 0x0080 /* new 0x40 */
+#define TVSetHiVision 0x0100 /* new 0x80; = 1080i, software-wise identical */
+#define TVSetTVSimuMode 0x0200 /* new 0x200, prev. 0x800 */
+#define TVRPLLDIV2XO 0x0400 /* prev 0x1000 */
+#define TVSetNTSC1024 0x0800 /* new 0x100, prev. 0x2000 */
+#define TVAspect43 0x2000
+#define TVAspect169 0x4000
+#define TVAspect43LB 0x8000
+
+/* YPbPr flag (>=315, <661; converted to TVMode) */
+#define YPbPr525p 0x0001
+#define YPbPr750p 0x0002
+#define YPbPr525i 0x0004
+#define YPbPrHiVision 0x0008
#define YPbPrModeMask (YPbPr750p | YPbPr525p | YPbPr525i | YPbPrHiVision)
/* SysFlags (to identify special versions) */
#define SF_IsM661 0x0020
#define SF_IsM741 0x0040
#define SF_IsM760 0x0080
+#define SF_760LFB 0x8000 /* 760: We have LFB */
/* CR32 (Newer 630, and 315 series)
#define LCDRGB18Bit 0x0001
#define LCDNonExpanding 0x0010
#define LCDSync 0x0020
-#define LCDPass11 0x0100
+#define LCDPass11 0x0100 /* 0: center screen, 1: Pass 1:1 data */
#define LCDDualLink 0x0200
#define DontExpandLCD LCDNonExpanding
#define EnablePALMN 0x40 /* Romflag: 1 = Allow PALM/PALN */
/* CR39 (650 only) */
-#define LCDPass1_1 0x01 /* LVDS only; set by driver to pass 1:1 data to LVDS output */
+#define LCDPass1_1 0x01 /* 0: center screen, 1: pass 1:1 data output */
#define Enable302LV_DualLink 0x04 /* 302LV only; enable dual link */
/* CR39 (661 and later)
#define Panel300_1024x600 0x06
#define Panel300_1152x768 0x07
#define Panel300_1280x768 0x0a
-#define Panel300_320x480 0x0e /* fstn - TW: This is fake, can be any */
+#define Panel300_320x480 0x0e /* fstn - This is fake, can be any */
#define Panel300_Custom 0x0f
#define Panel300_Barco1366 0x10
#define Panel310_320x480 0x0e /* fstn - TW: This is fake, can be any */
#define Panel310_Custom 0x0f
+#define Panel661_800x600 0x01
+#define Panel661_1024x768 0x02
+#define Panel661_1280x1024 0x03
+#define Panel661_640x480 0x04
+#define Panel661_1024x600 0x05
+#define Panel661_1152x864 0x06
+#define Panel661_1280x960 0x07
+#define Panel661_1152x768 0x08
+#define Panel661_1400x1050 0x09
+#define Panel661_1280x768 0x0a
+#define Panel661_1600x1200 0x0b
+#define Panel661_1280x800 0x0c
+#define Panel661_1680x1050 0x0d
+#define Panel661_1280x720 0x0e
+#define Panel661_Custom 0x0f
+
#define Panel_800x600 0x01 /* Unified values */
-#define Panel_1024x768 0x02
+#define Panel_1024x768 0x02 /* MUST match BIOS values from 0-e */
#define Panel_1280x1024 0x03
#define Panel_640x480 0x04
#define Panel_1024x600 0x05
#define Panel_1280x960 0x07
#define Panel_1152x768 0x08 /* LVDS only */
#define Panel_1400x1050 0x09
-#define Panel_1280x768 0x0a /* LVDS only */
+#define Panel_1280x768 0x0a /* 30xB/C and LVDS only (BIOS: all) */
#define Panel_1600x1200 0x0b
-#define Panel_640x480_2 0x0c
-#define Panel_640x480_3 0x0d
-#define Panel_320x480 0x0e /* fstn - TW: This is fake, can be any */
-#define Panel_Custom 0x0f
-#define Panel_Barco1366 0x10
-#define Panel_848x480 0x11
-#define Panel_1280x800 0x12 /* 661etc: 0x0c */
-#define Panel_1680x1050 0x13 /* 661etc: 0x0d */
+#define Panel_1280x800 0x0c /* 661etc */
+#define Panel_1680x1050 0x0d /* 661etc */
+#define Panel_1280x720 0x0e /* 661etc */
+#define Panel_Custom 0x0f /* MUST BE 0x0f (for DVI DDC detection */
+#define Panel_320x480 0x10 /* SiS 550 fstn - TW: This is fake, can be any */
+#define Panel_Barco1366 0x11
+#define Panel_848x480 0x12
+#define Panel_640x480_2 0x13 /* SiS 550 */
+#define Panel_640x480_3 0x14 /* SiS 550 */
+#define Panel_1280x768_2 0x15 /* 30xLV */
+#define Panel_1280x768_3 0x16 /* 30xLV */
/* Index in ModeResInfo table */
#define SIS_RI_320x200 0
#define SIS_RI_856x480 19
#define SIS_RI_1280x768 20
#define SIS_RI_1400x1050 21
-#define SIS_RI_1152x864 22 /* Up to this SiS conforming */
+#define SIS_RI_1152x864 22 /* Up to here SiS conforming */
#define SIS_RI_848x480 23
#define SIS_RI_1360x768 24
#define SIS_RI_1024x600 25
#define SIS_RI_1152x768 26
#define SIS_RI_768x576 27
#define SIS_RI_1360x1024 28
+#define SIS_RI_1680x1050 29
+#define SIS_RI_1280x800 30
+#define SIS_RI_1920x1080 31
+#define SIS_RI_960x540 32
/* CR5F */
#define IsM650 0x80
#define VCLK108_3_300 0x42 /* Index in VCLKData table (300) */
#define VCLK100_300 0x43 /* Index in VCLKData table (300) */
#define VCLK34_300 0x3d /* Index in VCLKData table (300) */
+#define VCLK_CUSTOM_300 0x46
#define VCLK65_315 0x0b /* Index in (VB)VCLKData table (315) */
#define VCLK108_2_315 0x19 /* Index in (VB)VCLKData table (315) */
#define VCLK81_315 0x5b /* Index in (VB)VCLKData table (315) */
-#define VCLK162_315 0x21 /* Index in (VB)VCLKData table (315) */
+#define VCLK162_315 0x5e /* Index in (VB)VCLKData table (315) */
#define VCLK108_3_315 0x45 /* Index in VBVCLKData table (315) */
#define VCLK100_315 0x46 /* Index in VBVCLKData table (315) */
-#define VCLK34_315 0x55 /* Index in VBVCLKData table (315) */
+#define VCLK34_315 0x55
#define VCLK68_315 0x0d
+#define VCLK69_315 0x5c /* deprecated ! Index in VBVCLKData table (315) */
+#define VCLK83_315 0x5c /* Index in VBVCLKData table (315) */
+#define VCLK121_315 0x5d /* Index in VBVCLKData table (315) */
+#define VCLK_1280x720 0x5f
+#define VCLK_1280x768_2 0x60
+#define VCLK_1280x768_3 0x61
+#define VCLK_CUSTOM_315 0x62
+#define VCLK_1280x720_2 0x63
+#define VCLK_720x480 0x67
+#define VCLK_720x576 0x68
+#define VCLK_768x576 0x68
+#define VCLK_848x480 0x65
+#define VCLK_856x480 0x66
+#define VCLK_800x480 0x65
+#define VCLK_1024x576 0x51
+#define VCLK_1152x864 0x64
+#define VCLK_1360x768 0x58
#define TVCLKBASE_300 0x21 /* Indices on TV clocks in VCLKData table (300) */
#define TVCLKBASE_315 0x3a /* Indices on TV clocks in (VB)VCLKData table (315) */
#define HiTVVCLK 0x03 /* Index relative to TVCLKBASE */
#define HiTVSimuVCLK 0x04 /* Index relative to TVCLKBASE */
#define HiTVTextVCLK 0x05 /* Index relative to TVCLKBASE */
-#define YPbPr750pVCLK 0x0f /* NOT relative to TVCLKBASE ! */
+#define YPbPr750pVCLK 0x25 /* Index relative to TVCLKBASE; was 0x0f NOT relative */
/* ------------------------------ */
/*
=============================================================
- for 315 series
+ for 315 series (old data layout)
=============================================================
*/
#define SoftDRAMType 0x80
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* OEM Data for 300 series
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* OEM Data for 315/330 series
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0x02,0x02,0x02
};
-static const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
+static const UCHAR SiS310_LCDDelayCompensation_651301LV[] = /* M650/651 301LV */
{
0x33,0x33,0x33, /* 800x600 (guessed) - new: PanelType, not PanelRes ! */
0x33,0x33,0x33, /* 1024x768 */
0x33,0x33,0x33
};
-static const UCHAR SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
+static const UCHAR SiS310_LCDDelayCompensation_651302LV[] = /* M650/651 302LV */
{
0x33,0x33,0x33, /* 800x600 (guessed) */
0x33,0x33,0x33, /* 1024x768 */
0x33,0x33,0x33
};
-static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB,LV */
+static const UCHAR SiS310_LCDDelayCompensation_3xx301B[] = /* 30xB */
{
0x01,0x01,0x01, /* 800x600 */
0x0C,0x0C,0x0C, /* 1024x768 */
0x02,0x02,0x02
};
+static const UCHAR SiS310_LCDDelayCompensation_3xx301LV[] = /* 315+30xLV */
+{
+ 0x01,0x01,0x01, /* 800x600 */
+ 0x04,0x04,0x04, /* 1024x768 (A531/BIOS 1.14.05f: 4 - works with 6 */
+ 0x0C,0x0C,0x0C, /* 1280x1024 */
+ 0x08,0x08,0x08, /* 640x480 */
+ 0x0C,0x0C,0x0C, /* 1024x600 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1152x864 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1280x960 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1152x768 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1400x1050 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1280x768 (guessed) */
+ 0x0C,0x0C,0x0C, /* 1600x1200 (guessed) */
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02,
+ 0x02,0x02,0x02
+};
+
static const UCHAR SiS310_TVDelayCompensation_301[] = /* 301 */
{
0x02,0x02, /* NTSC Enhanced, Standard */
0x05,0x05
};
-static const UCHAR SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
-{
- 0x0a,0x0a,
- 0x0a,0x0a,
- 0x0a,0x0a
-};
-
static const UCHAR SiS310_TVDelayCompensation_651301LV[] = /* M650, 651, 301LV */
{
0x33,0x33,
0x44,0x44
};
+static const UCHAR SiS310_TVDelayCompensation_LVDS[] = /* LVDS */
+{
+ 0x0a,0x0a,
+ 0x0a,0x0a,
+ 0x0a,0x0a
+};
+
static const UCHAR SiS310_TVAntiFlick1[6][2] =
{
{0x4,0x0},
{ 1, 1,1696,1066,1696,1066}
};
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_1[] =
-{
- {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x35,0x1B,0xA0,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x45,0x1C,0x20,0x3F,0xFF,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
- {{0x49,0x1C,0x40,0x7F,0xFF,0xAD,0x23,0x0A,0x07,0xF3,0x8A,0x12}},
- {{0x4C,0x1C,0x18,0x2F,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_2[] =
-{
- {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x33,0x13,0x01,0x0D,0xFD,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
- {{0x3F,0x1B,0x3D,0x49,0x39,0x54,0x23,0xC0,0x27,0x66,0x30,0x42}},
- {{0x33,0x1B,0x91,0x9D,0x8D,0x8C,0x23,0xF8,0x27,0x9E,0x68,0x42}},
- {{0x43,0x24,0x11,0x1D,0x0D,0xCC,0x23,0x38,0x37,0xDE,0xA8,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xEA,0x23,0x0A,0x07,0x32,0xC6,0x42}}
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_3[] =
-{
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
- {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}
-};
-
-/* LCDA CRT2 data is std */
-
-static const SiS_LVDSDesStruct Compaq1280x1024Des_1[] =
-{
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
-};
-
-static const SiS_LVDSDesStruct Compaq1280x1024Des_2[] =
-{
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
-};
-
-/* Clevo L285/287 (dual-link 1024x768) */
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_1[] =
-{
- {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x2C,0x12,0x9A,0xAE,0x88,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x16,0x0C,0xE6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_2[] =
-{
- {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xE0,0x12,0xB1,0x47,0x30,0x71,0x33}},
- {{0x2D,0x12,0x79,0x96,0x70,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
- {{0x29,0x12,0xB5,0xD2,0xAC,0xF4,0x12,0xD9,0x47,0x44,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
-#if 0
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
- {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
- {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
-#endif
-};
-
-static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_3[] =
-{
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, /* Corrected */
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xC9,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
-};
-
-/* CRT2 data is std */
-
-static const SiS_LVDSDesStruct Clevo1024x768Des_1[] =
-{
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
-};
-
-static const SiS_LVDSDesStruct Clevo1024x768Des_2[] =
-{
- { 1184, 622 },
- { 1184, 597 },
- { 1184, 622 },
- { 1184, 597 },
- { 1152, 622 },
- { 1232, 722 },
- { 0, 0 }
-};
-
/* Asus A2xxxH _2 */
static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Asus1024x768_3[] =
{{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
};
-static const SiS_LVDSDesStruct Asus1024x768Des_1[] =
-{
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
-};
-
-static const SiS_LVDSDesStruct Asus1024x768Des_2[] =
-{
- { 1184, 622 },
- { 1184, 597 },
- { 1184, 622 },
- { 1184, 597 },
- { 1152, 622 },
- { 1232, 722 },
- { 0, 0 }
-};
-
-/* CRT2 data is std */
-
-/* Uniwill N243S9, ECS A928 */
-static const SiS_LVDSDesStruct Uniwill1024x768Des_1[] =
-{
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 805 }
-};
-
-static const SiS_LVDSDesStruct Uniwill1024x768Des_2[] =
-{
- { 1184, 622 },
- { 1184, 597 },
- { 1184, 622 },
- { 1184, 597 },
- { 1152, 650 },
- { 1232, 722 },
- { 0, 805 },
-};
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* OS depending defines
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
*/
/* The choices are: */
-
#define LINUX_KERNEL /* Kernel framebuffer */
/* #define LINUX_XF86 */ /* XFree86 */
-/**********************************************************************/
-#ifdef LINUX_KERNEL /* -------------------------- */
-#include <linux/config.h>
-#include <linux/version.h>
-
-#ifdef CONFIG_FB_SIS_300
-#define SIS300
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-#define SIS315H
-#endif
-
-#if 1
-#define SISFBACCEL /* Include 2D acceleration */
-#endif
-
-#endif
-
-#ifdef LINUX_XF86 /* ----------------------------- */
-#define SIS300
-#define SIS315H
-#endif
-
-/**********************************************************************/
-#ifdef LINUX_XF86
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
-#endif
-
-#ifdef LINUX_KERNEL
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-#define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
-#endif
-
-/**********************************************************************/
-
#ifdef OutPortByte
#undef OutPortByte
-#endif /* OutPortByte */
+#endif
#ifdef OutPortWord
#undef OutPortWord
-#endif /* OutPortWord */
+#endif
#ifdef OutPortLong
#undef OutPortLong
-#endif /* OutPortLong */
+#endif
#ifdef InPortByte
#undef InPortByte
-#endif /* InPortByte */
+#endif
#ifdef InPortWord
#undef InPortWord
-#endif /* InPortWord */
+#endif
#ifdef InPortLong
#undef InPortLong
-#endif /* InPortLong */
+#endif
/**********************************************************************/
-/* LINUX XF86 */
+/* LINUX KERNEL */
/**********************************************************************/
-#ifdef LINUX_XF86
-#define OutPortByte(p,v) outb((CARD16)(p),(CARD8)(v))
-#define OutPortWord(p,v) outw((CARD16)(p),(CARD16)(v))
-#define OutPortLong(p,v) outl((CARD16)(p),(CARD32)(v))
-#define InPortByte(p) inb((CARD16)(p))
-#define InPortWord(p) inw((CARD16)(p))
-#define InPortLong(p) inl((CARD16)(p))
+#ifdef LINUX_KERNEL
+#include <linux/config.h>
+
+#ifdef CONFIG_FB_SIS_300
+#define SIS300
+#endif
+
+#ifdef CONFIG_FB_SIS_315
+#define SIS315H
+#endif
+
+#if !defined(SIS300) && !defined(SIS315H)
+#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
+#warning sisfb will not work!
+#endif
+
+#define OutPortByte(p,v) outb((u8)(v),(SISIOADDRESS)(p))
+#define OutPortWord(p,v) outw((u16)(v),(SISIOADDRESS)(p))
+#define OutPortLong(p,v) outl((u32)(v),(SISIOADDRESS)(p))
+#define InPortByte(p) inb((SISIOADDRESS)(p))
+#define InPortWord(p) inw((SISIOADDRESS)(p))
+#define InPortLong(p) inl((SISIOADDRESS)(p))
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
#endif
/**********************************************************************/
-/* LINUX KERNEL */
+/* XFree86, X.org */
/**********************************************************************/
-#ifdef LINUX_KERNEL
-#define OutPortByte(p,v) outb((u8)(v),(u16)(p))
-#define OutPortWord(p,v) outw((u16)(v),(u16)(p))
-#define OutPortLong(p,v) outl((u32)(v),(u16)(p))
-#define InPortByte(p) inb((u16)(p))
-#define InPortWord(p) inw((u16)(p))
-#define InPortLong(p) inl((u16)(p))
+#ifdef LINUX_XF86
+#define SIS300
+#define SIS315H
+
+#define OutPortByte(p,v) outb((IOADDRESS)(p),(CARD8)(v))
+#define OutPortWord(p,v) outw((IOADDRESS)(p),(CARD16)(v))
+#define OutPortLong(p,v) outl((IOADDRESS)(p),(CARD32)(v))
+#define InPortByte(p) inb((IOADDRESS)(p))
+#define InPortWord(p) inw((IOADDRESS)(p))
+#define InPortLong(p) inl((IOADDRESS)(p))
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
#endif
+/*
+ * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
+ * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
+ *
+ * Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the named License,
+ * or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ */
+
#ifndef _SIS_H
#define _SIS_H
-#if 1
-#define TWDEBUG(x)
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include "osdef.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <video/sisfb.h>
#else
+#include <linux/sisfb.h>
+#endif
+
+#include "vgatypes.h"
+#include "vstruct.h"
+
+#define VER_MAJOR 1
+#define VER_MINOR 7
+#define VER_LEVEL 12
+
+#undef SIS_CONFIG_COMPAT
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/spinlock.h>
+#ifdef CONFIG_COMPAT
+#include <linux/ioctl32.h>
+#define SIS_CONFIG_COMPAT
+#endif
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
+#ifdef __x86_64__
+/* Shouldn't we check for CONFIG_IA32_EMULATION here? */
+#include <asm/ioctl32.h>
+#define SIS_CONFIG_COMPAT
+#endif
+#endif
+
+#undef SISFBDEBUG
+
+#ifdef SISFBDEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
#define TWDEBUG(x) printk(KERN_INFO x "\n");
+#else
+#define DPRINTK(fmt, args...)
+#define TWDEBUG(x)
+#endif
+
+#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
+
+/* To be included in pci_ids.h */
+#ifndef PCI_DEVICE_ID_SI_650_VGA
+#define PCI_DEVICE_ID_SI_650_VGA 0x6325
+#endif
+#ifndef PCI_DEVICE_ID_SI_650
+#define PCI_DEVICE_ID_SI_650 0x0650
+#endif
+#ifndef PCI_DEVICE_ID_SI_651
+#define PCI_DEVICE_ID_SI_651 0x0651
+#endif
+#ifndef PCI_DEVICE_ID_SI_740
+#define PCI_DEVICE_ID_SI_740 0x0740
+#endif
+#ifndef PCI_DEVICE_ID_SI_330
+#define PCI_DEVICE_ID_SI_330 0x0330
+#endif
+#ifndef PCI_DEVICE_ID_SI_660_VGA
+#define PCI_DEVICE_ID_SI_660_VGA 0x6330
+#endif
+#ifndef PCI_DEVICE_ID_SI_661
+#define PCI_DEVICE_ID_SI_661 0x0661
+#endif
+#ifndef PCI_DEVICE_ID_SI_741
+#define PCI_DEVICE_ID_SI_741 0x0741
+#endif
+#ifndef PCI_DEVICE_ID_SI_660
+#define PCI_DEVICE_ID_SI_660 0x0660
+#endif
+#ifndef PCI_DEVICE_ID_SI_760
+#define PCI_DEVICE_ID_SI_760 0x0760
+#endif
+
+/* To be included in fb.h */
+#ifndef FB_ACCEL_SIS_GLAMOUR_2
+#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
+#endif
+#ifndef FB_ACCEL_SIS_XABRE
+#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 760 */
+#endif
+
+#define MAX_ROM_SCAN 0x10000
+
+/* ivideo->caps */
+#define HW_CURSOR_CAP 0x80
+#define TURBO_QUEUE_CAP 0x40
+#define AGP_CMD_QUEUE_CAP 0x20
+#define VM_CMD_QUEUE_CAP 0x10
+#define MMIO_CMD_QUEUE_CAP 0x08
+
+/* For 300 series */
+#define TURBO_QUEUE_AREA_SIZE 0x80000 /* 512K */
+#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */
+
+/* For 315/Xabre series */
+#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */
+#define COMMAND_QUEUE_THRESHOLD 0x1F
+#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */
+
+#define SIS_OH_ALLOC_SIZE 4000
+#define SENTINEL 0x7fffffff
+
+#define SEQ_ADR 0x14
+#define SEQ_DATA 0x15
+#define DAC_ADR 0x18
+#define DAC_DATA 0x19
+#define CRTC_ADR 0x24
+#define CRTC_DATA 0x25
+#define DAC2_ADR (0x16-0x30)
+#define DAC2_DATA (0x17-0x30)
+#define VB_PART1_ADR (0x04-0x30)
+#define VB_PART1_DATA (0x05-0x30)
+#define VB_PART2_ADR (0x10-0x30)
+#define VB_PART2_DATA (0x11-0x30)
+#define VB_PART3_ADR (0x12-0x30)
+#define VB_PART3_DATA (0x13-0x30)
+#define VB_PART4_ADR (0x14-0x30)
+#define VB_PART4_DATA (0x15-0x30)
+
+#define SISSR ivideo->SiS_Pr.SiS_P3c4
+#define SISCR ivideo->SiS_Pr.SiS_P3d4
+#define SISDACA ivideo->SiS_Pr.SiS_P3c8
+#define SISDACD ivideo->SiS_Pr.SiS_P3c9
+#define SISPART1 ivideo->SiS_Pr.SiS_Part1Port
+#define SISPART2 ivideo->SiS_Pr.SiS_Part2Port
+#define SISPART3 ivideo->SiS_Pr.SiS_Part3Port
+#define SISPART4 ivideo->SiS_Pr.SiS_Part4Port
+#define SISPART5 ivideo->SiS_Pr.SiS_Part5Port
+#define SISDAC2A SISPART5
+#define SISDAC2D (SISPART5 + 1)
+#define SISMISCR (ivideo->SiS_Pr.RelIO + 0x1c)
+#define SISMISCW ivideo->SiS_Pr.SiS_P3c2
+#define SISINPSTAT (ivideo->SiS_Pr.RelIO + 0x2a)
+#define SISPEL ivideo->SiS_Pr.SiS_P3c6
+
+#define IND_SIS_PASSWORD 0x05 /* SRs */
+#define IND_SIS_COLOR_MODE 0x06
+#define IND_SIS_RAMDAC_CONTROL 0x07
+#define IND_SIS_DRAM_SIZE 0x14
+#define IND_SIS_MODULE_ENABLE 0x1E
+#define IND_SIS_PCI_ADDRESS_SET 0x20
+#define IND_SIS_TURBOQUEUE_ADR 0x26
+#define IND_SIS_TURBOQUEUE_SET 0x27
+#define IND_SIS_POWER_ON_TRAP 0x38
+#define IND_SIS_POWER_ON_TRAP2 0x39
+#define IND_SIS_CMDQUEUE_SET 0x26
+#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
+
+#define IND_SIS_AGP_IO_PAD 0x48
+
+#define SIS_CRT2_WENABLE_300 0x24 /* Part1 */
+#define SIS_CRT2_WENABLE_315 0x2F
+
+#define SIS_PASSWORD 0x86 /* SR05 */
+#define SIS_INTERLACED_MODE 0x20 /* SR06 */
+#define SIS_8BPP_COLOR_MODE 0x0
+#define SIS_15BPP_COLOR_MODE 0x1
+#define SIS_16BPP_COLOR_MODE 0x2
+#define SIS_32BPP_COLOR_MODE 0x4
+
+#define SIS_ENABLE_2D 0x40 /* SR1E */
+
+#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
+#define SIS_PCI_ADDR_ENABLE 0x80
+
+#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330 series SR26 */
+#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
+#define SIS_MMIO_CMD_ENABLE 0x20
+#define SIS_CMD_QUEUE_SIZE_512k 0x00
+#define SIS_CMD_QUEUE_SIZE_1M 0x04
+#define SIS_CMD_QUEUE_SIZE_2M 0x08
+#define SIS_CMD_QUEUE_SIZE_4M 0x0C
+#define SIS_CMD_QUEUE_RESET 0x01
+#define SIS_CMD_AUTO_CORR 0x02
+
+#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
+#define SIS_MODE_SELECT_CRT2 0x02
+#define SIS_VB_OUTPUT_COMPOSITE 0x04
+#define SIS_VB_OUTPUT_SVIDEO 0x08
+#define SIS_VB_OUTPUT_SCART 0x10
+#define SIS_VB_OUTPUT_LCD 0x20
+#define SIS_VB_OUTPUT_CRT2 0x40
+#define SIS_VB_OUTPUT_HIVISION 0x80
+
+#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
+#define SIS_DRIVER_MODE 0x40
+
+#define SIS_VB_COMPOSITE 0x01 /* CR32 */
+#define SIS_VB_SVIDEO 0x02
+#define SIS_VB_SCART 0x04
+#define SIS_VB_LCD 0x08
+#define SIS_VB_CRT2 0x10
+#define SIS_CRT1 0x20
+#define SIS_VB_HIVISION 0x40
+#define SIS_VB_YPBPR 0x80
+#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
+ SIS_VB_SCART | SIS_VB_HIVISION | SIS_VB_YPBPR)
+
+#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
+#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
+#define SIS_EXTERNAL_CHIP_LVDS 0x02
+#define SIS_EXTERNAL_CHIP_TRUMPION 0x03
+#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04
+#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05
+#define SIS310_EXTERNAL_CHIP_LVDS 0x02
+#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03
+
+#define SIS_AGP_2X 0x20 /* CR48 */
+
+#define HW_DEVICE_EXTENSION SIS_HW_INFO
+#define PHW_DEVICE_EXTENSION PSIS_HW_INFO
+
+/* Useful macros */
+#define inSISREG(base) inb(base)
+#define outSISREG(base,val) outb(val,base)
+#define orSISREG(base,val) do { \
+ u8 __Temp = inb(base); \
+ outSISREG(base, __Temp | (val)); \
+ } while (0)
+#define andSISREG(base,val) do { \
+ u8 __Temp = inb(base); \
+ outSISREG(base, __Temp & (val)); \
+ } while (0)
+#define inSISIDXREG(base,idx,var) do { \
+ outb(idx,base); var=inb((base)+1); \
+ } while (0)
+#define outSISIDXREG(base,idx,val) do { \
+ outb(idx,base); outb((val),(base)+1); \
+ } while (0)
+#define orSISIDXREG(base,idx,val) do { \
+ u8 __Temp; \
+ outb(idx,base); \
+ __Temp = inb((base)+1)|(val); \
+ outSISIDXREG(base,idx,__Temp); \
+ } while (0)
+#define andSISIDXREG(base,idx,and) do { \
+ u8 __Temp; \
+ outb(idx,base); \
+ __Temp = inb((base)+1)&(and); \
+ outSISIDXREG(base,idx,__Temp); \
+ } while (0)
+#define setSISIDXREG(base,idx,and,or) do { \
+ u8 __Temp; \
+ outb(idx,base); \
+ __Temp = (inb((base)+1)&(and))|(or); \
+ outSISIDXREG(base,idx,__Temp); \
+ } while (0)
+
+/* MMIO access macros */
+#define MMIO_IN8(base, offset) readb((base+offset))
+#define MMIO_IN16(base, offset) readw((base+offset))
+#define MMIO_IN32(base, offset) readl((base+offset))
+
+#define MMIO_OUT8(base, offset, val) writeb(((u8)(val)), (base+offset))
+#define MMIO_OUT16(base, offset, val) writew(((u16)(val)), (base+offset))
+#define MMIO_OUT32(base, offset, val) writel(((u32)(val)), (base+offset))
+
+/* Queue control MMIO registers */
+#define Q_BASE_ADDR 0x85C0 /* Base address of software queue */
+#define Q_WRITE_PTR 0x85C4 /* Current write pointer */
+#define Q_READ_PTR 0x85C8 /* Current read pointer */
+#define Q_STATUS 0x85CC /* queue status */
+
+#define MMIO_QUEUE_PHYBASE Q_BASE_ADDR
+#define MMIO_QUEUE_WRITEPORT Q_WRITE_PTR
+#define MMIO_QUEUE_READPORT Q_READ_PTR
+
+enum _SIS_CMDTYPE {
+ MMIO_CMD = 0,
+ AGP_CMD_QUEUE,
+ VM_CMD_QUEUE,
+};
+typedef unsigned int SIS_CMDTYPE;
+
+/* Our "par" */
+struct sis_video_info {
+ int cardnumber;
+ struct fb_info *memyselfandi;
+
+ SIS_HW_INFO sishw_ext;
+ SiS_Private SiS_Pr;
+
+ sisfb_info sisfbinfo; /* For ioctl SISFB_GET_INFO */
+
+ struct fb_var_screeninfo default_var;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ struct fb_fix_screeninfo sisfb_fix;
+ u32 pseudo_palette[17];
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ struct display sis_disp;
+ struct display_switch sisfb_sw;
+ struct {
+ u16 red, green, blue, pad;
+ } sis_palette[256];
+ union {
+#ifdef FBCON_HAS_CFB16
+ u16 cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+ u32 cfb32[16];
+#endif
+ } sis_fbcon_cmap;
+#endif
+
+ struct sisfb_monitor {
+ u16 hmin;
+ u16 hmax;
+ u16 vmin;
+ u16 vmax;
+ u32 dclockmax;
+ u8 feature;
+ BOOLEAN datavalid;
+ } sisfb_thismonitor;
+
+ int chip_id;
+ char myid[40];
+
+ struct pci_dev *nbridge;
+
+ int mni; /* Mode number index */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ int currcon;
+#endif
+
+ unsigned long video_size;
+ unsigned long video_base;
+ unsigned long mmio_size;
+ unsigned long mmio_base;
+ unsigned long vga_base;
+
+ unsigned long video_vbase;
+ unsigned long mmio_vbase;
+ char * bios_vbase;
+ char * bios_abase;
+
+ int mtrr;
+
+ u32 sisfb_mem;
+
+ u32 sisfb_parm_mem;
+ int sisfb_accel;
+ int sisfb_ypan;
+ int sisfb_max;
+ int sisfb_userom;
+ int sisfb_useoem;
+ int sisfb_mode_idx;
+ int sisfb_parm_rate;
+ int sisfb_crt1off;
+ int sisfb_forcecrt1;
+ int sisfb_crt2type;
+ int sisfb_crt2flags;
+ int sisfb_dstn;
+ int sisfb_fstn;
+ int sisfb_tvplug;
+ int sisfb_tvstd;
+ int sisfb_filter;
+ int sisfb_nocrt2rate;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ int sisfb_inverse;
+#endif
+
+ u32 heapstart; /* offset */
+ unsigned long sisfb_heap_start; /* address */
+ unsigned long sisfb_heap_end; /* address */
+ u32 sisfb_heap_size;
+ int havenoheap;
+#if 0
+ SIS_HEAP sisfb_heap;
#endif
+
+ int video_bpp;
+ int video_cmap_len;
+ int video_width;
+ int video_height;
+ unsigned int refresh_rate;
+
+ unsigned int chip;
+ u8 revision_id;
+
+ int video_linelength; /* real pitch */
+ int scrnpitchCRT1; /* pitch regarding interlace */
+
+ u16 DstColor; /* For 2d acceleration */
+ u32 SiS310_AccelDepth;
+ u32 CommandReg;
+ int cmdqueuelength;
+
+ spinlock_t lockaccel; /* Do not use outside of kernel! */
+
+ unsigned int pcibus;
+ unsigned int pcislot;
+ unsigned int pcifunc;
+
+ int accel;
+
+ u16 subsysvendor;
+ u16 subsysdevice;
+
+ u32 vbflags; /* Replacing deprecated stuff from above */
+ u32 currentvbflags;
+
+ int lcdxres, lcdyres;
+ int lcddefmodeidx, tvdefmodeidx, defmodeidx;
+
+ int current_bpp;
+ int current_width;
+ int current_height;
+ int current_htotal;
+ int current_vtotal;
+ int current_linelength;
+ __u32 current_pixclock;
+ int current_refresh_rate;
+
+ u8 mode_no;
+ u8 rate_idx;
+ int modechanged;
+ unsigned char modeprechange;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ u8 sisfb_lastrates[128];
+#endif
+
+ int newrom;
+ int registered;
+#ifdef SIS_CONFIG_COMPAT
+ int ioctl32registered;
+ int ioctl32vblankregistered;
+#endif
+
+ int sisvga_engine;
+ int hwcursor_size;
+ int CRT2_write_enable;
+ u8 caps;
+
+ u8 detectedpdc;
+ u8 detectedpdca;
+ u8 detectedlcda;
+
+ unsigned long hwcursor_vbase;
+
+ int chronteltype;
+ int tvxpos, tvypos;
+ u8 p2_1f,p2_20,p2_2b,p2_42,p2_43,p2_01,p2_02;
+ int tvx, tvy;
+
+ u8 sisfblocked;
+
+ struct sis_video_info *next;
+};
+
+typedef struct _SIS_OH {
+ struct _SIS_OH *poh_next;
+ struct _SIS_OH *poh_prev;
+ u32 offset;
+ u32 size;
+} SIS_OH;
+
+typedef struct _SIS_OHALLOC {
+ struct _SIS_OHALLOC *poha_next;
+ SIS_OH aoh[1];
+} SIS_OHALLOC;
+
+typedef struct _SIS_HEAP {
+ SIS_OH oh_free;
+ SIS_OH oh_used;
+ SIS_OH *poh_freelist;
+ SIS_OHALLOC *poha_chain;
+ u32 max_freesize;
+ struct sis_video_info *vinfo;
+} SIS_HEAP;
+
#endif
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
*
- * Based on the XFree86 driver's sis300_accel.c which is
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
- * and sis310_accel.c which is
+ * Based on the XFree86/X.org driver which is
* Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
*
* Author: Thomas Winischhofer <thomas@winischhofer.net>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/console.h>
#include <linux/selection.h>
#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/vt_kern.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/agp_backend.h>
-
#include <linux/types.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#include <linux/sisfb.h>
-#else
-#include <video/sisfb.h>
-#endif
-
#include <asm/io.h>
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb32.h>
#endif
-#include "osdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
-#include "sis_accel.h"
#include "sis.h"
+#include "sis_accel.h"
-extern struct video_info ivideo;
-extern VGA_ENGINE sisvga_engine;
-extern int sisfb_accel;
-
-static const int sisALUConv[] =
+static const u8 sisALUConv[] =
{
0x00, /* dest = 0; 0, GXclear, 0 */
0x88, /* dest &= src; DSa, GXand, 0x1 */
0xFF, /* dest = 0xFF; 1, GXset, 0xF */
};
/* same ROP but with Pattern as Source */
-static const int sisPatALUConv[] =
+static const u8 sisPatALUConv[] =
{
0x00, /* dest = 0; 0, GXclear, 0 */
0xA0, /* dest &= src; DPa, GXand, 0x1 */
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
-static const unsigned char myrops[] = {
+static const int myrops[] = {
3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
- };
+};
#endif
/* 300 series ----------------------------------------------------- */
#ifdef CONFIG_FB_SIS_300
static void
-SiS300Sync(void)
+SiS300Sync(struct sis_video_info *ivideo)
{
SiS300Idle
}
static void
-SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
- unsigned int planemask, int trans_color)
+SiS300SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int xdir, int ydir,
+ int rop, int trans_color)
{
- SiS300SetupDSTColorDepth(ivideo.DstColor);
- SiS300SetupSRCPitch(ivideo.video_linelength)
- SiS300SetupDSTRect(ivideo.video_linelength, -1)
+ SiS300SetupDSTColorDepth(ivideo->DstColor);
+ SiS300SetupSRCPitch(ivideo->video_linelength)
+ SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
if(trans_color != -1) {
SiS300SetupROP(0x0A)
}
static void
-SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
- int width, int height)
+SiS300SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x,
+ int src_y, int dst_x, int dst_y, int width, int height)
{
- long srcbase, dstbase;
+ u32 srcbase = 0, dstbase = 0;
- srcbase = dstbase = 0;
- if (src_y >= 2048) {
- srcbase = ivideo.video_linelength * src_y;
+ if(src_y >= 2048) {
+ srcbase = ivideo->video_linelength * src_y;
src_y = 0;
}
- if (dst_y >= 2048) {
- dstbase = ivideo.video_linelength * dst_y;
+ if(dst_y >= 2048) {
+ dstbase = ivideo->video_linelength * dst_y;
dst_y = 0;
}
SiS300SetupSRCBase(srcbase);
SiS300SetupDSTBase(dstbase);
- if(!(ivideo.CommandReg & X_INC)) {
+ if(!(ivideo->CommandReg & X_INC)) {
src_x += width-1;
dst_x += width-1;
}
- if(!(ivideo.CommandReg & Y_INC)) {
+ if(!(ivideo->CommandReg & Y_INC)) {
src_y += height-1;
dst_y += height-1;
}
}
static void
-SiS300SetupForSolidFill(int color, int rop, unsigned int planemask)
+SiS300SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
{
SiS300SetupPATFG(color)
- SiS300SetupDSTRect(ivideo.video_linelength, -1)
- SiS300SetupDSTColorDepth(ivideo.DstColor);
+ SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
+ SiS300SetupDSTColorDepth(ivideo->DstColor);
SiS300SetupROP(sisPatALUConv[rop])
SiS300SetupCMDFlag(PATFG)
}
static void
-SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
+SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
{
- long dstbase;
+ u32 dstbase = 0;
- dstbase = 0;
if(y >= 2048) {
- dstbase = ivideo.video_linelength * y;
+ dstbase = ivideo->video_linelength * y;
y = 0;
}
SiS300SetupDSTBase(dstbase)
#ifdef CONFIG_FB_SIS_315
static void
-SiS310Sync(void)
+SiS310Sync(struct sis_video_info *ivideo)
{
SiS310Idle
}
static void
-SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
- unsigned int planemask, int trans_color)
+SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int trans_color)
{
- SiS310SetupDSTColorDepth(ivideo.DstColor);
- SiS310SetupSRCPitch(ivideo.video_linelength)
- SiS310SetupDSTRect(ivideo.video_linelength, -1)
- if (trans_color != -1) {
+ SiS310SetupDSTColorDepth(ivideo->DstColor);
+ SiS310SetupSRCPitch(ivideo->video_linelength)
+ SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+ if(trans_color != -1) {
SiS310SetupROP(0x0A)
SiS310SetupSRCTrans(trans_color)
SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
/* Set command - not needed, both 0 */
/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
}
- SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+ SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
/* The 315 series is smart enough to know the direction */
}
static void
-SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
- int width, int height)
+SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int src_y,
+ int dst_x, int dst_y, int width, int height)
{
- long srcbase, dstbase;
- int mymin, mymax;
-
- srcbase = dstbase = 0;
- mymin = min(src_y, dst_y);
- mymax = max(src_y, dst_y);
+ u32 srcbase = 0, dstbase = 0;
+ int mymin = min(src_y, dst_y);
+ int mymax = max(src_y, dst_y);
/* Although the chip knows the direction to use
* if the source and destination areas overlap,
*/
if((mymax - mymin) < height) {
if((src_y >= 2048) || (dst_y >= 2048)) {
- srcbase = ivideo.video_linelength * mymin;
- dstbase = ivideo.video_linelength * mymin;
+ srcbase = ivideo->video_linelength * mymin;
+ dstbase = ivideo->video_linelength * mymin;
src_y -= mymin;
dst_y -= mymin;
}
} else {
if(src_y >= 2048) {
- srcbase = ivideo.video_linelength * src_y;
+ srcbase = ivideo->video_linelength * src_y;
src_y = 0;
}
if(dst_y >= 2048) {
- dstbase = ivideo.video_linelength * dst_y;
+ dstbase = ivideo->video_linelength * dst_y;
dst_y = 0;
}
}
}
static void
-SiS310SetupForSolidFill(int color, int rop, unsigned int planemask)
+SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
{
SiS310SetupPATFG(color)
- SiS310SetupDSTRect(ivideo.video_linelength, -1)
- SiS310SetupDSTColorDepth(ivideo.DstColor);
+ SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+ SiS310SetupDSTColorDepth(ivideo->DstColor);
SiS310SetupROP(sisPatALUConv[rop])
- SiS310SetupCMDFlag(PATFG | ivideo.SiS310_AccelDepth)
+ SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
}
static void
-SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
+SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
{
- long dstbase;
+ u32 dstbase = 0;
- dstbase = 0;
if(y >= 2048) {
- dstbase = ivideo.video_linelength * y;
+ dstbase = ivideo->video_linelength * y;
y = 0;
}
SiS310SetupDSTBase(dstbase)
/* The exported routines */
-int sisfb_initaccel(void)
+int sisfb_initaccel(struct sis_video_info *ivideo)
{
#ifdef SISFB_USE_SPINLOCKS
- spin_lock_init(&ivideo.lockaccel);
+ spin_lock_init(&ivideo->lockaccel);
#endif
return(0);
}
-void sisfb_syncaccel(void)
+void sisfb_syncaccel(struct sis_video_info *ivideo)
{
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
- SiS310Sync();
+ SiS310Sync(ivideo);
#endif
}
}
int fbcon_sis_sync(struct fb_info *info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
CRITFLAGS
- if(!ivideo.accel)
+ if(!ivideo->accel)
return 0;
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
- SiS310Sync();
+ SiS310Sync(ivideo);
#endif
}
CRITEND
void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
- int col=0;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ u32 col = 0;
+ u32 vxres = info->var.xres_virtual;
+ u32 vyres = info->var.yres_virtual;
+ int width, height;
CRITFLAGS
- TWDEBUG("Inside sis_fillrect");
- if(!rect->width || !rect->height)
- return;
+ if(info->state != FBINFO_STATE_RUNNING) {
+ return;
+ }
- if(!ivideo.accel) {
+ if(!ivideo->accel) {
cfb_fillrect(info, rect);
return;
}
+ if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) {
+ return;
+ }
+
+ /* Clipping */
+ width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
+ height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
+
switch(info->var.bits_per_pixel) {
case 8: col = rect->color;
break;
- case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
- break;
+ case 16:
case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
break;
}
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
CRITBEGIN
- SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
- SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+ SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+ SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
CRITEND
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
CRITBEGIN
- SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
- SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+ SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+ SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
CRITEND
- SiS310Sync();
+ SiS310Sync(ivideo);
#endif
}
void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
- int xdir, ydir;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ u32 vxres = info->var.xres_virtual;
+ u32 vyres = info->var.yres_virtual;
+ int width = area->width;
+ int height = area->height;
CRITFLAGS
- TWDEBUG("Inside sis_copyarea");
- if(!ivideo.accel) {
+ if(info->state != FBINFO_STATE_RUNNING) {
+ return;
+ }
+
+ if(!ivideo->accel) {
cfb_copyarea(info, area);
return;
}
- if(!area->width || !area->height)
+ if(!width || !height ||
+ area->sx >= vxres || area->sy >= vyres ||
+ area->dx >= vxres || area->dy >= vyres) {
return;
+ }
- if(area->sx < area->dx) xdir = 0;
- else xdir = 1;
- if(area->sy < area->dy) ydir = 0;
- else ydir = 1;
+ /* Clipping */
+ if((area->sx + width) > vxres) width = vxres - area->sx;
+ if((area->dx + width) > vxres) width = vxres - area->dx;
+ if((area->sy + height) > vyres) height = vyres - area->sy;
+ if((area->dy + height) > vyres) height = vyres - area->dy;
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
+ int xdir, ydir;
+
+ if(area->sx < area->dx) xdir = 0;
+ else xdir = 1;
+ if(area->sy < area->dy) ydir = 0;
+ else ydir = 1;
+
CRITBEGIN
- SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
- SiS300SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+ SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+ SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
+ width, height);
CRITEND
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
CRITBEGIN
- SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
- SiS310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+ SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+ SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
+ width, height);
CRITEND
- SiS310Sync();
+ SiS310Sync(ivideo);
#endif
}
}
void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
int dsty, int dstx, int height, int width)
{
- int xdir, ydir;
+ struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
+
CRITFLAGS
- if(!ivideo.accel) {
- switch(ivideo.video_bpp) {
+ if(!ivideo->accel) {
+ switch(ivideo->video_bpp) {
case 8:
#ifdef FBCON_HAS_CFB8
fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
width *= fontwidth(p);
height *= fontheight(p);
- if(srcx < dstx) xdir = 0;
- else xdir = 1;
- if(srcy < dsty) ydir = 0;
- else ydir = 1;
-
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
+ int xdir, ydir;
+
+ if(srcx < dstx) xdir = 0;
+ else xdir = 1;
+ if(srcy < dsty) ydir = 0;
+ else ydir = 1;
+
CRITBEGIN
- SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
- SiS300SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+ SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+ SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
CRITEND
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
CRITBEGIN
- SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
- SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+ SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+ SiS310SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
CRITEND
- SiS310Sync();
-#if 0
- printk(KERN_INFO "sis_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
- srcx, srcy, dstx, dsty, width, height);
-#endif
+ SiS310Sync(ivideo);
#endif
}
}
static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
int srcy, int srcx, int height, int width, int color)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
CRITFLAGS
srcx *= fontwidth(p);
width *= fontwidth(p);
height *= fontheight(p);
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
CRITBEGIN
- SiS300SetupForSolidFill(color, 3, 0);
- SiS300SubsequentSolidFillRect(srcx, srcy, width, height);
+ SiS300SetupForSolidFill(ivideo, color, 3);
+ SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
CRITEND
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
CRITBEGIN
- SiS310SetupForSolidFill(color, 3, 0);
- SiS310SubsequentSolidFillRect(srcx, srcy, width, height);
+ SiS310SetupForSolidFill(ivideo, color, 3);
+ SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
CRITEND
- SiS310Sync();
+ SiS310Sync(ivideo);
#endif
}
}
void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
int srcy, int srcx, int height, int width)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
u32 bgx;
- if(!ivideo.accel) {
+ if(!ivideo->accel) {
#ifdef FBCON_HAS_CFB8
fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
#endif
void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
int srcy, int srcx, int height, int width)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
u32 bgx;
- if(!ivideo.accel) {
+
+ if(!ivideo->accel) {
#ifdef FBCON_HAS_CFB16
fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
#endif
void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
int srcy, int srcx, int height, int width)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
u32 bgx;
- if(!ivideo.accel) {
+ if(!ivideo->accel) {
#ifdef FBCON_HAS_CFB32
fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
#endif
void fbcon_sis_revc(struct display *p, int srcx, int srcy)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
CRITFLAGS
- if(!ivideo.accel) {
- switch(ivideo.video_bpp) {
+ if(!ivideo->accel) {
+ switch(ivideo->video_bpp) {
case 16:
#ifdef FBCON_HAS_CFB16
fbcon_cfb16_revc(p, srcx, srcy);
srcx *= fontwidth(p);
srcy *= fontheight(p);
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
#ifdef CONFIG_FB_SIS_300
CRITBEGIN
- SiS300SetupForSolidFill(0, 0x0a, 0);
- SiS300SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+ SiS300SetupForSolidFill(ivideo, 0, 0x0a);
+ SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
CRITEND
- SiS300Sync();
+ SiS300Sync(ivideo);
#endif
} else {
#ifdef CONFIG_FB_SIS_315
CRITBEGIN
- SiS310SetupForSolidFill(0, 0x0a, 0);
- SiS310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+ SiS310SetupForSolidFill(ivideo, 0, 0x0a);
+ SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
CRITEND
- SiS310Sync();
+ SiS310Sync(ivideo);
#endif
}
}
#ifdef FBCON_HAS_CFB8
struct display_switch fbcon_sis8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = fbcon_sis_bmove,
- .clear = fbcon_sis_clear8,
- .putc = fbcon_cfb8_putc,
- .putcs = fbcon_cfb8_putcs,
- .revc = fbcon_cfb8_revc,
- .clear_margins = fbcon_cfb8_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ .setup = fbcon_cfb8_setup,
+ .bmove = fbcon_sis_bmove,
+ .clear = fbcon_sis_clear8,
+ .putc = fbcon_cfb8_putc,
+ .putcs = fbcon_cfb8_putcs,
+ .revc = fbcon_cfb8_revc,
+ .clear_margins = fbcon_cfb8_clear_margins,
+ .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
#endif
#ifdef FBCON_HAS_CFB16
struct display_switch fbcon_sis16 = {
- .setup = fbcon_cfb16_setup,
- .bmove = fbcon_sis_bmove,
- .clear = fbcon_sis_clear16,
- .putc = fbcon_cfb16_putc,
- .putcs = fbcon_cfb16_putcs,
- .revc = fbcon_sis_revc,
- .clear_margins = fbcon_cfb16_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ .setup = fbcon_cfb16_setup,
+ .bmove = fbcon_sis_bmove,
+ .clear = fbcon_sis_clear16,
+ .putc = fbcon_cfb16_putc,
+ .putcs = fbcon_cfb16_putcs,
+ .revc = fbcon_sis_revc,
+ .clear_margins = fbcon_cfb16_clear_margins,
+ .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
#endif
#ifdef FBCON_HAS_CFB32
struct display_switch fbcon_sis32 = {
- .setup = fbcon_cfb32_setup,
- .bmove = fbcon_sis_bmove,
- .clear = fbcon_sis_clear32,
- .putc = fbcon_cfb32_putc,
- .putcs = fbcon_cfb32_putcs,
- .revc = fbcon_sis_revc,
- .clear_margins = fbcon_cfb32_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+ .setup = fbcon_cfb32_setup,
+ .bmove = fbcon_sis_bmove,
+ .clear = fbcon_sis_clear32,
+ .putc = fbcon_cfb32_putc,
+ .putcs = fbcon_cfb32_putcs,
+ .revc = fbcon_sis_revc,
+ .clear_margins = fbcon_cfb32_clear_margins,
+ .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
#endif
#ifdef SISFB_USE_SPINLOCKS
#include <linux/spinlock.h>
-#define CRITBEGIN spin_lock_irqsave(&ivideo.lockaccel), critflags);
-#define CRITEND spin_unlock_irqrestore(&ivideo.lockaccel), critflags);
+#define CRITBEGIN spin_lock_irqsave(&ivideo->lockaccel, critflags);
+#define CRITEND spin_unlock_irqrestore(&ivideo->lockaccel, critflags);
#define CRITFLAGS unsigned long critflags;
#else
#define CRITBEGIN
#define A3D_FUNCTION 0x00000008 /* 3D command ? */
#define CLEAR_Z_BUFFER 0x00000009 /* ? */
#define GRADIENT_FILL 0x0000000A /* Gradient fill */
-#define STRETCH_BITBLT 0x0000000B /* Stretched Blit */
/* source select */
#define SRCVIDEO 0x00000000 /* source is video RAM */
#define DSTAGP 0x02000000
#define DSTVIDEO 0x02000000
-/* Line */
-#define LINE_STYLE 0x00800000
-#define NO_RESET_COUNTER 0x00400000
-#define NO_LAST_PIXEL 0x00200000
-
/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
#define COLOR_TO_MONO 0x00100000
#define AA_TEXT 0x00200000
#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */
-/* Line registers */
-#define LINE_X0 SRC_Y
-#define LINE_X1 DST_Y
-#define LINE_Y0 SRC_X
-#define LINE_Y1 DST_X
-#define LINE_COUNT RECT_WIDTH
-#define LINE_STYLE_PERIOD RECT_HEIGHT
-#define LINE_STYLE_0 MONO_MASK
-#define LINE_STYLE_1 0x8230
-#define LINE_XN PATTERN_REG
-#define LINE_YN PATTERN_REG+2
-
/* Transparent bitblit registers */
#define TRANS_DST_KEY_HIGH PAT_FGCOLOR
#define TRANS_DST_KEY_LOW PAT_BGCOLOR
#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR
#define TRANS_SRC_KEY_LOW SRC_BGCOLOR
-/* Queue */
-#define Q_BASE_ADDR 0x85C0 /* Base address of software queue (?) */
-#define Q_WRITE_PTR 0x85C4 /* Current write pointer (?) */
-#define Q_READ_PTR 0x85C8 /* Current read pointer (?) */
-#define Q_STATUS 0x85CC /* queue status */
-
-
-#define MMIO_IN8(base, offset) \
- *(volatile u8 *)(((u8*)(base)) + (offset))
-#define MMIO_IN16(base, offset) \
- *(volatile u16 *)(void *)(((u8*)(base)) + (offset))
-#define MMIO_IN32(base, offset) \
- *(volatile u32 *)(void *)(((u8*)(base)) + (offset))
-#define MMIO_OUT8(base, offset, val) \
- *(volatile u8 *)(((u8*)(base)) + (offset)) = (val)
-#define MMIO_OUT16(base, offset, val) \
- *(volatile u16 *)(void *)(((u8*)(base)) + (offset)) = (val)
-#define MMIO_OUT32(base, offset, val) \
- *(volatile u32 *)(void *)(((u8*)(base)) + (offset)) = (val)
+/* Store queue length in par */
+#define CmdQueLen ivideo->cmdqueuelength
/* ------------- SiS 300 series -------------- */
-/* Macros to do useful things with the SIS BitBLT engine */
-
-/* BR(16) (0x8420):
+/* BR(16) (0x8240):
bit 31 2D engine: 1 is idle,
bit 30 3D engine: 1 is idle,
bit 29 Command queue: 1 is empty
-
bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0]
-
bits 15:0: Current command queue length
*/
-/* TW: BR(16)+2 = 0x8242 */
-
-int CmdQueLen;
-
#define SiS300Idle \
{ \
- while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
- while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
- while( (MMIO_IN16(ivideo.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
- CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, 0x8240); \
+ while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ while((MMIO_IN16(ivideo->mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \
+ CmdQueLen = MMIO_IN16(ivideo->mmio_vbase, 0x8240); \
}
-/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
+/* (do three times, because 2D engine seems quite unsure about whether or not it's idle) */
#define SiS300SetupSRCBase(base) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(0), base);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(0), base);\
+ CmdQueLen--;
#define SiS300SetupSRCPitch(pitch) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, BR(1), pitch);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT16(ivideo->mmio_vbase, BR(1), pitch);\
+ CmdQueLen--;
#define SiS300SetupSRCXY(x,y) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(2), (x)<<16 | (y) );\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(2), (x)<<16 | (y) );\
+ CmdQueLen--;
#define SiS300SetupDSTBase(base) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(4), base);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(4), base);\
+ CmdQueLen--;
#define SiS300SetupDSTXY(x,y) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(3), (x)<<16 | (y) );\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(3), (x)<<16 | (y) );\
+ CmdQueLen--;
#define SiS300SetupDSTRect(x,y) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(5), (y)<<16 | (x) );\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(5), (y)<<16 | (x) );\
+ CmdQueLen--;
#define SiS300SetupDSTColorDepth(bpp) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, BR(1)+2, bpp);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT16(ivideo->mmio_vbase, BR(1)+2, bpp);\
+ CmdQueLen--;
#define SiS300SetupRect(w,h) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(6), (h)<<16 | (w) );\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(6), (h)<<16 | (w) );\
+ CmdQueLen--;
#define SiS300SetupPATFG(color) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(7), color);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(7), color);\
+ CmdQueLen--;
#define SiS300SetupPATBG(color) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(8), color);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(8), color);\
+ CmdQueLen--;
#define SiS300SetupSRCFG(color) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(9), color);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(9), color);\
+ CmdQueLen--;
#define SiS300SetupSRCBG(color) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(10), color);\
- CmdQueLen --;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(10), color);\
+ CmdQueLen--;
/* 0x8224 src colorkey high */
/* 0x8228 src colorkey low */
/* 0x821c dest colorkey high */
/* 0x8220 dest colorkey low */
#define SiS300SetupSRCTrans(color) \
- if (CmdQueLen <= 1) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, 0x8224, color);\
- MMIO_OUT32(ivideo.mmio_vbase, 0x8228, color);\
- CmdQueLen -= 2;
+ if(CmdQueLen <= 1) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, 0x8224, color);\
+ MMIO_OUT32(ivideo->mmio_vbase, 0x8228, color);\
+ CmdQueLen -= 2;
#define SiS300SetupDSTTrans(color) \
- if (CmdQueLen <= 1) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, 0x821C, color); \
- MMIO_OUT32(ivideo.mmio_vbase, 0x8220, color); \
- CmdQueLen -= 2;
+ if(CmdQueLen <= 1) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, 0x821C, color); \
+ MMIO_OUT32(ivideo->mmio_vbase, 0x8220, color); \
+ CmdQueLen -= 2;
#define SiS300SetupMONOPAT(p0,p1) \
- if (CmdQueLen <= 1) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(11), p0);\
- MMIO_OUT32(ivideo.mmio_vbase, BR(12), p1);\
- CmdQueLen -= 2;
+ if(CmdQueLen <= 1) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(11), p0);\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(12), p1);\
+ CmdQueLen -= 2;
#define SiS300SetupClipLT(left,top) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\
+ CmdQueLen--;
#define SiS300SetupClipRB(right,bottom) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\
+ CmdQueLen--;
/* General */
#define SiS300SetupROP(rop) \
- ivideo.CommandReg = (rop) << 8;
+ ivideo->CommandReg = (rop) << 8;
#define SiS300SetupCMDFlag(flags) \
- ivideo.CommandReg |= (flags);
+ ivideo->CommandReg |= (flags);
#define SiS300DoCMD \
- if (CmdQueLen <= 1) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(15), ivideo.CommandReg); \
- MMIO_OUT32(ivideo.mmio_vbase, BR(16), 0);\
- CmdQueLen -= 2;
-
-/* Line */
-#define SiS300SetupX0Y0(x,y) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(2), (y)<<16 | (x) );\
- CmdQueLen--;
-
-#define SiS300SetupX1Y1(x,y) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(3), (y)<<16 | (x) );\
- CmdQueLen--;
-
-#define SiS300SetupLineCount(c) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, BR(6), c);\
- CmdQueLen--;
+ if(CmdQueLen <= 1) SiS300Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, BR(15), ivideo->CommandReg); \
+ MMIO_OUT32(ivideo->mmio_vbase, BR(16), 0);\
+ CmdQueLen -= 2;
-#define SiS300SetupStylePeriod(p) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, BR(6)+2, p);\
- CmdQueLen--;
-
-#define SiS300SetupStyleLow(ls) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(11), ls);\
- CmdQueLen--;
-
-#define SiS300SetupStyleHigh(ls) \
- if (CmdQueLen <= 0) SiS300Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, BR(12), ls);\
- CmdQueLen--;
-
-
-
-/* -------------- SiS 315 series --------------- */
+/* -------------- SiS 315/330 series --------------- */
/* Q_STATUS:
bit 31 = 1: All engines idle and all queues empty
bits 23:16: 2D counter 3
bits 15:8: 2D counter 2
bits 7:0: 2D counter 1
-
- Where is the command queue length (current amount of commands the queue
- can accept) on the 315 series?
*/
-/* TW: FIXME: CmdQueLen is... where....? */
-/* We assume a length of 4 bytes per command; since 512K of
- * of RAM are allocated, the number of commands is easily
- * calculated (assuming that there is no 3D support yet)
- * We calculate it very cautiously (128K only) and let the
- * rest to the (never?)-to-come (?) 3D engine. (The 3D engine
- * can use a similar technique, using the remaining 384K,
- * hence a queue overflow is avoided)
- * UPDATE: This technique causes a terrible system latency
- * on integrated chipsets. Disable the queue handling for
- * now.
- */
#define SiS310Idle \
{ \
- while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
- while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
- CmdQueLen = 0; \
- /*CmdQueLen = ((128 * 1024) / 4) - 64; */ \
+ while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ while( (MMIO_IN16(ivideo->mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
+ CmdQueLen = 0; \
}
#define SiS310SetupSRCBase(base) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, SRC_ADDR, base);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, SRC_ADDR, base);\
+ CmdQueLen--;
#define SiS310SetupSRCPitch(pitch) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, SRC_PITCH, pitch);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT16(ivideo->mmio_vbase, SRC_PITCH, pitch);\
+ CmdQueLen--;
#define SiS310SetupSRCXY(x,y) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, SRC_Y, (x)<<16 | (y) );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, SRC_Y, (x)<<16 | (y) );\
+ CmdQueLen--;
#define SiS310SetupDSTBase(base) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, DST_ADDR, base);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, DST_ADDR, base);\
+ CmdQueLen--;
#define SiS310SetupDSTXY(x,y) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, DST_Y, (x)<<16 | (y) );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, DST_Y, (x)<<16 | (y) );\
+ CmdQueLen--;
#define SiS310SetupDSTRect(x,y) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, DST_PITCH, (y)<<16 | (x) );\
+ CmdQueLen--;
#define SiS310SetupDSTColorDepth(bpp) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, AGP_BASE, bpp);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT16(ivideo->mmio_vbase, AGP_BASE, bpp);\
+ CmdQueLen--;
#define SiS310SetupRect(w,h) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\
+ CmdQueLen--;
#define SiS310SetupPATFG(color) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, PAT_FGCOLOR, color);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, PAT_FGCOLOR, color);\
+ CmdQueLen--;
#define SiS310SetupPATBG(color) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, PAT_BGCOLOR, color);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, PAT_BGCOLOR, color);\
+ CmdQueLen--;
#define SiS310SetupSRCFG(color) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, SRC_FGCOLOR, color);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, SRC_FGCOLOR, color);\
+ CmdQueLen--;
#define SiS310SetupSRCBG(color) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, SRC_BGCOLOR, color);\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, SRC_BGCOLOR, color);\
+ CmdQueLen--;
#define SiS310SetupSRCTrans(color) \
- if (CmdQueLen <= 1) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
- MMIO_OUT32(ivideo.mmio_vbase, TRANS_SRC_KEY_LOW, color);\
- CmdQueLen -= 2;
+ if(CmdQueLen <= 1) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_HIGH, color);\
+ MMIO_OUT32(ivideo->mmio_vbase, TRANS_SRC_KEY_LOW, color);\
+ CmdQueLen -= 2;
#define SiS310SetupDSTTrans(color) \
- if (CmdQueLen <= 1) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, TRANS_DST_KEY_HIGH, color); \
- MMIO_OUT32(ivideo.mmio_vbase, TRANS_DST_KEY_LOW, color); \
- CmdQueLen -= 2;
+ if(CmdQueLen <= 1) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_HIGH, color); \
+ MMIO_OUT32(ivideo->mmio_vbase, TRANS_DST_KEY_LOW, color); \
+ CmdQueLen -= 2;
#define SiS310SetupMONOPAT(p0,p1) \
- if (CmdQueLen <= 1) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, MONO_MASK, p0);\
- MMIO_OUT32(ivideo.mmio_vbase, MONO_MASK+4, p1);\
- CmdQueLen -= 2;
+ if(CmdQueLen <= 1) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK, p0);\
+ MMIO_OUT32(ivideo->mmio_vbase, MONO_MASK+4, p1);\
+ CmdQueLen -= 2;
#define SiS310SetupClipLT(left,top) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\
+ CmdQueLen--;
#define SiS310SetupClipRB(right,bottom) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
- CmdQueLen--;
+ if(CmdQueLen <= 0) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\
+ CmdQueLen--;
#define SiS310SetupROP(rop) \
- ivideo.CommandReg = (rop) << 8;
+ ivideo->CommandReg = (rop) << 8;
#define SiS310SetupCMDFlag(flags) \
- ivideo.CommandReg |= (flags);
+ ivideo->CommandReg |= (flags);
#define SiS310DoCMD \
- if (CmdQueLen <= 1) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, COMMAND_READY, ivideo.CommandReg); \
- MMIO_OUT32(ivideo.mmio_vbase, FIRE_TRIGGER, 0); \
- CmdQueLen -= 2;
-
-#define SiS310SetupX0Y0(x,y) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, LINE_X0, (y)<<16 | (x) );\
- CmdQueLen--;
-
-#define SiS310SetupX1Y1(x,y) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, LINE_X1, (y)<<16 | (x) );\
- CmdQueLen--;
-
-#define SiS310SetupLineCount(c) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, LINE_COUNT, c);\
- CmdQueLen--;
-
-#define SiS310SetupStylePeriod(p) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT16(ivideo.mmio_vbase, LINE_STYLE_PERIOD, p);\
- CmdQueLen--;
-
-#define SiS310SetupStyleLow(ls) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, LINE_STYLE_0, ls);\
- CmdQueLen--;
-
-#define SiS310SetupStyleHigh(ls) \
- if (CmdQueLen <= 0) SiS310Idle;\
- MMIO_OUT32(ivideo.mmio_vbase, LINE_STYLE_1, ls);\
- CmdQueLen--;
-
-int sisfb_initaccel(void);
-void sisfb_syncaccel(void);
-
-extern struct video_info ivideo;
+ if(CmdQueLen <= 1) SiS310Idle;\
+ MMIO_OUT32(ivideo->mmio_vbase, COMMAND_READY, ivideo->CommandReg); \
+ MMIO_OUT32(ivideo->mmio_vbase, FIRE_TRIGGER, 0); \
+ CmdQueLen -= 2;
+
+
+int sisfb_initaccel(struct sis_video_info *ivideo);
+void sisfb_syncaccel(struct sis_video_info *ivideo);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
void fbcon_sis_bmove(struct display *p, int srcy, int srcx, int dsty,
- int dstx, int height, int width);
+ int dstx, int height, int width);
void fbcon_sis_revc(struct display *p, int srcy, int srcx);
void fbcon_sis_clear8(struct vc_data *conp, struct display *p, int srcy,
- int srcx, int height, int width);
+ int srcx, int height, int width);
void fbcon_sis_clear16(struct vc_data *conp, struct display *p, int srcy,
- int srcx, int height, int width);
+ int srcx, int height, int width);
void fbcon_sis_clear32(struct vc_data *conp, struct display *p, int srcy,
- int srcx, int height, int width);
+ int srcx, int height, int width);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
-extern int sisfb_accel;
void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area);
#endif
/*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/M741/330/760
- * frame buffer driver for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/305/540/630(S)/730(S)
+ * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3
*
* Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
*
*
* Author: Thomas Winischhofer <thomas@winischhofer.net>
*
- * Author of code base:
- * SiS (www.sis.com.tw)
+ * Author of (practically wiped) code base:
+ * SiS (www.sis.com)
* Copyright (C) 1999 Silicon Integrated Systems, Inc.
*
* See http://www.winischhofer.net/ for more information and updates
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#include <linux/moduleparam.h>
+#endif
#include <linux/kernel.h>
+#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#include <linux/vmalloc.h>
-#endif
#include <linux/vt_kern.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/agp_backend.h>
#include <linux/types.h>
#include <asm/uaccess.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#include <linux/spinlock.h>
-#endif
-
-#include "osdef.h"
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#include <video/sisfb.h>
-#else
-#include <linux/sisfb.h>
-#endif
-
#include <asm/io.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#include <video/fbcon-cfb32.h>
#endif
-#include "vgatypes.h"
-#include "sis_main.h"
#include "sis.h"
+#include "sis_main.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#error "This version of sisfb requires at least 2.6.0"
-#else
-#if 0
-#define NEWFBDEV /* Define this as soon as new fvdev code has been merged */
-#endif
-#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)
+#error "This version of sisfb requires at least 2.6.3"
#endif
-
-/* -------------------- Macro definitions ---------------------------- */
-
-#undef SISFBDEBUG /* TW: no debugging */
-
-#ifdef SISFBDEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef SISFBACCEL
#ifdef FBCON_HAS_CFB8
extern struct display_switch fbcon_sis8;
#endif
extern struct display_switch fbcon_sis32;
#endif
#endif
-#endif
-/* --------------- Hardware Access Routines -------------------------- */
+/* ------------------ Internal helper routines ----------------- */
-void sisfb_set_reg4(u16 port, unsigned long data)
+static void __init
+sisfb_setdefaultparms(void)
{
- outl((u32) (data & 0xffffffff), port);
+ sisfb_off = 0;
+ sisfb_parm_mem = 0;
+ sisfb_accel = -1;
+ sisfb_ypan = -1;
+ sisfb_max = -1;
+ sisfb_userom = -1;
+ sisfb_useoem = -1;
+#ifdef MODULE
+ /* Module: "None" for 2.4, default mode for 2.5+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ sisfb_mode_idx = -1;
+#else
+ sisfb_mode_idx = MODE_INDEX_NONE;
+#endif
+#else
+ /* Static: Default mode */
+ sisfb_mode_idx = -1;
+#endif
+ sisfb_parm_rate = -1;
+ sisfb_crt1off = 0;
+ sisfb_forcecrt1 = -1;
+ sisfb_crt2type = -1;
+ sisfb_crt2flags = 0;
+ sisfb_pdc = 0xff;
+ sisfb_pdca = 0xff;
+ sisfb_scalelcd = -1;
+ sisfb_specialtiming = CUT_NONE;
+ sisfb_lvdshl = -1;
+ sisfb_dstn = 0;
+ sisfb_fstn = 0;
+ sisfb_tvplug = -1;
+ sisfb_tvstd = -1;
+ sisfb_tvxposoffset = 0;
+ sisfb_tvyposoffset = 0;
+ sisfb_filter = -1;
+ sisfb_nocrt2rate = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ sisfb_inverse = 0;
+ sisfb_fontname[0] = 0;
+#endif
+#if !defined(__i386__) && !defined(__x86_64__)
+ sisfb_resetcard = 0;
+ sisfb_videoram = 0;
+#endif
}
-u32 sisfb_get_reg3(u16 port)
+static void __init
+sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
{
- u32 data;
+ int i = 0, j = 0;
- data = inl(port);
- return (data);
-}
+ /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+
+ if(vesamode == 0) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ sisfb_mode_idx = MODE_INDEX_NONE;
+#else
+ if(!quiet) {
+ printk(KERN_ERR "sisfb: Invalid mode. Using default.\n");
+ }
+ sisfb_mode_idx = DEFAULT_MODE;
+#endif
+ return;
+ }
+
+ vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
-/* ------------ Interface for init & mode switching code ------------- */
+ while(sisbios_mode[i++].mode_no[0] != 0) {
+ if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
+ (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
+ if(sisfb_fstn) {
+ if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+ sisbios_mode[i-1].mode_no[1] == 0x56 ||
+ sisbios_mode[i-1].mode_no[1] == 0x53) continue;
+ } else {
+ if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+ sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
+ }
+ sisfb_mode_idx = i - 1;
+ j = 1;
+ break;
+ }
+ }
+ if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+}
-BOOLEAN
-sisfb_query_VGA_config_space(PSIS_HW_INFO psishw_ext,
- unsigned long offset, unsigned long set, unsigned long *value)
+static void
+sisfb_search_mode(char *name, BOOLEAN quiet)
{
- static struct pci_dev *pdev = NULL;
- static unsigned char init = 0, valid_pdev = 0;
+ int i = 0;
+ unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
+ char strbuf[16], strbuf1[20];
+ char *nameptr = name;
- if (!set)
- DPRINTK("sisfb: Get VGA offset 0x%lx\n", offset);
- else
- DPRINTK("sisfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
+ /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
- if (!init) {
- init = TRUE;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
- pci_for_each_dev(pdev) {
-#else
- while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
-#endif
- DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
- pdev->device, ivideo.chip_id);
- if ((pdev->vendor == PCI_VENDOR_ID_SI)
- && (pdev->device == ivideo.chip_id)) {
- valid_pdev = TRUE;
- break;
- }
- }
+ if(name == NULL) {
+ if(!quiet) {
+ printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+ }
+ sisfb_mode_idx = DEFAULT_MODE;
+ return;
}
- if (!valid_pdev) {
- printk(KERN_DEBUG "sisfb: Can't find SiS %d VGA device.\n",
- ivideo.chip_id);
- return FALSE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
+ if(!quiet) {
+ printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+ }
+ sisfb_mode_idx = DEFAULT_MODE;
+ return;
}
+#endif
+ if(strlen(name) <= 19) {
+ strcpy(strbuf1, name);
+ for(i=0; i<strlen(strbuf1); i++) {
+ if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
+ }
- if (set == 0)
- pci_read_config_dword(pdev, offset, (u32 *)value);
- else
- pci_write_config_dword(pdev, offset, (u32)(*value));
+ /* This does some fuzzy mode naming detection */
+ if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
+ if((rate <= 32) || (depth > 32)) {
+ j = rate; rate = depth; depth = j;
+ }
+ sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+ nameptr = strbuf;
+ sisfb_parm_rate = rate;
+ } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
+ sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+ nameptr = strbuf;
+ } else {
+ xres = 0;
+ if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
+ sprintf(strbuf, "%ux%ux8", xres, yres);
+ nameptr = strbuf;
+ } else {
+ sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
+ return;
+ }
+ }
+ }
- return TRUE;
+ i = 0; j = 0;
+ while(sisbios_mode[i].mode_no[0] != 0) {
+ if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
+ if(sisfb_fstn) {
+ if(sisbios_mode[i-1].mode_no[1] == 0x50 ||
+ sisbios_mode[i-1].mode_no[1] == 0x56 ||
+ sisbios_mode[i-1].mode_no[1] == 0x53) continue;
+ } else {
+ if(sisbios_mode[i-1].mode_no[1] == 0x5a ||
+ sisbios_mode[i-1].mode_no[1] == 0x5b) continue;
+ }
+ sisfb_mode_idx = i - 1;
+ j = 1;
+ break;
+ }
+ }
+ if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
}
-BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_INFO psishw_ext,
- unsigned long offset, unsigned long set, unsigned long *value)
+#ifndef MODULE
+static void __devinit
+sisfb_get_vga_mode_from_kernel(void)
{
- static struct pci_dev *pdev = NULL;
- static unsigned char init = 0, valid_pdev = 0;
- u16 nbridge_id = 0;
+#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT)
+ char mymode[32];
+ int mydepth = screen_info.lfb_depth;
- if (!init) {
- init = TRUE;
- switch (ivideo.chip) {
-#ifdef CONFIG_FB_SIS_300
- case SIS_540:
- nbridge_id = PCI_DEVICE_ID_SI_540;
- break;
- case SIS_630:
- nbridge_id = PCI_DEVICE_ID_SI_630;
- break;
- case SIS_730:
- nbridge_id = PCI_DEVICE_ID_SI_730;
- break;
+ if(screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return;
+
+ if( (screen_info.lfb_width >= 320) && (screen_info.lfb_width <= 2048) &&
+ (screen_info.lfb_height >= 200) && (screen_info.lfb_height <= 1536) &&
+ (mydepth >= 8) && (mydepth <= 32) ) {
+
+ if(mydepth == 24) mydepth = 32;
+
+ sprintf(mymode, "%ux%ux%u", screen_info.lfb_width,
+ screen_info.lfb_height,
+ mydepth);
+
+ printk(KERN_DEBUG "sisfb: Using vga mode %s pre-set by kernel as default\n", mymode);
+
+ sisfb_search_mode(mymode, TRUE);
+ }
#endif
-#ifdef CONFIG_FB_SIS_315
- case SIS_550:
- nbridge_id = PCI_DEVICE_ID_SI_550;
- break;
- case SIS_650:
- nbridge_id = PCI_DEVICE_ID_SI_650;
- break;
- case SIS_740:
- nbridge_id = PCI_DEVICE_ID_SI_740;
- break;
- case SIS_661:
- nbridge_id = PCI_DEVICE_ID_SI_660;
- break;
- case SIS_741:
- nbridge_id = PCI_DEVICE_ID_SI_741;
- break;
- case SIS_660:
- nbridge_id = PCI_DEVICE_ID_SI_660;
- break;
- case SIS_760:
- nbridge_id = PCI_DEVICE_ID_SI_760;
- break;
+ return;
+}
#endif
- default:
- nbridge_id = 0;
- break;
- }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
- pci_for_each_dev(pdev) {
-#else
- while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
-#endif
- DPRINTK("Current: 0x%x, target: 0x%x\n",
- pdev->device, ivideo.chip_id);
- if ((pdev->vendor == PCI_VENDOR_ID_SI)
- && (pdev->device == nbridge_id)) {
- valid_pdev = TRUE;
- break;
- }
- }
- }
+static void __init
+sisfb_search_crt2type(const char *name)
+{
+ int i = 0;
+
+ /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
- if (!valid_pdev) {
- printk(KERN_DEBUG "sisfb: Can't find SiS %d North Bridge device.\n",
- nbridge_id);
- return FALSE;
+ if(name == NULL) return;
+
+ while(sis_crt2type[i].type_no != -1) {
+ if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
+ sisfb_crt2type = sis_crt2type[i].type_no;
+ sisfb_tvplug = sis_crt2type[i].tvplug_no;
+ sisfb_crt2flags = sis_crt2type[i].flags;
+ break;
+ }
+ i++;
}
- if (set == 0)
- pci_read_config_dword(pdev, offset, (u32 *)value);
- else
- pci_write_config_dword(pdev, offset, (u32)(*value));
+ sisfb_dstn = (sisfb_crt2flags & FL_550_DSTN) ? 1 : 0;
+ sisfb_fstn = (sisfb_crt2flags & FL_550_FSTN) ? 1 : 0;
- return TRUE;
+ if(sisfb_crt2type < 0) {
+ printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
+ }
}
-/* ------------------ Internal helper routines ----------------- */
-
-static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
+static void __init
+sisfb_search_tvstd(const char *name)
{
- int htotal, vtotal;
- unsigned int dclock, hsync;
-
- if(!monitor->datavalid) return TRUE;
+ int i = 0;
- if(mode_idx < 0) return FALSE;
+ /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
- if(rate < (monitor->vmin - 1)) return FALSE;
- if(rate > (monitor->vmax + 1)) return FALSE;
+ if(name == NULL) return;
- if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
- &htotal, &vtotal, rate_idx)) {
- dclock = (htotal * vtotal * rate) / 1000;
- if(dclock > (monitor->dclockmax + 1000)) return FALSE;
- hsync = dclock / htotal;
- if(hsync < (monitor->hmin - 1)) return FALSE;
- if(hsync > (monitor->hmax + 1)) return FALSE;
- } else {
- return FALSE;
+ while(sis_tvtype[i].type_no != -1) {
+ if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
+ sisfb_tvstd = sis_tvtype[i].type_no;
+ break;
+ }
+ i++;
}
- return TRUE;
-};
+}
+
+static void __init
+sisfb_search_specialtiming(const char *name)
+{
+ int i = 0;
+ BOOLEAN found = FALSE;
+
+ /* BEWARE: We don't know the hardware specs yet and there is no ivideo */
+
+ if(name == NULL) return;
+
+ if(!strnicmp(name, "none", 4)) {
+ sisfb_specialtiming = CUT_FORCENONE;
+ printk(KERN_DEBUG "sisfb: Special timing disabled\n");
+ } else {
+ while(mycustomttable[i].chipID != 0) {
+ if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
+ sisfb_specialtiming = mycustomttable[i].SpecialID;
+ found = TRUE;
+ printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
+ mycustomttable[i].vendorName, mycustomttable[i].cardName,
+ mycustomttable[i].optionName);
+ break;
+ }
+ i++;
+ }
+ if(!found) {
+ printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
+ printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
+ i = 0;
+ while(mycustomttable[i].chipID != 0) {
+ printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
+ mycustomttable[i].optionName,
+ mycustomttable[i].vendorName,
+ mycustomttable[i].cardName);
+ i++;
+ }
+ }
+ }
+}
-static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
+static BOOLEAN __devinit
+sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
{
int i, j, xres, yres, refresh, index;
u32 emodes;
return(monitor->datavalid);
}
-static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
+static void __devinit
+sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, int crtno)
{
USHORT temp, i, realcrtno = crtno;
u8 buffer[256];
monitor->datavalid = FALSE;
if(crtno) {
- if(ivideo.vbflags & CRT2_LCD) realcrtno = 1;
- else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
+ if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
+ else if(ivideo->vbflags & CRT2_VGA) realcrtno = 2;
else return;
}
- if((sisfb_crt1off) && (!crtno)) return;
+ if((ivideo->sisfb_crt1off) && (!crtno)) return;
- temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
+ realcrtno, 0, &buffer[0]);
if((!temp) || (temp == 0xffff)) {
printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
return;
if(temp & 0x02) {
i = 3; /* Number of retrys */
do {
- temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine,
realcrtno, 1, &buffer[0]);
} while((temp) && i--);
if(!temp) {
}
}
-static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
+static BOOLEAN
+sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
+ int mode_idx, int rate_idx, int rate)
{
- int i = 0, j = 0;
+ int htotal, vtotal;
+ unsigned int dclock, hsync;
- if(vesamode == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- sisfb_mode_idx = MODE_INDEX_NONE;
-#else
- if(!quiet)
- printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
- sisfb_mode_idx = DEFAULT_MODE;
+ if(!monitor->datavalid) return TRUE;
+
+ if(mode_idx < 0) return FALSE;
+
+ /* Skip for 320x200, 320x240, 640x400 */
+ switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
+ case 0x59:
+ case 0x41:
+ case 0x4f:
+ case 0x50:
+ case 0x56:
+ case 0x53:
+ case 0x2f:
+ case 0x5d:
+ case 0x5e:
+ return TRUE;
+#ifdef CONFIG_FB_SIS_315
+ case 0x5a:
+ case 0x5b:
+ if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
#endif
- return;
- }
+ }
- vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
+ if(rate < (monitor->vmin - 1)) return FALSE;
+ if(rate > (monitor->vmax + 1)) return FALSE;
- while(sisbios_mode[i++].mode_no != 0) {
- if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
- (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
- if(sisfb_fstn) {
- if(sisbios_mode[i-1].mode_no == 0x50 ||
- sisbios_mode[i-1].mode_no == 0x56 ||
- sisbios_mode[i-1].mode_no == 0x53) continue;
- } else {
- if(sisbios_mode[i-1].mode_no == 0x5a ||
- sisbios_mode[i-1].mode_no == 0x5b) continue;
- }
- sisfb_mode_idx = i - 1;
- j = 1;
- break;
- }
+ if(sisfb_gettotalfrommode(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+ sisbios_mode[mode_idx].mode_no[ivideo->mni],
+ &htotal, &vtotal, rate_idx)) {
+ dclock = (htotal * vtotal * rate) / 1000;
+ if(dclock > (monitor->dclockmax + 1000)) return FALSE;
+ hsync = dclock / htotal;
+ if(hsync < (monitor->hmin - 1)) return FALSE;
+ if(hsync > (monitor->hmax + 1)) return FALSE;
+ } else {
+ return FALSE;
}
- if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+ return TRUE;
}
-static void sisfb_search_mode(char *name, BOOLEAN quiet)
+static int
+sisfb_validate_mode(struct sis_video_info *ivideo, int myindex, u32 vbflags)
{
- int i = 0;
- unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
- char strbuf[16], strbuf1[20];
- char *nameptr = name;
-
- if(name == NULL) {
- if(!quiet)
- printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
- sisfb_mode_idx = DEFAULT_MODE;
- return;
- }
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- if (!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
- if(!quiet)
- printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
- sisfb_mode_idx = DEFAULT_MODE;
- return;
- }
-#endif
- if(strlen(name) <= 19) {
- strcpy(strbuf1, name);
- for(i=0; i<strlen(strbuf1); i++) {
- if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
- }
-
- /* This does some fuzzy mode naming detection */
- if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
- if((rate <= 32) || (depth > 32)) {
- j = rate; rate = depth; depth = j;
- }
- sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
- nameptr = strbuf;
- ivideo.refresh_rate = sisfb_parm_rate = rate;
- } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
- sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
- nameptr = strbuf;
- } else {
- xres = 0;
- if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
- sprintf(strbuf, "%ux%ux8", xres, yres);
- nameptr = strbuf;
- } else {
- sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
- return;
- }
- }
- }
-
- i = 0; j = 0;
- while(sisbios_mode[i].mode_no != 0) {
- if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
- if(sisfb_fstn) {
- if(sisbios_mode[i-1].mode_no == 0x50 ||
- sisbios_mode[i-1].mode_no == 0x56 ||
- sisbios_mode[i-1].mode_no == 0x53) continue;
- } else {
- if(sisbios_mode[i-1].mode_no == 0x5a ||
- sisbios_mode[i-1].mode_no == 0x5b) continue;
- }
- sisfb_mode_idx = i - 1;
- j = 1;
- break;
- }
- }
- if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
-
-}
-
-static int sisfb_validate_mode(int myindex, unsigned long vbflags)
-{
- u16 xres, yres, myres;
+ u16 xres=0, yres, myres;
#ifdef CONFIG_FB_SIS_300
- if(sisvga_engine == SIS_300_VGA) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
if(!(sisbios_mode[myindex].chipset & MD_SIS300)) return(-1);
}
#endif
#ifdef CONFIG_FB_SIS_315
- if(sisvga_engine == SIS_315_VGA) {
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
if(!(sisbios_mode[myindex].chipset & MD_SIS315)) return(-1);
}
#endif
myres = sisbios_mode[myindex].yres;
- switch (vbflags & VB_DISPTYPE_DISP2) {
+ switch(vbflags & VB_DISPTYPE_DISP2) {
+
case CRT2_LCD:
- switch (sishw_ext.ulCRT2LCDType) {
- case LCD_640x480: xres = 640; yres = 480; break;
- case LCD_800x600: xres = 800; yres = 600; break;
- case LCD_1024x600: xres = 1024; yres = 600; break;
- case LCD_1024x768: xres = 1024; yres = 768; break;
- case LCD_1152x768: xres = 1152; yres = 768; break;
- case LCD_1280x960: xres = 1280; yres = 960; break;
- case LCD_1280x768: xres = 1280; yres = 768; break;
- case LCD_1280x1024:xres = 1280; yres = 1024; break;
- case LCD_1400x1050:xres = 1400; yres = 1050; break;
- case LCD_1600x1200:xres = 1600; yres = 1200; break;
- case LCD_320x480: xres = 320; yres = 480; break; /* FSTN (old) */
- case LCD_640x480_2:
- case LCD_640x480_3:xres = 640; yres = 480; break; /* FSTN (new) */
- default: xres = 0; yres = 0; break;
- }
-
- if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
- xres = 1360; yres = 1024;
- }
-
- if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
- xres = 848; yres = 480;
- } else {
- if(sisbios_mode[myindex].xres > xres) return(-1);
- if(myres > yres) return(-1);
+
+ xres = ivideo->lcdxres; yres = ivideo->lcdyres;
+
+ if(ivideo->SiS_Pr.SiS_CustomT != CUT_PANEL848) {
+ if(sisbios_mode[myindex].xres > xres) return(-1);
+ if(myres > yres) return(-1);
}
if(vbflags & (VB_LVDS | VB_30xBDH)) {
if(sisbios_mode[myindex].xres == 320) {
if((myres == 240) || (myres == 480)) {
- if(!sisfb_fstn) {
- if(sisbios_mode[myindex].mode_no == 0x5a ||
- sisbios_mode[myindex].mode_no == 0x5b)
+ if(!ivideo->sisfb_fstn) {
+ if(sisbios_mode[myindex].mode_no[1] == 0x5a ||
+ sisbios_mode[myindex].mode_no[1] == 0x5b)
return(-1);
} else {
- if(sisbios_mode[myindex].mode_no == 0x50 ||
- sisbios_mode[myindex].mode_no == 0x56 ||
- sisbios_mode[myindex].mode_no == 0x53)
+ if(sisbios_mode[myindex].mode_no[1] == 0x50 ||
+ sisbios_mode[myindex].mode_no[1] == 0x56 ||
+ sisbios_mode[myindex].mode_no[1] == 0x53)
return(-1);
}
}
}
}
- if(SiS_GetModeID_LCD(sisvga_engine, vbflags, sisbios_mode[myindex].xres, sisbios_mode[myindex].yres,
- 0, sisfb_fstn, SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
- return(-1);
+ if(SiS_GetModeID_LCD(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+ sisbios_mode[myindex].yres, 0, ivideo->sisfb_fstn,
+ ivideo->SiS_Pr.SiS_CustomT, xres, yres) < 0x14) {
+ return(-1);
}
break;
case CRT2_TV:
- if(SiS_GetModeID_TV(sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+ if(SiS_GetModeID_TV(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
sisbios_mode[myindex].yres, 0) < 0x14) {
- return(-1);
+ return(-1);
}
break;
case CRT2_VGA:
- if(SiS_GetModeID_VGA2(sisvga_engine, vbflags, sisbios_mode[myindex].xres,
- sisbios_mode[myindex].yres, 0) < 0x14) {
- return(-1);
+ if(SiS_GetModeID_VGA2(ivideo->sisvga_engine, vbflags, sisbios_mode[myindex].xres,
+ sisbios_mode[myindex].yres, 0) < 0x14) {
+ return(-1);
}
break;
}
return(myindex);
}
-static void sisfb_search_crt2type(const char *name)
-{
- int i = 0;
-
- if(name == NULL)
- return;
-
- while(sis_crt2type[i].type_no != -1) {
- if (!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
- sisfb_crt2type = sis_crt2type[i].type_no;
- sisfb_tvplug = sis_crt2type[i].tvplug_no;
- sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
- sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
- break;
- }
- i++;
- }
- if(sisfb_crt2type < 0)
- printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
- if(ivideo.chip != SIS_550) {
- sisfb_dstn = sisfb_fstn = 0;
- }
-}
-
-static void sisfb_search_queuemode(const char *name)
-{
- int i = 0;
-
- if(name == NULL)
- return;
-
- while (sis_queuemode[i].type_no != -1) {
- if (!strnicmp(name, sis_queuemode[i].name, strlen(sis_queuemode[i].name))) {
- sisfb_queuemode = sis_queuemode[i].type_no;
- break;
- }
- i++;
- }
- if (sisfb_queuemode < 0)
- printk(KERN_ERR "sisfb: Invalid queuemode type: %s\n", name);
-}
-
-static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
+static u8
+sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int mode_idx)
{
u16 xres, yres;
int i = 0;
xres = sisbios_mode[mode_idx].xres;
yres = sisbios_mode[mode_idx].yres;
- sisfb_rate_idx = 0;
- while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
- if ((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
- if (sisfb_vrate[i].refresh == rate) {
- sisfb_rate_idx = sisfb_vrate[i].idx;
+ ivideo->rate_idx = 0;
+ while((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
+ if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
+ if(sisfb_vrate[i].refresh == rate) {
+ ivideo->rate_idx = sisfb_vrate[i].idx;
break;
- } else if (sisfb_vrate[i].refresh > rate) {
- if ((sisfb_vrate[i].refresh - rate) <= 3) {
+ } else if(sisfb_vrate[i].refresh > rate) {
+ if((sisfb_vrate[i].refresh - rate) <= 3) {
DPRINTK("sisfb: Adjusting rate from %d up to %d\n",
rate, sisfb_vrate[i].refresh);
- sisfb_rate_idx = sisfb_vrate[i].idx;
- ivideo.refresh_rate = sisfb_vrate[i].refresh;
- } else if (((rate - sisfb_vrate[i-1].refresh) <= 2)
+ ivideo->rate_idx = sisfb_vrate[i].idx;
+ ivideo->refresh_rate = sisfb_vrate[i].refresh;
+ } else if(((rate - sisfb_vrate[i-1].refresh) <= 2)
&& (sisfb_vrate[i].idx != 1)) {
DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
rate, sisfb_vrate[i-1].refresh);
- sisfb_rate_idx = sisfb_vrate[i-1].idx;
- ivideo.refresh_rate = sisfb_vrate[i-1].refresh;
+ ivideo->rate_idx = sisfb_vrate[i-1].idx;
+ ivideo->refresh_rate = sisfb_vrate[i-1].refresh;
}
break;
} else if((rate - sisfb_vrate[i].refresh) <= 2) {
DPRINTK("sisfb: Adjusting rate from %d down to %d\n",
rate, sisfb_vrate[i].refresh);
- sisfb_rate_idx = sisfb_vrate[i].idx;
+ ivideo->rate_idx = sisfb_vrate[i].idx;
break;
}
}
i++;
}
- if (sisfb_rate_idx > 0) {
- return sisfb_rate_idx;
+ if(ivideo->rate_idx > 0) {
+ return ivideo->rate_idx;
} else {
- printk(KERN_INFO
- "sisfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
+ printk(KERN_INFO "sisfb: Unsupported rate %d for %dx%d\n",
+ rate, xres, yres);
return 0;
}
}
-static void sisfb_search_tvstd(const char *name)
-{
- int i = 0;
-
- if(name == NULL)
- return;
-
- while (sis_tvtype[i].type_no != -1) {
- if (!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
- ivideo.vbflags |= sis_tvtype[i].type_no;
- break;
- }
- i++;
- }
-}
-
-static void sisfb_search_specialtiming(const char *name)
-{
- int i = 0;
- BOOLEAN found = FALSE;
-
- if(name == NULL)
- return;
-
- if(!strnicmp(name, "none", 4)) {
- SiS_Pr.SiS_CustomT = CUT_FORCENONE;
- printk(KERN_DEBUG "sisfb: Special timing disabled\n");
- } else {
- while(mycustomttable[i].chipID != 0) {
- if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
- SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
- found = TRUE;
- printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
- mycustomttable[i].vendorName, mycustomttable[i].cardName,
- mycustomttable[i].optionName);
- break;
- }
- i++;
- }
- if(!found) {
- printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
- printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
- i = 0;
- while(mycustomttable[i].chipID != 0) {
- printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
- mycustomttable[i].optionName,
- mycustomttable[i].vendorName,
- mycustomttable[i].cardName);
- i++;
- }
- }
- }
-}
-
-static BOOLEAN sisfb_bridgeisslave(void)
+static BOOLEAN
+sisfb_bridgeisslave(struct sis_video_info *ivideo)
{
unsigned char P1_00;
- if(!(ivideo.vbflags & VB_VIDEOBRIDGE)) return FALSE;
+ if(!(ivideo->vbflags & VB_VIDEOBRIDGE)) return FALSE;
inSISIDXREG(SISPART1,0x00,P1_00);
- if( ((sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
- ((sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
+ if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
+ ((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
return TRUE;
} else {
return FALSE;
}
}
-static BOOLEAN sisfballowretracecrt1(void)
+static BOOLEAN
+sisfballowretracecrt1(struct sis_video_info *ivideo)
{
- unsigned char temp;
+ u8 temp;
inSISIDXREG(SISCR,0x17,temp);
if(!(temp & 0x80)) return FALSE;
return TRUE;
}
-static BOOLEAN sisfbcheckvretracecrt1(void)
+static BOOLEAN
+sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
{
-
- if(!sisfballowretracecrt1()) return FALSE;
+ if(!sisfballowretracecrt1(ivideo)) return FALSE;
if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
else return FALSE;
}
-static void sisfbwaitretracecrt1(void)
+static void
+sisfbwaitretracecrt1(struct sis_video_info *ivideo)
{
int watchdog;
- if(!sisfballowretracecrt1()) return;
+ if(!sisfballowretracecrt1(ivideo)) return;
watchdog = 65536;
while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
}
-static BOOLEAN sisfbcheckvretracecrt2(void)
+static BOOLEAN
+sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
{
unsigned char temp, reg;
- switch(sisvga_engine) {
- case SIS_300_VGA:
- reg = 0x25;
- break;
- case SIS_315_VGA:
- reg = 0x30;
- break;
- default:
- return FALSE;
+ switch(ivideo->sisvga_engine) {
+ case SIS_300_VGA: reg = 0x25; break;
+ case SIS_315_VGA: reg = 0x30; break;
+ default: return FALSE;
}
inSISIDXREG(SISPART1, reg, temp);
else return TRUE;
}
-static BOOLEAN sisfb_CheckVBRetrace(void)
+static BOOLEAN
+sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
{
- if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
- if(sisfb_bridgeisslave()) {
- return(sisfbcheckvretracecrt1());
+ if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+ if(sisfb_bridgeisslave(ivideo)) {
+ return(sisfbcheckvretracecrt1(ivideo));
} else {
- return(sisfbcheckvretracecrt2());
+ return(sisfbcheckvretracecrt2(ivideo));
}
}
- return(sisfbcheckvretracecrt1());
+ return(sisfbcheckvretracecrt1(ivideo));
+}
+
+static u32
+sisfb_setupvbblankflags(struct sis_video_info *ivideo, u32 *vcount, u32 *hcount)
+{
+ u8 idx, reg1, reg2, reg3, reg4;
+ u32 ret = 0;
+
+ (*vcount) = (*hcount) = 0;
+
+ if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
+ ret |= (FB_VBLANK_HAVE_VSYNC |
+ FB_VBLANK_HAVE_HBLANK |
+ FB_VBLANK_HAVE_VBLANK |
+ FB_VBLANK_HAVE_VCOUNT |
+ FB_VBLANK_HAVE_HCOUNT);
+ switch(ivideo->sisvga_engine) {
+ case SIS_300_VGA: idx = 0x25; break;
+ default:
+ case SIS_315_VGA: idx = 0x30; break;
+ }
+ inSISIDXREG(SISPART1,(idx+0),reg1); /* 30 */
+ inSISIDXREG(SISPART1,(idx+1),reg2); /* 31 */
+ inSISIDXREG(SISPART1,(idx+2),reg3); /* 32 */
+ inSISIDXREG(SISPART1,(idx+3),reg4); /* 33 */
+ if(!(reg1 & 0x01)) ret |= FB_VBLANK_VBLANKING;
+ if(!(reg1 & 0x02)) ret |= FB_VBLANK_VSYNCING;
+ if(!(reg4 & 0x80)) ret |= FB_VBLANK_HBLANKING;
+ (*vcount) = reg3 | ((reg4 & 0x70) << 4);
+ (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
+ } else if(sisfballowretracecrt1(ivideo)) {
+ ret |= (FB_VBLANK_HAVE_VSYNC |
+ FB_VBLANK_HAVE_VBLANK |
+ FB_VBLANK_HAVE_VCOUNT |
+ FB_VBLANK_HAVE_HCOUNT);
+ reg1 = inSISREG(SISINPSTAT);
+ if(reg1 & 0x08) ret |= FB_VBLANK_VSYNCING;
+ if(reg1 & 0x01) ret |= FB_VBLANK_VBLANKING;
+ inSISIDXREG(SISCR,0x20,reg1);
+ inSISIDXREG(SISCR,0x1b,reg1);
+ inSISIDXREG(SISCR,0x1c,reg2);
+ inSISIDXREG(SISCR,0x1d,reg3);
+ (*vcount) = reg2 | ((reg3 & 0x07) << 8);
+ (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
+ }
+ return ret;
}
-static int sisfb_myblank(int blank)
+static int
+sisfb_myblank(struct sis_video_info *ivideo, int blank)
{
u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
BOOLEAN backlight = TRUE;
return 1;
}
- if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
+ if(ivideo->currentvbflags & VB_DISPTYPE_CRT1) {
- setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+ if( (!ivideo->sisfb_thismonitor.datavalid) ||
+ ((ivideo->sisfb_thismonitor.datavalid) &&
+ (ivideo->sisfb_thismonitor.feature & 0xe0))) {
- if( (!sisfb_thismonitor.datavalid) ||
- ((sisfb_thismonitor.datavalid) &&
- (sisfb_thismonitor.feature & 0xe0))) {
-
- if(sisvga_engine == SIS_315_VGA) {
- setSISIDXREG(SISCR, SiS_Pr.SiS_MyCR63, 0xbf, cr63);
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, 0xbf, cr63);
}
- setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+ if(!(sisfb_bridgeisslave(ivideo))) {
+ setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+ setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+ }
}
}
- if(ivideo.currentvbflags & CRT2_LCD) {
+ if(ivideo->currentvbflags & CRT2_LCD) {
- if(ivideo.vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
if(backlight) {
- SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
+ SiS_SiS30xBLOn(&ivideo->SiS_Pr, &ivideo->sishw_ext);
} else {
- SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
+ SiS_SiS30xBLOff(&ivideo->SiS_Pr, &ivideo->sishw_ext);
}
- } else if(sisvga_engine == SIS_315_VGA) {
- if(ivideo.vbflags & VB_CHRONTEL) {
+ } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if(ivideo->vbflags & VB_CHRONTEL) {
if(backlight) {
- SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
+ SiS_Chrontel701xBLOn(&ivideo->SiS_Pr,&ivideo->sishw_ext);
} else {
- SiS_Chrontel701xBLOff(&SiS_Pr);
+ SiS_Chrontel701xBLOff(&ivideo->SiS_Pr);
}
}
}
- if(((sisvga_engine == SIS_300_VGA) &&
- (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
- ((sisvga_engine == SIS_315_VGA) &&
- ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+ if(((ivideo->sisvga_engine == SIS_300_VGA) &&
+ (ivideo->vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
+ ((ivideo->sisvga_engine == SIS_315_VGA) &&
+ ((ivideo->vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
}
- if(sisvga_engine == SIS_300_VGA) {
- if((ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) &&
- (!(ivideo.vbflags & VB_30xBDH))) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
+ (!(ivideo->vbflags & VB_30xBDH))) {
setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
}
- } else if(sisvga_engine == SIS_315_VGA) {
- if((ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) &&
- (!(ivideo.vbflags & VB_30xBDH))) {
+ } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if((ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) &&
+ (!(ivideo->vbflags & VB_30xBDH))) {
setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
}
}
- } else if(ivideo.currentvbflags & CRT2_VGA) {
+ } else if(ivideo->currentvbflags & CRT2_VGA) {
- if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) {
+ if(ivideo->vbflags & (VB_301B|VB_301C|VB_302B)) {
setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
}
/* ----------- FBDev related routines for all series ----------- */
-static void sisfb_set_vparms(void)
+static int
+sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
{
- switch(ivideo.video_bpp) {
- case 8:
- ivideo.DstColor = 0x0000;
- ivideo.SiS310_AccelDepth = 0x00000000;
- ivideo.video_cmap_len = 256;
- break;
- case 16:
- ivideo.DstColor = 0x8000;
- ivideo.SiS310_AccelDepth = 0x00010000;
- ivideo.video_cmap_len = 16;
- break;
- case 32:
- ivideo.DstColor = 0xC000;
- ivideo.SiS310_AccelDepth = 0x00020000;
- ivideo.video_cmap_len = 16;
- break;
- default:
- ivideo.video_cmap_len = 16;
- printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
- ivideo.accel = 0;
- break;
- }
+ return (var->bits_per_pixel == 8) ? 256 : 16;
+}
+
+static void
+sisfb_set_vparms(struct sis_video_info *ivideo)
+{
+ switch(ivideo->video_bpp) {
+ case 8:
+ ivideo->DstColor = 0x0000;
+ ivideo->SiS310_AccelDepth = 0x00000000;
+ ivideo->video_cmap_len = 256;
+ break;
+ case 16:
+ ivideo->DstColor = 0x8000;
+ ivideo->SiS310_AccelDepth = 0x00010000;
+ ivideo->video_cmap_len = 16;
+ break;
+ case 32:
+ ivideo->DstColor = 0xC000;
+ ivideo->SiS310_AccelDepth = 0x00020000;
+ ivideo->video_cmap_len = 16;
+ break;
+ default:
+ ivideo->video_cmap_len = 16;
+ printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);
+ ivideo->accel = 0;
+ break;
+ }
+}
+
+static int
+sisfb_calc_maxyres(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+{
+ int maxyres = ivideo->heapstart / (var->xres_virtual * (var->bits_per_pixel >> 3));
+
+ if(maxyres > 32767) maxyres = 32767;
+
+ return maxyres;
+}
+
+static void
+sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+{
+ ivideo->video_linelength = var->xres_virtual * (var->bits_per_pixel >> 3);
+ ivideo->scrnpitchCRT1 = ivideo->video_linelength;
+ if(!(ivideo->currentvbflags & CRT1_LCDA)) {
+ if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ ivideo->scrnpitchCRT1 <<= 1;
+ }
+ }
+
+}
+
+static void
+sisfb_set_pitch(struct sis_video_info *ivideo)
+{
+ BOOLEAN isslavemode = FALSE;
+ unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
+ unsigned short HDisplay2 = ivideo->video_linelength >> 3;
+
+ if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
+
+ /* We need to set pitch for CRT1 if bridge is in slave mode, too */
+ if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
+ outSISIDXREG(SISCR,0x13,(HDisplay1 & 0xFF));
+ setSISIDXREG(SISSR,0x0E,0xF0,(HDisplay1 >> 8));
+ }
+
+ /* We must not set the pitch for CRT2 if bridge is in slave mode */
+ if((ivideo->currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
+ orSISIDXREG(SISPART1,ivideo->CRT2_write_enable,0x01);
+ outSISIDXREG(SISPART1,0x07,(HDisplay2 & 0xFF));
+ setSISIDXREG(SISPART1,0x09,0xF0,(HDisplay2 >> 8));
+ }
+}
+
+static void
+sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
+{
+ ivideo->video_cmap_len = sisfb_get_cmap_len(var);
+
+ switch(var->bits_per_pixel) {
+ case 8:
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 6;
+ break;
+ case 16:
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case 32:
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ break;
+ }
}
-static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
- struct fb_info *info)
+static int
+sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
unsigned int htotal = 0, vtotal = 0;
unsigned int drate = 0, hrate = 0;
int found_mode = 0;
}
if(pixclock && htotal && vtotal) {
- drate = 1000000000 / pixclock;
- hrate = (drate * 1000) / htotal;
- ivideo.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
- } else ivideo.refresh_rate = 60;
-
-#if 0
- printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
- var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
-#endif
+ drate = 1000000000 / pixclock;
+ hrate = (drate * 1000) / htotal;
+ ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+ } else {
+ ivideo->refresh_rate = 60;
+ }
- old_mode = sisfb_mode_idx;
- sisfb_mode_idx = 0;
+ old_mode = ivideo->sisfb_mode_idx;
+ ivideo->sisfb_mode_idx = 0;
- while( (sisbios_mode[sisfb_mode_idx].mode_no != 0) &&
- (sisbios_mode[sisfb_mode_idx].xres <= var->xres) ) {
- if( (sisbios_mode[sisfb_mode_idx].xres == var->xres) &&
- (sisbios_mode[sisfb_mode_idx].yres == var->yres) &&
- (sisbios_mode[sisfb_mode_idx].bpp == var->bits_per_pixel)) {
- sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
+ while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) &&
+ (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) {
+ if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) &&
+ (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) &&
+ (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) {
+ ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
found_mode = 1;
break;
}
- sisfb_mode_idx++;
+ ivideo->sisfb_mode_idx++;
}
- if(found_mode)
- sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
- else
- sisfb_mode_idx = -1;
+ if(found_mode) {
+ ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
+ ivideo->sisfb_mode_idx, ivideo->currentvbflags);
+ } else {
+ ivideo->sisfb_mode_idx = -1;
+ }
- if(sisfb_mode_idx < 0) {
+ if(ivideo->sisfb_mode_idx < 0) {
printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,
var->yres, var->bits_per_pixel);
- sisfb_mode_idx = old_mode;
+ ivideo->sisfb_mode_idx = old_mode;
return -EINVAL;
}
- if(sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx) == 0) {
- sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
- ivideo.refresh_rate = 60;
+ if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {
+ ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
+ ivideo->refresh_rate = 60;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if(sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
- sisfb_rate_idx, ivideo.refresh_rate)) {
+ if(ivideo->sisfb_thismonitor.datavalid) {
+ if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
+ ivideo->rate_idx, ivideo->refresh_rate)) {
printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
}
}
#else
if(isactive) {
#endif
- sisfb_pre_setmode();
+ sisfb_pre_setmode(ivideo);
- if(SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
- printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", sisfb_mode_no);
+ if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
+ printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
return -EINVAL;
}
outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
- ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
- ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
- ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
- ivideo.org_x = ivideo.org_y = 0;
- ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
- ivideo.accel = 0;
- if(sisfb_accel) {
- ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
- }
+ sisfb_post_setmode(ivideo);
- sisfb_set_vparms();
+ ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
+ ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
+ ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
- ivideo.current_width = ivideo.video_width;
- ivideo.current_height = ivideo.video_height;
- ivideo.current_bpp = ivideo.video_bpp;
- ivideo.current_htotal = htotal;
- ivideo.current_vtotal = vtotal;
- ivideo.current_pixclock = var->pixclock;
- ivideo.current_refresh_rate = ivideo.refresh_rate;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- sisfb_lastrates[sisfb_mode_no] = ivideo.refresh_rate;
+ sisfb_calc_pitch(ivideo, var);
+ sisfb_set_pitch(ivideo);
+
+ ivideo->accel = 0;
+#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
+#ifdef STUPID_ACCELF_TEXT_SHIT
+ if(var->accel_flags & FB_ACCELF_TEXT) {
+ info->flags &= ~FBINFO_HWACCEL_DISABLED;
+ } else {
+ info->flags |= FBINFO_HWACCEL_DISABLED;
+ }
+#endif
+ if(!(info->flags & FBINFO_HWACCEL_DISABLED)) ivideo->accel = -1;
+#else
+ if(var->accel_flags & FB_ACCELF_TEXT) ivideo->accel = -1;
#endif
- sisfb_post_setmode();
+ sisfb_set_vparms(ivideo);
+ ivideo->current_width = ivideo->video_width;
+ ivideo->current_height = ivideo->video_height;
+ ivideo->current_bpp = ivideo->video_bpp;
+ ivideo->current_htotal = htotal;
+ ivideo->current_vtotal = vtotal;
+ ivideo->current_linelength = ivideo->video_linelength;
+ ivideo->current_pixclock = var->pixclock;
+ ivideo->current_refresh_rate = ivideo->refresh_rate;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;
+#endif
}
+
return 0;
}
-static int sisfb_pan_var(struct fb_var_screeninfo *var)
+static int
+sisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
{
unsigned int base;
- if (var->xoffset > (var->xres_virtual - var->xres)) {
+ if(var->xoffset > (var->xres_virtual - var->xres)) {
return -EINVAL;
}
if(var->yoffset > (var->yres_virtual - var->yres)) {
return -EINVAL;
}
- base = var->yoffset * var->xres_virtual + var->xoffset;
+ base = (var->yoffset * var->xres_virtual) + var->xoffset;
/* calculate base bpp dep. */
switch(var->bits_per_pixel) {
+ case 32:
+ break;
case 16:
base >>= 1;
break;
- case 32:
- break;
case 8:
default:
base >>= 2;
outSISIDXREG(SISCR, 0x0D, base & 0xFF);
outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);
outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);
- if(sisvga_engine == SIS_315_VGA) {
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
}
- if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
- orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+ if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
+ orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));
- if(sisvga_engine == SIS_315_VGA) {
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
}
}
return 0;
}
-static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
-{
- switch(var->bits_per_pixel) {
- case 8:
- var->red.offset = var->green.offset = var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 6;
- ivideo.video_cmap_len = 256;
- break;
- case 16:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- ivideo.video_cmap_len = 16;
- break;
- case 32:
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 24;
- var->transp.length = 8;
- ivideo.video_cmap_len = 16;
- break;
- }
-}
-
-void sis_dispinfo(struct ap_data *rec)
-{
- rec->minfo.bpp = ivideo.video_bpp;
- rec->minfo.xres = ivideo.video_width;
- rec->minfo.yres = ivideo.video_height;
- rec->minfo.v_xres = ivideo.video_vwidth;
- rec->minfo.v_yres = ivideo.video_vheight;
- rec->minfo.org_x = ivideo.org_x;
- rec->minfo.org_y = ivideo.org_y;
- rec->minfo.vrate = ivideo.refresh_rate;
- rec->iobase = ivideo.vga_base - 0x30;
- rec->mem_size = ivideo.video_size;
- rec->disp_state = ivideo.disp_state;
- rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
- rec->hasVB = ivideo.hasVB;
- rec->TV_type = ivideo.TV_type;
- rec->TV_plug = ivideo.TV_plug;
- rec->chip = ivideo.chip;
- rec->vbflags = ivideo.vbflags;
- rec->currentvbflags = ivideo.currentvbflags;
-}
-
-/* ------------ FBDev related routines for 2.4 series ----------- */
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-
-static void sisfb_crtc_to_var(struct fb_var_screeninfo *var)
+/* ------------ FBDev related routines for 2.4 series ----------- */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+static void
+sisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
{
u16 VRE, VBE, VRS, VBS, VDE, VT;
u16 HRE, HBE, HRS, HBS, HDE, HT;
else
var->vmode = FB_VMODE_NONINTERLACED;
- switch ((sr_data & 0x1C) >> 2) {
- case SIS_8BPP_COLOR_MODE:
+ switch((sr_data & 0x1C) >> 2) {
+ case SIS_8BPP_COLOR_MODE:
var->bits_per_pixel = 8;
break;
- case SIS_16BPP_COLOR_MODE:
+ case SIS_16BPP_COLOR_MODE:
var->bits_per_pixel = 16;
break;
- case SIS_32BPP_COLOR_MODE:
+ case SIS_32BPP_COLOR_MODE:
var->bits_per_pixel = 32;
break;
}
- sisfb_bpp_to_var(var);
+ sisfb_bpp_to_var(ivideo, var);
inSISIDXREG(SISSR, 0x0A, sr_data);
-
inSISIDXREG(SISCR, 0x06, cr_data);
-
inSISIDXREG(SISCR, 0x07, cr_data2);
- VT = (cr_data & 0xFF) | ((u16) (cr_data2 & 0x01) << 8) |
- ((u16) (cr_data2 & 0x20) << 4) | ((u16) (sr_data & 0x01) << 10);
+ VT = (cr_data & 0xFF) |
+ ((u16) (cr_data2 & 0x01) << 8) |
+ ((u16) (cr_data2 & 0x20) << 4) |
+ ((u16) (sr_data & 0x01) << 10);
A = VT + 2;
inSISIDXREG(SISCR, 0x12, cr_data);
- VDE = (cr_data & 0xff) | ((u16) (cr_data2 & 0x02) << 7) |
- ((u16) (cr_data2 & 0x40) << 3) | ((u16) (sr_data & 0x02) << 9);
+ VDE = (cr_data & 0xff) |
+ ((u16) (cr_data2 & 0x02) << 7) |
+ ((u16) (cr_data2 & 0x40) << 3) |
+ ((u16) (sr_data & 0x02) << 9);
E = VDE + 1;
inSISIDXREG(SISCR, 0x10, cr_data);
- VRS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x04) << 6) |
- ((u16) (cr_data2 & 0x80) << 2) | ((u16) (sr_data & 0x08) << 7);
+ VRS = (cr_data & 0xff) |
+ ((u16) (cr_data2 & 0x04) << 6) |
+ ((u16) (cr_data2 & 0x80) << 2) |
+ ((u16) (sr_data & 0x08) << 7);
F = VRS + 1 - E;
inSISIDXREG(SISCR, 0x15, cr_data);
-
inSISIDXREG(SISCR, 0x09, cr_data3);
if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
- VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
- ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
+ VBS = (cr_data & 0xff) |
+ ((u16) (cr_data2 & 0x08) << 5) |
+ ((u16) (cr_data3 & 0x20) << 4) |
+ ((u16) (sr_data & 0x04) << 8);
inSISIDXREG(SISCR, 0x16, cr_data);
}
inSISIDXREG(SISSR, 0x0b, sr_data);
-
inSISIDXREG(SISCR, 0x00, cr_data);
HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);
HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);
inSISIDXREG(SISSR, 0x0c, sr_data);
-
inSISIDXREG(SISCR, 0x03, cr_data);
-
inSISIDXREG(SISCR, 0x05, cr_data2);
- HBE = (cr_data & 0x1f) | ((u16) (cr_data2 & 0x80) >> 2) |
- ((u16) (sr_data & 0x03) << 6);
+ HBE = (cr_data & 0x1f) |
+ ((u16) (cr_data2 & 0x80) >> 2) |
+ ((u16) (sr_data & 0x03) << 6);
HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
temp = HBE - ((E - 1) & 255);
D = B - F - C;
- var->xres = var->xres_virtual = E * 8;
+ var->xres = E * 8;
+ if(var->xres_virtual < var->xres) {
+ var->xres_virtual = var->xres;
+ }
if((var->xres == 320) &&
(var->yres == 200 || var->yres == 240)) {
if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
VT <<= 1;
}
- hrate = ivideo.refresh_rate * VT / 2;
+ hrate = ivideo->refresh_rate * VT / 2;
drate = (hrate * HT) / 1000;
var->pixclock = (u32) (1000000000 / drate);
- if(sisfb_ypan) {
- maxyres = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
- if(maxyres > 32767) maxyres = 32767;
- if(sisfb_max) {
+ if(ivideo->sisfb_ypan) {
+ maxyres = sisfb_calc_maxyres(ivideo, var);
+ if(ivideo->sisfb_max) {
var->yres_virtual = maxyres;
} else {
if(var->yres_virtual > maxyres) {
if(var->yres_virtual <= var->yres) {
var->yres_virtual = var->yres;
}
- } else
+ } else {
var->yres_virtual = var->yres;
+ }
}
-static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
- unsigned *transp, struct fb_info *fb_info)
+static int
+sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+ unsigned *transp, struct fb_info *info)
{
- if (regno >= ivideo.video_cmap_len)
- return 1;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+ if(regno >= ivideo->video_cmap_len) return 1;
- *red = sis_palette[regno].red;
- *green = sis_palette[regno].green;
- *blue = sis_palette[regno].blue;
+ *red = ivideo->sis_palette[regno].red;
+ *green = ivideo->sis_palette[regno].green;
+ *blue = ivideo->sis_palette[regno].blue;
*transp = 0;
+
return 0;
}
-static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
- unsigned transp, struct fb_info *fb_info)
+static int
+sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
{
- if (regno >= ivideo.video_cmap_len)
- return 1;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
- sis_palette[regno].red = red;
- sis_palette[regno].green = green;
- sis_palette[regno].blue = blue;
+ if(regno >= ivideo->video_cmap_len) return 1;
- switch (ivideo.video_bpp) {
+ ivideo->sis_palette[regno].red = red;
+ ivideo->sis_palette[regno].green = green;
+ ivideo->sis_palette[regno].blue = blue;
+
+ switch(ivideo->video_bpp) {
#ifdef FBCON_HAS_CFB8
case 8:
outSISREG(SISDACA, regno);
outSISREG(SISDACD, (red >> 10));
outSISREG(SISDACD, (green >> 10));
outSISREG(SISDACD, (blue >> 10));
- if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
outSISREG(SISDAC2A, regno);
outSISREG(SISDAC2D, (red >> 8));
outSISREG(SISDAC2D, (green >> 8));
#endif
#ifdef FBCON_HAS_CFB16
case 16:
- sis_fbcon_cmap.cfb16[regno] =
+ ivideo->sis_fbcon_cmap.cfb16[regno] =
((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
break;
#endif
#ifdef FBCON_HAS_CFB32
case 32:
- red >>= 8;
+ red >>= 8;
green >>= 8;
- blue >>= 8;
- sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+ blue >>= 8;
+ ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
break;
#endif
}
+
return 0;
}
-static void sisfb_set_disp(int con, struct fb_var_screeninfo *var,
- struct fb_info *info)
+static void
+sisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ struct display *display;
+ struct display_switch *sw;
struct fb_fix_screeninfo fix;
long flags;
- struct display *display;
- struct display_switch *sw;
- if(con >= 0)
- display = &fb_display[con];
- else
- display = &sis_disp;
+ display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
- sisfb_get_fix(&fix, con, 0);
+ sisfb_get_fix(&fix, con, info);
- display->screen_base = ivideo.video_vbase;
+ display->var = *var;
+ display->screen_base = (char *)ivideo->video_vbase;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
display->ypanstep = fix.ypanstep;
display->ywrapstep = fix.ywrapstep;
display->line_length = fix.line_length;
- display->next_line = fix.line_length;
display->can_soft_blank = 1;
- display->inverse = sisfb_inverse;
- display->var = *var;
+ display->inverse = ivideo->sisfb_inverse;
+ display->next_line = fix.line_length;
save_flags(flags);
- switch (ivideo.video_bpp) {
+ switch(ivideo->video_bpp) {
#ifdef FBCON_HAS_CFB8
- case 8:
-#ifdef SISFBACCEL
- sw = ivideo.accel ? &fbcon_sis8 : &fbcon_cfb8;
-#else
- sw = &fbcon_cfb8;
-#endif
+ case 8: sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;
break;
#endif
#ifdef FBCON_HAS_CFB16
- case 16:
-#ifdef SISFBACCEL
- sw = ivideo.accel ? &fbcon_sis16 : &fbcon_cfb16;
-#else
- sw = &fbcon_cfb16;
-#endif
- display->dispsw_data = sis_fbcon_cmap.cfb16;
+ case 16:sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;
+ display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;
break;
#endif
#ifdef FBCON_HAS_CFB32
- case 32:
-#ifdef SISFBACCEL
- sw = ivideo.accel ? &fbcon_sis32 : &fbcon_cfb32;
-#else
- sw = &fbcon_cfb32;
-#endif
- display->dispsw_data = sis_fbcon_cmap.cfb32;
+ case 32:sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;
+ display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;
break;
#endif
- default:
- sw = &fbcon_dummy;
- return;
+ default:sw = &fbcon_dummy;
+ break;
}
- memcpy(&sisfb_sw, sw, sizeof(*sw));
- display->dispsw = &sisfb_sw;
+ memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));
+ display->dispsw = &ivideo->sisfb_sw;
+
restore_flags(flags);
- if(sisfb_ypan) {
+ if(ivideo->sisfb_ypan) {
/* display->scrollmode = 0; */
} else {
display->scrollmode = SCROLL_YREDRAW;
- sisfb_sw.bmove = fbcon_redraw_bmove;
+ ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;
}
}
-static void sisfb_do_install_cmap(int con, struct fb_info *info)
+static void
+sisfb_do_install_cmap(int con, struct fb_info *info)
{
- if (con != currcon)
- return;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+ if(con != ivideo->currcon) return;
- if (fb_display[con].cmap.len)
+ if(fb_display[con].cmap.len) {
fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);
- else
- fb_set_cmap(fb_default_cmap(ivideo.video_cmap_len), 1,
- sisfb_setcolreg, info);
+ } else {
+ int size = sisfb_get_cmap_len(&fb_display[con].var);
+ fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);
+ }
}
-
-static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int
+sisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
- if(con == -1)
- memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
- else
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+ if(con == -1) {
+ memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));
+ } else {
*var = fb_display[con].var;
+ }
- if(sisfb_fstn) {
- if (var->xres == 320 && var->yres == 480)
- var->yres = 240;
+ if(ivideo->sisfb_fstn) {
+ if(var->xres == 320 && var->yres == 480) var->yres = 240;
}
return 0;
}
-static int sisfb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int
+sisfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
int err;
- unsigned int cols, rows;
fb_display[con].var.activate = FB_ACTIVATE_NOW;
- if(sisfb_do_set_var(var, con == currcon, info)) {
- sisfb_crtc_to_var(var);
+
+ if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {
+ sisfb_crtc_to_var(ivideo, var);
return -EINVAL;
}
- sisfb_crtc_to_var(var);
+ sisfb_crtc_to_var(ivideo, var);
sisfb_set_disp(con, var, info);
- if(info->changevar)
- (*info->changevar) (con);
+ if(info->changevar) {
+ (*info->changevar)(con);
+ }
- if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0)))
+ if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {
return err;
+ }
sisfb_do_install_cmap(con, info);
- cols = sisbios_mode[sisfb_mode_idx].cols;
- rows = sisbios_mode[sisfb_mode_idx].rows;
-#if 0
- /* Why was this called here? */
+#if 0 /* Why was this called here? */
+ unsigned int cols, rows;
+ cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
+ rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
#endif
-
return 0;
}
-static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
+static int
+sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
{
- if (con == currcon)
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ struct display *display;
+
+ display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
+
+ if(con == ivideo->currcon) {
+
return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
- else if (fb_display[con].cmap.len)
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
+ } else if(display->cmap.len) {
- return 0;
-}
+ fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);
-static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- int err;
+ } else {
- if (!fb_display[con].cmap.len) {
- err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
- if (err)
- return err;
- }
-
- if (con == currcon)
- return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+ int size = sisfb_get_cmap_len(&display->var);
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+ }
return 0;
}
-static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info* info)
+static int
+sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
{
- int err;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ struct display *display;
+ int err, size;
- if (var->vmode & FB_VMODE_YWRAP) {
- if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
- return -EINVAL;
- } else {
- if (var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
- var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)
- return -EINVAL;
- }
+ display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;
- if(con == currcon) {
- if((err = sisfb_pan_var(var)) < 0) return err;
+ size = sisfb_get_cmap_len(&display->var);
+ if(display->cmap.len != size) {
+ err = fb_alloc_cmap(&display->cmap, size, 0);
+ if(err) return err;
+ }
+
+ if(con == ivideo->currcon) {
+ return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+ } else {
+ fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);
}
-
- fb_display[con].var.xoffset = var->xoffset;
- fb_display[con].var.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- fb_display[con].var.vmode |= FB_VMODE_YWRAP;
- else
- fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
return 0;
}
-static int sisfb_mmap(struct fb_info *info, struct file *file,
- struct vm_area_struct *vma)
+static int
+sisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info)
{
- struct fb_var_screeninfo var;
- unsigned long start;
- unsigned long off;
- u32 len, mmio_off;
-
- if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL;
-
- off = vma->vm_pgoff << PAGE_SHIFT;
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ int err;
- start = (unsigned long) ivideo.video_base;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
-#if 0
- if (off >= len) {
- off -= len;
-#endif
- /* By Jake Page: Treat mmap request with offset beyond heapstart
- * as request for mapping the mmio area
- */
- mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);
- if(off >= mmio_off) {
- off -= mmio_off;
- sisfb_get_var(&var, currcon, info);
- if(var.accel_flags) return -EINVAL;
+ if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
- start = (unsigned long) ivideo.mmio_base;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
+ if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||
+ (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {
+ return -EINVAL;
}
- start &= PAGE_MASK;
- if((vma->vm_end - vma->vm_start + off) > len) return -EINVAL;
-
- off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
- vma->vm_flags |= VM_IO; /* by Jake Page; is that really needed? */
+ if(con == ivideo->currcon) {
+ if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
+ }
-#if defined(__i386__) || defined(__x86_64__)
- if (boot_cpu_data.x86 > 3)
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
- /* RedHat requires vma as the first paramater to the following call */
- if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
- return -EAGAIN;
+ fb_display[con].var.xoffset = var->xoffset;
+ fb_display[con].var.yoffset = var->yoffset;
return 0;
}
-static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly)
+static int
+sisfb_update_var(int con, struct fb_info *info)
{
- struct display *p = &fb_display[currcon];
- u16 c;
- u8 *cdat;
- int widthb;
- u8 *gbuf = gly->gmask;
- int size;
-
- gly->fontheight = fontheight(p);
- gly->fontwidth = fontwidth(p);
- widthb = (fontwidth(p) + 7) / 8;
-
- c = gly->ch & p->charmask;
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + c * fontheight(p);
- else
- cdat = p->fontdata + (c * fontheight(p) << 1);
-
- size = fontheight(p) * widthb;
- memcpy(gbuf, cdat, size);
- gly->ngmask = size;
-}
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-static int sisfb_update_var(int con, struct fb_info *info)
-{
- return(sisfb_pan_var(&fb_display[con].var));
+ return(sisfb_pan_var(ivideo, &fb_display[con].var));
}
-static int sisfb_switch(int con, struct fb_info *info)
+static int
+sisfb_switch(int con, struct fb_info *info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
int cols, rows;
- if(fb_display[currcon].cmap.len)
- fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);
+ if(fb_display[ivideo->currcon].cmap.len) {
+ fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);
+ }
fb_display[con].var.activate = FB_ACTIVATE_NOW;
- if(!memcmp(&fb_display[con].var, &fb_display[currcon].var,
- sizeof(struct fb_var_screeninfo))) {
- currcon = con;
+ if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,
+ sizeof(struct fb_var_screeninfo))) {
+ ivideo->currcon = con;
return 1;
}
- currcon = con;
+ ivideo->currcon = con;
sisfb_do_set_var(&fb_display[con].var, 1, info);
sisfb_do_install_cmap(con, info);
- cols = sisbios_mode[sisfb_mode_idx].cols;
- rows = sisbios_mode[sisfb_mode_idx].rows;
+ cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;
+ rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;
vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
sisfb_update_var(con, info);
return 1;
}
-static void sisfb_blank(int blank, struct fb_info *info)
+static void
+sisfb_blank(int blank, struct fb_info *info)
{
- sisfb_myblank(blank);
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+ sisfb_myblank(ivideo, blank);
}
#endif
-/* ------------ FBDev related routines for 2.5 series ----------- */
+/* ------------ FBDev related routines for 2.6 series ----------- */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_open(struct fb_info *info, int user)
+static int
+sisfb_open(struct fb_info *info, int user)
{
- return 0;
+ return 0;
}
-static int sisfb_release(struct fb_info *info, int user)
+static int
+sisfb_release(struct fb_info *info, int user)
{
- return 0;
+ return 0;
}
-static int sisfb_get_cmap_len(const struct fb_var_screeninfo *var)
+static int
+sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
{
- int rc = 16;
-
- switch(var->bits_per_pixel) {
- case 8:
- rc = 256;
- break;
- case 16:
- case 32:
- rc = 16;
- break;
- }
- return rc;
-}
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
- unsigned transp, struct fb_info *info)
-{
- if (regno >= sisfb_get_cmap_len(&info->var))
- return 1;
+ if(regno >= sisfb_get_cmap_len(&info->var)) return 1;
- switch (info->var.bits_per_pixel) {
+ switch(info->var.bits_per_pixel) {
case 8:
outSISREG(SISDACA, regno);
outSISREG(SISDACD, (red >> 10));
outSISREG(SISDACD, (green >> 10));
outSISREG(SISDACD, (blue >> 10));
- if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
outSISREG(SISDAC2A, regno);
outSISREG(SISDAC2D, (red >> 8));
outSISREG(SISDAC2D, (green >> 8));
red >>= 8;
green >>= 8;
blue >>= 8;
- ((u32 *) (info->pseudo_palette))[regno] =
- (red << 16) | (green << 8) | (blue);
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (red << 16) | (green << 8) | (blue);
break;
}
return 0;
}
-static int sisfb_set_par(struct fb_info *info)
+static int
+sisfb_set_par(struct fb_info *info)
{
int err;
- if((err = sisfb_do_set_var(&info->var, 1, info)))
+ if((err = sisfb_do_set_var(&info->var, 1, info))) {
return err;
+ }
sisfb_get_fix(&info->fix, info->currcon, info);
return 0;
}
-static int sisfb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
+static int
+sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
unsigned int drate = 0, hrate = 0, maxyres;
int found_mode = 0;
}
search_idx = 0;
- while( (sisbios_mode[search_idx].mode_no != 0) &&
+ while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
(sisbios_mode[search_idx].xres <= var->xres) ) {
if( (sisbios_mode[search_idx].xres == var->xres) &&
(sisbios_mode[search_idx].yres == var->yres) &&
(sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
- if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+ if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) {
found_mode = 1;
break;
}
}
if(!found_mode) {
-
search_idx = 0;
- while(sisbios_mode[search_idx].mode_no != 0) {
+ while(sisbios_mode[search_idx].mode_no[0] != 0) {
if( (var->xres <= sisbios_mode[search_idx].xres) &&
(var->yres <= sisbios_mode[search_idx].yres) &&
(var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
- if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
+ if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) {
found_mode = 1;
break;
}
}
}
- if( ((ivideo.vbflags & VB_LVDS) || /* Slave modes on LVDS and 301B-DH */
- ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
+ if( ((ivideo->vbflags & VB_LVDS) || /* Slave modes on LVDS and 301B-DH */
+ ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&
(var->bits_per_pixel == 8) ) {
refresh_rate = 60;
recalc_clock = TRUE;
- } else if( (ivideo.current_htotal == htotal) && /* x=x & y=y & c=c -> assume depth change */
- (ivideo.current_vtotal == vtotal) &&
- (ivideo.current_pixclock == pixclock) ) {
+ } else if( (ivideo->current_htotal == htotal) && /* x=x & y=y & c=c -> assume depth change */
+ (ivideo->current_vtotal == vtotal) &&
+ (ivideo->current_pixclock == pixclock) ) {
drate = 1000000000 / pixclock;
hrate = (drate * 1000) / htotal;
refresh_rate = (unsigned int) (hrate * 2 / vtotal);
- } else if( ( (ivideo.current_htotal != htotal) || /* x!=x | y!=y & c=c -> invalid pixclock */
- (ivideo.current_vtotal != vtotal) ) &&
- (ivideo.current_pixclock == var->pixclock) ) {
- if(sisfb_lastrates[sisbios_mode[search_idx].mode_no]) {
- refresh_rate = sisfb_lastrates[sisbios_mode[search_idx].mode_no];
- } else if(sisfb_parm_rate != -1) {
- refresh_rate = sisfb_parm_rate;
+ } else if( ( (ivideo->current_htotal != htotal) || /* x!=x | y!=y & c=c -> invalid pixclock */
+ (ivideo->current_vtotal != vtotal) ) &&
+ (ivideo->current_pixclock == var->pixclock) ) {
+ if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {
+ refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];
+ } else if(ivideo->sisfb_parm_rate != -1) {
+ /* Sic, sisfb_parm_rate - want to know originally desired rate here */
+ refresh_rate = ivideo->sisfb_parm_rate;
} else {
refresh_rate = 60;
}
drate = 1000000000 / pixclock;
hrate = (drate * 1000) / htotal;
refresh_rate = (unsigned int) (hrate * 2 / vtotal);
- } else if(ivideo.current_refresh_rate) {
- refresh_rate = ivideo.current_refresh_rate;
+ } else if(ivideo->current_refresh_rate) {
+ refresh_rate = ivideo->current_refresh_rate;
recalc_clock = TRUE;
} else {
refresh_rate = 60;
recalc_clock = TRUE;
}
- myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
+ myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
/* Eventually recalculate timing and clock */
if(recalc_clock) {
if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
- var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
- sisbios_mode[search_idx].mode_no, myrateindex));
- sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
- sisbios_mode[search_idx].mode_no, myrateindex,
- &var->left_margin, &var->right_margin,
- &var->upper_margin, &var->lower_margin,
- &var->hsync_len, &var->vsync_len,
- &var->sync, &var->vmode);
+ var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr,
+ &ivideo->sishw_ext,
+ sisbios_mode[search_idx].mode_no[ivideo->mni],
+ myrateindex));
+ sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+ sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex, var);
if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- var->pixclock <<= 1;
+ var->pixclock <<= 1;
}
}
- if(sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
+ if(ivideo->sisfb_thismonitor.datavalid) {
+ if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,
myrateindex, refresh_rate)) {
printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
}
}
/* Adapt RGB settings */
- sisfb_bpp_to_var(var);
+ sisfb_bpp_to_var(ivideo, var);
/* Sanity check for offsets */
- if (var->xoffset < 0)
- var->xoffset = 0;
- if (var->yoffset < 0)
- var->yoffset = 0;
+ if(var->xoffset < 0) var->xoffset = 0;
+ if(var->yoffset < 0) var->yoffset = 0;
- /* Horiz-panning not supported */
- if(var->xres != var->xres_virtual)
- var->xres_virtual = var->xres;
+ if(var->xres > var->xres_virtual) {
+ var->xres_virtual = var->xres;
+ }
- if(sisfb_ypan) {
- maxyres = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
- if(maxyres > 32767) maxyres = 32767;
- if(sisfb_max) {
+ if(ivideo->sisfb_ypan) {
+ maxyres = sisfb_calc_maxyres(ivideo, var);
+ if(ivideo->sisfb_max) {
var->yres_virtual = maxyres;
} else {
if(var->yres_virtual > maxyres) {
}
/* Truncate offsets to maximum if too high */
- if(var->xoffset > var->xres_virtual - var->xres)
- var->xoffset = var->xres_virtual - var->xres - 1;
+ if(var->xoffset > var->xres_virtual - var->xres) {
+ var->xoffset = var->xres_virtual - var->xres - 1;
+ }
- if(var->yoffset > var->yres_virtual - var->yres)
- var->yoffset = var->yres_virtual - var->yres - 1;
+ if(var->yoffset > var->yres_virtual - var->yres) {
+ var->yoffset = var->yres_virtual - var->yres - 1;
+ }
/* Set everything else to 0 */
var->red.msb_right =
- var->green.msb_right =
- var->blue.msb_right =
- var->transp.offset = var->transp.length = var->transp.msb_right = 0;
+ var->green.msb_right =
+ var->blue.msb_right =
+ var->transp.offset =
+ var->transp.length =
+ var->transp.msb_right = 0;
return 0;
}
-static int sisfb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info* info)
+static int
+sisfb_pan_display(struct fb_var_screeninfo *var, struct fb_info* info)
{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
int err;
- if (var->xoffset > (var->xres_virtual - var->xres))
+ if(var->xoffset > (var->xres_virtual - var->xres)) {
return -EINVAL;
- if (var->yoffset > (var->yres_virtual - var->yres))
+ }
+ if(var->yoffset > (var->yres_virtual - var->yres)) {
return -EINVAL;
-
- if (var->vmode & FB_VMODE_YWRAP) {
- if (var->yoffset < 0 ||
- var->yoffset >= info->var.yres_virtual ||
- var->xoffset)
- return -EINVAL;
- } else {
- if (var->xoffset + info->var.xres > info->var.xres_virtual ||
- var->yoffset + info->var.yres > info->var.yres_virtual)
- return -EINVAL;
}
-
- if((err = sisfb_pan_var(var)) < 0) return err;
-
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- info->var.vmode |= FB_VMODE_YWRAP;
- else
- info->var.vmode &= ~FB_VMODE_YWRAP;
-
- return 0;
-}
-
-static int sisfb_mmap(struct fb_info *info, struct file *file,
- struct vm_area_struct *vma)
-{
- unsigned long start;
- unsigned long off;
- u32 len, mmio_off;
-
- if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL;
- off = vma->vm_pgoff << PAGE_SHIFT;
+ if(var->vmode & FB_VMODE_YWRAP) return -EINVAL;
- start = (unsigned long) ivideo.video_base;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);
-#if 0
- if (off >= len) {
- off -= len;
-#endif
- /* By Jake Page: Treat mmap request with offset beyond heapstart
- * as request for mapping the mmio area
- */
- mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);
- if(off >= mmio_off) {
- off -= mmio_off;
- if(info->var.accel_flags) return -EINVAL;
-
- start = (unsigned long) ivideo.mmio_base;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);
+ if(var->xoffset + info->var.xres > info->var.xres_virtual ||
+ var->yoffset + info->var.yres > info->var.yres_virtual) {
+ return -EINVAL;
}
- start &= PAGE_MASK;
- if((vma->vm_end - vma->vm_start + off) > len) return -EINVAL;
-
- off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
- vma->vm_flags |= VM_IO; /* by Jake Page; is that really needed? */
+ if((err = sisfb_pan_var(ivideo, var)) < 0) return err;
-#if defined(__i386__) || defined(__x86_64__)
- if (boot_cpu_data.x86 > 3)
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
- if (io_remap_page_range(vma, vma->vm_start, off, vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
- return -EAGAIN;
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
return 0;
}
-static int sisfb_blank(int blank, struct fb_info *info)
+static int
+sisfb_blank(int blank, struct fb_info *info)
{
- return(sisfb_myblank(blank));
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+
+ return(sisfb_myblank(ivideo, blank));
}
#endif
/* ----------- FBDev related routines for all series ---------- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static int sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg,
- struct fb_info *info)
-#else
-static int sisfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int con,
- struct fb_info *info)
-#endif
-{
- struct sis_memreq sismemreq;
- struct ap_data sisapdata;
- unsigned long sismembase = 0;
+static int
+sisfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- SIS_GLYINFO sisglyinfo;
+ int con,
#endif
+ struct fb_info *info)
+{
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+ struct sis_memreq sismemreq;
+ struct fb_vblank sisvbblank;
+ sisfb_info x;
+ u32 gpu32 = 0;
+ static int count = 0;
+ u32 __user *argp = (u32 __user *) arg;
switch (cmd) {
case FBIO_ALLOC:
- if(!capable(CAP_SYS_RAWIO))
+ if(!capable(CAP_SYS_RAWIO)) {
return -EPERM;
- if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
+ }
+ if(copy_from_user(&sismemreq, argp, sizeof(sismemreq))) {
return -EFAULT;
+ }
sis_malloc(&sismemreq);
- if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
- sis_free(sismemreq.offset);
+ if(copy_to_user(argp, &sismemreq, sizeof(sismemreq))) {
+ sis_free((u32)sismemreq.offset);
return -EFAULT;
}
break;
+
case FBIO_FREE:
- if(!capable(CAP_SYS_RAWIO))
+ if(!capable(CAP_SYS_RAWIO)) {
return -EPERM;
- if(get_user(sismembase, (unsigned long *) arg))
+ }
+ if(get_user(gpu32, argp)) {
return -EFAULT;
- sis_free(sismembase);
+ }
+ sis_free(gpu32);
break;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- case FBIOGET_GLYPH:
- if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
+
+ case FBIOGET_VBLANK:
+ sisvbblank.count = 0;
+ sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
+ if(copy_to_user(argp, &sisvbblank, sizeof(sisvbblank))) {
return -EFAULT;
- sis_get_glyph(info, &sisglyinfo);
- break;
- case FBIOPUT_MODEINFO:
- {
- struct mode_info x;
-
- if(copy_from_user(&x, (void *)arg, sizeof(x)))
- return -EFAULT;
-
- ivideo.video_bpp = x.bpp;
- ivideo.video_width = x.xres;
- ivideo.video_height = x.yres;
- ivideo.video_vwidth = x.v_xres;
- ivideo.video_vheight = x.v_yres;
- ivideo.org_x = x.org_x;
- ivideo.org_y = x.org_y;
- ivideo.refresh_rate = x.vrate;
- ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
- sisfb_set_vparms();
- break;
}
-#endif
- case FBIOGET_HWCINFO:
- {
- unsigned long myhwcoffset = 0;
-
- if(sisfb_caps & HW_CURSOR_CAP)
- myhwcoffset = sisfb_hwcursor_vbase -
- (unsigned long) ivideo.video_vbase;
+ break;
- return put_user(myhwcoffset, (unsigned long *)arg);
+ case SISFB_GET_INFO_SIZE:
+ return put_user(sizeof(sisfb_info), argp);
- break;
+ case SISFB_GET_INFO_OLD:
+ if(++count < 50) {
+ printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
}
- case FBIOGET_DISPINFO:
- sis_dispinfo(&sisapdata);
- if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
- return -EFAULT;
- break;
case SISFB_GET_INFO: /* For communication with X driver */
- {
- sisfb_info x;
-
- x.sisfb_id = SISFB_ID;
- x.sisfb_version = VER_MAJOR;
- x.sisfb_revision = VER_MINOR;
- x.sisfb_patchlevel = VER_LEVEL;
- x.chip_id = ivideo.chip_id;
- x.memory = ivideo.video_size / 1024;
- x.heapstart = ivideo.heapstart / 1024;
- x.fbvidmode = sisfb_mode_no;
- x.sisfb_caps = sisfb_caps;
- x.sisfb_tqlen = 512; /* yet fixed */
- x.sisfb_pcibus = ivideo.pcibus;
- x.sisfb_pcislot = ivideo.pcislot;
- x.sisfb_pcifunc = ivideo.pcifunc;
- x.sisfb_lcdpdc = sisfb_detectedpdc;
- x.sisfb_lcda = sisfb_detectedlcda;
- x.sisfb_vbflags = ivideo.vbflags;
- x.sisfb_currentvbflags = ivideo.currentvbflags;
- x.sisfb_scalelcd = SiS_Pr.UsePanelScaler;
- x.sisfb_specialtiming = SiS_Pr.SiS_CustomT;
- x.sisfb_haveemi = SiS_Pr.HaveEMI ? 1 : 0;
- x.sisfb_haveemilcd = SiS_Pr.HaveEMILCD ? 1 : 0;
- x.sisfb_emi30 = SiS_Pr.EMI_30;
- x.sisfb_emi31 = SiS_Pr.EMI_31;
- x.sisfb_emi32 = SiS_Pr.EMI_32;
- x.sisfb_emi33 = SiS_Pr.EMI_33;
- if(copy_to_user((void *)arg, &x, sizeof(x)))
- return -EFAULT;
- break;
+ x.sisfb_id = SISFB_ID;
+ x.sisfb_version = VER_MAJOR;
+ x.sisfb_revision = VER_MINOR;
+ x.sisfb_patchlevel = VER_LEVEL;
+ x.chip_id = ivideo->chip_id;
+ x.memory = ivideo->video_size / 1024;
+ x.heapstart = ivideo->heapstart / 1024;
+ if(ivideo->modechanged) {
+ x.fbvidmode = ivideo->mode_no;
+ } else {
+ x.fbvidmode = ivideo->modeprechange;
+ }
+ x.sisfb_caps = ivideo->caps;
+ x.sisfb_tqlen = 512; /* yet fixed */
+ x.sisfb_pcibus = ivideo->pcibus;
+ x.sisfb_pcislot = ivideo->pcislot;
+ x.sisfb_pcifunc = ivideo->pcifunc;
+ x.sisfb_lcdpdc = ivideo->detectedpdc;
+ x.sisfb_lcdpdca = ivideo->detectedpdca;
+ x.sisfb_lcda = ivideo->detectedlcda;
+ x.sisfb_vbflags = ivideo->vbflags;
+ x.sisfb_currentvbflags = ivideo->currentvbflags;
+ x.sisfb_scalelcd = ivideo->SiS_Pr.UsePanelScaler;
+ x.sisfb_specialtiming = ivideo->SiS_Pr.SiS_CustomT;
+ x.sisfb_haveemi = ivideo->SiS_Pr.HaveEMI ? 1 : 0;
+ x.sisfb_haveemilcd = ivideo->SiS_Pr.HaveEMILCD ? 1 : 0;
+ x.sisfb_emi30 = ivideo->SiS_Pr.EMI_30;
+ x.sisfb_emi31 = ivideo->SiS_Pr.EMI_31;
+ x.sisfb_emi32 = ivideo->SiS_Pr.EMI_32;
+ x.sisfb_emi33 = ivideo->SiS_Pr.EMI_33;
+ x.sisfb_tvxpos = (u16)(ivideo->tvxpos + 32);
+ x.sisfb_tvypos = (u16)(ivideo->tvypos + 32);
+
+ if(copy_to_user(argp, &x, sizeof(x))) {
+ return -EFAULT;
+ }
+ break;
+
+ case SISFB_GET_VBRSTATUS_OLD:
+ if(++count < 50) {
+ printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
}
case SISFB_GET_VBRSTATUS:
- {
- if(sisfb_CheckVBRetrace())
- return put_user(1UL, (unsigned long *) arg);
- else
- return put_user(0UL, (unsigned long *) arg);
- break;
+ if(sisfb_CheckVBRetrace(ivideo)) {
+ return put_user((u32)1, argp);
+ } else {
+ return put_user((u32)0, argp);
+ }
+
+ case SISFB_GET_AUTOMAXIMIZE_OLD:
+ if(++count < 50) {
+ printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
}
case SISFB_GET_AUTOMAXIMIZE:
- {
- if(sisfb_max)
- return put_user(1UL, (unsigned long *) arg);
- else
- return put_user(0UL, (unsigned long *) arg);
- break;
+ if(ivideo->sisfb_max) return put_user((u32)1, argp);
+ else return put_user((u32)0, argp);
+
+ case SISFB_SET_AUTOMAXIMIZE_OLD:
+ if(++count < 50) {
+ printk(KERN_INFO "sisfb: Deprecated ioctl call received - update your application!\n");
}
case SISFB_SET_AUTOMAXIMIZE:
- {
- unsigned long newmax;
+ if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+ return -EFAULT;
+ }
+ ivideo->sisfb_max = (gpu32) ? 1 : 0;
+ break;
+
+ case SISFB_SET_TVPOSOFFSET:
+ if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+ return -EFAULT;
+ }
+ sisfb_set_TVxposoffset(ivideo, ((int)(gpu32 >> 16)) - 32);
+ sisfb_set_TVyposoffset(ivideo, ((int)(gpu32 & 0xffff)) - 32);
+ break;
- if(copy_from_user(&newmax, (unsigned long *)arg, sizeof(newmax)))
- return -EFAULT;
+ case SISFB_GET_TVPOSOFFSET:
+ return put_user((u32)(((ivideo->tvxpos+32)<<16)|((ivideo->tvypos+32)&0xffff)), argp);
- if(newmax) sisfb_max = 1;
- else sisfb_max = 0;
- break;
+ case SISFB_SET_LOCK:
+ if(copy_from_user(&gpu32, argp, sizeof(gpu32))) {
+ return -EFAULT;
}
+ ivideo->sisfblocked = (gpu32) ? 1 : 0;
+ break;
+
default:
return -EINVAL;
}
return 0;
}
-
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
+static int
+sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- strcpy(fix->id, sis_fb_info->modename);
-#else
- strcpy(fix->id, myid);
-#endif
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- fix->smem_start = ivideo.video_base;
-
- if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
- if(sisvga_engine == SIS_300_VGA) {
- if(ivideo.video_size > 0x1000000) {
- fix->smem_len = 0xc00000;
- } else if(ivideo.video_size > 0x800000)
- fix->smem_len = 0x800000;
- else
- fix->smem_len = 0x400000;
- } else {
- fix->smem_len = ivideo.video_size - 0x100000;
- }
- } else
- fix->smem_len = sisfb_mem * 1024;
+ strcpy(fix->id, ivideo->myid);
+ fix->smem_start = ivideo->video_base;
+ fix->smem_len = ivideo->sisfb_mem;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
- if(ivideo.video_bpp == 8)
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
- else
- fix->visual = FB_VISUAL_TRUECOLOR;
- fix->xpanstep = 0;
-
- if(sisfb_ypan) fix->ypanstep = 1;
-
+ fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 1;
+ fix->ypanstep = (ivideo->sisfb_ypan) ? 1 : 0;
fix->ywrapstep = 0;
- fix->line_length = ivideo.video_linelength;
- fix->mmio_start = ivideo.mmio_base;
- fix->mmio_len = sisfb_mmio_size;
- if(sisvga_engine == SIS_300_VGA)
+ fix->line_length = ivideo->video_linelength;
+ fix->mmio_start = ivideo->mmio_base;
+ fix->mmio_len = ivideo->mmio_size;
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
fix->accel = FB_ACCEL_SIS_GLAMOUR;
- else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_760))
+ } else if((ivideo->chip == SIS_330) || (ivideo->chip == SIS_760)) {
fix->accel = FB_ACCEL_SIS_XABRE;
- else
+ } else {
fix->accel = FB_ACCEL_SIS_GLAMOUR_2;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- fix->reserved[0] = ivideo.video_size & 0xFFFF;
- fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
- fix->reserved[2] = sisfb_caps;
-#endif
+ }
return 0;
}
.fb_get_cmap = sisfb_get_cmap,
.fb_set_cmap = sisfb_set_cmap,
.fb_pan_display = sisfb_pan_display,
- .fb_ioctl = sisfb_ioctl,
- .fb_mmap = sisfb_mmap,
+ .fb_ioctl = sisfb_ioctl
};
#endif
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
static struct fb_ops sisfb_ops = {
- .owner = THIS_MODULE,
- .fb_open = sisfb_open,
- .fb_release = sisfb_release,
- .fb_check_var = sisfb_check_var,
- .fb_set_par = sisfb_set_par,
- .fb_setcolreg = sisfb_setcolreg,
+ .owner = THIS_MODULE,
+ .fb_open = sisfb_open,
+ .fb_release = sisfb_release,
+ .fb_check_var = sisfb_check_var,
+ .fb_set_par = sisfb_set_par,
+ .fb_setcolreg = sisfb_setcolreg,
.fb_pan_display = sisfb_pan_display,
- .fb_blank = sisfb_blank,
- .fb_fillrect = fbcon_sis_fillrect,
- .fb_copyarea = fbcon_sis_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_cursor = soft_cursor,
- .fb_sync = fbcon_sis_sync,
- .fb_ioctl = sisfb_ioctl,
- .fb_mmap = sisfb_mmap,
+ .fb_blank = sisfb_blank,
+ .fb_fillrect = fbcon_sis_fillrect,
+ .fb_copyarea = fbcon_sis_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
+ .fb_sync = fbcon_sis_sync,
+ .fb_ioctl = sisfb_ioctl
};
#endif
-
/* ---------------- Chip generation dependent routines ---------------- */
-#ifdef CONFIG_FB_SIS_300 /* for SiS 300/630/540/730 */
-
-static int sisfb_get_dram_size_300(void)
+static struct pci_dev * sisfb_get_northbridge(int basechipid)
{
struct pci_dev *pdev = NULL;
- int pdev_valid = 0;
- u8 pci_data, reg;
- u16 nbridge_id;
-
- switch (ivideo.chip) {
- case SIS_540:
- nbridge_id = PCI_DEVICE_ID_SI_540;
- break;
- case SIS_630:
- nbridge_id = PCI_DEVICE_ID_SI_630;
- break;
- case SIS_730:
- nbridge_id = PCI_DEVICE_ID_SI_730;
- break;
- default:
- nbridge_id = 0;
- break;
+ int nbridgenum, nbridgeidx, i;
+ const unsigned short nbridgeids[] = {
+ PCI_DEVICE_ID_SI_540, /* for SiS 540 VGA */
+ PCI_DEVICE_ID_SI_630, /* for SiS 630/730 VGA */
+ PCI_DEVICE_ID_SI_730,
+ PCI_DEVICE_ID_SI_550, /* for SiS 550 VGA */
+ PCI_DEVICE_ID_SI_650, /* for SiS 650/651/740 VGA */
+ PCI_DEVICE_ID_SI_651,
+ PCI_DEVICE_ID_SI_740,
+ PCI_DEVICE_ID_SI_661, /* for SiS 661/741/660/760 VGA */
+ PCI_DEVICE_ID_SI_741,
+ PCI_DEVICE_ID_SI_660,
+ PCI_DEVICE_ID_SI_760
+ };
+
+ switch(basechipid) {
+#ifdef CONFIG_FB_SIS_300
+ case SIS_540: nbridgeidx = 0; nbridgenum = 1; break;
+ case SIS_630: nbridgeidx = 1; nbridgenum = 2; break;
+#endif
+#ifdef CONFIG_FB_SIS_315
+ case SIS_550: nbridgeidx = 3; nbridgenum = 1; break;
+ case SIS_650: nbridgeidx = 4; nbridgenum = 3; break;
+ case SIS_660: nbridgeidx = 7; nbridgenum = 4; break;
+#endif
+ default: return NULL;
}
-
- if (nbridge_id == 0) { /* 300 */
-
- inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE,reg);
- ivideo.video_size =
- ((unsigned int) ((reg & SIS_DRAM_SIZE_MASK) + 1) << 20);
-
- } else { /* 540, 630, 730 */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
- pci_for_each_dev(pdev) {
-#else
- while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
-#endif
- if ((pdev->vendor == PCI_VENDOR_ID_SI)
- && (pdev->device == nbridge_id)) {
- pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
- pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
- ivideo.video_size = (unsigned int)(1 << (pci_data+21));
- pdev_valid = 1;
-
- reg = SIS_DATA_BUS_64 << 6;
- switch (pci_data) {
- case BRI_DRAM_SIZE_2MB:
- reg |= SIS_DRAM_SIZE_2MB;
- break;
- case BRI_DRAM_SIZE_4MB:
- reg |= SIS_DRAM_SIZE_4MB;
- break;
- case BRI_DRAM_SIZE_8MB:
- reg |= SIS_DRAM_SIZE_8MB;
- break;
- case BRI_DRAM_SIZE_16MB:
- reg |= SIS_DRAM_SIZE_16MB;
- break;
- case BRI_DRAM_SIZE_32MB:
- reg |= SIS_DRAM_SIZE_32MB;
- break;
- case BRI_DRAM_SIZE_64MB:
- reg |= SIS_DRAM_SIZE_64MB;
- break;
- }
- outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
- break;
- }
- }
-
- if (!pdev_valid) return -1;
+ for(i = 0; i < nbridgenum; i++) {
+ if((pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridgeids[nbridgeidx+i], NULL))) break;
}
- return 0;
+ return pdev;
}
-#endif /* CONFIG_FB_SIS_300 */
-
-
-#ifdef CONFIG_FB_SIS_315 /* for SiS 315/550/650/740/330/661/741/760 */
-
-static int sisfb_get_dram_size_315(void)
+static int __devinit sisfb_get_dram_size(struct sis_video_info *ivideo)
{
- u8 reg = 0;
-
- if(ivideo.chip == SIS_550 ||
- ivideo.chip == SIS_650 ||
- ivideo.chip == SIS_740) {
-
- inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
- reg &= 0x3f;
- reg++;
- reg <<= 2;
- ivideo.video_size = reg << 20;
- return 0;
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
+ u8 reg;
+#endif
- } else if(ivideo.chip == SIS_661 ||
- ivideo.chip == SIS_741 ||
- ivideo.chip == SIS_660 ||
- ivideo.chip == SIS_760) {
+ ivideo->video_size = 0;
+ switch(ivideo->chip) {
+#ifdef CONFIG_FB_SIS_300
+ case SIS_300:
+ inSISIDXREG(SISSR, 0x14, reg);
+ ivideo->video_size = ((reg & 0x3F) + 1) << 20;
+ break;
+ case SIS_540:
+ case SIS_630:
+ case SIS_730:
+ if(!ivideo->nbridge) return -1;
+ pci_read_config_byte(ivideo->nbridge, 0x63, ®);
+ ivideo->video_size = 1 << (((reg & 0x70) >> 4) + 21);
+ break;
+#endif
+#ifdef CONFIG_FB_SIS_315
+ case SIS_315H:
+ case SIS_315PRO:
+ case SIS_315:
+ inSISIDXREG(SISSR, 0x14, reg);
+ ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+ switch((reg >> 2) & 0x03) {
+ case 0x01:
+ case 0x03:
+ ivideo->video_size <<= 1;
+ break;
+ case 0x02:
+ ivideo->video_size += (ivideo->video_size/2);
+ }
+ break;
+ case SIS_330:
+ inSISIDXREG(SISSR, 0x14, reg);
+ ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+ if(reg & 0x0c) ivideo->video_size <<= 1;
+ break;
+ case SIS_550:
+ case SIS_650:
+ case SIS_740:
+ inSISIDXREG(SISSR, 0x14, reg);
+ ivideo->video_size = (((reg & 0x3f) + 1) << 2) << 20;
+ break;
+ case SIS_661:
+ case SIS_741:
+ inSISIDXREG(SISCR, 0x79, reg);
+ ivideo->video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
+ break;
+ case SIS_660:
+ case SIS_760:
inSISIDXREG(SISCR, 0x79, reg);
- reg &= 0xf0;
- reg >>= 4;
- ivideo.video_size = (1 << reg) << 20;
- return 0;
-
- } else { /* 315, 330 */
-
- inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
- ivideo.video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
-
- reg &= SIS315_DUAL_CHANNEL_MASK;
- reg >>= 2;
-
- if(ivideo.chip == SIS_330) {
-
- if(reg) ivideo.video_size <<= 1;
-
- } else {
-
- switch (reg) {
- case SIS315_SINGLE_CHANNEL_2_RANK:
- ivideo.video_size <<= 1;
- break;
- case SIS315_DUAL_CHANNEL_1_RANK:
- ivideo.video_size <<= 1;
- break;
- case SIS315_ASYM_DDR: /* TW: DDR asymetric */
- ivideo.video_size += (ivideo.video_size/2);
- break;
- }
+ reg = (reg & 0xf0) >> 4;
+ if(reg) ivideo->video_size = (1 << reg) << 20;
+ inSISIDXREG(SISCR, 0x78, reg);
+ reg &= 0x30;
+ if(reg) {
+ if(reg == 0x10) ivideo->video_size += (32 << 20);
+ else ivideo->video_size += (64 << 20);
}
-
- return 0;
+ break;
+#endif
+ default:
+ return -1;
}
-
- return -1;
-
+ return 0;
}
-#endif /* CONFIG_FB_SIS_315 */
+/* -------------- video bridge device detection --------------- */
-
-/* -------------- video bridge detection --------------- */
-
-static void sisfb_detect_VB_connect()
+static void __devinit sisfb_detect_VB_connect(struct sis_video_info *ivideo)
{
- u8 sr16, sr17, cr32, temp;
-
- if(sisvga_engine == SIS_300_VGA) {
-
- inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
-
- if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
-
- /* Old BIOSes store the detected CRT2 type in SR17
- * instead of CR32. However, since our detection
- * routines store their results to CR32, we now copy
- * the remaining bits (for LCD and VGA) to CR32 for
- * unified usage.
- * SR17[0] CRT1 [1] LCD [2] TV [3] VGA2
- * [4] AVIDEO [5] SVIDEO
- */
-
-#if 0
- if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
- else andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
-
- if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
- else andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
-
- /* no HiVision and no DVI connector here */
- andSISIDXREG(SISCR, 0x32, ~0xc0);
-#endif
+ u8 cr32, temp;
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ inSISIDXREG(SISSR, 0x17, temp);
+ if((temp & 0x0F) && (ivideo->chip != SIS_300)) {
/* PAL/NTSC is stored on SR16 on such machines */
- if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
- inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
- if (sr16 & 0x20)
- ivideo.vbflags |= TV_PAL;
+ if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN))) {
+ inSISIDXREG(SISSR, 0x16, temp);
+ if(temp & 0x20)
+ ivideo->vbflags |= TV_PAL;
else
- ivideo.vbflags |= TV_NTSC;
+ ivideo->vbflags |= TV_NTSC;
}
-
}
-
}
+#endif
- inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
+ inSISIDXREG(SISCR, 0x32, cr32);
- if (cr32 & SIS_CRT1)
- sisfb_crt1off = 0;
- else {
- if (cr32 & 0x5F)
- sisfb_crt1off = 1;
- else
- sisfb_crt1off = 0;
+ if(cr32 & SIS_CRT1) {
+ ivideo->sisfb_crt1off = 0;
+ } else {
+ ivideo->sisfb_crt1off = (cr32 & 0xDF) ? 1 : 0;
}
- ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
+ ivideo->vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
- if (cr32 & SIS_VB_TV)
- ivideo.vbflags |= CRT2_TV;
- if (cr32 & SIS_VB_LCD)
- ivideo.vbflags |= CRT2_LCD;
- if (cr32 & SIS_VB_CRT2)
- ivideo.vbflags |= CRT2_VGA;
+ if(cr32 & SIS_VB_TV) ivideo->vbflags |= CRT2_TV;
+ if(cr32 & SIS_VB_LCD) ivideo->vbflags |= CRT2_LCD;
+ if(cr32 & SIS_VB_CRT2) ivideo->vbflags |= CRT2_VGA;
- /* TW: Detect/set TV plug & type */
- if(sisfb_tvplug != -1)
- ivideo.vbflags |= sisfb_tvplug;
+ /* Check given parms for hardware compatibility.
+ * (Cannot do this in the search_xx routines since we don't
+ * know what hardware we are running on then)
+ */
- if (cr32 & SIS_VB_SVIDEO)
- ivideo.vbflags |= TV_SVIDEO;
- else if (cr32 & SIS_VB_COMPOSITE)
- ivideo.vbflags |= TV_AVIDEO;
- else if (cr32 & SIS_VB_SCART)
- ivideo.vbflags |= TV_SCART;
+ if(ivideo->chip != SIS_550) {
+ ivideo->sisfb_dstn = ivideo->sisfb_fstn = 0;
+ }
- if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
- if(sisvga_engine == SIS_300_VGA) {
- inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
- if (temp & 0x01)
- ivideo.vbflags |= TV_PAL;
- else
- ivideo.vbflags |= TV_NTSC;
- } else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
+ if(ivideo->sisfb_tvplug != -1) {
+ if( (ivideo->sisvga_engine != SIS_315_VGA) ||
+ (!(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) ) {
+ if(ivideo->sisfb_tvplug & TV_YPBPR) {
+ ivideo->sisfb_tvplug = -1;
+ printk(KERN_ERR "sisfb: YPbPr not supported\n");
+ }
+ }
+ }
+ if(ivideo->sisfb_tvplug != -1) {
+ if( (ivideo->sisvga_engine != SIS_315_VGA) ||
+ (!(ivideo->vbflags & (VB_301|VB_301B|VB_302B))) ) {
+ if(ivideo->sisfb_tvplug & TV_HIVISION) {
+ ivideo->sisfb_tvplug = -1;
+ printk(KERN_ERR "sisfb: HiVision not supported\n");
+ }
+ }
+ }
+ if(ivideo->sisfb_tvstd != -1) {
+ if( (!(ivideo->vbflags & VB_SISBRIDGE)) &&
+ (!((ivideo->sisvga_engine == SIS_315_VGA) && (ivideo->vbflags & VB_CHRONTEL))) ) {
+ if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) {
+ ivideo->sisfb_tvstd = -1;
+ printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n");
+ }
+ }
+ }
- inSISIDXREG(SISSR, 0x38, temp);
- if(temp & 0x01)
- ivideo.vbflags |= TV_PAL;
- else
- ivideo.vbflags |= TV_NTSC;
+ /* Detect/set TV plug & type */
+ if(ivideo->sisfb_tvplug != -1) {
+ ivideo->vbflags |= ivideo->sisfb_tvplug;
+ } else {
+ if(cr32 & SIS_VB_YPBPR) ivideo->vbflags |= (TV_YPBPR|TV_YPBPR525I); /* default: 480i */
+ else if(cr32 & SIS_VB_HIVISION) ivideo->vbflags |= TV_HIVISION;
+ else if(cr32 & SIS_VB_SCART) ivideo->vbflags |= TV_SCART;
+ else {
+ if(cr32 & SIS_VB_SVIDEO) ivideo->vbflags |= TV_SVIDEO;
+ if(cr32 & SIS_VB_COMPOSITE) ivideo->vbflags |= TV_AVIDEO;
+ }
+ }
+ if(!(ivideo->vbflags & (TV_YPBPR | TV_HIVISION))) {
+ if(ivideo->sisfb_tvstd != -1) {
+ ivideo->vbflags &= ~(TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ);
+ ivideo->vbflags |= ivideo->sisfb_tvstd;
+ }
+ if(ivideo->vbflags & TV_SCART) {
+ ivideo->vbflags &= ~(TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ);
+ ivideo->vbflags |= TV_PAL;
+ }
+ if(!(ivideo->vbflags & (TV_PAL | TV_NTSC | TV_PALM | TV_PALN | TV_NTSCJ))) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ inSISIDXREG(SISSR, 0x38, temp);
+ if(temp & 0x01) ivideo->vbflags |= TV_PAL;
+ else ivideo->vbflags |= TV_NTSC;
+ } else if((ivideo->chip <= SIS_315PRO) || (ivideo->chip >= SIS_330)) {
+ inSISIDXREG(SISSR, 0x38, temp);
+ if(temp & 0x01) ivideo->vbflags |= TV_PAL;
+ else ivideo->vbflags |= TV_NTSC;
} else {
-
inSISIDXREG(SISCR, 0x79, temp);
- if(temp & 0x20)
- ivideo.vbflags |= TV_PAL;
- else
- ivideo.vbflags |= TV_NTSC;
+ if(temp & 0x20) ivideo->vbflags |= TV_PAL;
+ else ivideo->vbflags |= TV_NTSC;
}
+ }
}
- /* TW: Copy forceCRT1 option to CRT1off if option is given */
- if (sisfb_forcecrt1 != -1) {
- if(sisfb_forcecrt1) sisfb_crt1off = 0;
- else sisfb_crt1off = 1;
+ /* Copy forceCRT1 option to CRT1off if option is given */
+ if(ivideo->sisfb_forcecrt1 != -1) {
+ ivideo->sisfb_crt1off = (ivideo->sisfb_forcecrt1) ? 0 : 1;
}
-
}
-static void sisfb_get_VB_type(void)
+static void __devinit sisfb_get_VB_type(struct sis_video_info *ivideo)
{
- u8 vb_chipid;
- u8 reg;
char stdstr[] = "sisfb: Detected";
char bridgestr[] = "video bridge";
- char lvdsstr[] = "LVDS transmitter";
- char chrstr[] = "Chrontel TV encoder";
-
- ivideo.hasVB = HASVB_NONE;
- sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
- sishw_ext.Is301BDH = FALSE;
- sishw_ext.usExternalChip = 0;
+ u8 vb_chipid;
+ u8 reg;
inSISIDXREG(SISPART4, 0x00, vb_chipid);
- switch (vb_chipid) {
- case 0x01:
- ivideo.hasVB = HASVB_301;
+ switch(vb_chipid) {
+ case 0x01:
inSISIDXREG(SISPART4, 0x01, reg);
if(reg < 0xb0) {
- ivideo.vbflags |= VB_301;
- sishw_ext.ujVBChipID = VB_CHIP_301;
+ ivideo->vbflags |= VB_301;
printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
} else if(reg < 0xc0) {
- ivideo.vbflags |= VB_301B;
- sishw_ext.ujVBChipID = VB_CHIP_301B;
+ ivideo->vbflags |= VB_301B;
inSISIDXREG(SISPART4,0x23,reg);
if(!(reg & 0x02)) {
- sishw_ext.Is301BDH = TRUE;
- ivideo.vbflags |= VB_30xBDH;
+ ivideo->vbflags |= VB_30xBDH;
printk(KERN_INFO "%s SiS301B-DH %s\n", stdstr, bridgestr);
} else {
printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
}
} else if(reg < 0xd0) {
- ivideo.vbflags |= VB_301C;
- sishw_ext.ujVBChipID = VB_CHIP_301C;
+ ivideo->vbflags |= VB_301C;
printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
} else if(reg < 0xe0) {
- ivideo.vbflags |= VB_301LV;
- sishw_ext.ujVBChipID = VB_CHIP_301LV;
+ ivideo->vbflags |= VB_301LV;
printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
} else if(reg <= 0xe1) {
inSISIDXREG(SISPART4,0x39,reg);
if(reg == 0xff) {
- ivideo.vbflags |= VB_302LV;
- sishw_ext.ujVBChipID = VB_CHIP_302LV;
+ ivideo->vbflags |= VB_302LV;
printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
} else {
- ivideo.vbflags |= VB_302ELV;
- sishw_ext.ujVBChipID = VB_CHIP_302ELV;
+ ivideo->vbflags |= VB_301C;
+ printk(KERN_INFO "%s SiS301C(P4) %s\n", stdstr, bridgestr);
+#if 0
+ ivideo->vbflags |= VB_302ELV;
printk(KERN_INFO "%s SiS302ELV %s\n", stdstr, bridgestr);
+#endif
}
}
break;
- case 0x02:
- ivideo.hasVB = HASVB_302;
- inSISIDXREG(SISPART4, 0x01, reg);
- if(reg < 0xd0) {
- ivideo.vbflags |= VB_302B;
- sishw_ext.ujVBChipID = VB_CHIP_302B;
- inSISIDXREG(SISPART4,0x23,reg);
- if(!(reg & 0x02)) {
- sishw_ext.Is301BDH = TRUE;
- ivideo.vbflags |= VB_30xBDH;
- printk(KERN_INFO "%s SiS302B-DH %s\n", stdstr, bridgestr);
- } else {
- printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
- }
- } else if(reg < 0xe0) {
- ivideo.vbflags |= VB_301LV;
- sishw_ext.ujVBChipID = VB_CHIP_301LV;
- printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
- } else if(reg <= 0xe1) {
- ivideo.vbflags |= VB_302LV;
- sishw_ext.ujVBChipID = VB_CHIP_302LV;
- printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
- }
+ case 0x02:
+ ivideo->vbflags |= VB_302B;
+ printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
break;
}
- if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {
- inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+ if((!(ivideo->vbflags & VB_VIDEOBRIDGE)) && (ivideo->chip != SIS_300)) {
+ inSISIDXREG(SISCR, 0x37, reg);
reg &= SIS_EXTERNAL_CHIP_MASK;
reg >>= 1;
- if(sisvga_engine == SIS_300_VGA) {
- switch (reg) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+#ifdef CONFIG_FB_SIS_300
+ switch(reg) {
case SIS_EXTERNAL_CHIP_LVDS:
- ivideo.hasVB = HASVB_LVDS;
- ivideo.vbflags |= VB_LVDS;
- sishw_ext.usExternalChip = 0x01;
- printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
+ ivideo->vbflags |= VB_LVDS;
break;
case SIS_EXTERNAL_CHIP_TRUMPION:
- ivideo.hasVB = HASVB_TRUMPION;
- sishw_ext.usExternalChip = 0x02;
- printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
+ ivideo->vbflags |= VB_TRUMPION;
break;
case SIS_EXTERNAL_CHIP_CHRONTEL:
- ivideo.hasVB = HASVB_CHRONTEL;
- ivideo.vbflags |= VB_CHRONTEL;
- sishw_ext.usExternalChip = 0x04;
- printk(KERN_INFO "%s %s\n", stdstr, chrstr);
+ ivideo->vbflags |= VB_CHRONTEL;
break;
case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
- ivideo.hasVB = HASVB_LVDS_CHRONTEL;
- ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
- sishw_ext.usExternalChip = 0x05;
- printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+ ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
break;
}
- } else if(ivideo.chip < SIS_661) {
+ if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 1;
+#endif
+ } else if(ivideo->chip < SIS_661) {
+#ifdef CONFIG_FB_SIS_315
switch (reg) {
case SIS310_EXTERNAL_CHIP_LVDS:
- ivideo.hasVB = HASVB_LVDS;
- ivideo.vbflags |= VB_LVDS;
- sishw_ext.usExternalChip = 0x01;
- printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
+ ivideo->vbflags |= VB_LVDS;
break;
case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
- ivideo.hasVB = HASVB_LVDS_CHRONTEL;
- ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
- sishw_ext.usExternalChip = 0x05;
- printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+ ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
+ break;
+ }
+ if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+ } else if(ivideo->chip >= SIS_661) {
+#ifdef CONFIG_FB_SIS_315
+ inSISIDXREG(SISCR, 0x38, reg);
+ reg >>= 5;
+ switch(reg) {
+ case 0x02:
+ ivideo->vbflags |= VB_LVDS;
+ break;
+ case 0x03:
+ ivideo->vbflags |= (VB_LVDS | VB_CHRONTEL);
+ break;
+ case 0x04:
+ ivideo->vbflags |= (VB_LVDS | VB_CONEXANT);
break;
}
+ if(ivideo->vbflags & VB_CHRONTEL) ivideo->chronteltype = 2;
+#endif
+ }
+ if(ivideo->vbflags & VB_LVDS) {
+ printk(KERN_INFO "%s LVDS transmitter\n", stdstr);
+ }
+ if(ivideo->vbflags & VB_TRUMPION) {
+ printk(KERN_INFO "%s Trumpion Zurac LCD scaler\n", stdstr);
+ }
+ if(ivideo->vbflags & VB_CHRONTEL) {
+ printk(KERN_INFO "%s Chrontel TV encoder\n", stdstr);
+ }
+ if(ivideo->vbflags & VB_CONEXANT) {
+ printk(KERN_INFO "%s Conexant external device\n", stdstr);
}
-
}
- if(ivideo.vbflags & VB_SISBRIDGE) {
- SiS_Sense30x();
- } else if(ivideo.vbflags & VB_CHRONTEL) {
- SiS_SenseCh();
+ if(ivideo->vbflags & VB_SISBRIDGE) {
+ SiS_Sense30x(ivideo);
+ } else if(ivideo->vbflags & VB_CHRONTEL) {
+ SiS_SenseCh(ivideo);
}
-
}
/* ------------------ Sensing routines ------------------ */
-static BOOLEAN
-sisfb_test_DDC1(void)
+static BOOLEAN __devinit sisfb_test_DDC1(struct sis_video_info *ivideo)
{
unsigned short old;
int count = 48;
- old = SiS_ReadDDC1Bit(&SiS_Pr);
+ old = SiS_ReadDDC1Bit(&ivideo->SiS_Pr);
do {
- if(old != SiS_ReadDDC1Bit(&SiS_Pr)) break;
+ if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
} while(count--);
return (count == -1) ? FALSE : TRUE;
}
-static void
-sisfb_sense_crt1(void)
+static void __devinit sisfb_sense_crt1(struct sis_video_info *ivideo)
{
- unsigned char SR1F, CR63=0, CR17;
- unsigned short temp = 0xffff;
- int i;
BOOLEAN mustwait = FALSE;
+ u8 SR1F, CR17;
+#ifdef CONFIG_FB_SIS_315
+ u8 CR63=0;
+#endif
+ u16 temp = 0xffff;
+ int i;
inSISIDXREG(SISSR,0x1F,SR1F);
orSISIDXREG(SISSR,0x1F,0x04);
andSISIDXREG(SISSR,0x1F,0x3F);
if(SR1F & 0xc0) mustwait = TRUE;
- if(sisvga_engine == SIS_315_VGA) {
- inSISIDXREG(SISCR,SiS_Pr.SiS_MyCR63,CR63);
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ inSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,CR63);
CR63 &= 0x40;
- andSISIDXREG(SISCR,SiS_Pr.SiS_MyCR63,0xBF);
+ andSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF);
}
+#endif
inSISIDXREG(SISCR,0x17,CR17);
CR17 &= 0x80;
}
if(mustwait) {
- for(i=0; i < 10; i++) sisfbwaitretracecrt1();
+ for(i=0; i < 10; i++) sisfbwaitretracecrt1(ivideo);
}
- i = 3;
- do {
- temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, 0, 0, NULL);
- } while(((temp == 0) || (temp == 0xffff)) && i--);
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->chip >= SIS_330) {
+ andSISIDXREG(SISCR,0x32,~0x20);
+ if(ivideo->chip >= SIS_340) {
+ outSISIDXREG(SISCR, 0x57, 0x4a);
+ } else {
+ outSISIDXREG(SISCR, 0x57, 0x5f);
+ }
+ orSISIDXREG(SISCR, 0x53, 0x02);
+ while((inSISREG(SISINPSTAT)) & 0x01) break;
+ while(!((inSISREG(SISINPSTAT)) & 0x01)) break;
+ if((inSISREG(SISMISCW)) & 0x10) temp = 1;
+ andSISIDXREG(SISCR, 0x53, 0xfd);
+ andSISIDXREG(SISCR, 0x57, 0x00);
+ }
+#endif
+
+ if(temp == 0xffff) {
+ i = 3;
+ do {
+ temp = SiS_HandleDDC(&ivideo->SiS_Pr, ivideo->vbflags, ivideo->sisvga_engine, 0, 0, NULL);
+ } while(((temp == 0) || (temp == 0xffff)) && i--);
- if((temp == 0) || (temp == 0xffff)) {
- if(sisfb_test_DDC1()) temp = 1;
+ if((temp == 0) || (temp == 0xffff)) {
+ if(sisfb_test_DDC1(ivideo)) temp = 1;
+ }
}
if((temp) && (temp != 0xffff)) {
orSISIDXREG(SISCR,0x32,0x20);
}
- if(sisvga_engine == SIS_315_VGA) {
- setSISIDXREG(SISCR,SiS_Pr.SiS_MyCR63,0xBF,CR63);
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ setSISIDXREG(SISCR,ivideo->SiS_Pr.SiS_MyCR63,0xBF,CR63);
}
+#endif
setSISIDXREG(SISCR,0x17,0x7F,CR17);
}
/* Determine and detect attached devices on SiS30x */
-static int
-SISDoSense(int tempbl, int tempbh, int tempcl, int tempch)
+static int __devinit SISDoSense(struct sis_video_info *ivideo, u16 type, u16 test)
{
- int temp;
-
- outSISIDXREG(SISPART4,0x11,tempbl);
- temp = tempbh | tempcl;
- setSISIDXREG(SISPART4,0x10,0xe0,temp);
- SiS_DDC2Delay(&SiS_Pr, 0x1000);
- tempch &= 0x7f;
- inSISIDXREG(SISPART4,0x03,temp);
- temp ^= 0x0e;
- temp &= tempch;
- return((temp == tempch));
+ int temp, mytest, result, i, j;
+
+ for(j = 0; j < 10; j++) {
+ result = 0;
+ for(i = 0; i < 3; i++) {
+ mytest = test;
+ outSISIDXREG(SISPART4,0x11,(type & 0x00ff));
+ temp = (type >> 8) | (mytest & 0x00ff);
+ setSISIDXREG(SISPART4,0x10,0xe0,temp);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1500);
+ mytest >>= 8;
+ mytest &= 0x7f;
+ inSISIDXREG(SISPART4,0x03,temp);
+ temp ^= 0x0e;
+ temp &= mytest;
+ if(temp == mytest) result++;
+#if 1
+ outSISIDXREG(SISPART4,0x11,0x00);
+ andSISIDXREG(SISPART4,0x10,0xe0);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x1000);
+#endif
+ }
+ if((result == 0) || (result >= 2)) break;
+ }
+ return(result);
}
-static void
-SiS_Sense30x(void)
+static void __devinit SiS_Sense30x(struct sis_video_info *ivideo)
{
- u8 backupP4_0d,backupP2_00;
- u8 svhs_bl, svhs_bh;
- u8 svhs_cl, svhs_ch;
- u8 cvbs_bl, cvbs_bh;
- u8 cvbs_cl, cvbs_ch;
- u8 vga2_bl, vga2_bh;
- u8 vga2_cl, vga2_ch;
- int myflag, result, haveresult, i, j;
- char stdstr[] = "sisfb: Detected";
- char tvstr[] = "TV connected to";
-
- inSISIDXREG(SISPART4,0x0d,backupP4_0d);
- if(!(ivideo.vbflags & (VB_301C|VB_302ELV))) {
- outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
- }
-
- inSISIDXREG(SISPART2,0x00,backupP2_00);
- outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
-
- if(sisvga_engine == SIS_300_VGA) {
-
- if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)) {
- vga2_bh = 0x01; vga2_bl = 0x90;
- svhs_bh = 0x01; svhs_bl = 0x6b;
- cvbs_bh = 0x01; cvbs_bl = 0x74;
- } else {
- vga2_bh = 0x00; vga2_bl = 0xd1;
- svhs_bh = 0x00; svhs_bl = 0xb9;
- cvbs_bh = 0x00; cvbs_bl = 0xb3;
- }
- inSISIDXREG(SISPART4,0x01,myflag);
- if(myflag & 0x04) {
- vga2_bh = 0x00; vga2_bl = 0xfd;
- svhs_bh = 0x00; svhs_bl = 0xdd;
- cvbs_bh = 0x00; cvbs_bl = 0xee;
- }
- vga2_ch = 0x0e; vga2_cl = 0x08;
- svhs_ch = 0x04; svhs_cl = 0x04;
- cvbs_ch = 0x08; cvbs_cl = 0x04;
- if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
- vga2_bh = 0x00; vga2_bl = 0x00;
- vga2_ch = 0x00; vga2_cl = 0x00;
- }
- if(ivideo.chip == SIS_300) {
- inSISIDXREG(SISSR,0x3b,myflag);
- if(!(myflag & 0x01)) {
- vga2_bh = 0x00; vga2_bl = 0x00;
- vga2_ch = 0x00; vga2_cl = 0x00;
- }
- }
+ u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
+ u16 svhs=0, svhs_c=0;
+ u16 cvbs=0, cvbs_c=0;
+ u16 vga2=0, vga2_c=0;
+ int myflag, result;
+ char stdstr[] = "sisfb: Detected";
+ char tvstr[] = "TV connected to";
+
+ if(ivideo->vbflags & VB_301) {
+ svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
+ inSISIDXREG(SISPART4,0x01,myflag);
+ if(myflag & 0x04) {
+ svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
+ }
+ } else if(ivideo->vbflags & (VB_301B | VB_302B)) {
+ svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
+ } else if(ivideo->vbflags & (VB_301LV | VB_302LV)) {
+ svhs = 0x0200; cvbs = 0x0100;
+ } else if(ivideo->vbflags & (VB_301C | VB_302ELV)) {
+ svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
+ } else return;
+
+ vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
+ if(ivideo->vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
+ svhs_c = 0x0408; cvbs_c = 0x0808;
+ }
+ biosflag = 2;
- } else {
-
- if(ivideo.vbflags & (VB_301B|VB_302B)) {
- vga2_bh = 0x01; vga2_bl = 0x90;
- svhs_bh = 0x01; svhs_bl = 0x6b;
- cvbs_bh = 0x01; cvbs_bl = 0x74;
- } else if(ivideo.vbflags & (VB_301C|VB_302ELV)) {
- vga2_bh = 0x01; vga2_bl = 0x90;
- svhs_bh = 0x01; svhs_bl = 0x6b;
- cvbs_bh = 0x01; cvbs_bl = 0x10;
- } else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
- vga2_bh = 0x00; vga2_bl = 0x00;
- svhs_bh = 0x02; svhs_bl = 0x00;
- cvbs_bh = 0x01; cvbs_bl = 0x00;
- } else {
- vga2_bh = 0x00; vga2_bl = 0xd1;
- svhs_bh = 0x00; svhs_bl = 0xb9;
- cvbs_bh = 0x00; cvbs_bl = 0xb3;
- inSISIDXREG(SISPART4,0x01,myflag);
- if(myflag & 0x04) {
- vga2_bh = 0x00; vga2_bl = 0xfd;
- svhs_bh = 0x00; svhs_bl = 0xdd;
- cvbs_bh = 0x00; cvbs_bl = 0xee;
- }
- }
+ if(ivideo->chip == SIS_300) {
+ inSISIDXREG(SISSR,0x3b,myflag);
+ if(!(myflag & 0x01)) vga2 = vga2_c = 0;
+ }
- if(ivideo.vbflags & (VB_301LV|VB_302LV|VB_302ELV)) {
- vga2_bh = 0x00; vga2_bl = 0x00;
- vga2_ch = 0x00; vga2_cl = 0x00;
- svhs_ch = 0x04; svhs_cl = 0x08;
- cvbs_ch = 0x08; cvbs_cl = 0x08;
- } else {
- vga2_ch = 0x0e; vga2_cl = 0x08;
- svhs_ch = 0x04; svhs_cl = 0x04;
- cvbs_ch = 0x08; cvbs_cl = 0x04;
- }
- }
-
- if(vga2_ch || vga2_cl || vga2_bh || vga2_bl) {
- haveresult = 0;
- for(j = 0; j < 10; j++) {
- result = 0;
- for(i = 0; i < 3; i++) {
- if(SISDoSense(vga2_bl, vga2_bh, vga2_cl, vga2_ch))
- result++;
- }
- if((result == 0) || (result >= 2)) break;
- }
- if(result) {
- printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
- orSISIDXREG(SISCR, 0x32, 0x10);
- } else {
- andSISIDXREG(SISCR, 0x32, ~0x10);
+ inSISIDXREG(SISSR,0x1e,backupSR_1e);
+ orSISIDXREG(SISSR,0x1e,0x20);
+
+ inSISIDXREG(SISPART4,0x0d,backupP4_0d);
+ if(ivideo->vbflags & VB_301C) {
+ setSISIDXREG(SISPART4,0x0d,~0x07,0x01);
+ } else {
+ orSISIDXREG(SISPART4,0x0d,0x04);
+ }
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
+
+ inSISIDXREG(SISPART2,0x00,backupP2_00);
+ outSISIDXREG(SISPART2,0x00,((backupP2_00 | 0x1c) & 0xfc));
+
+ inSISIDXREG(SISPART2,0x4d,backupP2_4d);
+ if(ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV)) {
+ outSISIDXREG(SISPART2,0x4d,(backupP2_4d & ~0x10));
+ }
+
+ if(!(ivideo->vbflags & VB_301C)) {
+ SISDoSense(ivideo, 0, 0);
+ }
+
+ andSISIDXREG(SISCR, 0x32, ~0x14);
+
+ if(vga2_c || vga2) {
+ if(SISDoSense(ivideo, vga2, vga2_c)) {
+ if(biosflag & 0x01) {
+ printk(KERN_INFO "%s %s SCART output\n", stdstr, tvstr);
+ orSISIDXREG(SISCR, 0x32, 0x04);
+ } else {
+ printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
+ orSISIDXREG(SISCR, 0x32, 0x10);
+ }
}
}
- if(ivideo.vbflags & (VB_301C|VB_302ELV)) {
+ andSISIDXREG(SISCR, 0x32, 0x3f);
+
+ if(ivideo->vbflags & VB_301C) {
orSISIDXREG(SISPART4,0x0d,0x04);
}
- haveresult = 0;
- for(j = 0; j < 10; j++) {
- result = 0;
- for(i = 0; i < 3; i++) {
- if(SISDoSense(svhs_bl, svhs_bh, svhs_cl, svhs_ch))
- result++;
+ if((ivideo->sisvga_engine == SIS_315_VGA) &&
+ (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV|VB_302ELV))) {
+ outSISIDXREG(SISPART2,0x4d,(backupP2_4d | 0x10));
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x2000);
+ if((result = SISDoSense(ivideo, svhs, 0x0604))) {
+ if((result = SISDoSense(ivideo, cvbs, 0x0804))) {
+ printk(KERN_INFO "%s %s YPbPr component output\n", stdstr, tvstr);
+ orSISIDXREG(SISCR,0x32,0x80);
+ }
}
- if((result == 0) || (result >= 2)) break;
- }
- if(result) {
- printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
- ivideo.vbflags |= TV_SVIDEO;
- orSISIDXREG(SISCR, 0x32, 0x02);
- andSISIDXREG(SISCR, 0x32, ~0x05);
+ outSISIDXREG(SISPART2,0x4d,backupP2_4d);
}
- if(!result) {
+ andSISIDXREG(SISCR, 0x32, ~0x03);
- haveresult = 0;
- for(j = 0; j < 10; j++) {
- result = 0;
- for(i = 0; i < 3; i++) {
- if(SISDoSense(cvbs_bl, cvbs_bh, cvbs_cl, cvbs_ch))
- result++;
- }
- if((result == 0) || (result >= 2)) break;
- }
- if(result) {
- printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
- ivideo.vbflags |= TV_AVIDEO;
- orSISIDXREG(SISCR, 0x32, 0x01);
- andSISIDXREG(SISCR, 0x32, ~0x06);
- } else {
- andSISIDXREG(SISCR, 0x32, ~0x07);
- }
+ if(!(ivideo->vbflags & TV_YPBPR)) {
+ if((result = SISDoSense(ivideo, svhs, svhs_c))) {
+ printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
+ orSISIDXREG(SISCR, 0x32, 0x02);
+ }
+ if((biosflag & 0x02) || (!result)) {
+ if(SISDoSense(ivideo, cvbs, cvbs_c)) {
+ printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
+ orSISIDXREG(SISCR, 0x32, 0x01);
+ }
+ }
}
- SISDoSense(0, 0, 0, 0);
+
+ SISDoSense(ivideo, 0, 0);
outSISIDXREG(SISPART2,0x00,backupP2_00);
outSISIDXREG(SISPART4,0x0d,backupP4_0d);
+ outSISIDXREG(SISSR,0x1e,backupSR_1e);
+
+ if(ivideo->vbflags & VB_301C) {
+ inSISIDXREG(SISPART2,0x00,biosflag);
+ if(biosflag & 0x20) {
+ for(myflag = 2; myflag > 0; myflag--) {
+ biosflag ^= 0x20;
+ outSISIDXREG(SISPART2,0x00,biosflag);
+ }
+ }
+ }
+
+ outSISIDXREG(SISPART2,0x00,backupP2_00);
}
/* Determine and detect attached TV's on Chrontel */
-static void
-SiS_SenseCh(void)
+static void __devinit SiS_SenseCh(struct sis_video_info *ivideo)
{
-
- u8 temp1, temp2;
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
+ u8 temp1, temp2;
+ char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
+#endif
#ifdef CONFIG_FB_SIS_300
- unsigned char test[3];
- int i;
+ unsigned char test[3];
+ int i;
#endif
- char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
- if(ivideo.chip < SIS_315H) {
+ if(ivideo->chip < SIS_315H) {
#ifdef CONFIG_FB_SIS_300
- SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */
- SiS_SetChrontelGPIO(&SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */
- SiS_DDC2Delay(&SiS_Pr, 1000);
- temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
+ ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 1; /* Chrontel 700x */
+ SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x9c); /* Set general purpose IO for Chrontel communication */
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 1000);
+ temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
/* See Chrontel TB31 for explanation */
- temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+ temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
- SiS_SetCH700x(&SiS_Pr, 0x0b0e);
- SiS_DDC2Delay(&SiS_Pr, 300);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0b0e);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
}
- temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
+ temp2 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x25);
if(temp2 != temp1) temp1 = temp2;
if((temp1 >= 0x22) && (temp1 <= 0x50)) {
/* Read power status */
- temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+ temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0e);
if((temp1 & 0x03) != 0x03) {
/* Power all outputs */
- SiS_SetCH700x(&SiS_Pr, 0x0B0E);
- SiS_DDC2Delay(&SiS_Pr, 300);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0B0E);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 300);
}
/* Sense connected TV devices */
for(i = 0; i < 3; i++) {
- SiS_SetCH700x(&SiS_Pr, 0x0110);
- SiS_DDC2Delay(&SiS_Pr, 0x96);
- SiS_SetCH700x(&SiS_Pr, 0x0010);
- SiS_DDC2Delay(&SiS_Pr, 0x96);
- temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0110);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+ SiS_SetCH700x(&ivideo->SiS_Pr, 0x0010);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+ temp1 = SiS_GetCH700x(&ivideo->SiS_Pr, 0x10);
if(!(temp1 & 0x08)) test[i] = 0x02;
else if(!(temp1 & 0x02)) test[i] = 0x01;
else test[i] = 0;
- SiS_DDC2Delay(&SiS_Pr, 0x96);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
}
if(test[0] == test[1]) temp1 = test[0];
}
if(temp1 == 0x02) {
printk(KERN_INFO "%s SVIDEO output\n", stdstr);
- ivideo.vbflags |= TV_SVIDEO;
+ ivideo->vbflags |= TV_SVIDEO;
orSISIDXREG(SISCR, 0x32, 0x02);
andSISIDXREG(SISCR, 0x32, ~0x05);
} else if (temp1 == 0x01) {
printk(KERN_INFO "%s CVBS output\n", stdstr);
- ivideo.vbflags |= TV_AVIDEO;
+ ivideo->vbflags |= TV_AVIDEO;
orSISIDXREG(SISCR, 0x32, 0x01);
andSISIDXREG(SISCR, 0x32, ~0x06);
} else {
- SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
andSISIDXREG(SISCR, 0x32, ~0x07);
}
} else if(temp1 == 0) {
- SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, 0x010E,0xF8);
andSISIDXREG(SISCR, 0x32, ~0x07);
}
/* Set general purpose IO for Chrontel communication */
- SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
+ SiS_SetChrontelGPIO(&ivideo->SiS_Pr, 0x00);
#endif
- } else {
+ } else {
#ifdef CONFIG_FB_SIS_315
- SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
- temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
- SiS_SetCH701x(&SiS_Pr, 0x2049);
- SiS_DDC2Delay(&SiS_Pr, 0x96);
- temp2 = SiS_GetCH701x(&SiS_Pr, 0x20);
+ ivideo->SiS_Pr.SiS_IF_DEF_CH70xx = 2; /* Chrontel 7019 */
+ temp1 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x49);
+ SiS_SetCH701x(&ivideo->SiS_Pr, 0x2049);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+ temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
temp2 |= 0x01;
- SiS_SetCH701x(&SiS_Pr, (temp2 << 8) | 0x20);
- SiS_DDC2Delay(&SiS_Pr, 0x96);
+ SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
temp2 ^= 0x01;
- SiS_SetCH701x(&SiS_Pr, (temp2 << 8) | 0x20);
- SiS_DDC2Delay(&SiS_Pr, 0x96);
- temp2 = SiS_GetCH701x(&SiS_Pr, 0x20);
- SiS_SetCH701x(&SiS_Pr, (temp1 << 8) | 0x49);
+ SiS_SetCH701x(&ivideo->SiS_Pr, (temp2 << 8) | 0x20);
+ SiS_DDC2Delay(&ivideo->SiS_Pr, 0x96);
+ temp2 = SiS_GetCH701x(&ivideo->SiS_Pr, 0x20);
+ SiS_SetCH701x(&ivideo->SiS_Pr, (temp1 << 8) | 0x49);
temp1 = 0;
if(temp2 & 0x02) temp1 |= 0x01;
if(temp2 & 0x10) temp1 |= 0x01;
switch(temp1) {
case 0x01:
printk(KERN_INFO "%s CVBS output\n", stdstr);
- ivideo.vbflags |= TV_AVIDEO;
+ ivideo->vbflags |= TV_AVIDEO;
orSISIDXREG(SISCR, 0x32, 0x01);
andSISIDXREG(SISCR, 0x32, ~0x06);
break;
case 0x02:
printk(KERN_INFO "%s SVIDEO output\n", stdstr);
- ivideo.vbflags |= TV_SVIDEO;
+ ivideo->vbflags |= TV_SVIDEO;
orSISIDXREG(SISCR, 0x32, 0x02);
andSISIDXREG(SISCR, 0x32, ~0x05);
break;
andSISIDXREG(SISCR, 0x32, ~0x07);
}
#endif
-
- }
+ }
}
-
/* ------------------------ Heap routines -------------------------- */
-static int sisfb_heap_init(void)
+static u32 __devinit
+sisfb_getheapstart(struct sis_video_info *ivideo)
{
- SIS_OH *poh;
- u8 temp=0;
-#ifdef CONFIG_FB_SIS_315
- int agp_enabled = 1;
- u32 agp_size;
- unsigned long *cmdq_baseport = 0;
- unsigned long *read_port = 0;
- unsigned long *write_port = 0;
- SIS_CMDTYPE cmd_type;
-#ifndef AGPOFF
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- struct agp_kern_info *agp_info;
- struct agp_memory *agp;
-#else
- agp_kern_info *agp_info;
- agp_memory *agp;
-#endif
- u32 agp_phys;
-#endif
-#endif
-/* The heap start is either set manually using the "mem" parameter, or
- * defaults as follows:
- * -) If more than 16MB videoRAM available, let our heap start at 12MB.
- * -) If more than 8MB videoRAM available, let our heap start at 8MB.
- * -) If 4MB or less is available, let it start at 4MB.
- * This is for avoiding a clash with X driver which uses the beginning
- * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
- * in XF86Config-4.
- * The heap start can also be specified by parameter "mem" when starting the sisfb
- * driver. sisfb mem=1024 lets heap starts at 1MB, etc.
- *
- * On the 315 and Xabre series, the default is a 1MB heap since DRI is not
- * supported there.
- */
- if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
- if(sisvga_engine == SIS_300_VGA) {
- if (ivideo.video_size > 0x1000000) {
- ivideo.heapstart = 0xc00000;
- } else if (ivideo.video_size > 0x800000) {
- ivideo.heapstart = 0x800000;
+ u32 ret = ivideo->sisfb_parm_mem * 1024;
+ u32 max = ivideo->video_size - ivideo->hwcursor_size;
+ u32 def;
+
+ /* Calculate heap start = end of memory for console
+ *
+ * CCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDHHHHQQQQQQQQQQ
+ * C = console, D = heap, H = HWCursor, Q = cmd-queue
+ *
+ * Basically given by "mem" parameter
+ *
+ * maximum = videosize - cmd_queue - hwcursor
+ * (results in a heap of size 0)
+ * default = SiS 300: depends on videosize
+ * SiS 315/330: 32k below max
+ */
+
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ max -= TURBO_QUEUE_AREA_SIZE;
+ if(ivideo->video_size > 0x1000000) {
+ def = 0xc00000;
+ } else if(ivideo->video_size > 0x800000) {
+ def = 0x800000;
} else {
- ivideo.heapstart = 0x400000;
+ def = 0x400000;
}
} else {
- ivideo.heapstart = ivideo.video_size - 0x100000;
+ max -= COMMAND_QUEUE_AREA_SIZE;
+ def = max - 0x8000;
}
- } else {
- ivideo.heapstart = sisfb_mem * 1024;
- }
- sisfb_heap_start = (unsigned long) (ivideo.video_vbase + ivideo.heapstart);
- printk(KERN_INFO "sisfb: Memory heap starting at %dK\n",
- (int)(ivideo.heapstart / 1024));
- sisfb_heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
- sisfb_heap_size = sisfb_heap_end - sisfb_heap_start;
+ if((!ret) || (ret > max) || (ivideo->cardnumber != 0)) {
+ ret = def;
+ }
-#ifdef CONFIG_FB_SIS_315
- if (sisvga_engine == SIS_315_VGA) {
- /* Now initialize the 315/330 series' command queue mode.
- * On 315, there are three queue modes available which
- * are chosen by setting bits 7:5 in SR26:
- * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
- * track of the queue, the FIFO, command parsing and so
- * on. This is the one comparable to the 300 series.
- * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
- * have to do queue management himself. Register 0x85c4 will
- * hold the location of the next free queue slot, 0x85c8
- * is the "queue read pointer" whose way of working is
- * unknown to me. Anyway, this mode would require a
- * translation of the MMIO commands to some kind of
- * accelerator assembly and writing these commands
- * to the memory location pointed to by 0x85c4.
- * We will not use this, as nobody knows how this
- * "assembly" works, and as it would require a complete
- * re-write of the accelerator code.
- * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
- * queue in AGP memory space.
- *
- * SR26 bit 4 is called "Bypass H/W queue".
- * SR26 bit 1 is called "Enable Command Queue Auto Correction"
- * SR26 bit 0 resets the queue
- * Size of queue memory is encoded in bits 3:2 like this:
- * 00 (0x00) 512K
- * 01 (0x04) 1M
- * 10 (0x08) 2M
- * 11 (0x0C) 4M
- * The queue location is to be written to 0x85C0.
- *
- */
- cmdq_baseport = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_PHYBASE);
- write_port = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_WRITEPORT);
- read_port = (unsigned long *)(ivideo.mmio_vbase + MMIO_QUEUE_READPORT);
+ return ret;
+}
- DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
+static int __devinit
+sisfb_heap_init(struct sis_video_info *ivideo)
+{
+ SIS_OH *poh;
- agp_size = COMMAND_QUEUE_AREA_SIZE;
+ ivideo->heapstart = ivideo->sisfb_mem = sisfb_getheapstart(ivideo);
-#ifndef AGPOFF
- if (sisfb_queuemode == AGP_CMD_QUEUE) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- agp_info = vmalloc(sizeof(*agp_info));
- memset((void*)agp_info, 0x00, sizeof(*agp_info));
-#else
- agp_info = vmalloc(sizeof(agp_kern_info));
- memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
-#endif
- agp_copy_info(agp_info);
+ ivideo->sisfb_heap_start = ivideo->video_vbase + ivideo->heapstart;
+ ivideo->sisfb_heap_end = ivideo->video_vbase + ivideo->video_size;
- agp_backend_acquire();
+ /* Initialize command queue (We use MMIO only) */
- agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
- AGP_NORMAL_MEMORY);
- if (agp == NULL) {
- DPRINTK("sisfb: Allocating AGP buffer failed.\n");
- agp_enabled = 0;
- } else {
- if (agp_bind_memory(agp, agp->pg_start) != 0) {
- DPRINTK("sisfb: AGP: Failed to bind memory\n");
- /* TODO: Free AGP memory here */
- agp_enabled = 0;
- } else {
- agp_enable(0);
- }
- }
- }
-#else
- agp_enabled = 0;
-#endif
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ u32 tempq = 0;
+ u8 temp = 0;
- /* Now select the queue mode */
+ ivideo->sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
- if ((agp_enabled) && (sisfb_queuemode == AGP_CMD_QUEUE)) {
- cmd_type = AGP_CMD_QUEUE;
- printk(KERN_INFO "sisfb: Using AGP queue mode\n");
-/* } else if (sisfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
- } else if (sisfb_queuemode == VM_CMD_QUEUE) {
- cmd_type = VM_CMD_QUEUE;
- printk(KERN_INFO "sisfb: Using VRAM queue mode\n");
- } else {
- printk(KERN_INFO "sisfb: Using MMIO queue mode\n");
- cmd_type = MMIO_CMD;
- }
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
- switch (agp_size) {
- case 0x80000:
- temp = SIS_CMD_QUEUE_SIZE_512k;
- break;
- case 0x100000:
- temp = SIS_CMD_QUEUE_SIZE_1M;
- break;
- case 0x200000:
- temp = SIS_CMD_QUEUE_SIZE_2M;
- break;
- case 0x400000:
- temp = SIS_CMD_QUEUE_SIZE_4M;
- break;
- }
+ tempq = MMIO_IN32(ivideo->mmio_vbase, MMIO_QUEUE_READPORT);
+ MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_WRITEPORT, tempq);
- switch (cmd_type) {
- case AGP_CMD_QUEUE:
-#ifndef AGPOFF
- DPRINTK("sisfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
- agp_info->aper_base, agp->physical, agp_size/1024);
+ temp = SIS_CMD_QUEUE_SIZE_512k;
+ temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
+ outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
- agp_phys = agp_info->aper_base + agp->physical;
+ tempq = (u32)(ivideo->video_size - COMMAND_QUEUE_AREA_SIZE);
+ MMIO_OUT32(ivideo->mmio_vbase, MMIO_QUEUE_PHYBASE, tempq);
- outSISIDXREG(SISCR, IND_SIS_AGP_IO_PAD, 0);
- outSISIDXREG(SISCR, IND_SIS_AGP_IO_PAD, SIS_AGP_2X);
+ ivideo->caps |= MMIO_CMD_QUEUE_CAP;
+ }
+#endif
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ unsigned long tqueue_pos;
+ u8 tq_state;
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+ ivideo->sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
- *write_port = *read_port;
+ tqueue_pos = (ivideo->video_size - TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
- temp |= SIS_AGP_CMDQUEUE_ENABLE;
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+ inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
+ tq_state |= 0xf0;
+ tq_state &= 0xfc;
+ tq_state |= (u8)(tqueue_pos >> 8);
+ outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
- *cmdq_baseport = agp_phys;
+ outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, (u8)(tqueue_pos & 0xff));
- sisfb_caps |= AGP_CMD_QUEUE_CAP;
+ ivideo->caps |= TURBO_QUEUE_CAP;
+ }
#endif
- break;
- case VM_CMD_QUEUE:
- sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
- sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+ /* Reserve memory for the HWCursor */
+ ivideo->sisfb_heap_end -= ivideo->hwcursor_size;
+ ivideo->hwcursor_vbase = ivideo->sisfb_heap_end;
+ ivideo->caps |= HW_CURSOR_CAP;
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
+ ivideo->sisfb_heap_size = ivideo->sisfb_heap_end - ivideo->sisfb_heap_start;
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+ if(ivideo->cardnumber == 0) {
- *write_port = *read_port;
+ printk(KERN_INFO "sisfb: Memory heap starting at %dK, size %dK\n",
+ (int)(ivideo->heapstart / 1024), (int)(ivideo->sisfb_heap_size / 1024));
- temp |= SIS_VRAM_CMDQUEUE_ENABLE;
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+ sisfb_heap.vinfo = ivideo;
- *cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
+ sisfb_heap.poha_chain = NULL;
+ sisfb_heap.poh_freelist = NULL;
- sisfb_caps |= VM_CMD_QUEUE_CAP;
+ poh = sisfb_poh_new_node();
+ if(poh == NULL) return 1;
- DPRINTK("sisfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
- *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
- break;
+ poh->poh_next = &sisfb_heap.oh_free;
+ poh->poh_prev = &sisfb_heap.oh_free;
+ poh->size = ivideo->sisfb_heap_size;
+ poh->offset = ivideo->heapstart;
- default: /* MMIO */
- sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
- sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
+ sisfb_heap.oh_free.poh_next = poh;
+ sisfb_heap.oh_free.poh_prev = poh;
+ sisfb_heap.oh_free.size = 0;
+ sisfb_heap.max_freesize = poh->size;
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, SIS_CMD_QUEUE_RESET);
+ sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
+ sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
+ sisfb_heap.oh_used.size = SENTINEL;
- *write_port = *read_port;
+ } else {
- /* Set Auto_Correction bit */
- temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
- outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
+ printk(KERN_INFO "Skipped heap initialization for secondary cards\n");
- *cmdq_baseport = ivideo.video_size - COMMAND_QUEUE_AREA_SIZE;
+ }
- sisfb_caps |= MMIO_CMD_QUEUE_CAP;
+ return 0;
+}
- DPRINTK("sisfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
- *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
- break;
- }
- } /* sisvga_engine = 315 */
-#endif
-
-#ifdef CONFIG_FB_SIS_300
- if (sisvga_engine == SIS_300_VGA) {
- /* Now initialize TurboQueue. TB is always located at the very
- * top of the video RAM. */
- if (sisfb_heap_size >= TURBO_QUEUE_AREA_SIZE) {
- unsigned int tqueue_pos;
- u8 tq_state;
-
- tqueue_pos = (ivideo.video_size -
- TURBO_QUEUE_AREA_SIZE) / (64 * 1024);
-
- temp = (u8) (tqueue_pos & 0xff);
-
- inSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
- tq_state |= 0xf0;
- tq_state &= 0xfc;
- tq_state |= (u8) (tqueue_pos >> 8);
- outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_SET, tq_state);
-
- outSISIDXREG(SISSR, IND_SIS_TURBOQUEUE_ADR, temp);
-
- sisfb_caps |= TURBO_QUEUE_CAP;
-
- sisfb_heap_end -= TURBO_QUEUE_AREA_SIZE;
- sisfb_heap_size -= TURBO_QUEUE_AREA_SIZE;
- DPRINTK("sisfb: TurboQueue start at 0x%lx, size is %dK\n",
- sisfb_heap_end, TURBO_QUEUE_AREA_SIZE/1024);
- }
- }
-#endif
- /* Now reserve memory for the HWCursor. It is always located at the very
- top of the videoRAM, right below the TB memory area (if used). */
- if (sisfb_heap_size >= sisfb_hwcursor_size) {
- sisfb_heap_end -= sisfb_hwcursor_size;
- sisfb_heap_size -= sisfb_hwcursor_size;
- sisfb_hwcursor_vbase = sisfb_heap_end;
-
- sisfb_caps |= HW_CURSOR_CAP;
-
- DPRINTK("sisfb: Hardware Cursor start at 0x%lx, size is %dK\n",
- sisfb_heap_end, sisfb_hwcursor_size/1024);
- }
-
- sisfb_heap.poha_chain = NULL;
- sisfb_heap.poh_freelist = NULL;
-
- poh = sisfb_poh_new_node();
-
- if(poh == NULL) return 1;
-
- poh->poh_next = &sisfb_heap.oh_free;
- poh->poh_prev = &sisfb_heap.oh_free;
- poh->size = sisfb_heap_end - sisfb_heap_start + 1;
- poh->offset = sisfb_heap_start - (unsigned long) ivideo.video_vbase;
-
- DPRINTK("sisfb: Heap start:0x%p, end:0x%p, len=%dk\n",
- (char *) sisfb_heap_start, (char *) sisfb_heap_end,
- (unsigned int) poh->size / 1024);
-
- DPRINTK("sisfb: First Node offset:0x%x, size:%dk\n",
- (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
-
- sisfb_heap.oh_free.poh_next = poh;
- sisfb_heap.oh_free.poh_prev = poh;
- sisfb_heap.oh_free.size = 0;
- sisfb_heap.max_freesize = poh->size;
-
- sisfb_heap.oh_used.poh_next = &sisfb_heap.oh_used;
- sisfb_heap.oh_used.poh_prev = &sisfb_heap.oh_used;
- sisfb_heap.oh_used.size = SENTINEL;
-
- return 0;
-}
-
-static SIS_OH *sisfb_poh_new_node(void)
+static SIS_OH *
+sisfb_poh_new_node(void)
{
int i;
unsigned long cOhs;
SIS_OHALLOC *poha;
SIS_OH *poh;
- if (sisfb_heap.poh_freelist == NULL) {
- poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
+ if(sisfb_heap.poh_freelist == NULL) {
+ poha = kmalloc(SIS_OH_ALLOC_SIZE, GFP_KERNEL);
if(!poha) return NULL;
poha->poha_next = sisfb_heap.poha_chain;
sisfb_heap.poha_chain = poha;
- cOhs = (OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
+ cOhs = (SIS_OH_ALLOC_SIZE - sizeof(SIS_OHALLOC)) / sizeof(SIS_OH) + 1;
poh = &poha->aoh[0];
- for (i = cOhs - 1; i != 0; i--) {
+ for(i = cOhs - 1; i != 0; i--) {
poh->poh_next = poh + 1;
poh = poh + 1;
}
return (poh);
}
-static SIS_OH *sisfb_poh_allocate(unsigned long size)
+static SIS_OH *
+sisfb_poh_allocate(u32 size)
{
SIS_OH *pohThis;
SIS_OH *pohRoot;
int bAllocated = 0;
- if (size > sisfb_heap.max_freesize) {
- DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+ if(size > sisfb_heap.max_freesize) {
+ DPRINTK("sisfb: Can't allocate %dk video memory\n",
(unsigned int) size / 1024);
return (NULL);
}
pohThis = sisfb_heap.oh_free.poh_next;
- while (pohThis != &sisfb_heap.oh_free) {
+ while(pohThis != &sisfb_heap.oh_free) {
if (size <= pohThis->size) {
bAllocated = 1;
break;
pohThis = pohThis->poh_next;
}
- if (!bAllocated) {
- DPRINTK("sisfb: Can't allocate %dk size on offscreen\n",
+ if(!bAllocated) {
+ DPRINTK("sisfb: Can't allocate %dk video memory\n",
(unsigned int) size / 1024);
return (NULL);
}
- if (size == pohThis->size) {
+ if(size == pohThis->size) {
pohRoot = pohThis;
sisfb_delete_node(pohThis);
} else {
pohRoot = sisfb_poh_new_node();
- if (pohRoot == NULL) {
+ if(pohRoot == NULL) {
return (NULL);
}
return (pohRoot);
}
-static void sisfb_delete_node(SIS_OH *poh)
+static void
+sisfb_delete_node(SIS_OH *poh)
{
SIS_OH *poh_prev;
SIS_OH *poh_next;
poh_prev->poh_next = poh_next;
poh_next->poh_prev = poh_prev;
-
}
-static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
+static void
+sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh)
{
SIS_OH *pohTemp;
poh->poh_next = pohTemp;
}
-static SIS_OH *sisfb_poh_free(unsigned long base)
+static SIS_OH *
+sisfb_poh_free(u32 base)
{
SIS_OH *pohThis;
SIS_OH *poh_freed;
SIS_OH *poh_prev;
SIS_OH *poh_next;
- unsigned long ulUpper;
- unsigned long ulLower;
- int foundNode = 0;
+ u32 ulUpper;
+ u32 ulLower;
+ int foundNode = 0;
poh_freed = sisfb_heap.oh_used.poh_next;
poh_freed = poh_freed->poh_next;
}
- if (!foundNode) return (NULL);
+ if(!foundNode) return(NULL);
sisfb_heap.max_freesize += poh_freed->size;
pohThis = sisfb_heap.oh_free.poh_next;
- while (pohThis != &sisfb_heap.oh_free) {
- if (pohThis->offset == ulUpper) {
+ while(pohThis != &sisfb_heap.oh_free) {
+ if(pohThis->offset == ulUpper) {
poh_next = pohThis;
- }
- else if ((pohThis->offset + pohThis->size) ==
- ulLower) {
+ } else if((pohThis->offset + pohThis->size) == ulLower) {
poh_prev = pohThis;
}
pohThis = pohThis->poh_next;
sisfb_delete_node(poh_freed);
- if (poh_prev && poh_next) {
+ if(poh_prev && poh_next) {
poh_prev->size += (poh_freed->size + poh_next->size);
sisfb_delete_node(poh_next);
sisfb_free_node(poh_freed);
sisfb_free_node(poh_next);
- return (poh_prev);
+ return(poh_prev);
}
- if (poh_prev) {
+ if(poh_prev) {
poh_prev->size += poh_freed->size;
sisfb_free_node(poh_freed);
- return (poh_prev);
+ return(poh_prev);
}
- if (poh_next) {
+ if(poh_next) {
poh_next->size += poh_freed->size;
poh_next->offset = poh_freed->offset;
sisfb_free_node(poh_freed);
- return (poh_next);
+ return(poh_next);
}
sisfb_insert_node(&sisfb_heap.oh_free, poh_freed);
- return (poh_freed);
+ return(poh_freed);
}
-static void sisfb_free_node(SIS_OH *poh)
+static void
+sisfb_free_node(SIS_OH *poh)
{
if(poh == NULL) return;
poh->poh_next = sisfb_heap.poh_freelist;
sisfb_heap.poh_freelist = poh;
-
}
-void sis_malloc(struct sis_memreq *req)
+void
+sis_malloc(struct sis_memreq *req)
{
- SIS_OH *poh;
+ struct sis_video_info *ivideo = sisfb_heap.vinfo;
+ SIS_OH *poh = NULL;
- poh = sisfb_poh_allocate(req->size);
+ if((ivideo) && (!ivideo->havenoheap)) {
+ poh = sisfb_poh_allocate((u32)req->size);
+ }
if(poh == NULL) {
- req->offset = 0;
- req->size = 0;
- DPRINTK("sisfb: Video RAM allocation failed\n");
+ req->offset = req->size = 0;
+ DPRINTK("sisfb: Video RAM allocation failed\n");
} else {
- DPRINTK("sisfb: Video RAM allocation succeeded: 0x%p\n",
- (char *) (poh->offset + (unsigned long) ivideo.video_vbase));
-
- req->offset = poh->offset;
- req->size = poh->size;
+ req->offset = poh->offset;
+ req->size = poh->size;
+ DPRINTK("sisfb: Video RAM allocation succeeded: 0x%lx\n",
+ (poh->offset + ivideo->video_vbase));
}
}
-void sis_free(unsigned long base)
+/* sis_free: u32 because "base" is offset inside video ram, can never be >4GB */
+
+void
+sis_free(u32 base)
{
+ struct sis_video_info *ivideo = sisfb_heap.vinfo;
SIS_OH *poh;
- poh = sisfb_poh_free(base);
+ if((!ivideo) || (ivideo->havenoheap)) return;
+
+ poh = sisfb_poh_free((u32)base);
if(poh == NULL) {
DPRINTK("sisfb: sisfb_poh_free() failed at base 0x%x\n",
/* --------------------- SetMode routines ------------------------- */
-static void sisfb_pre_setmode(void)
+static void
+sisfb_pre_setmode(struct sis_video_info *ivideo)
{
- u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0;
+ u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
+ int tvregnum = 0;
- ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
+ ivideo->currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
inSISIDXREG(SISCR, 0x31, cr31);
cr31 &= ~0x60;
cr31 |= 0x04;
- cr33 = sisfb_rate_idx & 0x0F;
+ cr33 = ivideo->rate_idx & 0x0F;
+
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if(ivideo->chip >= SIS_661) {
+ inSISIDXREG(SISCR, 0x38, cr38);
+ cr38 &= ~0x07; /* Clear LCDA/DualEdge and YPbPr bits */
+ } else {
+ tvregnum = 0x38;
+ inSISIDXREG(SISCR, tvregnum, cr38);
+ cr38 &= ~0x3b; /* Clear LCDA/DualEdge and YPbPr bits */
+ }
+ }
+#endif
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ tvregnum = 0x35;
+ inSISIDXREG(SISCR, tvregnum, cr38);
+ }
+#endif
+
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
- SiS_SetEnableDstn(&SiS_Pr, FALSE);
- SiS_SetEnableFstn(&SiS_Pr, FALSE);
+ switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
- switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
case CRT2_TV:
- ivideo.disp_state = DISPTYPE_TV;
- if (ivideo.vbflags & TV_SVIDEO) {
- cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
- ivideo.currentvbflags |= TV_SVIDEO;
- ivideo.TV_plug = TVPLUG_SVIDEO;
- } else if (ivideo.vbflags & TV_AVIDEO) {
- cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
- ivideo.currentvbflags |= TV_AVIDEO;
- ivideo.TV_plug = TVPLUG_COMPOSITE;
- } else if (ivideo.vbflags & TV_SCART) {
- cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
- ivideo.currentvbflags |= TV_SCART;
- ivideo.TV_plug = TVPLUG_SCART;
- }
- cr31 |= SIS_DRIVER_MODE;
-
- if(!(ivideo.vbflags & TV_HIVISION)) {
- if (ivideo.vbflags & TV_PAL) {
- cr31 |= 0x01;
- cr35 |= 0x01;
- ivideo.currentvbflags |= TV_PAL;
- ivideo.TV_type = TVMODE_PAL;
- } else {
- cr31 &= ~0x01;
- cr35 &= ~0x01;
- ivideo.currentvbflags |= TV_NTSC;
- ivideo.TV_type = TVMODE_NTSC;
- }
- }
- break;
+ cr38 &= ~0xc0; /* Clear PAL-M / PAL-N bits */
+ if((ivideo->vbflags & TV_YPBPR) && (ivideo->vbflags & (VB_301C|VB_301LV|VB_302LV))) {
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->chip >= SIS_661) {
+ cr38 |= 0x04;
+ if(ivideo->vbflags & TV_YPBPR525P) cr35 |= 0x20;
+ else if(ivideo->vbflags & TV_YPBPR750P) cr35 |= 0x40;
+ else if(ivideo->vbflags & TV_YPBPR1080I) cr35 |= 0x60;
+ cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
+ cr35 &= ~0x01;
+ ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
+ } else if(ivideo->sisvga_engine == SIS_315_VGA) {
+ cr30 |= (0x80 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr38 |= 0x08;
+ if(ivideo->vbflags & TV_YPBPR525P) cr38 |= 0x10;
+ else if(ivideo->vbflags & TV_YPBPR750P) cr38 |= 0x20;
+ else if(ivideo->vbflags & TV_YPBPR1080I) cr38 |= 0x30;
+ cr31 &= ~0x01;
+ ivideo->currentvbflags |= (TV_YPBPR | (ivideo->vbflags & TV_YPBPRALL));
+ }
+#endif
+ } else if((ivideo->vbflags & TV_HIVISION) && (ivideo->vbflags & (VB_301|VB_301B|VB_302B))) {
+ if(ivideo->chip >= SIS_661) {
+ cr38 |= 0x04;
+ cr35 |= 0x60;
+ } else {
+ cr30 |= 0x80;
+ }
+ cr30 |= SIS_SIMULTANEOUS_VIEW_ENABLE;
+ cr31 |= 0x01;
+ cr35 |= 0x01;
+ ivideo->currentvbflags |= TV_HIVISION;
+ } else if(ivideo->vbflags & TV_SCART) {
+ cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr31 |= 0x01;
+ cr35 |= 0x01;
+ ivideo->currentvbflags |= TV_SCART;
+ } else {
+ if(ivideo->vbflags & TV_SVIDEO) {
+ cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ ivideo->currentvbflags |= TV_SVIDEO;
+ }
+ if(ivideo->vbflags & TV_AVIDEO) {
+ cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ ivideo->currentvbflags |= TV_AVIDEO;
+ }
+ }
+ cr31 |= SIS_DRIVER_MODE;
+
+ if(ivideo->vbflags & (TV_AVIDEO|TV_SVIDEO)) {
+ if(ivideo->vbflags & TV_PAL) {
+ cr31 |= 0x01; cr35 |= 0x01;
+ ivideo->currentvbflags |= TV_PAL;
+ if(ivideo->vbflags & TV_PALM) {
+ cr38 |= 0x40; cr35 |= 0x04;
+ ivideo->currentvbflags |= TV_PALM;
+ } else if(ivideo->vbflags & TV_PALN) {
+ cr38 |= 0x80; cr35 |= 0x08;
+ ivideo->currentvbflags |= TV_PALN;
+ }
+ } else {
+ cr31 &= ~0x01; cr35 &= ~0x01;
+ ivideo->currentvbflags |= TV_NTSC;
+ if(ivideo->vbflags & TV_NTSCJ) {
+ cr38 |= 0x40; cr35 |= 0x02;
+ ivideo->currentvbflags |= TV_NTSCJ;
+ }
+ }
+ }
+ break;
+
case CRT2_LCD:
- ivideo.disp_state = DISPTYPE_LCD;
- cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
- cr31 |= SIS_DRIVER_MODE;
- SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
- SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
- break;
+ cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr31 |= SIS_DRIVER_MODE;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, ivideo->sisfb_dstn);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, ivideo->sisfb_fstn);
+ break;
+
case CRT2_VGA:
- ivideo.disp_state = DISPTYPE_CRT2;
- cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
- cr31 |= SIS_DRIVER_MODE;
- if(sisfb_nocrt2rate) {
- cr33 |= (sisbios_mode[sisfb_mode_idx].rate_idx << 4);
- } else {
- cr33 |= ((sisfb_rate_idx & 0x0F) << 4);
- }
- break;
+ cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+ cr31 |= SIS_DRIVER_MODE;
+ if(ivideo->sisfb_nocrt2rate) {
+ cr33 |= (sisbios_mode[ivideo->sisfb_mode_idx].rate_idx << 4);
+ } else {
+ cr33 |= ((ivideo->rate_idx & 0x0F) << 4);
+ }
+ break;
+
default: /* disable CRT2 */
- cr30 = 0x00;
- cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
+ cr30 = 0x00;
+ cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
}
- if(ivideo.chip >= SIS_661) {
- cr31 &= ~0x01;
- /* Leave overscan bit alone */
- setSISIDXREG(SISCR, 0x35, ~0x10, cr35);
- }
- outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
- outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
- outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
+ outSISIDXREG(SISCR, 0x30, cr30);
+ outSISIDXREG(SISCR, 0x33, cr33);
+ if(ivideo->chip >= SIS_661) {
#ifdef CONFIG_FB_SIS_315
- if(sisvga_engine == SIS_315_VGA) {
- /* Clear LCDA and PAL-N/M bits */
- andSISIDXREG(SISCR,0x38,~0x03);
- if(ivideo.chip < SIS_661) {
- andSISIDXREG(SISCR,0x38,~0xc0);
- }
+ cr31 &= ~0x01; /* Clear PAL flag (now in CR35) */
+ setSISIDXREG(SISCR, 0x35, ~0x10, cr35); /* Leave overscan bit alone */
+ cr38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */
+ setSISIDXREG(SISCR, 0x38, 0xf8, cr38);
+#endif
+ } else if(ivideo->chip != SIS_300) {
+ outSISIDXREG(SISCR, tvregnum, cr38);
}
+ outSISIDXREG(SISCR, 0x31, cr31);
+
+ if(ivideo->accel) sisfb_syncaccel(ivideo);
+
+ ivideo->SiS_Pr.SiS_UseOEM = ivideo->sisfb_useoem;
+}
+
+/* Fix SR11 for 661 and later */
+#ifdef CONFIG_FB_SIS_315
+static void
+sisfb_fixup_SR11(struct sis_video_info *ivideo)
+{
+ u8 tmpreg;
+
+ if(ivideo->chip >= SIS_661) {
+ inSISIDXREG(SISSR,0x11,tmpreg);
+ if(tmpreg & 0x20) {
+ inSISIDXREG(SISSR,0x3e,tmpreg);
+ tmpreg = (tmpreg + 1) & 0xff;
+ outSISIDXREG(SISSR,0x3e,tmpreg);
+ inSISIDXREG(SISSR,0x11,tmpreg);
+ }
+ if(tmpreg & 0xf0) {
+ andSISIDXREG(SISSR,0x11,0x0f);
+ }
+ }
+}
#endif
- if(ivideo.accel) sisfb_syncaccel();
+static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val)
+{
+ if(val > 32) val = 32;
+ if(val < -32) val = -32;
+ ivideo->tvxpos = val;
+
+ if(ivideo->sisfblocked) return;
+ if(!ivideo->modechanged) return;
+
+ if(ivideo->currentvbflags & CRT2_TV) {
+
+ if(ivideo->vbflags & VB_CHRONTEL) {
+
+ int x = ivideo->tvx;
+
+ switch(ivideo->chronteltype) {
+ case 1:
+ x += val;
+ if(x < 0) x = 0;
+ outSISIDXREG(SISSR,0x05,0x86);
+ SiS_SetCH700x(&ivideo->SiS_Pr, (((x & 0xff) << 8) | 0x0a));
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, (((x & 0x0100) << 1) | 0x08),0xFD);
+ break;
+ case 2:
+ /* Not supported by hardware */
+ break;
+ }
- SiS_Pr.SiS_UseOEM = sisfb_useoem;
+ } else if(ivideo->vbflags & VB_SISBRIDGE) {
+
+ u8 p2_1f,p2_20,p2_2b,p2_42,p2_43;
+ unsigned short temp;
+
+ p2_1f = ivideo->p2_1f;
+ p2_20 = ivideo->p2_20;
+ p2_2b = ivideo->p2_2b;
+ p2_42 = ivideo->p2_42;
+ p2_43 = ivideo->p2_43;
+
+ temp = p2_1f | ((p2_20 & 0xf0) << 4);
+ temp += (val * 2);
+ p2_1f = temp & 0xff;
+ p2_20 = (temp & 0xf00) >> 4;
+ p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
+ temp = p2_43 | ((p2_42 & 0xf0) << 4);
+ temp += (val * 2);
+ p2_43 = temp & 0xff;
+ p2_42 = (temp & 0xf00) >> 4;
+ outSISIDXREG(SISPART2,0x1f,p2_1f);
+ setSISIDXREG(SISPART2,0x20,0x0F,p2_20);
+ setSISIDXREG(SISPART2,0x2b,0xF0,p2_2b);
+ setSISIDXREG(SISPART2,0x42,0x0F,p2_42);
+ outSISIDXREG(SISPART2,0x43,p2_43);
+ }
+ }
}
-static void sisfb_post_setmode(void)
+static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
+{
+ if(val > 32) val = 32;
+ if(val < -32) val = -32;
+ ivideo->tvypos = val;
+
+ if(ivideo->sisfblocked) return;
+ if(!ivideo->modechanged) return;
+
+ if(ivideo->currentvbflags & CRT2_TV) {
+
+ if(ivideo->vbflags & VB_CHRONTEL) {
+
+ int y = ivideo->tvy;
+
+ switch(ivideo->chronteltype) {
+ case 1:
+ y -= val;
+ if(y < 0) y = 0;
+ outSISIDXREG(SISSR,0x05,0x86);
+ SiS_SetCH700x(&ivideo->SiS_Pr, (((y & 0xff) << 8) | 0x0b));
+ SiS_SetCH70xxANDOR(&ivideo->SiS_Pr, ((y & 0x0100) | 0x08),0xFE);
+ break;
+ case 2:
+ /* Not supported by hardware */
+ break;
+ }
+
+ } else if(ivideo->vbflags & VB_SISBRIDGE) {
+
+ char p2_01, p2_02;
+ val /= 2;
+ p2_01 = ivideo->p2_01;
+ p2_02 = ivideo->p2_02;
+
+ p2_01 += val;
+ p2_02 += val;
+ while((p2_01 <= 0) || (p2_02 <= 0)) {
+ p2_01 += 2;
+ p2_02 += 2;
+ }
+ outSISIDXREG(SISPART2,0x01,p2_01);
+ outSISIDXREG(SISPART2,0x02,p2_02);
+ }
+ }
+}
+
+static void
+sisfb_post_setmode(struct sis_video_info *ivideo)
{
- u8 reg;
BOOLEAN crt1isoff = FALSE;
+ BOOLEAN doit = TRUE;
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
+ u8 reg;
+#endif
#ifdef CONFIG_FB_SIS_315
u8 reg1;
#endif
-#ifdef CONFIG_FB_SIS_300
- BOOLEAN doit = TRUE;
-#endif
- /* We can't switch off CRT1 if bridge is in slave mode */
- if(ivideo.vbflags & VB_VIDEOBRIDGE) {
-#ifdef CONFIG_FB_SIS_300
- if(sisvga_engine == SIS_300_VGA) {
- inSISIDXREG(SISPART1, 0x00, reg);
- if((reg & 0xa0) == 0x20) {
- doit = FALSE;
- }
- }
+
+ outSISIDXREG(SISSR,0x05,0x86);
+
+#ifdef CONFIG_FB_SIS_315
+ sisfb_fixup_SR11(ivideo);
#endif
- } else sisfb_crt1off = 0;
- if(sisvga_engine == SIS_300_VGA) {
+ /* Now we actually HAVE changed the display mode */
+ ivideo->modechanged = 1;
+
+ /* We can't switch off CRT1 if bridge is in slave mode */
+ if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+ if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
+ } else ivideo->sisfb_crt1off = 0;
#ifdef CONFIG_FB_SIS_300
- if((sisfb_crt1off) && (doit)) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if((ivideo->sisfb_crt1off) && (doit)) {
crt1isoff = TRUE;
reg = 0x00;
} else {
reg = 0x80;
}
setSISIDXREG(SISCR, 0x17, 0x7f, reg);
+ }
#endif
-
- } else {
-
#ifdef CONFIG_FB_SIS_315
- if(sisfb_crt1off) {
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if((ivideo->sisfb_crt1off) && (doit)) {
crt1isoff = TRUE;
reg = 0x40;
reg1 = 0xc0;
reg1 = 0x00;
}
- setSISIDXREG(SISCR, SiS_Pr.SiS_MyCR63, ~0x40, reg);
+ setSISIDXREG(SISCR, ivideo->SiS_Pr.SiS_MyCR63, ~0x40, reg);
setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
-#endif
-
}
+#endif
if(crt1isoff) {
- ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
- ivideo.currentvbflags |= VB_SINGLE_MODE;
- ivideo.disp_state |= DISPMODE_SINGLE;
+ ivideo->currentvbflags &= ~VB_DISPTYPE_CRT1;
+ ivideo->currentvbflags |= VB_SINGLE_MODE;
} else {
- ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
- ivideo.disp_state |= DISPTYPE_CRT1;
- if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
- ivideo.currentvbflags |= VB_MIRROR_MODE;
- ivideo.disp_state |= DISPMODE_MIRROR;
+ ivideo->currentvbflags |= VB_DISPTYPE_CRT1;
+ if(ivideo->currentvbflags & VB_DISPTYPE_CRT2) {
+ ivideo->currentvbflags |= VB_MIRROR_MODE;
} else {
- ivideo.currentvbflags |= VB_SINGLE_MODE;
- ivideo.disp_state |= DISPMODE_SINGLE;
+ ivideo->currentvbflags |= VB_SINGLE_MODE;
}
}
andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
- if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) { /* Set filter for SiS301 */
+ if(ivideo->currentvbflags & CRT2_TV) {
+ if(ivideo->vbflags & VB_SISBRIDGE) {
+ inSISIDXREG(SISPART2,0x1f,ivideo->p2_1f);
+ inSISIDXREG(SISPART2,0x20,ivideo->p2_20);
+ inSISIDXREG(SISPART2,0x2b,ivideo->p2_2b);
+ inSISIDXREG(SISPART2,0x42,ivideo->p2_42);
+ inSISIDXREG(SISPART2,0x43,ivideo->p2_43);
+ inSISIDXREG(SISPART2,0x01,ivideo->p2_01);
+ inSISIDXREG(SISPART2,0x02,ivideo->p2_02);
+ } else if(ivideo->vbflags & VB_CHRONTEL) {
+ if(ivideo->chronteltype == 1) {
+ ivideo->tvx = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0a);
+ ivideo->tvx |= (((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x02) >> 1) << 8);
+ ivideo->tvy = SiS_GetCH700x(&ivideo->SiS_Pr, 0x0b);
+ ivideo->tvy |= ((SiS_GetCH700x(&ivideo->SiS_Pr, 0x08) & 0x01) << 8);
+ }
+ }
+ }
+
+ if(ivideo->tvxpos) {
+ sisfb_set_TVxposoffset(ivideo, ivideo->tvxpos);
+ }
+ if(ivideo->tvypos) {
+ sisfb_set_TVyposoffset(ivideo, ivideo->tvypos);
+ }
+
+ if((ivideo->currentvbflags & CRT2_TV) && (ivideo->vbflags & VB_301)) { /* Set filter for SiS301 */
+
+ unsigned char filter_tb = 0;
- switch (ivideo.video_width) {
+ switch (ivideo->video_width) {
case 320:
- filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
+ filter_tb = (ivideo->vbflags & TV_NTSC) ? 4 : 12;
break;
case 640:
- filter_tb = (ivideo.vbflags & TV_NTSC) ? 5 : 13;
+ filter_tb = (ivideo->vbflags & TV_NTSC) ? 5 : 13;
break;
case 720:
- filter_tb = (ivideo.vbflags & TV_NTSC) ? 6 : 14;
+ filter_tb = (ivideo->vbflags & TV_NTSC) ? 6 : 14;
break;
case 400:
case 800:
- filter_tb = (ivideo.vbflags & TV_NTSC) ? 7 : 15;
+ filter_tb = (ivideo->vbflags & TV_NTSC) ? 7 : 15;
break;
default:
- filter = -1;
+ ivideo->sisfb_filter = -1;
break;
}
- orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
+ orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);
- if(ivideo.vbflags & TV_NTSC) {
+ if(ivideo->vbflags & TV_NTSC) {
andSISIDXREG(SISPART2, 0x3a, 0x1f);
- if (ivideo.vbflags & TV_SVIDEO) {
+ if (ivideo->vbflags & TV_SVIDEO) {
andSISIDXREG(SISPART2, 0x30, 0xdf);
- } else if (ivideo.vbflags & TV_AVIDEO) {
+ } else if (ivideo->vbflags & TV_AVIDEO) {
orSISIDXREG(SISPART2, 0x30, 0x20);
- switch (ivideo.video_width) {
+ switch (ivideo->video_width) {
case 640:
outSISIDXREG(SISPART2, 0x35, 0xEB);
outSISIDXREG(SISPART2, 0x36, 0x04);
}
}
- } else if(ivideo.vbflags & TV_PAL) {
+ } else if(ivideo->vbflags & TV_PAL) {
andSISIDXREG(SISPART2, 0x3A, 0x1F);
- if (ivideo.vbflags & TV_SVIDEO) {
+ if (ivideo->vbflags & TV_SVIDEO) {
andSISIDXREG(SISPART2, 0x30, 0xDF);
- } else if (ivideo.vbflags & TV_AVIDEO) {
+ } else if (ivideo->vbflags & TV_AVIDEO) {
orSISIDXREG(SISPART2, 0x30, 0x20);
- switch (ivideo.video_width) {
+ switch (ivideo->video_width) {
case 640:
outSISIDXREG(SISPART2, 0x35, 0xF1);
outSISIDXREG(SISPART2, 0x36, 0xF7);
}
}
- if ((filter >= 0) && (filter <= 7)) {
- DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
- sis_TV_filter[filter_tb].filter[filter][0],
- sis_TV_filter[filter_tb].filter[filter][1],
- sis_TV_filter[filter_tb].filter[filter][2],
- sis_TV_filter[filter_tb].filter[filter][3]
- );
- outSISIDXREG(SISPART2, 0x35, (sis_TV_filter[filter_tb].filter[filter][0]));
- outSISIDXREG(SISPART2, 0x36, (sis_TV_filter[filter_tb].filter[filter][1]));
- outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
- outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
+ if((ivideo->sisfb_filter >= 0) && (ivideo->sisfb_filter <= 7)) {
+ outSISIDXREG(SISPART2,0x35,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][0]));
+ outSISIDXREG(SISPART2,0x36,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][1]));
+ outSISIDXREG(SISPART2,0x37,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][2]));
+ outSISIDXREG(SISPART2,0x38,(sis_TV_filter[filter_tb].filter[ivideo->sisfb_filter][3]));
}
}
-
}
#ifndef MODULE
-int sisfb_setup(char *options)
+int __init sisfb_setup(char *options)
{
char *this_opt;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- sisfb_fontname[0] = '\0';
-#endif
-
- ivideo.refresh_rate = 0;
- SiS_Pr.SiS_CustomT = CUT_NONE;
- SiS_Pr.UsePanelScaler = -1;
- SiS_Pr.LVDSHL = -1;
+ sisfb_setdefaultparms();
printk(KERN_DEBUG "sisfb: Options %s\n", options);
- if (!options || !*options)
+ if(!options || !(*options)) {
return 0;
+ }
while((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ if(!(*this_opt)) continue;
- if (!strnicmp(this_opt, "mode:", 5)) {
+ if(!strnicmp(this_opt, "off", 3)) {
+ sisfb_off = 1;
+ } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) {
+ /* Need to check crt2 type first for fstn/dstn */
+ sisfb_search_crt2type(this_opt + 14);
+ } else if(!strnicmp(this_opt, "tvmode:",7)) {
+ sisfb_search_tvstd(this_opt + 7);
+ } else if(!strnicmp(this_opt, "tvstandard:",11)) {
+ sisfb_search_tvstd(this_opt + 7);
+ } else if(!strnicmp(this_opt, "mode:", 5)) {
sisfb_search_mode(this_opt + 5, FALSE);
- } else if (!strnicmp(this_opt, "vesa:", 5)) {
+ } else if(!strnicmp(this_opt, "vesa:", 5)) {
sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- } else if (!strnicmp(this_opt, "inverse", 7)) {
+ } else if(!strnicmp(this_opt, "inverse", 7)) {
sisfb_inverse = 1;
/* fb_invert_cmaps(); */
- } else if (!strnicmp(this_opt, "font:", 5)) {
- strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
- sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
+ } else if(!strnicmp(this_opt, "font:", 5)) {
+ if(strlen(this_opt + 5) < 40) {
+ strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
+ sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
+ }
#endif
- } else if (!strnicmp(this_opt, "vrate:", 6)) {
- ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
- sisfb_parm_rate = ivideo.refresh_rate;
- } else if (!strnicmp(this_opt, "rate:", 5)) {
- ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
- sisfb_parm_rate = ivideo.refresh_rate;
- } else if (!strnicmp(this_opt, "off", 3)) {
- sisfb_off = 1;
- } else if (!strnicmp(this_opt, "crt1off", 7)) {
- sisfb_crt1off = 1;
- } else if (!strnicmp(this_opt, "filter:", 7)) {
- filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
- } else if (!strnicmp(this_opt, "forcecrt2type:", 14)) {
- sisfb_search_crt2type(this_opt + 14);
- } else if (!strnicmp(this_opt, "forcecrt1:", 10)) {
+ } else if(!strnicmp(this_opt, "rate:", 5)) {
+ sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
+ } else if(!strnicmp(this_opt, "filter:", 7)) {
+ sisfb_filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
+ } else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
- } else if (!strnicmp(this_opt, "tvmode:",7)) {
- sisfb_search_tvstd(this_opt + 7);
- } else if (!strnicmp(this_opt, "tvstandard:",11)) {
- sisfb_search_tvstd(this_opt + 7);
- } else if (!strnicmp(this_opt, "mem:",4)) {
- sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
- } else if (!strnicmp(this_opt, "queuemode:", 10)) {
- sisfb_search_queuemode(this_opt + 10);
- } else if (!strnicmp(this_opt, "pdc:", 4)) {
+ } else if(!strnicmp(this_opt, "mem:",4)) {
+ sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0);
+ } else if(!strnicmp(this_opt, "pdc:", 4)) {
sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
- } else if (!strnicmp(this_opt, "noaccel", 7)) {
+ } else if(!strnicmp(this_opt, "pdc1:", 5)) {
+ sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0);
+ } else if(!strnicmp(this_opt, "noaccel", 7)) {
sisfb_accel = 0;
- } else if (!strnicmp(this_opt, "noypan", 6)) {
+ } else if(!strnicmp(this_opt, "accel", 5)) {
+ sisfb_accel = -1;
+ } else if(!strnicmp(this_opt, "noypan", 6)) {
sisfb_ypan = 0;
- } else if (!strnicmp(this_opt, "nomax", 5)) {
+ } else if(!strnicmp(this_opt, "ypan", 4)) {
+ sisfb_ypan = -1;
+ } else if(!strnicmp(this_opt, "nomax", 5)) {
sisfb_max = 0;
- } else if (!strnicmp(this_opt, "userom:", 7)) {
+ } else if(!strnicmp(this_opt, "max", 3)) {
+ sisfb_max = -1;
+ } else if(!strnicmp(this_opt, "userom:", 7)) {
sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
- } else if (!strnicmp(this_opt, "useoem:", 7)) {
+ } else if(!strnicmp(this_opt, "useoem:", 7)) {
sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
- } else if (!strnicmp(this_opt, "nocrt2rate", 10)) {
+ } else if(!strnicmp(this_opt, "nocrt2rate", 10)) {
sisfb_nocrt2rate = 1;
- } else if (!strnicmp(this_opt, "scalelcd:", 9)) {
+ } else if(!strnicmp(this_opt, "scalelcd:", 9)) {
unsigned long temp = 2;
temp = simple_strtoul(this_opt + 9, NULL, 0);
if((temp == 0) || (temp == 1)) {
- SiS_Pr.UsePanelScaler = temp ^ 1;
+ sisfb_scalelcd = temp ^ 1;
}
- } else if (!strnicmp(this_opt, "specialtiming:", 14)) {
+ } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) {
+ int temp = 0;
+ temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+ if((temp >= -32) && (temp <= 32)) {
+ sisfb_tvxposoffset = temp;
+ }
+ } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) {
+ int temp = 0;
+ temp = (int)simple_strtol(this_opt + 13, NULL, 0);
+ if((temp >= -32) && (temp <= 32)) {
+ sisfb_tvyposoffset = temp;
+ }
+ } else if(!strnicmp(this_opt, "specialtiming:", 14)) {
sisfb_search_specialtiming(this_opt + 14);
- } else if (!strnicmp(this_opt, "lvdshl:", 7)) {
- unsigned long temp = 4;
+ } else if(!strnicmp(this_opt, "lvdshl:", 7)) {
+ int temp = 4;
temp = simple_strtoul(this_opt + 7, NULL, 0);
if((temp >= 0) && (temp <= 3)) {
- SiS_Pr.LVDSHL = temp;
+ sisfb_lvdshl = temp;
}
} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
sisfb_search_mode(this_opt, TRUE);
+#if !defined(__i386__) && !defined(__x86_64__)
+ } else if(!strnicmp(this_opt, "resetcard", 9)) {
+ sisfb_resetcard = 1;
+ } else if(!strnicmp(this_opt, "videoram:", 9)) {
+ sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0);
+#endif
} else {
printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
}
- /* TW: Acceleration only with MMIO mode */
- if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
- sisfb_accel = 0;
- }
-
}
+
+
+
return 0;
}
#endif
-static char *sis_find_rom(void)
+static char * __devinit sis_find_rom(struct pci_dev *pdev)
{
-#if defined(__i386__)
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+
+#if defined(__i386__) || defined(__x86_64__)
u32 segstart;
unsigned char *rom_base, *rom;
int romptr;
for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
- rom_base = (char *)ioremap(segstart, 0x10000);
- if(!rom_base) continue;
+ rom_base = (unsigned char *)ioremap(segstart, 0x10000);
+ if(!rom_base) continue;
- if((*rom_base != 0x55) || (*(rom_base + 1) != 0xaa)) {
- iounmap(rom_base);
- continue;
- }
+ if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) {
+ iounmap(rom_base);
+ continue;
+ }
- romptr = (unsigned short)(*(rom_base + 0x18) | (*(rom_base + 0x19) << 8));
- if(romptr > (0x10000 - 8)) {
- iounmap(rom_base);
- continue;
- }
+ romptr = (unsigned short)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
+ if(romptr > (0x10000 - 8)) {
+ iounmap(rom_base);
+ continue;
+ }
- rom = rom_base + romptr;
+ rom = rom_base + romptr;
- if((*rom != 'P') || (*(rom + 1) != 'C') || (*(rom + 2) != 'I') || (*(rom + 3) != 'R')) {
- iounmap(rom_base);
- continue;
- }
+ if((readb(rom) != 'P') || (readb(rom + 1) != 'C') ||
+ (readb(rom + 2) != 'I') || (readb(rom + 3) != 'R')) {
+ iounmap(rom_base);
+ continue;
+ }
- pciid = (*(rom + 4)) | ((*(rom + 5)) << 8);
- if(pciid != 0x1039) {
- iounmap(rom_base);
- continue;
- }
+ pciid = readb(rom + 4) | (readb(rom + 5) << 8);
+ if(pciid != 0x1039) {
+ iounmap(rom_base);
+ continue;
+ }
- pciid = (*(rom + 6)) | ((*(rom + 7)) << 8);
- if(pciid == ivideo.chip_id) return rom_base;
+ pciid = readb(rom + 6) | (readb(rom + 7) << 8);
+ if(pciid == ivideo->chip_id) return rom_base;
- iounmap(rom_base);
+ iounmap(rom_base);
}
+#else
+ unsigned char *rom_base, *rom, *myrombase = NULL;
+ int romptr;
+ unsigned short pciid;
+ u32 backup;
+
+ pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &backup);
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
+ (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
+
+ rom_base = ioremap(ivideo->video_base, 65536);
+ if(rom_base) {
+ if((readb(rom_base) == 0x55) && (readb(rom_base + 1) == 0xaa)) {
+ romptr = (u16)(readb(rom_base + 0x18) | (readb(rom_base + 0x19) << 8));
+ if(romptr <= (0x10000 - 8)) {
+ rom = rom_base + romptr;
+ if((readb(rom) == 'P') && (readb(rom + 1) == 'C') &&
+ (readb(rom + 2) == 'I') && (readb(rom + 3) == 'R')) {
+ pciid = readb(rom + 4) | (readb(rom + 5) << 8);
+ if(pciid == 0x1039) {
+ pciid = readb(rom + 6) | (readb(rom + 7) << 8);
+ if(pciid == ivideo->chip_id) {
+ if((myrombase = vmalloc(65536))) {
+ memcpy_fromio(myrombase, rom_base, 65536);
+ }
+ }
+ }
+ }
+ }
+ }
+ iounmap(rom_base);
+ }
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS, backup);
+ if(myrombase) return myrombase;
#endif
return NULL;
}
-
-
-int __init sisfb_init(void)
+#ifdef CONFIG_FB_SIS_300
+static int __devinit
+sisfb_chkbuswidth300(struct pci_dev *pdev, ULONG FBAddress)
{
- struct pci_dev *pdev = NULL;
- struct board *b;
- int pdev_valid = 0;
- u32 reg32;
- u16 reg16;
- u8 reg;
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ int i, j;
+ USHORT temp;
+ UCHAR reg;
+
+ andSISIDXREG(SISSR,0x15,0xFB);
+ orSISIDXREG(SISSR,0x15,0x04);
+ outSISIDXREG(SISSR,0x13,0x00);
+ outSISIDXREG(SISSR,0x14,0xBF);
+
+ for(i=0; i<2; i++) {
+ temp = 0x1234;
+ for(j=0; j<4; j++) {
+ writew(temp, FBAddress);
+ if(readw(FBAddress) == temp) break;
+ orSISIDXREG(SISSR,0x3c,0x01);
+ inSISIDXREG(SISSR,0x05,reg);
+ inSISIDXREG(SISSR,0x05,reg);
+ andSISIDXREG(SISSR,0x3c,0xfe);
+ inSISIDXREG(SISSR,0x05,reg);
+ inSISIDXREG(SISSR,0x05,reg);
+ temp++;
+ }
+ }
-#if 0
- /* for DOC VB */
- sisfb_set_reg4(0xcf8,0x800000e0);
- reg32 = sisfb_get_reg3(0xcfc);
- reg32 = reg32 | 0x00001000;
- sisfb_set_reg4(0xcfc,reg32);
+ writel(0x01234567L, FBAddress);
+ writel(0x456789ABL, (FBAddress+4));
+ writel(0x89ABCDEFL, (FBAddress+8));
+ writel(0xCDEF0123L, (FBAddress+12));
+ inSISIDXREG(SISSR,0x3b,reg);
+ if(reg & 0x01) {
+ if(readl((FBAddress+12)) == 0xCDEF0123L) return(4); /* Channel A 128bit */
}
-#endif
+ if(readl((FBAddress+4)) == 0x456789ABL) return(2); /* Channel B 64bit */
+ return(1); /* 32bit */
+}
- if (sisfb_off)
- return -ENXIO;
+static void __devinit
+sisfb_setramsize300(struct pci_dev *pdev)
+{
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ ULONG FBAddr = (ULONG)ivideo->sishw_ext.pjVideoMemoryAddress, Addr;
+ USHORT SR13, SR14=0, buswidth, Done, data, TotalCapacity, PhysicalAdrOtherPage=0;
+ int PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
+ int RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
+ int PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage, i, j, k;
+ const USHORT SiS_DRAMType[17][5] = {
+ {0x0C,0x0A,0x02,0x40,0x39},
+ {0x0D,0x0A,0x01,0x40,0x48},
+ {0x0C,0x09,0x02,0x20,0x35},
+ {0x0D,0x09,0x01,0x20,0x44},
+ {0x0C,0x08,0x02,0x10,0x31},
+ {0x0D,0x08,0x01,0x10,0x40},
+ {0x0C,0x0A,0x01,0x20,0x34},
+ {0x0C,0x09,0x01,0x08,0x32},
+ {0x0B,0x08,0x02,0x08,0x21},
+ {0x0C,0x08,0x01,0x08,0x30},
+ {0x0A,0x08,0x02,0x04,0x11},
+ {0x0B,0x0A,0x01,0x10,0x28},
+ {0x09,0x08,0x02,0x02,0x01},
+ {0x0B,0x09,0x01,0x08,0x24},
+ {0x0B,0x08,0x01,0x04,0x20},
+ {0x0A,0x08,0x01,0x02,0x10},
+ {0x09,0x08,0x01,0x01,0x00}
+ };
+
+ buswidth = sisfb_chkbuswidth300(pdev, FBAddr);
+
+ MB2Bank = 16;
+ Done = 0;
+ for(i = 6; i >= 0; i--) {
+ if(Done) break;
+ PseudoRankCapacity = 1 << i;
+ for(j = 4; j >= 1; j--) {
+ if(Done) break;
+ PseudoTotalCapacity = PseudoRankCapacity * j;
+ PseudoAdrPinCount = 15 - j;
+ if(PseudoTotalCapacity <= 64) {
+ for(k = 0; k <= 16; k++) {
+ if(Done) break;
+ RankCapacity = buswidth * SiS_DRAMType[k][3];
+ AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
+ if(RankCapacity == PseudoRankCapacity)
+ if(AdrPinCount <= PseudoAdrPinCount) {
+ if(j == 3) { /* Rank No */
+ BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
+ BankNumMid = RankCapacity * MB2Bank * 1 - 1;
+ } else {
+ BankNumHigh = RankCapacity * MB2Bank * j - 1;
+ BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
+ }
+ PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
+ PhysicalAdrHigh = BankNumHigh;
+ PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
+ PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
+ /* Write data */
+ andSISIDXREG(SISSR,0x15,0xFB); /* Test */
+ orSISIDXREG(SISSR,0x15,0x04); /* Test */
+ TotalCapacity = SiS_DRAMType[k][3] * buswidth;
+ SR13 = SiS_DRAMType[k][4];
+ if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
+ if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
+ if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
+ outSISIDXREG(SISSR,0x13,SR13);
+ outSISIDXREG(SISSR,0x14,SR14);
+ Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
+ /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh; */
+ writew(((USHORT)PhysicalAdrHigh), Addr);
+ Addr = FBAddr + BankNumMid * 64 * 1024 + PhysicalAdrHigh;
+ /* *((USHORT *)(Addr)) = (USHORT)BankNumMid; */
+ writew(((USHORT)BankNumMid), Addr);
+ Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHalfPage;
+ /* *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage; */
+ writew(((USHORT)PhysicalAdrHalfPage), Addr);
+ Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrOtherPage;
+ /* *((USHORT *)(Addr)) = PhysicalAdrOtherPage; */
+ writew(((USHORT)PhysicalAdrOtherPage), Addr);
+ /* Read data */
+ Addr = FBAddr + BankNumHigh * 64 * 1024 + PhysicalAdrHigh;
+ data = readw(Addr); /* *((USHORT *)(Addr)); */
+ if(data == PhysicalAdrHigh) Done = 1;
+ } /* if */
+ } /* for k */
+ } /* if */
+ } /* for j */
+ } /* for i */
+}
- sisfb_registered = 0;
- sisfb_thismonitor.datavalid = FALSE;
+static void __devinit sisfb_post_sis300(struct pci_dev *pdev)
+{
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
+ u16 index, rindex, memtype = 0;
- memset(&sishw_ext, 0, sizeof(sishw_ext));
+ outSISIDXREG(SISSR,0x05,0x86);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- memset(&sisfb_lastrates[0], 0, 128);
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- memset(&sis_disp, 0, sizeof(sis_disp));
-#endif
+ if(ivideo->sishw_ext.UseROM) {
+ if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80) {
+ memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
+ } else {
+ inSISIDXREG(SISSR,0x3a,memtype);
+ }
+ memtype &= 0x07;
+ }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
- pci_for_each_dev(pdev) {
-#else
- while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+ if(ivideo->revision_id <= 0x13) {
+ v1 = 0x44; v2 = 0x42; v3 = 0x80;
+ v4 = 0x44; v5 = 0x42; v6 = 0x80;
+ } else {
+ v1 = 0x68; v2 = 0x43; v3 = 0x80; /* Assume 125Mhz MCLK */
+ v4 = 0x68; v5 = 0x43; v6 = 0x80; /* Assume 125Mhz ECLK */
+ if(ivideo->sishw_ext.UseROM) {
+ index = memtype * 5;
+ rindex = index + 0x54;
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ rindex = index + 0x7c;
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ }
+ }
+ outSISIDXREG(SISSR,0x28,v1);
+ outSISIDXREG(SISSR,0x29,v2);
+ outSISIDXREG(SISSR,0x2a,v3);
+ outSISIDXREG(SISSR,0x2e,v4);
+ outSISIDXREG(SISSR,0x2f,v5);
+ outSISIDXREG(SISSR,0x30,v6);
+ v1 = 0x10;
+ if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0xa4];
+ outSISIDXREG(SISSR,0x07,v1); /* DAC speed */
+ outSISIDXREG(SISSR,0x11,0x0f); /* DDC, power save */
+ v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
+ v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
+ if(ivideo->sishw_ext.UseROM) {
+ memtype += 0xa5;
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[memtype];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 8];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 16];
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 24];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 32];
+ v6 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 40];
+ v7 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 48];
+ v8 = ivideo->sishw_ext.pjVirtualRomBase[memtype + 56];
+ }
+ if(ivideo->revision_id >= 0x80) v3 &= 0xfd;
+ outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0xa5 step 8) */
+ outSISIDXREG(SISSR,0x16,v2);
+ outSISIDXREG(SISSR,0x17,v3);
+ outSISIDXREG(SISSR,0x18,v4);
+ outSISIDXREG(SISSR,0x19,v5);
+ outSISIDXREG(SISSR,0x1a,v6);
+ outSISIDXREG(SISSR,0x1b,v7);
+ outSISIDXREG(SISSR,0x1c,v8); /* ---- */
+ andSISIDXREG(SISSR,0x15,0xfb);
+ orSISIDXREG(SISSR,0x15,0x04);
+ if(ivideo->sishw_ext.UseROM) {
+ if(ivideo->sishw_ext.pjVirtualRomBase[0x53] & 0x02) {
+ orSISIDXREG(SISSR,0x19,0x20);
+ }
+ }
+ v1 = 0x04; /* DAC pedestal (BIOS 0xe5) */
+ if(ivideo->revision_id >= 0x80) v1 |= 0x01;
+ outSISIDXREG(SISSR,0x1f,v1);
+ outSISIDXREG(SISSR,0x20,0xa0); /* linear & relocated io */
+ v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe8];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe9];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[0xea];
+ }
+ outSISIDXREG(SISSR,0x23,v1);
+ outSISIDXREG(SISSR,0x24,v2);
+ outSISIDXREG(SISSR,0x25,v3);
+ outSISIDXREG(SISSR,0x21,0x84);
+ outSISIDXREG(SISSR,0x22,0x00);
+ outSISIDXREG(SISCR,0x37,0x00);
+ orSISIDXREG(SISPART1,0x24,0x01); /* unlock crt2 */
+ outSISIDXREG(SISPART1,0x00,0x00);
+ v1 = 0x40; v2 = 0x11;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xec];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0xeb];
+ }
+ outSISIDXREG(SISPART1,0x02,v1);
+ if(ivideo->revision_id >= 0x80) v2 &= ~0x01;
+ inSISIDXREG(SISPART4,0x00,reg);
+ if((reg == 1) || (reg == 2)) {
+ outSISIDXREG(SISCR,0x37,0x02);
+ outSISIDXREG(SISPART2,0x00,0x1c);
+ v4 = 0x00; v5 = 0x00; v6 = 0x10;
+ if(ivideo->sishw_ext.UseROM) {
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[0xf5];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[0xf6];
+ v6 = ivideo->sishw_ext.pjVirtualRomBase[0xf7];
+ }
+ outSISIDXREG(SISPART4,0x0d,v4);
+ outSISIDXREG(SISPART4,0x0e,v5);
+ outSISIDXREG(SISPART4,0x10,v6);
+ outSISIDXREG(SISPART4,0x0f,0x3f);
+ inSISIDXREG(SISPART4,0x01,reg);
+ if(reg >= 0xb0) {
+ inSISIDXREG(SISPART4,0x23,reg);
+ reg &= 0x20;
+ reg <<= 1;
+ outSISIDXREG(SISPART4,0x23,reg);
+ }
+ } else {
+ v2 &= ~0x10;
+ }
+ outSISIDXREG(SISSR,0x32,v2);
+ andSISIDXREG(SISPART1,0x24,0xfe); /* Lock CRT2 */
+ inSISIDXREG(SISSR,0x16,reg);
+ reg &= 0xc3;
+ outSISIDXREG(SISCR,0x35,reg);
+ outSISIDXREG(SISCR,0x83,0x00);
+#if !defined(__i386__) && !defined(__x86_64__)
+ if(sisfb_videoram) {
+ outSISIDXREG(SISSR,0x13,0x28); /* ? */
+ reg = ((sisfb_videoram >> 10) - 1) | 0x40;
+ outSISIDXREG(SISSR,0x14,reg);
+ } else {
#endif
- for (b = sisdev_list; b->vendor; b++) {
- if ((b->vendor == pdev->vendor)
- && (b->device == pdev->device)) {
- pdev_valid = 1;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && defined(NEWFBDEV)
- sis_fb_info = framebuffer_alloc(0, &pdev->dev);
-#else
- sis_fb_info = kmalloc(sizeof(*sis_fb_info), GFP_KERNEL);
+ /* Need to map max FB size for finding out about RAM size */
+ ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
+ if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+ sisfb_setramsize300(pdev);
+ iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+ } else {
+ printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
+ outSISIDXREG(SISSR,0x13,0x28); /* ? */
+ outSISIDXREG(SISSR,0x14,0x47); /* 8MB, 64bit default */
+ }
+#if !defined(__i386__) && !defined(__x86_64__)
+ }
#endif
- if(!sis_fb_info) return -ENOMEM;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (!(defined(NEWFBDEV)))
- memset(sis_fb_info, 0, sizeof(*sis_fb_info));
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xe6];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0xe7];
+ } else {
+ inSISIDXREG(SISSR,0x3a,reg);
+ if((reg & 0x30) == 0x30) {
+ v1 = 0x04; /* PCI */
+ v2 = 0x92;
+ } else {
+ v1 = 0x14; /* AGP */
+ v2 = 0xb2;
+ }
+ }
+ outSISIDXREG(SISSR,0x21,v1);
+ outSISIDXREG(SISSR,0x22,v2);
+}
#endif
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, b->name);
-#else
- strcpy(myid, b->name);
-#endif
- ivideo.chip_id = pdev->device;
- pci_read_config_byte(pdev, PCI_REVISION_ID,
- &ivideo.revision_id);
- pci_read_config_word(pdev, PCI_COMMAND, ®16);
- sishw_ext.jChipRevision = ivideo.revision_id;
- sisvga_enabled = reg16 & 0x01;
- ivideo.pcibus = pdev->bus->number;
- ivideo.pcislot = PCI_SLOT(pdev->devfn);
- ivideo.pcifunc = PCI_FUNC(pdev->devfn);
- ivideo.subsysvendor = pdev->subsystem_vendor;
- ivideo.subsysdevice = pdev->subsystem_device;
- break;
- }
- }
- if (pdev_valid)
- break;
+#ifdef CONFIG_FB_SIS_315
+static void __devinit sisfb_post_sis315330(struct pci_dev *pdev)
+{
+#ifdef YET_TO_BE_DONE
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ u8 reg, v1, v2, v3, v4, v5, v6, v7, v8;
+ u16 index, rindex, memtype = 0;
+ u32 reg1_32, reg2_32, reg3_32;
+ int i;
+
+ /* Unlock */
+ /* outSISIDXREG(0x3c4,0x05,0x86); */
+ outSISIDXREG(SISSR,0x05,0x86);
+
+ /* Enable relocated i/o ports */
+ /* setSISIDXREG(0x3c4,0x20,~0x10,0x20); */
+ setSISIDXREG(SISSR,0x20,~0x10,0x20);
+
+ /* Clear regs */
+ for(i = 0; i < 0x22; i++) {
+ outSISIDXREG(SISSR,(0x06 + i),0x00);
+ }
+ v1 = 0x0d;
+ if( is 330) v1 = 0x0b;
+ for(i = 0; i < v1; i++) {
+ outSISIDXREG(SISSR,(0x31 + i),0x00);
+ }
+ for(i = 0; i < 0x10; i++) {
+ outSISIDXREG(SISCR,(0x30 + i),0x00);
+ }
+
+ /* Reset clocks */
+ reg = inSISREG(SISMISCR);
+ outSISIDXREG(SISSR,0x28,0x81);
+ outSISIDXREG(SISSR,0x2A,0x00);
+ outSISIDXREG(SISSR,0x29,0xE1);
+ outSISREG(SISMISCW,(reg | 0x0c));
+ outSISIDXREG(SISSR,0x2B,0x81);
+ outSISIDXREG(SISSR,0x2D,0x00);
+ outSISIDXREG(SISSR,0x2C,0xE1);
+ outSISIDXREG(SISSR,0x2E,0x81);
+ outSISIDXREG(SISSR,0x30,0x00);
+ outSISIDXREG(SISSR,0x2F,0xE1);
+ SiS_DDC2Delay(....);
+ outSISREG(SISMISCW,reg);
+
+ /* Get memory type */
+ if(ivideo->sishw_ext.UseROM) {
+ if(ivideo->sishw_ext.pjVirtualRomBase[0x52] & 0x80)) {
+ memtype = ivideo->sishw_ext.pjVirtualRomBase[0x52];
+ } else {
+ inSISIDXREG(SISSR,0x3a,memtype);
+ }
+ memtype &= 0x03;
+ if( is 330 ) {
+ if(memtype <= 1) memtype = 0;
+ else {
+ inSISIDXREG(SISCR,0x5F,reg);
+ reg &= 0x30;
+ switch(reg) {
+ case 0x00: memtype = 1; break;
+ case 0x10: memtype = 3; break;
+ case 0x20: memtype = 3; break;
+ default: memtype = 2;
+ }
+ }
+ }
}
- if (!pdev_valid)
- return -ENODEV;
+ /* Set clocks */
+ v1 = 0x3b; v2 = 0x22; v3 = 0x01; /* Assume 143Mhz MCLK */
+ v4 = 0x5c; v5 = 0x23; v6 = 0x01; /* Assume 166Mhz ECLK */
+ if(ivideo->sishw_ext.UseROM) {
+ index = memtype * 5;
+ rindex = index + 0x54;
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ rindex = index + 0x68;
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ v6 = ivideo->sishw_ext.pjVirtualRomBase[rindex++];
+ }
+ outSISIDXREG(SISSR,0x28,v1);
+ outSISIDXREG(SISSR,0x29,v2);
+ outSISIDXREG(SISSR,0x2a,v3);
+ if( is 330 ) {
+ inSISIDXREG(SISSR,0x3a,reg);
+ reg &= 0x03;
+ if(reg >= 2) {
+ ...
+ }
+ }
+ outSISIDXREG(SISSR,0x2e,v4);
+ outSISIDXREG(SISSR,0x2f,v5);
+ outSISIDXREG(SISSR,0x30,v6);
+
+ /* End of comp with 330 */
+
+ v1 = 0x18;
+ if(ivideo->sishw_ext.UseROM) v1 = ivideo->sishw_ext.pjVirtualRomBase[0x7c];
+ outSISIDXREG(SISSR,0x07,v1);
+ outSISIDXREG(SISSR,0x11,0x0f);
+
+ v1 = 0x00; v2 = 0x0f; v3 = 0xba; v4 = 0xa9;
+ v5 = 0xa0; v6 = 0x00; v7 = 0x30;
+ if(ivideo->sishw_ext.UseROM) {
+ index = memtype + 0x7d;
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
+ v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
+ v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
+ }
+ outSISIDXREG(SISSR,0x15,v1); /* Ram type (assuming 0, BIOS 0x7d step 4) */
+ outSISIDXREG(SISSR,0x16,v2);
+ outSISIDXREG(SISSR,0x17,v3);
+ outSISIDXREG(SISSR,0x18,v4);
+ outSISIDXREG(SISSR,0x19,v5);
+ outSISIDXREG(SISSR,0x1a,v6);
+ outSISIDXREG(SISSR,0x1b,v7);
+ outSISIDXREG(SISSR,0x1c,v8); /* ---- */
+
+ v1 = 0x77; v2 = 0x77; v3 = 0x00; v4 = 0x5b; v5 = 0x00;
+ if(ivideo->sishw_ext.UseROM) {
+ index = memtype + 0xa2;
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
+ }
+ outSISIDXREG(SISCR,0x40,v1);
+ outSISIDXREG(SISCR,0x41,v2);
+ outSISIDXREG(SISCR,0x42,v3);
+ outSISIDXREG(SISCR,0x43,v4);
+ outSISIDXREG(SISCR,0x44,v5);
+
+ if( is 330 ) {
+
+ v1 = 0x;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
+ }
+ outSISIDXREG(SISCR,0x59,v1);
+
+ v1 = 0x; v2 = 0x; v3 = 0x; v4 = 0x;
+ v5 = 0x; v6 = 0x; v7 = 0x; v8 = 0x;
+ if(ivideo->sishw_ext.UseROM) {
+ index = memtype + 0xbe;
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[index];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[index + 4];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[index + 8];
+ v4 = ivideo->sishw_ext.pjVirtualRomBase[index + 12];
+ v5 = ivideo->sishw_ext.pjVirtualRomBase[index + 16];
+ v6 = ivideo->sishw_ext.pjVirtualRomBase[index + 20];
+ v7 = ivideo->sishw_ext.pjVirtualRomBase[index + 24];
+ v8 = ivideo->sishw_ext.pjVirtualRomBase[index + 28];
+ }
+ outSISIDXREG(SISCR,0x68,v1);
+ outSISIDXREG(SISCR,0x69,v2);
+ outSISIDXREG(SISCR,0x6a,v3);
+ outSISIDXREG(SISCR,0x6b,v4);
+ outSISIDXREG(SISCR,0x6c,v5);
+ outSISIDXREG(SISCR,0x6d,v6);
+ outSISIDXREG(SISCR,0x6e,v7);
+ outSISIDXREG(SISCR,0x6f,v8);
+
+ v1 = 0x20;
+ inSISIDXREG(SISSR,0x3b,reg);
+
+ if(!(reg & 0x04)) {
+ inSISIDXREG(SISCR,0x5F,reg);
+ reg &= 0x30;
+ if(reg) v1 = 0x23;
+ }
+ outSISIDXREG(SISCR,0x48,v1);
+ outSISIDXREG(SISCR,0x4c,0x20);
+
+ xx= xxx();
+ if(xx >= 1) {
+ v1 = 0x;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xBA];
+ }
+ outSISIDXREG(SISCR,0x59,v1);
+ }
+
+
+
+ } else {
+
+ outSISIDXREG(SISCR,0x48,0x23);
+
+ andSISIDXREG(SISSR,0x16,0x0f);
+ if(memtype <= 1) {
+ orSISIDXREG(SISSR,0x16,0x80);
+ } else {
+ v1 = 0x0f;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0x81 + memtype];
+ }
+ if(!(v1 & 0x10)) v2 = 0xc0;
+ else v2 = 0xd0;
+ orSISIDXREG(SISSR,0x16,v2);
+ andSISIDXREG(SISSR,0x16,0x0f);
+ if(!(v1 & 0x10)) v2 = 0x80;
+ else v2 = 0xA0;
+ orSISIDXREG(SISSR,0x16,v2);
+ }
+
+ if(memtype >= 2) {
+ const u8 sr3cseq1[] = { 0xc0,0xe0,0xf0,0xe0,0xf0,0xa0,0xb0,0xa0,0xb0,0x90,0xd0 };
+ const u8 sr3cseq2[] = { 0xc0,0xa0,0xb0,0xa0,0xb0,0xe0,0xf0,0xa0,0xb0,0x90,0xd0 };
+ for(i = 0; i < 11; i++) {
+ outSISIDXREG(SISSR,0x3c,sr3cseq1[i]);
+ }
+ outSISIDXREG(SISSR,0x3d,0x00);
+ outSISIDXREG(SISSR,0x3d,0x04);
+ SiS_DDC2Delay(0x200);
+ v1 = inSISIDXREG(SISCR,0xEC);
+ v2 = inSISIDXREG(SISCR,0xED);
+ reg1_32 = (v2 << 8) | v1;
+ outSISIDXREG(SISSR,0x3D,0x00);
+ for(i = 0; i < 11; i++) {
+ outSISIDXREG(SISSR,0x3c,sr3cseq2[i]);
+ }
+ outSISIDXREG(SISSR,0x3d,0x00);
+ outSISIDXREG(SISSR,0x3d,0x04);
+ SiS_DDC2Delay(0x200);
+ v1 = inSISIDXREG(SISCR,0xEC);
+ v2 = inSISIDXREG(SISCR,0xED);
+ reg2_32 = (v2 << 8) | v1;
+ outSISIDXREG(SISSR,0x3D,0x00);
+ reg3_32 = reg2_32 << 1;
+ reg2_32 >>= 1;
+ reg3_32 += reg2_32;
+ v1 = 0x40;
+ if(reg3_32 > reg1_32) v1 = 0x10;
+ outSISIDXREG(SISCR,0x59,v1);
+ }
+
+ }
+
+ v1 = 0x00;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0x99];
+ }
+ outSISIDXREG(SISSR,0x1f,v1);
+
+ outSISIDXREG(SISSR,0x20,0x20);
+
+ v1 = 0xf6; v2 = 0x0d; v3 = 0x33;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9c];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9d];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[0x9e];
+ }
+ outSISIDXREG(SISSR,0x23,v1);
+ outSISIDXREG(SISSR,0x24,v2);
+ outSISIDXREG(SISSR,0x25,v3);
+
+ outSISIDXREG(SISSR,0x21,0x84);
+ outSISIDXREG(SISSR,0x22,0x00);
+ outSISIDXREG(SISSR,0x27,0x1f);
+
+ v1 = 0x00; v2 = 0x00;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9F];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0xA1];
+ }
+ outSISIDXREG(SISSR,0x31,v1);
+ outSISIDXREG(SISSR,0x33,v2);
+
+ v1 = 0x11;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xA0];
+ }
+ v2 = inSISIDXREG(SISPART4,0x00);
+ if((v2 != 1) && (v2 != 2)) v1 &= 0xef;
+ outSISIDXREG(SISSR,0x32,v1);
+
+ /* AGP */
+ pci_read_config_long(pdev, 0x50, ®1_32);
+ reg1_32 >>= 20;
+ reg1_32 &= 0x0f;
+ if(reg1_32 == 1) {
+ v1 = 0xAA; v2 = 0x33;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF7];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9E];
+ }
+ } else {
+ v1 = 0x88; v2 = 0x03;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xF8];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0xF6];
+ }
+ }
+ outSISIDXREG(SISCR,0x49,v1);
+ outSISIDXREG(SISSR,0x25,v2);
+
+ v1 = inSISIDXREG(SISPART4,0x00);
+ if((v1 == 1) || (v1 == 2)) {
+ orSISIDXREG(SISPART1,0x2F,0x01); /* Unlock CRT2 */
+ outSISIDXREG(SISPART1,0x00,0x00);
+ v1 = 0x00;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb6];
+ }
+ outSISIDXREG(SISPART1,0x02,v1);
+ outSISIDXREG(SISPART1,0x2E,0x08);
+ outSISIDXREG(SISPART2,0x00,0x1c);
+ v1 = 0x40; v2 = 0x00; v3 = 0x80;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0xb7];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0xb8];
+ v3 = ivideo->sishw_ext.pjVirtualRomBase[0xbb];
+ }
+ outSISIDXREG(SISPART4,0x0d,v1);
+ outSISIDXREG(SISPART4,0x0e,v2);
+ outSISIDXREG(SISPART4,0x10,v3);
+ outSISIDXREG(SISPART4,0x0F,0x3F);
+
+ inSISIDXREG(SISPART4,0x01,reg);
+ if(reg >= 0xb0) {
+ inSISIDXREG(SISPART4,0x23,reg);
+ reg &= 0x20;
+ reg <<= 1;
+ outSISIDXREG(SISPART4,0x23,reg);
+ }
+ }
+ outSISIDXREG(SISCR,0x37,0x02); /* Why? */
+
+ outSISIDXREG(SISCR,0x83,0x00);
+ outSISIDXREG(SISCR,0x90,0x00);
+ andSISIDXREG(SISSR,0x5B,0xDF);
+ outSISIDXREG(SISVID,0x00,0x86);
+ outSISIDXREG(SISVID,0x32,0x00);
+ outSISIDXREG(SISVID,0x30,0x00);
+ outSISIDXREG(SISVID,0x32,0x01);
+ outSISIDXREG(SISVID,0x30,0x00);
+ orSISIDXREG(SISCR,0x63,0x80);
+ /* End of Init1 */
+
+ /* Set Mode 0x2e */
+
+ /* Ramsize */
+ orSISIDXREG(SISSR,0x16,0x0f);
+ orSISIDXREG(SISSR,0x18,0xA9);
+ orSISIDXREG(SISSR,0x19,0xA0);
+ orSISIDXREG(SISSR,0x1B,0x30);
+ andSISIDXREG(SISSR,0x17,0xF8);
+ orSISIDXREG(SISSR,0x19,0x03);
+ andSIDIDXREG(SISSR,0x13,0x00);
+
+ /* Need to map max FB size for finding out about RAM size */
+ ivideo->sishw_ext.pjVideoMemoryAddress = ioremap(ivideo->video_base, 0x4000000);
+ if(ivideo->sishw_ext.pjVideoMemoryAddress) {
+ /* Find out about bus width */
+ if(memtype <= 1) {
+ outSISIDXREG(SISSR,0x14,0x02);
+ andSISIDXREG(SISSR,0x16,0x0F);
+ orSISIDXREG(SISSR,0x16,0x80);
+
+ ...
+
+ } else {
+
+ ...
+
+ }
+
+ /* Find out about size */
+
+
+ iounmap(ivideo->sishw_ext.pjVideoMemoryAddress);
+ } else {
+ printk(KERN_DEBUG "sisfb: Failed to map memory for size detection, assuming 8MB\n");
+ outSISIDXREG(SISSR,0x14,0x??); /* 8MB, 64bit default */
+ }
+
+ /* AGP (Missing: Checks for VIA and AMD hosts) */
+ v1 = 0xA5; v2 = 0xFB;
+ if(ivideo->sishw_ext.UseROM) {
+ v1 = ivideo->sishw_ext.pjVirtualRomBase[0x9A];
+ v2 = ivideo->sishw_ext.pjVirtualRomBase[0x9B];
+ }
+ outSISIDXREG(SISSR,0x21,v1);
+ outSISIDXREG(SISSR,0x22,v2);
- switch (ivideo.chip_id) {
-#ifdef CONFIG_FB_SIS_300
- case PCI_DEVICE_ID_SI_300:
- ivideo.chip = SIS_300;
- sisvga_engine = SIS_300_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2; /* New X driver uses 2 buffers */
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
- break;
- case PCI_DEVICE_ID_SI_630_VGA:
- {
- ivideo.chip = SIS_630;
- sisfb_set_reg4(0xCF8, 0x80000000);
- reg32 = sisfb_get_reg3(0xCFC);
- if(reg32 == 0x07301039) {
- ivideo.chip = SIS_730;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, "SIS 730");
-#else
- strcpy(myid, "SIS 730");
-#endif
- }
- sisvga_engine = SIS_300_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
- break;
- }
- case PCI_DEVICE_ID_SI_540_VGA:
- ivideo.chip = SIS_540;
- sisvga_engine = SIS_300_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
- break;
-#endif
-#ifdef CONFIG_FB_SIS_315
- case PCI_DEVICE_ID_SI_315H:
- ivideo.chip = SIS_315H;
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- break;
- case PCI_DEVICE_ID_SI_315:
- ivideo.chip = SIS_315;
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- break;
- case PCI_DEVICE_ID_SI_315PRO:
- ivideo.chip = SIS_315PRO;
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- break;
- case PCI_DEVICE_ID_SI_550_VGA:
- ivideo.chip = SIS_550;
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- break;
- case PCI_DEVICE_ID_SI_650_VGA:
- {
- ivideo.chip = SIS_650;
- sisfb_set_reg4(0xCF8, 0x80000000);
- reg32 = sisfb_get_reg3(0xCFC);
- if(reg32 == 0x07401039) {
- ivideo.chip = SIS_740;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, "SIS 740");
-#else
- strcpy(myid, "SIS 740");
-#endif
- }
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- break;
- }
- case PCI_DEVICE_ID_SI_330:
- ivideo.chip = SIS_330;
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
- break;
- case PCI_DEVICE_ID_SI_660_VGA:
- {
- sisfb_set_reg4(0xCF8, 0x80000000);
- reg32 = sisfb_get_reg3(0xCFC);
- if(reg32 == 0x07601039) {
- ivideo.chip = SIS_760;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, "SIS 760");
-#else
- strcpy(myid, "SIS 760");
#endif
- } else if(reg32 == 0x06601039) {
- ivideo.chip = SIS_660;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, "SIS 660");
-#else
- strcpy(myid, "SIS 660");
+ return;
+}
#endif
- } else if(reg32 == 0x07411039) {
- ivideo.chip = SIS_741;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, "SIS 741");
+
+
+int __devinit sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data];
+ struct sis_video_info *ivideo = NULL;
+ struct fb_info *sis_fb_info = NULL;
+ u16 reg16;
+ u8 reg;
+ int sisvga_enabled = 0, i;
+
+ if(sisfb_off) return -ENXIO;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
+ sis_fb_info = framebuffer_alloc(sizeof(*ivideo), &pdev->dev);
+ if(!sis_fb_info) return -ENOMEM;
#else
- strcpy(myid, "SIS 741");
+ sis_fb_info = kmalloc(sizeof(*sis_fb_info) + sizeof(*ivideo), GFP_KERNEL);
+ if(!sis_fb_info) return -ENOMEM;
+ memset(sis_fb_info, 0, sizeof(*sis_fb_info) + sizeof(*ivideo));
+ sis_fb_info->par = ((char *)sis_fb_info + sizeof(*sis_fb_info));
#endif
- } else {
- ivideo.chip = SIS_661;
+
+ ivideo = (struct sis_video_info *)sis_fb_info->par;
+ ivideo->memyselfandi = sis_fb_info;
+
+ if(card_list == NULL) {
+ ivideo->cardnumber = 0;
+ } else {
+ struct sis_video_info *countvideo = card_list;
+ ivideo->cardnumber = 1;
+ while ((countvideo = countvideo->next) != NULL) ivideo->cardnumber++;
+ }
+
+ strncpy(ivideo->myid, chipinfo->chip_name, 30);
+
+ ivideo->chip_id = pdev->device;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &ivideo->revision_id);
+ ivideo->sishw_ext.jChipRevision = ivideo->revision_id;
+ pci_read_config_word(pdev, PCI_COMMAND, ®16);
+ sisvga_enabled = reg16 & 0x01;
+ ivideo->pcibus = pdev->bus->number;
+ ivideo->pcislot = PCI_SLOT(pdev->devfn);
+ ivideo->pcifunc = PCI_FUNC(pdev->devfn);
+ ivideo->subsysvendor = pdev->subsystem_vendor;
+ ivideo->subsysdevice = pdev->subsystem_device;
+#ifdef SIS_CONFIG_COMPAT
+ ivideo->ioctl32registered = 0;
+ ivideo->ioctl32vblankregistered = 0;
+#endif
+
+#ifndef MODULE
+ if(sisfb_mode_idx == -1) {
+ sisfb_get_vga_mode_from_kernel();
+ }
+#endif
+
+ ivideo->chip = chipinfo->chip;
+ ivideo->sisvga_engine = chipinfo->vgaengine;
+ ivideo->hwcursor_size = chipinfo->hwcursor_size;
+ ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
+ ivideo->mni = chipinfo->mni;
+
+ ivideo->detectedpdc = 0xff;
+ ivideo->detectedpdca = 0xff;
+ ivideo->detectedlcda = 0xff;
+
+ ivideo->sisfb_thismonitor.datavalid = FALSE;
+
+ ivideo->sisfb_parm_mem = sisfb_parm_mem;
+ ivideo->sisfb_accel = sisfb_accel;
+ ivideo->sisfb_ypan = sisfb_ypan;
+ ivideo->sisfb_max = sisfb_max;
+ ivideo->sisfb_userom = sisfb_userom;
+ ivideo->sisfb_useoem = sisfb_useoem;
+ ivideo->sisfb_mode_idx = sisfb_mode_idx;
+ ivideo->sisfb_parm_rate = sisfb_parm_rate;
+ ivideo->sisfb_crt1off = sisfb_crt1off;
+ ivideo->sisfb_forcecrt1 = sisfb_forcecrt1;
+ ivideo->sisfb_crt2type = sisfb_crt2type;
+ ivideo->sisfb_crt2flags = sisfb_crt2flags;
+ /* pdc(a), scalelcd, special timing, lvdshl handled below */
+ ivideo->sisfb_dstn = sisfb_dstn;
+ ivideo->sisfb_fstn = sisfb_fstn;
+ ivideo->sisfb_tvplug = sisfb_tvplug;
+ ivideo->sisfb_tvstd = sisfb_tvstd;
+ ivideo->tvxpos = sisfb_tvxposoffset;
+ ivideo->tvypos = sisfb_tvyposoffset;
+ ivideo->sisfb_filter = sisfb_filter;
+ ivideo->sisfb_nocrt2rate = sisfb_nocrt2rate;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- strcpy(sis_fb_info->modename, "SIS 661");
-#else
- strcpy(myid, "SIS 661");
+ ivideo->sisfb_inverse = sisfb_inverse;
#endif
- }
- sisvga_engine = SIS_315_VGA;
- sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
- sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+
+ ivideo->refresh_rate = 0;
+ if(ivideo->sisfb_parm_rate != -1) {
+ ivideo->refresh_rate = ivideo->sisfb_parm_rate;
+ }
+
+ ivideo->SiS_Pr.UsePanelScaler = sisfb_scalelcd;
+ ivideo->SiS_Pr.CenterScreen = -1;
+ ivideo->SiS_Pr.SiS_CustomT = sisfb_specialtiming;
+ ivideo->SiS_Pr.LVDSHL = sisfb_lvdshl;
+
+ ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
+ ivideo->SiS_Pr.SiS_CHOverScan = -1;
+ ivideo->SiS_Pr.SiS_ChSW = FALSE;
+ ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
+ ivideo->SiS_Pr.HaveEMI = FALSE;
+ ivideo->SiS_Pr.HaveEMILCD = FALSE;
+ ivideo->SiS_Pr.OverruleEMI = FALSE;
+ ivideo->SiS_Pr.SiS_SensibleSR11 = FALSE;
+ ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
+ ivideo->SiS_Pr.PDC = -1;
+ ivideo->SiS_Pr.PDCA = -1;
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->chip >= SIS_330) {
+ ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
+ if(ivideo->chip >= SIS_661) {
+ ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
+ }
+ }
+#endif
+
+ memcpy(&ivideo->default_var, &my_default_var, sizeof(my_default_var));
+
+ pci_set_drvdata(pdev, ivideo);
+
+ /* Patch special cases */
+ if((ivideo->nbridge = sisfb_get_northbridge(ivideo->chip))) {
+ switch(ivideo->nbridge->device) {
+#ifdef CONFIG_FB_SIS_300
+ case PCI_DEVICE_ID_SI_730:
+ ivideo->chip = SIS_730;
+ strcpy(ivideo->myid, "SiS 730");
+ break;
+#endif
+#ifdef CONFIG_FB_SIS_315
+ case PCI_DEVICE_ID_SI_651:
+ /* ivideo->chip is ok */
+ strcpy(ivideo->myid, "SiS 651");
+ break;
+ case PCI_DEVICE_ID_SI_740:
+ ivideo->chip = SIS_740;
+ strcpy(ivideo->myid, "SiS 740");
+ break;
+ case PCI_DEVICE_ID_SI_661:
+ ivideo->chip = SIS_661;
+ strcpy(ivideo->myid, "SiS 661");
+ break;
+ case PCI_DEVICE_ID_SI_741:
+ ivideo->chip = SIS_741;
+ strcpy(ivideo->myid, "SiS 741");
+ break;
+ case PCI_DEVICE_ID_SI_760:
+ ivideo->chip = SIS_760;
+ strcpy(ivideo->myid, "SiS 760");
break;
- }
#endif
- default:
- kfree(sis_fb_info);
- return -ENODEV;
+ }
}
- sishw_ext.jChipType = ivideo.chip;
- /* for Debug */
- if( (sishw_ext.jChipType == SIS_315PRO) ||
- (sishw_ext.jChipType == SIS_315) )
- sishw_ext.jChipType = SIS_315H;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ strcpy(sis_fb_info->modename, ivideo->myid);
+#endif
+
+ ivideo->sishw_ext.jChipType = ivideo->chip;
- ivideo.video_base = pci_resource_start(pdev, 0);
- ivideo.mmio_base = pci_resource_start(pdev, 1);
- sishw_ext.ulIOAddress = SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
- ivideo.vga_base = (unsigned short) sishw_ext.ulIOAddress;
+#ifdef CONFIG_FB_SIS_315
+ if((ivideo->sishw_ext.jChipType == SIS_315PRO) ||
+ (ivideo->sishw_ext.jChipType == SIS_315)) {
+ ivideo->sishw_ext.jChipType = SIS_315H;
+ }
+#endif
- sisfb_mmio_size = pci_resource_len(pdev, 1);
+ ivideo->video_base = pci_resource_start(pdev, 0);
+ ivideo->mmio_base = pci_resource_start(pdev, 1);
+ ivideo->mmio_size = pci_resource_len(pdev, 1);
+ ivideo->SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
+ ivideo->sishw_ext.ulIOAddress = ivideo->vga_base = ivideo->SiS_Pr.RelIO;
if(!sisvga_enabled) {
- if(pci_enable_device(pdev)) {
- kfree(sis_fb_info);
- return -EIO;
- }
+ if(pci_enable_device(pdev)) {
+ pci_set_drvdata(pdev, NULL);
+ kfree(sis_fb_info);
+ return -EIO;
+ }
}
- SiS_Pr.SiS_Backup70xx = 0xff;
- SiS_Pr.SiS_CHOverScan = -1;
- SiS_Pr.SiS_ChSW = FALSE;
- SiS_Pr.SiS_UseLCDA = FALSE;
- SiS_Pr.HaveEMI = FALSE;
- SiS_Pr.HaveEMILCD = FALSE;
- SiS_Pr.OverruleEMI = FALSE;
- SiS_Pr.SiS_SensibleSR11 = FALSE;
- SiS_Pr.SiS_MyCR63 = 0x63;
- if(ivideo.chip >= SIS_661) {
- SiS_Pr.SiS_SensibleSR11 = TRUE;
- SiS_Pr.SiS_MyCR63 = 0x53;
- }
- SiSRegInit(&SiS_Pr, sishw_ext.ulIOAddress);
+ SiSRegInit(&ivideo->SiS_Pr, ivideo->sishw_ext.ulIOAddress);
#ifdef CONFIG_FB_SIS_300
- /* TW: Find PCI systems for Chrontel/GPIO communication setup */
- if(ivideo.chip == SIS_630) {
- int i=0;
+ /* Find PCI systems for Chrontel/GPIO communication setup */
+ if(ivideo->chip == SIS_630) {
+ i=0;
do {
- if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
- mychswtable[i].subsysCard == ivideo.subsysdevice) {
- SiS_Pr.SiS_ChSW = TRUE;
+ if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
+ mychswtable[i].subsysCard == ivideo->subsysdevice) {
+ ivideo->SiS_Pr.SiS_ChSW = TRUE;
printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
mychswtable[i].vendorName, mychswtable[i].cardName);
break;
}
#endif
- outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+ outSISIDXREG(SISSR, 0x05, 0x86);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#ifdef MODULE
+ if( (!sisvga_enabled)
+#if !defined(__i386__) && !defined(__x86_64__)
+ || (sisfb_resetcard)
+#endif
+ ) {
+ for(i = 0x30; i <= 0x3f; i++) {
+ outSISIDXREG(SISCR,i,0x00);
+ }
+ }
+
+ /* Find out about current video mode */
inSISIDXREG(SISCR,0x34,reg);
+ if(reg & 0x7f) {
+ ivideo->modeprechange = reg & 0x7f;
+ } else {
+ ivideo->modeprechange = 0x03;
+#if defined(__i386__) || defined(__x86_64__)
+ {
+ unsigned char *tt = ioremap(0, 0x1000);
+ if(tt) {
+ ivideo->modeprechange = tt[0x449];
+ iounmap(tt);
+ }
+ }
+#endif
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#ifdef MODULE
if((reg & 0x80) && (reg != 0xff)) {
- if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
+ if((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF) {
printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -EBUSY;
}
#endif
#endif
- if (sisvga_engine == SIS_315_VGA) {
- switch (ivideo.chip) {
- case SIS_315H:
- case SIS_315:
- case SIS_330:
- sishw_ext.bIntegratedMMEnabled = TRUE;
- break;
- case SIS_550:
- case SIS_650:
- case SIS_740:
- case SIS_661:
- case SIS_741:
- case SIS_660:
- case SIS_760:
- sishw_ext.bIntegratedMMEnabled = TRUE;
- break;
- default:
- break;
- }
- } else if (sisvga_engine == SIS_300_VGA) {
- if (ivideo.chip == SIS_300) {
- sishw_ext.bIntegratedMMEnabled = TRUE;
- } else {
- inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_1A, reg);
- if (reg & SIS_SCRATCH_REG_1A_MASK)
- sishw_ext.bIntegratedMMEnabled = TRUE;
- else
- sishw_ext.bIntegratedMMEnabled = FALSE;
- }
+ ivideo->sishw_ext.bIntegratedMMEnabled = TRUE;
+#ifdef CONFIG_FB_SIS_300
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->chip != SIS_300) {
+ inSISIDXREG(SISSR, 0x1a, reg);
+ if(!(reg & 0x10)) {
+ ivideo->sishw_ext.bIntegratedMMEnabled = FALSE;
+ }
+ }
}
+#endif
- if(sisfb_userom) {
- sishw_ext.pjVirtualRomBase = sis_find_rom();
- if(sishw_ext.pjVirtualRomBase) {
- printk(KERN_INFO "sisfb: Video ROM found and mapped to %p\n",
- sishw_ext.pjVirtualRomBase);
- sishw_ext.UseROM = TRUE;
+ ivideo->bios_vbase = ivideo->bios_abase = NULL;
+ if(ivideo->sisfb_userom) {
+ ivideo->sishw_ext.pjVirtualRomBase = sis_find_rom(pdev);
+#if defined(__i386__) || defined(__x86_64__)
+ ivideo->bios_vbase = ivideo->sishw_ext.pjVirtualRomBase; /* mapped */
+#else
+ ivideo->bios_abase = ivideo->sishw_ext.pjVirtualRomBase; /* allocated */
+#endif
+ if(ivideo->sishw_ext.pjVirtualRomBase) {
+ printk(KERN_INFO "sisfb: Video ROM found and %s to 0x%p\n",
+ ivideo->bios_vbase ? "mapped" : "copied",
+ ivideo->sishw_ext.pjVirtualRomBase);
+ ivideo->sishw_ext.UseROM = TRUE;
} else {
- sishw_ext.UseROM = FALSE;
+ ivideo->sishw_ext.UseROM = FALSE;
printk(KERN_INFO "sisfb: Video ROM not found\n");
}
} else {
- sishw_ext.pjVirtualRomBase = NULL;
- sishw_ext.UseROM = FALSE;
+ ivideo->sishw_ext.pjVirtualRomBase = NULL;
+ ivideo->sishw_ext.UseROM = FALSE;
printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
}
- sishw_ext.bSkipDramSizing = 0;
- sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space;
- sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
/* Find systems for special custom timing */
- if(SiS_Pr.SiS_CustomT == CUT_NONE) {
- int i=0, j;
+ if(ivideo->SiS_Pr.SiS_CustomT == CUT_NONE) {
+ int j;
unsigned char *biosver = NULL;
unsigned char *biosdate = NULL;
BOOLEAN footprint;
- unsigned long chksum = 0;
+ u32 chksum = 0;
- if(sishw_ext.UseROM) {
- biosver = sishw_ext.pjVirtualRomBase + 0x06;
- biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
- for(i=0; i<32768; i++) chksum += sishw_ext.pjVirtualRomBase[i];
+ if(ivideo->sishw_ext.UseROM) {
+ biosver = ivideo->sishw_ext.pjVirtualRomBase + 0x06;
+ biosdate = ivideo->sishw_ext.pjVirtualRomBase + 0x2c;
+ for(i=0; i<32768; i++) chksum += ivideo->sishw_ext.pjVirtualRomBase[i];
}
i=0;
do {
- if( (mycustomttable[i].chipID == ivideo.chip) &&
+ if( (mycustomttable[i].chipID == ivideo->chip) &&
((!strlen(mycustomttable[i].biosversion)) ||
- (sishw_ext.UseROM &&
+ (ivideo->sishw_ext.UseROM &&
(!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
((!strlen(mycustomttable[i].biosdate)) ||
- (sishw_ext.UseROM &&
+ (ivideo->sishw_ext.UseROM &&
(!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
((!mycustomttable[i].bioschksum) ||
- (sishw_ext.UseROM &&
+ (ivideo->sishw_ext.UseROM &&
(mycustomttable[i].bioschksum == chksum))) &&
- (mycustomttable[i].pcisubsysvendor == ivideo.subsysvendor) &&
- (mycustomttable[i].pcisubsyscard == ivideo.subsysdevice) ) {
+ (mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
+ (mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
footprint = TRUE;
- for(j=0; j<5; j++) {
+ for(j = 0; j < 5; j++) {
if(mycustomttable[i].biosFootprintAddr[j]) {
- if(sishw_ext.UseROM) {
- if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
- mycustomttable[i].biosFootprintData[j])
- footprint = FALSE;
+ if(ivideo->sishw_ext.UseROM) {
+ if(ivideo->sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
+ mycustomttable[i].biosFootprintData[j]) {
+ footprint = FALSE;
+ }
} else footprint = FALSE;
}
}
if(footprint) {
- SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+ ivideo->SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
mycustomttable[i].vendorName,
mycustomttable[i].cardName);
}
#ifdef CONFIG_FB_SIS_300
- /* Mode numbers for 1280x768 are different for 300 and 315 series */
- if(sisvga_engine == SIS_300_VGA) {
- sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
- sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
- sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
- sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
- }
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if( (!sisvga_enabled)
+#if !defined(__i386__) && !defined(__x86_64__)
+ || (sisfb_resetcard)
#endif
-
- sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
- if (sishw_ext.pSR == NULL) {
- printk(KERN_ERR "sisfb: Fatal error: Allocating SRReg space failed.\n");
- kfree(sis_fb_info);
- return -ENODEV;
- }
- sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF;
-
- sishw_ext.pCR = vmalloc(sizeof(SIS_DSReg) * CR_BUFFER_SIZE);
- if (sishw_ext.pCR == NULL) {
- vfree(sishw_ext.pSR);
- printk(KERN_ERR "sisfb: Fatal error: Allocating CRReg space failed.\n");
- kfree(sis_fb_info);
- return -ENODEV;
- }
- sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF;
-
-#ifdef CONFIG_FB_SIS_300
- if(sisvga_engine == SIS_300_VGA) {
- if(!sisvga_enabled) {
- /* Mapping Max FB Size for 300 Init */
- sishw_ext.pjVideoMemoryAddress = ioremap(ivideo.video_base, 0x4000000);
- if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
- outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
+ ) {
+ if(ivideo->chip == SIS_300) {
+ sisfb_post_sis300(pdev);
}
}
- if(sisfb_get_dram_size_300()) {
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
- printk(KERN_ERR "sisfb: Fatal error: Unable to determine RAM size\n");
- kfree(sis_fb_info);
- return -ENODEV;
- }
}
#endif
#ifdef CONFIG_FB_SIS_315
- if (sisvga_engine == SIS_315_VGA) {
- if (!sisvga_enabled) {
- /* Mapping Max FB Size for 315 Init */
- sishw_ext.pjVideoMemoryAddress = ioremap(ivideo.video_base, 0x8000000);
- if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
- outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
- sishw_ext.bSkipDramSizing = TRUE;
- sishw_ext.pSR[0].jIdx = 0x13;
- sishw_ext.pSR[1].jIdx = 0x14;
- sishw_ext.pSR[2].jIdx = 0xFF;
- inSISIDXREG(SISSR, 0x13, sishw_ext.pSR[0].jVal);
- inSISIDXREG(SISSR, 0x14, sishw_ext.pSR[1].jVal);
- sishw_ext.pSR[2].jVal = 0xFF;
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if( (!sisvga_enabled)
+#if !defined(__i386__) && !defined(__x86_64__)
+ || (sisfb_resetcard)
+#endif
+ ) {
+ if((ivideo->chip == SIS_315H) ||
+ (ivideo->chip == SIS_315) ||
+ (ivideo->chip == SIS_315PRO) ||
+ (ivideo->chip == SIS_330)) {
+ sisfb_post_sis315330(pdev);
}
}
- if(sisfb_get_dram_size_315()) {
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
- printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
- kfree(sis_fb_info);
- return -ENODEV;
- }
}
#endif
- if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+ if(sisfb_get_dram_size(ivideo)) {
+ printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ pci_set_drvdata(pdev, NULL);
+ kfree(sis_fb_info);
+ return -ENODEV;
+ }
+ if((ivideo->sisfb_mode_idx < 0) ||
+ ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
/* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
orSISIDXREG(SISSR, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
-
/* Enable 2D accelerator engine */
orSISIDXREG(SISSR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
-
}
- sishw_ext.ulVideoMemorySize = ivideo.video_size;
-
- if(sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
- if(sisfb_pdc) {
- SiS_Pr.PDC = sisfb_pdc;
- } else {
- SiS_Pr.PDC = 0;
+ if(sisfb_pdc != 0xff) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
+ else sisfb_pdc &= 0x1f;
+ ivideo->SiS_Pr.PDC = sisfb_pdc;
}
+#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+ if(sisfb_pdca != 0xff) ivideo->SiS_Pr.PDCA = sisfb_pdca & 0x1f;
+ }
+#endif
- if(!request_mem_region(ivideo.video_base, ivideo.video_size, "sisfb FB")) {
+ if(!request_mem_region(ivideo->video_base, ivideo->video_size, "sisfb FB")) {
printk(KERN_ERR "sisfb: Fatal error: Unable to reserve frame buffer memory\n");
printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -ENODEV;
}
- if(!request_mem_region(ivideo.mmio_base, sisfb_mmio_size, "sisfb MMIO")) {
+ if(!request_mem_region(ivideo->mmio_base, ivideo->mmio_size, "sisfb MMIO")) {
printk(KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
- release_mem_region(ivideo.video_base, ivideo.video_size);
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
+ release_mem_region(ivideo->video_base, ivideo->video_size);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -ENODEV;
}
- ivideo.video_vbase = sishw_ext.pjVideoMemoryAddress = ioremap(ivideo.video_base, ivideo.video_size);
- if(!ivideo.video_vbase) {
+ ivideo->video_vbase = (unsigned long)ioremap(ivideo->video_base, ivideo->video_size);
+ ivideo->sishw_ext.pjVideoMemoryAddress = (unsigned char *)ivideo->video_vbase;
+ if(!ivideo->video_vbase) {
printk(KERN_ERR "sisfb: Fatal error: Unable to map frame buffer memory\n");
- release_mem_region(ivideo.video_base, ivideo.video_size);
- release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
+ release_mem_region(ivideo->video_base, ivideo->video_size);
+ release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -ENODEV;
}
- ivideo.mmio_vbase = ioremap(ivideo.mmio_base, sisfb_mmio_size);
- if(!ivideo.mmio_vbase) {
+ ivideo->mmio_vbase = (unsigned long)ioremap(ivideo->mmio_base, ivideo->mmio_size);
+ if(!ivideo->mmio_vbase) {
printk(KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
- iounmap(ivideo.video_vbase);
- release_mem_region(ivideo.video_base, ivideo.video_size);
- release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
+ iounmap((void *)ivideo->video_vbase);
+ release_mem_region(ivideo->video_base, ivideo->video_size);
+ release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -ENODEV;
}
- printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
- ivideo.video_base, ivideo.video_vbase, ivideo.video_size / 1024);
+ printk(KERN_INFO "sisfb: Framebuffer at 0x%lx, mapped to 0x%lx, size %ldk\n",
+ ivideo->video_base, ivideo->video_vbase, ivideo->video_size / 1024);
- printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
- ivideo.mmio_base, ivideo.mmio_vbase, sisfb_mmio_size / 1024);
+ printk(KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
+ ivideo->mmio_base, ivideo->mmio_vbase, ivideo->mmio_size / 1024);
- if(sisfb_heap_init()) {
+ if((ivideo->havenoheap = sisfb_heap_init(ivideo))) {
printk(KERN_WARNING "sisfb: Failed to initialize offscreen memory heap\n");
}
- ivideo.mtrr = (unsigned int) 0;
+ /* Used for clearing the screen only, therefore respect our mem limit */
+ ivideo->sishw_ext.ulVideoMemorySize = ivideo->sisfb_mem;
+
+ ivideo->mtrr = 0;
- ivideo.vbflags = 0;
+ ivideo->vbflags = 0;
+ ivideo->lcddefmodeidx = DEFAULT_LCDMODE;
+ ivideo->tvdefmodeidx = DEFAULT_TVMODE;
+ ivideo->defmodeidx = DEFAULT_MODE;
- if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
+ ivideo->newrom = SiSDetermineROMLayout661(&ivideo->SiS_Pr, &ivideo->sishw_ext);
- sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
- sishw_ext.Is301BDH = FALSE;
- sishw_ext.usExternalChip = 0;
+ if((ivideo->sisfb_mode_idx < 0) ||
+ ((sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni]) != 0xFF)) {
- sisfb_sense_crt1();
+ sisfb_sense_crt1(ivideo);
- sisfb_get_VB_type();
+ sisfb_get_VB_type(ivideo);
- if(ivideo.vbflags & VB_VIDEOBRIDGE) {
- sisfb_detect_VB_connect();
+ if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+ sisfb_detect_VB_connect(ivideo);
}
- ivideo.currentvbflags = ivideo.vbflags & VB_VIDEOBRIDGE;
+ ivideo->currentvbflags = ivideo->vbflags & (VB_VIDEOBRIDGE | TV_STANDARD);
- if(ivideo.vbflags & VB_VIDEOBRIDGE) {
- if(sisfb_crt2type != -1) {
- if((sisfb_crt2type == CRT2_LCD) && (ivideo.vbflags & CRT2_LCD)) {
- ivideo.currentvbflags |= CRT2_LCD;
- } else if(sisfb_crt2type != CRT2_LCD) {
- ivideo.currentvbflags |= sisfb_crt2type;
+ if(ivideo->vbflags & VB_VIDEOBRIDGE) {
+ if(ivideo->sisfb_crt2type != -1) {
+ if((ivideo->sisfb_crt2type == CRT2_LCD) && (ivideo->vbflags & CRT2_LCD)) {
+ ivideo->currentvbflags |= CRT2_LCD;
+ } else if(ivideo->sisfb_crt2type != CRT2_LCD) {
+ ivideo->currentvbflags |= ivideo->sisfb_crt2type;
}
} else {
/* Chrontel 700x TV detection often unreliable, therefore use a
* different default order on such machines
*/
- if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
- if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
- else if(ivideo.vbflags & CRT2_TV) ivideo.currentvbflags |= CRT2_TV;
- else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+ if((ivideo->sisvga_engine == SIS_300_VGA) && (ivideo->vbflags & VB_CHRONTEL)) {
+ if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
+ else if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV;
+ else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
} else {
- if(ivideo.vbflags & CRT2_TV) ivideo.currentvbflags |= CRT2_TV;
- else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
- else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+ if(ivideo->vbflags & CRT2_TV) ivideo->currentvbflags |= CRT2_TV;
+ else if(ivideo->vbflags & CRT2_LCD) ivideo->currentvbflags |= CRT2_LCD;
+ else if(ivideo->vbflags & CRT2_VGA) ivideo->currentvbflags |= CRT2_VGA;
}
}
}
- if(ivideo.vbflags & CRT2_LCD) {
- inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+ if(ivideo->vbflags & CRT2_LCD) {
+ inSISIDXREG(SISCR, 0x36, reg);
reg &= 0x0f;
- if(sisvga_engine == SIS_300_VGA) {
- sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ ivideo->sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+ } else if(ivideo->chip >= SIS_661) {
+ ivideo->sishw_ext.ulCRT2LCDType = sis661paneltype[reg];
} else {
- sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+ ivideo->sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+ if((ivideo->chip == SIS_550) && (sisfb_fstn)) {
+ if((ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_2) &&
+ (ivideo->sishw_ext.ulCRT2LCDType != LCD_640x480_3)) {
+ ivideo->sishw_ext.ulCRT2LCDType = LCD_320x480;
+ }
+ }
+ }
+ if(ivideo->sishw_ext.ulCRT2LCDType == LCD_UNKNOWN) {
+ ivideo->sishw_ext.ulCRT2LCDType = LCD_1024x768;
+ printk(KERN_DEBUG "sisfb: Illegal panel ID (%02x), assuming 1024x768\n", reg);
+ }
+ for(i = 0; i < SIS_LCD_NUMBER; i++) {
+ if(ivideo->sishw_ext.ulCRT2LCDType == sis_lcd_data[i].lcdtype) {
+ ivideo->lcdxres = sis_lcd_data[i].xres;
+ ivideo->lcdyres = sis_lcd_data[i].yres;
+ ivideo->lcddefmodeidx = sis_lcd_data[i].default_mode_idx;
+ break;
+ }
+ }
+ if(ivideo->SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
+ ivideo->lcdxres = 1360; ivideo->lcdyres = 1024; ivideo->lcddefmodeidx = 99;
+ } else if(ivideo->SiS_Pr.SiS_CustomT == CUT_PANEL848) {
+ ivideo->lcdxres = 848; ivideo->lcdyres = 480; ivideo->lcddefmodeidx = 47;
}
+ printk(KERN_DEBUG "sisfb: Detected %dx%d flat panel\n",
+ ivideo->lcdxres, ivideo->lcdyres);
}
-
- sisfb_detectedpdc = 0;
#ifdef CONFIG_FB_SIS_300
/* Save the current PanelDelayCompensation if the LCD is currently used */
- if(sisvga_engine == SIS_300_VGA) {
- if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
+ if(ivideo->sisvga_engine == SIS_300_VGA) {
+ if(ivideo->vbflags & (VB_LVDS | VB_30xBDH)) {
int tmp;
inSISIDXREG(SISCR,0x30,tmp);
if(tmp & 0x20) {
/* Currently on LCD? If yes, read current pdc */
- inSISIDXREG(SISPART1,0x13,sisfb_detectedpdc);
- sisfb_detectedpdc &= 0x3c;
- if(SiS_Pr.PDC == 0) {
+ inSISIDXREG(SISPART1,0x13,ivideo->detectedpdc);
+ ivideo->detectedpdc &= 0x3c;
+ if(ivideo->SiS_Pr.PDC == -1) {
/* Let option override detection */
- SiS_Pr.PDC = sisfb_detectedpdc;
+ ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
}
- printk(KERN_INFO
- "sisfb: Detected LCD PanelDelayCompensation %d\n",
- sisfb_detectedpdc);
+ printk(KERN_INFO "sisfb: Detected LCD PDC 0x%02x\n",
+ ivideo->detectedpdc);
}
- if((SiS_Pr.PDC) && (SiS_Pr.PDC != sisfb_detectedpdc)) {
- printk(KERN_INFO
- "sisfb: Using LCD PanelDelayCompensation %d\n",
- SiS_Pr.PDC);
+ if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+ printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x\n",
+ ivideo->SiS_Pr.PDC);
}
}
}
#endif
- sisfb_detectedlcda = 0xff;
-
#ifdef CONFIG_FB_SIS_315
+ if(ivideo->sisvga_engine == SIS_315_VGA) {
+
+ /* Try to find about LCDA */
+ if(ivideo->vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
+ int tmp;
+ inSISIDXREG(SISPART1,0x13,tmp);
+ if(tmp & 0x04) {
+ ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
+ ivideo->detectedlcda = 0x03;
+ }
+ }
- if(sisvga_engine == SIS_315_VGA) {
/* Save PDC */
- if(ivideo.vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
+ if(ivideo->vbflags & (VB_301LV | VB_302LV | VB_302ELV)) {
int tmp;
inSISIDXREG(SISCR,0x30,tmp);
- if(tmp & 0x20) {
+ if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
/* Currently on LCD? If yes, read current pdc */
- inSISIDXREG(SISPART1,0x2D,sisfb_detectedpdc);
- if(SiS_Pr.PDC == 0) {
- /* Let option override detection */
- SiS_Pr.PDC = sisfb_detectedpdc;
+ u8 pdc;
+ inSISIDXREG(SISPART1,0x2D,pdc);
+ ivideo->detectedpdc = (pdc & 0x0f) << 1;
+ ivideo->detectedpdca = (pdc & 0xf0) >> 3;
+ inSISIDXREG(SISPART1,0x35,pdc);
+ ivideo->detectedpdc |= ((pdc >> 7) & 0x01);
+ inSISIDXREG(SISPART1,0x20,pdc);
+ ivideo->detectedpdca |= ((pdc >> 6) & 0x01);
+ if(ivideo->newrom) {
+ /* New ROM invalidates other PDC resp. */
+ if(ivideo->detectedlcda != 0xff) {
+ ivideo->detectedpdc = 0xff;
+ } else {
+ ivideo->detectedpdca = 0xff;
+ }
+ }
+ if(ivideo->SiS_Pr.PDC == -1) {
+ if(ivideo->detectedpdc != 0xff) {
+ ivideo->SiS_Pr.PDC = ivideo->detectedpdc;
+ }
+ }
+ if(ivideo->SiS_Pr.PDCA == -1) {
+ if(ivideo->detectedpdca != 0xff) {
+ ivideo->SiS_Pr.PDCA = ivideo->detectedpdca;
+ }
+ }
+ if(ivideo->detectedpdc != 0xff) {
+ printk(KERN_INFO
+ "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
+ ivideo->detectedpdc);
+ }
+ if(ivideo->detectedpdca != 0xff) {
+ printk(KERN_INFO
+ "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
+ ivideo->detectedpdca);
}
- printk(KERN_INFO
- "sisfb: Detected LCD PanelDelayCompensation %d\n",
- sisfb_detectedpdc);
- }
- if((SiS_Pr.PDC) && (SiS_Pr.PDC != sisfb_detectedpdc)) {
- printk(KERN_INFO
- "sisfb: Using LCD PanelDelayCompensation %d\n",
- SiS_Pr.PDC);
}
+
/* Save EMI */
- if(ivideo.vbflags & (VB_302LV | VB_302ELV)) {
- inSISIDXREG(SISPART4,0x30,SiS_Pr.EMI_30);
- inSISIDXREG(SISPART4,0x31,SiS_Pr.EMI_31);
- inSISIDXREG(SISPART4,0x32,SiS_Pr.EMI_32);
- inSISIDXREG(SISPART4,0x33,SiS_Pr.EMI_33);
- SiS_Pr.HaveEMI = TRUE;
- if(tmp & 0x20) SiS_Pr.HaveEMILCD = TRUE;
+ if(ivideo->vbflags & (VB_302LV | VB_302ELV)) {
+ inSISIDXREG(SISPART4,0x30,ivideo->SiS_Pr.EMI_30);
+ inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
+ inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
+ inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
+ ivideo->SiS_Pr.HaveEMI = TRUE;
+ if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
+ ivideo->SiS_Pr.HaveEMILCD = TRUE;
+ }
}
}
- /* Try to find about LCDA */
- if(ivideo.vbflags & (VB_301C | VB_302B | VB_301LV | VB_302LV | VB_302ELV)) {
- int tmp;
- inSISIDXREG(SISCR,0x34,tmp);
- if((tmp <= 0x13) || (tmp == 0xff)) {
- /* Currently on LCDA? (Some BIOSes leave CR38) */
- inSISIDXREG(SISCR,0x38,tmp);
- if((tmp & 0x03) == 0x03) SiS_Pr.SiS_UseLCDA = TRUE;
- else {
- /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
- inSISIDXREG(SISCR,0x35,tmp);
- if(tmp & 0x01) SiS_Pr.SiS_UseLCDA = TRUE;
- else {
- /* Currently on LCD? If so, we can find out
- * by peeking the mode register
- */
- inSISIDXREG(SISCR,0x30,tmp);
- if(tmp & 0x20) {
- inSISIDXREG(SISPART1,0x13,tmp);
- if(tmp & 0x04) SiS_Pr.SiS_UseLCDA = TRUE;
- }
- }
- }
+ /* Let user override detected PDCs (all bridges) */
+ if(ivideo->vbflags & (VB_301B | VB_301C | VB_301LV | VB_302LV | VB_302ELV)) {
+ if((ivideo->SiS_Pr.PDC != -1) && (ivideo->SiS_Pr.PDC != ivideo->detectedpdc)) {
+ printk(KERN_INFO "sisfb: Using LCD PDC 0x%02x (for LCD=CRT2)\n",
+ ivideo->SiS_Pr.PDC);
}
- if(SiS_Pr.SiS_UseLCDA) {
- sisfb_detectedlcda = 0x03;
- printk(KERN_DEBUG
- "sisfb: Bridge uses LCDA for low resolution and text modes\n");
+ if((ivideo->SiS_Pr.PDCA != -1) && (ivideo->SiS_Pr.PDCA != ivideo->detectedpdca)) {
+ printk(KERN_INFO "sisfb: Using LCD PDC1 0x%02x (for LCD=CRT1)\n",
+ ivideo->SiS_Pr.PDCA);
}
- }
+ }
+
}
#endif
- if (!sisfb_crt1off) {
- sisfb_handle_ddc(&sisfb_thismonitor, 0);
+ if(!ivideo->sisfb_crt1off) {
+ sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 0);
} else {
- if ((ivideo.vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
- (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
- sisfb_handle_ddc(&sisfb_thismonitor, 1);
+ if((ivideo->vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
+ (ivideo->vbflags & (CRT2_VGA | CRT2_LCD))) {
+ sisfb_handle_ddc(ivideo, &ivideo->sisfb_thismonitor, 1);
}
}
- if (sisfb_mode_idx >= 0)
- sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
+ if(ivideo->sisfb_mode_idx >= 0) {
+ int bu = ivideo->sisfb_mode_idx;
+ ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo,
+ ivideo->sisfb_mode_idx, ivideo->currentvbflags);
+ if(bu != ivideo->sisfb_mode_idx) {
+ printk(KERN_ERR "Mode %dx%dx%d failed validation\n",
+ sisbios_mode[bu].xres,
+ sisbios_mode[bu].yres,
+ sisbios_mode[bu].bpp);
+ }
+ }
- if (sisfb_mode_idx < 0) {
- switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+ if(ivideo->sisfb_mode_idx < 0) {
+ switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
case CRT2_LCD:
- sisfb_mode_idx = DEFAULT_LCDMODE;
+ ivideo->sisfb_mode_idx = ivideo->lcddefmodeidx;
break;
case CRT2_TV:
- sisfb_mode_idx = DEFAULT_TVMODE;
+ ivideo->sisfb_mode_idx = ivideo->tvdefmodeidx;
break;
default:
- sisfb_mode_idx = DEFAULT_MODE;
+ ivideo->sisfb_mode_idx = ivideo->defmodeidx;
break;
}
}
- sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
+ ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];
- if (ivideo.refresh_rate != 0)
- sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx);
+ if(ivideo->refresh_rate != 0) {
+ sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx);
+ }
- if (sisfb_rate_idx == 0) {
- sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
- ivideo.refresh_rate = 60;
+ if(ivideo->rate_idx == 0) {
+ ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;
+ ivideo->refresh_rate = 60;
}
- if (sisfb_thismonitor.datavalid) {
- if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
- sisfb_rate_idx, ivideo.refresh_rate)) {
+ if(ivideo->sisfb_thismonitor.datavalid) {
+ if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,
+ ivideo->rate_idx, ivideo->refresh_rate)) {
printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
}
}
- ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
- ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
- ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
- ivideo.org_x = ivideo.org_y = 0;
- ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
+ ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;
+ ivideo->video_width = sisbios_mode[ivideo->sisfb_mode_idx].xres;
+ ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;
- sisfb_set_vparms();
+ sisfb_set_vparms(ivideo);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/* ---------------- For 2.4: Now switch the mode ------------------ */
printk(KERN_INFO "sisfb: Mode is %dx%dx%d (%dHz)\n",
- ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
- ivideo.refresh_rate);
+ ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+ ivideo->refresh_rate);
- sisfb_pre_setmode();
+ sisfb_pre_setmode(ivideo);
- if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
+ if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {
printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
- sisfb_mode_no);
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
- release_mem_region(ivideo.video_base, ivideo.video_size);
- release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+ ivideo->mode_no);
+ iounmap((void *)ivideo->video_vbase);
+ iounmap((void *)ivideo->mmio_vbase);
+ release_mem_region(ivideo->video_base, ivideo->video_size);
+ release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -EINVAL;
}
outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
- sisfb_post_setmode();
-
- ivideo.accel = 0;
- if(sisfb_accel) {
- ivideo.accel = -1;
- default_var.accel_flags |= FB_ACCELF_TEXT;
- sisfb_initaccel();
- }
+ sisfb_post_setmode(ivideo);
/* Maximize regardless of sisfb_max at startup */
- default_var.yres_virtual = 32767;
- sisfb_crtc_to_var(&default_var);
+ ivideo->default_var.yres_virtual = 32767;
+
+ /* Force reset of x virtual in crtc_to_var */
+ ivideo->default_var.xres_virtual = 0;
+
+ sisfb_crtc_to_var(ivideo, &ivideo->default_var);
+
+ sisfb_calc_pitch(ivideo, &ivideo->default_var);
+ sisfb_set_pitch(ivideo);
+
+ ivideo->accel = 0;
+ if(ivideo->sisfb_accel) {
+ ivideo->accel = -1;
+ ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+ }
+ sisfb_initaccel(ivideo);
- sis_fb_info->node = -1;
+ sis_fb_info->node = -1;
sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
- sis_fb_info->blank = &sisfb_blank;
sis_fb_info->fbops = &sisfb_ops;
+ sis_fb_info->disp = &ivideo->sis_disp;
+ sis_fb_info->blank = &sisfb_blank;
sis_fb_info->switch_con = &sisfb_switch;
- sis_fb_info->updatevar = &sisfb_update_var;
- sis_fb_info->changevar = NULL;
- sis_fb_info->disp = &sis_disp;
+ sis_fb_info->updatevar = &sisfb_update_var;
+ sis_fb_info->changevar = NULL;
strcpy(sis_fb_info->fontname, sisfb_fontname);
- sisfb_set_disp(-1, &default_var, sis_fb_info);
+ sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info);
-#else /* --------- For 2.5: Setup a somewhat sane default var ------------ */
+#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
- ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
- ivideo.refresh_rate);
+ ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
+ ivideo->refresh_rate);
- default_var.xres = default_var.xres_virtual = ivideo.video_width;
- default_var.yres = default_var.yres_virtual = ivideo.video_height;
- default_var.bits_per_pixel = ivideo.video_bpp;
+ ivideo->default_var.xres = ivideo->default_var.xres_virtual = ivideo->video_width;
+ ivideo->default_var.yres = ivideo->default_var.yres_virtual = ivideo->video_height;
+ ivideo->default_var.bits_per_pixel = ivideo->video_bpp;
- sisfb_bpp_to_var(&default_var);
+ sisfb_bpp_to_var(ivideo, &ivideo->default_var);
- default_var.pixclock = (u32) (1000000000 /
- sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
- sisfb_mode_no, sisfb_rate_idx));
+ ivideo->default_var.pixclock = (u32) (1000000000 /
+ sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+ ivideo->mode_no, ivideo->rate_idx));
- if(sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
- sisfb_mode_no, sisfb_rate_idx,
- &default_var.left_margin, &default_var.right_margin,
- &default_var.upper_margin, &default_var.lower_margin,
- &default_var.hsync_len, &default_var.vsync_len,
- &default_var.sync, &default_var.vmode)) {
- if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- default_var.pixclock <<= 1;
+ if(sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,
+ ivideo->mode_no, ivideo->rate_idx, &ivideo->default_var)) {
+ if((ivideo->default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+ ivideo->default_var.pixclock <<= 1;
}
}
- ivideo.accel = 0;
- if(sisfb_accel) {
- ivideo.accel = -1;
- default_var.accel_flags |= FB_ACCELF_TEXT;
- sisfb_initaccel();
- }
-
- if(sisfb_ypan) {
+ if(ivideo->sisfb_ypan) {
/* Maximize regardless of sisfb_max at startup */
- default_var.yres_virtual =
- ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
- if(default_var.yres_virtual > 32767) default_var.yres_virtual = 32767;
- if(default_var.yres_virtual <= default_var.yres) {
- default_var.yres_virtual = default_var.yres;
+ ivideo->default_var.yres_virtual = sisfb_calc_maxyres(ivideo, &ivideo->default_var);
+ if(ivideo->default_var.yres_virtual < ivideo->default_var.yres) {
+ ivideo->default_var.yres_virtual = ivideo->default_var.yres;
}
}
+ sisfb_calc_pitch(ivideo, &ivideo->default_var);
+
+ ivideo->accel = 0;
+ if(ivideo->sisfb_accel) {
+ ivideo->accel = -1;
+#ifdef STUPID_ACCELF_TEXT_SHIT
+ ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
+#endif
+ }
+ sisfb_initaccel(ivideo);
+
+#if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
+ sis_fb_info->flags = FBINFO_DEFAULT |
+ FBINFO_HWACCEL_YPAN |
+ FBINFO_HWACCEL_XPAN |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT |
+ ((ivideo->accel) ? 0 : FBINFO_HWACCEL_DISABLED);
+#else
sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
- sis_fb_info->var = default_var;
- sis_fb_info->fix = sisfb_fix;
- sis_fb_info->par = &ivideo;
- sis_fb_info->screen_base = ivideo.video_vbase;
- sis_fb_info->fbops = &sisfb_ops;
-#ifdef NEWFBDEV
- sis_fb_info->class_dev.dev = &pdev->dev;
#endif
+ sis_fb_info->var = ivideo->default_var;
+ sis_fb_info->fix = ivideo->sisfb_fix;
+ sis_fb_info->screen_base = (char *)ivideo->video_vbase;
+ sis_fb_info->fbops = &sisfb_ops;
+
sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
- sis_fb_info->pseudo_palette = pseudo_palette;
+ sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
-#endif
+#endif /* 2.6 */
- printk(KERN_INFO "sisfb: Initial vbflags 0x%lx\n", ivideo.vbflags);
+ printk(KERN_DEBUG "sisfb: Initial vbflags 0x%lx\n", (unsigned long)ivideo->vbflags);
#ifdef CONFIG_MTRR
- ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
- (unsigned int) ivideo.video_size,
- MTRR_TYPE_WRCOMB, 1);
- if(ivideo.mtrr) {
- printk(KERN_INFO "sisfb: Added MTRRs\n");
+ ivideo->mtrr = mtrr_add(ivideo->video_base, ivideo->video_size,
+ MTRR_TYPE_WRCOMB, 1);
+ if(!ivideo->mtrr) {
+ printk(KERN_DEBUG "sisfb: Failed to add MTRRs\n");
}
-
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#endif
if(register_framebuffer(sis_fb_info) < 0) {
- vfree(sishw_ext.pSR);
- vfree(sishw_ext.pCR);
- release_mem_region(ivideo.video_base, ivideo.video_size);
- release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
+ iounmap((void *)ivideo->video_vbase);
+ iounmap((void *)ivideo->mmio_vbase);
+ release_mem_region(ivideo->video_base, ivideo->video_size);
+ release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -EINVAL;
}
- sisfb_registered = 1;
+ ivideo->registered = 1;
- printk(KERN_DEBUG "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
- printk(KERN_DEBUG "sisfb: Installed SISFB_GET_VBRSTATUS ioctl (%x)\n", SISFB_GET_VBRSTATUS);
-
- printk(KERN_INFO "sisfb: 2D acceleration is %s, scrolling mode %s\n",
- sisfb_accel ? "enabled" : "disabled",
- sisfb_ypan ? (sisfb_max ? "ypan (auto-max)" : "ypan (no auto-max)") : "redraw");
+ /* Enlist us */
+ ivideo->next = card_list;
+ card_list = ivideo;
+
+#ifdef SIS_CONFIG_COMPAT
+ {
+ int ret;
+ /* Our ioctls are all "32/64bit compatible" */
+ if(register_ioctl32_conversion(FBIOGET_VBLANK, NULL)) {
+ printk(KERN_ERR "sisfb: Error registering FBIOGET_VBLANK ioctl32 translation\n");
+ } else {
+ ivideo->ioctl32vblankregistered = 1;
+ }
+ ret = register_ioctl32_conversion(FBIO_ALLOC, NULL);
+ ret |= register_ioctl32_conversion(FBIO_FREE, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_INFO_SIZE, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_INFO, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_TVPOSOFFSET, NULL);
+ ret |= register_ioctl32_conversion(SISFB_SET_TVPOSOFFSET, NULL);
+ ret |= register_ioctl32_conversion(SISFB_SET_LOCK, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_VBRSTATUS, NULL);
+ ret |= register_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE, NULL);
+ ret |= register_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE, NULL);
+ if(ret) printk(KERN_ERR "sisfb: Error registering ioctl32 translations\n");
+ else ivideo->ioctl32registered = 1;
+ }
+#endif
+ printk(KERN_INFO "sisfb: 2D acceleration is %s, y-panning %s\n",
+ ivideo->sisfb_accel ? "enabled" : "disabled",
+ ivideo->sisfb_ypan ?
+ (ivideo->sisfb_max ? "enabled (auto-max)" : "enabled (no auto-max)") : "disabled");
+
+
+ printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%d\n",
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
- GET_FB_IDX(sis_fb_info->node), sis_fb_info->modename, VER_MAJOR, VER_MINOR,
- VER_LEVEL);
+ GET_FB_IDX(sis_fb_info->node),
#else
- printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
- sis_fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+ sis_fb_info->node,
#endif
+ ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
printk(KERN_INFO "sisfb: (C) 2001-2004 Thomas Winischhofer.\n");
} /* if mode = "none" */
+
return 0;
}
+/*****************************************************/
+/* PCI DEVICE HANDLING */
+/*****************************************************/
+
+static void __devexit sisfb_remove(struct pci_dev *pdev)
+{
+ struct sis_video_info *ivideo = pci_get_drvdata(pdev);
+ struct fb_info *sis_fb_info = ivideo->memyselfandi;
+ int registered = ivideo->registered;
+
+#ifdef SIS_CONFIG_COMPAT
+ if(ivideo->ioctl32vblankregistered) {
+ if(unregister_ioctl32_conversion(FBIOGET_VBLANK)) {
+ printk(KERN_ERR "sisfb: Error unregistering FBIOGET_VBLANK ioctl32 translation\n");
+ }
+ }
+ if(ivideo->ioctl32registered) {
+ int ret;
+ ret = unregister_ioctl32_conversion(FBIO_ALLOC);
+ ret |= unregister_ioctl32_conversion(FBIO_FREE);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_INFO_SIZE);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_INFO);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_TVPOSOFFSET);
+ ret |= unregister_ioctl32_conversion(SISFB_SET_TVPOSOFFSET);
+ ret |= unregister_ioctl32_conversion(SISFB_SET_LOCK);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_VBRSTATUS);
+ ret |= unregister_ioctl32_conversion(SISFB_GET_AUTOMAXIMIZE);
+ ret |= unregister_ioctl32_conversion(SISFB_SET_AUTOMAXIMIZE);
+ if(ret) printk(KERN_ERR "sisfb: Error unregistering ioctl32 translations\n");
+ }
+#endif
+
+ /* Unmap */
+ iounmap((void *)ivideo->video_vbase);
+ iounmap((void *)ivideo->mmio_vbase);
+ if(ivideo->bios_vbase) iounmap(ivideo->bios_vbase);
+ if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+
+ /* Release mem regions */
+ release_mem_region(ivideo->video_base, ivideo->video_size);
+ release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
+
+#ifdef CONFIG_MTRR
+ /* Release MTRR region */
+ if(ivideo->mtrr) {
+ mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);
+ }
+#endif
+
+ /* Unregister the framebuffer */
+ if(ivideo->registered) {
+ unregister_framebuffer(sis_fb_info);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,3))
+ framebuffer_release(sis_fb_info);
+#else
+ kfree(sis_fb_info);
+#endif
+ }
+
+ pci_set_drvdata(pdev, NULL);
+
+ /* TODO: Restore the initial mode
+ * This sounds easy but is as good as impossible
+ * on many machines with SiS chip and video bridge
+ * since text modes are always set up differently
+ * from machine to machine. Depends on the type
+ * of integration between chipset and bridge.
+ */
+ if(registered) {
+ printk(KERN_INFO "sisfb: Restoring of text mode not supported yet\n");
+ }
+};
+
+static struct pci_driver sisfb_driver = {
+ .name = "sisfb",
+ .id_table = sisfb_pci_table,
+ .probe = sisfb_probe,
+ .remove = __devexit_p(sisfb_remove)
+};
+
+int __init sisfb_init(void)
+{
+ return(pci_module_init(&sisfb_driver));
+}
+
+/*****************************************************/
+/* MODULE */
+/*****************************************************/
#ifdef MODULE
static unsigned int mem = 0;
static char *forcecrt2type = NULL;
static int forcecrt1 = -1;
-static char *queuemode = NULL;
-static int pdc = 0;
+static int pdc = -1;
+static int pdc1 = -1;
static int noaccel = -1;
static int noypan = -1;
static int nomax = -1;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static int inverse = 0;
#endif
-static int userom = 1;
+static int userom = -1;
static int useoem = -1;
static char *tvstandard = NULL;
static int nocrt2rate = 0;
static int scalelcd = -1;
static char *specialtiming = NULL;
static int lvdshl = -1;
+static int tvxposoffset = 0, tvyposoffset = 0;
+static int filter = -1;
+#if !defined(__i386__) && !defined(__x86_64__)
+static int resetcard = 0;
+static int videoram = 0;
+#endif
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/651/661/740/741/330/760 framebuffer driver");
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device driver");
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
+MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>, Others");
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+MODULE_PARM(mem, "i");
+MODULE_PARM(noaccel, "i");
+MODULE_PARM(noypan, "i");
+MODULE_PARM(nomax, "i");
+MODULE_PARM(userom, "i");
+MODULE_PARM(useoem, "i");
MODULE_PARM(mode, "s");
-MODULE_PARM_DESC(mode,
- "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
- "1024x768x16. Other formats supported include XxY-Depth and\n"
- "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
- "number, it will be interpreted as a VESA mode number. (default: none if\n"
- "sisfb is a module; this leaves the console untouched and the driver will\n"
- "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
- "is in the kernel)");
+MODULE_PARM(vesa, "i");
+MODULE_PARM(rate, "i");
+MODULE_PARM(forcecrt1, "i");
+MODULE_PARM(forcecrt2type, "s");
+MODULE_PARM(scalelcd, "i");
+MODULE_PARM(pdc, "i");
+MODULE_PARM(pdc1, "i");
+MODULE_PARM(specialtiming, "s");
+MODULE_PARM(lvdshl, "i");
+MODULE_PARM(tvstandard, "s");
+MODULE_PARM(tvxposoffset, "i");
+MODULE_PARM(tvyposoffset, "i");
+MODULE_PARM(filter, "i");
+MODULE_PARM(nocrt2rate, "i");
+MODULE_PARM(inverse, "i");
+#if !defined(__i386__) && !defined(__x86_64__)
+MODULE_PARM(resetcard, "i");
+MODULE_PARM(videoram, "i");
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-MODULE_PARM(mode, "s");
-MODULE_PARM_DESC(mode,
- "\nSelects the desired default display mode in the format XxYxDepth,\n"
- "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
- "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
- "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+module_param(mem, int, 0);
+module_param(noaccel, int, 0);
+module_param(noypan, int, 0);
+module_param(nomax, int, 0);
+module_param(userom, int, 0);
+module_param(useoem, int, 0);
+module_param(mode, charp, 0);
+module_param(vesa, int, 0);
+module_param(rate, int, 0);
+module_param(forcecrt1, int, 0);
+module_param(forcecrt2type, charp, 0);
+module_param(scalelcd, int, 0);
+module_param(pdc, int, 0);
+module_param(pdc1, int, 0);
+module_param(specialtiming, charp, 0);
+module_param(lvdshl, int, 0);
+module_param(tvstandard, charp, 0);
+module_param(tvxposoffset, int, 0);
+module_param(tvyposoffset, int, 0);
+module_param(filter, int, 0);
+module_param(nocrt2rate, int, 0);
+#if !defined(__i386__) && !defined(__x86_64__)
+module_param(resetcard, int, 0);
+module_param(videoram, int, 0);
+#endif
+#endif
+
+MODULE_PARM_DESC(mem,
+ "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
+ "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
+ "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
+ "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
+ "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
+ "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
+ "for XFree86 4.x/X.org 6.7 and later.\n");
+
+MODULE_PARM_DESC(noaccel,
+ "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
+ "(default: 0)\n");
+
+MODULE_PARM_DESC(noypan,
+ "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
+ "will be performed by redrawing the screen. (default: 0)\n");
+
+MODULE_PARM_DESC(nomax,
+ "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
+ "memory for the virtual screen in order to optimize scrolling performance. If\n"
+ "this is set to anything other than 0, sisfb will not do this and thereby \n"
+ "enable the user to positively specify a virtual Y size of the screen using\n"
+ "fbset. (default: 0)\n");
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM(vesa, "i");
+MODULE_PARM_DESC(mode,
+ "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
+ "1024x768x16. Other formats supported include XxY-Depth and\n"
+ "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+ "number, it will be interpreted as a VESA mode number. (default: none if\n"
+ "sisfb is a module; this leaves the console untouched and the driver will\n"
+ "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
+ "is in the kernel)\n");
MODULE_PARM_DESC(vesa,
- "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
- "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
- "and the driver will only do the video memory management for eg. DRM/DRI;\n"
- "0x0103 if sisfb is in the kernel)");
+ "\nSelects the desired display mode by VESA defined mode number, eg. 0x117\n"
+ "(default: 0x0000 if sisfb is a module; this leaves the console untouched\n"
+ "and the driver will only do the video memory management for eg. DRM/DRI;\n"
+ "0x0103 if sisfb is in the kernel)\n");
#endif
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-MODULE_PARM(vesa, "i");
+MODULE_PARM_DESC(mode,
+ "\nSelects the desired default display mode in the format XxYxDepth,\n"
+ "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
+ "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+ "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
+
MODULE_PARM_DESC(vesa,
"\nSelects the desired default display mode by VESA defined mode number, eg.\n"
- "0x117 (default: 0x0103)");
+ "0x117 (default: 0x0103)\n");
#endif
-MODULE_PARM(rate, "i");
MODULE_PARM_DESC(rate,
"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
"If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
- "will be ignored (default: 60)");
-
-MODULE_PARM(crt1off, "i");
-MODULE_PARM_DESC(crt1off,
- "(Deprecated, please use forcecrt1)");
+ "will be ignored (default: 60)\n");
-MODULE_PARM(filter, "i");
-MODULE_PARM_DESC(filter,
- "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
- "(Possible values 0-7, default: [no filter])");
-
-MODULE_PARM(queuemode, "s");
-MODULE_PARM_DESC(queuemode,
- "\nSelects the queue mode on 315/550/65x/74x/330/760. Possible choices are AGP, VRAM,\n"
- "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
- "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
- "require a totally different way of programming the engines. If any mode than\n"
- "MMIO is selected, sisfb will disable its own 2D acceleration. On\n"
- "300/540/630/730, this option is ignored. (default: MMIO)");
-
-/* TW: "Import" the options from the X driver */
-MODULE_PARM(mem, "i");
-MODULE_PARM_DESC(mem,
- "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
- "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
- "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
- "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
- "otherwise at 12288KB. On 315 and Xabre series, the heap is 1MB by default. The\n"
- "value is to be specified without 'KB' and should match the MaxXFBMem setting for\n"
- "XFree 4.x (x>=2).");
+MODULE_PARM_DESC(forcecrt1,
+ "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
+ "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
+ "0=CRT1 OFF) (default: [autodetected])\n");
-MODULE_PARM(forcecrt2type, "s");
MODULE_PARM_DESC(forcecrt2type,
"\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
"LCD, TV or secondary VGA. With this option, this autodetection can be\n"
"overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
- "On systems with a 301(B/LV) bridge, parameters SVIDEO, COMPOSITE or SCART can be\n"
- "used instead of TV to override the TV detection. (default: [autodetected])");
+ "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
+ "be used instead of TV to override the TV detection. Furthermore, on systems\n"
+ "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
+ "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
+ "depends on the very hardware in use. (default: [autodetected])\n");
-MODULE_PARM(forcecrt1, "i");
-MODULE_PARM_DESC(forcecrt1,
- "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
- "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
- " 0=CRT1 off) (default: [autodetected])");
+MODULE_PARM_DESC(scalelcd,
+ "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
+ "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
+ "show black bars around the image, TMDS panels will probably do the scaling\n"
+ "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
-MODULE_PARM(pdc, "i");
MODULE_PARM_DESC(pdc,
"\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
"should detect this correctly in most cases; however, sometimes this is not\n"
"possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
- "on a 300 series chipset; 3 or 51 on a 315 series chipset. If the problem persists,\n"
+ "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
"try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
- "and value from 0 to 255). (default: [autodetected])");
+ "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel,
- "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
- "(default: 0)");
+#ifdef CONFIG_FB_SIS_315
+MODULE_PARM_DESC(pdc1,
+ "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
+ "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
+ "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
+ "implemented yet.\n");
+#endif
-MODULE_PARM(noypan, "i");
-MODULE_PARM_DESC(noypan,
- "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
- "will be performed by redrawing the screen. (default: 0)");
+MODULE_PARM_DESC(specialtiming,
+ "\nPlease refer to documentation for more information on this option.\n");
-MODULE_PARM(nomax, "i");
-MODULE_PARM_DESC(nomax,
- "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
- "memory for the virtual screen in order to optimize scrolling performance. If this\n"
- "is set to anything other than 0, sisfb will not do this and thereby enable the user\n"
- "to positively specify a virtual Y size of the screen using fbset. (default: 0)\n");
+MODULE_PARM_DESC(lvdshl,
+ "\nPlease refer to documentation for more information on this option.\n");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-MODULE_PARM(inverse, "i");
-MODULE_PARM_DESC(inverse,
- "\nSetting this to anything but 0 should invert the display colors, but this\n"
- "does not seem to work. (default: 0)");
-#endif
+MODULE_PARM_DESC(tvstandard,
+ "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
+ "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
-MODULE_PARM(userom, "i");
-MODULE_PARM_DESC(userom,
- "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
- "for some LCD and TV setup. (default: 1)");
+MODULE_PARM_DESC(tvxposoffset,
+ "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
+ "Default: 0\n");
-MODULE_PARM(useoem, "i");
-MODULE_PARM_DESC(useoem,
- "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
- "panels and TV connector types. (default: [auto])");
+MODULE_PARM_DESC(tvyposoffset,
+ "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
+ "Default: 0\n");
-MODULE_PARM(tvstandard, "s");
-MODULE_PARM_DESC(tvstandard,
- "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
- "pal and ntsc. (default: [auto])");
+MODULE_PARM_DESC(filter,
+ "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
+ "(Possible values 0-7, default: [no filter])\n");
-MODULE_PARM(nocrt2rate, "i");
MODULE_PARM_DESC(nocrt2rate,
"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
- "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)");
-
-MODULE_PARM(scalelcd, "i");
-MODULE_PARM_DESC(scalelcd,
- "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
- "native resolution. Setting it to 0 will disable scaling; if the panel can scale\n"
- "by itself, it will probably do this, otherwise you will see a black bar around\n"
- "the screen image. Default: [autodetect if panel can scale]");
-
-MODULE_PARM(specialtiming, "s");
+ "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
-MODULE_PARM(lvdshl, "i");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+MODULE_PARM_DESC(inverse,
+ "\nSetting this to anything but 0 should invert the display colors, but this\n"
+ "does not seem to work. (default: 0)\n");
+#endif
+#if !defined(__i386__) && !defined(__x86_64__)
+#ifdef CONFIG_FB_SIS_300
+MODULE_PARM_DESC(resetcard,
+ "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
+ "the BIOS did not POST the card (only supported for SiS 300/305 currently).\n"
+ "Default: 0\n");
+
+MODULE_PARM_DESC(videoram,
+ "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
+ "some non-x86 architectures where the memory auto detection fails. Only\n"
+ "relevant if resetcard is set, too. Default: [auto-detect]\n");
+#endif
+#endif
-int init_module(void)
+int __init sisfb_init_module(void)
{
- int err;
+ sisfb_setdefaultparms();
- SiS_Pr.UsePanelScaler = -1;
- SiS_Pr.SiS_CustomT = CUT_NONE;
- SiS_Pr.LVDSHL = -1;
-
- ivideo.refresh_rate = sisfb_parm_rate = rate;
+ if(rate) sisfb_parm_rate = rate;
if((scalelcd == 0) || (scalelcd == 1)) {
- SiS_Pr.UsePanelScaler = scalelcd ^ 1;
+ sisfb_scalelcd = scalelcd ^ 1;
}
- if(mode)
- sisfb_search_mode(mode, FALSE);
- else if(vesa != -1)
- sisfb_search_vesamode(vesa, FALSE);
- else
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- /* For 2.4, set mode=none if no mode is given */
- sisfb_mode_idx = MODE_INDEX_NONE;
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- /* For 2.5, we don't need this "mode=none" stuff anymore */
- sisfb_mode_idx = DEFAULT_MODE;
-#endif
+ /* Need to check crt2 type first for fstn/dstn */
if(forcecrt2type)
sisfb_search_crt2type(forcecrt2type);
if(tvstandard)
sisfb_search_tvstd(tvstandard);
- if(crt1off == 0)
- sisfb_crt1off = 1;
- else
- sisfb_crt1off = 0;
+ if(mode)
+ sisfb_search_mode(mode, FALSE);
+ else if(vesa != -1)
+ sisfb_search_vesamode(vesa, FALSE);
+
+ sisfb_crt1off = (crt1off == 0) ? 1 : 0;
sisfb_forcecrt1 = forcecrt1;
- if(forcecrt1 == 1)
- sisfb_crt1off = 0;
- else if(forcecrt1 == 0)
- sisfb_crt1off = 1;
+ if(forcecrt1 == 1) sisfb_crt1off = 0;
+ else if(forcecrt1 == 0) sisfb_crt1off = 1;
if(noaccel == 1) sisfb_accel = 0;
else if(noaccel == 0) sisfb_accel = 1;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
if(inverse) sisfb_inverse = 1;
- sisfb_fontname[0] = '\0';
#endif
- if(mem) sisfb_mem = mem;
+ if(mem) sisfb_parm_mem = mem;
- sisfb_userom = userom;
+ if(userom != -1) sisfb_userom = userom;
+ if(useoem != -1) sisfb_useoem = useoem;
- sisfb_useoem = useoem;
-
- if (queuemode) sisfb_search_queuemode(queuemode);
-
- /* If other queuemode than MMIO, disable 2D accel and ypan */
- if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
- sisfb_accel = 0;
- }
-
- if(pdc) sisfb_pdc = pdc & 0x3c;
+ if(pdc != -1) sisfb_pdc = (pdc & 0x7f);
+ if(pdc1 != -1) sisfb_pdca = (pdc1 & 0x1f);
sisfb_nocrt2rate = nocrt2rate;
if(specialtiming)
sisfb_search_specialtiming(specialtiming);
- if((lvdshl >= 0) && (lvdshl <= 3)) SiS_Pr.LVDSHL = lvdshl;
-
- if((err = sisfb_init()) < 0) return err;
+ if((lvdshl >= 0) && (lvdshl <= 3)) sisfb_lvdshl = lvdshl;
- return 0;
-}
+ if(filter != -1) sisfb_filter = filter;
-void cleanup_module(void)
-{
- /* Unmap */
- iounmap(ivideo.video_vbase);
- iounmap(ivideo.mmio_vbase);
+ sisfb_tvxposoffset = tvxposoffset;
+ sisfb_tvyposoffset = tvyposoffset;
- /* Release mem regions */
- release_mem_region(ivideo.video_base, ivideo.video_size);
- release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-
-#ifdef CONFIG_MTRR
- /* Release MTRR region */
- if(ivideo.mtrr) {
- mtrr_del(ivideo.mtrr,
- (unsigned int)ivideo.video_base,
- (unsigned int)ivideo.video_size);
- }
+#if !defined(__i386__) && !defined(__x86_64__)
+ sisfb_resetcard = (resetcard) ? 1 : 0;
+ if(videoram) sisfb_videoram = videoram;
#endif
- /* Unregister the framebuffer */
- if(sisfb_registered) {
- unregister_framebuffer(sis_fb_info);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (defined(NEWFBDEV))
- framebuffer_release(sis_fb_info);
-#else
- kfree(sis_fb_info);
-#endif
- }
+ return(sisfb_init());
+}
- if(sishw_ext.pSR) vfree(sishw_ext.pSR);
- if(sishw_ext.pCR) vfree(sishw_ext.pCR);
-
- /* TODO: Restore the initial mode
- * This sounds easy but is as good as impossible
- * on many machines with SiS chip and video bridge
- * since text modes are always set up differently
- * from machine to machine. Depends on the type
- * of integration between chipset and bridge.
- */
-
- printk(KERN_INFO "sisfb: Module unloaded\n");
+static void __exit sisfb_remove_module(void)
+{
+ pci_unregister_driver(&sisfb_driver);
+ printk(KERN_DEBUG "sisfb: Module unloaded\n");
}
-#endif
+module_init(sisfb_init_module);
+module_exit(sisfb_remove_module);
+
+#endif /* /MODULE */
EXPORT_SYMBOL(sis_malloc);
EXPORT_SYMBOL(sis_free);
-EXPORT_SYMBOL(sis_dispinfo);
-EXPORT_SYMBOL(ivideo);
-
+
/*
- * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
- * frame buffer driver for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/305/540/630(S)/730(S)
+ * SiS 315(H/PRO)/55x/(M)65x/(M)661(F/M)X/740/741(GX)/330/(M)760
+ * frame buffer driver for Linux kernels >=2.4.14 and >=2.6.3
*
* Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
*
#ifndef _SISFB_MAIN
#define _SISFB_MAIN
-#include "vstruct.h"
-
-/* ------------------- Constant Definitions ------------------------- */
-
-#define AGPOFF /* default is turn off AGP */
-
-#define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
-
-#define VER_MAJOR 1
-#define VER_MINOR 6
-#define VER_LEVEL 25
+#include <linux/spinlock.h>
+#include "vstruct.h"
#include "sis.h"
-/* To be included in pci_ids.h */
-#ifndef PCI_DEVICE_ID_SI_650_VGA
-#define PCI_DEVICE_ID_SI_650_VGA 0x6325
-#endif
-#ifndef PCI_DEVICE_ID_SI_650
-#define PCI_DEVICE_ID_SI_650 0x0650
-#endif
-#ifndef PCI_DEVICE_ID_SI_740
-#define PCI_DEVICE_ID_SI_740 0x0740
-#endif
-#ifndef PCI_DEVICE_ID_SI_330
-#define PCI_DEVICE_ID_SI_330 0x0330
-#endif
-#ifndef PCI_DEVICE_ID_SI_660_VGA
-#define PCI_DEVICE_ID_SI_660_VGA 0x6330
-#endif
-#ifndef PCI_DEVICE_ID_SI_660
-#define PCI_DEVICE_ID_SI_660 0x0661
-#endif
-#ifndef PCI_DEVICE_ID_SI_741
-#define PCI_DEVICE_ID_SI_741 0x0741
-#endif
-#ifndef PCI_DEVICE_ID_SI_660
-#define PCI_DEVICE_ID_SI_660 0x0660
-#endif
-#ifndef PCI_DEVICE_ID_SI_760
-#define PCI_DEVICE_ID_SI_760 0x0760
-#endif
-
-/* To be included in fb.h */
-#ifndef FB_ACCEL_SIS_GLAMOUR_2
-#define FB_ACCEL_SIS_GLAMOUR_2 40 /* SiS 315, 65x, 740, 661, 741 */
-#endif
-#ifndef FB_ACCEL_SIS_XABRE
-#define FB_ACCEL_SIS_XABRE 41 /* SiS 330 ("Xabre"), 760 */
-#endif
-
-#define MAX_ROM_SCAN 0x10000
-
-#define HW_CURSOR_CAP 0x80
-#define TURBO_QUEUE_CAP 0x40
-#define AGP_CMD_QUEUE_CAP 0x20
-#define VM_CMD_QUEUE_CAP 0x10
-#define MMIO_CMD_QUEUE_CAP 0x08
-
-/* For 300 series */
-#ifdef CONFIG_FB_SIS_300
-#define TURBO_QUEUE_AREA_SIZE 0x80000 /* 512K */
-#endif
-
-/* For 315/Xabre series */
-#ifdef CONFIG_FB_SIS_315
-#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */
-#define COMMAND_QUEUE_THRESHOLD 0x1F
-#endif
-
-#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */
-#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */
-
-#define OH_ALLOC_SIZE 4000
-#define SENTINEL 0x7fffffff
-
-#define SEQ_ADR 0x14
-#define SEQ_DATA 0x15
-#define DAC_ADR 0x18
-#define DAC_DATA 0x19
-#define CRTC_ADR 0x24
-#define CRTC_DATA 0x25
-#define DAC2_ADR (0x16-0x30)
-#define DAC2_DATA (0x17-0x30)
-#define VB_PART1_ADR (0x04-0x30)
-#define VB_PART1_DATA (0x05-0x30)
-#define VB_PART2_ADR (0x10-0x30)
-#define VB_PART2_DATA (0x11-0x30)
-#define VB_PART3_ADR (0x12-0x30)
-#define VB_PART3_DATA (0x13-0x30)
-#define VB_PART4_ADR (0x14-0x30)
-#define VB_PART4_DATA (0x15-0x30)
-
-#define SISSR SiS_Pr.SiS_P3c4
-#define SISCR SiS_Pr.SiS_P3d4
-#define SISDACA SiS_Pr.SiS_P3c8
-#define SISDACD SiS_Pr.SiS_P3c9
-#define SISPART1 SiS_Pr.SiS_Part1Port
-#define SISPART2 SiS_Pr.SiS_Part2Port
-#define SISPART3 SiS_Pr.SiS_Part3Port
-#define SISPART4 SiS_Pr.SiS_Part4Port
-#define SISPART5 SiS_Pr.SiS_Part5Port
-#define SISDAC2A SISPART5
-#define SISDAC2D (SISPART5 + 1)
-#define SISMISCR (SiS_Pr.RelIO + 0x1c)
-#define SISMISCW SiS_Pr.SiS_P3c2
-#define SISINPSTAT (SiS_Pr.RelIO + 0x2a)
-#define SISPEL SiS_Pr.SiS_P3c6
-
-#define IND_SIS_PASSWORD 0x05 /* SRs */
-#define IND_SIS_COLOR_MODE 0x06
-#define IND_SIS_RAMDAC_CONTROL 0x07
-#define IND_SIS_DRAM_SIZE 0x14
-#define IND_SIS_SCRATCH_REG_16 0x16
-#define IND_SIS_SCRATCH_REG_17 0x17
-#define IND_SIS_SCRATCH_REG_1A 0x1A
-#define IND_SIS_MODULE_ENABLE 0x1E
-#define IND_SIS_PCI_ADDRESS_SET 0x20
-#define IND_SIS_TURBOQUEUE_ADR 0x26
-#define IND_SIS_TURBOQUEUE_SET 0x27
-#define IND_SIS_POWER_ON_TRAP 0x38
-#define IND_SIS_POWER_ON_TRAP2 0x39
-#define IND_SIS_CMDQUEUE_SET 0x26
-#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
-
-#define IND_SIS_SCRATCH_REG_CR30 0x30 /* CRs */
-#define IND_SIS_SCRATCH_REG_CR31 0x31
-#define IND_SIS_SCRATCH_REG_CR32 0x32
-#define IND_SIS_SCRATCH_REG_CR33 0x33
-#define IND_SIS_LCD_PANEL 0x36
-#define IND_SIS_SCRATCH_REG_CR37 0x37
-#define IND_SIS_AGP_IO_PAD 0x48
-
-#define IND_BRI_DRAM_STATUS 0x63 /* PCI config memory size offset */
-
-#define MMIO_QUEUE_PHYBASE 0x85C0
-#define MMIO_QUEUE_WRITEPORT 0x85C4
-#define MMIO_QUEUE_READPORT 0x85C8
-
-#define IND_SIS_CRT2_WRITE_ENABLE_300 0x24
-#define IND_SIS_CRT2_WRITE_ENABLE_315 0x2F
-
-#define SIS_PASSWORD 0x86 /* SR05 */
-#define SIS_INTERLACED_MODE 0x20 /* SR06 */
-#define SIS_8BPP_COLOR_MODE 0x0
-#define SIS_15BPP_COLOR_MODE 0x1
-#define SIS_16BPP_COLOR_MODE 0x2
-#define SIS_32BPP_COLOR_MODE 0x4
-#define SIS_DRAM_SIZE_MASK 0x3F /* 300/630/730 SR14 */
-#define SIS_DRAM_SIZE_1MB 0x00
-#define SIS_DRAM_SIZE_2MB 0x01
-#define SIS_DRAM_SIZE_4MB 0x03
-#define SIS_DRAM_SIZE_8MB 0x07
-#define SIS_DRAM_SIZE_16MB 0x0F
-#define SIS_DRAM_SIZE_32MB 0x1F
-#define SIS_DRAM_SIZE_64MB 0x3F
-#define SIS_DATA_BUS_MASK 0xC0
-#define SIS_DATA_BUS_32 0x00
-#define SIS_DATA_BUS_64 0x01
-#define SIS_DATA_BUS_128 0x02
-
-#define SIS315_DATA_BUS_MASK 0x02
-#define SIS315_DATA_BUS_64 0x00
-#define SIS315_DATA_BUS_128 0x01
-#define SIS315_DUAL_CHANNEL_MASK 0x0C
-#define SIS315_SINGLE_CHANNEL_1_RANK 0x0
-#define SIS315_SINGLE_CHANNEL_2_RANK 0x1
-#define SIS315_ASYM_DDR 0x02
-#define SIS315_DUAL_CHANNEL_1_RANK 0x3
-
-#define SIS_SCRATCH_REG_1A_MASK 0x10
-
-#define SIS_ENABLE_2D 0x40 /* SR1E */
-
-#define SIS_MEM_MAP_IO_ENABLE 0x01 /* SR20 */
-#define SIS_PCI_ADDR_ENABLE 0x80
-
-#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/650/740 SR26 */
-#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
-#define SIS_MMIO_CMD_ENABLE 0x20
-#define SIS_CMD_QUEUE_SIZE_512k 0x00
-#define SIS_CMD_QUEUE_SIZE_1M 0x04
-#define SIS_CMD_QUEUE_SIZE_2M 0x08
-#define SIS_CMD_QUEUE_SIZE_4M 0x0C
-#define SIS_CMD_QUEUE_RESET 0x01
-#define SIS_CMD_AUTO_CORR 0x02
-
-#define SIS_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */
-#define SIS_MODE_SELECT_CRT2 0x02
-#define SIS_VB_OUTPUT_COMPOSITE 0x04
-#define SIS_VB_OUTPUT_SVIDEO 0x08
-#define SIS_VB_OUTPUT_SCART 0x10
-#define SIS_VB_OUTPUT_LCD 0x20
-#define SIS_VB_OUTPUT_CRT2 0x40
-#define SIS_VB_OUTPUT_HIVISION 0x80
-
-#define SIS_VB_OUTPUT_DISABLE 0x20 /* CR31 */
-#define SIS_DRIVER_MODE 0x40
-
-#define SIS_VB_COMPOSITE 0x01 /* CR32 */
-#define SIS_VB_SVIDEO 0x02
-#define SIS_VB_SCART 0x04
-#define SIS_VB_LCD 0x08
-#define SIS_VB_CRT2 0x10
-#define SIS_CRT1 0x20
-#define SIS_VB_HIVISION 0x40
-#define SIS_VB_DVI 0x80
-#define SIS_VB_TV (SIS_VB_COMPOSITE | SIS_VB_SVIDEO | \
- SIS_VB_SCART | SIS_VB_HIVISION)
-
-#define SIS_EXTERNAL_CHIP_MASK 0x0E /* CR37 (< SiS 660) */
-#define SIS_EXTERNAL_CHIP_SIS301 0x01 /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_TRUMPION 0x03 /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04 /* in CR37 << 1 ! */
-#define SIS_EXTERNAL_CHIP_CHRONTEL 0x05 /* in CR37 << 1 ! */
-#define SIS310_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */
-#define SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03 /* in CR37 << 1 ! */
-
-#define SIS_AGP_2X 0x20 /* CR48 */
-
-#define BRI_DRAM_SIZE_MASK 0x70 /* PCI bridge config data */
-#define BRI_DRAM_SIZE_2MB 0x00
-#define BRI_DRAM_SIZE_4MB 0x01
-#define BRI_DRAM_SIZE_8MB 0x02
-#define BRI_DRAM_SIZE_16MB 0x03
-#define BRI_DRAM_SIZE_32MB 0x04
-#define BRI_DRAM_SIZE_64MB 0x05
-
-#define HW_DEVICE_EXTENSION SIS_HW_INFO
-#define PHW_DEVICE_EXTENSION PSIS_HW_INFO
-
-#define SR_BUFFER_SIZE 5
-#define CR_BUFFER_SIZE 5
-
-/* entries for disp_state - deprecated as of 1.6.02 */
-#define DISPTYPE_CRT1 0x00000008L
-#define DISPTYPE_CRT2 0x00000004L
-#define DISPTYPE_LCD 0x00000002L
-#define DISPTYPE_TV 0x00000001L
-#define DISPTYPE_DISP1 DISPTYPE_CRT1
-#define DISPTYPE_DISP2 (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV)
-#define DISPMODE_SINGLE 0x00000020L
-#define DISPMODE_MIRROR 0x00000010L
-#define DISPMODE_DUALVIEW 0x00000040L
-
-/* Deprecated as of 1.6.02 - use vbflags instead */
-#define HASVB_NONE 0x00
-#define HASVB_301 0x01
-#define HASVB_LVDS 0x02
-#define HASVB_TRUMPION 0x04
-#define HASVB_LVDS_CHRONTEL 0x10
-#define HASVB_302 0x20
-#define HASVB_303 0x40
-#define HASVB_CHRONTEL 0x80
-
-/* Useful macros */
-#define inSISREG(base) inb(base)
-#define outSISREG(base,val) outb(val,base)
-#define orSISREG(base,val) do { \
- unsigned char __Temp = inb(base); \
- outSISREG(base, __Temp | (val)); \
- } while (0)
-#define andSISREG(base,val) do { \
- unsigned char __Temp = inb(base); \
- outSISREG(base, __Temp & (val)); \
- } while (0)
-#define inSISIDXREG(base,idx,var) do { \
- outb(idx,base); var=inb((base)+1); \
- } while (0)
-#define outSISIDXREG(base,idx,val) do { \
- outb(idx,base); outb((val),(base)+1); \
- } while (0)
-#define orSISIDXREG(base,idx,val) do { \
- unsigned char __Temp; \
- outb(idx,base); \
- __Temp = inb((base)+1)|(val); \
- outSISIDXREG(base,idx,__Temp); \
- } while (0)
-#define andSISIDXREG(base,idx,and) do { \
- unsigned char __Temp; \
- outb(idx,base); \
- __Temp = inb((base)+1)&(and); \
- outSISIDXREG(base,idx,__Temp); \
- } while (0)
-#define setSISIDXREG(base,idx,and,or) do { \
- unsigned char __Temp; \
- outb(idx,base); \
- __Temp = (inb((base)+1)&(and))|(or); \
- outSISIDXREG(base,idx,__Temp); \
- } while (0)
-
-/* ------------------- Global Variables ----------------------------- */
-
-/* Fbcon variables */
-static struct fb_info *sis_fb_info;
+#define MODE_INDEX_NONE 0 /* index for mode=none */
-static struct fb_var_screeninfo default_var = {
+/* Fbcon stuff */
+static struct fb_var_screeninfo my_default_var = {
.xres = 0,
.yres = 0,
.xres_virtual = 0,
.vsync_len = 0,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- .reserved = {0, 0, 0, 0, 0, 0}
-#endif
};
+/* Boot-time parameters */
+static int sisfb_off = 0;
+static int sisfb_parm_mem = 0;
+static int sisfb_accel = -1;
+static int sisfb_ypan = -1;
+static int sisfb_max = -1;
+static int sisfb_userom = 1;
+static int sisfb_useoem = -1;
+#ifdef MODULE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static struct fb_fix_screeninfo sisfb_fix = {
- .id = "SiS",
- .type = FB_TYPE_PACKED_PIXELS,
- .xpanstep = 0,
- .ypanstep = 1,
-};
-static char myid[40];
-static u32 pseudo_palette[17];
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static struct display sis_disp;
-
-static struct display_switch sisfb_sw;
-
-static struct {
- u16 blue, green, red, pad;
-} sis_palette[256];
-
-static union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
+static int sisfb_mode_idx = -1;
+#else
+static int sisfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */
#endif
-} sis_fbcon_cmap;
-
-static int sisfb_inverse = 0;
-static int currcon = 0;
+#else
+static int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
#endif
-
-/* global flags */
-static int sisfb_off = 0;
+static int sisfb_parm_rate = -1;
static int sisfb_crt1off = 0;
static int sisfb_forcecrt1 = -1;
-static int sisvga_enabled = 0;
-static int sisfb_userom = 1;
-static int sisfb_useoem = -1;
-static int sisfb_parm_rate = -1;
-static int sisfb_registered = 0;
-static int sisfb_mem = 0;
-static int sisfb_pdc = 0;
-static int sisfb_ypan = -1;
-static int sisfb_max = -1;
-static int sisfb_nocrt2rate = 0;
+static int sisfb_crt2type = -1; /* CRT2 type (for overriding autodetection) */
+static int sisfb_crt2flags = 0;
+static int sisfb_pdc = 0xff;
+static int sisfb_pdca = 0xff;
+static int sisfb_scalelcd = -1;
+static int sisfb_specialtiming = CUT_NONE;
+static int sisfb_lvdshl = -1;
static int sisfb_dstn = 0;
static int sisfb_fstn = 0;
+static int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
+static int sisfb_tvstd = -1;
+static int sisfb_tvxposoffset = 0;
+static int sisfb_tvyposoffset = 0;
+static int sisfb_filter = -1;
+static int sisfb_nocrt2rate = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+static int sisfb_inverse = 0;
+static char sisfb_fontname[40];
+#endif
+#if !defined(__i386__) && !defined(__x86_64__)
+static int sisfb_resetcard = 0;
+static int sisfb_videoram = 0;
+#endif
-VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
-int sisfb_accel = -1;
-
-/* These are to adapted according to VGA_ENGINE type */
-static int sisfb_hwcursor_size = 0;
-static int sisfb_CRT2_write_enable = 0;
-
-int sisfb_crt2type = -1; /* CRT2 type (for overriding autodetection) */
-int sisfb_tvplug = -1; /* Tv plug type (for overriding autodetection) */
-
-int sisfb_queuemode = -1; /* Use MMIO queue mode by default (315 series only) */
-
-unsigned char sisfb_detectedpdc = 0;
-
-unsigned char sisfb_detectedlcda = 0xff;
-
-/* data for sis hardware ("par") */
-struct video_info ivideo;
-
-/* For ioctl SISFB_GET_INFO */
-sisfb_info sisfbinfo;
-
-/* Hardware info; contains data on hardware */
-SIS_HW_INFO sishw_ext;
+/* List of supported chips */
+static struct sisfb_chip_info {
+ int chip;
+ int vgaengine;
+ int mni;
+ int hwcursor_size;
+ int CRT2_write_enable;
+ const char *chip_name;
+} sisfb_chip_info[] __devinitdata = {
+ { SIS_300, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 300/305" },
+ { SIS_540, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 540" },
+ { SIS_630, SIS_300_VGA, 0, HW_CURSOR_AREA_SIZE_300 * 2, SIS_CRT2_WENABLE_300, "SiS 630" },
+ { SIS_315H, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315H" },
+ { SIS_315, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315" },
+ { SIS_315PRO, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 315PRO" },
+ { SIS_550, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 55x" },
+ { SIS_650, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 650" },
+ { SIS_330, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 330" },
+ { SIS_660, SIS_315_VGA, 1, HW_CURSOR_AREA_SIZE_315 * 4, SIS_CRT2_WENABLE_315, "SiS 660" },
+};
-/* SiS private structure */
-SiS_Private SiS_Pr;
+static struct pci_device_id __devinitdata sisfb_pci_table[] = {
+#ifdef CONFIG_FB_SIS_300
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+#endif
+#ifdef CONFIG_FB_SIS_315
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+ { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+#endif
+ { 0 }
+};
-/* Card parameters */
-static unsigned long sisfb_mmio_size = 0;
-static u8 sisfb_caps = 0;
+MODULE_DEVICE_TABLE(pci, sisfb_pci_table);
-typedef enum _SIS_CMDTYPE {
- MMIO_CMD = 0,
- AGP_CMD_QUEUE,
- VM_CMD_QUEUE,
-} SIS_CMDTYPE;
+static struct sis_video_info *card_list = NULL;
-/* List of supported chips */
-static struct board {
- u16 vendor, device;
- const char *name;
-} sisdev_list[] = {
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, "SIS 300"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA, "SIS 540 VGA"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA, "SIS 630/730 VGA"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315H, "SIS 315H"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315, "SIS 315"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO, "SIS 315PRO"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 65x/M65x/740 VGA"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330, "SIS 330"},
- {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 661FX/M661FX/741/760 VGA"},
- {0, 0, NULL}
-};
+/* TODO: This is not handled card-wise because the DRM
+ does not refer to a unique fb when calling sis_alloc
+ or sis_free. Therefore, this is handled globally for
+ now (hoping that nobody is crazy enough to run two
+ SiS cards at the same time).
+ */
+SIS_HEAP sisfb_heap;
#define MD_SIS300 1
#define MD_SIS315 2
/* Mode table */
-/* NOT const - will be patched for 1280x768 mode number chaos reasons */
-struct _sisbios_mode {
+static const struct _sisbios_mode {
char name[15];
- u8 mode_no;
+ u8 mode_no[2];
u16 vesa_mode_no_1; /* "SiS defined" VESA mode number */
u16 vesa_mode_no_2; /* Real VESA mode numbers */
u16 xres;
u16 rows;
u8 chipset;
} sisbios_mode[] = {
-#define MODE_INDEX_NONE 0 /* index for mode=none */
- {"none", 0xff, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_SIS300|MD_SIS315},
- {"320x200x8", 0x59, 0x0138, 0x0000, 320, 200, 8, 1, 40, 12, MD_SIS300|MD_SIS315},
- {"320x200x16", 0x41, 0x010e, 0x0000, 320, 200, 16, 1, 40, 12, MD_SIS300|MD_SIS315},
- {"320x200x24", 0x4f, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315}, /* TW: That's for people who mix up color- and fb depth */
- {"320x200x32", 0x4f, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315},
- {"320x240x8", 0x50, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS300|MD_SIS315},
- {"320x240x16", 0x56, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
- {"320x240x24", 0x53, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
- {"320x240x32", 0x53, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
- {"320x240x8", 0x5a, 0x0132, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* TW: FSTN */
- {"320x240x16", 0x5b, 0x0135, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* TW: FSTN */
- {"400x300x8", 0x51, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
- {"400x300x16", 0x57, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
- {"400x300x24", 0x54, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
- {"400x300x32", 0x54, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
- {"512x384x8", 0x52, 0x0000, 0x0000, 512, 384, 8, 1, 64, 24, MD_SIS300|MD_SIS315},
- {"512x384x16", 0x58, 0x0000, 0x0000, 512, 384, 16, 1, 64, 24, MD_SIS300|MD_SIS315},
- {"512x384x24", 0x5c, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
- {"512x384x32", 0x5c, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
- {"640x400x8", 0x2f, 0x0000, 0x0000, 640, 400, 8, 1, 80, 25, MD_SIS300|MD_SIS315},
- {"640x400x16", 0x5d, 0x0000, 0x0000, 640, 400, 16, 1, 80, 25, MD_SIS300|MD_SIS315},
- {"640x400x24", 0x5e, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
- {"640x400x32", 0x5e, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
- {"640x480x8", 0x2e, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_SIS300|MD_SIS315},
- {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, MD_SIS300|MD_SIS315},
- {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
- {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
- {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, MD_SIS300|MD_SIS315},
- {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, MD_SIS300|MD_SIS315},
- {"720x480x24", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
- {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
- {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, MD_SIS300|MD_SIS315},
- {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, MD_SIS300|MD_SIS315},
- {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
- {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
- {"768x576x8", 0x5f, 0x0000, 0x0000, 768, 576, 8, 1, 96, 36, MD_SIS300|MD_SIS315},
- {"768x576x16", 0x60, 0x0000, 0x0000, 768, 576, 16, 1, 96, 36, MD_SIS300|MD_SIS315},
- {"768x576x24", 0x61, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
- {"768x576x32", 0x61, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
- {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, MD_SIS300|MD_SIS315},
- {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
- {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
- {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+/*0*/ {"none", {0xff,0xff}, 0x0000, 0x0000, 0, 0, 0, 0, 0, 0, MD_SIS300|MD_SIS315},
+ {"320x200x8", {0x59,0x59}, 0x0138, 0x0000, 320, 200, 8, 1, 40, 12, MD_SIS300|MD_SIS315},
+ {"320x200x16", {0x41,0x41}, 0x010e, 0x0000, 320, 200, 16, 1, 40, 12, MD_SIS300|MD_SIS315},
+ {"320x200x24", {0x4f,0x4f}, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315}, /* That's for people who mix up color- and fb depth */
+ {"320x200x32", {0x4f,0x4f}, 0x0000, 0x0000, 320, 200, 32, 1, 40, 12, MD_SIS300|MD_SIS315},
+ {"320x240x8", {0x50,0x50}, 0x0132, 0x0000, 320, 240, 8, 1, 40, 15, MD_SIS300|MD_SIS315},
+ {"320x240x16", {0x56,0x56}, 0x0135, 0x0000, 320, 240, 16, 1, 40, 15, MD_SIS300|MD_SIS315},
+ {"320x240x24", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
+ {"320x240x32", {0x53,0x53}, 0x0000, 0x0000, 320, 240, 32, 1, 40, 15, MD_SIS300|MD_SIS315},
+ {"320x240x8", {0x5a,0x5a}, 0x0132, 0x0000, 320, 480, 8, 1, 40, 30, MD_SIS315}, /* FSTN */
+/*10*/ {"320x240x16", {0x5b,0x5b}, 0x0135, 0x0000, 320, 480, 16, 1, 40, 30, MD_SIS315}, /* FSTN */
+ {"400x300x8", {0x51,0x51}, 0x0133, 0x0000, 400, 300, 8, 1, 50, 18, MD_SIS300|MD_SIS315},
+ {"400x300x16", {0x57,0x57}, 0x0136, 0x0000, 400, 300, 16, 1, 50, 18, MD_SIS300|MD_SIS315},
+ {"400x300x24", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
+ {"400x300x32", {0x54,0x54}, 0x0000, 0x0000, 400, 300, 32, 1, 50, 18, MD_SIS300|MD_SIS315},
+ {"512x384x8", {0x52,0x52}, 0x0000, 0x0000, 512, 384, 8, 1, 64, 24, MD_SIS300|MD_SIS315},
+ {"512x384x16", {0x58,0x58}, 0x0000, 0x0000, 512, 384, 16, 1, 64, 24, MD_SIS300|MD_SIS315},
+ {"512x384x24", {0x5c,0x5c}, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
+ {"512x384x32", {0x5c,0x5c}, 0x0000, 0x0000, 512, 384, 32, 1, 64, 24, MD_SIS300|MD_SIS315},
+ {"640x400x8", {0x2f,0x2f}, 0x0000, 0x0000, 640, 400, 8, 1, 80, 25, MD_SIS300|MD_SIS315},
+/*20*/ {"640x400x16", {0x5d,0x5d}, 0x0000, 0x0000, 640, 400, 16, 1, 80, 25, MD_SIS300|MD_SIS315},
+ {"640x400x24", {0x5e,0x5e}, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
+ {"640x400x32", {0x5e,0x5e}, 0x0000, 0x0000, 640, 400, 32, 1, 80, 25, MD_SIS300|MD_SIS315},
+ {"640x480x8", {0x2e,0x2e}, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"640x480x16", {0x44,0x44}, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"640x480x24", {0x62,0x62}, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"640x480x32", {0x62,0x62}, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, MD_SIS300|MD_SIS315},
+ {"720x480x8", {0x31,0x31}, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, MD_SIS300|MD_SIS315},
+ {"720x480x16", {0x33,0x33}, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, MD_SIS300|MD_SIS315},
+ {"720x480x24", {0x35,0x35}, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
+/*30*/ {"720x480x32", {0x35,0x35}, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, MD_SIS300|MD_SIS315},
+ {"720x576x8", {0x32,0x32}, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, MD_SIS300|MD_SIS315},
+ {"720x576x16", {0x34,0x34}, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, MD_SIS300|MD_SIS315},
+ {"720x576x24", {0x36,0x36}, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
+ {"720x576x32", {0x36,0x36}, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, MD_SIS300|MD_SIS315},
+ {"768x576x8", {0x5f,0x5f}, 0x0000, 0x0000, 768, 576, 8, 1, 96, 36, MD_SIS300|MD_SIS315},
+ {"768x576x16", {0x60,0x60}, 0x0000, 0x0000, 768, 576, 16, 1, 96, 36, MD_SIS300|MD_SIS315},
+ {"768x576x24", {0x61,0x61}, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
+ {"768x576x32", {0x61,0x61}, 0x0000, 0x0000, 768, 576, 32, 1, 96, 36, MD_SIS300|MD_SIS315},
+ {"800x480x8", {0x70,0x70}, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, MD_SIS300|MD_SIS315},
+/*40*/ {"800x480x16", {0x7a,0x7a}, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
+ {"800x480x24", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
+ {"800x480x32", {0x76,0x76}, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
#define DEFAULT_MODE 43 /* index for 800x600x8 */
#define DEFAULT_LCDMODE 43 /* index for 800x600x8 */
#define DEFAULT_TVMODE 43 /* index for 800x600x8 */
- {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
- {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
- {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
- {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
- {"848x480x8", 0x39, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
- {"848x480x16", 0x3b, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
- {"848x480x24", 0x3e, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
- {"848x480x32", 0x3e, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
- {"856x480x8", 0x3f, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
- {"856x480x16", 0x42, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
- {"856x480x24", 0x45, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
- {"856x480x32", 0x45, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
- {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, MD_SIS300|MD_SIS315},
- {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
- {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
- {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
- {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_SIS300 },
- {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, MD_SIS300 },
- {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
- {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
- {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 2, 128, 48, MD_SIS300|MD_SIS315},
- {"1024x768x16", 0x4a, 0x0117, 0x0117, 1024, 768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
- {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
- {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
- {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_SIS300 },
- {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, MD_SIS300 },
- {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
- {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
- {"1152x864x8", 0x29, 0x0000, 0x0000, 1152, 864, 8, 1, 144, 54, MD_SIS300|MD_SIS315},
- {"1152x864x16", 0x2a, 0x0000, 0x0000, 1152, 864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
- {"1152x864x24", 0x2b, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
- {"1152x864x32", 0x2b, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
- {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, MD_SIS300|MD_SIS315},
- {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
- {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
- {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
-#define MODEINDEX_1280x768 79
- {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_SIS300|MD_SIS315},
- {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
- {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
- {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
- {"1280x960x8", 0x7c, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
- {"1280x960x16", 0x7d, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
- {"1280x960x24", 0x7e, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
- {"1280x960x32", 0x7e, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
- {"1280x1024x8", 0x3a, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
- {"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
- {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
- {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
- {"1360x768x8", 0x48, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
- {"1360x768x16", 0x4b, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
- {"1360x768x24", 0x4e, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
- {"1360x768x32", 0x4e, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
- {"1360x1024x8", 0x67, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
- {"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
- {"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
- {"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
- {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
- {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
- {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
- {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
- {"1600x1200x8", 0x3c, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
- {"1600x1200x16", 0x3d, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
- {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
- {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
- {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
- {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
- {"1920x1440x24", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
- {"1920x1440x32", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
- {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
- {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
- {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
- {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
- {"\0", 0x00, 0, 0, 0, 0, 0, 0, 0}
+ {"800x600x8", {0x30,0x30}, 0x0103, 0x0103, 800, 600, 8, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"800x600x16", {0x47,0x47}, 0x0114, 0x0114, 800, 600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"800x600x24", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"800x600x32", {0x63,0x63}, 0x013b, 0x0115, 800, 600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+ {"848x480x8", {0x39,0x39}, 0x0000, 0x0000, 848, 480, 8, 2, 106, 30, MD_SIS300|MD_SIS315},
+ {"848x480x16", {0x3b,0x3b}, 0x0000, 0x0000, 848, 480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
+ {"848x480x24", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
+/*50*/ {"848x480x32", {0x3e,0x3e}, 0x0000, 0x0000, 848, 480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
+ {"856x480x8", {0x3f,0x3f}, 0x0000, 0x0000, 856, 480, 8, 2, 107, 30, MD_SIS300|MD_SIS315},
+ {"856x480x16", {0x42,0x42}, 0x0000, 0x0000, 856, 480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
+ {"856x480x24", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+ {"856x480x32", {0x45,0x45}, 0x0000, 0x0000, 856, 480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+ {"960x540x8", {0x1d,0x1d}, 0x0000, 0x0000, 960, 540, 8, 1, 120, 33, MD_SIS315},
+ {"960x540x16", {0x1e,0x1e}, 0x0000, 0x0000, 960, 540, 16, 1, 120, 33, MD_SIS315},
+ {"960x540x24", {0x1f,0x1f}, 0x0000, 0x0000, 960, 540, 32, 1, 120, 33, MD_SIS315},
+ {"960x540x32", {0x1f,0x1f}, 0x0000, 0x0000, 960, 540, 32, 1, 120, 33, MD_SIS315},
+ {"1024x576x8", {0x71,0x71}, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, MD_SIS300|MD_SIS315},
+/*60*/ {"1024x576x16", {0x74,0x74}, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
+ {"1024x576x24", {0x77,0x77}, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+ {"1024x576x32", {0x77,0x77}, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
+ {"1024x600x8", {0x20,0x20}, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, MD_SIS300 },
+ {"1024x600x16", {0x21,0x21}, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, MD_SIS300 },
+ {"1024x600x24", {0x22,0x22}, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
+ {"1024x600x32", {0x22,0x22}, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, MD_SIS300 },
+ {"1024x768x8", {0x38,0x38}, 0x0105, 0x0105, 1024, 768, 8, 2, 128, 48, MD_SIS300|MD_SIS315},
+ {"1024x768x16", {0x4a,0x4a}, 0x0117, 0x0117, 1024, 768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
+ {"1024x768x24", {0x64,0x64}, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+/*70*/ {"1024x768x32", {0x64,0x64}, 0x013c, 0x0118, 1024, 768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
+ {"1152x768x8", {0x23,0x23}, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, MD_SIS300 },
+ {"1152x768x16", {0x24,0x24}, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, MD_SIS300 },
+ {"1152x768x24", {0x25,0x25}, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
+ {"1152x768x32", {0x25,0x25}, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, MD_SIS300 },
+ {"1152x864x8", {0x29,0x29}, 0x0000, 0x0000, 1152, 864, 8, 1, 144, 54, MD_SIS300|MD_SIS315},
+ {"1152x864x16", {0x2a,0x2a}, 0x0000, 0x0000, 1152, 864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
+ {"1152x864x24", {0x2b,0x2b}, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+ {"1152x864x32", {0x2b,0x2b}, 0x0000, 0x0000, 1152, 864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+ {"1280x720x8", {0x79,0x79}, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, MD_SIS300|MD_SIS315},
+/*80*/ {"1280x720x16", {0x75,0x75}, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
+ {"1280x720x24", {0x78,0x78}, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+ {"1280x720x32", {0x78,0x78}, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
+ {"1280x768x8", {0x55,0x23}, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, MD_SIS300|MD_SIS315},
+ {"1280x768x16", {0x5a,0x24}, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
+ {"1280x768x24", {0x5b,0x25}, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+ {"1280x768x32", {0x5b,0x25}, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+ {"1280x800x8", {0x14,0x14}, 0x0000, 0x0000, 1280, 800, 8, 1, 160, 50, MD_SIS315},
+ {"1280x800x16", {0x15,0x15}, 0x0000, 0x0000, 1280, 800, 16, 1, 160, 50, MD_SIS315},
+ {"1280x800x24", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
+/*90*/ {"1280x800x32", {0x16,0x16}, 0x0000, 0x0000, 1280, 800, 32, 1, 160, 50, MD_SIS315},
+ {"1280x960x8", {0x7c,0x7c}, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_SIS300|MD_SIS315},
+ {"1280x960x16", {0x7d,0x7d}, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+ {"1280x960x24", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+ {"1280x960x32", {0x7e,0x7e}, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+ {"1280x1024x8", {0x3a,0x3a}, 0x0107, 0x0107, 1280, 1024, 8, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1280x1024x16", {0x4d,0x4d}, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1280x1024x24", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1280x1024x32", {0x65,0x65}, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
+ {"1360x768x8", {0x48,0x48}, 0x0000, 0x0000, 1360, 768, 8, 1, 170, 48, MD_SIS300|MD_SIS315},
+/*100*/ {"1360x768x16", {0x4b,0x4b}, 0x0000, 0x0000, 1360, 768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
+ {"1360x768x24", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+ {"1360x768x32", {0x4e,0x4e}, 0x0000, 0x0000, 1360, 768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+ {"1360x1024x8", {0x67,0x67}, 0x0000, 0x0000, 1360, 1024, 8, 1, 170, 64, MD_SIS300 },
+ {"1360x1024x16", {0x6f,0x6f}, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300 },
+ {"1360x1024x24", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
+ {"1360x1024x32", {0x72,0x72}, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300 },
+ {"1400x1050x8", {0x26,0x26}, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, MD_SIS315},
+ {"1400x1050x16", {0x27,0x27}, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, MD_SIS315},
+ {"1400x1050x24", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
+/*110*/ {"1400x1050x32", {0x28,0x28}, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, MD_SIS315},
+ {"1600x1200x8", {0x3c,0x3c}, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1600x1200x16", {0x3d,0x3d}, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1600x1200x24", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1600x1200x32", {0x66,0x66}, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
+ {"1680x1050x8", {0x17,0x17}, 0x0000, 0x0000, 1680, 1050, 8, 1, 210, 65, MD_SIS315},
+ {"1680x1050x16", {0x18,0x18}, 0x0000, 0x0000, 1680, 1050, 16, 1, 210, 65, MD_SIS315},
+ {"1680x1050x24", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
+ {"1680x1050x32", {0x19,0x19}, 0x0000, 0x0000, 1680, 1050, 32, 1, 210, 65, MD_SIS315},
+ {"1920x1080x8", {0x2c,0x2c}, 0x0000, 0x0000, 1920, 1080, 8, 1, 240, 67, MD_SIS315},
+/*120*/ {"1920x1080x16", {0x2d,0x2d}, 0x0000, 0x0000, 1920, 1080, 16, 1, 240, 67, MD_SIS315},
+ {"1920x1080x24", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
+ {"1920x1080x32", {0x73,0x73}, 0x0000, 0x0000, 1920, 1080, 32, 1, 240, 67, MD_SIS315},
+ {"1920x1440x8", {0x68,0x68}, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, MD_SIS300|MD_SIS315},
+ {"1920x1440x16", {0x69,0x69}, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
+ {"1920x1440x24", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+ {"1920x1440x32", {0x6b,0x6b}, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+ {"2048x1536x8", {0x6c,0x6c}, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, MD_SIS315},
+ {"2048x1536x16", {0x6d,0x6d}, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, MD_SIS315},
+ {"2048x1536x24", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
+/*130*/ {"2048x1536x32", {0x6e,0x6e}, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, MD_SIS315},
+ {"\0", {0x00,0x00}, 0, 0, 0, 0, 0, 0, 0}
};
-/* mode-related variables */
-#ifdef MODULE
-int sisfb_mode_idx = MODE_INDEX_NONE; /* Don't use a mode by default if we are a module */
-#else
-int sisfb_mode_idx = -1; /* Use a default mode if we are inside the kernel */
-#endif
-u8 sisfb_mode_no = 0;
-u8 sisfb_rate_idx = 0;
+#define SIS_LCD_NUMBER 17
+static const struct _sis_lcd_data {
+ u32 lcdtype;
+ u16 xres;
+ u16 yres;
+ u8 default_mode_idx;
+} sis_lcd_data[] = {
+ { LCD_640x480, 640, 480, 23 },
+ { LCD_800x600, 800, 600, 43 },
+ { LCD_1024x600, 1024, 600, 63 },
+ { LCD_1024x768, 1024, 768, 67 },
+ { LCD_1152x768, 1152, 768, 71 },
+ { LCD_1152x864, 1152, 864, 75 },
+ { LCD_1280x720, 1280, 720, 79 },
+ { LCD_1280x768, 1280, 768, 83 },
+ { LCD_1280x800, 1280, 800, 87 },
+ { LCD_1280x960, 1280, 960, 91 },
+ { LCD_1280x1024, 1280, 1024, 95 },
+ { LCD_1400x1050, 1400, 1050, 107 },
+ { LCD_1680x1050, 1680, 1050, 115 },
+ { LCD_1600x1200, 1600, 1200, 111 },
+ { LCD_640x480_2, 640, 480, 23 },
+ { LCD_640x480_3, 640, 480, 23 },
+ { LCD_320x480, 320, 480, 9 },
+};
/* CR36 evaluation */
const USHORT sis300paneltype[] =
{ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768,
- LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768,
- LCD_1024x768, LCD_1024x768, LCD_320x480, LCD_1024x768 };
+ LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN,
+ LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN, LCD_UNKNOWN };
const USHORT sis310paneltype[] =
{ LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
- LCD_640x480_2, LCD_640x480_3, LCD_320x480, LCD_1024x768 };
+ LCD_640x480_2, LCD_640x480_3, LCD_UNKNOWN, LCD_UNKNOWN };
+
+const USHORT sis661paneltype[] =
+ { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024,
+ LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960,
+ LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
+ LCD_1280x800, LCD_1680x1050, LCD_1280x720, LCD_UNKNOWN };
#define FL_550_DSTN 0x01
#define FL_550_FSTN 0x02
-
-static const struct _sis_crt2type {
- char name[10];
- int type_no;
- int tvplug_no;
- unsigned short flags;
-} sis_crt2type[] = {
- {"NONE", 0, -1, 0},
- {"LCD", CRT2_LCD, -1, 0},
- {"TV", CRT2_TV, -1, 0},
- {"VGA", CRT2_VGA, -1, 0},
- {"SVIDEO", CRT2_TV, TV_SVIDEO, 0},
- {"COMPOSITE", CRT2_TV, TV_AVIDEO, 0},
- {"SCART", CRT2_TV, TV_SCART, 0},
- {"DSTN", CRT2_LCD, -1, FL_550_DSTN},
- {"FSTN", CRT2_LCD, -1, FL_550_FSTN},
- {"\0", -1, -1, 0}
-};
-
-/* Queue mode selection for 310 series */
-static const struct _sis_queuemode {
- char name[6];
- int type_no;
-} sis_queuemode[] = {
- {"AGP", AGP_CMD_QUEUE},
- {"VRAM", VM_CMD_QUEUE},
- {"MMIO", MMIO_CMD},
- {"\0", -1}
+#define FL_300 0x04
+#define FL_315 0x08
+
+static struct _sis_crt2type {
+ char name[32];
+ u32 type_no;
+ u32 tvplug_no;
+ u16 flags;
+} sis_crt2type[] __initdata = {
+ {"NONE", 0, -1, FL_300|FL_315},
+ {"LCD", CRT2_LCD, -1, FL_300|FL_315},
+ {"TV", CRT2_TV, -1, FL_300|FL_315},
+ {"VGA", CRT2_VGA, -1, FL_300|FL_315},
+ {"SVIDEO", CRT2_TV, TV_SVIDEO, FL_300|FL_315},
+ {"COMPOSITE", CRT2_TV, TV_AVIDEO, FL_300|FL_315},
+ {"CVBS", CRT2_TV, TV_AVIDEO, FL_300|FL_315},
+ {"SVIDEO+COMPOSITE", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
+ {"COMPOSITE+SVIDEO", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
+ {"SVIDEO+CVBS", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
+ {"CVBS+SVIDEO", CRT2_TV, TV_AVIDEO|TV_SVIDEO, FL_300|FL_315},
+ {"SCART", CRT2_TV, TV_SCART, FL_300|FL_315},
+ {"HIVISION", CRT2_TV, TV_HIVISION, FL_315},
+ {"YPBPR480I", CRT2_TV, TV_YPBPR|TV_YPBPR525I, FL_315},
+ {"YPBPR480P", CRT2_TV, TV_YPBPR|TV_YPBPR525P, FL_315},
+ {"YPBPR720P", CRT2_TV, TV_YPBPR|TV_YPBPR750P, FL_315},
+ {"YPBPR1080I", CRT2_TV, TV_YPBPR|TV_YPBPR1080I, FL_315},
+ {"DSTN", CRT2_LCD, -1, FL_315|FL_550_DSTN},
+ {"FSTN", CRT2_LCD, -1, FL_315|FL_550_FSTN},
+ {"\0", -1, -1, 0}
};
/* TV standard */
-static const struct _sis_tvtype {
+static struct _sis_tvtype {
char name[6];
- int type_no;
-} sis_tvtype[] = {
+ u32 type_no;
+} sis_tvtype[] __initdata = {
{"PAL", TV_PAL},
{"NTSC", TV_NTSC},
+ {"PALM", TV_PAL|TV_PALM},
+ {"PALN", TV_PAL|TV_PALN},
+ {"NTSCJ", TV_NTSC|TV_NTSCJ},
{"\0", -1}
};
{7, 800, 600, 120, TRUE}, {8, 800, 600, 160, TRUE},
{1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
{1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
+ {1, 960, 540, 60, TRUE},
{1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
{1, 1024, 600, 60, TRUE},
{1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
{1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, TRUE},
{1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
{1, 1280, 768, 60, TRUE},
+ {1, 1280, 800, 60, TRUE},
{1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
{1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
{4, 1280, 1024, 85, TRUE},
{1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
{4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
{7, 1600, 1200, 120, TRUE},
+ {1, 1680, 1050, 60, TRUE},
+ {1, 1920, 1080, 30, TRUE},
{1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
{4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
{1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
{0, 0, 0, 0, FALSE}
};
-static struct sisfb_monitor {
- u16 hmin;
- u16 hmax;
- u16 vmin;
- u16 vmax;
- u32 dclockmax;
- u8 feature;
- BOOLEAN datavalid;
-} sisfb_thismonitor;
-
static const struct _sisfbddcsmodes {
u32 mask;
u16 h;
{ 1920, 1440, 75, 113,297000}
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-static u8 sisfb_lastrates[128];
-#endif
-
-static const struct _chswtable {
- int subsysVendor;
- int subsysCard;
+#ifdef CONFIG_FB_SIS_300
+static struct _chswtable {
+ u16 subsysVendor;
+ u16 subsysCard;
char *vendorName;
char *cardName;
-} mychswtable[] = {
+} mychswtable[] __devinitdata = {
{ 0x1631, 0x1002, "Mitachi", "0x1002" },
{ 0x1071, 0x7521, "Mitac" , "7521P" },
{ 0, 0, "" , "" }
};
+#endif
-static const struct _customttable {
- unsigned short chipID;
- char *biosversion;
- char *biosdate;
- unsigned long bioschksum;
- unsigned short biosFootprintAddr[5];
- unsigned char biosFootprintData[5];
- unsigned short pcisubsysvendor;
- unsigned short pcisubsyscard;
- char *vendorName;
- char *cardName;
- unsigned long SpecialID;
- char *optionName;
-} mycustomttable[] = {
+static struct _customttable {
+ u16 chipID;
+ char *biosversion;
+ char *biosdate;
+ u32 bioschksum;
+ u16 biosFootprintAddr[5];
+ u8 biosFootprintData[5];
+ u16 pcisubsysvendor;
+ u16 pcisubsyscard;
+ char *vendorName;
+ char *cardName;
+ u32 SpecialID;
+ char *optionName;
+} mycustomttable[] __devinitdata = {
{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
0x3240A8,
{ 0x220, 0x227, 0x228, 0x229, 0x0ee },
}
};
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/* Offscreen layout */
-typedef struct _SIS_GLYINFO {
- unsigned char ch;
- int fontwidth;
- int fontheight;
- u8 gmask[72];
- int ngmask;
-} SIS_GLYINFO;
-
-static char sisfb_fontname[40];
-#endif
-
-typedef struct _SIS_OH {
- struct _SIS_OH *poh_next;
- struct _SIS_OH *poh_prev;
- unsigned long offset;
- unsigned long size;
-} SIS_OH;
-
-typedef struct _SIS_OHALLOC {
- struct _SIS_OHALLOC *poha_next;
- SIS_OH aoh[1];
-} SIS_OHALLOC;
-
-typedef struct _SIS_HEAP {
- SIS_OH oh_free;
- SIS_OH oh_used;
- SIS_OH *poh_freelist;
- SIS_OHALLOC *poha_chain;
- unsigned long max_freesize;
-} SIS_HEAP;
-
-static unsigned long sisfb_hwcursor_vbase;
-
-static unsigned long sisfb_heap_start;
-static unsigned long sisfb_heap_end;
-static unsigned long sisfb_heap_size;
-static SIS_HEAP sisfb_heap;
-
static const struct _sis_TV_filter {
u8 filter[9][4];
} sis_TV_filter[] = {
{0xFF,0xFF,0xFF,0xFF} }}
};
-static int filter = -1;
-static unsigned char filter_tb;
-
/* ---------------------- Prototypes ------------------------- */
/* Interface used by the world */
/* Interface to the low level console driver */
int sisfb_init(void);
+
/* fbdev routines */
+static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static int sisfb_get_fix(struct fb_fix_screeninfo *fix,
int con,
static int sisfb_set_var(struct fb_var_screeninfo *var,
int con,
struct fb_info *info);
-static void sisfb_crtc_to_var(struct fb_var_screeninfo *var);
+static void sisfb_crtc_to_var(struct sis_video_info *ivideo,
+ struct fb_var_screeninfo *var);
static int sisfb_get_cmap(struct fb_cmap *cmap,
int kspc,
int con,
struct fb_info *fb_info);
static void sisfb_do_install_cmap(int con,
struct fb_info *info);
-static void sis_get_glyph(struct fb_info *info,
- SIS_GLYINFO *gly);
-static int sisfb_mmap(struct fb_info *info, struct file *file,
- struct vm_area_struct *vma);
static int sisfb_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg, int con,
struct fb_info *info);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg,
+ struct fb_info *info);
static int sisfb_set_par(struct fb_info *info);
static int sisfb_blank(int blank,
struct fb_info *info);
-static int sisfb_mmap(struct fb_info *info, struct file *file,
- struct vm_area_struct *vma);
extern void fbcon_sis_fillrect(struct fb_info *info,
const struct fb_fillrect *rect);
extern void fbcon_sis_copyarea(struct fb_info *info,
const struct fb_copyarea *area);
extern int fbcon_sis_sync(struct fb_info *info);
-static int sisfb_ioctl(struct inode *inode,
- struct file *file,
- unsigned int cmd,
- unsigned long arg,
- struct fb_info *info);
-extern int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr,
- PSIS_HW_INFO HwDeviceExtension,
- unsigned char modeno, unsigned char rateindex);
-extern int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
- unsigned char modeno, unsigned char rateindex,
- unsigned int *left_margin, unsigned int *right_margin,
- unsigned int *upper_margin, unsigned int *lower_margin,
- unsigned int *hsync_len, unsigned int *vsync_len,
- unsigned int *sync, unsigned int *vmode);
#endif
-static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-
/* Internal 2D accelerator functions */
-extern int sisfb_initaccel(void);
-extern void sisfb_syncaccel(void);
+extern int sisfb_initaccel(struct sis_video_info *ivideo);
+extern void sisfb_syncaccel(struct sis_video_info *ivideo);
/* Internal general routines */
static void sisfb_search_mode(char *name, BOOLEAN quiet);
-static int sisfb_validate_mode(int modeindex, unsigned long vbflags);
-static u8 sisfb_search_refresh_rate(unsigned int rate, int index);
+static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
+static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
+ int index);
static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *fb_info);
static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
struct fb_info *info);
-static void sisfb_pre_setmode(void);
-static void sisfb_post_setmode(void);
-
-static char * sis_find_rom(void);
-static BOOLEAN sisfb_CheckVBRetrace(void);
-static BOOLEAN sisfbcheckvretracecrt2(void);
-static BOOLEAN sisfbcheckvretracecrt1(void);
-static BOOLEAN sisfb_bridgeisslave(void);
-static void sisfb_detect_VB_connect(void);
-static void sisfb_get_VB_type(void);
-
-static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
-static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
-
-/* SiS-specific Export functions */
-void sis_dispinfo(struct ap_data *rec);
+static void sisfb_pre_setmode(struct sis_video_info *ivideo);
+static void sisfb_post_setmode(struct sis_video_info *ivideo);
+static char * sis_find_rom(struct pci_dev *pdev);
+static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
+static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
+static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
+static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
+static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
+static void sisfb_get_VB_type(struct sis_video_info *ivideo);
+static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
+static void sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val);
+
+/* SiS-specific exported functions */
void sis_malloc(struct sis_memreq *req);
-void sis_free(unsigned long base);
-
-/* Internal hardware access routines */
-void sisfb_set_reg4(u16 port, unsigned long data);
-u32 sisfb_get_reg3(u16 port);
-
-/* Chipset-dependent internal routines */
-#ifdef CONFIG_FB_SIS_300
-static int sisfb_get_dram_size_300(void);
-#endif
-#ifdef CONFIG_FB_SIS_315
-static int sisfb_get_dram_size_315(void);
-#endif
+void sis_free(u32 base);
/* Internal heap routines */
-static int sisfb_heap_init(void);
+static int sisfb_heap_init(struct sis_video_info *ivideo);
static SIS_OH *sisfb_poh_new_node(void);
-static SIS_OH *sisfb_poh_allocate(unsigned long size);
+static SIS_OH *sisfb_poh_allocate(u32 size);
static void sisfb_delete_node(SIS_OH *poh);
static void sisfb_insert_node(SIS_OH *pohList, SIS_OH *poh);
-static SIS_OH *sisfb_poh_free(unsigned long base);
+static SIS_OH *sisfb_poh_free(u32 base);
static void sisfb_free_node(SIS_OH *poh);
-/* Internal routines to access PCI configuration space */
-BOOLEAN sisfb_query_VGA_config_space(PSIS_HW_INFO psishw_ext,
- unsigned long offset, unsigned long set, unsigned long *value);
-BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_INFO psishw_ext,
- unsigned long offset, unsigned long set, unsigned long *value);
-
/* Sensing routines */
-static void SiS_Sense30x(void);
-static int SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
-static void SiS_SenseCh(void);
+static void SiS_Sense30x(struct sis_video_info *ivideo);
+static void SiS_SenseCh(struct sis_video_info *ivideo);
/* Routines from init.c/init301.c */
extern USHORT SiS_GetModeID(int VGAEngine, ULONG VBFlags, int HDisplay, int VDisplay, int Depth, BOOLEAN FSTN);
extern void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
extern void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+extern BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+
extern BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+extern int sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr,
+ PSIS_HW_INFO HwDeviceExtension,
+ unsigned char modeno, unsigned char rateindex);
+extern int sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
+ unsigned char modeno, unsigned char rateindex,
+ struct fb_var_screeninfo *var);
+#endif
-/* Chrontel TV functions */
+/* Chrontel TV, DDC and DPMS functions */
extern USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
extern void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
extern USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
extern void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
extern void SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
extern void SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
-extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+extern USHORT SiS_HandleDDC(SiS_Private *SiS_Pr, ULONG VBFlags, int VGAEngine,
USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
extern USHORT SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
extern void SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
extern void SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
extern void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
extern void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
-
-
#endif
+
+
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* General type definitions for universal mode switching modules
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
#endif
#endif
-#ifndef LINUX_KERNEL /* For the linux kernel, this is defined in sisfb.h */
-#ifndef SIS_CHIP_TYPE
-typedef enum _SIS_CHIP_TYPE {
+enum _SIS_CHIP_TYPE {
SIS_VGALegacy = 0,
-#ifdef LINUX_XF86
SIS_530,
SIS_OLD,
-#endif
SIS_300,
SIS_630,
SIS_730,
SIS_540,
SIS_315H, /* SiS 310 */
SIS_315,
- SIS_315PRO, /* SiS 325 */
+ SIS_315PRO,
SIS_550,
SIS_650,
SIS_740,
SIS_741,
SIS_660,
SIS_760,
+ SIS_761,
+ SIS_340,
MAX_SIS_CHIP
-} SIS_CHIP_TYPE;
-#endif
-#endif
-
-#ifndef SIS_VB_CHIP_TYPE
-typedef enum _SIS_VB_CHIP_TYPE {
- VB_CHIP_Legacy = 0,
- VB_CHIP_301,
- VB_CHIP_301B,
- VB_CHIP_301LV,
- VB_CHIP_302,
- VB_CHIP_302B,
- VB_CHIP_302LV,
- VB_CHIP_301C,
- VB_CHIP_302ELV,
- VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
- MAX_VB_CHIP
-} SIS_VB_CHIP_TYPE;
-#endif
+};
-#ifndef SIS_LCD_TYPE
-typedef enum _SIS_LCD_TYPE {
+#ifdef LINUX_KERNEL
+enum _SIS_LCD_TYPE {
LCD_INVALID = 0,
LCD_800x600,
LCD_1024x768,
LCD_1600x1200,
LCD_1920x1440,
LCD_2048x1536,
- LCD_320x480, /* FSTN, DSTN */
+ LCD_320x480, /* FSTN */
LCD_1400x1050,
LCD_1152x864,
LCD_1152x768,
LCD_1280x768,
LCD_1024x600,
- LCD_640x480_2, /* FSTN, DSTN */
- LCD_640x480_3, /* FSTN, DSTN */
+ LCD_640x480_2, /* DSTN */
+ LCD_640x480_3, /* DSTN */
LCD_848x480,
LCD_1280x800,
LCD_1680x1050,
+ LCD_1280x720,
LCD_CUSTOM,
LCD_UNKNOWN
-} SIS_LCD_TYPE;
-#endif
-
-#ifndef PSIS_DSReg
-typedef struct _SIS_DSReg
-{
- UCHAR jIdx;
- UCHAR jVal;
-} SIS_DSReg, *PSIS_DSReg;
+};
+typedef unsigned int SIS_LCD_TYPE;
#endif
#ifndef SIS_HW_INFO
/* of Linear VGA memory */
ULONG ulVideoMemorySize; /* size, in bytes, of the memory on the board */
- SISIOADDRESS ulIOAddress; /* base I/O address of VGA ports (0x3B0) */
+
+ SISIOADDRESS ulIOAddress; /* base I/O address of VGA ports (0x3B0; relocated) */
+
UCHAR jChipType; /* Used to Identify SiS Graphics Chip */
- /* defined in the data structure type */
- /* "SIS_CHIP_TYPE" */
+ /* defined in the enum "SIS_CHIP_TYPE" (above or sisfb.h) */
UCHAR jChipRevision; /* Used to Identify SiS Graphics Chip Revision */
- UCHAR ujVBChipID; /* the ID of video bridge */
- /* defined in the data structure type */
- /* "SIS_VB_CHIP_TYPE" */
-#ifdef LINUX_KERNEL
- BOOLEAN Is301BDH;
-#endif
- USHORT usExternalChip; /* NO VB or other video bridge (other than */
- /* SiS video bridge) */
-
- ULONG ulCRT2LCDType; /* defined in the data structure type */
- /* "SIS_LCD_TYPE" */
-
BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
-
- BOOLEAN bSkipDramSizing; /* True: Skip video memory sizing. */
#ifdef LINUX_KERNEL
- PSIS_DSReg pSR; /* restore SR registers in initial function. */
- /* end data :(idx, val) = (FF, FF). */
- /* Note : restore SR registers if */
- /* bSkipDramSizing = TRUE */
-
- PSIS_DSReg pCR; /* restore CR registers in initial function. */
- /* end data :(idx, val) = (FF, FF) */
- /* Note : restore cR registers if */
- /* bSkipDramSizing = TRUE */
+ ULONG ulCRT2LCDType; /* defined in the data structure type */
+ /* "SIS_LCD_TYPE" */
#endif
-
- PSIS_QUERYSPACE pQueryVGAConfigSpace; /* Get/Set VGA Configuration */
- /* space */
-
- PSIS_QUERYSPACE pQueryNorthBridgeSpace;/* Get/Set North Bridge */
- /* space */
};
#endif
-/* Addtional IOCTL for communication sisfb <> X driver */
+/* Addtional IOCTLs for communication sisfb <> X driver */
/* If changing this, sisfb.h must also be changed (for sisfb) */
#ifdef LINUX_XF86 /* We don't want the X driver to depend on the kernel source */
/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO 0x80046ef8 /* Wow, what a terrible hack... */
+#define SISFB_GET_INFO_SIZE 0x8004f300
+#define SISFB_GET_INFO 0x8000f301 /* Must be patched with result from ..._SIZE at D[29:16] */
+/* deprecated ioctl number (for older versions of sisfb) */
+#define SISFB_GET_INFO_OLD 0x80046ef8
+
+/* ioctls for tv parameters (position) */
+#define SISFB_SET_TVPOSOFFSET 0x4004f304
+
+/* lock sisfb from register access */
+#define SISFB_SET_LOCK 0x4004f306
/* Structure argument for SISFB_GET_INFO ioctl */
typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
struct _SISFB_INFO {
- unsigned long sisfb_id; /* for identifying sisfb */
+ CARD32 sisfb_id; /* for identifying sisfb */
#ifndef SISFB_ID
#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
#endif
- int chip_id; /* PCI ID of detected chip */
- int memory; /* video memory in KB which sisfb manages */
- int heapstart; /* heap start (= sisfb "mem" argument) in KB */
- unsigned char fbvidmode; /* current sisfb mode */
+ CARD32 chip_id; /* PCI ID of detected chip */
+ CARD32 memory; /* video memory in KB which sisfb manages */
+ CARD32 heapstart; /* heap start (= sisfb "mem" argument) in KB */
+ CARD8 fbvidmode; /* current sisfb mode */
+
+ CARD8 sisfb_version;
+ CARD8 sisfb_revision;
+ CARD8 sisfb_patchlevel;
+
+ CARD8 sisfb_caps; /* sisfb's capabilities */
+
+ CARD32 sisfb_tqlen; /* turbo queue length (in KB) */
- unsigned char sisfb_version;
- unsigned char sisfb_revision;
- unsigned char sisfb_patchlevel;
+ CARD32 sisfb_pcibus; /* The card's PCI ID */
+ CARD32 sisfb_pcislot;
+ CARD32 sisfb_pcifunc;
- unsigned char sisfb_caps; /* sisfb's capabilities */
+ CARD8 sisfb_lcdpdc;
- int sisfb_tqlen; /* turbo queue length (in KB) */
+ CARD8 sisfb_lcda;
- unsigned int sisfb_pcibus; /* The card's PCI ID */
- unsigned int sisfb_pcislot;
- unsigned int sisfb_pcifunc;
+ CARD32 sisfb_vbflags;
+ CARD32 sisfb_currentvbflags;
- unsigned char sisfb_lcdpdc;
-
- unsigned char sisfb_lcda;
+ CARD32 sisfb_scalelcd;
+ CARD32 sisfb_specialtiming;
- unsigned long sisfb_vbflags;
- unsigned long sisfb_currentvbflags;
+ CARD8 sisfb_haveemi;
+ CARD8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+ CARD8 sisfb_haveemilcd;
- int sisfb_scalelcd;
- unsigned long sisfb_specialtiming;
+ CARD8 sisfb_lcdpdca;
- unsigned char sisfb_haveemi;
- unsigned char sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
- unsigned char sisfb_haveemilcd;
+ CARD16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
- char reserved[213]; /* for future use */
+ CARD8 reserved[208]; /* for future use */
};
#endif
/* $XFree86$ */
+/* $XdotOrg$ */
/*
* General structure definitions for universal mode switching modules
*
* * 2) Redistributions in binary form must reproduce the above copyright
* * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
- * * 3) All advertising materials mentioning features or use of this software
- * * must display the following acknowledgement: "This product includes
- * * software developed by Thomas Winischhofer, Vienna, Austria."
- * * 4) The name of the author may not be used to endorse or promote products
+ * * 3) The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission.
* *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
* * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
{
UCHAR Ext_ModeID;
USHORT Ext_ModeFlag;
- UCHAR Ext_ModeOffset;
USHORT Ext_VESAID;
UCHAR Ext_RESINFO;
UCHAR VB_ExtTVFlickerIndex;
UCHAR VB_ExtTVYFilterIndex;
UCHAR VB_ExtTVYFilterIndexROM661;
UCHAR REFindex;
+ CHAR ROMMODEIDX661;
} SiS_ExtStruct;
typedef struct _SiS_Ext2Struct
UCHAR Ext_CRT1CRTC;
UCHAR Ext_CRTVCLK;
UCHAR Ext_CRT2CRTC;
+ UCHAR Ext_CRT2CRTC_NS;
UCHAR ModeID;
USHORT XRes;
USHORT YRes;
UCHAR YChar;
} SiS_ModeResInfoStruct;
+
+
typedef UCHAR DRAM4Type[4];
/* Defines for SiS_CustomT */
USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
#endif
BOOLEAN SiS_UseROM;
- int SiS_CHOverScan;
+ BOOLEAN SiS_ROMNew;
+ BOOLEAN SiS_NeedRomModeData;
+ BOOLEAN PanelSelfDetected;
+ int SiS_CHOverScan;
BOOLEAN SiS_CHSOverScan;
BOOLEAN SiS_ChSW;
BOOLEAN SiS_UseLCDA;
- int SiS_UseOEM;
- ULONG SiS_CustomT;
- USHORT SiS_Backup70xx;
+ int SiS_UseOEM;
+ ULONG SiS_CustomT;
+ USHORT SiS_Backup70xx;
BOOLEAN HaveEMI;
BOOLEAN HaveEMILCD;
BOOLEAN OverruleEMI;
UCHAR EMI_30,EMI_31,EMI_32,EMI_33;
- UCHAR PDC;
+ SHORT PDC, PDCA;
UCHAR SiS_MyCR63;
USHORT SiS_CRT1Mode;
USHORT SiS_flag_clearbuffer;
USHORT SiS_DDC_DeviceAddr;
USHORT SiS_DDC_ReadAddr;
USHORT SiS_DDC_SecAddr;
+ USHORT SiS_ChrontelInit;
BOOLEAN SiS_SensibleSR11;
- USHORT SiS_Panel800x600;
- USHORT SiS_Panel1024x768;
- USHORT SiS_Panel1280x1024;
- USHORT SiS_Panel1600x1200;
- USHORT SiS_Panel1280x960;
- USHORT SiS_Panel1400x1050;
- USHORT SiS_Panel320x480;
- USHORT SiS_Panel1152x768;
- USHORT SiS_Panel1280x768;
- USHORT SiS_Panel1024x600;
- USHORT SiS_Panel640x480;
- USHORT SiS_Panel640x480_2;
- USHORT SiS_Panel640x480_3;
- USHORT SiS_Panel1152x864;
- USHORT SiS_PanelCustom;
- USHORT SiS_PanelBarco1366;
- USHORT SiS_PanelMax;
+ USHORT SiS661LCD2TableSize;
+
USHORT SiS_PanelMinLVDS;
USHORT SiS_PanelMin301;
- USHORT SiS_ChrontelInit;
-
+
const SiS_StStruct *SiS_SModeIDTable;
SiS_StandTableStruct *SiS_StandTable;
const SiS_ExtStruct *SiS_EModeIDTable;
const SiS_CRT1TableStruct *SiS_CRT1Table;
const SiS_MCLKDataStruct *SiS_MCLKData_0;
const SiS_MCLKDataStruct *SiS_MCLKData_1;
- const SiS_VCLKDataStruct *SiS_VCLKData;
- const SiS_VBVCLKDataStruct *SiS_VBVCLKData;
+ SiS_VCLKDataStruct *SiS_VCLKData;
+ SiS_VBVCLKDataStruct *SiS_VBVCLKData;
const SiS_StResInfoStruct *SiS_StResInfo;
const SiS_ModeResInfoStruct *SiS_ModeResInfo;
- const UCHAR *SiS_ScreenOffset;
const UCHAR *pSiS_OutputSelect;
const UCHAR *pSiS_SoftSetting;
const USHORT *pSiS_VideoSenseData2;
const USHORT *pSiS_YCSenseData2;
#endif
+
+ const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
+ const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+
+ /* SiS bridge */
+
const UCHAR *SiS_NTSCPhase;
const UCHAR *SiS_PALPhase;
const UCHAR *SiS_NTSCPhase2;
const UCHAR *SiS_SpecialPhase;
const UCHAR *SiS_SpecialPhaseM;
const UCHAR *SiS_SpecialPhaseJ;
- const SiS_LCDDataStruct *SiS_StLCD1024x768Data;
const SiS_LCDDataStruct *SiS_ExtLCD1024x768Data;
const SiS_LCDDataStruct *SiS_St2LCD1024x768Data;
- const SiS_LCDDataStruct *SiS_StLCD1280x1024Data;
+ const SiS_LCDDataStruct *SiS_LCD1280x720Data;
+ const SiS_LCDDataStruct *SiS_StLCD1280x768_2Data;
+ const SiS_LCDDataStruct *SiS_ExtLCD1280x768_2Data;
+ const SiS_LCDDataStruct *SiS_LCD1280x768_3Data;
+ const SiS_LCDDataStruct *SiS_LCD1280x800Data;
+ const SiS_LCDDataStruct *SiS_LCD1280x960Data;
const SiS_LCDDataStruct *SiS_ExtLCD1280x1024Data;
const SiS_LCDDataStruct *SiS_St2LCD1280x1024Data;
- const SiS_LCDDataStruct *SiS_NoScaleData1024x768;
- const SiS_LCDDataStruct *SiS_NoScaleData1280x1024;
- const SiS_LCDDataStruct *SiS_LCD1280x960Data;
- const SiS_LCDDataStruct *SiS_NoScaleData1400x1050;
- const SiS_LCDDataStruct *SiS_NoScaleData1600x1200;
- const SiS_LCDDataStruct *SiS_NoScaleData1280x768;
const SiS_LCDDataStruct *SiS_StLCD1400x1050Data;
- const SiS_LCDDataStruct *SiS_StLCD1600x1200Data;
- const SiS_LCDDataStruct *SiS_StLCD1280x768Data;
const SiS_LCDDataStruct *SiS_ExtLCD1400x1050Data;
+ const SiS_LCDDataStruct *SiS_StLCD1600x1200Data;
const SiS_LCDDataStruct *SiS_ExtLCD1600x1200Data;
- const SiS_LCDDataStruct *SiS_ExtLCD1280x768Data;
+ const SiS_LCDDataStruct *SiS_LCD1680x1050Data;
const SiS_LCDDataStruct *SiS_NoScaleData;
const SiS_TVDataStruct *SiS_StPALData;
const SiS_TVDataStruct *SiS_ExtPALData;
const UCHAR *SiS_HiTVTextTiming;
const UCHAR *SiS_HiTVGroup3Text;
#endif
- const SiS_PanelDelayTblStruct *SiS_PanelDelayTbl;
- const SiS_PanelDelayTblStruct *SiS_PanelDelayTblLVDS;
+
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
+ const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
+
+ /* LVDS, Chrontel */
+
const SiS_LVDSDataStruct *SiS_LVDS800x600Data_1;
const SiS_LVDSDataStruct *SiS_LVDS800x600Data_2;
const SiS_LVDSDataStruct *SiS_LVDS1024x768Data_1;
const SiS_LVDSDataStruct *SiS_LVDS640x480Data_1;
const SiS_LVDSDataStruct *SiS_LVDS640x480Data_2;
const SiS_LVDSDataStruct *SiS_LVDS320x480Data_1;
- const SiS_LVDSDataStruct *SiS_LCDA1024x768Data_1;
- const SiS_LVDSDataStruct *SiS_LCDA1024x768Data_2;
- const SiS_LVDSDataStruct *SiS_LCDA1280x1024Data_1;
- const SiS_LVDSDataStruct *SiS_LCDA1280x1024Data_2;
- const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_1;
- const SiS_LVDSDataStruct *SiS_LCDA1400x1050Data_2;
- const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_1;
- const SiS_LVDSDataStruct *SiS_LCDA1600x1200Data_2;
const SiS_LVDSDataStruct *SiS_LVDSXXXxXXXData_1;
const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_1;
const SiS_LVDSDataStruct *SiS_LVDSBARCO1366Data_2;
const SiS_LVDSDataStruct *SiS_CHTVUPALNData;
const SiS_LVDSDataStruct *SiS_CHTVOPALNData;
const SiS_LVDSDataStruct *SiS_CHTVSOPALData;
+
const SiS_LVDSDesStruct *SiS_PanelType00_1;
const SiS_LVDSDesStruct *SiS_PanelType01_1;
const SiS_LVDSDesStruct *SiS_PanelType02_1;
const SiS_LVDSDesStruct *SiS_PanelType0e_2;
const SiS_LVDSDesStruct *SiS_PanelType0f_2;
const SiS_LVDSDesStruct *SiS_PanelTypeNS_2;
-
- const SiS_LVDSDesStruct *LVDS1024x768Des_1;
- const SiS_LVDSDesStruct *LVDS1280x1024Des_1;
- const SiS_LVDSDesStruct *LVDS1400x1050Des_1;
- const SiS_LVDSDesStruct *LVDS1600x1200Des_1;
- const SiS_LVDSDesStruct *LVDS1024x768Des_2;
- const SiS_LVDSDesStruct *LVDS1280x1024Des_2;
- const SiS_LVDSDesStruct *LVDS1400x1050Des_2;
- const SiS_LVDSDesStruct *LVDS1600x1200Des_2;
-
const SiS_LVDSDesStruct *SiS_CHTVUNTSCDesData;
const SiS_LVDSDesStruct *SiS_CHTVONTSCDesData;
const SiS_LVDSDesStruct *SiS_CHTVUPALDesData;
const SiS_LVDSDesStruct *SiS_CHTVOPALDesData;
+
const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1800x600_1;
const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11024x768_1;
const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT11280x1024_1;
const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_2_H;
const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3;
const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1640x480_3_H;
+ const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1;
const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UNTSC;
const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1ONTSC;
const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1UPAL;
const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1OPAL;
const SiS_LVDSCRT1DataStruct *SiS_CHTVCRT1SOPAL;
- const SiS_LVDSCRT1DataStruct *SiS_LVDSCRT1320x480_1;
-
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_1;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_1;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_1_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_1_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_1_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_1_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11024x768_2_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11280x1024_2_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11400x1050_2_H;
- const SiS_LCDACRT1DataStruct *SiS_LCDACRT11600x1200_2_H;
-
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_1;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_2;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_2;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_2;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_2;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_3;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_3;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_3;
- const SiS_Part2PortTblStruct *SiS_CRT2Part2_1600x1200_3;
-
const SiS_CHTVRegDataStruct *SiS_CHTVReg_UNTSC;
const SiS_CHTVRegDataStruct *SiS_CHTVReg_ONTSC;
const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPAL;
const SiS_CHTVRegDataStruct *SiS_CHTVReg_UPALN;
const SiS_CHTVRegDataStruct *SiS_CHTVReg_OPALN;
const SiS_CHTVRegDataStruct *SiS_CHTVReg_SOPAL;
+
const UCHAR *SiS_CHTVVCLKUNTSC;
const UCHAR *SiS_CHTVVCLKONTSC;
const UCHAR *SiS_CHTVVCLKUPAL;
const UCHAR *SiS_CHTVVCLKOPALN;
const UCHAR *SiS_CHTVVCLKSOPAL;
- USHORT PanelXRes;
- USHORT PanelYRes;
-
+ USHORT PanelXRes, PanelHT;
+ USHORT PanelYRes, PanelVT;
+ USHORT PanelHRS, PanelHRE;
+ USHORT PanelVRS, PanelVRE;
+ USHORT PanelVCLKIdx300;
+ USHORT PanelVCLKIdx315;
+
BOOLEAN UseCustomMode;
BOOLEAN CRT1UsesCustomMode;
USHORT CHDisplay;
UCHAR Backup_1d;
int UsePanelScaler;
+ int CenterScreen;
USHORT CP_Vendor, CP_Product;
BOOLEAN CP_HaveCustomData;
- int CP_PreferredX, CP_PreferredY;
+ int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
int CP_MaxX, CP_MaxY, CP_MaxClock;
BOOLEAN CP_Supports64048075;
int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
info.fbops = &xxxfb_ops;
info.fix = xxxfb_fix;
info.pseudo_palette = pseudo_palette;
- info.flags = FBINFO_FLAG_DEFAULT;
+
+ /*
+ * Set up flags to indicate what sort of acceleration your
+ * driver can provide (pan/wrap/copyarea/etc.) and whether it
+ * is a module -- see FBINFO_* in include/linux/fb.h
+ */
+ info.flags = FBINFO_DEFAULT;
info.par = current_par;
/*
/* fills lfb with #arg pixels */
case _IOW('F', 0xdc, u32): /* 0x46dc */
- if (copy_from_user(&val, (void *)arg, sizeof(val)))
+ if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
return -EFAULT;
if (val > info->fix.smem_len)
val = info->fix.smem_len;
/* change VGA pass_through mode */
case _IOW('F', 0xdd, u32): /* 0x46dd */
- if (copy_from_user(&val, (void *)arg, sizeof(val)))
+ if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
return -EFAULT;
pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
vga16fb.par = &vga16_par;
vga16fb.flags = FBINFO_FLAG_DEFAULT;
- vga16fb.fix.smem_start = VGA_MAP_MEM(vga16fb.fix.smem_start);
-
i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
ret = fb_alloc_cmap(&vga16fb.cmap, i, 0);
if (ret) {
static int afs_file_invalidatepage(struct page *page, unsigned long offset);
static int afs_file_releasepage(struct page *page, int gfp_flags);
-static ssize_t afs_file_write(struct file *file, const char *buf, size_t size,
- loff_t *off);
+static ssize_t afs_file_write(struct file *file, const char __user *buf,
+ size_t size, loff_t *off);
struct inode_operations afs_file_inode_operations = {
.getattr = afs_inode_getattr,
/*
* AFS file write
*/
-static ssize_t afs_file_write(struct file *file, const char *buf, size_t size,
- loff_t *off)
+static ssize_t afs_file_write(struct file *file, const char __user *buf,
+ size_t size, loff_t *off)
{
struct afs_vnode *vnode;
static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos);
static void afs_proc_cells_stop(struct seq_file *p, void *v);
static int afs_proc_cells_show(struct seq_file *m, void *v);
-static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
+static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
size_t size, loff_t *_pos);
static struct seq_operations afs_proc_cells_ops = {
static int afs_proc_rootcell_open(struct inode *inode, struct file *file);
static int afs_proc_rootcell_release(struct inode *inode, struct file *file);
-static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
+static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
size_t size, loff_t *_pos);
-static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
+static ssize_t afs_proc_rootcell_write(struct file *file,
+ const char __user *buf,
size_t size, loff_t *_pos);
static struct file_operations afs_proc_rootcell_fops = {
* handle writes to /proc/fs/afs/cells
* - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]"
*/
-static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
+static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
size_t size, loff_t *_pos)
{
char *kbuf, *name, *args;
return 0;
}
-static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
+static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
size_t size, loff_t *_pos)
{
return 0;
* handle writes to /proc/fs/afs/rootcell
* - to initialize rootcell: echo "cell.name:192.168.231.14"
*/
-static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
+static ssize_t afs_proc_rootcell_write(struct file *file,
+ const char __user *buf,
size_t size, loff_t *_pos)
{
char *kbuf, *s;
#include <linux/aio_abi.h>
#include <linux/module.h>
-//#define DEBUG 1
+#define DEBUG 0
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/aio.h>
#include <linux/highmem.h>
#include <linux/workqueue.h>
+#include <linux/security.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
req->ki_ctx = ctx;
req->ki_cancel = NULL;
req->ki_retry = NULL;
- req->ki_user_obj = NULL;
+ req->ki_obj.user = NULL;
/* Check if the completion queue has enough free space to
* accept an event from this io.
{
req->ki_ctx = NULL;
req->ki_filp = NULL;
- req->ki_user_obj = NULL;
+ req->ki_obj.user = NULL;
kmem_cache_free(kiocb_cachep, req);
ctx->reqs_active--;
* single context. */
if (is_sync_kiocb(iocb)) {
kiocbSetKicked(iocb);
- wake_up_process(iocb->ki_user_obj);
+ wake_up_process(iocb->ki_obj.tsk);
return;
}
spin_unlock_irq(&ctx->ctx_lock);
}
/* sync iocbs put the task here for us */
- wake_up_process(iocb->ki_user_obj);
+ wake_up_process(iocb->ki_obj.tsk);
return ret;
}
event = aio_ring_event(info, tail, KM_IRQ0);
tail = (tail + 1) % info->nr;
- event->obj = (u64)(unsigned long)iocb->ki_user_obj;
+ event->obj = (u64)(unsigned long)iocb->ki_obj.user;
event->data = iocb->ki_user_data;
event->res = res;
event->res2 = res2;
dprintk("aio_complete: %p[%lu]: %p: %p %Lx %lx %lx\n",
- ctx, tail, iocb, iocb->ki_user_obj, iocb->ki_user_data,
+ ctx, tail, iocb, iocb->ki_obj.user, iocb->ki_user_data,
res, res2);
/* after flagging the request as done, we
static inline void set_timeout(long start_jiffies, struct timeout *to,
const struct timespec *ts)
{
- unsigned long how_long;
-
- if (ts->tv_sec < 0 || (!ts->tv_sec && !ts->tv_nsec)) {
+ to->timer.expires = start_jiffies + timespec_to_jiffies(ts);
+ if (time_after(to->timer.expires, jiffies))
+ add_timer(&to->timer);
+ else
to->timed_out = 1;
- return;
- }
-
- how_long = ts->tv_sec * HZ;
-#define HZ_NS (1000000000 / HZ)
- how_long += (ts->tv_nsec + HZ_NS - 1) / HZ_NS;
-
- to->timer.expires = jiffies + how_long;
- add_timer(&to->timer);
}
static inline void clear_timeout(struct timeout *to)
ret = put_user(ioctx->user_id, ctxp);
if (!ret)
return 0;
+ get_ioctx(ioctx);
io_destroy(ioctx);
}
goto out_put_req;
}
- req->ki_user_obj = user_iocb;
+ req->ki_obj.user = user_iocb;
req->ki_user_data = iocb->aio_data;
req->ki_pos = iocb->aio_offset;
ret = -EFAULT;
if (unlikely(!access_ok(VERIFY_WRITE, buf, iocb->aio_nbytes)))
goto out_put_req;
+ ret = security_file_permission (file, MAY_READ);
+ if (ret)
+ goto out_put_req;
ret = -EINVAL;
if (file->f_op->aio_read)
ret = file->f_op->aio_read(req, buf,
ret = -EFAULT;
if (unlikely(!access_ok(VERIFY_READ, buf, iocb->aio_nbytes)))
goto out_put_req;
+ ret = security_file_permission (file, MAY_WRITE);
+ if (ret)
+ goto out_put_req;
ret = -EINVAL;
if (file->f_op->aio_write)
ret = file->f_op->aio_write(req, buf,
/* TODO: use a hash or array, this sucks. */
list_for_each(pos, &ctx->active_reqs) {
struct kiocb *kiocb = list_kiocb(pos);
- if (kiocb->ki_user_obj == iocb && kiocb->ki_key == key)
+ if (kiocb->ki_obj.user == iocb && kiocb->ki_key == key)
return kiocb;
}
return NULL;
struct io_event tmp;
pr_debug("calling cancel\n");
memset(&tmp, 0, sizeof(tmp));
- tmp.obj = (u64)(unsigned long)kiocb->ki_user_obj;
+ tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user;
tmp.data = kiocb->ki_user_data;
ret = cancel(kiocb, &tmp);
if (!ret) {
/* Get/set timeout ioctl() operation */
static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
- unsigned long *p)
+ unsigned long __user *p)
{
unsigned long ntimeout;
}
/* Return protocol version */
-static inline int autofs_get_protover(int *p)
+static inline int autofs_get_protover(int __user *p)
{
return put_user(AUTOFS_PROTO_VERSION, p);
}
static inline int autofs_expire_run(struct super_block *sb,
struct autofs_sb_info *sbi,
struct vfsmount *mnt,
- struct autofs_packet_expire *pkt_p)
+ struct autofs_packet_expire __user *pkt_p)
{
struct autofs_dir_ent *ent;
struct autofs_packet_expire pkt;
unsigned int cmd, unsigned long arg)
{
struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
+ void __user *argp = (void __user *)arg;
DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
autofs_catatonic_mode(sbi);
return 0;
case AUTOFS_IOC_PROTOVER: /* Get protocol version */
- return autofs_get_protover((int *)arg);
+ return autofs_get_protover(argp);
case AUTOFS_IOC_SETTIMEOUT:
- return autofs_get_set_timeout(sbi,(unsigned long *)arg);
+ return autofs_get_set_timeout(sbi, argp);
case AUTOFS_IOC_EXPIRE:
return autofs_expire_run(inode->i_sb, sbi, filp->f_vfsmnt,
- (struct autofs_packet_expire *)arg);
+ argp);
default:
return -ENOSYS;
}
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
/* make sure we actually have a data and stack area to dump */
set_fs(USER_DS);
#ifdef __sparc__
- if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize))
+ if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize))
dump.u_dsize = 0;
- if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize))
+ if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize))
dump.u_ssize = 0;
#else
- if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
+ if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
dump.u_dsize = 0;
- if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
+ if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
dump.u_ssize = 0;
#endif
* memory and creates the pointer tables from them, and puts their
* addresses on the "stack", returning the new stack pointer value.
*/
-static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm)
+static unsigned long __user *create_aout_tables(char __user *p, struct linux_binprm * bprm)
{
- char **argv, **envp;
- unsigned long * sp;
+ char __user * __user *argv;
+ char __user * __user *envp;
+ unsigned long __user *sp;
int argc = bprm->argc;
int envc = bprm->envc;
- sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
+ sp = (void __user *)((-(unsigned long)sizeof(char *)) & (unsigned long) p);
#ifdef __sparc__
/* This imposes the proper stack alignment for a new process. */
- sp = (unsigned long *) (((unsigned long) sp) & ~7);
+ sp = (void __user *) (((unsigned long) sp) & ~7);
if ((envc+argc+3)&1) --sp;
#endif
#ifdef __alpha__
put_user(0x3e9, --sp);
#endif
sp -= envc+1;
- envp = (char **) sp;
+ envp = (char __user * __user *) sp;
sp -= argc+1;
- argv = (char **) sp;
+ argv = (char __user * __user *) sp;
#if defined(__i386__) || defined(__mc68000__) || defined(__arm__) || defined(__arch_um__)
put_user((unsigned long) envp,--sp);
put_user((unsigned long) argv,--sp);
}
current->mm->start_stack =
- (unsigned long) create_aout_tables((char *) bprm->p, bprm);
+ (unsigned long) create_aout_tables((char __user *) bprm->p, bprm);
#ifdef __alpha__
regs->gp = ex.a_gpvalue;
#endif
#include <asm/uaccess.h>
#include <asm/param.h>
-#include <asm/pgalloc.h>
#include <linux/elf.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/unaligned.h>
#include <asm/cacheflush.h>
enum {Enabled, Magic};
#define MISC_FMT_PRESERVE_ARGV0 (1<<31)
+#define MISC_FMT_OPEN_BINARY (1<<30)
+#define MISC_FMT_CREDENTIALS (1<<29)
typedef struct {
struct list_head list;
static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{
Node *fmt;
- struct file * file;
+ struct file * interp_file = NULL;
char iname[BINPRM_BUF_SIZE];
char *iname_addr = iname;
int retval;
+ int fd_binary = -1;
+ char fd_str[12];
+ struct files_struct *files = NULL;
retval = -ENOEXEC;
if (!enabled)
if (!fmt)
goto _ret;
- allow_write_access(bprm->file);
- fput(bprm->file);
- bprm->file = NULL;
-
- /* Build args for interpreter */
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
remove_arg_zero(bprm);
}
- retval = copy_strings_kernel(1, &bprm->interp, bprm);
- if (retval < 0) goto _ret;
- bprm->argc++;
- retval = copy_strings_kernel(1, &iname_addr, bprm);
- if (retval < 0) goto _ret;
- bprm->argc++;
- bprm->interp = iname; /* for binfmt_script */
- file = open_exec(iname);
- retval = PTR_ERR(file);
- if (IS_ERR(file))
- goto _ret;
- bprm->file = file;
+ if (fmt->flags & MISC_FMT_OPEN_BINARY) {
+ char *fdsp = fd_str;
+
+ files = current->files;
+ retval = unshare_files();
+ if (retval < 0)
+ goto _ret;
+ if (files == current->files) {
+ put_files_struct(files);
+ files = NULL;
+ }
+ /* if the binary should be opened on behalf of the
+ * interpreter than keep it open and assign descriptor
+ * to it */
+ fd_binary = get_unused_fd();
+ if (fd_binary < 0) {
+ retval = fd_binary;
+ goto _unshare;
+ }
+ fd_install(fd_binary, bprm->file);
+
+ /* if the binary is not readable than enforce mm->dumpable=0
+ regardless of the interpreter's permissions */
+ if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL))
+ bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+
+ allow_write_access(bprm->file);
+ bprm->file = NULL;
+
+ /* make argv[1] be the file descriptor of the binary */
+ snprintf(fd_str, sizeof(fd_str), "%d", fd_binary);
+ retval = copy_strings_kernel(1, &fdsp, bprm);
+ if (retval < 0)
+ goto _error;
+ bprm->argc++;
+
+ } else {
+ allow_write_access(bprm->file);
+ fput(bprm->file);
+ bprm->file = NULL;
+ /* make argv[1] be the path to the binary */
+ retval = copy_strings_kernel (1, &bprm->interp, bprm);
+ if (retval < 0)
+ goto _error;
+ bprm->argc++;
+ }
+ retval = copy_strings_kernel (1, &iname_addr, bprm);
+ if (retval < 0)
+ goto _error;
+ bprm->argc ++;
+ bprm->interp = iname; /* for binfmt_script */
- retval = prepare_binprm(bprm);
- if (retval >= 0)
- retval = search_binary_handler(bprm, regs);
+ interp_file = open_exec (iname);
+ retval = PTR_ERR (interp_file);
+ if (IS_ERR (interp_file))
+ goto _error;
+
+ bprm->file = interp_file;
+ if (fmt->flags & MISC_FMT_CREDENTIALS) {
+ /*
+ * No need to call prepare_binprm(), it's already been
+ * done. bprm->buf is stale, update from interp_file.
+ */
+ memset(bprm->buf, 0, BINPRM_BUF_SIZE);
+ retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
+ } else
+ retval = prepare_binprm (bprm);
+
+ if (retval < 0)
+ goto _error;
+
+ retval = search_binary_handler (bprm, regs);
+ if (retval < 0)
+ goto _error;
+
+ if (files) {
+ steal_locks(files);
+ put_files_struct(files);
+ files = NULL;
+ }
_ret:
return retval;
+_error:
+ if (fd_binary > 0)
+ sys_close(fd_binary);
+ bprm->interp_flags = 0;
+_unshare:
+ if (files) {
+ put_files_struct(current->files);
+ current->files = files;
+ }
+ goto _ret;
}
/* Command parsers */
return p - from;
}
+static inline char * check_special_flags (char * sfs, Node * e)
+{
+ char * p = sfs;
+ int cont = 1;
+
+ /* special flags */
+ while (cont) {
+ switch (*p) {
+ case 'P':
+ p++;
+ e->flags |= MISC_FMT_PRESERVE_ARGV0;
+ break;
+ case 'O':
+ p++;
+ e->flags |= MISC_FMT_OPEN_BINARY;
+ break;
+ case 'C':
+ p++;
+ /* this flags also implies the
+ open-binary flag */
+ e->flags |= (MISC_FMT_CREDENTIALS |
+ MISC_FMT_OPEN_BINARY);
+ break;
+ default:
+ cont = 0;
+ }
+ }
+
+ return p;
+}
/*
* This registers a new binary format, it recognises the syntax
- * ':name:type:offset:magic:mask:interpreter:'
+ * ':name:type:offset:magic:mask:interpreter:flags'
* where the ':' is the IFS, that can be chosen with the first char
*/
-static Node *create_entry(const char *buffer, size_t count)
+static Node *create_entry(const char __user *buffer, size_t count)
{
Node *e;
int memsize, err;
if (!e->interpreter[0])
goto Einval;
- if (*p == 'P') {
- p++;
- e->flags |= MISC_FMT_PRESERVE_ARGV0;
- }
+
+ p = check_special_flags (p, e);
if (*p == '\n')
p++;
* Set status of entry/binfmt_misc:
* '1' enables, '0' disables and '-1' clears entry/binfmt_misc
*/
-static int parse_command(const char *buffer, size_t count)
+static int parse_command(const char __user *buffer, size_t count)
{
char s[4];
{
char *dp;
char *status = "disabled";
+ const char * flags = "flags: ";
if (test_bit(Enabled, &e->flags))
status = "enabled";
sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter);
dp = page + strlen(page);
+
+ /* print the special flags */
+ sprintf (dp, "%s", flags);
+ dp += strlen (flags);
+ if (e->flags & MISC_FMT_PRESERVE_ARGV0) {
+ *dp ++ = 'P';
+ }
+ if (e->flags & MISC_FMT_OPEN_BINARY) {
+ *dp ++ = 'O';
+ }
+ if (e->flags & MISC_FMT_CREDENTIALS) {
+ *dp ++ = 'C';
+ }
+ *dp ++ = '\n';
+
+
if (!test_bit(Magic, &e->flags)) {
sprintf(dp, "extension .%s\n", e->magic);
} else {
/* /<entry> */
static ssize_t
-bm_entry_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
{
Node *e = file->f_dentry->d_inode->u.generic_ip;
loff_t pos = *ppos;
return res;
}
-static ssize_t bm_entry_write(struct file *file, const char *buffer,
+static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct dentry *root;
/* /register */
-static ssize_t bm_register_write(struct file *file, const char *buffer,
+static ssize_t bm_register_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
Node *e;
/* /status */
static ssize_t
-bm_status_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
char *s = enabled ? "enabled" : "disabled";
int len = strlen(s);
return nbytes;
}
-static ssize_t bm_status_write(struct file * file, const char * buffer,
+static ssize_t bm_status_write(struct file * file, const char __user * buffer,
size_t count, loff_t *ppos)
{
int res = parse_command(buffer, count);
Shobhit Dayal
Sergey Vlasov
Richard Hughes
+Yury Umanets
Test case and Bug Report contributors
-------------------------------------
and debug of problems they have found: Jochen Dolze, David Blaine,
Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori,
Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen,
-Kieron Briggs and others.
+Olaf Kirch, Kieron Briggs and others.
+And thanks to the IBM LTC and Power test teams and SuSE testers for
+finding multiple bugs during excellent stress test runs.
+Version 1.18
+------------
+Do not rename hardlinked files (since that should be a noop). Flush
+cached write behind data when reopening a file after session abend,
+except when already in write. Grab per socket sem during reconnect
+to avoid oops in sendmsg if overlapping with reconnect.
+
+
+Version 1.17
+------------
+Update number of blocks in file so du command is happier (in Linux a fake
+blocksize of 512 is required for calculating number of blocks in inode).
+Fix prepare write of partial pages to read in data from server if possible.
+Fix race on tcpStatus field between unmount and reconnection code, causing
+cifsd process sometimes to hang around forever. Improve out of memory
+checks in cifs_filldir
+
Version 1.16
------------
Fix incorrect file size in file handle based setattr on big endian hardware.
case sensitive = yes
delete readonly = yes
-
+ ea support = yes
+
+Note that ea support is required for supporting Linux xattrs.
Some administrators also change the "map archive" and the "create mask"
parameters from their default values. Creating special devices (mknod) remotely
may require specifying a mkdev function to Samba. For more information on these
=======================================
Informational pseudo-files:
DebugData Displays information about active CIFS sessions
- as well as per share statistics (if CONFIG_CIFS_STATS
- is enabled in the kernel configuration).
+ and shares.
SimultaneousOps Counter which holds maximum number of
simultaneous outstanding SMB/CIFS requests.
-Stats Lists summary resource usage information
+Stats Lists summary resource usage information as well as per
+ share statistics, if CONFIG_CIFS_STATS in enabled
+ in the kernel configuration.
Configuration pseudo-files:
MultiuserMount If set to one, more than one CIFS session to
but recognizes them
3) create of new files to FAT partitions on Windows servers can
succeed but still return access denied (appears to be Windows
-not client problem) and has not been reproduced recently.
+server not cifs client problem) and has not been reproduced recently.
NTFS partitions do not have this problem.
4) debug connectation lock test case 10 which fails against
Samba (may be unmappable due to POSIX to Windows lock model
differences but worth investigating). Also debug Samba to
see why lock test case 7 takes longer to complete to Samba
than to Windows.
-5) prepare_write does not initialize pages properly when partial
-page writes begin in the middle of a page (pages can get zeroed).
-6) Write caching done incorrectly when files are only opened
-with write permission by the application.
-7) Rename of files that are hardlinked does not work correctly e.g.
- ln source target
- mv source target
-This should be no op since files are linked but in cifs it causes
-the source file to go away. This may require implementation of
-the cifs POSIX extensions (Unix Extensions version 2) for
-it to be done correctly since Samba is failing the rename,
-(rather than ignoring it) so the client not knowing they
-are linked proceeds to delete the target and then retry the
-move which succeeds this time (but the source is gone).
Misc testing to do
==================
sprintf(buf, " type: %d ",
tcon->fsDevInfo.DeviceType);
buf += length;
- if(tcon->tidStatus == CifsNeedReconnect)
+ if(tcon->tidStatus == CifsNeedReconnect) {
buf += sprintf(buf, "\tDISCONNECTED ");
-#ifdef CONFIG_CIFS_STATS
- length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
- atomic_read(&tcon->num_smbs_sent),
- atomic_read(&tcon->num_oplock_brks));
- buf += length;
- length = sprintf(buf,"\nReads: %d Bytes %lld",
- atomic_read(&tcon->num_reads),
- (long long)(tcon->bytes_read));
- buf += length;
- length = sprintf(buf,"\nWrites: %d Bytes: %lld",
- atomic_read(&tcon->num_writes),
- (long long)(tcon->bytes_written));
- buf += length;
- length = sprintf(buf,
- "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
- atomic_read(&tcon->num_opens),
- atomic_read(&tcon->num_deletes),
- atomic_read(&tcon->num_mkdirs),
- atomic_read(&tcon->num_rmdirs));
- buf += length;
-#endif
-
+ length += 14;
+ }
}
read_unlock(&GlobalSMBSeslock);
return length;
}
+#ifdef CONFIG_CIFS_STATS
int
cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
int length, int *eof, void *data)
{
- int item_length;
- length =
- sprintf(buf,
- "Currently Allocated structures\nCIFS Sessions: %d\n",sesInfoAllocCount.counter);
+ int item_length,i;
+ struct list_head *tmp;
+ struct cifsTconInfo *tcon;
+
+ length = sprintf(buf,
+ "Resources in use\nCIFS Session: %d\n",
+ sesInfoAllocCount.counter);
buf += length;
item_length =
- sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter);
+ sprintf(buf,"Share (unique mount targets): %d\n",
+ tconInfoAllocCount.counter);
length += item_length;
buf += item_length;
item_length =
- sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter);
+ sprintf(buf,"SMB Request/Response Buffer: %d\n",
+ bufAllocCount.counter);
length += item_length;
buf += item_length;
item_length =
- sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter);
+ sprintf(buf,"Operations (MIDs): %d\n",
+ midCount.counter);
length += item_length;
buf += item_length;
- item_length = sprintf(buf,"%d sessions and %d shares reconnected after failure\n",tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
+ item_length = sprintf(buf,
+ "\n%d session %d share reconnects\n",
+ tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
length += item_length;
+ buf += item_length;
+
+ i = 0;
+ read_lock(&GlobalSMBSeslock);
+ list_for_each(tmp, &GlobalTreeConnectionList) {
+ i++;
+ tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
+ item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName);
+ buf += item_length;
+ length += item_length;
+ if(tcon->tidStatus == CifsNeedReconnect) {
+ buf += sprintf(buf, "\tDISCONNECTED ");
+ length += 14;
+ }
+ item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
+ atomic_read(&tcon->num_smbs_sent),
+ atomic_read(&tcon->num_oplock_brks));
+ buf += item_length;
+ length += item_length;
+ item_length = sprintf(buf,"\nReads: %d Bytes %lld",
+ atomic_read(&tcon->num_reads),
+ (long long)(tcon->bytes_read));
+ buf += item_length;
+ item_length = sprintf(buf,"\nWrites: %d Bytes: %lld",
+ atomic_read(&tcon->num_writes),
+ (long long)(tcon->bytes_written));
+ buf += item_length;
+ item_length = sprintf(buf,
+ "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
+ atomic_read(&tcon->num_opens),
+ atomic_read(&tcon->num_deletes),
+ atomic_read(&tcon->num_mkdirs),
+ atomic_read(&tcon->num_rmdirs));
+ buf += item_length;
+ length += item_length;
+ }
+ read_unlock(&GlobalSMBSeslock);
+
return length;
}
+#endif
struct proc_dir_entry *proc_fs_cifs;
read_proc_t cifs_txanchor_read;
create_proc_read_entry("SimultaneousOps", 0, proc_fs_cifs,
cifs_total_xid_read, 0);
-
+#ifdef CONFIG_CIFS_STATS
create_proc_read_entry("Stats", 0, proc_fs_cifs,
cifs_stats_read, 0);
-
+#endif
pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
cifsFYI_read, 0);
if (pde)
remove_proc_entry("cifsFYI", proc_fs_cifs);
remove_proc_entry("traceSMB", proc_fs_cifs);
remove_proc_entry("SimultaneousOps", proc_fs_cifs);
+#ifdef CONFIG_CIFS_STATS
remove_proc_entry("Stats", proc_fs_cifs);
+#endif
remove_proc_entry("MultiuserMount", proc_fs_cifs);
remove_proc_entry("OplockEnabled", proc_fs_cifs);
remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
return len;
}
static int
-cifsFYI_write(struct file *file, const char *buffer,
+cifsFYI_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-oplockEnabled_write(struct file *file, const char *buffer,
+oplockEnabled_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-quotaEnabled_write(struct file *file, const char *buffer,
+quotaEnabled_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-linuxExtensionsEnabled_write(struct file *file, const char *buffer,
+linuxExtensionsEnabled_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-lookupFlag_write(struct file *file, const char *buffer,
+lookupFlag_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-traceSMB_write(struct file *file, const char *buffer,
+traceSMB_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-multiuser_mount_write(struct file *file, const char *buffer,
+multiuser_mount_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-extended_security_write(struct file *file, const char *buffer,
+extended_security_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-ntlmv2_enabled_write(struct file *file, const char *buffer,
+ntlmv2_enabled_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
return len;
}
static int
-packet_signing_enabled_write(struct file *file, const char *buffer,
+packet_signing_enabled_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char c;
}
static ssize_t
-cifs_read_wrapper(struct file * file, char *read_data, size_t read_size,
+cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
loff_t * poffset)
{
if(file == NULL)
}
static ssize_t
-cifs_write_wrapper(struct file * file, const char *write_data,
+cifs_write_wrapper(struct file * file, const char __user *write_data,
size_t write_size, loff_t * poffset)
{
ssize_t written;
/* Functions related to symlinks */
extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
-extern int cifs_readlink(struct dentry *direntry, char *buffer, int buflen);
+extern int cifs_readlink(struct dentry *direntry, char __user *buffer, int buflen);
extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
const char *symname);
extern int cifs_removexattr(struct dentry *, const char *);
size_t, int);
extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
-#define CIFS_VERSION "1.16"
+#define CIFS_VERSION "1.18"
#endif /* _CIFSFS_H */
__u16 ByteCount; /* bct = 0 */
} CREATE_DIRECTORY_RSP;
+/***************************************************/
+/* NT Transact structure defintions follow */
+/* Currently only ioctl and notify are implemented */
+/***************************************************/
typedef struct smb_com_transaction_ioctl_req {
struct smb_hdr hdr; /* wct = 23 */
__u8 MaxSetupCount;
} TRANSACT_IOCTL_RSP;
typedef struct smb_com_transaction_change_notify_req {
- struct smb_hdr hdr; /* wct = 23 */
- __u8 MaxSetupCount;
- __u16 Reserved;
- __u32 TotalParameterCount;
- __u32 TotalDataCount;
- __u32 MaxParameterCount;
- __u32 MaxDataCount;
- __u32 ParameterCount;
- __u32 ParameterOffset;
- __u32 DataCount;
- __u32 DataOffset;
- __u8 SetupCount; /* four setup words follow subcommand */
- /* SNIA spec incorrectly included spurious pad here */
- __u16 SubCommand;/* 4 = Change Notify */
+ struct smb_hdr hdr; /* wct = 23 */
+ __u8 MaxSetupCount;
+ __u16 Reserved;
+ __u32 TotalParameterCount;
+ __u32 TotalDataCount;
+ __u32 MaxParameterCount;
+ __u32 MaxDataCount;
+ __u32 ParameterCount;
+ __u32 ParameterOffset;
+ __u32 DataCount;
+ __u32 DataOffset;
+ __u8 SetupCount; /* four setup words follow subcommand */
+ /* SNIA spec incorrectly included spurious pad here */
+ __u16 SubCommand;/* 4 = Change Notify */
__u32 CompletionFilter; /* operation to monitor */
__u16 Fid;
__u8 WatchTree; /* 1 = Monitor subdirectories */
+ __u8 Reserved2;
__u16 ByteCount;
- __u8 Pad[3];
- __u8 Data[1];
+/* __u8 Pad[3];*/
+/* __u8 Data[1];*/
} TRANSACT_CHANGE_NOTIFY_REQ;
-/* Completion Filter flags */
+typedef struct smb_com_transaction_change_notify_rsp {
+ struct smb_hdr hdr; /* wct = 18 */
+ __u8 Reserved[3];
+ __u32 TotalParameterCount;
+ __u32 TotalDataCount;
+ __u32 ParameterCount;
+ __u32 ParameterOffset;
+ __u32 ParameterDisplacement;
+ __u32 DataCount;
+ __u32 DataOffset;
+ __u32 DataDisplacement;
+ __u8 SetupCount; /* 0 */
+ __u16 ByteCount;
+ /* __u8 Pad[3]; */
+} TRANSACT_CHANGE_NOTIFY_RSP;
+/* Completion Filter flags for Notify */
#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
#define FILE_NOTIFY_CHANGE_NAME 0x00000003
/* PathInfo/FileInfo infolevels */
#define SMB_INFO_STANDARD 1
+#define SMB_INFO_QUERY_EAS_FROM_LIST 3
+#define SMB_INFO_QUERY_ALL_EAS 4
#define SMB_INFO_IS_NAME_VALID 6
#define SMB_QUERY_FILE_BASIC_INFO 0x101
#define SMB_QUERY_FILE_STANDARD_INFO 0x102
+#define SMB_QUERY_FILE_EA_INFO 0x103
#define SMB_QUERY_FILE_NAME_INFO 0x104
#define SMB_QUERY_FILE_ALLOCATION_INFO 0x105
#define SMB_QUERY_FILE_END_OF_FILEINFO 0x106
};
struct fea {
- unsigned char fEA;
- unsigned char cbName;
- unsigned short cbValue;
+ unsigned char EA_flags;
+ __u8 name_len;
+ __u16 value_len;
char szName[1];
+ /* optionally followed by value */
};
/* flags for _FEA.fEA */
#define FEA_NEEDEA 0x80 /* need EA bit */
struct fealist {
- unsigned long cbList;
+ __u32 list_len;
struct fea list[1];
};
const __u16 target_tid,
const char *toName, const int flags,
const struct nls_table *nls_codepage);
+extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
+ const int notify_subdirs,const __u16 netfid,__u32 filter,
+ const struct nls_table *nls_codepage);
+extern int CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+ const unsigned char *searchName,
+ char * EAData, size_t size,
+ const struct nls_table *nls_codepage);
#endif /* _CIFSPROTO_H */
smb_buffer_response, &length, 0);
if (ses->server) {
atomic_dec(&ses->server->socketUseCount);
- if (atomic_read(&ses->server->socketUseCount) == 0)
+ if (atomic_read(&ses->server->socketUseCount) == 0) {
+ spin_lock(&GlobalMid_Lock);
ses->server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
+ }
}
if (pSMB)
cifs_buf_release(pSMB);
pSMB->TotalParameterCount = 0 ;
pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
+ pSMB->MaxParameterCount = cpu_to_le32(2);
/* BB find exact data count max from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
+ pSMB->MaxDataCount = cpu_to_le32(4000);
pSMB->MaxSetupCount = 4;
pSMB->Reserved = 0;
pSMB->ParameterOffset = 0;
} else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
/* BB also check enough total bytes returned */
+ /* BB we need to improve the validity checking
+ of these trans2 responses */
if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
rc = -EIO; /* bad smb */
else if (pFindData){
goto setPermsRetry;
return rc;
}
+
+int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
+ const int notify_subdirs, const __u16 netfid,
+ __u32 filter, const struct nls_table *nls_codepage)
+{
+ int rc = 0;
+ struct smb_com_transaction_change_notify_req * pSMB = NULL;
+ struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
+ int bytes_returned;
+
+ cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
+ rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ pSMB->TotalParameterCount = 0 ;
+ pSMB->TotalDataCount = 0;
+ pSMB->MaxParameterCount = cpu_to_le32(2);
+ /* BB find exact data count max from sess structure BB */
+ pSMB->MaxDataCount = 0; /* same in little endian or be */
+ pSMB->MaxSetupCount = 4;
+ pSMB->Reserved = 0;
+ pSMB->ParameterOffset = 0;
+ pSMB->DataCount = 0;
+ pSMB->DataOffset = 0;
+ pSMB->SetupCount = 4; /* single byte does not need le conversion */
+ pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
+ if(notify_subdirs)
+ pSMB->WatchTree = 1; /* one byte - no le conversion needed */
+ pSMB->Reserved2 = 0;
+ pSMB->CompletionFilter = cpu_to_le32(filter);
+ pSMB->Fid = netfid; /* file handle always le */
+ pSMB->ByteCount = 0;
+
+ pSMB->hdr.smb_buf_length += pSMB->ByteCount;
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Error in Notify = %d", rc));
+ }
+ if (pSMB)
+ cifs_buf_release(pSMB);
+/* if (rc == -EAGAIN)
+ goto NotifyRetry; */
+ return rc;
+}
+#ifdef CONFIG_CIFS_XATTR
+int
+CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+ const unsigned char *searchName,
+ char * EAData, size_t size,
+ const struct nls_table *nls_codepage)
+{
+ /* BB assumes one setup word */
+ TRANSACTION2_QPI_REQ *pSMB = NULL;
+ TRANSACTION2_QPI_RSP *pSMBr = NULL;
+ int rc = 0;
+ int bytes_returned;
+ int name_len;
+
+ cFYI(1, ("In Query All EAs path %s", searchName));
+QAllEAsRetry:
+ rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
+ name_len =
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
+ /* find define for this maxpathcomponent */
+ , nls_codepage);
+ name_len++; /* trailing null */
+ name_len *= 2;
+ } else { /* BB improve the check for buffer overruns BB */
+ name_len = strnlen(searchName, 530);
+ name_len++; /* trailing null */
+ strncpy(pSMB->FileName, searchName, name_len);
+ }
+
+ pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ +
+ name_len /* includes null */ ;
+ pSMB->TotalDataCount = 0;
+ pSMB->MaxParameterCount = cpu_to_le16(2);
+ pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
+ pSMB->MaxSetupCount = 0;
+ pSMB->Reserved = 0;
+ pSMB->Flags = 0;
+ pSMB->Timeout = 0;
+ pSMB->Reserved2 = 0;
+ pSMB->ParameterOffset = cpu_to_le16(offsetof(
+ struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
+ pSMB->DataCount = 0;
+ pSMB->DataOffset = 0;
+ pSMB->SetupCount = 1;
+ pSMB->Reserved3 = 0;
+ pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
+ pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
+ pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
+ pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
+ pSMB->Reserved4 = 0;
+ pSMB->hdr.smb_buf_length += pSMB->ByteCount;
+ pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
+ if (rc) {
+ cFYI(1, ("Send error in QueryAllEAs = %d", rc));
+ } else { /* decode response */
+ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
+ /* BB also check enough total bytes returned */
+ /* BB we need to improve the validity checking
+ of these trans2 responses */
+ if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512))
+ rc = -EIO; /* bad smb */
+ /* else if (pFindData){
+ memcpy((char *) pFindData,
+ (char *) &pSMBr->hdr.Protocol +
+ pSMBr->DataOffset, kl);
+ }*/ else {
+ /* check that length of list is not more than bcc */
+ /* check that each entry does not go beyond length
+ of list */
+ /* check that each element of each entry does not
+ go beyond end of list */
+ struct fealist * ea_response_data;
+ rc = 0;
+ /* validate_trans2_offsets() */
+ /* BB to check if(start of smb + pSMBr->DataOffset > &bcc+ bcc)*/
+ ea_response_data = (struct fealist *)
+ (((char *) &pSMBr->hdr.Protocol) +
+ pSMBr->DataOffset);
+ cFYI(1,("ea length %d",ea_response_data->list_len));
+ }
+ }
+ if (pSMB)
+ cifs_buf_release(pSMB);
+ if (rc == -EAGAIN)
+ goto QAllEAsRetry;
+
+ return rc;
+}
+#endif
struct cifsTconInfo *tcon;
struct mid_q_entry * mid_entry;
- if(server->tcpStatus == CifsExiting)
+ spin_lock(&GlobalMid_Lock);
+ if(server->tcpStatus == CifsExiting) {
+ /* the demux thread will exit normally
+ next time through the loop */
+ spin_unlock(&GlobalMid_Lock);
return rc;
- server->tcpStatus = CifsNeedReconnect;
+ } else
+ server->tcpStatus = CifsNeedReconnect;
+ spin_unlock(&GlobalMid_Lock);
server->maxBuf = 0;
cFYI(1, ("Reconnecting tcp session "));
}
}
read_unlock(&GlobalSMBSeslock);
-
+ /* do not want to be sending data on a socket we are freeing */
+ down(&server->tcpSem);
if(server->ssocket) {
cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
server->ssocket->flags));
}
}
spin_unlock(&GlobalMid_Lock);
-
+ up(&server->tcpSem);
while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
{
schedule_timeout(3 * HZ);
} else {
atomic_inc(&tcpSesReconnectCount);
- server->tcpStatus = CifsGood;
+ spin_lock(&GlobalMid_Lock);
+ if(server->tcpStatus != CifsExiting)
+ server->tcpStatus = CifsGood;
+ spin_unlock(&GlobalMid_Lock);
atomic_set(&server->inFlight,0);
wake_up(&server->response_q);
}
/* some servers kill tcp session rather than returning
smb negprot error in which case reconnecting here is
not going to help - return error to mount */
+ spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
wake_up(&server->response_q);
break;
}
- cFYI(1,("Reconnecting after unexpected rcvmsg error "));
+ cFYI(1,("Reconnecting after unexpected peek error %d",length));
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
length = sock_recvmsg(csocket, &smb_msg, 4, 0);
cFYI(0,("Received 4 byte keep alive packet"));
} else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
- iov.iov_base = smb_buffer;
+ iov.iov_base = smb_buffer;
iov.iov_len = 4;
length = sock_recvmsg(csocket, &smb_msg, 4, 0);
cFYI(1,("Good RFC 1002 session rsp"));
/* if nack on negprot (rather than
ret of smb negprot error) reconnecting
not going to help, ret error to mount */
+ spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
/* wake up thread doing negprot */
wake_up(&server->response_q);
break;
}
}
}
+ spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
atomic_set(&server->inFlight, 0);
/* Although there should not be any requests blocked on
this queue it can not hurt to be paranoid and try to wake up requests
}
if ((temp_len = strnlen(value, 300)) < 300) {
vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
+ if(vol->UNC == NULL)
+ return 1;
strcpy(vol->UNC,value);
if (strncmp(vol->UNC, "//", 2) == 0) {
vol->UNC[0] = '\\';
}
if ((temp_len = strnlen(devname, 300)) < 300) {
vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
+ if(vol->UNC == NULL)
+ return 1;
strcpy(vol->UNC,devname);
if (strncmp(vol->UNC, "//", 2) == 0) {
vol->UNC[0] = '\\';
} else {
/* BB other socket options to set KEEPALIVE, NODELAY? */
cFYI(1,("ipv6 Socket created"));
- (*csocket)->sk->sk_allocation = GFP_NOFS;
+ (*csocket)->sk->sk_allocation = GFP_NOFS;
}
}
init_waitqueue_head(&srvTcp->response_q);
init_waitqueue_head(&srvTcp->request_q);
INIT_LIST_HEAD(&srvTcp->pending_mid_q);
+ /* at this point we are the only ones with the pointer
+ to the struct since the kernel thread not created yet
+ so no need to spinlock this init of tcpStatus */
srvTcp->tcpStatus = CifsNew;
init_MUTEX(&srvTcp->tcpSem);
kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
/* on error free sesinfo and tcon struct if needed */
if (rc) {
- if(atomic_read(&srvTcp->socketUseCount) == 0)
- srvTcp->tcpStatus = CifsExiting;
- /* If find_unc succeeded then rc == 0 so we can not end */
+ if(atomic_read(&srvTcp->socketUseCount) == 0) {
+ spin_lock(&GlobalMid_Lock);
+ srvTcp->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
+ }
+ /* If find_unc succeeded then rc == 0 so we can not end */
if (tcon) /* up here accidently freeing someone elses tcon struct */
tconInfoFree(tcon);
if (existingCifsSes == 0) {
bcc_ptr +=
pSMBr->resp.SecurityBlobLength;
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
pSMBr->resp.SecurityBlobLength));
}
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
ses->server->secMode |=
SECMODE_SIGN_ENABLED;
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
cFYI(1,
("NTLMSSP response to Authenticate "));
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
/* skip service field (NB: this field is always ASCII) */
bcc_ptr += length + 1;
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
length = UniStrnlen((wchar_t *) bcc_ptr, 512);
if (((long) bcc_ptr + (2 * length)) -
(long) pByteArea(smb_buffer_response) <=
char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
int ntlmv2_flag = FALSE;
- /* what if server changes its buffer size after dropping the session? */
+ /* what if server changes its buffer size after dropping the session? */
if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
rc = CIFSSMBNegotiate(xid, pSesInfo);
if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
if(rc == -EAGAIN)
rc = -EHOSTDOWN;
}
- if(rc == 0)
- pSesInfo->server->tcpStatus = CifsGood;
+ if(rc == 0) {
+ spin_lock(&GlobalMid_Lock);
+ if(pSesInfo->server->tcpStatus != CifsExiting)
+ pSesInfo->server->tcpStatus = CifsGood;
+ else
+ rc = -EHOSTDOWN;
+ spin_unlock(&GlobalMid_Lock);
+
+ }
}
if (!rc) {
pSesInfo->capabilities = pSesInfo->server->capabilities;
struct cifsFileInfo * pCifsFile = NULL;
struct cifsInodeInfo * pCifsInode;
int disposition = FILE_OVERWRITE_IF;
+ int write_only = FALSE;
xid = GetXid();
if(nd) {
if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY)
desiredAccess = GENERIC_READ;
- else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY)
+ else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) {
desiredAccess = GENERIC_WRITE;
- else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) {
+ write_only = TRUE;
+ } else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) {
/* GENERIC_ALL is too much permission to request */
/* can cause unnecessary access denied on create */
/* desiredAccess = GENERIC_ALL; */
pCifsFile->invalidHandle = FALSE;
pCifsFile->closePend = FALSE;
init_MUTEX(&pCifsFile->fh_sem);
- /* pCifsFile->pfile = file; */ /* put in at open time */
+ /* put the following in at open now */
+ /* pCifsFile->pfile = file; */
write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList);
pCifsInode = CIFS_I(newinode);
if(pCifsInode) {
- list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+ /* if readable file instance put first in list*/
+ if (write_only == TRUE) {
+ list_add_tail(&pCifsFile->flist,
+ &pCifsInode->openFileList);
+ } else {
+ list_add(&pCifsFile->flist,
+ &pCifsInode->openFileList);
+ }
if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
pCifsInode->clientCanCacheAll = TRUE;
pCifsInode->clientCanCacheRead = TRUE;
- cFYI(1,("Exclusive Oplock granted on inode %p",newinode));
+ cFYI(1,("Exclusive Oplock granted on inode %p",
+ newinode));
} else if((oplock & 0xF) == OPLOCK_READ)
pCifsInode->clientCanCacheRead = TRUE;
}
{
int xid;
int rc = -EINVAL;
+ int oplock = FALSE;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
char *full_path = NULL;
+ __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
+ __u16 netfid;
xid = GetXid();
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
rc = -ENOMEM;
} else {
cFYI(1,("cifs dir notify on file %s",full_path));
- /* CIFSSMBNotify(xid, pTcon, full_path, cifs_sb->local_nls);*/
+ rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
+ GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
+ &netfid, &oplock,NULL, cifs_sb->local_nls);
+ /* BB fixme - add this handle to a notify handle list */
+ if(rc) {
+ cFYI(1,("Could not open directory for notify"));
+ } else {
+ rc = CIFSSMBNotify(xid, pTcon, 1 /* subdirs */, netfid,
+ filter, cifs_sb->local_nls);
+ /* BB add code to close file eventually (at unmount
+ it would close automatically but may be a way
+ to do it easily when inode freed or when
+ notify info is cleared/changed */
+ }
}
FreeXid(xid);
/* Also refresh inode by passing in file_info buf returned by SMBOpen
and calling get_inode_info with returned buf (at least
helps non-Unix server case */
+
+ /* BB we can not do this if this is the second open of a file
+ and the first handle has writebehind data, we might be
+ able to simply do a filemap_fdatawrite/filemap_fdatawait first */
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
if(buf==0) {
if (full_path)
list_add(&pCifsFile->tlist,&pTcon->openFileList);
pCifsInode = CIFS_I(file->f_dentry->d_inode);
if(pCifsInode) {
- list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+ /* want handles we can use to read with first */
+ /* in the list so we do not have to walk the */
+ /* list to search for one in prepare_write */
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
+ list_add_tail(&pCifsFile->flist,&pCifsInode->openFileList);
+ } else {
+ list_add(&pCifsFile->flist,&pCifsInode->openFileList);
+ }
write_unlock(&GlobalSMBSeslock);
write_unlock(&file->f_owner.lock);
if(pCifsInode->clientCanCacheRead) {
return rc;
}
-static int cifs_reopen_file(struct inode *inode, struct file *file)
+static int cifs_reopen_file(struct inode *inode, struct file *file, int can_flush)
{
int rc = -EACCES;
int xid, oplock;
int desiredAccess = 0x20197;
int disposition = FILE_OPEN;
__u16 netfid;
- FILE_ALL_INFO * buf = NULL;
if(inode == NULL)
return -EBADF;
else
oplock = FALSE;
- /* BB pass O_SYNC flag through on file attributes .. BB */
+
+ /* Can not refresh inode by passing in file_info buf to be returned
+ by SMBOpen and then calling get_inode_info with returned buf
+ since file might have write behind data that needs to be flushed
+ and server version of file size can be stale. If we
+ knew for sure that inode was not dirty locally we could do this */
- /* Also refresh inode by passing in file_info buf returned by SMBOpen
- and calling get_inode_info with returned buf (at least
- helps non-Unix server case */
- buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
+/* buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
if(buf==0) {
up(&pCifsFile->fh_sem);
if (full_path)
kfree(full_path);
FreeXid(xid);
return -ENOMEM;
- }
+ }*/
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
- CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls);
+ CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls);
if (rc) {
up(&pCifsFile->fh_sem);
cFYI(1, ("cifs_open returned 0x%x ", rc));
up(&pCifsFile->fh_sem);
pCifsInode = CIFS_I(inode);
if(pCifsInode) {
- if (pTcon->ses->capabilities & CAP_UNIX)
- rc = cifs_get_inode_info_unix(&inode,
+ if(can_flush) {
+ filemap_fdatawrite(inode->i_mapping);
+ filemap_fdatawait(inode->i_mapping);
+ /* temporarily disable caching while we
+ go to server to get inode info */
+ pCifsInode->clientCanCacheAll = FALSE;
+ pCifsInode->clientCanCacheRead = FALSE;
+ if (pTcon->ses->capabilities & CAP_UNIX)
+ rc = cifs_get_inode_info_unix(&inode,
full_path, inode->i_sb);
- else
- rc = cifs_get_inode_info(&inode,
- full_path, buf, inode->i_sb);
-
+ else
+ rc = cifs_get_inode_info(&inode,
+ full_path, NULL, inode->i_sb);
+ } /* else we are writing out data to server already
+ and could deadlock if we tried to flush data, and
+ since we do not know if we have data that would
+ invalidate the current end of file on the server
+ we can not go to the server to get the new
+ inod info */
if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
pCifsInode->clientCanCacheAll = TRUE;
pCifsInode->clientCanCacheRead = TRUE;
}
}
- if (buf)
- kfree(buf);
if (full_path)
kfree(full_path);
FreeXid(xid);
FreeXid(xid);
return total_written;
}
- rc = cifs_reopen_file(file->f_dentry->d_inode,file);
+ /* we could deadlock if we called
+ filemap_fdatawait from here so tell
+ reopen_file not to flush data to server now */
+ rc = cifs_reopen_file(file->f_dentry->d_inode,
+ file,FALSE);
if(rc != 0)
break;
}
cifsInode = CIFS_I(mapping->host);
read_lock(&GlobalSMBSeslock);
+ /* BB we should start at the end */
list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
open_file = list_entry(tmp,struct cifsFileInfo, flist);
if(open_file->closePend)
xid = GetXid();
/* BB add check for wbc flags */
page_cache_get(page);
+ if (!PageUptodate(page)) {
+ cFYI(1,("ppw - page not up to date"));
+ }
rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
int rc = 0;
struct inode *inode = page->mapping->host;
loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
- /* struct cifsFileInfo *open_file;
- struct cifs_sb_info *cifs_sb; */
+ char * page_data;
xid = GetXid();
cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
cFYI(1,(" SetEOF (commit write) rc = %d",rc));
}*/
}
- set_page_dirty(page);
+ if (!PageUptodate(page)) {
+ position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
+ /* can not rely on (or let) writepage write this data */
+ if(to < offset) {
+ cFYI(1,("Illegal offsets, can not copy from %d to %d",
+ offset,to));
+ FreeXid(xid);
+ return rc;
+ }
+ /* this is probably better than directly calling
+ partialpage_write since in this function
+ the file handle is known which we might as well
+ leverage */
+ /* BB check if anything else missing out of ppw */
+ /* such as updating last write time */
+ page_data = kmap(page);
+ rc = cifs_write(file, page_data+offset,to-offset,
+ &position);
+ if(rc > 0)
+ rc = 0;
+ /* else if rc < 0 should we set writebehind rc? */
+ kunmap(page);
+ } else {
+ set_page_dirty(page);
+ }
FreeXid(xid);
return rc;
}
open_file = (struct cifsFileInfo *)file->private_data;
+ if((file->f_flags & O_ACCMODE) == O_WRONLY) {
+ cFYI(1,("attempting read on write only file instance"));
+ }
+
for (total_read = 0,current_offset=read_data; read_size > total_read;
total_read += bytes_read,current_offset+=bytes_read) {
current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
rc = -EAGAIN;
while(rc == -EAGAIN) {
if ((open_file->invalidHandle) && (!open_file->closePend)) {
- rc = cifs_reopen_file(file->f_dentry->d_inode,file);
+ rc = cifs_reopen_file(file->f_dentry->d_inode,
+ file,TRUE);
if(rc != 0)
break;
}
rc = -EAGAIN;
while(rc == -EAGAIN) {
if ((open_file->invalidHandle) && (!open_file->closePend)) {
- rc = cifs_reopen_file(file->f_dentry->d_inode,file);
+ rc = cifs_reopen_file(file->f_dentry->d_inode,
+ file, TRUE);
if(rc != 0)
break;
}
return rc;
}
-static int
-cifs_readpage(struct file *file, struct page *page)
+static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
{
- loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
char * read_data;
- int rc = -EACCES;
- int xid;
-
- xid = GetXid();
-
- if (file->private_data == NULL) {
- FreeXid(xid);
- return -EBADF;
- }
-
- cFYI(0,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
+ int rc;
page_cache_get(page);
read_data = kmap(page);
/* for reads over a certain size could initiate async read ahead */
-
- rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset);
-
+
+ rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
+
if (rc < 0)
goto io_error;
else {
cFYI(1,("Bytes read %d ",rc));
}
-
+
file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-
+
if(PAGE_CACHE_SIZE > rc) {
memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
}
flush_dcache_page(page);
SetPageUptodate(page);
rc = 0;
-
+
io_error:
- kunmap(page);
+ kunmap(page);
+ page_cache_release(page);
+ return rc;
+}
+
+static int
+cifs_readpage(struct file *file, struct page *page)
+{
+ loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+ int rc = -EACCES;
+ int xid;
+
+ xid = GetXid();
+
+ if (file->private_data == NULL) {
+ FreeXid(xid);
+ return -EBADF;
+ }
+
+ cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
+
+ rc = cifs_readpage_worker(file,page,&offset);
+
unlock_page(page);
- page_cache_release(page);
FreeXid(xid);
return rc;
}
+/* We do not want to update the file size from server for inodes
+ open for write - to avoid races with writepage extending
+ the file - in the future we could consider allowing
+ refreshing the inode only on increases in the file size
+ but this is tricky to do without racing with writebehind
+ page caching in the current Linux kernel design */
+
+int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
+{
+ struct list_head *tmp;
+ struct list_head *tmp1;
+ struct cifsFileInfo *open_file = NULL;
+ int rc = TRUE;
+
+ if(cifsInode == NULL)
+ return rc;
+
+ read_lock(&GlobalSMBSeslock);
+ list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
+ open_file = list_entry(tmp,struct cifsFileInfo, flist);
+ if(open_file == NULL)
+ break;
+ if(open_file->closePend)
+ continue;
+ /* We check if file is open for writing,
+ BB we could supplement this with a check to see if file size
+ changes have been flushed to server - ie inode metadata dirty */
+ if((open_file->pfile) &&
+ ((open_file->pfile->f_flags & O_RDWR) ||
+ (open_file->pfile->f_flags & O_WRONLY))) {
+ rc = FALSE;
+ break;
+ }
+ if(tmp->next == NULL) {
+ cFYI(1,("File instance %p removed",tmp));
+ break;
+ }
+ }
+ read_unlock(&GlobalSMBSeslock);
+ return rc;
+}
+
+
void
fill_in_inode(struct inode *tmp_inode,
FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
atomic_set(&cifsInfo->inUse,1);
}
- i_size_write(tmp_inode,pfindData->EndOfFile);
- tmp_inode->i_blocks =
- (tmp_inode->i_blksize - 1 + pfindData->AllocationSize) >> tmp_inode->i_blkbits;
+ if(is_size_safe_to_change(cifsInfo)) {
+ /* can not safely change the file size here if the
+ client is writing to it due to potential races */
+ i_size_write(tmp_inode,pfindData->EndOfFile);
+
+ /* 512 bytes (2**9) is the fake blocksize that must be used */
+ /* for this calculation, even though the reported blocksize is larger */
+ tmp_inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9;
+ }
+
if (pfindData->AllocationSize < pfindData->EndOfFile)
cFYI(1, ("Possible sparse file: allocation size less than end of file "));
cFYI(1,
tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
pfindData->NumOfBytes = le64_to_cpu(pfindData->NumOfBytes);
- pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
- i_size_write(tmp_inode,pfindData->EndOfFile);
- tmp_inode->i_blocks =
- (tmp_inode->i_blksize - 1 + pfindData->NumOfBytes) >> tmp_inode->i_blkbits;
+
+ if(is_size_safe_to_change(cifsInfo)) {
+ /* can not safely change the file size here if the
+ client is writing to it due to potential races */
+ pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
+ i_size_write(tmp_inode,pfindData->EndOfFile);
+
+ /* 512 bytes (2**9) is the fake blocksize that must be used */
+ /* for this calculation, not the real blocksize */
+ tmp_inode->i_blocks = (512 - 1 + pfindData->NumOfBytes) >> 9;
+ }
if (S_ISREG(tmp_inode->i_mode)) {
cFYI(1, ("File inode"));
/* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
if(*ptmp_inode == NULL) {
*ptmp_inode = new_inode(file->f_dentry->d_sb);
+ if(*ptmp_inode == NULL)
+ return;
d_instantiate(tmp_dentry, *ptmp_inode);
}
} else {
tmp_dentry = d_alloc(file->f_dentry, qstring);
if(tmp_dentry == NULL) {
cERROR(1,("Failed allocating dentry"));
+ *ptmp_inode = NULL;
return;
}
tmp_dentry->d_op = &cifs_dentry_ops;
cFYI(0, (" instantiate dentry 0x%p with inode 0x%p ",
tmp_dentry, *ptmp_inode));
+ if(*ptmp_inode == NULL)
+ return;
d_instantiate(tmp_dentry, *ptmp_inode);
d_rehash(tmp_dentry);
}
pqstring->len = pfindData->FileNameLength;
construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
-
+ if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
+ return -ENOMEM;
+ }
fill_in_inode(tmp_inode, pfindData, &object_type);
rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
tmp_inode->i_ino, object_type);
pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
+ if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
+ return -ENOMEM;
+ }
unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
int cifs_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
+ int rc = 0;
+ loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
if (!PageUptodate(page)) {
- if (to - from != PAGE_CACHE_SIZE) {
+ /* if (to - from != PAGE_CACHE_SIZE) {
void *kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr, 0, from);
memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
+ } */
+ /* If we are writing a full page it will be up to date,
+ no need to read from the server */
+ if((to==PAGE_CACHE_SIZE) && (from == 0))
+ SetPageUptodate(page);
+
+ /* might as well read a page, it is fast enough */
+ if((file->f_flags & O_ACCMODE) != O_WRONLY) {
+ rc = cifs_readpage_worker(file,page,&offset);
+ } else {
+ /* should we try using another
+ file handle if there is one - how would we lock it
+ to prevent close of that handle racing with this read? */
+ /* In any case this will be written out by commit_write */
}
- SetPageUptodate(page);
}
+
+ /* BB should we pass any errors back? e.g. if we do not have read access to the file */
return 0;
}
.readpage = cifs_readpage,
.readpages = cifs_readpages,
.writepage = cifs_writepage,
- .prepare_write = simple_prepare_write, /* BB fixme BB */
-/* .prepare_write = cifs_prepare_write, */ /* BB removeme BB */
+ .prepare_write = cifs_prepare_write,
.commit_write = cifs_commit_write,
/* .sync_page = cifs_sync_page, */
/*.direct_IO = */
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
+extern int is_size_safe_to_change(struct cifsInodeInfo *);
+
int
cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *tmp_path;
-/* BB add caching check so we do not go to server to overwrite inode info to cached file
- where the local file sizes are correct and the server info is stale BB */
-
xid = GetXid();
pTcon = cifs_sb->tcon;
inode->i_nlink = le64_to_cpu(findData.Nlinks);
findData.NumOfBytes = le64_to_cpu(findData.NumOfBytes);
findData.EndOfFile = le64_to_cpu(findData.EndOfFile);
- i_size_write(inode,findData.EndOfFile);
+
+ if(is_size_safe_to_change(cifsInfo)) {
+ /* can not safely change the file size here if the
+ client is writing to it due to potential races */
+
+ i_size_write(inode,findData.EndOfFile);
/* blksize needs to be multiple of two. So safer to default to blksize
and blkbits set in superblock so 2**blkbits and blksize will match */
/* inode->i_blksize =
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
- inode->i_blocks =
- (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;
+
+ /* This seems incredibly stupid but it turns out that
+ i_blocks is not related to (i_size / i_blksize), instead a
+ size of 512 is required to be used for calculating num blocks */
+
+
+/* inode->i_blocks =
+ (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;*/
+
+ /* 512 bytes (2**9) is the fake blocksize that must be used */
+ /* for this calculation */
+ inode->i_blocks = (512 - 1 + findData.NumOfBytes) >> 9;
+ }
if (findData.NumOfBytes < findData.EndOfFile)
cFYI(1, ("Server inconsistency Error: it says allocation size less than end of file "));
inode->i_mode &= ~(S_IWUGO);
/* BB add code here - validate if device or weird share or device type? */
}
- i_size_write(inode,le64_to_cpu(pfindData->EndOfFile));
+ if(is_size_safe_to_change(cifsInfo)) {
+ /* can not safely change the file size here if the
+ client is writing to it due to potential races */
+
+ i_size_write(inode,le64_to_cpu(pfindData->EndOfFile));
+
+ /* 512 bytes (2**9) is the fake blocksize that must be used */
+ /* for this calculation */
+ inode->i_blocks = (512 - 1 + pfindData->AllocationSize)
+ >> 9;
+ }
pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
- inode->i_blocks =
- (inode->i_blksize - 1 + pfindData->AllocationSize) >> inode->i_blkbits;
inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
rc = CIFSSMBRename(xid, pTcon, fromName, toName,
cifs_sb_source->local_nls);
if(rc == -EEXIST) {
- cifs_unlink(target_inode, target_direntry);
- rc = CIFSSMBRename(xid, pTcon, fromName, toName,
- cifs_sb_source->local_nls);
+ /* check if they are the same file
+ because rename of hardlinked files is a noop */
+ FILE_UNIX_BASIC_INFO * info_buf_source;
+ FILE_UNIX_BASIC_INFO * info_buf_target;
+
+ info_buf_source =
+ kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),GFP_KERNEL);
+ if(info_buf_source != NULL) {
+ info_buf_target = info_buf_source+1;
+ rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
+ info_buf_source, cifs_sb_source->local_nls);
+ if(rc == 0) {
+ rc = CIFSSMBUnixQPathInfo(xid,pTcon,toName,
+ info_buf_target,
+ cifs_sb_target->local_nls);
+ }
+ if((rc == 0) &&
+ (info_buf_source->UniqueId ==
+ info_buf_target->UniqueId)) {
+ /* do not rename since the files are hardlinked
+ which is a noop */
+ } else {
+ /* we either can not tell the files are hardlinked
+ (as with Windows servers) or files are not hardlinked
+ so delete the target manually before renaming to
+ follow POSIX rather than Windows semantics */
+ cifs_unlink(target_inode, target_direntry);
+ rc = CIFSSMBRename(xid, pTcon, fromName, toName,
+ cifs_sb_source->local_nls);
+ }
+ kfree(info_buf_source);
+ } /* if we can not get memory just leave rc as EEXIST */
}
if((rc == -EIO)||(rc == -EEXIST)) {
}
int
-cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
+cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
{
struct inode *inode = direntry->d_inode;
int rc = -EACCES;
unsigned int smb_buf_length, struct sockaddr *sin)
{
int rc = 0;
+ int i = 0;
struct msghdr smb_msg;
struct iovec iov;
mm_segment_t temp_fs;
if(ssocket == NULL)
return -ENOTSOCK; /* BB eventually add reconnect code here */
-/* ssocket->sk->allocation = GFP_BUFFER; *//* BB is this spurious? */
iov.iov_base = smb_buffer;
iov.iov_len = smb_buf_length + 4;
while(iov.iov_len > 0) {
rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
+ i++;
+ if(i > 60) {
+ cERROR(1,
+ ("sends on sock %p stuck for 30 seconds",
+ ssocket));
+ rc = -EAGAIN;
+ break;
+ }
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/2);
continue;
midQ->midState = MID_REQUEST_SUBMITTED;
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->addr.sockAddr));
- up(&ses->server->tcpSem);
+ if(rc < 0) {
+ DeleteMidQEntry(midQ);
+ up(&ses->server->tcpSem);
+ /* If not lock req, update # of requests on wire to server */
+ if(long_op < 3) {
+ atomic_dec(&ses->server->inFlight);
+ wake_up(&ses->server->request_q);
+ }
+ return rc;
+ } else
+ up(&ses->server->tcpSem);
if (long_op == -1)
goto cifs_no_response_exit;
else if (long_op == 2) /* writes past end of file can take looooong time */
*/
#include <linux/fs.h>
+#include "cifsfs.h"
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
int cifs_removexattr(struct dentry * direntry, const char * name)
{
- int rc = -EOPNOTSUPP;
- return rc;
+ int rc = -EOPNOTSUPP;
+ return rc;
}
int cifs_setxattr(struct dentry * direntry, const char * name,
const void * value, size_t size, int flags)
{
- int rc = -EOPNOTSUPP;
- return rc;
+ int rc = -EOPNOTSUPP;
+ return rc;
}
ssize_t cifs_getxattr(struct dentry * direntry, const char * name,
void * value, size_t size)
{
- ssize_t rc = -EOPNOTSUPP;
- return rc;
+ ssize_t rc = -EOPNOTSUPP;
+ return rc;
}
ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size)
{
- ssize_t rc = -EOPNOTSUPP;
+ ssize_t rc = -EOPNOTSUPP;
+#ifdef CONFIG_CIFS_XATTR
+ int xid;
+ struct cifs_sb_info *cifs_sb;
+ struct cifsTconInfo *pTcon;
+ struct super_block * sb;
+ char * full_path;
+ if(direntry == NULL)
+ return -EIO;
+ if(direntry->d_inode == NULL)
+ return -EIO;
+ sb = direntry->d_inode->i_sb;
+ if(sb == NULL)
+ return -EIO;
+ xid = GetXid();
+ cifs_sb = CIFS_SB(sb);
+ pTcon = cifs_sb->tcon;
+
+ down(&sb->s_vfs_rename_sem);
+ full_path = build_path_from_dentry(direntry);
+ up(&sb->s_vfs_rename_sem);
+ if(full_path == NULL) {
+ FreeXid(xid);
+ return -ENOMEM;
+ }
/* return dosattributes as pseudo xattr */
/* return alt name if available as pseudo attr */
/* if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to
returns as xattrs */
-
- return rc;
+ rc = CIFSSMBQAllEAs(xid,pTcon,full_path,ea_data,ea_size,cifs_sb->local_nls);
+ FreeXid(xid);
+#endif
+ return rc;
}
int use_coda_close;
static ssize_t
-coda_file_read(struct file *coda_file, char *buf, size_t count, loff_t *ppos)
+coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
{
struct coda_file_info *cfi;
struct file *host_file;
}
static ssize_t
-coda_file_write(struct file *coda_file, const char *buf, size_t count, loff_t *ppos)
+coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos)
{
struct inode *host_inode, *coda_inode = coda_file->f_dentry->d_inode;
struct coda_file_info *cfi;
struct coda_inode_info *cnp;
/* get the Pioctl data arguments from user space */
- if (copy_from_user(&data, (int *)user_data, sizeof(data))) {
+ if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) {
return -EINVAL;
}
switch(cmd) {
case CIOC_KERNEL_VERSION:
data = CODA_KERNEL_VERSION;
- return put_user(data, (int *) arg);
+ return put_user(data, (int __user *) arg);
default:
return -ENOTTY;
}
* Receive a message written by Venus to the psdev
*/
-static ssize_t coda_psdev_write(struct file *file, const char *buf,
+static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
size_t nbytes, loff_t *off)
{
struct venus_comm *vcp = (struct venus_comm *) file->private_data;
* Read a message from the kernel to Venus
*/
-static ssize_t coda_psdev_read(struct file * file, char * buf,
+static ssize_t coda_psdev_read(struct file * file, char __user * buf,
size_t nbytes, loff_t *off)
{
DECLARE_WAITQUEUE(wait, current);
}
int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
- void * buffer, size_t * lenp )
+ void __user * buffer, size_t * lenp )
{
if ( write ) {
reset_coda_vfs_stats();
}
int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
- struct file * filp, void * buffer,
+ struct file * filp, void __user * buffer,
size_t * lenp )
{
if ( write ) {
#define coda_proc_create(name,get_info) \
create_proc_info_entry(name, 0, proc_fs_coda, get_info)
-void coda_sysctl_init()
+void coda_sysctl_init(void)
{
reset_coda_vfs_stats();
reset_coda_cache_inv_stats();
#endif
}
-void coda_sysctl_clean()
+void coda_sysctl_clean(void)
{
#ifdef CONFIG_SYSCTL
#include <linux/syscalls.h>
#include <linux/ctype.h>
#include <linux/module.h>
+#include <linux/dirent.h>
#include <linux/dnotify.h>
#include <linux/highuid.h>
#include <linux/sunrpc/svc.h>
return retval;
}
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
+#define COMPAT_ROUND_UP(x) (((x)+sizeof(compat_long_t)-1) & \
+ ~(sizeof(compat_long_t)-1))
+
+struct compat_old_linux_dirent {
+ compat_ulong_t d_ino;
+ compat_ulong_t d_offset;
+ unsigned short d_namlen;
+ char d_name[1];
+};
+
+struct compat_readdir_callback {
+ struct compat_old_linux_dirent __user *dirent;
+ int result;
+};
+
+static int compat_fillonedir(void *__buf, const char *name, int namlen,
+ loff_t offset, ino_t ino, unsigned int d_type)
+{
+ struct compat_readdir_callback *buf = __buf;
+ struct compat_old_linux_dirent __user *dirent;
+
+ if (buf->result)
+ return -EINVAL;
+ buf->result++;
+ dirent = buf->dirent;
+ if (!access_ok(VERIFY_WRITE, (unsigned long)dirent,
+ (unsigned long)(dirent->d_name + namlen + 1) -
+ (unsigned long)dirent))
+ goto efault;
+ if ( __put_user(ino, &dirent->d_ino) ||
+ __put_user(offset, &dirent->d_offset) ||
+ __put_user(namlen, &dirent->d_namlen) ||
+ __copy_to_user(dirent->d_name, name, namlen) ||
+ __put_user(0, dirent->d_name + namlen))
+ goto efault;
+ return 0;
+efault:
+ buf->result = -EFAULT;
+ return -EFAULT;
+}
+
+asmlinkage long compat_old_readdir(unsigned int fd,
+ struct compat_old_linux_dirent __user *dirent, unsigned int count)
+{
+ int error;
+ struct file *file;
+ struct compat_readdir_callback buf;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.result = 0;
+ buf.dirent = dirent;
+
+ error = vfs_readdir(file, compat_fillonedir, &buf);
+ if (error >= 0)
+ error = buf.result;
+
+ fput(file);
+out:
+ return error;
+}
+
+struct compat_linux_dirent {
+ compat_ulong_t d_ino;
+ compat_ulong_t d_off;
+ unsigned short d_reclen;
+ char d_name[1];
+};
+
+struct compat_getdents_callback {
+ struct compat_linux_dirent __user *current_dir;
+ struct compat_linux_dirent __user *previous;
+ int count;
+ int error;
+};
+
+static int compat_filldir(void *__buf, const char *name, int namlen,
+ loff_t offset, ino_t ino, unsigned int d_type)
+{
+ struct compat_linux_dirent __user * dirent;
+ struct compat_getdents_callback *buf = __buf;
+ int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+ if (dirent) {
+ if (__put_user(offset, &dirent->d_off))
+ goto efault;
+ }
+ dirent = buf->current_dir;
+ if (__put_user(ino, &dirent->d_ino))
+ goto efault;
+ if (__put_user(reclen, &dirent->d_reclen))
+ goto efault;
+ if (copy_to_user(dirent->d_name, name, namlen))
+ goto efault;
+ if (__put_user(0, dirent->d_name + namlen))
+ goto efault;
+ if (__put_user(d_type, (char __user *) dirent + reclen - 1))
+ goto efault;
+ buf->previous = dirent;
+ dirent = (void __user *)dirent + reclen;
+ buf->current_dir = dirent;
+ buf->count -= reclen;
+ return 0;
+efault:
+ buf->error = -EFAULT;
+ return -EFAULT;
+}
+
+asmlinkage long compat_sys_getdents(unsigned int fd,
+ struct compat_linux_dirent __user *dirent, unsigned int count)
+{
+ struct file * file;
+ struct compat_linux_dirent __user * lastdirent;
+ struct compat_getdents_callback buf;
+ int error;
+
+ error = -EFAULT;
+ if (!access_ok(VERIFY_WRITE, dirent, count))
+ goto out;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.current_dir = dirent;
+ buf.previous = NULL;
+ buf.count = count;
+ buf.error = 0;
+
+ error = vfs_readdir(file, compat_filldir, &buf);
+ if (error < 0)
+ goto out_putf;
+ error = buf.error;
+ lastdirent = buf.previous;
+ if (lastdirent) {
+ if (put_user(file->f_pos, &lastdirent->d_off))
+ error = -EFAULT;
+ else
+ error = count - buf.count;
+ }
+
+out_putf:
+ fput(file);
+out:
+ return error;
+}
+
+#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64
+#define COMPAT_ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
+
+struct compat_getdents_callback64 {
+ struct linux_dirent64 __user *current_dir;
+ struct linux_dirent64 __user *previous;
+ int count;
+ int error;
+};
+
+static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
+ ino_t ino, unsigned int d_type)
+{
+ struct linux_dirent64 __user *dirent;
+ struct compat_getdents_callback64 *buf = __buf;
+ int jj = NAME_OFFSET(dirent);
+ int reclen = COMPAT_ROUND_UP64(jj + namlen + 1);
+ u64 off;
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+
+ if (dirent) {
+ if (__put_user(offset, (u32 __user *)&dirent->d_off))
+ goto efault;
+ if (__put_user(offset >> 32,
+ ((u32 __user *)&dirent->d_off) + 1))
+ goto efault;
+ }
+ dirent = buf->current_dir;
+ if ((__put_user(ino, (u32 __user *)&dirent->d_ino))
+ || (__put_user(ino >> 32, ((u32 __user *)&dirent->d_ino) + 1)))
+ goto efault;
+ off = 0;
+ if ((__put_user(off, (u32 __user *)&dirent->d_off))
+ || (__put_user(off >> 32, ((u32 __user *)&dirent->d_off) + 1)))
+ goto efault;
+ if (__put_user(reclen, &dirent->d_reclen))
+ goto efault;
+ if (__put_user(d_type, &dirent->d_type))
+ goto efault;
+ if (copy_to_user(dirent->d_name, name, namlen))
+ goto efault;
+ if (__put_user(0, dirent->d_name + namlen))
+ goto efault;
+ buf->previous = dirent;
+ dirent = (void __user *)dirent + reclen;
+ buf->current_dir = dirent;
+ buf->count -= reclen;
+ return 0;
+efault:
+ buf->error = -EFAULT;
+ return -EFAULT;
+}
+
+asmlinkage long compat_sys_getdents64(unsigned int fd,
+ struct linux_dirent64 __user * dirent, unsigned int count)
+{
+ struct file * file;
+ struct linux_dirent64 __user * lastdirent;
+ struct compat_getdents_callback64 buf;
+ int error;
+
+ error = -EFAULT;
+ if (!access_ok(VERIFY_WRITE, dirent, count))
+ goto out;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.current_dir = dirent;
+ buf.previous = NULL;
+ buf.count = count;
+ buf.error = 0;
+
+ error = vfs_readdir(file, compat_filldir64, &buf);
+ if (error < 0)
+ goto out_putf;
+ error = buf.error;
+ lastdirent = buf.previous;
+ if (lastdirent) {
+ typeof(lastdirent->d_off) d_off = file->f_pos;
+ __put_user(d_off, (u32 __user *)&lastdirent->d_off);
+ __put_user(d_off >> 32, ((u32 __user *)&lastdirent->d_off) + 1);
+ error = count - buf.count;
+ }
+
+out_putf:
+ fput(file);
+out:
+ return error;
+}
+#endif /* ! __ARCH_OMIT_COMPAT_SYS_GETDENTS64 */
+
static ssize_t compat_do_readv_writev(int type, struct file *file,
const struct compat_iovec __user *uvector,
unsigned long nr_segs, loff_t *pos)
{
u32 tmp;
- if(get_user(tmp, &up->base))
+ if (get_user(tmp, &up->base))
return -EFAULT;
- kp->base = compat_ptr(tmp);
+
+ /* This is actually a physical address stored
+ * as a void pointer.
+ */
+ kp->base = (void *)(unsigned long) tmp;
+
__get_user(kp->height, &up->height);
__get_user(kp->width, &up->width);
__get_user(kp->depth, &up->depth);
set_fs(old_fs);
if (!err)
- err = put_user(kuid, (unsigned int *)compat_ptr(arg));
+ err = put_user(kuid,
+ (unsigned int __user *) compat_ptr(arg));
return err;
}
static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg);
- struct ncp_privatedata_ioctl *p = __user compat_alloc_user_space(sizeof(*p));
+ struct ncp_privatedata_ioctl __user *p =
+ compat_alloc_user_space(sizeof(*p));
u32 len;
int err;
static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg)
{
- struct ncp_privatedata_ioctl_32 n32, *p32 = compat_ptr(arg);
- struct ncp_privatedata_ioctl *p = compat_alloc_user_space(sizeof(*p));
+ struct ncp_privatedata_ioctl_32 n32;
+ struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg);
+ struct ncp_privatedata_ioctl __user *p =
+ compat_alloc_user_space(sizeof(*p));
if (copy_from_user(&n32, p32, sizeof(n32)) ||
put_user(n32.len, &p->len) ||
static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
const char *name, int namelen,
int traverse_symlink);
-static ssize_t devfsd_read(struct file *file, char *buf, size_t len,
+static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
loff_t * ppos);
static int devfsd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static int devfsd_close(struct inode *inode, struct file *file);
#ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read(struct file *file, char *buf, size_t len,
+static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
loff_t * ppos);
static struct file_operations stat_fops = {
.read = stat_read,
/* File operations for devfsd follow */
-static ssize_t devfsd_read(struct file *file, char *buf, size_t len,
+static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
loff_t * ppos)
{
int done = FALSE;
switch (cmd) {
case DEVFSDIOC_GET_PROTO_REV:
ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
- if (copy_to_user((void *)arg, &ival, sizeof ival))
+ if (copy_to_user((void __user *)arg, &ival, sizeof ival))
return -EFAULT;
break;
case DEVFSDIOC_SET_EVENT_MASK:
/*break; */
#ifdef CONFIG_DEVFS_DEBUG
case DEVFSDIOC_SET_DEBUG_MASK:
- if (copy_from_user(&ival, (void *)arg, sizeof ival))
+ if (copy_from_user(&ival, (void __user *)arg, sizeof ival))
return -EFAULT;
devfs_debug = ival;
break;
} /* End Function devfsd_close */
#ifdef CONFIG_DEVFS_DEBUG
-static ssize_t stat_read(struct file *file, char *buf, size_t len,
+static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
loff_t * ppos)
{
ssize_t num;
kfree(dio);
}
} else {
+ ssize_t transferred = 0;
+
finished_one_bio(dio);
ret2 = dio_await_completion(dio);
if (ret == 0)
ret = ret2;
if (ret == 0)
ret = dio->page_errors;
- if (ret == 0 && dio->result) {
+ if (dio->result) {
loff_t i_size = i_size_read(inode);
- ret = dio->result;
+ transferred = dio->result;
/*
* Adjust the return value if the read crossed a
* non-block-aligned EOF.
*/
- if (rw == READ && (offset + ret > i_size))
- ret = i_size - offset;
+ if (rw == READ && (offset + transferred > i_size))
+ transferred = i_size - offset;
}
- dio_complete(dio, offset, ret);
+ dio_complete(dio, offset, transferred);
+ if (ret == 0)
+ ret = transferred;
+
/* We could have also come here on an AIO file extend */
if (!is_sync_kiocb(iocb) && rw == WRITE &&
ret >= 0 && dio->result == dio->size)
int dquot_acquire(struct dquot *dquot)
{
- int ret = 0;
+ int ret = 0, ret2 = 0;
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
down(&dquot->dq_lock);
/* Instantiate dquot if needed */
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+ /* Write the info if needed */
+ if (info_dirty(&dqopt->info[dquot->dq_type]))
+ ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
if (ret < 0)
goto out_iolock;
+ if (ret2 < 0) {
+ ret = ret2;
+ goto out_iolock;
+ }
}
set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
out_iolock:
*/
int dquot_commit(struct dquot *dquot)
{
- int ret = 0;
+ int ret = 0, ret2 = 0;
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
down(&dqopt->dqio_sem);
spin_unlock(&dq_list_lock);
/* Inactive dquot can be only if there was error during read/init
* => we have better not writing it */
- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+ if (info_dirty(&dqopt->info[dquot->dq_type]))
+ ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+ if (ret >= 0)
+ ret = ret2;
+ }
out_sem:
up(&dqopt->dqio_sem);
- if (info_dirty(&dqopt->info[dquot->dq_type]))
- dquot->dq_sb->dq_op->write_info(dquot->dq_sb, dquot->dq_type);
return ret;
}
*/
int dquot_release(struct dquot *dquot)
{
- int ret = 0;
+ int ret = 0, ret2 = 0;
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
down(&dquot->dq_lock);
if (atomic_read(&dquot->dq_count) > 1)
goto out_dqlock;
down(&dqopt->dqio_sem);
- if (dqopt->ops[dquot->dq_type]->release_dqblk)
+ if (dqopt->ops[dquot->dq_type]->release_dqblk) {
ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
+ /* Write the info */
+ if (info_dirty(&dqopt->info[dquot->dq_type]))
+ ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+ if (ret >= 0)
+ ret = ret2;
+ }
clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
up(&dqopt->dqio_sem);
out_dqlock:
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/rwsem.h>
+#include <linux/rbtree.h>
#include <linux/wait.h>
#include <linux/eventpoll.h>
#include <linux/mount.h>
/* Maximum number of poll wake up nests we are allowing */
#define EP_MAX_POLLWAKE_NESTS 4
-/* Maximum size of the hash in bits ( 2^N ) */
-#define EP_MAX_HASH_BITS 17
-
-/* Minimum size of the hash in bits ( 2^N ) */
-#define EP_MIN_HASH_BITS 9
-
-/* Number of hash entries ( "struct list_head" ) inside a page */
-#define EP_HENTRY_X_PAGE (PAGE_SIZE / sizeof(struct list_head))
-
-/* Maximum size of the hash in pages */
-#define EP_MAX_HPAGES ((1 << EP_MAX_HASH_BITS) / EP_HENTRY_X_PAGE + 1)
-
-/* Number of pages allocated for an "hbits" sized hash table */
-#define EP_HASH_PAGES(hbits) ((int) ((1 << (hbits)) / EP_HENTRY_X_PAGE + \
- ((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
-
/* Macro to allocate a "struct epitem" from the slab cache */
#define EPI_MEM_ALLOC() (struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
/* Fast test to see if the file is an evenpoll file */
#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
+/* Setup the structure that is used as key for the rb-tree */
+#define EP_SET_FFD(p, f, d) do { (p)->file = (f); (p)->fd = (d); } while (0)
+
+/* Compare rb-tree keys */
+#define EP_CMP_FFD(p1, p2) ((p1)->file > (p2)->file ? +1: \
+ ((p1)->file < (p2)->file ? -1: (p1)->fd - (p2)->fd))
+
+/* Special initialization for the rb-tree node to detect linkage */
+#define EP_RB_INITNODE(n) (n)->rb_parent = (n)
+
+/* Removes a node from the rb-tree and marks it for a fast is-linked check */
+#define EP_RB_ERASE(n, r) do { rb_erase(n, r); (n)->rb_parent = (n); } while (0)
+
+/* Fast check to verify that the item is linked to the main rb-tree */
+#define EP_RB_LINKED(n) ((n)->rb_parent != (n))
+
/*
* Remove the item from the list and perform its initialization.
* This is useful for us because we can test if the item is linked
/* Get the "struct epitem" from an epoll queue wrapper */
#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
+
+struct epoll_filefd {
+ struct file *file;
+ int fd;
+};
+
/*
* Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
* It is used to keep track on all tasks that are currently inside the wake_up() code
/* List of ready file descriptors */
struct list_head rdllist;
- /* Size of the hash */
- unsigned int hashbits;
-
- /* Pages for the "struct epitem" hash */
- char *hpages[EP_MAX_HPAGES];
+ /* RB-Tree root used to store monitored fd structs */
+ struct rb_root rbr;
};
/* Wait structure used by the poll hooks */
* have an entry of this type linked to the hash.
*/
struct epitem {
- /* List header used to link this structure to the eventpoll hash */
- struct list_head llink;
+ /* RB-Tree node used to link this structure to the eventpoll rb-tree */
+ struct rb_node rbn;
/* List header used to link this structure to the eventpoll ready list */
struct list_head rdllink;
- /* The file descriptor this item refers to */
- int fd;
+ /* The file descriptor information this item refers to */
+ struct epoll_filefd ffd;
/* Number of active wait queue attached to poll operations */
int nwait;
/* The "container" of this item */
struct eventpoll *ep;
- /* The file this item refers to */
- struct file *file;
-
/* The structure that describe the interested events and the source fd */
struct epoll_event event;
static void ep_poll_safewake_init(struct poll_safewake *psw);
static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
-static unsigned int ep_get_hash_bits(unsigned int hintsize);
static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
-static int ep_alloc_pages(char **pages, int numpages);
-static int ep_free_pages(char **pages, int numpages);
-static int ep_file_init(struct file *file, unsigned int hashbits);
-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file,
- int fd);
-static struct list_head *ep_hash_entry(struct eventpoll *ep,
- unsigned int index);
-static int ep_init(struct eventpoll *ep, unsigned int hashbits);
+static int ep_file_init(struct file *file);
static void ep_free(struct eventpoll *ep);
static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
static void ep_use_epitem(struct epitem *epi);
static void ep_release_epitem(struct epitem *epi);
static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
poll_table *pt);
+static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi);
static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
struct file *tfile, int fd);
static int ep_modify(struct eventpoll *ep, struct epitem *epi,
}
-/*
- * Calculate the size of the hash in bits. The returned size will be
- * bounded between EP_MIN_HASH_BITS and EP_MAX_HASH_BITS.
- */
-static unsigned int ep_get_hash_bits(unsigned int hintsize)
-{
- unsigned int i, val;
-
- for (i = 0, val = 1; val < hintsize && i < EP_MAX_HASH_BITS; i++, val <<= 1);
- return i < EP_MIN_HASH_BITS ? EP_MIN_HASH_BITS: i;
-}
-
-
/* Used to initialize the epoll bits inside the "struct file" */
void eventpoll_init_file(struct file *file)
{
asmlinkage long sys_epoll_create(int size)
{
int error, fd;
- unsigned int hashbits;
struct inode *inode;
struct file *file;
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
current, size));
- /* Correctly size the hash */
- hashbits = ep_get_hash_bits((unsigned int) size);
+ /* Sanity check on the size parameter */
+ error = -EINVAL;
+ if (size <= 0)
+ goto eexit_1;
/*
* Creates all the items needed to setup an eventpoll file. That is,
goto eexit_1;
/* Setup the file internal data structure ( "struct eventpoll" ) */
- error = ep_file_init(file, hashbits);
+ error = ep_file_init(file);
if (error)
goto eexit_2;
}
-static int ep_alloc_pages(char **pages, int numpages)
+static int ep_file_init(struct file *file)
{
- int i;
-
- for (i = 0; i < numpages; i++) {
- pages[i] = (char *) __get_free_pages(GFP_KERNEL, 0);
- if (!pages[i]) {
- for (--i; i >= 0; i--) {
- ClearPageReserved(virt_to_page(pages[i]));
- free_pages((unsigned long) pages[i], 0);
- }
- return -ENOMEM;
- }
- SetPageReserved(virt_to_page(pages[i]));
- }
- return 0;
-}
-
-
-static int ep_free_pages(char **pages, int numpages)
-{
- int i;
-
- for (i = 0; i < numpages; i++) {
- ClearPageReserved(virt_to_page(pages[i]));
- free_pages((unsigned long) pages[i], 0);
- }
- return 0;
-}
-
-
-static int ep_file_init(struct file *file, unsigned int hashbits)
-{
- int error;
struct eventpoll *ep;
if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
return -ENOMEM;
memset(ep, 0, sizeof(*ep));
-
- error = ep_init(ep, hashbits);
- if (error) {
- kfree(ep);
- return error;
- }
-
- file->private_data = ep;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
- current, ep));
- return 0;
-}
-
-
-/*
- * Calculate the index of the hash relative to "file".
- */
-static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file, int fd)
-{
- unsigned long ptr = (unsigned long) file ^ (fd << ep->hashbits);
-
- return (unsigned int) hash_ptr((void *) ptr, ep->hashbits);
-}
-
-
-/*
- * Returns the hash entry ( struct list_head * ) of the passed index.
- */
-static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index)
-{
-
- return (struct list_head *) (ep->hpages[index / EP_HENTRY_X_PAGE] +
- (index % EP_HENTRY_X_PAGE) * sizeof(struct list_head));
-}
-
-
-static int ep_init(struct eventpoll *ep, unsigned int hashbits)
-{
- int error;
- unsigned int i, hsize;
-
rwlock_init(&ep->lock);
init_rwsem(&ep->sem);
init_waitqueue_head(&ep->wq);
init_waitqueue_head(&ep->poll_wait);
INIT_LIST_HEAD(&ep->rdllist);
+ ep->rbr = RB_ROOT;
- /* Hash allocation and setup */
- ep->hashbits = hashbits;
- error = ep_alloc_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
- if (error)
- goto eexit_1;
-
- /* Initialize hash buckets */
- for (i = 0, hsize = 1 << hashbits; i < hsize; i++)
- INIT_LIST_HEAD(ep_hash_entry(ep, i));
+ file->private_data = ep;
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
+ current, ep));
return 0;
-eexit_1:
- return error;
}
static void ep_free(struct eventpoll *ep)
{
- unsigned int i, hsize;
- struct list_head *lsthead, *lnk;
+ struct rb_node *rbp;
struct epitem *epi;
/* We need to release all tasks waiting for these file */
down(&epsem);
/*
- * Walks through the whole hash by unregistering poll callbacks.
+ * Walks through the whole tree by unregistering poll callbacks.
*/
- for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
- lsthead = ep_hash_entry(ep, i);
+ for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) {
+ epi = rb_entry(rbp, struct epitem, rbn);
- list_for_each(lnk, lsthead) {
- epi = list_entry(lnk, struct epitem, llink);
-
- ep_unregister_pollwait(ep, epi);
- }
+ ep_unregister_pollwait(ep, epi);
}
/*
* write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
*/
- for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
- lsthead = ep_hash_entry(ep, i);
-
- while (!list_empty(lsthead)) {
- epi = list_entry(lsthead->next, struct epitem, llink);
-
- ep_remove(ep, epi);
- }
+ while ((rbp = rb_first(&ep->rbr))) {
+ epi = rb_entry(rbp, struct epitem, rbn);
+ ep_remove(ep, epi);
}
up(&epsem);
-
- /* Free hash pages */
- ep_free_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
}
*/
static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd)
{
+ int kcmp;
unsigned long flags;
- struct list_head *lsthead, *lnk;
- struct epitem *epi = NULL;
+ struct rb_node *rbp;
+ struct epitem *epi, *epir = NULL;
+ struct epoll_filefd ffd;
+ EP_SET_FFD(&ffd, file, fd);
read_lock_irqsave(&ep->lock, flags);
-
- lsthead = ep_hash_entry(ep, ep_hash_index(ep, file, fd));
- list_for_each(lnk, lsthead) {
- epi = list_entry(lnk, struct epitem, llink);
-
- if (epi->file == file && epi->fd == fd) {
+ for (rbp = ep->rbr.rb_node; rbp; ) {
+ epi = rb_entry(rbp, struct epitem, rbn);
+ kcmp = EP_CMP_FFD(&ffd, &epi->ffd);
+ if (kcmp > 0)
+ rbp = rbp->rb_right;
+ else if (kcmp < 0)
+ rbp = rbp->rb_left;
+ else {
ep_use_epitem(epi);
+ epir = epi;
break;
}
- epi = NULL;
}
-
read_unlock_irqrestore(&ep->lock, flags);
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
- current, file, epi));
+ current, file, epir));
- return epi;
+ return epir;
}
}
+static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
+{
+ int kcmp;
+ struct rb_node **p = &ep->rbr.rb_node, *parent = NULL;
+ struct epitem *epic;
+
+ while (*p) {
+ parent = *p;
+ epic = rb_entry(parent, struct epitem, rbn);
+ kcmp = EP_CMP_FFD(&epi->ffd, &epic->ffd);
+ if (kcmp > 0)
+ p = &parent->rb_right;
+ else
+ p = &parent->rb_left;
+ }
+ rb_link_node(&epi->rbn, parent, p);
+ rb_insert_color(&epi->rbn, &ep->rbr);
+}
+
+
static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
struct file *tfile, int fd)
{
goto eexit_1;
/* Item initialization follow here ... */
- INIT_LIST_HEAD(&epi->llink);
+ EP_RB_INITNODE(&epi->rbn);
INIT_LIST_HEAD(&epi->rdllink);
INIT_LIST_HEAD(&epi->fllink);
INIT_LIST_HEAD(&epi->txlink);
INIT_LIST_HEAD(&epi->pwqlist);
epi->ep = ep;
- epi->file = tfile;
- epi->fd = fd;
+ EP_SET_FFD(&epi->ffd, tfile, fd);
epi->event = *event;
atomic_set(&epi->usecnt, 1);
epi->nwait = 0;
/* We have to drop the new item inside our item list to keep track of it */
write_lock_irqsave(&ep->lock, flags);
- /* Add the current item to the hash table */
- list_add(&epi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile, fd)));
+ /* Add the current item to the rb-tree */
+ ep_rbtree_insert(ep, epi);
/* If the file is already "ready" we drop it inside the ready list */
if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) {
* Get current event bits. We can safely use the file* here because
* its usage count has been increased by the caller of this function.
*/
- revents = epi->file->f_op->poll(epi->file, NULL);
+ revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
write_lock_irqsave(&ep->lock, flags);
* If the item is not linked to the hash it means that it's on its
* way toward the removal. Do nothing in this case.
*/
- if (EP_IS_LINKED(&epi->llink)) {
+ if (EP_RB_LINKED(&epi->rbn)) {
/*
* If the item is "hot" and it is not registered inside the ready
* list, push it inside. If the item is not "hot" and it is currently
* The check protect us from doing a double unlink ( crash ).
*/
error = -ENOENT;
- if (!EP_IS_LINKED(&epi->llink))
+ if (!EP_RB_LINKED(&epi->rbn))
goto eexit_1;
/*
epi->event.events = 0;
/*
- * At this point is safe to do the job, unlink the item from our list.
+ * At this point is safe to do the job, unlink the item from our rb-tree.
* This operation togheter with the above check closes the door to
* double unlinks.
*/
- EP_LIST_DEL(&epi->llink);
+ EP_RB_ERASE(&epi->rbn, &ep->rbr);
/*
* If the item we are going to remove is inside the ready file descriptors
{
int error;
unsigned long flags;
- struct file *file = epi->file;
+ struct file *file = epi->ffd.file;
/*
* Removes poll wait queue hooks. We _have_ to do this without holding
* because we are holding the "sem" in read and this will
* guarantee that both the file and the item will not vanish.
*/
- revents = epi->file->f_op->poll(epi->file, NULL);
+ revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
/*
* Set the return event set for the current file descriptor.
* item is set to have an Edge Triggered behaviour, we don't have
* to push it back either.
*/
- if (EP_IS_LINKED(&epi->llink) && !(epi->event.events & EPOLLET) &&
+ if (EP_RB_LINKED(&epi->rbn) && !(epi->event.events & EPOLLET) &&
(epi->revents & epi->event.events) && !EP_IS_LINKED(&epi->rdllink)) {
list_add_tail(&epi->rdllink, &ep->rdllist);
ricnt++;
#include <linux/rmap.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#ifdef CONFIG_KMOD
flush_thread();
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
- permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL))
+ permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
+ (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP))
current->mm->dumpable = 0;
/* An exec changes our domain. We are no longer part of the thread
int retval;
int i;
- sched_balance_exec();
-
file = open_exec(filename);
retval = PTR_ERR(file);
if (IS_ERR(file))
return retval;
+ sched_balance_exec();
+
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
bprm.file = file;
bprm.filename = filename;
bprm.interp = filename;
+ bprm.interp_flags = 0;
bprm.sh_bang = 0;
bprm.loader = 0;
bprm.exec = 0;
obj-$(CONFIG_EXT3_FS) += ext3.o
ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
- ioctl.o namei.o super.o symlink.o hash.o resize.o
+ ioctl.o namei.o super.o symlink.o hash.o
ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
error_out:
return bh;
}
-/*
- * The reservation window structure operations
- * --------------------------------------------
- * Operations include:
- * dump, find, add, remove, is_empty, find_next_reservable_window, etc.
- *
- * We use sorted double linked list for the per-filesystem reservation
- * window list. (like in vm_region).
- *
- * Initially, we keep those small operations in the abstract functions,
- * so later if we need a better searching tree than double linked-list,
- * we could easily switch to that without changing too much
- * code.
- */
-static inline void rsv_window_dump(struct reserve_window *head, char *fn)
-{
- struct reserve_window *rsv;
-
- printk("Block Allocation Reservation Windows Map (%s):\n", fn);
- list_for_each_entry(rsv, &head->rsv_list, rsv_list) {
- printk("reservation window 0x%p start: %d, end: %d\n",
- rsv, rsv->rsv_start, rsv->rsv_end);
- }
-}
-
-static int
-goal_in_my_reservation(struct reserve_window *rsv, int goal,
- unsigned int group, struct super_block * sb)
-{
- unsigned long group_first_block, group_last_block;
-
- group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
- group * EXT3_BLOCKS_PER_GROUP(sb);
- group_last_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
-
- if ((rsv->rsv_start > group_last_block) ||
- (rsv->rsv_end < group_first_block))
- return 0;
- if ((goal >= 0) && ((goal + group_first_block < rsv->rsv_start)
- || (goal + group_first_block > rsv->rsv_end)))
- return 0;
- return 1;
-}
-
-static inline void rsv_window_add(struct reserve_window *rsv,
- struct reserve_window *prev)
-{
- /* insert the new reservation window after the head */
- list_add(&rsv->rsv_list, &prev->rsv_list);
-}
-
-static inline void rsv_window_remove(struct reserve_window *rsv)
-{
- rsv->rsv_start = 0;
- rsv->rsv_end = 0;
- rsv->rsv_alloc_hit = 0;
- list_del(&rsv->rsv_list);
- INIT_LIST_HEAD(&rsv->rsv_list);
-}
-
-static inline int rsv_is_empty(struct reserve_window *rsv)
-{
- /* a valid reservation end block could not be 0 */
- return (rsv->rsv_end == 0);
-}
-
-void ext3_discard_reservation(struct inode *inode)
-{
- struct ext3_inode_info *ei = EXT3_I(inode);
- struct reserve_window *rsv = &ei->i_rsv_window;
- spinlock_t *rsv_lock = &EXT3_SB(inode->i_sb)->s_rsv_window_lock;
-
- if (!rsv_is_empty(rsv)) {
- spin_lock(rsv_lock);
- rsv_window_remove(rsv);
- spin_unlock(rsv_lock);
- }
-}
/* Free given blocks, update quota and i_blocks field */
-void ext3_free_blocks(handle_t *handle, struct inode *inode,
+void ext3_free_blocks (handle_t *handle, struct inode * inode,
unsigned long block, unsigned long count)
{
struct buffer_head *bitmap_bh = NULL;
error_return:
brelse(bitmap_bh);
ext3_std_error(sb, err);
- if (dquot_freed_blocks && !(EXT3_I(inode)->i_state & EXT3_STATE_RESIZE))
+ if (dquot_freed_blocks)
DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
return;
}
* data-writes at some point, and disable it for metadata allocations or
* sync-data inodes.
*/
-static int ext3_test_allocatable(int nr, struct buffer_head *bh)
+static inline int ext3_test_allocatable(int nr, struct buffer_head *bh)
{
int ret;
struct journal_head *jh = bh2jh(bh);
return ret;
}
-static int
-bitmap_search_next_usable_block(int start, struct buffer_head *bh,
- int maxblocks)
-{
- int next;
- struct journal_head *jh = bh2jh(bh);
-
- /*
- * The bitmap search --- search forward alternately through the actual
- * bitmap and the last-committed copy until we find a bit free in
- * both
- */
- while (start < maxblocks) {
- next = ext3_find_next_zero_bit(bh->b_data, maxblocks, start);
- if (next >= maxblocks)
- return -1;
- if (ext3_test_allocatable(next, bh))
- return next;
- jbd_lock_bh_state(bh);
- if (jh->b_committed_data)
- start = ext3_find_next_zero_bit(jh->b_committed_data,
- maxblocks, next);
- jbd_unlock_bh_state(bh);
- }
- return -1;
-}
-
/*
* Find an allocatable block in a bitmap. We honour both the bitmap and
* its last-committed copy (if that exists), and perform the "most
{
int here, next;
char *p, *r;
+ struct journal_head *jh = bh2jh(bh);
if (start > 0) {
/*
* next 64-bit boundary is simple..
*/
int end_goal = (start + 63) & ~63;
- if (end_goal > maxblocks)
- end_goal = maxblocks;
here = ext3_find_next_zero_bit(bh->b_data, end_goal, start);
if (here < end_goal && ext3_test_allocatable(here, bh))
return here;
r = memscan(p, 0, (maxblocks - here + 7) >> 3);
next = (r - ((char *)bh->b_data)) << 3;
- if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh))
+ if (next < maxblocks && ext3_test_allocatable(next, bh))
return next;
/*
* bitmap and the last-committed copy until we find a bit free in
* both
*/
- here = bitmap_search_next_usable_block(here, bh, maxblocks);
- return here;
+ while (here < maxblocks) {
+ next = ext3_find_next_zero_bit(bh->b_data, maxblocks, here);
+ if (next >= maxblocks)
+ return -1;
+ if (ext3_test_allocatable(next, bh))
+ return next;
+ jbd_lock_bh_state(bh);
+ if (jh->b_committed_data)
+ here = ext3_find_next_zero_bit(jh->b_committed_data,
+ maxblocks, next);
+ jbd_unlock_bh_state(bh);
+ }
+ return -1;
}
/*
*/
static int
ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
- struct buffer_head *bitmap_bh, int goal, struct reserve_window *my_rsv)
+ struct buffer_head *bitmap_bh, int goal, int *errp)
{
- int group_first_block, start, end;
-
- /* we do allocation within the reservation window if we have a window */
- if (my_rsv) {
- group_first_block =
- le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
- group * EXT3_BLOCKS_PER_GROUP(sb);
- if (my_rsv->rsv_start >= group_first_block)
- start = my_rsv->rsv_start - group_first_block;
- else
- /* reservation window cross group boundary */
- start = 0;
- end = my_rsv->rsv_end - group_first_block + 1;
- if (end > EXT3_BLOCKS_PER_GROUP(sb))
- /* reservation window crosses group boundary */
- end = EXT3_BLOCKS_PER_GROUP(sb);
- if ((start <= goal) && (goal < end))
- start = goal;
- else
- goal = -1;
- } else {
- if (goal > 0)
- start = goal;
- else
- start = 0;
- end = EXT3_BLOCKS_PER_GROUP(sb);
- }
+ int i;
+ int fatal;
+ int credits = 0;
- BUG_ON(start > EXT3_BLOCKS_PER_GROUP(sb));
+ *errp = 0;
+
+ /*
+ * Make sure we use undo access for the bitmap, because it is critical
+ * that we do the frozen_data COW on bitmap buffers in all cases even
+ * if the buffer is in BJ_Forget state in the committing transaction.
+ */
+ BUFFER_TRACE(bitmap_bh, "get undo access for new block");
+ fatal = ext3_journal_get_undo_access(handle, bitmap_bh, &credits);
+ if (fatal) {
+ *errp = fatal;
+ goto fail;
+ }
repeat:
if (goal < 0 || !ext3_test_allocatable(goal, bitmap_bh)) {
- goal = find_next_usable_block(start, bitmap_bh, end);
+ goal = find_next_usable_block(goal, bitmap_bh,
+ EXT3_BLOCKS_PER_GROUP(sb));
if (goal < 0)
goto fail_access;
- if (!my_rsv) {
- int i;
-
- for (i = 0; i < 7 && goal > start &&
- ext3_test_allocatable(goal - 1,
- bitmap_bh);
- i++, goal--)
- ;
- }
+
+ for (i = 0; i < 7 && goal > 0 &&
+ ext3_test_allocatable(goal - 1, bitmap_bh);
+ i++, goal--);
}
- start = goal;
if (!claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) {
/*
* The block was allocated by another thread, or it was
* allocated and then freed by another thread
*/
- start++;
goal++;
- if (start >= end)
+ if (goal >= EXT3_BLOCKS_PER_GROUP(sb))
goto fail_access;
goto repeat;
}
- if (my_rsv)
- my_rsv->rsv_alloc_hit++;
- return goal;
-fail_access:
- return -1;
-}
-/**
- * find_next_reservable_window():
- * find a reservable space within the given range
- * It does not allocate the reservation window for now
- * alloc_new_reservation() will do the work later.
- *
- * @search_head: the head of the searching list;
- * This is not necessary the list head of the whole filesystem
- *
- * we have both head and start_block to assist the search
- * for the reservable space. The list start from head,
- * but we will shift to the place where start_block is,
- * then start from there, we looking for a resevable space.
- *
- * @fs_rsv_head: per-filesystem reervation list head.
- *
- * @size: the target new reservation window size
- * @group_first_block: the first block we consider to start
- * the real search from
- *
- * @last_block:
- * the maxium block number that our goal reservable space
- * could start from. This is normally the last block in this
- * group. The search will end when we found the start of next
- * possiblereservable space is out of this boundary.
- * This could handle the cross bounday reservation window request.
- *
- * basically we search from the given range, rather than the whole
- * reservation double linked list, (start_block, last_block)
- * to find a free region that of of my size and has not
- * been reserved.
- *
- * on succeed, it returns the reservation window to be append to.
- * failed, return NULL.
- */
-static inline
-struct reserve_window *find_next_reservable_window(
- struct reserve_window *search_head,
- struct reserve_window *fs_rsv_head,
- unsigned long size, int *start_block,
- int last_block)
-{
- struct reserve_window *rsv;
- int cur;
-
- /* TODO:make the start of the reservation window byte alligned */
- /*cur = *start_block & 8;*/
- cur = *start_block;
- rsv = list_entry(search_head->rsv_list.next,
- struct reserve_window, rsv_list);
- while (rsv != fs_rsv_head) {
- if (cur + size <= rsv->rsv_start) {
- /*
- * Found a reserveable space big enough. We could
- * have a reservation across the group boundary here
- */
- break;
- }
- if (cur <= rsv->rsv_end)
- cur = rsv->rsv_end + 1;
-
- /* TODO?
- * in the case we could not find a reservable space
- * that is what is expected, during the re-search, we could
- * remember what's the largest reservable space we could have
- * and return that one.
- *
- * For now it will fail if we could not find the reservable
- * space with expected-size (or more)...
- */
- rsv = list_entry(rsv->rsv_list.next,
- struct reserve_window, rsv_list);
- if (cur > last_block)
- return NULL; /* fail */
- }
- /*
- * we come here either :
- * when we rearch to the end of the whole list,
- * and there is empty reservable space after last entry in the list.
- * append it to the end of the list.
- *
- * or we found one reservable space in the middle of the list,
- * return the reservation window that we could append to.
- * succeed.
- */
- *start_block = cur;
- return list_entry(rsv->rsv_list.prev, struct reserve_window, rsv_list);
-}
-
-/**
- * alloc_new_reservation()--allocate a new reservation window
- * if there is an existing reservation, discard it first
- * then allocate the new one from there
- * otherwise allocate the new reservation from the given
- * start block, or the beginning of the group, if a goal
- * is not given.
- *
- * To make a new reservation, we search part of the filesystem
- * reservation list(the list that inside the group).
- *
- * If we have a old reservation, the search goal is the end of
- * last reservation. If we do not have a old reservatio, then we
- * start from a given goal, or the first block of the group, if
- * the goal is not given.
- *
- * We first find a reservable space after the goal, then from
- * there,we check the bitmap for the first free block after
- * it. If there is no free block until the end of group, then the
- * whole group is full, we failed. Otherwise, check if the free
- * block is inside the expected reservable space, if so, we
- * succeed.
- * If the first free block is outside the reseravle space, then
- * start from the first free block, we search for next avalibale
- * space, and go on.
- *
- * on succeed, a new reservation will be found and inserted into the list
- * It contains at least one free block, and it is not overlap with other
- * reservation window.
- *
- * failed: we failed to found a reservation window in this group
- *
- * @rsv: the reservation
- *
- * @goal: The goal. It is where the search for a
- * free reservable space should start from.
- * if we have a old reservation, start_block is the end of
- * old reservation. Otherwise,
- * if we have a goal(goal >0 ), then start from there,
- * no goal(goal = -1), we start from the first block
- * of the group.
- *
- * @sb: the super block
- * @group: the group we are trying to do allocate in
- * @bitmap_bh: the block group block bitmap
- */
-static int alloc_new_reservation(struct reserve_window *my_rsv,
- int goal, struct super_block *sb,
- unsigned int group, struct buffer_head *bitmap_bh)
-{
- struct reserve_window *search_head;
- int group_first_block, group_end_block, start_block;
- int first_free_block;
- int reservable_space_start;
- struct reserve_window *prev_rsv;
- struct reserve_window *fs_rsv_head = &EXT3_SB(sb)->s_rsv_window_head;
- unsigned long size;
-
- group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
- group * EXT3_BLOCKS_PER_GROUP(sb);
- group_end_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
-
- if (goal < 0)
- start_block = group_first_block;
- else
- start_block = goal + group_first_block;
-
- size = atomic_read(&my_rsv->rsv_goal_size);
- /* if we have a old reservation, start the search from the old rsv */
- if (!rsv_is_empty(my_rsv)) {
- /*
- * if the old reservation is cross group boundary
- * we will come here when we just failed to allocate from
- * the first part of the window. We still have another part
- * that belongs to the next group. In this case, there is no
- * point to discard our window and try to allocate a new one
- * in this group(which will fail). we should
- * keep the reservation window, just simply move on.
- *
- * Maybe we could shift the start block of the reservation
- * window to the first block of next group.
- */
-
- if ((my_rsv->rsv_start <= group_end_block) &&
- (my_rsv->rsv_end > group_end_block))
- return -1;
-
- /* remember where we are before we discard the old one */
- if (my_rsv->rsv_end + 1 > start_block)
- start_block = my_rsv->rsv_end + 1;
- search_head = my_rsv;
- if ((my_rsv->rsv_alloc_hit > (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) {
- /*
- * if we previously allocation hit ration is greater than half
- * we double the size of reservation window next time
- * otherwise keep the same
- */
- size = size * 2;
- if (size > EXT3_MAX_RESERVE_BLOCKS)
- size = EXT3_MAX_RESERVE_BLOCKS;
- atomic_set(&my_rsv->rsv_goal_size, size);
- }
- }
- else {
- /*
- * we don't have a reservation,
- * we set our goal(start_block) and
- * the list head for the search
- */
- search_head = fs_rsv_head;
- }
-
- /*
- * find_next_reservable_window() simply find a reservable window
- * inside the given range(start_block, group_end_block).
- *
- * To make sure the reservation window has a free bit inside it, we
- * need to check the bitmap after we found a reservable window.
- */
-retry:
- prev_rsv = find_next_reservable_window(search_head, fs_rsv_head, size,
- &start_block, group_end_block);
- if (prev_rsv == NULL)
- goto failed;
- reservable_space_start = start_block;
- /*
- * On success, find_next_reservable_window() returns the
- * reservation window where there is a reservable space after it.
- * Before we reserve this reservable space, we need
- * to make sure there is at least a free block inside this region.
- *
- * searching the first free bit on the block bitmap and copy of
- * last committed bitmap alternatively, until we found a allocatable
- * block. Search start from the start block of the reservable space
- * we just found.
- */
- first_free_block = bitmap_search_next_usable_block(
- reservable_space_start - group_first_block,
- bitmap_bh, group_end_block - group_first_block + 1);
-
- if (first_free_block < 0) {
- /*
- * no free block left on the bitmap, no point
- * to reserve the space. return failed.
- */
- goto failed;
- }
- start_block = first_free_block + group_first_block;
- /*
- * check if the first free block is within the
- * free space we just found
- */
- if ((start_block >= reservable_space_start) &&
- (start_block < reservable_space_start + size))
- goto found_rsv_window;
- /*
- * if the first free bit we found is out of the reservable space
- * this means there is no free block on the reservable space
- * we should continue search for next reservable space,
- * start from where the free block is,
- * we also shift the list head to where we stopped last time
- */
- search_head = prev_rsv;
- goto retry;
-
-found_rsv_window:
- /*
- * great! the reservable space contains some free blocks.
- * if the search returns that we should add the new
- * window just next to where the old window, we don't
- * need to remove the old window first then add it to the
- * same place, just update the new start and new end.
- */
- if (my_rsv != prev_rsv) {
- if (!rsv_is_empty(my_rsv))
- rsv_window_remove(my_rsv);
- rsv_window_add(my_rsv, prev_rsv);
- }
- my_rsv->rsv_start = reservable_space_start;
- my_rsv->rsv_end = my_rsv->rsv_start + size - 1;
- return 0; /* succeed */
-failed:
- return -1; /* failed */
-}
-
-/*
- * This is the main function used to allocate a new block and its reservation
- * window.
- *
- * Each time when a new block allocation is need, first try to allocate from
- * its own reservation. If it does not have a reservation window, instead of
- * looking for a free bit on bitmap first, then look up the reservation list to
- * see if it is inside somebody else's reservation window, we try to allocate a
- * reservation window for it start from the goal first. Then do the block
- * allocation within the reservation window.
- *
- * This will aviod keep searching the reservation list again and again when
- * someboday is looking for a free block(without reservation), and there are
- * lots of free blocks, but they are all being reserved
- *
- * We use a sorted double linked list for the per-filesystem reservation list.
- * The insert, remove and find a free space(non-reserved) operations for the
- * sorted double linked list should be fast.
- *
- */
-static int
-ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
- unsigned int group, struct buffer_head *bitmap_bh,
- int goal, struct reserve_window * my_rsv,
- int *errp)
-{
- spinlock_t *rsv_lock;
- unsigned long group_first_block;
- int ret = 0;
- int fatal;
- int credits = 0;
-
- *errp = 0;
-
- /*
- * Make sure we use undo access for the bitmap, because it is critical
- * that we do the frozen_data COW on bitmap buffers in all cases even
- * if the buffer is in BJ_Forget state in the committing transaction.
- */
- BUFFER_TRACE(bitmap_bh, "get undo access for new block");
- fatal = ext3_journal_get_undo_access(handle, bitmap_bh, &credits);
+ BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for bitmap block");
+ fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
if (fatal) {
*errp = fatal;
- return -1;
- }
-
- /*
- * we don't deal with reservation when
- * filesystem is mounted without reservation
- * or the file is not a regular file
- * of last attemp of allocating a block with reservation turn on failed
- */
- if (my_rsv == NULL ) {
- ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
- goto out;
- }
- rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
- /*
- * goal is a group relative block number (if there is a goal)
- * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb)
- * first block is a filesystem wide block number
- * first block is the block number of the first block in this group
- */
- group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
- group * EXT3_BLOCKS_PER_GROUP(sb);
-
- /*
- * Basically we will allocate a new block from inode's reservation
- * window.
- *
- * We need to allocate a new reservation window, if:
- * a) inode does not have a reservation window; or
- * b) last attemp of allocating a block from existing reservation
- * failed; or
- * c) we come here with a goal and with a reservation window
- *
- * We do not need to allocate a new reservation window if we come here
- * at the beginning with a goal and the goal is inside the window, or
- * or we don't have a goal but already have a reservation window.
- * then we could go to allocate from the reservation window directly.
- */
- while (1) {
- if (rsv_is_empty(my_rsv) || (ret < 0) ||
- !goal_in_my_reservation(my_rsv, goal, group, sb)) {
- spin_lock(rsv_lock);
- ret = alloc_new_reservation(my_rsv, goal, sb,
- group, bitmap_bh);
- spin_unlock(rsv_lock);
- if (ret < 0)
- break; /* failed */
-
- if (!goal_in_my_reservation(my_rsv, goal, group, sb))
- goal = -1;
- }
- if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
- || (my_rsv->rsv_end < group_first_block))
- BUG();
- ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
- my_rsv);
- if (ret >= 0)
- break; /* succeed */
- }
-out:
- if (ret >= 0) {
- BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for "
- "bitmap block");
- fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
- if (fatal) {
- *errp = fatal;
- return -1;
- }
- return ret;
+ goto fail;
}
+ return goal;
+fail_access:
BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
ext3_journal_release_buffer(handle, bitmap_bh, credits);
- return ret;
+fail:
+ return -1;
}
static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
* bitmap, and then for any free bit if that fails.
* This function also updates quota and i_blocks field.
*/
-int ext3_new_block(handle_t *handle, struct inode *inode,
- unsigned long goal, int *errp)
+int
+ext3_new_block(handle_t *handle, struct inode *inode, unsigned long goal,
+ u32 *prealloc_count, u32 *prealloc_block, int *errp)
{
- struct buffer_head *bitmap_bh = NULL;
- struct buffer_head *gdp_bh;
- int group_no;
- int goal_group;
- int ret_block;
- int bgi; /* blockgroup iteration index */
- int target_block;
+ struct buffer_head *bitmap_bh = NULL; /* bh */
+ struct buffer_head *gdp_bh; /* bh2 */
+ int group_no; /* i */
+ int ret_block; /* j */
+ int bgi; /* blockgroup iteration index */
+ int target_block; /* tmp */
int fatal = 0, err;
int performed_allocation = 0;
int free_blocks;
struct ext3_group_desc *gdp;
struct ext3_super_block *es;
struct ext3_sb_info *sbi;
- struct reserve_window *my_rsv = NULL;
#ifdef EXT3FS_DEBUG
static int goal_hits, goal_attempts;
#endif
sbi = EXT3_SB(sb);
es = EXT3_SB(sb)->s_es;
ext3_debug("goal=%lu.\n", goal);
- if (test_opt(sb, RESERVATION) && S_ISREG(inode->i_mode))
- my_rsv = &EXT3_I(inode)->i_rsv_window;
+
if (!ext3_has_free_blocks(sbi)) {
*errp = -ENOSPC;
goto out;
if (!gdp)
goto io_error;
- goal_group = group_no;
-retry:
free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
if (free_blocks > 0) {
ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
goto io_error;
- ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
- bitmap_bh, ret_block, my_rsv, &fatal);
+ ret_block = ext3_try_to_allocate(sb, handle, group_no,
+ bitmap_bh, ret_block, &fatal);
if (fatal)
goto out;
if (ret_block >= 0)
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
goto io_error;
- ret_block = ext3_try_to_allocate_with_rsv(sb, handle, group_no,
- bitmap_bh, -1, my_rsv, &fatal);
+ ret_block = ext3_try_to_allocate(sb, handle, group_no,
+ bitmap_bh, -1, &fatal);
if (fatal)
goto out;
if (ret_block >= 0)
goto allocated;
}
- /*
- * We may end up a bogus ealier ENOSPC error due to
- * filesystem is "full" of reservations, but
- * there maybe indeed free blocks avaliable on disk
- * In this case, we just forget about the reservations
- * just do block allocation as without reservations.
- */
- if (my_rsv) {
- my_rsv = NULL;
- group_no = goal_group;
- goto retry;
- }
+
/* No space left on the device */
*errp = -ENOSPC;
goto out;
*/
static int ext3_release_file (struct inode * inode, struct file * filp)
{
- /* if we are the last writer on the inode, drop the block reservation */
- if ((filp->f_mode & FMODE_WRITE) &&
- (atomic_read(&inode->i_writecount) == 1))
- ext3_discard_reservation(inode);
+ if (filp->f_mode & FMODE_WRITE)
+ ext3_discard_prealloc (inode);
if (is_dx(inode) && filp->private_data)
ext3_htree_free_dir_info(filp->private_data);
ei->i_file_acl = 0;
ei->i_dir_acl = 0;
ei->i_dtime = 0;
- ei->i_rsv_window.rsv_start = 0;
- ei->i_rsv_window.rsv_end = 0;
- atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS);
- ei->i_rsv_window.rsv_alloc_hit = 0;
- INIT_LIST_HEAD(&ei->i_rsv_window.rsv_list);
+#ifdef EXT3_PREALLOCATE
+ ei->i_prealloc_block = 0;
+ ei->i_prealloc_count = 0;
+#endif
ei->i_block_group = group;
ext3_set_inode_flags(inode);
return ext3_journal_restart(handle, blocks_for_truncate(inode));
}
+/*
+ * Called at each iput()
+ *
+ * The inode may be "bad" if ext3_read_inode() saw an error from
+ * ext3_get_inode(), so we need to check that to avoid freeing random disk
+ * blocks.
+ */
+void ext3_put_inode(struct inode *inode)
+{
+ if (!is_bad_inode(inode))
+ ext3_discard_prealloc(inode);
+}
+
/*
* Called at the last iput() if i_nlink is zero.
*/
clear_inode(inode); /* We must guarantee clearing of inode... */
}
+void ext3_discard_prealloc (struct inode * inode)
+{
+#ifdef EXT3_PREALLOCATE
+ struct ext3_inode_info *ei = EXT3_I(inode);
+ /* Writer: ->i_prealloc* */
+ if (ei->i_prealloc_count) {
+ unsigned short total = ei->i_prealloc_count;
+ unsigned long block = ei->i_prealloc_block;
+ ei->i_prealloc_count = 0;
+ ei->i_prealloc_block = 0;
+ /* Writer: end */
+ ext3_free_blocks (inode, block, total);
+ }
+#endif
+}
+
static int ext3_alloc_block (handle_t *handle,
struct inode * inode, unsigned long goal, int *err)
{
unsigned long result;
- result = ext3_new_block (handle, inode, goal, err);
+#ifdef EXT3_PREALLOCATE
+#ifdef EXT3FS_DEBUG
+ static unsigned long alloc_hits, alloc_attempts;
+#endif
+ struct ext3_inode_info *ei = EXT3_I(inode);
+ /* Writer: ->i_prealloc* */
+ if (ei->i_prealloc_count &&
+ (goal == ei->i_prealloc_block ||
+ goal + 1 == ei->i_prealloc_block))
+ {
+ result = ei->i_prealloc_block++;
+ ei->i_prealloc_count--;
+ /* Writer: end */
+ ext3_debug ("preallocation hit (%lu/%lu).\n",
+ ++alloc_hits, ++alloc_attempts);
+ } else {
+ ext3_discard_prealloc (inode);
+ ext3_debug ("preallocation miss (%lu/%lu).\n",
+ alloc_hits, ++alloc_attempts);
+ if (S_ISREG(inode->i_mode))
+ result = ext3_new_block (inode, goal,
+ &ei->i_prealloc_count,
+ &ei->i_prealloc_block, err);
+ else
+ result = ext3_new_block (inode, goal, 0, 0, err);
+ /*
+ * AKPM: this is somewhat sticky. I'm not surprised it was
+ * disabled in 2.2's ext3. Need to integrate b_committed_data
+ * guarding with preallocation, if indeed preallocation is
+ * effective.
+ */
+ }
+#else
+ result = ext3_new_block (handle, inode, goal, 0, 0, err);
+#endif
return result;
}
bh = ext3_getblk (handle, inode, block, create, err);
if (!bh)
return bh;
+#ifdef EXT3_PREALLOCATE
+ /*
+ * If the inode has grown, and this is a directory, then use a few
+ * more of the preallocated blocks to keep directory fragmentation
+ * down. The preallocated blocks are guaranteed to be contiguous.
+ */
+ if (create &&
+ S_ISDIR(inode->i_mode) &&
+ inode->i_blocks > prev_blocks &&
+ EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
+ EXT3_FEATURE_COMPAT_DIR_PREALLOC)) {
+ int i;
+ struct buffer_head *tmp_bh;
+
+ for (i = 1;
+ EXT3_I(inode)->i_prealloc_count &&
+ i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
+ i++) {
+ /*
+ * ext3_getblk will zero out the contents of the
+ * directory for us
+ */
+ tmp_bh = ext3_getblk(handle, inode,
+ block+i, create, err);
+ if (!tmp_bh) {
+ brelse (bh);
+ return 0;
+ }
+ brelse (tmp_bh);
+ }
+ }
+#endif
if (buffer_uptodate(bh))
return bh;
ll_rw_block (READ, 1, &bh);
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
- ext3_discard_reservation(inode);
+ ext3_discard_prealloc(inode);
/*
* We have to lock the EOF page here, because lock_page() nests
unsigned long offset, block;
struct buffer_head *bh;
struct ext3_group_desc * gdp;
-
if ((ino != EXT3_ROOT_INO &&
ino != EXT3_JOURNAL_INO &&
- ino != EXT3_RESIZE_INO &&
ino < EXT3_FIRST_INO(sb)) ||
ino > le32_to_cpu(
EXT3_SB(sb)->s_es->s_inodes_count)) {
}
ei->i_disksize = inode->i_size;
inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+#ifdef EXT3_PREALLOCATE
+ ei->i_prealloc_count = 0;
+#endif
ei->i_block_group = iloc.block_group;
- ei->i_rsv_window.rsv_start = 0;
- ei->i_rsv_window.rsv_end= 0;
- atomic_set(&ei->i_rsv_window.rsv_goal_size, EXT3_DEFAULT_RESERVE_BLOCKS);
- INIT_LIST_HEAD(&ei->i_rsv_window.rsv_list);
+
/*
* NOTE! The in-memory inode i_data array is in little-endian order
* even on big-endian machines: we do NOT byteswap the block numbers!
{
struct ext3_inode_info *ei = EXT3_I(inode);
unsigned int flags;
- unsigned short rsv_window_size;
ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
switch (cmd) {
case EXT3_IOC_GETFLAGS:
flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
- return put_user(flags, (int *) arg);
+ return put_user(flags, (int __user *) arg);
case EXT3_IOC_SETFLAGS: {
handle_t *handle = NULL;
int err;
if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
return -EACCES;
- if (get_user(flags, (int *) arg))
+ if (get_user(flags, (int __user *) arg))
return -EFAULT;
if (!S_ISDIR(inode->i_mode))
}
case EXT3_IOC_GETVERSION:
case EXT3_IOC_GETVERSION_OLD:
- return put_user(inode->i_generation, (int *) arg);
+ return put_user(inode->i_generation, (int __user *) arg);
case EXT3_IOC_SETVERSION:
case EXT3_IOC_SETVERSION_OLD: {
handle_t *handle;
return -EPERM;
if (IS_RDONLY(inode))
return -EROFS;
- if (get_user(generation, (int *) arg))
+ if (get_user(generation, (int __user *) arg))
return -EFAULT;
handle = ext3_journal_start(inode, 1);
return ret;
}
#endif
- case EXT3_IOC_GETRSVSZ:
- if (test_opt(inode->i_sb, RESERVATION) && S_ISREG(inode->i_mode)) {
- rsv_window_size = atomic_read(&ei->i_rsv_window.rsv_goal_size);
- return put_user(rsv_window_size, (int *)arg);
- }
- return -ENOTTY;
- case EXT3_IOC_SETRSVSZ:
- if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
- return -ENOTTY;
-
- if (IS_RDONLY(inode))
- return -EROFS;
-
- if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
- return -EACCES;
-
- if (get_user(rsv_window_size, (int *)arg))
- return -EFAULT;
-
- if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS)
- rsv_window_size = EXT3_MAX_RESERVE_BLOCKS;
- atomic_set(&ei->i_rsv_window.rsv_goal_size, rsv_window_size);
- return 0;
- case EXT3_IOC_GROUP_EXTEND: {
- unsigned long n_blocks_count;
- struct super_block *sb = inode->i_sb;
- int err;
-
- if (!capable(CAP_SYS_RESOURCE))
- return -EACCES;
-
- if (sb->s_flags & MS_RDONLY)
- return -EROFS;
-
- if (get_user(n_blocks_count, (__u32 *)arg))
- return -EFAULT;
-
- err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count);
- journal_lock_updates(EXT3_SB(sb)->s_journal);
- journal_flush(EXT3_SB(sb)->s_journal);
- journal_unlock_updates(EXT3_SB(sb)->s_journal);
-
- return err;
- }
- case EXT3_IOC_GROUP_ADD: {
- struct ext3_new_group_data input;
- struct super_block *sb = inode->i_sb;
- int err;
-
- if (!capable(CAP_SYS_RESOURCE))
- return -EACCES;
-
- if (inode->i_sb->s_flags & MS_RDONLY)
- return -EROFS;
-
- if (copy_from_user(&input, (struct ext3_new_group_input *)arg,
- sizeof(input)))
- return -EFAULT;
-
- err = ext3_group_add(sb, &input);
- journal_lock_updates(EXT3_SB(sb)->s_journal);
- journal_flush(EXT3_SB(sb)->s_journal);
- journal_unlock_updates(EXT3_SB(sb)->s_journal);
-
- return err;
- }
-
-
default:
return -ENOTTY;
}
((hinfo->hash == start_hash) &&
(hinfo->minor_hash < start_minor_hash)))
continue;
+ if (de->inode == 0)
+ continue;
if ((err = ext3_htree_store_dirent(dir_file,
hinfo->hash, hinfo->minor_hash, de)) != 0) {
brelse(bh);
goto out_brelse;
NEXT_ORPHAN(inode) = 0;
err = ext3_mark_iloc_dirty(handle, inode, &iloc);
- if (err)
- goto out_brelse;
out_err:
ext3_std_error(inode->i_sb, err);
printk(KERN_INFO "ext3_inode_cache: not all structures were freed\n");
}
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+
static void ext3_clear_inode(struct inode *inode)
{
-#ifdef CONFIG_EXT3_FS_POSIX_ACL
if (EXT3_I(inode)->i_acl &&
EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) {
posix_acl_release(EXT3_I(inode)->i_acl);
posix_acl_release(EXT3_I(inode)->i_default_acl);
EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED;
}
-#endif
- if (!is_bad_inode(inode))
- ext3_discard_reservation(inode);
}
+#else
+# define ext3_clear_inode NULL
+#endif
+
#ifdef CONFIG_QUOTA
#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
.read_inode = ext3_read_inode,
.write_inode = ext3_write_inode,
.dirty_inode = ext3_dirty_inode,
+ .put_inode = ext3_put_inode,
.delete_inode = ext3_delete_inode,
.put_super = ext3_put_super,
.write_super = ext3_write_super,
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
- Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
- Opt_reservation, Opt_noreservation, Opt_noload,
+ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
Opt_commit, Opt_journal_update, Opt_journal_inum,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
- Opt_ignore, Opt_err, Opt_resize,
+ Opt_ignore, Opt_err,
};
static match_table_t tokens = {
{Opt_nouser_xattr, "nouser_xattr"},
{Opt_acl, "acl"},
{Opt_noacl, "noacl"},
- {Opt_reservation, "reservation"},
- {Opt_noreservation, "noreservation"},
{Opt_noload, "noload"},
{Opt_commit, "commit=%u"},
{Opt_journal_update, "journal=update"},
{Opt_ignore, "noquota"},
{Opt_ignore, "quota"},
{Opt_ignore, "usrquota"},
- {Opt_err, NULL},
- {Opt_resize, "resize"}
-
+ {Opt_err, NULL}
};
static unsigned long get_sb_block(void **data)
}
static int parse_options (char * options, struct super_block *sb,
- unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
+ unsigned long * inum, int is_remount)
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
char * p;
printk("EXT3 (no)acl options not supported\n");
break;
#endif
- case Opt_reservation:
- set_opt(sbi->s_mount_opt, RESERVATION);
- break;
- case Opt_noreservation:
- clear_opt(sbi->s_mount_opt, RESERVATION);
- break;
case Opt_journal_update:
/* @@@ FIXME */
/* Eventually we will want to be able to create
break;
case Opt_ignore:
break;
- case Opt_resize:
- if (!n_blocks_count) {
- printk("EXT3-fs: resize option only available "
- "for remount\n");
- return 0;
- }
- match_int(&args[0], &option);
- *n_blocks_count = option;
- break;
default:
printk (KERN_ERR
"EXT3-fs: Unrecognized mount option \"%s\" "
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
- set_opt(sbi->s_mount_opt, RESERVATION);
-
- if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
+ if (!parse_options ((char *) data, sb, &journal_inum, 0))
goto failed_mount;
sb->s_flags |= MS_ONE_SECOND;
sbi->s_gdb_count = db_count;
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock);
- /* per fileystem reservation list head & lock */
- spin_lock_init(&sbi->s_rsv_window_lock);
- INIT_LIST_HEAD(&sbi->s_rsv_window_head.rsv_list);
- sbi->s_rsv_window_head.rsv_start = 0;
- sbi->s_rsv_window_head.rsv_end = 0;
- sbi->s_rsv_window_head.rsv_alloc_hit = 0;
- atomic_set(&sbi->s_rsv_window_head.rsv_goal_size, 0);
-
/*
* set up enough so that it can read an inode
*/
if (!journal) {
printk(KERN_ERR "EXT3-fs: Could not load journal inode\n");
iput(journal_inode);
+ return NULL;
}
journal->j_private = sb;
ext3_init_journal_params(EXT3_SB(sb), journal);
static void ext3_mark_recovery_complete(struct super_block * sb,
struct ext3_super_block * es)
{
- journal_flush(EXT3_SB(sb)->s_journal);
+ journal_t *journal = EXT3_SB(sb)->s_journal;
+
+ journal_lock_updates(journal);
+ journal_flush(journal);
if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) &&
sb->s_flags & MS_RDONLY) {
EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
sb->s_dirt = 0;
ext3_commit_super(sb, es, 1);
}
+ journal_unlock_updates(journal);
}
/*
struct ext3_super_block * es;
struct ext3_sb_info *sbi = EXT3_SB(sb);
unsigned long tmp;
- unsigned long n_blocks_count = 0;
/*
* Allow the "check" option to be passed as a remount option.
*/
- if (!parse_options(data, sb, &tmp, &n_blocks_count, 1))
+ if (!parse_options(data, sb, &tmp, 1))
return -EINVAL;
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
ext3_init_journal_params(sbi, sbi->s_journal);
- if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
- n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
+ if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
return -EROFS;
*/
ext3_clear_journal_err(sb, es);
sbi->s_mount_state = le16_to_cpu(es->s_state);
- if ((ret = ext3_group_extend(sb, es, n_blocks_count)))
- return ret;
if (!ext3_setup_super (sb, es, 0))
sb->s_flags &= ~MS_RDONLY;
}
EXT3_I(inode)->i_block_group *
EXT3_BLOCKS_PER_GROUP(sb);
int block = ext3_new_block(handle,
- inode, goal, &error);
+ inode, goal, 0, 0, &error);
if (error)
goto cleanup;
ea_idebug(inode, "creating block %d", block);
sb = sb_entry(super_blocks.prev);
for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
if (!list_empty(&sb->s_dirty) || !list_empty(&sb->s_io)) {
+ /* we're making our own get_super here */
sb->s_count++;
spin_unlock(&sb_lock);
- sync_sb_inodes(sb, wbc);
+ /*
+ * If we can't get the readlock, there's no sense in
+ * waiting around, most of the time the FS is going to
+ * be unmounted by the time it is released.
+ */
+ if (down_read_trylock(&sb->s_umount)) {
+ if (sb->s_root)
+ sync_sb_inodes(sb, wbc);
+ up_read(&sb->s_umount);
+ }
spin_lock(&sb_lock);
if (__put_super(sb))
goto restart;
*/
void sync_inodes_sb(struct super_block *sb, int wait)
{
- struct page_state ps;
struct writeback_control wbc = {
- .bdi = NULL,
.sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD,
- .older_than_this = NULL,
- .nr_to_write = 0,
};
+ unsigned long nr_dirty = read_page_state(nr_dirty);
+ unsigned long nr_unstable = read_page_state(nr_unstable);
- get_page_state(&ps);
- wbc.nr_to_write = ps.nr_dirty + ps.nr_unstable +
+ wbc.nr_to_write = nr_dirty + nr_unstable +
(inodes_stat.nr_inodes - inodes_stat.nr_unused) +
- ps.nr_dirty + ps.nr_unstable;
+ nr_dirty + nr_unstable;
wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */
spin_lock(&inode_lock);
sync_sb_inodes(sb, &wbc);
flags |= EXT2_FLAG_APPEND; /* EXT2_APPEND_FL */
if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP)
flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
- return put_user(flags, (int *)arg);
+ return put_user(flags, (int __user *)arg);
case HFSPLUS_IOC_EXT2_SETFLAGS: {
if (IS_RDONLY(inode))
return -EROFS;
if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
return -EACCES;
- if (get_user(flags, (int *)arg))
+ if (get_user(flags, (int __user *)arg))
return -EFAULT;
if (flags & (EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND) ||
struct qstr quick_string;
char buf[16];
- if (!can_do_mlock())
+ if (!capable(CAP_IPC_LOCK))
return ERR_PTR(-EPERM);
if (!is_hugepage_mem_enough(size))
obj-$(CONFIG_ISO9660_FS) += isofs.o
-isofs-objs-y := namei.o inode.o dir.o util.o rock.o
+isofs-objs-y := namei.o inode.o dir.o util.o rock.o export.o
isofs-objs-$(CONFIG_JOLIET) += joliet.o
isofs-objs-$(CONFIG_ZISOFS) += compress.o
isofs-objs := $(isofs-objs-y)
break;
/* Convert remaining ';' to '.' */
- if (c == ';')
+ /* Also '/' to '.' (broken Acorn-generated ISO9660 images) */
+ if (c == ';' || c == '/')
c = '.';
new[i] = c;
{
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
- unsigned int block, offset;
- int inode_number = 0; /* Quiet GCC */
+ unsigned long block, offset, block_saved, offset_saved;
+ unsigned long inode_number = 0; /* Quiet GCC */
struct buffer_head *bh = NULL;
int len;
int map;
}
de = (struct iso_directory_record *) (bh->b_data + offset);
- if (first_de)
- inode_number = (bh->b_blocknr << bufbits) + offset;
de_len = *(unsigned char *) de;
continue;
}
+ block_saved = block;
+ offset_saved = offset;
offset += de_len;
/* Make sure we have a full directory entry */
de = tmpde;
}
+ if (first_de) {
+ isofs_normalize_block_and_offset(de,
+ &block_saved,
+ &offset_saved);
+ inode_number = isofs_get_ino(block_saved,
+ offset_saved,
+ bufbits);
+ }
+
if (de->flags[-sbi->s_high_sierra] & 0x80) {
first_de = 0;
filp->f_pos += de_len;
* 1995 Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
* 1997 Gordon Chaffee - Joliet CDs
* 1998 Eric Lammerts - ISO 9660 Level 3
+ * 2004 Paul Serice - Inode Support pushed out from 4GB to 128GB
+ * 2004 Paul Serice - NFS Export Operations
*/
#include <linux/config.h>
.remount_fs = isofs_remount,
};
-/* the export_operations structure for describing
- * how to export (e.g. via kNFSd) is deliberately
- * empty.
- * This means that the filesystem want to use iget
- * to map an inode number into an inode.
- * The lack of a get_parent operation means that
- * if something isn't in the cache, then you cannot
- * access it.
- * It should be possible to write a get_parent,
- * but it would be a bit hairy...
- */
-static struct export_operations isofs_export_ops = {
-};
-
static struct dentry_operations isofs_dentry_ops[] = {
{
/* Set this for reference. Its not currently used except on write
which we don't have .. */
- /* RDE: data zone now byte offset! */
-
- first_data_zone = ((isonum_733 (rootp->extent) +
- isonum_711 (rootp->ext_attr_length))
- << sbi->s_log_zone_size);
+ first_data_zone = isonum_733 (rootp->extent) +
+ isonum_711 (rootp->ext_attr_length);
sbi->s_firstdatazone = first_data_zone;
#ifndef BEQUIET
printk(KERN_DEBUG "Max size:%ld Log zone size:%ld\n",
sbi->s_max_size,
1UL << sbi->s_log_zone_size);
- printk(KERN_DEBUG "First datazone:%ld Root inode number:%ld\n",
- sbi->s_firstdatazone >> sbi->s_log_zone_size,
- sbi->s_firstdatazone);
+ printk(KERN_DEBUG "First datazone:%ld\n", sbi->s_firstdatazone);
if(sbi->s_high_sierra)
printk(KERN_DEBUG "Disc in High Sierra format.\n");
#endif
pri = (struct iso_primary_descriptor *) sec;
rootp = (struct iso_directory_record *)
pri->root_directory_record;
- first_data_zone = ((isonum_733 (rootp->extent) +
- isonum_711 (rootp->ext_attr_length))
- << sbi->s_log_zone_size);
+ first_data_zone = isonum_733 (rootp->extent) +
+ isonum_711 (rootp->ext_attr_length);
}
/*
* the s_rock flag. Once we have the final s_rock value,
* we then decide whether to use the Joliet descriptor.
*/
- inode = iget(s, sbi->s_firstdatazone);
+ inode = isofs_iget(s, sbi->s_firstdatazone, 0);
/*
* If this disk has both Rock Ridge and Joliet on it, then we
printk(KERN_DEBUG
"ISOFS: changing to secondary root\n");
iput(inode);
- inode = iget(s, sbi->s_firstdatazone);
+ inode = isofs_iget(s, sbi->s_firstdatazone, 0);
}
}
unsigned long b_off;
unsigned offset, sect_size;
unsigned int firstext;
- unsigned long nextino;
+ unsigned long nextblk, nextoff;
long iblock = (long)iblock_s;
int section, rv;
struct iso_inode_info *ei = ISOFS_I(inode);
offset = 0;
firstext = ei->i_first_extent;
sect_size = ei->i_section_size >> ISOFS_BUFFER_BITS(inode);
- nextino = ei->i_next_section_ino;
+ nextblk = ei->i_next_section_block;
+ nextoff = ei->i_next_section_offset;
section = 0;
while ( nblocks ) {
goto abort;
}
- if (nextino) {
+ if (nextblk) {
while (b_off >= (offset + sect_size)) {
struct inode *ninode;
offset += sect_size;
- if (nextino == 0)
+ if (nextblk == 0)
goto abort;
- ninode = iget(inode->i_sb, nextino);
+ ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
if (!ninode)
goto abort;
firstext = ISOFS_I(ninode)->i_first_extent;
- sect_size = ISOFS_I(ninode)->i_section_size;
- nextino = ISOFS_I(ninode)->i_next_section_ino;
+ sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
+ nextblk = ISOFS_I(ninode)->i_next_section_block;
+ nextoff = ISOFS_I(ninode)->i_next_section_offset;
iput(ninode);
if (++section > 100) {
printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
- printk("isofs_get_blocks: ino=%lu block=%ld firstext=%u sect_size=%u nextino=%lu\n",
- inode->i_ino, iblock, firstext, (unsigned) sect_size, nextino);
+ printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
+ "nextblk=%lu nextoff=%lu\n",
+ iblock, firstext, (unsigned) sect_size,
+ nextblk, nextoff);
goto abort;
}
}
return isofs_get_blocks(inode, iblock, &bh_result, 1) ? 0 : -EIO;
}
-static int isofs_bmap(struct inode *inode, int block)
+static int isofs_bmap(struct inode *inode, sector_t block)
{
struct buffer_head dummy;
int error;
static int isofs_read_level3_size(struct inode * inode)
{
- unsigned long f_pos = inode->i_ino;
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra;
struct buffer_head * bh = NULL;
- unsigned long block, offset;
+ unsigned long block, offset, block_saved, offset_saved;
int i = 0;
int more_entries = 0;
struct iso_directory_record * tmpde = NULL;
struct iso_inode_info *ei = ISOFS_I(inode);
inode->i_size = 0;
- ei->i_next_section_ino = 0;
- block = f_pos >> ISOFS_BUFFER_BITS(inode);
- offset = f_pos & (bufsize-1);
+ /* The first 16 blocks are reserved as the System Area. Thus,
+ * no inodes can appear in block 0. We use this to flag that
+ * this is the last section. */
+ ei->i_next_section_block = 0;
+ ei->i_next_section_offset = 0;
+
+ block = ei->i_iget5_block;
+ offset = ei->i_iget5_offset;
do {
struct iso_directory_record * de;
if (de_len == 0) {
brelse(bh);
bh = NULL;
- f_pos = (f_pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
- block = f_pos >> ISOFS_BUFFER_BITS(inode);
+ ++block;
offset = 0;
continue;
}
+ block_saved = block;
+ offset_saved = offset;
offset += de_len;
/* Make sure we have a full directory entry */
}
inode->i_size += isonum_733(de->size);
- if (i == 1)
- ei->i_next_section_ino = f_pos;
+ if (i == 1) {
+ ei->i_next_section_block = block_saved;
+ ei->i_next_section_offset = offset_saved;
+ }
more_entries = de->flags[-high_sierra] & 0x80;
- f_pos += de_len;
i++;
if(i > 100)
goto out_toomany;
out_toomany:
printk(KERN_INFO "isofs_read_level3_size: "
"More than 100 file sections ?!?, aborting...\n"
- "isofs_read_level3_size: inode=%lu ino=%lu\n",
- inode->i_ino, f_pos);
+ "isofs_read_level3_size: inode=%lu\n",
+ inode->i_ino);
goto out;
}
struct super_block *sb = inode->i_sb;
struct isofs_sb_info *sbi = ISOFS_SB(sb);
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
- int block = inode->i_ino >> ISOFS_BUFFER_BITS(inode);
+ unsigned long block;
int high_sierra = sbi->s_high_sierra;
struct buffer_head * bh = NULL;
struct iso_directory_record * de;
struct iso_directory_record * tmpde = NULL;
unsigned int de_len;
unsigned long offset;
- int i;
struct iso_inode_info *ei = ISOFS_I(inode);
+ block = ei->i_iget5_block;
bh = sb_bread(inode->i_sb, block);
if (!bh)
goto out_badread;
- offset = (inode->i_ino & (bufsize - 1));
+ offset = ei->i_iget5_offset;
+
de = (struct iso_directory_record *) (bh->b_data + offset);
de_len = *(unsigned char *) de;
de = tmpde;
}
+ inode->i_ino = isofs_get_ino(ei->i_iget5_block,
+ ei->i_iget5_offset,
+ ISOFS_BUFFER_BITS(inode));
+
/* Assume it is a normal-format file unless told otherwise */
ei->i_file_format = isofs_file_normal;
inode->i_mode = sbi->s_mode;
inode->i_nlink = 1;
inode->i_mode |= S_IFREG;
- /* If there are no periods in the name,
- * then set the execute permission bit
- */
- for(i=0; i< de->name_len[0]; i++)
- if(de->name[i]=='.' || de->name[i]==';')
- break;
- if(i == de->name_len[0] || de->name[i] == ';')
- inode->i_mode |= S_IXUGO; /* execute permission */
}
inode->i_uid = sbi->s_uid;
inode->i_gid = sbi->s_gid;
if(de->flags[-high_sierra] & 0x80) {
if(isofs_read_level3_size(inode)) goto fail;
} else {
- ei->i_next_section_ino = 0;
+ ei->i_next_section_block = 0;
+ ei->i_next_section_offset = 0;
inode->i_size = isonum_733 (de->size);
}
goto out;
}
+struct isofs_iget5_callback_data {
+ unsigned long block;
+ unsigned long offset;
+};
+
+static int isofs_iget5_test(struct inode *ino, void *data)
+{
+ struct iso_inode_info *i = ISOFS_I(ino);
+ struct isofs_iget5_callback_data *d =
+ (struct isofs_iget5_callback_data*)data;
+ return (i->i_iget5_block == d->block)
+ && (i->i_iget5_offset == d->offset);
+}
+
+static int isofs_iget5_set(struct inode *ino, void *data)
+{
+ struct iso_inode_info *i = ISOFS_I(ino);
+ struct isofs_iget5_callback_data *d =
+ (struct isofs_iget5_callback_data*)data;
+ i->i_iget5_block = d->block;
+ i->i_iget5_offset = d->offset;
+ return 0;
+}
+
+/* Store, in the inode's containing structure, the block and block
+ * offset that point to the underlying meta-data for the inode. The
+ * code below is otherwise similar to the iget() code in
+ * include/linux/fs.h */
+struct inode *isofs_iget(struct super_block *sb,
+ unsigned long block,
+ unsigned long offset)
+{
+ unsigned long hashval;
+ struct inode *inode;
+ struct isofs_iget5_callback_data data;
+
+ data.block = block;
+ data.offset = offset;
+
+ hashval = (block << sb->s_blocksize_bits) | offset;
+
+ inode = iget5_locked(sb,
+ hashval,
+ &isofs_iget5_test,
+ &isofs_iget5_set,
+ &data);
+
+ if (inode && (inode->i_state & I_NEW)) {
+ sb->s_op->read_inode(inode);
+ unlock_new_inode(inode);
+ }
+
+ return inode;
+}
+
#ifdef LEAK_CHECK
#undef malloc
#undef free_s
#include <linux/config.h> /* Joliet? */
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include <linux/dcache.h>
#include <asm/uaccess.h>
*/
static unsigned long
isofs_find_entry(struct inode *dir, struct dentry *dentry,
+ unsigned long *block_rv, unsigned long* offset_rv,
char * tmpname, struct iso_directory_record * tmpde)
{
- unsigned long inode_number;
unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
- unsigned int block, f_pos, offset;
+ unsigned long block, f_pos, offset, block_saved, offset_saved;
struct buffer_head * bh = NULL;
struct isofs_sb_info *sbi = ISOFS_SB(dir->i_sb);
}
de = (struct iso_directory_record *) (bh->b_data + offset);
- inode_number = (bh->b_blocknr << bufbits) + offset;
de_len = *(unsigned char *) de;
if (!de_len) {
continue;
}
+ block_saved = bh->b_blocknr;
+ offset_saved = offset;
offset += de_len;
f_pos += de_len;
match = (isofs_cmp(dentry,dpnt,dlen) == 0);
}
if (match) {
+ isofs_normalize_block_and_offset(de,
+ &block_saved,
+ &offset_saved);
+ *block_rv = block_saved;
+ *offset_rv = offset_saved;
if (bh) brelse(bh);
- return inode_number;
+ return 1;
}
}
if (bh) brelse(bh);
struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
{
- unsigned long ino;
+ int found;
+ unsigned long block, offset;
struct inode *inode;
struct page *page;
return ERR_PTR(-ENOMEM);
lock_kernel();
- ino = isofs_find_entry(dir, dentry, page_address(page),
- 1024 + page_address(page));
+ found = isofs_find_entry(dir, dentry,
+ &block, &offset,
+ page_address(page),
+ 1024 + page_address(page));
__free_page(page);
inode = NULL;
- if (ino) {
- inode = iget(dir->i_sb, ino);
+ if (found) {
+ inode = isofs_iget(dir->i_sb, block, offset);
if (!inode) {
unlock_kernel();
return ERR_PTR(-EACCES);
}
}
unlock_kernel();
+ if (inode)
+ return d_splice_alias(inode, dentry);
d_add(dentry, inode);
return NULL;
}
goto out;
case SIG('C','L'):
ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location);
- reloc = iget(inode->i_sb,
- (ISOFS_I(inode)->i_first_extent <<
- ISOFS_SB(inode->i_sb)->s_log_zone_size));
+ reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0);
if (!reloc)
goto out;
inode->i_mode = reloc->i_mode;
static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
{
struct inode *inode = page->mapping->host;
+ struct iso_inode_info *ei = ISOFS_I(inode);
char *link = kmap(page);
unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
- unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
struct buffer_head *bh;
char *rpnt = link;
unsigned char *pnt;
struct iso_directory_record *raw_inode;
CONTINUE_DECLS;
- int block;
+ unsigned long block, offset;
int sig;
int len;
unsigned char *chr;
if (!ISOFS_SB(inode->i_sb)->s_rock)
panic ("Cannot have symlink with high sierra variant of iso filesystem\n");
- block = inode->i_ino >> bufbits;
+ block = ei->i_iget5_block;
lock_kernel();
bh = sb_bread(inode->i_sb, block);
if (!bh)
goto out_noread;
- pnt = (unsigned char *) bh->b_data + (inode->i_ino & (bufsize - 1));
+ offset = ei->i_iget5_offset;
+ pnt = (unsigned char *) bh->b_data + offset;
raw_inode = (struct iso_directory_record *) pnt;
/*
* If we go past the end of the buffer, there is some sort of error.
*/
- if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize)
+ if (offset + *pnt > bufsize)
goto out_bad_span;
/* Now test for possible Rock Ridge extensions which will override
tagp = &bh->b_data[sizeof(journal_header_t)];
space_left = bh->b_size - sizeof(journal_header_t);
first_tag = 1;
- set_bit(BH_JWrite, &bh->b_state);
+ set_buffer_jwrite(bh);
+ set_buffer_dirty(bh);
wbuf[bufs++] = bh;
/* Record it so that we can wait for IO
JBUFFER_TRACE(descriptor, "write commit block");
{
struct buffer_head *bh = jh2bh(descriptor);
- set_buffer_uptodate(bh);
+
+ set_buffer_dirty(bh);
sync_dirty_buffer(bh);
if (unlikely(!buffer_uptodate(bh)))
err = -EIO;
* We play buffer_head aliasing tricks to write data/metadata blocks to
* the journal without copying their contents, but for journal
* descriptor blocks we do need to generate bona fide buffers.
+ *
+ * After the caller of journal_get_descriptor_buffer() has finished modifying
+ * the buffer's contents they really should run flush_dcache_page(bh->b_page).
+ * But we don't bother doing that, so there will be coherency problems with
+ * mmaps of blockdevs which hold live JBD-controlled filesystems.
*/
-
-struct journal_head * journal_get_descriptor_buffer(journal_t *journal)
+struct journal_head *journal_get_descriptor_buffer(journal_t *journal)
{
struct buffer_head *bh;
unsigned long blocknr;
return NULL;
bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+ lock_buffer(bh);
memset(bh->b_data, 0, journal->j_blocksize);
- bh->b_state |= (1 << BH_Dirty);
+ set_buffer_uptodate(bh);
+ unlock_buffer(bh);
BUFFER_TRACE(bh, "return this buffer");
return journal_add_journal_head(bh);
}
kmem_cache_free(revoke_record_cache, record);
}
}
- if (descriptor)
+ if (descriptor)
flush_descriptor(journal, descriptor, offset);
jbd_debug(1, "Wrote %d revoke records\n", count);
}
header->r_count = htonl(offset);
set_buffer_jwrite(bh);
BUFFER_TRACE(bh, "write");
- set_buffer_uptodate(bh);
+ set_buffer_dirty(bh);
ll_rw_block(WRITE, 1, &bh);
}
#endif
struct jffs_fmcontrol *fmc = c->fmc;
printk("Flash status -- ");
if (!access_ok(VERIFY_WRITE,
- (struct jffs_flash_status *)arg,
+ (struct jffs_flash_status __user *)arg,
sizeof(struct jffs_flash_status))) {
D(printk("jffs_ioctl(): Bad arg in "
"JFFS_GET_STATUS ioctl!\n"));
"begin: %d, end: %d\n",
fst.size, fst.used, fst.dirty,
fst.begin, fst.end);
- if (copy_to_user((struct jffs_flash_status *)arg,
+ if (copy_to_user((struct jffs_flash_status __user *)arg,
&fst,
sizeof(struct jffs_flash_status))) {
ret = -EFAULT;
/*
- * Copyright (c) International Business Machines Corp., 2000-2001
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* record the path traversed during the search;
* top frame record the leaf page/entry selected.
*/
-#define MAXTREEHEIGHT 8
struct btframe { /* stack frame */
s64 bn; /* 8: */
s16 index; /* 2: */
- s16 lastindex; /* 2: */
- struct metapage *mp; /* 4: */
-}; /* (16) */
+ s16 lastindex; /* 2: unused */
+ struct metapage *mp; /* 4/8: */
+}; /* (16/24) */
struct btstack {
struct btframe *top;
#define BT_CLR(btstack)\
(btstack)->top = (btstack)->stack
+#define BT_STACK_FULL(btstack)\
+ ( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1]))
+
#define BT_PUSH(BTSTACK, BN, INDEX)\
{\
+ assert(!BT_STACK_FULL(BTSTACK));\
(BTSTACK)->top->bn = BN;\
(BTSTACK)->top->index = INDEX;\
++(BTSTACK)->top;\
- assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
}
#define BT_POP(btstack)\
#define BT_STACK(btstack)\
( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
+static inline void BT_STACK_DUMP(struct btstack *btstack)
+{
+ int i;
+ printk("btstack dump:\n");
+ for (i = 0; i < MAXTREEHEIGHT; i++)
+ printk(KERN_ERR "bn = %Lx, index = %d\n",
+ btstack->stack[i].bn,
+ btstack->stack[i].index);
+}
+
/* retrieve search results */
#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
{\
/*
- * Copyright (C) International Business Machines Corp., 2000-2003
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
IREAD_LOCK(ipbmap);
/* block to be freed better be within the mapsize. */
- if (blkno + nblocks > bmp->db_mapsize) {
+ if (unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) {
IREAD_UNLOCK(ipbmap);
printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n",
(unsigned long long) blkno,
/*
- * Copyright (C) International Business Machines Corp., 2000-2003
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* It's time to move the inline table to an external
* page and begin to build the xtree
*/
+ if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
+ goto clean_up; /* No space */
/*
* Save the table, we're going to overwrite it with the
/*
* Allocate the first block & add it to the xtree
*/
- xaddr = 0;
if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
+ /* This really shouldn't fail */
jfs_warn("add_index: xtInsert failed!");
memcpy(&jfs_ip->i_dirtable, temp_table,
sizeof (temp_table));
*/
getChild:
/* update max. number of pages to split */
- if (btstack->nsplit >= 8) {
+ if (BT_STACK_FULL(btstack)) {
/* Something's corrupted, mark filesytem dirty so
* chkdsk will fix it.
*/
jfs_error(sb, "stack overrun in dtSearch!");
+ BT_STACK_DUMP(btstack);
rc = -EIO;
goto out;
}
n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */
if (n <= split->nslot)
xlen++;
- if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)))
+ if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) {
+ DT_PUTPAGE(smp);
goto freeKeyName;
+ }
pxdlist.maxnpxd = 1;
pxdlist.npxd = 0;
/*
* descend down to leftmost child page
*/
+ if (BT_STACK_FULL(btstack)) {
+ DT_PUTPAGE(mp);
+ jfs_error(ip->i_sb, "dtReadFirst: btstack overrun");
+ BT_STACK_DUMP(btstack);
+ return -EIO;
+ }
/* push (bn, index) of the parent page/entry */
BT_PUSH(btstack, bn, 0);
spin_unlock(&meta_lock);
if (test_bit(META_stale, &mp->flag)) {
release_metapage(mp);
+ yield(); /* Let other waiters release it, too */
goto again;
}
if (test_bit(META_discard, &mp->flag)) {
if (lwm == next)
goto out;
- assert(lwm < next);
+ if (lwm > next) {
+ jfs_err("xtLog: lwm > next\n");
+ goto out;
+ }
tlck->flag |= tlckUPDATEMAP;
xadlock->flag = mlckALLOCXADLIST;
xadlock->count = next - lwm;
/*
* write log records
*/
- /*
- * allocate entries XAD[lwm:next]:
+ /* log after-image for logredo():
+ *
+ * logredo() will update bmap for alloc of new/extended
+ * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
+ * after-image of XADlist;
+ * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
+ * applying the after-image to the meta-data page.
*/
- if (lwm < next) {
- /* log after-image for logredo():
- * logredo() will update bmap for alloc of new/extended
- * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
- * after-image of XADlist;
- * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
- * applying the after-image to the meta-data page.
- */
- lrd->type = cpu_to_le16(LOG_REDOPAGE);
- PXDaddress(pxd, mp->index);
- PXDlength(pxd,
- mp->logical_size >> tblk->sb->
- s_blocksize_bits);
- lrd->backchain =
- cpu_to_le32(lmLog(log, tblk, lrd, tlck));
- }
+ lrd->type = cpu_to_le16(LOG_REDOPAGE);
+ PXDaddress(pxd, mp->index);
+ PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits);
+ lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
/*
* truncate entry XAD[twm == next - 1]:
lid_t lid, next;
struct metapage *mp;
struct tblock *tblk = tid_to_tblock(tid);
+ struct tlock *tlck;
jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty);
* free tlocks of the transaction
*/
for (lid = tblk->next; lid; lid = next) {
- next = lid_to_tlock(lid)->next;
-
- mp = lid_to_tlock(lid)->mp;
+ tlck = lid_to_tlock(lid);
+ next = tlck->next;
+ mp = tlck->mp;
+ JFS_IP(tlck->ip)->xtlid = 0;
if (mp) {
mp->lid = 0;
#define addressPXD(pxd)\
( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
+#define MAXTREEHEIGHT 8
/* pxd list */
struct pxdlist {
s16 maxnpxd;
s16 npxd;
- pxd_t pxd[8];
+ pxd_t pxd[MAXTREEHEIGHT];
};
unchar *i_fastsymlink;
s64 xlen = 0;
int bmask = 0, xsize;
- s64 xaddr;
+ s64 extent = 0, xaddr;
struct metapage *mp;
struct super_block *sb;
struct tblock *tblk;
down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem);
- if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
- goto out3;
-
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->ino = ip->i_ino;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
- /*
- * create entry for symbolic link in parent directory
- */
-
- ino = ip->i_ino;
-
-
-
- if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
- jfs_err("jfs_symlink: dtInsert returned %d", rc);
- /* discard ne inode */
- goto out3;
-
- }
-
/* fix symlink access permission
* (dir_create() ANDs in the u.u_cmask,
* but symlinks really need to be 777 access)
ip->i_mode |= 0777;
/*
- * write symbolic link target path name
+ * write symbolic link target path name
*/
xtInitRoot(tid, ip);
xsize = (ssize + bmask) & ~bmask;
xaddr = 0;
xlen = xsize >> JFS_SBI(sb)->l2bsize;
- if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) {
- ip->i_size = ssize - 1;
- while (ssize) {
- int copy_size = min(ssize, PSIZE);
-
- mp = get_metapage(ip, xaddr, PSIZE, 1);
-
- if (mp == NULL) {
- dtDelete(tid, dip, &dname, &ino,
- JFS_REMOVE);
- rc = -EIO;
- goto out3;
- }
- memcpy(mp->data, name, copy_size);
- flush_metapage(mp);
-#if 0
- set_buffer_uptodate(bp);
- mark_buffer_dirty(bp, 1);
- if (IS_SYNC(dip))
- sync_dirty_buffer(bp);
- brelse(bp);
-#endif /* 0 */
- ssize -= copy_size;
- xaddr += JFS_SBI(sb)->nbperpage;
- }
- ip->i_blocks = LBLK2PBLK(sb, xlen);
- } else {
- dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
+ if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
+ txAbort(tid, 0);
rc = -ENOSPC;
goto out3;
}
+ extent = xaddr;
+ ip->i_size = ssize - 1;
+ while (ssize) {
+ /* This is kind of silly since PATH_MAX == 4K */
+ int copy_size = min(ssize, PSIZE);
+
+ mp = get_metapage(ip, xaddr, PSIZE, 1);
+
+ if (mp == NULL) {
+ dbFree(ip, extent, xlen);
+ rc = -EIO;
+ txAbort(tid, 0);
+ goto out3;
+ }
+ memcpy(mp->data, name, copy_size);
+ flush_metapage(mp);
+ ssize -= copy_size;
+ name += copy_size;
+ xaddr += JFS_SBI(sb)->nbperpage;
+ }
+ ip->i_blocks = LBLK2PBLK(sb, xlen);
+ }
+
+ /*
+ * create entry for symbolic link in parent directory
+ */
+ rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
+ if (rc == 0) {
+ ino = ip->i_ino;
+ rc = dtInsert(tid, dip, &dname, &ino, &btstack);
+ }
+ if (rc) {
+ if (xlen)
+ dbFree(ip, extent, xlen);
+ txAbort(tid, 0);
+ /* discard new inode */
+ goto out3;
}
insert_inode_hash(ip);
/*
* commit update of parent directory and link object
- *
- * if extent allocation failed (ENOSPC),
- * the parent inode is committed regardless to avoid
- * backing out parent directory update (by dtInsert())
- * and subsequent dtDelete() which is harmless wrt
- * integrity concern.
- * the symlink inode will be freed by iput() at exit
- * as it has a zero link count (by dtDelete()) and
- * no permanant resources.
*/
iplist[0] = dip;
- if (rc == 0) {
- iplist[1] = ip;
- rc = txCommit(tid, 2, &iplist[0], 0);
- } else
- rc = txCommit(tid, 1, &iplist[0], 0);
+ iplist[1] = ip;
+ rc = txCommit(tid, 2, &iplist[0], 0);
out3:
txEnd(tid);
/* Linelock header of dtree */
tlck = txLock(tid, old_ip,
(struct metapage *) &JFS_IP(old_ip)->bxflag,
- tlckDTREE | tlckBTROOT);
+ tlckDTREE | tlckBTROOT | tlckRELINK);
dtlck = (struct dt_lock *) & tlck->lock;
ASSERT(dtlck->index == 0);
lv = & dtlck->lv[0];
}
inode->i_mode = mode;
mark_inode_dirty(inode);
- if (rc == 0)
- value = NULL;
}
/*
* We're changing the ACL. Get rid of the cached one
*/
acl =JFS_IP(inode)->i_acl;
- if (acl && (acl != JFS_ACL_NOT_CACHED))
+ if (acl != JFS_ACL_NOT_CACHED)
posix_acl_release(acl);
JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
+
+ return 0;
} else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) {
+ acl = posix_acl_from_xattr(value, value_len);
+ if (IS_ERR(acl)) {
+ rc = PTR_ERR(acl);
+ printk(KERN_ERR "posix_acl_from_xattr returned %d\n",
+ rc);
+ return rc;
+ }
+ posix_acl_release(acl);
+
/*
* We're changing the default ACL. Get rid of the cached one
*/
if (acl && (acl != JFS_ACL_NOT_CACHED))
posix_acl_release(acl);
JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED;
- } else
- /* Invalid xattr name */
- return -EINVAL;
- return 0;
-#else /* CONFIG_JFS_POSIX_ACL */
- return -EOPNOTSUPP;
+
+ return 0;
+ }
#endif /* CONFIG_JFS_POSIX_ACL */
+ return -EOPNOTSUPP;
}
static int can_set_xattr(struct inode *inode, const char *name,
int ncp_conn_logged_in(struct super_block *sb)
{
struct ncp_server* server = NCP_SBP(sb);
- struct nw_info_struct i;
int result;
if (ncp_single_volume(server)) {
int len;
struct dentry* dent;
+ __u32 volNumber, dirEntNum, DosDirNum;
__u8 __name[NCP_MAXPATHLEN + 1];
len = sizeof(__name);
if (result)
goto out;
result = -ENOENT;
- if (ncp_lookup_volume(server, __name, &i)) {
+ if (ncp_get_volume_root(server, __name, &volNumber, &dirEntNum, &DosDirNum)) {
PPRINTK("ncp_conn_logged_in: %s not found\n",
server->m.mounted_vol);
goto out;
if (dent) {
struct inode* ino = dent->d_inode;
if (ino) {
- NCP_FINFO(ino)->volNumber = i.volNumber;
- NCP_FINFO(ino)->dirEntNum = i.dirEntNum;
- NCP_FINFO(ino)->DosDirNum = i.DosDirNum;
+ NCP_FINFO(ino)->volNumber = volNumber;
+ NCP_FINFO(ino)->dirEntNum = dirEntNum;
+ NCP_FINFO(ino)->DosDirNum = DosDirNum;
} else {
DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n");
}
}
static ssize_t
-ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode;
}
static ssize_t
-ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
struct dentry *dentry = file->f_dentry;
struct inode *inode = dentry->d_inode;
/* maximum negotiable packet size */
#define NCP_PACKET_SIZE_INTERNAL 65536
+static int
+ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info* arg)
+{
+ struct ncp_fs_info info;
+
+ if ((permission(inode, MAY_WRITE, NULL) != 0)
+ && (current->uid != server->m.mounted_uid)) {
+ return -EACCES;
+ }
+ if (copy_from_user(&info, arg, sizeof(info)))
+ return -EFAULT;
+
+ if (info.version != NCP_GET_FS_INFO_VERSION) {
+ DPRINTK("info.version invalid: %d\n", info.version);
+ return -EINVAL;
+ }
+ /* TODO: info.addr = server->m.serv_addr; */
+ SET_UID(info.mounted_uid, server->m.mounted_uid);
+ info.connection = server->connection;
+ info.buffer_size = server->buffer_size;
+ info.volume_number = NCP_FINFO(inode)->volNumber;
+ info.directory_id = NCP_FINFO(inode)->DosDirNum;
+
+ if (copy_to_user(arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+}
+
+static int
+ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2* arg)
+{
+ struct ncp_fs_info_v2 info2;
+
+ if ((permission(inode, MAY_WRITE, NULL) != 0)
+ && (current->uid != server->m.mounted_uid)) {
+ return -EACCES;
+ }
+ if (copy_from_user(&info2, arg, sizeof(info2)))
+ return -EFAULT;
+
+ if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
+ DPRINTK("info.version invalid: %d\n", info2.version);
+ return -EINVAL;
+ }
+ info2.mounted_uid = server->m.mounted_uid;
+ info2.connection = server->connection;
+ info2.buffer_size = server->buffer_size;
+ info2.volume_number = NCP_FINFO(inode)->volNumber;
+ info2.directory_id = NCP_FINFO(inode)->DosDirNum;
+ info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
+
+ if (copy_to_user(arg, &info2, sizeof(info2)))
+ return -EFAULT;
+ return 0;
+}
+
+#ifdef CONFIG_NCPFS_NLS
+/* Here we are select the iocharset and the codepage for NLS.
+ * Thanks Petr Vandrovec for idea and many hints.
+ */
+static int
+ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
+{
+ struct ncp_nls_ioctl user;
+ struct nls_table *codepage;
+ struct nls_table *iocharset;
+ struct nls_table *oldset_io;
+ struct nls_table *oldset_cp;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (server->root_setuped)
+ return -EBUSY;
+
+ if (copy_from_user(&user, arg, sizeof(user)))
+ return -EFAULT;
+
+ codepage = NULL;
+ user.codepage[NCP_IOCSNAME_LEN] = 0;
+ if (!user.codepage[0] || !strcmp(user.codepage, "default"))
+ codepage = load_nls_default();
+ else {
+ codepage = load_nls(user.codepage);
+ if (!codepage) {
+ return -EBADRQC;
+ }
+ }
+
+ iocharset = NULL;
+ user.iocharset[NCP_IOCSNAME_LEN] = 0;
+ if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) {
+ iocharset = load_nls_default();
+ NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+ } else if (!strcmp(user.iocharset, "utf8")) {
+ iocharset = load_nls_default();
+ NCP_SET_FLAG(server, NCP_FLAG_UTF8);
+ } else {
+ iocharset = load_nls(user.iocharset);
+ if (!iocharset) {
+ unload_nls(codepage);
+ return -EBADRQC;
+ }
+ NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
+ }
+
+ oldset_cp = server->nls_vol;
+ server->nls_vol = codepage;
+ oldset_io = server->nls_io;
+ server->nls_io = iocharset;
+
+ if (oldset_cp)
+ unload_nls(oldset_cp);
+ if (oldset_io)
+ unload_nls(oldset_io);
+
+ return 0;
+}
+
+static int
+ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
+{
+ struct ncp_nls_ioctl user;
+ int len;
+
+ memset(&user, 0, sizeof(user));
+ if (server->nls_vol && server->nls_vol->charset) {
+ len = strlen(server->nls_vol->charset);
+ if (len > NCP_IOCSNAME_LEN)
+ len = NCP_IOCSNAME_LEN;
+ strncpy(user.codepage, server->nls_vol->charset, len);
+ user.codepage[len] = 0;
+ }
+
+ if (NCP_IS_FLAG(server, NCP_FLAG_UTF8))
+ strcpy(user.iocharset, "utf8");
+ else if (server->nls_io && server->nls_io->charset) {
+ len = strlen(server->nls_io->charset);
+ if (len > NCP_IOCSNAME_LEN)
+ len = NCP_IOCSNAME_LEN;
+ strncpy(user.iocharset, server->nls_io->charset, len);
+ user.iocharset[len] = 0;
+ }
+
+ if (copy_to_user(arg, &user, sizeof(user)))
+ return -EFAULT;
+ return 0;
+}
+#endif /* CONFIG_NCPFS_NLS */
+
int ncp_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
return ncp_conn_logged_in(inode->i_sb);
case NCP_IOC_GET_FS_INFO:
- {
- struct ncp_fs_info info;
-
- if ((permission(inode, MAY_WRITE, NULL) != 0)
- && (current->uid != server->m.mounted_uid)) {
- return -EACCES;
- }
- if (copy_from_user(&info, (struct ncp_fs_info *) arg,
- sizeof(info)))
- return -EFAULT;
-
- if (info.version != NCP_GET_FS_INFO_VERSION) {
- DPRINTK("info.version invalid: %d\n", info.version);
- return -EINVAL;
- }
- /* TODO: info.addr = server->m.serv_addr; */
- SET_UID(info.mounted_uid, server->m.mounted_uid);
- info.connection = server->connection;
- info.buffer_size = server->buffer_size;
- info.volume_number = NCP_FINFO(inode)->volNumber;
- info.directory_id = NCP_FINFO(inode)->DosDirNum;
-
- if (copy_to_user((struct ncp_fs_info *) arg, &info,
- sizeof(info))) return -EFAULT;
- return 0;
- }
+ return ncp_get_fs_info(server, inode, (struct ncp_fs_info *)arg);
case NCP_IOC_GET_FS_INFO_V2:
- {
- struct ncp_fs_info_v2 info2;
-
- if ((permission(inode, MAY_WRITE, NULL) != 0)
- && (current->uid != server->m.mounted_uid)) {
- return -EACCES;
- }
- if (copy_from_user(&info2, (struct ncp_fs_info_v2 *) arg,
- sizeof(info2)))
- return -EFAULT;
-
- if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
- DPRINTK("info.version invalid: %d\n", info2.version);
- return -EINVAL;
- }
- info2.mounted_uid = server->m.mounted_uid;
- info2.connection = server->connection;
- info2.buffer_size = server->buffer_size;
- info2.volume_number = NCP_FINFO(inode)->volNumber;
- info2.directory_id = NCP_FINFO(inode)->DosDirNum;
- info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;
-
- if (copy_to_user((struct ncp_fs_info_v2 *) arg, &info2,
- sizeof(info2))) return -EFAULT;
- return 0;
- }
+ return ncp_get_fs_info_v2(server, inode, (struct ncp_fs_info_v2 *)arg);
case NCP_IOC_GETMOUNTUID2:
{
case NCP_IOC_SETROOT:
{
struct ncp_setroot_ioctl sr;
- unsigned int vnum, de, dosde;
+ __u32 vnum, de, dosde;
struct dentry* dentry;
if (!capable(CAP_SYS_ADMIN))
dosde = 0;
} else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
return -EINVAL;
- } else {
- struct nw_info_struct ni;
-
- if (ncp_mount_subdir(server, &ni, sr.volNumber,
- sr.namespace, sr.dirEntNum))
- return -ENOENT;
- vnum = ni.volNumber;
- de = ni.dirEntNum;
- dosde = ni.DosDirNum;
+ } else if (ncp_mount_subdir(server, sr.volNumber,
+ sr.namespace, sr.dirEntNum,
+ &vnum, &de, &dosde)) {
+ return -ENOENT;
}
dentry = inode->i_sb->s_root;
}
#ifdef CONFIG_NCPFS_NLS
-/* Here we are select the iocharset and the codepage for NLS.
- * Thanks Petr Vandrovec for idea and many hints.
- */
case NCP_IOC_SETCHARSETS:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if (server->root_setuped)
- return -EBUSY;
-
- {
- struct ncp_nls_ioctl user;
- struct nls_table *codepage;
- struct nls_table *iocharset;
- struct nls_table *oldset_io;
- struct nls_table *oldset_cp;
-
- if (copy_from_user(&user, (struct ncp_nls_ioctl*)arg,
- sizeof(user)))
- return -EFAULT;
-
- codepage = NULL;
- user.codepage[NCP_IOCSNAME_LEN] = 0;
- if (!user.codepage[0] ||
- !strcmp(user.codepage, "default"))
- codepage = load_nls_default();
- else {
- codepage = load_nls(user.codepage);
- if (!codepage) {
- return -EBADRQC;
- }
- }
-
- iocharset = NULL;
- user.iocharset[NCP_IOCSNAME_LEN] = 0;
- if (!user.iocharset[0] ||
- !strcmp(user.iocharset, "default")) {
- iocharset = load_nls_default();
- NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
- } else {
- if (!strcmp(user.iocharset, "utf8")) {
- iocharset = load_nls_default();
- NCP_SET_FLAG(server, NCP_FLAG_UTF8);
- } else {
- iocharset = load_nls(user.iocharset);
- if (!iocharset) {
- unload_nls(codepage);
- return -EBADRQC;
- }
- NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
- }
- }
-
- oldset_cp = server->nls_vol;
- server->nls_vol = codepage;
- oldset_io = server->nls_io;
- server->nls_io = iocharset;
-
- if (oldset_cp)
- unload_nls(oldset_cp);
- if (oldset_io)
- unload_nls(oldset_io);
-
- return 0;
- }
+ return ncp_set_charsets(server, (struct ncp_nls_ioctl *)arg);
- case NCP_IOC_GETCHARSETS: /* not tested */
- {
- struct ncp_nls_ioctl user;
- int len;
-
- memset(&user, 0, sizeof(user));
- if (server->nls_vol && server->nls_vol->charset) {
- len = strlen(server->nls_vol->charset);
- if (len > NCP_IOCSNAME_LEN)
- len = NCP_IOCSNAME_LEN;
- strncpy(user.codepage,
- server->nls_vol->charset, len);
- user.codepage[len] = 0;
- }
-
- if (NCP_IS_FLAG(server, NCP_FLAG_UTF8))
- strcpy(user.iocharset, "utf8");
- else
- if (server->nls_io && server->nls_io->charset) {
- len = strlen(server->nls_io->charset);
- if (len > NCP_IOCSNAME_LEN)
- len = NCP_IOCSNAME_LEN;
- strncpy(user.iocharset,
- server->nls_io->charset, len);
- user.iocharset[len] = 0;
- }
+ case NCP_IOC_GETCHARSETS:
+ return ncp_get_charsets(server, (struct ncp_nls_ioctl *)arg);
- if (copy_to_user((struct ncp_nls_ioctl*)arg, &user,
- sizeof(user)))
- return -EFAULT;
-
- return 0;
- }
#endif /* CONFIG_NCPFS_NLS */
+
case NCP_IOC_SETDENTRYTTL:
if ((permission(inode, MAY_WRITE, NULL) != 0) &&
(current->uid != server->m.mounted_uid))
}
int
-ncp_mount_subdir(struct ncp_server *server, struct nw_info_struct *i,
- __u8 volNumber, __u8 srcNS, __u32 dirEntNum)
+ncp_mount_subdir(struct ncp_server *server,
+ __u8 volNumber, __u8 srcNS, __u32 dirEntNum,
+ __u32* volume, __u32* newDirEnt, __u32* newDosEnt)
{
int dstNS;
int result;
- __u32 newDirEnt;
- __u32 newDosEnt;
dstNS = ncp_get_known_namespace(server, volNumber);
if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber,
- dirEntNum, NULL, &newDirEnt, &newDosEnt)) != 0)
+ dirEntNum, NULL, newDirEnt, newDosEnt)) != 0)
{
return result;
}
server->name_space[volNumber] = dstNS;
- i->volNumber = volNumber;
- i->dirEntNum = newDirEnt;
- i->DosDirNum = newDosEnt;
+ *volume = volNumber;
server->m.mounted_vol[1] = 0;
server->m.mounted_vol[0] = 'X';
return 0;
}
int
-ncp_lookup_volume(struct ncp_server *server, char *volname,
- struct nw_info_struct *target)
+ncp_get_volume_root(struct ncp_server *server, const char *volname,
+ __u32* volume, __u32* dirent, __u32* dosdirent)
{
int result;
- int volnum;
+ __u8 volnum;
- DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
+ DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname);
ncp_init_request(server);
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
ncp_unlock_server(server);
return result;
}
- memset(target, 0, sizeof(*target));
- target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
- target->volNumber = volnum = ncp_reply_byte(server, 8);
+ *dirent = *dosdirent = ncp_reply_dword(server, 4);
+ volnum = ncp_reply_byte(server, 8);
ncp_unlock_server(server);
+ *volume = volnum;
server->name_space[volnum] = ncp_get_known_namespace(server, volnum);
DPRINTK("lookup_vol: namespace[%d] = %d\n",
volnum, server->name_space[volnum]);
+ return 0;
+}
+
+int
+ncp_lookup_volume(struct ncp_server *server, const char *volname,
+ struct nw_info_struct *target)
+{
+ int result;
+
+ memset(target, 0, sizeof(*target));
+ result = ncp_get_volume_root(server, volname,
+ &target->volNumber, &target->dirEntNum, &target->DosDirNum);
+ if (result) {
+ return result;
+ }
target->nameLen = strlen(volname);
memcpy(target->entryName, volname, target->nameLen+1);
target->attributes = aDIR;
*/
int
ncp_read_bounce(struct ncp_server *server, const char *file_id,
- __u32 offset, __u16 to_read, char *target, int *bytes_read,
+ __u32 offset, __u16 to_read, char __user *target, int *bytes_read,
void* bounce, __u32 bufsize)
{
int result;
return sizeof(struct ncp_reply_header) + 2 + 2 + size + 8;
};
int ncp_read_bounce(struct ncp_server *, const char *, __u32, __u16,
- char *, int *, void* bounce, __u32 bouncelen);
+ char __user *, int *, void* bounce, __u32 bouncelen);
int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16,
char *, int *);
int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16,
int ncp_obtain_info(struct ncp_server *server, struct inode *, char *,
struct nw_info_struct *target);
int ncp_obtain_nfs_info(struct ncp_server *server, struct nw_info_struct *target);
-int ncp_lookup_volume(struct ncp_server *, char *, struct nw_info_struct *);
+int ncp_get_volume_root(struct ncp_server *server, const char *volname,
+ __u32 *volume, __u32 *dirent, __u32 *dosdirent);
+int ncp_lookup_volume(struct ncp_server *, const char *, struct nw_info_struct *);
int ncp_modify_file_or_subdir_dos_info(struct ncp_server *, struct inode *,
__u32, const struct nw_modify_dos_info *info);
int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *, struct inode *,
#endif /* CONFIG_NCPFS_IOCTL_LOCKING */
int
-ncp_mount_subdir(struct ncp_server *, struct nw_info_struct *,
- __u8, __u8, __u32);
+ncp_mount_subdir(struct ncp_server *, __u8, __u8, __u32,
+ __u32* volume, __u32* dirent, __u32* dosdirent);
int ncp_dirhandle_alloc(struct ncp_server *, __u8 vol, __u32 dirent, __u8 *dirhandle);
int ncp_dirhandle_free(struct ncp_server *, __u8 dirhandle);
* cache.
*/
ssize_t
-nfs_file_direct_read(struct kiocb *iocb, char *buf, size_t count, loff_t pos)
+nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
{
ssize_t retval = -EINVAL;
loff_t *ppos = &iocb->ki_pos;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct iovec iov = {
- .iov_base = buf,
+ .iov_base = (char __user *)buf,
.iov_len = count,
};
struct idmap_hashtable idmap_group_hash;
};
-static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, char *,
- size_t);
-static ssize_t idmap_pipe_downcall(struct file *, const char *, size_t);
+static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *,
+ char __user *, size_t);
+static ssize_t idmap_pipe_downcall(struct file *, const char __user *,
+ size_t);
void idmap_pipe_destroy_msg(struct rpc_pipe_msg *);
static unsigned int fnvhash32(const void *, size_t);
/* RPC pipefs upcall/downcall routines */
static ssize_t
idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
- char *dst, size_t buflen)
+ char __user *dst, size_t buflen)
{
char *data = (char *)msg->data + msg->copied;
ssize_t mlen = msg->len - msg->copied;
}
static ssize_t
-idmap_pipe_downcall(struct file *filp, const char *src, size_t mlen)
+idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
{
struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
struct idmap *idmap = (struct idmap *)rpci->private;
if (err >= 0) {
err = 0;
if (wbc->for_reclaim)
- err = WRITEPAGE_ACTIVATE;
+ nfs_flush_inode(inode, 0, 0, FLUSH_STABLE);
}
} else {
err = nfs_writepage_sync(NULL, inode, page, 0,
}
unlock_kernel();
out:
- if (err != WRITEPAGE_ACTIVATE)
- unlock_page(page);
+ unlock_page(page);
if (inode_referenced)
iput(inode);
return err;
resp->buflen = count;
resp->common.err = nfs_ok;
resp->buffer = argp->buffer;
- resp->offset = NULL;
resp->rqstp = rqstp;
nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t*) &argp->cookie,
&resp->common, nfs3svc_encode_entry);
int elen; /* estimated entry length in words */
int num_entry_words = 0; /* actual number of words */
- if (cd->offset)
- xdr_encode_hyper(cd->offset, (u64) offset);
+ if (cd->offset) {
+ u64 offset64 = offset;
+
+ if (unlikely(cd->offset1)) {
+ /* we ended up with offset on a page boundary */
+ *cd->offset = htonl(offset64 >> 32);
+ *cd->offset1 = htonl(offset64 & 0xffffffff);
+ cd->offset1 = NULL;
+ } else {
+ xdr_encode_hyper(cd->offset, (u64) offset);
+ }
+ }
/*
dprintk("encode_entry(%.*s @%ld%s)\n",
/* update offset */
cd->offset = cd->buffer + (cd->offset - tmp);
} else {
+ unsigned int offset_r = (cd->offset - tmp) << 2;
+
+ /* update pointer to offset location.
+ * This is a 64bit quantity, so we need to
+ * deal with 3 cases:
+ * - entirely in first page
+ * - entirely in second page
+ * - 4 bytes in each page
+ */
+ if (offset_r + 8 <= len1) {
+ cd->offset = p + (cd->offset - tmp);
+ } else if (offset_r >= len1) {
+ cd->offset -= len1 >> 2;
+ } else {
+ /* sitting on the fence */
+ BUG_ON(offset_r != len1 - 4);
+ cd->offset = p + (cd->offset - tmp);
+ cd->offset1 = tmp;
+ }
+
len2 = (num_entry_words << 2) - len1;
/* move from temp page to current and next pages */
memmove(p, tmp, len1);
memmove(tmp, (caddr_t)tmp+len1, len2);
- /* update offset */
- if (((cd->offset - tmp) << 2) < len1)
- cd->offset = p + (cd->offset - tmp);
- else
- cd->offset -= len1 >> 2;
p = tmp + (len2 >> 2);
}
}
break;
default:
- BUG();
+ status = nfserr_badtype;
}
if (!status) {
gen_clid(new);
gen_confirm(new);
add_to_unconfirmed(new, strhashval);
- } else if (!cmp_clid(&conf->cl_clientid, &unconf->cl_clientid) &&
- !cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
+ } else if (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm)) {
/*
* CASE3:
* confirmed found (name, principal match)
* confirmed verifier does not match input clverifier
*
* unconfirmed found (name match)
- * confirmed->cl_clientid != unconfirmed->cl_clientid and
* confirmed->cl_confirm != unconfirmed->cl_confirm
*
* remove unconfirmed.
/* find the lockowner */
status = nfs_ok;
- for (i=0; i < LOCK_HASH_SIZE; i++) {
- list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash) {
- if(cmp_owner_str(local, owner, clid))
- break;
- }
- }
- if (local) {
- struct nfs4_stateid *stp;
-
- /* check for any locks held by any stateid associated with the
- * (lock) stateowner */
- status = nfserr_locks_held;
- list_for_each_entry(stp, &local->so_perfilestate, st_perfilestate) {
- if(stp->st_vfs_set) {
- if (check_for_locks(&stp->st_vfs_file, local))
- goto out;
+ for (i=0; i < LOCK_HASH_SIZE; i++)
+ list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash)
+ if(cmp_owner_str(local, owner, clid)) {
+ struct nfs4_stateid *stp;
+
+ /* check for any locks held by any stateid
+ * associated with the (lock) stateowner */
+ status = nfserr_locks_held;
+ list_for_each_entry(stp, &local->so_perfilestate,
+ st_perfilestate) {
+ if(stp->st_vfs_set) {
+ if (check_for_locks(&stp->st_vfs_file,
+ local))
+ goto out;
+ }
+ }
+ /* no locks held by (lock) stateowner */
+ status = nfs_ok;
+ release_stateowner(local);
+ goto out;
}
- }
- /* no locks held by (lock) stateowner */
- status = nfs_ok;
- release_stateowner(local);
- }
out:
nfs4_unlock_state();
return status;
case NF4SOCK:
case NF4FIFO:
case NF4DIR:
- break;
default:
- goto xdr_error;
+ break;
}
READ_BUF(4);
NF4SOCK, NF4BAD, NF4LNK, NF4BAD,
};
+static inline int
+xdr_padding(int l)
+{
+ return 3 - ((l - 1) & 3); /* smallest i>=0 such that (l+i)%4 = 0 */
+}
+
+static int
+nfsd4_encode_name(struct svc_rqst *rqstp, int group, uid_t id,
+ u32 **p, int *buflen)
+{
+ int status;
+ u32 len;
+
+ if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
+ return nfserr_resource;
+ if (group)
+ status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
+ else
+ status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
+ if (status < 0)
+ return nfserrno(status);
+ len = (unsigned)status;
+ *(*p)++ = htonl(len);
+ memset((u8 *)*p + len, 0, xdr_padding(len));
+ *p += XDR_QUADLEN(len);
+ *buflen -= (XDR_QUADLEN(len) << 2) + 4;
+ BUG_ON(*buflen < 0);
+ return 0;
+}
+
+static inline int
+nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen)
+{
+ return nfsd4_encode_name(rqstp, uid, 0, p, buflen);
+}
+
+static inline int
+nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen)
+{
+ return nfsd4_encode_name(rqstp, gid, 1, p, buflen);
+}
+
+
/*
* Note: @fhp can be NULL; in this case, we might have to compose the filehandle
* ourselves.
u32 bmval0 = bmval[0];
u32 bmval1 = bmval[1];
struct kstat stat;
- char owner[IDMAP_NAMESZ];
- u32 ownerlen = 0;
- char group[IDMAP_NAMESZ];
- u32 grouplen = 0;
struct svc_fh tempfh;
struct kstatfs statfs;
int buflen = *countp << 2;
goto out;
fhp = &tempfh;
}
- if (bmval1 & FATTR4_WORD1_OWNER) {
- int temp = nfsd_map_uid_to_name(rqstp, stat.uid, owner);
- if (temp < 0) {
- status = temp;
- goto out_nfserr;
- }
- ownerlen = (unsigned) temp;
- }
- if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
- int temp = nfsd_map_gid_to_name(rqstp, stat.gid, group);
- if (temp < 0) {
- status = temp;
- goto out_nfserr;
- }
- grouplen = (unsigned) temp;
- }
-
if ((buflen -= 16) < 0)
goto out_resource;
WRITE32(stat.nlink);
}
if (bmval1 & FATTR4_WORD1_OWNER) {
- buflen -= (XDR_QUADLEN(ownerlen) << 2) + 4;
- if (buflen < 0)
+ status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
+ if (status == nfserr_resource)
goto out_resource;
- WRITE32(ownerlen);
- WRITEMEM(owner, ownerlen);
+ if (status)
+ goto out;
}
if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
- buflen -= (XDR_QUADLEN(grouplen) << 2) + 4;
- if (buflen < 0)
+ status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
+ if (status == nfserr_resource)
goto out_resource;
- WRITE32(grouplen);
- WRITEMEM(group, grouplen);
+ if (status)
+ goto out;
}
if (bmval1 & FATTR4_WORD1_RAWDEV) {
if ((buflen -= 8) < 0)
/* make sure parents give x permission to user */
int err;
parent = dget_parent(tdentry);
- err = permission(parent->d_inode, S_IXOTH, NULL);
+ err = permission(parent->d_inode, MAY_EXEC, NULL);
if (err < 0) {
dput(parent);
break;
-ToDo:
+ToDo/Notes:
- Find and fix bugs.
- Either invalidate quotas or update the quota charges on NTFS 3.x
volumes with quota tracking enabled ($Quota).
pages as nothing can dirty a page other than ourselves. Should this
change, we will really need to roll our own ->set_page_dirty().
- Implement sops->dirty_inode() to implement {a,m,c}time updates and
- such things.
- - Implement sops->write_inode().
+ such things. This should probably just flag the ntfs inode such that
+ sops->write_inode(), i.e. ntfs_write_inode(), will copy the times
+ when it is invoked rather than having to update the mft record
+ every time.
- In between ntfs_prepare/commit_write, need exclusion between
simultaneous file extensions. Need perhaps an NInoResizeUnderway()
flag which we can set in ntfs_prepare_write() and clear again in
OTOH, perhaps i_sem, which is held accross generic_file_write is
sufficient for synchronisation here. We then just need to make sure
ntfs_readpage/writepage/truncate interoperate properly with us.
+ - Implement mft.c::sync_mft_mirror_umount(). We currently will just
+ leave the volume dirty on umount if the final iput(vol->mft_ino)
+ causes a write of any mirrored mft records due to the mft mirror
+ inode having been discarded already. Whether this can actually ever
+ happen is unclear however so it is worth waiting until someone hits
+ the problem.
+ - Enable the code for setting the NT4 compatibility flag when we start
+ making NTFS 1.2 specific modifications.
+
+2.1.14 - Fix an NFSd caused deadlock reported by several users.
+
+ - Modify fs/ntfs/ntfs_readdir() to copy the index root attribute value
+ to a buffer so that we can put the search context and unmap the mft
+ record before calling the filldir() callback. We need to do this
+ because of NFSd which calls ->lookup() from its filldir callback()
+ and this causes NTFS to deadlock as ntfs_lookup() maps the mft record
+ of the directory and since ntfs_readdir() has got it mapped already
+ ntfs_lookup() deadlocks.
+
+2.1.13 - Enable overwriting of resident files and housekeeping of system files.
+
+ - Implement writing of mft records (fs/ntfs/mft.[hc]), which includes
+ keeping the mft mirror in sync with the mft when mirrored mft records
+ are written. The functions are write_mft_record{,_nolock}(). The
+ implementation is quite rudimentary for now with lots of things not
+ implemented yet but I am not sure any of them can actually occur so
+ I will wait for people to hit each one and only then implement it.
+ - Commit open system inodes at umount time. This should make it
+ virtually impossible for sync_mft_mirror_umount() to ever be needed.
+ - Implement ->write_inode (fs/ntfs/inode.c::ntfs_write_inode()) for the
+ ntfs super operations. This gives us inode writing via the VFS inode
+ dirty code paths. Note: Access time updates are not implemented yet.
+ - Implement fs/ntfs/mft.[hc]::{,__}mark_mft_record_dirty() and make
+ fs/ntfs/aops.c::ntfs_writepage() and ntfs_commit_write() use it, thus
+ finally enabling resident file overwrite! (-8 This also includes a
+ placeholder for ->writepage (ntfs_mft_writepage()), which for now
+ just redirties the page and returns. Also, at umount time, we for
+ now throw away all mft data page cache pages after the last call to
+ ntfs_commit_inode() in the hope that all inodes will have been
+ written out by then and hence no dirty (meta)data will be lost. We
+ also check for this case and emit an error message telling the user
+ to run chkdsk.
+ - Use set_page_writeback() and end_page_writeback() in the resident
+ attribute code path of fs/ntfs/aops.c::ntfs_writepage() otherwise
+ the radix-tree tag PAGECACHE_TAG_DIRTY remains set even though the
+ page is clean.
+ - Implement ntfs_mft_writepage() so it now checks if any of the mft
+ records in the page are dirty and if so redirties the page and
+ returns. Otherwise it just returns (after doing set_page_writeback(),
+ unlock_page(), end_page_writeback() or the radix-tree tag
+ PAGECACHE_TAG_DIRTY remains set even though the page is clean), thus
+ alowing the VM to do with the page as it pleases. Also, at umount
+ time, now only throw away dirty mft (meta)data pages if dirty inodes
+ are present and ask the user to email us if they see this happening.
+ - Add functions ntfs_{clear,set}_volume_flags(), to modify the volume
+ information flags (fs/ntfs/super.c).
+ - Mark the volume dirty when (re)mounting read-write and mark it clean
+ when unmounting or remounting read-only. If any volume errors are
+ found, the volume is left marked dirty to force chkdsk to run.
+ - Add code to set the NT4 compatibility flag when (re)mounting
+ read-write for newer NTFS versions but leave it commented out for now
+ since we do not make any modifications that are NTFS 1.2 specific yet
+ and since setting this flag breaks Captive-NTFS which is not nice.
+ This code must be enabled once we start writing NTFS 1.2 specific
+ changes otherwise Windows NTFS driver might crash / cause corruption.
2.1.12 - Fix the second fix to the decompression engine and some cleanups.
ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
mst.o namei.o super.o sysctl.o unistr.o upcase.o
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.12\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.14\"
ifeq ($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
ni = NTFS_I(vi);
vol = ni->vol;
- ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
- "0x%lx.\n", vi->i_ino, ni->type, page->index);
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
+ "0x%lx.", vi->i_ino, ni->type, page->index);
BUG_ON(!NInoNonResident(ni));
BUG_ON(NInoMstProtected(ni));
*
* For resident attributes, OTOH, ntfs_writepage() writes the @page by copying
* the data to the mft record (which at this stage is most likely in memory).
- * Thus, in this case, I/O is synchronous, as even if the mft record is not
- * cached at this point in time, we need to wait for it to be read in before we
- * can do the copy.
+ * The mft record is then marked dirty and written out asynchronously via the
+ * vfs inode dirty code path.
*
* Note the caller clears the page dirty flag before calling ntfs_writepage().
*
BUG_ON(page_has_buffers(page));
BUG_ON(!PageUptodate(page));
- // TODO: Consider using PageWriteback() + unlock_page() in 2.5 once the
- // "VM fiddling has ended". Note, don't forget to replace all the
- // unlock_page() calls further below with end_page_writeback() ones.
- // FIXME: Make sure it is ok to SetPageError() on unlocked page under
- // writeback before doing the change!
-#if 0
- set_page_writeback(page);
- unlock_page(page);
-#endif
-
if (!NInoAttr(ni))
base_ni = ni;
else
if (unlikely(bytes > PAGE_CACHE_SIZE))
bytes = PAGE_CACHE_SIZE;
+ /*
+ * Keep the VM happy. This must be done otherwise the radix-tree tag
+ * PAGECACHE_TAG_DIRTY remains set even though the page is clean.
+ */
+ BUG_ON(PageWriteback(page));
+ set_page_writeback(page);
+ unlock_page(page);
+
/*
* Here, we don't need to zero the out of bounds area everytime because
* the below memcpy() already takes care of the mmap-at-end-of-file
* expose data to userspace/disk which should never have been exposed.
*
* FIXME: Ensure that i_size increases do the zeroing/overwriting and
- * if we cannot guarantee that, then enable the zeroing below.
+ * if we cannot guarantee that, then enable the zeroing below. If the
+ * zeroing below is enabled, we MUST move the unlock_page() from above
+ * to after the kunmap_atomic(), i.e. just before the
+ * end_page_writeback().
*/
kaddr = kmap_atomic(page, KM_USER0);
#endif
kunmap_atomic(kaddr, KM_USER0);
- unlock_page(page);
+ end_page_writeback(page);
- // TODO: Mark mft record dirty so it gets written back.
- ntfs_error(vi->i_sb, "Writing to resident files is not supported yet. "
- "Wrote to memory only...");
+ /* Mark the mft record dirty, so it gets written back. */
+ mark_mft_record_dirty(ctx->ntfs_ino);
put_attr_search_ctx(ctx);
unmap_mft_record(base_ni);
ni = NTFS_I(vi);
vol = ni->vol;
- ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
"0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
page->index, from, to);
struct inode *vi = page->mapping->host;
ntfs_inode *ni = NTFS_I(vi);
- ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
"0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
page->index, from, to);
vi = page->mapping->host;
- ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
"0x%lx, from = %u, to = %u.", vi->i_ino,
NTFS_I(vi)->type, page->index, from, to);
vi = page->mapping->host;
ni = NTFS_I(vi);
- ntfs_debug("Entering for inode %li, attribute type 0x%x, page index "
+ ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
"0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
page->index, from, to);
}
kunmap_atomic(kaddr, KM_USER0);
- // TODO: Mark mft record dirty so it gets written back.
- ntfs_error(vi->i_sb, "Writing to resident files is not supported yet. "
- "Wrote to memory only...");
+ /* Mark the mft record dirty, so it gets written back. */
+ mark_mft_record_dirty(ctx->ntfs_ino);
put_attr_search_ctx(ctx);
unmap_mft_record(base_ni);
if (drl[ds].vcn == marker_vcn) {
ntfs_debug("Old marker = 0x%llx, replacing "
- "with LCN_ENOENT.\n",
+ "with LCN_ENOENT.",
(unsigned long long)
drl[ds].lcn);
drl[ds].lcn = (LCN)LCN_ENOENT;
goto do_next_attr_loop;
}
ntfs_error(base_ni->vol->sb, "Inode contains corrupt attribute list "
- "attribute.\n");
+ "attribute.");
if (ni != base_ni) {
unmap_extent_mft_record(ni);
ctx->ntfs_ino = base_ni;
goto do_next_tag;
return_overflow:
- ntfs_error(NULL, "Failed. Returning -EOVERFLOW.\n");
+ ntfs_error(NULL, "Failed. Returning -EOVERFLOW.");
goto return_error;
}
if (err) {
ntfs_error(vol->sb, "ntfs_decompress() failed in inode "
"0x%lx with error code %i. Skipping "
- "this compression block.\n",
+ "this compression block.",
ni->mft_no, -err);
/* Release the unfinished pages. */
for (; prev_cur_page < cur_page; prev_cur_page++) {
ntfs_inode *ndir = NTFS_I(vdir);
ntfs_volume *vol = NTFS_SB(sb);
MFT_RECORD *m;
- INDEX_ROOT *ir;
+ INDEX_ROOT *ir = NULL;
INDEX_ENTRY *ie;
INDEX_ALLOCATION *ia;
u8 *name = NULL;
"inode 0x%lx.", vdir->i_ino);
goto err_out;
}
- /* Get to the index root value (it's been verified in read_inode). */
- ir = (INDEX_ROOT*)((u8*)ctx->attr +
- le16_to_cpu(ctx->attr->data.resident.value_offset));
+ /*
+ * Copy the index root attribute value to a buffer so that we can put
+ * the search context and unmap the mft record before calling the
+ * filldir() callback. We need to do this because of NFSd which calls
+ * ->lookup() from its filldir callback() and this causes NTFS to
+ * deadlock as ntfs_lookup() maps the mft record of the directory and
+ * we have got it mapped here already. The only solution is for us to
+ * unmap the mft record here so that a call to ntfs_lookup() is able to
+ * map the mft record without deadlocking.
+ */
+ rc = le32_to_cpu(ctx->attr->data.resident.value_length);
+ ir = (INDEX_ROOT*)kmalloc(rc, GFP_NOFS);
+ if (unlikely(!ir)) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ /* Copy the index root value (it has been verified in read_inode). */
+ memcpy(ir, (u8*)ctx->attr +
+ le16_to_cpu(ctx->attr->data.resident.value_offset), rc);
+ put_attr_search_ctx(ctx);
+ unmap_mft_record(ndir);
+ ctx = NULL;
+ m = NULL;
index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
/* The first index entry. */
ie = (INDEX_ENTRY*)((u8*)&ir->index +
for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
ntfs_debug("In index root, offset 0x%x.", (u8*)ie - (u8*)ir);
/* Bounds checks. */
- if (unlikely((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
+ if (unlikely((u8*)ie < (u8*)ir || (u8*)ie +
sizeof(INDEX_ENTRY_HEADER) > index_end ||
(u8*)ie + le16_to_cpu(ie->key_length) >
index_end))
rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ROOT, ir, ie,
name, dirent, filldir);
if (rc) {
- put_attr_search_ctx(ctx);
- unmap_mft_record(ndir);
+ kfree(ir);
goto abort;
}
}
- /*
- * We are done with the index root and the mft record for that matter.
- * We need to release it, otherwise we deadlock on ntfs_attr_iget()
- * and/or ntfs_read_page().
- */
- put_attr_search_ctx(ctx);
- unmap_mft_record(ndir);
- m = NULL;
- ctx = NULL;
+ /* We are done with the index root and can free the buffer. */
+ kfree(ir);
+ ir = NULL;
/* If there is no index allocation attribute we are finished. */
if (!NInoIndexAllocPresent(ndir))
goto EOD;
ntfs_unmap_page(bmp_page);
if (ia_page)
ntfs_unmap_page(ia_page);
+ if (ir)
+ kfree(ir);
if (name)
kfree(name);
if (ctx)
return err;
}
+/**
+ * ntfs_write_inode - write out a dirty inode
+ * @vi: inode to write out
+ * @sync: if true, write out synchronously
+ *
+ * Write out a dirty inode to disk including any extent inodes if present.
+ *
+ * If @sync is true, commit the inode to disk and wait for io completion. This
+ * is done using write_mft_record().
+ *
+ * If @sync is false, just schedule the write to happen but do not wait for i/o
+ * completion. In 2.6 kernels, scheduling usually happens just by virtue of
+ * marking the page (and in this case mft record) dirty but we do not implement
+ * this yet as write_mft_record() largely ignores the @sync parameter and
+ * always performs synchronous writes.
+ */
void ntfs_write_inode(struct inode *vi, int sync)
{
ntfs_inode *ni = NTFS_I(vi);
+#if 0
+ attr_search_context *ctx;
+#endif
+ MFT_RECORD *m;
+ int err = 0;
ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "",
vi->i_ino);
-
/*
* Dirty attribute inodes are written via their real inodes so just
- * clean them here.
+ * clean them here. TODO: Take care of access time updates.
*/
if (NInoAttr(ni)) {
NInoClearDirty(ni);
return;
}
-
- /* Write this base mft record. */
- if (NInoDirty(ni)) {
- ntfs_warning(vi->i_sb, "Cleaning dirty inode 0x%lx without "
- "writing to disk as this is not yet "
- "implemented.", vi->i_ino);
- NInoClearDirty(ni);
+ /* Map, pin, and lock the mft record belonging to the inode. */
+ m = map_mft_record(ni);
+ if (unlikely(IS_ERR(m))) {
+ err = PTR_ERR(m);
+ goto err_out;
}
-
+#if 0
+ /* Obtain the standard information attribute. */
+ ctx = get_attr_search_ctx(ni, m);
+ if (unlikely(!ctx)) {
+ err = -ENOMEM;
+ goto unm_err_out;
+ }
+ if (unlikely(!lookup_attr(AT_STANDARD_INFORMATION, NULL, 0,
+ IGNORE_CASE, 0, NULL, 0, ctx))) {
+ put_attr_search_ctx(ctx);
+ err = -ENOENT;
+ goto unm_err_out;
+ }
+ // TODO: Update the access times in the standard information attribute
+ // which is now in ctx->attr.
+ // - Probably want to have use sops->dirty_inode() to set a flag that
+ // we need to update the times here rather than having to blindly do
+ // it every time. Or even don't do it here at all and do it in
+ // sops->dirty_inode() instead. Problem with this would be that
+ // sops->dirty_inode() must be atomic under certain circumstances
+ // and mapping mft records and such like is not atomic.
+ // - For atime updates also need to check whether they are enabled in
+ // the superblock flags.
+ ntfs_warning(vi->i_sb, "Access time updates not implement yet.");
+ /*
+ * We just modified the mft record containing the standard information
+ * attribute. So need to mark the mft record dirty, too, but we do it
+ * manually so that mark_inode_dirty() is not called again.
+ * TODO: Only do this if there was a change in any of the times!
+ */
+ if (!NInoTestSetDirty(ctx->ntfs_ino))
+ __set_page_dirty_nobuffers(ctx->ntfs_ino->page);
+ put_attr_search_ctx(ctx);
+#endif
+ /* Write this base mft record. */
+ if (NInoDirty(ni))
+ err = write_mft_record(ni, m, sync);
/* Write all attached extent mft records. */
down(&ni->extent_lock);
if (ni->nr_extents > 0) {
- int i;
ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos;
+ int i;
+ ntfs_debug("Writing %i extent inodes.", ni->nr_extents);
for (i = 0; i < ni->nr_extents; i++) {
ntfs_inode *tni = extent_nis[i];
if (NInoDirty(tni)) {
- ntfs_warning(vi->i_sb, "Cleaning dirty extent "
- "inode 0x%lx without writing "
- "to disk as this is not yet "
- "implemented.", tni->mft_no);
- NInoClearDirty(tni);
+ MFT_RECORD *tm = map_mft_record(tni);
+ int ret;
+
+ if (unlikely(IS_ERR(tm))) {
+ if (!err || err == -ENOMEM)
+ err = PTR_ERR(tm);
+ continue;
+ }
+ ret = write_mft_record(tni, tm, sync);
+ unmap_mft_record(tni);
+ if (unlikely(ret)) {
+ if (!err || err == -ENOMEM)
+ err = ret;
+ }
}
}
}
up(&ni->extent_lock);
+ unmap_mft_record(ni);
+ if (unlikely(err))
+ goto err_out;
+ ntfs_debug("Done.");
+ return;
+#if 0
+unm_err_out:
+ unmap_mft_record(ni);
+#endif
+err_out:
+ if (err == -ENOMEM) {
+ ntfs_warning(vi->i_sb, "Not enough memory to write inode. "
+ "Marking the inode dirty again, so the VFS "
+ "retries later.");
+ mark_inode_dirty(vi);
+ } else {
+ ntfs_error(vi->i_sb, "Failed (error code %i): Marking inode "
+ "as bad. You should run chkdsk.", -err);
+ make_bad_inode(vi);
+ }
+ return;
}
#endif /* NTFS_RW */
*/
extern int ntfs_readpage(struct file *, struct page *);
+#ifdef NTFS_RW
+/**
+ * ntfs_mft_writepage - forward declaration, function is further below
+ */
+static int ntfs_mft_writepage(struct page *page, struct writeback_control *wbc);
+#endif /* NTFS_RW */
+
/**
* ntfs_mft_aops - address space operations for access to $MFT
*
.readpage = ntfs_readpage, /* Fill page with data. */
.sync_page = block_sync_page, /* Currently, just unplugs the
disk request queue. */
+#ifdef NTFS_RW
+ .writepage = ntfs_mft_writepage, /* Write out the dirty mft
+ records in a page. */
+#endif /* NTFS_RW */
};
/**
ntfs_clear_extent_inode(ni);
return m;
}
+
+#ifdef NTFS_RW
+
+/**
+ * __mark_mft_record_dirty - set the mft record and the page containing it dirty
+ * @ni: ntfs inode describing the mapped mft record
+ *
+ * Internal function. Users should call mark_mft_record_dirty() instead.
+ *
+ * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni,
+ * as well as the page containing the mft record, dirty. Also, mark the base
+ * vfs inode dirty. This ensures that any changes to the mft record are
+ * written out to disk.
+ *
+ * NOTE: We only set I_DIRTY_SYNC and I_DIRTY_DATASYNC (and not I_DIRTY_PAGES)
+ * on the base vfs inode, because even though file data may have been modified,
+ * it is dirty in the inode meta data rather than the data page cache of the
+ * inode, and thus there are no data pages that need writing out. Therefore, a
+ * full mark_inode_dirty() is overkill. A mark_inode_dirty_sync(), on the
+ * other hand, is not sufficient, because I_DIRTY_DATASYNC needs to be set to
+ * ensure ->write_inode is called from generic_osync_inode() and this needs to
+ * happen or the file data would not necessarily hit the device synchronously,
+ * even though the vfs inode has the O_SYNC flag set. Also, I_DIRTY_DATASYNC
+ * simply "feels" better than just I_DIRTY_SYNC, since the file data has not
+ * actually hit the block device yet, which is not what I_DIRTY_SYNC on its own
+ * would suggest.
+ */
+void __mark_mft_record_dirty(ntfs_inode *ni)
+{
+ struct page *page = ni->page;
+ ntfs_inode *base_ni;
+
+ ntfs_debug("Entering for inode 0x%lx.", ni->mft_no);
+ BUG_ON(!page);
+ BUG_ON(NInoAttr(ni));
+
+ /*
+ * Set the page containing the mft record dirty. This also marks the
+ * $MFT inode dirty (I_DIRTY_PAGES).
+ */
+ __set_page_dirty_nobuffers(page);
+
+ /* Determine the base vfs inode and mark it dirty, too. */
+ down(&ni->extent_lock);
+ if (likely(ni->nr_extents >= 0))
+ base_ni = ni;
+ else
+ base_ni = ni->ext.base_ntfs_ino;
+ up(&ni->extent_lock);
+ __mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC);
+}
+
+static const char *ntfs_please_email = "Please email "
+ "linux-ntfs-dev@lists.sourceforge.net and say that you saw "
+ "this message. Thank you.";
+
+/**
+ * sync_mft_mirror_umount - synchronise an mft record to the mft mirror
+ * @ni: ntfs inode whose mft record to synchronize
+ * @m: mapped, mst protected (extent) mft record to synchronize
+ *
+ * Write the mapped, mst protected (extent) mft record @m described by the
+ * (regular or extent) ntfs inode @ni to the mft mirror ($MFTMirr) bypassing
+ * the page cache and the $MFTMirr inode itself.
+ *
+ * This function is only for use at umount time when the mft mirror inode has
+ * already been disposed off. We BUG() if we are called while the mft mirror
+ * inode is still attached to the volume.
+ *
+ * On success return 0. On error return -errno.
+ *
+ * NOTE: This function is not implemented yet as I am not convinced it can
+ * actually be triggered considering the sequence of commits we do in super.c::
+ * ntfs_put_super(). But just in case we provide this place holder as the
+ * alternative would be either to BUG() or to get a NULL pointer dereference
+ * and Oops.
+ */
+static int sync_mft_mirror_umount(ntfs_inode *ni, MFT_RECORD *m)
+{
+ ntfs_volume *vol = ni->vol;
+
+ BUG_ON(vol->mftmirr_ino);
+ ntfs_error(vol->sb, "Umount time mft mirror syncing is not "
+ "implemented yet. %s", ntfs_please_email);
+ return -EOPNOTSUPP;
+}
+
+/**
+ * sync_mft_mirror - synchronize an mft record to the mft mirror
+ * @ni: ntfs inode whose mft record to synchronize
+ * @m: mapped, mst protected (extent) mft record to synchronize
+ * @sync: if true, wait for i/o completion
+ *
+ * Write the mapped, mst protected (extent) mft record @m described by the
+ * (regular or extent) ntfs inode @ni to the mft mirror ($MFTMirr).
+ *
+ * On success return 0. On error return -errno and set the volume errors flag
+ * in the ntfs_volume to which @ni belongs.
+ *
+ * NOTE: We always perform synchronous i/o and ignore the @sync parameter.
+ *
+ * TODO: If @sync is false, want to do truly asynchronous i/o, i.e. just
+ * schedule i/o via ->writepage or do it via kntfsd or whatever.
+ */
+static int sync_mft_mirror(ntfs_inode *ni, MFT_RECORD *m, int sync)
+{
+ ntfs_volume *vol = ni->vol;
+ struct page *page;
+ unsigned int blocksize = vol->sb->s_blocksize;
+ int max_bhs = vol->mft_record_size / blocksize;
+ struct buffer_head *bhs[max_bhs];
+ struct buffer_head *bh, *head;
+ u8 *kmirr;
+ unsigned int block_start, block_end, m_start, m_end;
+ int i_bhs, nr_bhs, err = 0;
+
+ ntfs_debug("Entering for inode 0x%lx.", ni->mft_no);
+ BUG_ON(!max_bhs);
+ if (unlikely(!vol->mftmirr_ino)) {
+ /* This could happen during umount... */
+ err = sync_mft_mirror_umount(ni, m);
+ if (likely(!err))
+ return err;
+ goto err_out;
+ }
+ /* Get the page containing the mirror copy of the mft record @m. */
+ page = ntfs_map_page(vol->mftmirr_ino->i_mapping, ni->mft_no >>
+ (PAGE_CACHE_SHIFT - vol->mft_record_size_bits));
+ if (unlikely(IS_ERR(page))) {
+ ntfs_error(vol->sb, "Failed to map mft mirror page.");
+ err = PTR_ERR(page);
+ goto err_out;
+ }
+ /*
+ * Exclusion against other writers. This should never be a problem
+ * since the page in which the mft record @m resides is also locked and
+ * hence any other writers would be held up there but it is better to
+ * make sure no one is writing from elsewhere.
+ */
+ lock_page(page);
+ /* The address in the page of the mirror copy of the mft record @m. */
+ kmirr = page_address(page) + ((ni->mft_no << vol->mft_record_size_bits)
+ & ~PAGE_CACHE_MASK);
+ /* Copy the mst protected mft record to the mirror. */
+ memcpy(kmirr, m, vol->mft_record_size);
+ /* Make sure we have mapped buffers. */
+ if (!page_has_buffers(page)) {
+no_buffers_err_out:
+ ntfs_error(vol->sb, "Writing mft mirror records without "
+ "existing buffers is not implemented yet. %s",
+ ntfs_please_email);
+ err = -EOPNOTSUPP;
+ goto unlock_err_out;
+ }
+ bh = head = page_buffers(page);
+ if (!bh)
+ goto no_buffers_err_out;
+ nr_bhs = 0;
+ block_start = 0;
+ m_start = kmirr - (u8*)page_address(page);
+ m_end = m_start + vol->mft_record_size;
+ do {
+ block_end = block_start + blocksize;
+ /*
+ * If the buffer is outside the mft record, just skip it,
+ * clearing it if it is dirty to make sure it is not written
+ * out. It should never be marked dirty but better be safe.
+ */
+ if ((block_end <= m_start) || (block_start >= m_end)) {
+ if (buffer_dirty(bh)) {
+ ntfs_warning(vol->sb, "Clearing dirty mft "
+ "record page buffer. %s",
+ ntfs_please_email);
+ clear_buffer_dirty(bh);
+ }
+ continue;
+ }
+ if (!buffer_mapped(bh)) {
+ ntfs_error(vol->sb, "Writing mft mirror records "
+ "without existing mapped buffers is "
+ "not implemented yet. %s",
+ ntfs_please_email);
+ err = -EOPNOTSUPP;
+ continue;
+ }
+ if (!buffer_uptodate(bh)) {
+ ntfs_error(vol->sb, "Writing mft mirror records "
+ "without existing uptodate buffers is "
+ "not implemented yet. %s",
+ ntfs_please_email);
+ err = -EOPNOTSUPP;
+ continue;
+ }
+ BUG_ON(!nr_bhs && (m_start != block_start));
+ BUG_ON(nr_bhs >= max_bhs);
+ bhs[nr_bhs++] = bh;
+ BUG_ON((nr_bhs >= max_bhs) && (m_end != block_end));
+ } while (block_start = block_end, (bh = bh->b_this_page) != head);
+ if (likely(!err)) {
+ /* Lock buffers and start synchronous write i/o on them. */
+ for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+ struct buffer_head *tbh = bhs[i_bhs];
+
+ if (unlikely(test_set_buffer_locked(tbh)))
+ BUG();
+ BUG_ON(!buffer_uptodate(tbh));
+ if (buffer_dirty(tbh))
+ clear_buffer_dirty(tbh);
+ get_bh(tbh);
+ tbh->b_end_io = end_buffer_write_sync;
+ submit_bh(WRITE, tbh);
+ }
+ /* Wait on i/o completion of buffers. */
+ for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+ struct buffer_head *tbh = bhs[i_bhs];
+
+ wait_on_buffer(tbh);
+ if (unlikely(!buffer_uptodate(tbh))) {
+ err = -EIO;
+ /*
+ * Set the buffer uptodate so the page & buffer
+ * states don't become out of sync.
+ */
+ if (PageUptodate(page))
+ set_buffer_uptodate(tbh);
+ }
+ }
+ } else /* if (unlikely(err)) */ {
+ /* Clean the buffers. */
+ for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++)
+ clear_buffer_dirty(bhs[i_bhs]);
+ }
+unlock_err_out:
+ /* Current state: all buffers are clean, unlocked, and uptodate. */
+ /* Remove the mst protection fixups again. */
+ post_write_mst_fixup((NTFS_RECORD*)kmirr);
+ flush_dcache_page(page);
+ unlock_page(page);
+ ntfs_unmap_page(page);
+ if (unlikely(err)) {
+ /* I/O error during writing. This is really bad! */
+ ntfs_error(vol->sb, "I/O error while writing mft mirror "
+ "record 0x%lx! You should unmount the volume "
+ "and run chkdsk or ntfsfix.", ni->mft_no);
+ goto err_out;
+ }
+ ntfs_debug("Done.");
+ return 0;
+err_out:
+ ntfs_error(vol->sb, "Failed to synchronize $MFTMirr (error code %i). "
+ "Volume will be left marked dirty on umount. Run "
+ "ntfsfix on the partition after umounting to correct "
+ "this.", -err);
+ /* We don't want to clear the dirty bit on umount. */
+ NVolSetErrors(vol);
+ return err;
+}
+
+/**
+ * write_mft_record_nolock - write out a mapped (extent) mft record
+ * @ni: ntfs inode describing the mapped (extent) mft record
+ * @m: mapped (extent) mft record to write
+ * @sync: if true, wait for i/o completion
+ *
+ * Write the mapped (extent) mft record @m described by the (regular or extent)
+ * ntfs inode @ni to backing store. If the mft record @m has a counterpart in
+ * the mft mirror, that is also updated.
+ *
+ * On success, clean the mft record and return 0. On error, leave the mft
+ * record dirty and return -errno. The caller should call make_bad_inode() on
+ * the base inode to ensure no more access happens to this inode. We do not do
+ * it here as the caller may want to finish writing other extent mft records
+ * first to minimize on-disk metadata inconsistencies.
+ *
+ * NOTE: We always perform synchronous i/o and ignore the @sync parameter.
+ * However, if the mft record has a counterpart in the mft mirror and @sync is
+ * true, we write the mft record, wait for i/o completion, and only then write
+ * the mft mirror copy. This ensures that if the system crashes either the mft
+ * or the mft mirror will contain a self-consistent mft record @m. If @sync is
+ * false on the other hand, we start i/o on both and then wait for completion
+ * on them. This provides a speedup but no longer guarantees that you will end
+ * up with a self-consistent mft record in the case of a crash but if you asked
+ * for asynchronous writing you probably do not care about that anyway.
+ *
+ * TODO: If @sync is false, want to do truly asynchronous i/o, i.e. just
+ * schedule i/o via ->writepage or do it via kntfsd or whatever.
+ */
+int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
+{
+ ntfs_volume *vol = ni->vol;
+ struct page *page = ni->page;
+ unsigned int blocksize = vol->sb->s_blocksize;
+ int max_bhs = vol->mft_record_size / blocksize;
+ struct buffer_head *bhs[max_bhs];
+ struct buffer_head *bh, *head;
+ unsigned int block_start, block_end, m_start, m_end;
+ int i_bhs, nr_bhs, err = 0;
+
+ ntfs_debug("Entering for inode 0x%lx.", ni->mft_no);
+ BUG_ON(NInoAttr(ni));
+ BUG_ON(!max_bhs);
+ BUG_ON(!page);
+ BUG_ON(!PageLocked(page));
+ /*
+ * If the ntfs_inode is clean no need to do anything. If it is dirty,
+ * mark it as clean now so that it can be redirtied later on if needed.
+ * There is no danger of races as as long as the caller is holding the
+ * locks for the mft record @m and the page it is in.
+ */
+ if (!NInoTestClearDirty(ni))
+ goto done;
+ /* Make sure we have mapped buffers. */
+ if (!page_has_buffers(page)) {
+no_buffers_err_out:
+ ntfs_error(vol->sb, "Writing mft records without existing "
+ "buffers is not implemented yet. %s",
+ ntfs_please_email);
+ err = -EOPNOTSUPP;
+ goto err_out;
+ }
+ bh = head = page_buffers(page);
+ if (!bh)
+ goto no_buffers_err_out;
+ nr_bhs = 0;
+ block_start = 0;
+ m_start = ni->page_ofs;
+ m_end = m_start + vol->mft_record_size;
+ do {
+ block_end = block_start + blocksize;
+ /*
+ * If the buffer is outside the mft record, just skip it,
+ * clearing it if it is dirty to make sure it is not written
+ * out. It should never be marked dirty but better be safe.
+ */
+ if ((block_end <= m_start) || (block_start >= m_end)) {
+ if (buffer_dirty(bh)) {
+ ntfs_warning(vol->sb, "Clearing dirty mft "
+ "record page buffer. %s",
+ ntfs_please_email);
+ clear_buffer_dirty(bh);
+ }
+ continue;
+ }
+ if (!buffer_mapped(bh)) {
+ ntfs_error(vol->sb, "Writing mft records without "
+ "existing mapped buffers is not "
+ "implemented yet. %s",
+ ntfs_please_email);
+ err = -EOPNOTSUPP;
+ continue;
+ }
+ if (!buffer_uptodate(bh)) {
+ ntfs_error(vol->sb, "Writing mft records without "
+ "existing uptodate buffers is not "
+ "implemented yet. %s",
+ ntfs_please_email);
+ err = -EOPNOTSUPP;
+ continue;
+ }
+ BUG_ON(!nr_bhs && (m_start != block_start));
+ BUG_ON(nr_bhs >= max_bhs);
+ bhs[nr_bhs++] = bh;
+ BUG_ON((nr_bhs >= max_bhs) && (m_end != block_end));
+ } while (block_start = block_end, (bh = bh->b_this_page) != head);
+ if (unlikely(err))
+ goto cleanup_out;
+ /* Apply the mst protection fixups. */
+ err = pre_write_mst_fixup((NTFS_RECORD*)m, vol->mft_record_size);
+ if (err) {
+ ntfs_error(vol->sb, "Failed to apply mst fixups!");
+ goto cleanup_out;
+ }
+ flush_dcache_mft_record_page(ni);
+ /* Lock buffers and start synchronous write i/o on them. */
+ for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+ struct buffer_head *tbh = bhs[i_bhs];
+
+ if (unlikely(test_set_buffer_locked(tbh)))
+ BUG();
+ BUG_ON(!buffer_uptodate(tbh));
+ if (buffer_dirty(tbh))
+ clear_buffer_dirty(tbh);
+ get_bh(tbh);
+ tbh->b_end_io = end_buffer_write_sync;
+ submit_bh(WRITE, tbh);
+ }
+ /* Synchronize the mft mirror now if not @sync. */
+ if (!sync && ni->mft_no < vol->mftmirr_size)
+ sync_mft_mirror(ni, m, sync);
+ /* Wait on i/o completion of buffers. */
+ for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
+ struct buffer_head *tbh = bhs[i_bhs];
+
+ wait_on_buffer(tbh);
+ if (unlikely(!buffer_uptodate(tbh))) {
+ err = -EIO;
+ /*
+ * Set the buffer uptodate so the page & buffer states
+ * don't become out of sync.
+ */
+ if (PageUptodate(page))
+ set_buffer_uptodate(tbh);
+ }
+ }
+ /* If @sync, now synchronize the mft mirror. */
+ if (sync && ni->mft_no < vol->mftmirr_size)
+ sync_mft_mirror(ni, m, sync);
+ /* Remove the mst protection fixups again. */
+ post_write_mst_fixup((NTFS_RECORD*)m);
+ flush_dcache_mft_record_page(ni);
+ if (unlikely(err)) {
+ /* I/O error during writing. This is really bad! */
+ ntfs_error(vol->sb, "I/O error while writing mft record "
+ "0x%lx! Marking base inode as bad. You "
+ "should unmount the volume and run chkdsk.",
+ ni->mft_no);
+ goto err_out;
+ }
+done:
+ ntfs_debug("Done.");
+ return 0;
+cleanup_out:
+ /* Clean the buffers. */
+ for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++)
+ clear_buffer_dirty(bhs[i_bhs]);
+err_out:
+ /*
+ * Current state: all buffers are clean, unlocked, and uptodate.
+ * The caller should mark the base inode as bad so that no more i/o
+ * happens. ->clear_inode() will still be invoked so all extent inodes
+ * and other allocated memory will be freed.
+ */
+ if (err == -ENOMEM) {
+ ntfs_error(vol->sb, "Not enough memory to write mft record. "
+ "Redirtying so the write is retried later.");
+ mark_mft_record_dirty(ni);
+ err = 0;
+ }
+ return err;
+}
+
+/**
+ * ntfs_mft_writepage - check if a metadata page contains dirty mft records
+ * @page: metadata page possibly containing dirty mft records
+ * @wbc: writeback control structure
+ *
+ * This is called from the VM when it wants to have a dirty $MFT/$DATA metadata
+ * page cache page cleaned. The VM has already locked the page and marked it
+ * clean. Instead of writing the page as a conventional ->writepage function
+ * would do, we check if the page still contains any dirty mft records (it must
+ * have done at some point in the past since the page was marked dirty) and if
+ * none are found, i.e. all mft records are clean, we unlock the page and
+ * return. The VM is then free to do with the page as it pleases. If on the
+ * other hand we do find any dirty mft records in the page, we redirty the page
+ * before unlocking it and returning so the VM knows that the page is still
+ * busy and cannot be thrown out.
+ *
+ * Note, we do not actually write any dirty mft records here because they are
+ * dirty inodes and hence will be written by the VFS inode dirty code paths.
+ * There is no need to write them from the VM page dirty code paths, too and in
+ * fact once we implement journalling it would be a complete nightmare having
+ * two code paths leading to mft record writeout.
+ */
+static int ntfs_mft_writepage(struct page *page, struct writeback_control *wbc)
+{
+ struct inode *mft_vi = page->mapping->host;
+ struct super_block *sb = mft_vi->i_sb;
+ ntfs_volume *vol = NTFS_SB(sb);
+ u8 *maddr;
+ MFT_RECORD *m;
+ ntfs_inode **extent_nis;
+ unsigned long mft_no;
+ int nr, i, j;
+ BOOL is_dirty = FALSE;
+
+ BUG_ON(mft_vi != vol->mft_ino);
+ /* The first mft record number in the page. */
+ mft_no = page->index << (PAGE_CACHE_SHIFT - vol->mft_record_size_bits);
+ /* Number of mft records in the page. */
+ nr = PAGE_CACHE_SIZE >> vol->mft_record_size_bits;
+ BUG_ON(!nr);
+ ntfs_debug("Entering for %i inodes starting at 0x%lx.", nr, mft_no);
+ /* Iterate over the mft records in the page looking for a dirty one. */
+ maddr = (u8*)kmap(page);
+ for (i = 0; i < nr; ++i, ++mft_no, maddr += vol->mft_record_size) {
+ struct inode *vi;
+ ntfs_inode *ni, *eni;
+ ntfs_attr na;
+
+ na.mft_no = mft_no;
+ na.name = NULL;
+ na.name_len = 0;
+ na.type = AT_UNUSED;
+ /*
+ * Check if the inode corresponding to this mft record is in
+ * the VFS inode cache and obtain a reference to it if it is.
+ */
+ ntfs_debug("Looking for inode 0x%lx in icache.", mft_no);
+ /*
+ * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from
+ * here or we deadlock because the inode is already locked by
+ * the kernel (fs/fs-writeback.c::__sync_single_inode()) and
+ * ilookup5() waits until the inode is unlocked before
+ * returning it and it never gets unlocked because
+ * ntfs_mft_writepage() never returns. )-: Fortunately, we
+ * have inode 0 pinned in icache for the duration of the mount
+ * so we can access it directly.
+ */
+ if (!mft_no) {
+ /* Balance the below iput(). */
+ vi = igrab(mft_vi);
+ BUG_ON(vi != mft_vi);
+ } else
+ vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na);
+ if (vi) {
+ ntfs_debug("Inode 0x%lx is in icache.", mft_no);
+ /* The inode is in icache. Check if it is dirty. */
+ ni = NTFS_I(vi);
+ if (!NInoDirty(ni)) {
+ /* The inode is not dirty, skip this record. */
+ ntfs_debug("Inode 0x%lx is not dirty, "
+ "continuing search.", mft_no);
+ iput(vi);
+ continue;
+ }
+ ntfs_debug("Inode 0x%lx is dirty, aborting search.",
+ mft_no);
+ /* The inode is dirty, no need to search further. */
+ iput(vi);
+ is_dirty = TRUE;
+ break;
+ }
+ ntfs_debug("Inode 0x%lx is not in icache.", mft_no);
+ /* The inode is not in icache. */
+ /* Skip the record if it is not a mft record (type "FILE"). */
+ if (!ntfs_is_mft_recordp(maddr)) {
+ ntfs_debug("Mft record 0x%lx is not a FILE record, "
+ "continuing search.", mft_no);
+ continue;
+ }
+ m = (MFT_RECORD*)maddr;
+ /*
+ * Skip the mft record if it is not in use. FIXME: What about
+ * deleted/deallocated (extent) inodes? (AIA)
+ */
+ if (!(m->flags & MFT_RECORD_IN_USE)) {
+ ntfs_debug("Mft record 0x%lx is not in use, "
+ "continuing search.", mft_no);
+ continue;
+ }
+ /* Skip the mft record if it is a base inode. */
+ if (!m->base_mft_record) {
+ ntfs_debug("Mft record 0x%lx is a base record, "
+ "continuing search.", mft_no);
+ continue;
+ }
+ /*
+ * This is an extent mft record. Check if the inode
+ * corresponding to its base mft record is in icache.
+ */
+ na.mft_no = MREF_LE(m->base_mft_record);
+ ntfs_debug("Mft record 0x%lx is an extent record. Looking "
+ "for base inode 0x%lx in icache.", mft_no,
+ na.mft_no);
+ vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode,
+ &na);
+ if (!vi) {
+ /*
+ * The base inode is not in icache. Skip this extent
+ * mft record.
+ */
+ ntfs_debug("Base inode 0x%lx is not in icache, "
+ "continuing search.", na.mft_no);
+ continue;
+ }
+ ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no);
+ /*
+ * The base inode is in icache. Check if it has the extent
+ * inode corresponding to this extent mft record attached.
+ */
+ ni = NTFS_I(vi);
+ down(&ni->extent_lock);
+ if (ni->nr_extents <= 0) {
+ /*
+ * The base inode has no attached extent inodes. Skip
+ * this extent mft record.
+ */
+ up(&ni->extent_lock);
+ iput(vi);
+ continue;
+ }
+ /* Iterate over the attached extent inodes. */
+ extent_nis = ni->ext.extent_ntfs_inos;
+ for (eni = NULL, j = 0; j < ni->nr_extents; ++j) {
+ if (mft_no == extent_nis[j]->mft_no) {
+ /*
+ * Found the extent inode corresponding to this
+ * extent mft record.
+ */
+ eni = extent_nis[j];
+ break;
+ }
+ }
+ /*
+ * If the extent inode was not attached to the base inode, skip
+ * this extent mft record.
+ */
+ if (!eni) {
+ up(&ni->extent_lock);
+ iput(vi);
+ continue;
+ }
+ /*
+ * Found the extent inode corrsponding to this extent mft
+ * record. If it is dirty, no need to search further.
+ */
+ if (NInoDirty(eni)) {
+ up(&ni->extent_lock);
+ iput(vi);
+ is_dirty = TRUE;
+ break;
+ }
+ /* The extent inode is not dirty, so do the next record. */
+ up(&ni->extent_lock);
+ iput(vi);
+ }
+ kunmap(page);
+ /* If a dirty mft record was found, redirty the page. */
+ if (is_dirty) {
+ ntfs_debug("Inode 0x%lx is dirty. Redirtying the page "
+ "starting at inode 0x%lx.", mft_no,
+ page->index << (PAGE_CACHE_SHIFT -
+ vol->mft_record_size_bits));
+ redirty_page_for_writepage(wbc, page);
+ unlock_page(page);
+ } else {
+ /*
+ * Keep the VM happy. This must be done otherwise the
+ * radix-tree tag PAGECACHE_TAG_DIRTY remains set even though
+ * the page is clean.
+ */
+ BUG_ON(PageWriteback(page));
+ set_page_writeback(page);
+ unlock_page(page);
+ end_page_writeback(page);
+ }
+ ntfs_debug("Done.");
+ return 0;
+}
+
+#endif /* NTFS_RW */
flush_dcache_page(ni->page);
}
+extern void __mark_mft_record_dirty(ntfs_inode *ni);
+
+/**
+ * mark_mft_record_dirty - set the mft record and the page containing it dirty
+ * @ni: ntfs inode describing the mapped mft record
+ *
+ * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni,
+ * as well as the page containing the mft record, dirty. Also, mark the base
+ * vfs inode dirty. This ensures that any changes to the mft record are
+ * written out to disk.
+ *
+ * NOTE: Do not do anything if the mft record is already marked dirty.
+ */
+static inline void mark_mft_record_dirty(ntfs_inode *ni)
+{
+ if (!NInoTestSetDirty(ni))
+ __mark_mft_record_dirty(ni);
+}
+
+extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync);
+
+/**
+ * write_mft_record - write out a mapped (extent) mft record
+ * @ni: ntfs inode describing the mapped (extent) mft record
+ * @m: mapped (extent) mft record to write
+ * @sync: if true, wait for i/o completion
+ *
+ * This is just a wrapper for write_mft_record_nolock() (see mft.c), which
+ * locks the page for the duration of the write. This ensures that there are
+ * no race conditions between writing the mft record via the dirty inode code
+ * paths and via the page cache write back code paths or between writing
+ * neighbouring mft records residing in the same page.
+ *
+ * Locking the page also serializes us against ->readpage() if the page is not
+ * uptodate.
+ *
+ * On success, clean the mft record and return 0. On error, leave the mft
+ * record dirty and return -errno. The caller should call make_bad_inode() on
+ * the base inode to ensure no more access happens to this inode. We do not do
+ * it here as the caller may want to finish writing other extent mft records
+ * first to minimize on-disk metadata inconsistencies.
+ */
+static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
+{
+ struct page *page = ni->page;
+ int err;
+
+ BUG_ON(!page);
+ lock_page(page);
+ err = write_mft_record_nolock(ni, m, sync);
+ unlock_page(page);
+ return err;
+}
+
#endif /* NTFS_RW */
#endif /* _LINUX_NTFS_MFT_H */
return FALSE;
}
+#ifdef NTFS_RW
+
+/**
+ * ntfs_write_volume_flags - write new flags to the volume information flags
+ * @vol: ntfs volume on which to modify the flags
+ * @flags: new flags value for the volume information flags
+ *
+ * Internal function. You probably want to use ntfs_{set,clear}_volume_flags()
+ * instead (see below).
+ *
+ * Replace the volume information flags on the volume @vol with the value
+ * supplied in @flags. Note, this overwrites the volume information flags, so
+ * make sure to combine the flags you want to modify with the old flags and use
+ * the result when calling ntfs_write_volume_flags().
+ *
+ * Return 0 on success and -errno on error.
+ */
+static int ntfs_write_volume_flags(ntfs_volume *vol, const VOLUME_FLAGS flags)
+{
+ ntfs_inode *ni = NTFS_I(vol->vol_ino);
+ MFT_RECORD *m;
+ VOLUME_INFORMATION *vi;
+ attr_search_context *ctx;
+ int err;
+
+ ntfs_debug("Entering, old flags = 0x%x, new flags = 0x%x.",
+ vol->vol_flags, flags);
+ if (vol->vol_flags == flags)
+ goto done;
+ BUG_ON(!ni);
+ m = map_mft_record(ni);
+ if (IS_ERR(m)) {
+ err = PTR_ERR(m);
+ goto err_out;
+ }
+ ctx = get_attr_search_ctx(ni, m);
+ if (!ctx) {
+ err = -ENOMEM;
+ goto put_unm_err_out;
+ }
+ if (!lookup_attr(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, ctx)) {
+ err = -EIO;
+ goto put_unm_err_out;
+ }
+ vi = (VOLUME_INFORMATION*)((u8*)ctx->attr +
+ le16_to_cpu(ctx->attr->data.resident.value_offset));
+ vol->vol_flags = vi->flags = flags;
+ flush_dcache_mft_record_page(ctx->ntfs_ino);
+ mark_mft_record_dirty(ctx->ntfs_ino);
+ put_attr_search_ctx(ctx);
+ unmap_mft_record(ni);
+done:
+ ntfs_debug("Done.");
+ return 0;
+put_unm_err_out:
+ if (ctx)
+ put_attr_search_ctx(ctx);
+ unmap_mft_record(ni);
+err_out:
+ ntfs_error(vol->sb, "Failed with error code %i.", -err);
+ return err;
+}
+
+/**
+ * ntfs_set_volume_flags - set bits in the volume information flags
+ * @vol: ntfs volume on which to modify the flags
+ * @flags: flags to set on the volume
+ *
+ * Set the bits in @flags in the volume information flags on the volume @vol.
+ *
+ * Return 0 on success and -errno on error.
+ */
+static inline int ntfs_set_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags)
+{
+ flags &= VOLUME_FLAGS_MASK;
+ return ntfs_write_volume_flags(vol, vol->vol_flags | flags);
+}
+
+/**
+ * ntfs_clear_volume_flags - clear bits in the volume information flags
+ * @vol: ntfs volume on which to modify the flags
+ * @flags: flags to clear on the volume
+ *
+ * Clear the bits in @flags in the volume information flags on the volume @vol.
+ *
+ * Return 0 on success and -errno on error.
+ */
+static inline int ntfs_clear_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags)
+{
+ flags &= VOLUME_FLAGS_MASK;
+ return ntfs_write_volume_flags(vol, vol->vol_flags & ~flags);
+}
+
+#endif /* NTFS_RW */
+
/**
* ntfs_remount - change the mount options of a mounted ntfs filesystem
* @sb: superblock of mounted ntfs filesystem
* For the read-write compiled driver, if we are remounting read-write,
* make sure there are no volume errors and that no unsupported volume
* flags are set. Also, empty the logfile journal as it would become
- * stale as soon as something is written to the volume.
+ * stale as soon as something is written to the volume and mark the
+ * volume dirty so that chkdsk is run if the volume is not umounted
+ * cleanly.
+ *
+ * When remounting read-only, mark the volume clean if no volume errors
+ * have occured.
*/
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
static const char *es = ". Cannot remount read-write.";
+ /* Remounting read-write. */
if (NVolErrors(vol)) {
ntfs_error(sb, "Volume has errors and is read-only%s",
es);
return -EROFS;
}
+ if (vol->vol_flags & VOLUME_IS_DIRTY) {
+ ntfs_error(sb, "Volume is dirty and read-only%s", es);
+ return -EROFS;
+ }
if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
ntfs_error(sb, "Volume has unsupported flags set and "
"is read-only%s", es);
return -EROFS;
}
+ if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
+ ntfs_error(sb, "Failed to set dirty bit in volume "
+ "information flags%s", es);
+ return -EROFS;
+ }
+#if 0
+ // TODO: Enable this code once we start modifying anything that
+ // is different between NTFS 1.2 and 3.x...
+ /* Set NT4 compatibility flag on newer NTFS version volumes. */
+ if ((vol->major_ver > 1)) {
+ if (ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) {
+ ntfs_error(sb, "Failed to set NT4 "
+ "compatibility flag%s", es);
+ NVolSetErrors(vol);
+ return -EROFS;
+ }
+ }
+#endif
if (!ntfs_empty_logfile(vol->logfile_ino)) {
ntfs_error(sb, "Failed to empty journal $LogFile%s",
es);
NVolSetErrors(vol);
return -EROFS;
}
+ } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
+ /* Remounting read-only. */
+ if (!NVolErrors(vol)) {
+ if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY))
+ ntfs_warning(sb, "Failed to clear dirty bit "
+ "in volume information "
+ "flags. Run chkdsk.");
+ }
}
// TODO: For now we enforce no atime and dir atime updates as they are
// not implemented.
+ if ((sb->s_flags & MS_NOATIME) && !(*flags & MS_NOATIME))
+ ntfs_warning(sb, "Atime updates are not implemented yet. "
+ "Leaving them disabled.");
+ else if ((sb->s_flags & MS_NODIRATIME) && !(*flags & MS_NODIRATIME))
+ ntfs_warning(sb, "Directory atime updates are not implemented "
+ "yet. Leaving them disabled.");
*flags |= MS_NOATIME | MS_NODIRATIME;
#endif /* ! NTFS_RW */
le32_to_cpu(ctx->attr->data.resident.value_length) >
(u8*)ctx->attr + le32_to_cpu(ctx->attr->length))
goto err_put_vol;
- /* Setup volume flags and version. */
+ /* Copy the volume flags and version to the ntfs_volume structure. */
vol->vol_flags = vi->flags;
vol->major_ver = vi->major_ver;
vol->minor_ver = vi->minor_ver;
#ifdef NTFS_RW
/* Make sure that no unsupported volume flags are set. */
if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
- static const char *es1 = "Volume has unsupported flags set";
+ static const char *es1a = "Volume is dirty";
+ static const char *es1b = "Volume has unsupported flags set";
static const char *es2 = ". Run chkdsk and mount in Windows.";
-
+ const char *es1;
+
+ es1 = vol->vol_flags & VOLUME_IS_DIRTY ? es1a : es1b;
/* If a read-write mount, convert it to a read-only mount. */
if (!(sb->s_flags & MS_RDONLY)) {
if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
*/
if (!load_and_check_logfile(vol) ||
!ntfs_is_logfile_clean(vol->logfile_ino)) {
- static const char *es1 = "Failed to load $LogFile";
- static const char *es2 = "$LogFile is not clean";
- static const char *es3 = ". Mount in Windows.";
+ static const char *es1a = "Failed to load $LogFile";
+ static const char *es1b = "$LogFile is not clean";
+ static const char *es2 = ". Mount in Windows.";
+ const char *es1;
+ es1 = !vol->logfile_ino ? es1a : es1b;
/* If a read-write mount, convert it to a read-only mount. */
if (!(sb->s_flags & MS_RDONLY)) {
if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
ntfs_error(sb, "%s and neither on_errors="
"continue nor on_errors="
"remount-ro was specified%s",
- !vol->logfile_ino ? es1 : es2,
- es3);
+ es1, es2);
goto iput_logfile_err_out;
}
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
- ntfs_error(sb, "%s. Mounting read-only%s",
- !vol->logfile_ino ? es1 : es2, es3);
+ ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);
} else
ntfs_warning(sb, "%s. Will not be able to remount "
- "read-write%s",
- !vol->logfile_ino ? es1 : es2, es3);
+ "read-write%s", es1, es2);
/* This will prevent a read-write remount. */
NVolSetErrors(vol);
- /* If a read-write mount, empty the logfile. */
- } else if (!(sb->s_flags & MS_RDONLY) &&
+ }
+ /* If (still) a read-write mount, mark the volume dirty. */
+ if (!(sb->s_flags & MS_RDONLY) &&
+ ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
+ static const char *es1 = "Failed to set dirty bit in volume "
+ "information flags";
+ static const char *es2 = ". Run chkdsk.";
+
+ /* Convert to a read-only mount. */
+ if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+ ON_ERRORS_CONTINUE))) {
+ ntfs_error(sb, "%s and neither on_errors=continue nor "
+ "on_errors=remount-ro was specified%s",
+ es1, es2);
+ goto iput_logfile_err_out;
+ }
+ ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);
+ sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+ /*
+ * Do not set NVolErrors() because ntfs_remount() might manage
+ * to set the dirty flag in which case all would be well.
+ */
+ }
+#if 0
+ // TODO: Enable this code once we start modifying anything that is
+ // different between NTFS 1.2 and 3.x...
+ /*
+ * If (still) a read-write mount, set the NT4 compatibility flag on
+ * newer NTFS version volumes.
+ */
+ if (!(sb->s_flags & MS_RDONLY) && (vol->major_ver > 1) &&
+ ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) {
+ static const char *es1 = "Failed to set NT4 compatibility flag";
+ static const char *es2 = ". Run chkdsk.";
+
+ /* Convert to a read-only mount. */
+ if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+ ON_ERRORS_CONTINUE))) {
+ ntfs_error(sb, "%s and neither on_errors=continue nor "
+ "on_errors=remount-ro was specified%s",
+ es1, es2);
+ goto iput_logfile_err_out;
+ }
+ ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);
+ sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+ NVolSetErrors(vol);
+ }
+#endif
+ /* If (still) a read-write mount, empty the logfile. */
+ if (!(sb->s_flags & MS_RDONLY) &&
!ntfs_empty_logfile(vol->logfile_ino)) {
static const char *es1 = "Failed to empty $LogFile";
static const char *es2 = ". Mount in Windows.";
es1, es2);
goto iput_logfile_err_out;
}
- sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);
- /* This will prevent a read-write remount. */
+ sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
NVolSetErrors(vol);
}
-#endif
+#endif /* NTFS_RW */
/*
* Get the inode for the attribute definitions file and parse the
* attribute definitions.
/**
* ntfs_put_super - called by the vfs to unmount a volume
- * @vfs_sb: vfs superblock of volume to unmount
+ * @sb: vfs superblock of volume to unmount
*
* ntfs_put_super() is called by the VFS (from fs/super.c::do_umount()) when
* the volume is being unmounted (umount system call has been invoked) and it
* releases all inodes and memory belonging to the NTFS specific part of the
* super block.
*/
-static void ntfs_put_super(struct super_block *vfs_sb)
+static void ntfs_put_super(struct super_block *sb)
{
- ntfs_volume *vol = NTFS_SB(vfs_sb);
+ ntfs_volume *vol = NTFS_SB(sb);
ntfs_debug("Entering.");
+#ifdef NTFS_RW
+ /*
+ * Commit all inodes while they are still open in case some of them
+ * cause others to be dirtied.
+ */
+ ntfs_commit_inode(vol->vol_ino);
+
+ /* NTFS 3.0+ specific. */
+ if (vol->major_ver >= 3) {
+ if (vol->secure_ino)
+ ntfs_commit_inode(vol->secure_ino);
+ }
+
+ ntfs_commit_inode(vol->root_ino);
+
+ down_write(&vol->lcnbmp_lock);
+ ntfs_commit_inode(vol->lcnbmp_ino);
+ up_write(&vol->lcnbmp_lock);
+
+ down_write(&vol->mftbmp_lock);
+ ntfs_commit_inode(vol->mftbmp_ino);
+ up_write(&vol->mftbmp_lock);
+
+ if (vol->logfile_ino)
+ ntfs_commit_inode(vol->logfile_ino);
+
+ if (vol->mftmirr_ino)
+ ntfs_commit_inode(vol->mftmirr_ino);
+ ntfs_commit_inode(vol->mft_ino);
+
+ /*
+ * If a read-write mount and no volume errors have occured, mark the
+ * volume clean. Also, re-commit all affected inodes.
+ */
+ if (!(sb->s_flags & MS_RDONLY)) {
+ if (!NVolErrors(vol)) {
+ if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY))
+ ntfs_warning(sb, "Failed to clear dirty bit "
+ "in volume information "
+ "flags. Run chkdsk.");
+ ntfs_commit_inode(vol->vol_ino);
+ ntfs_commit_inode(vol->root_ino);
+ if (vol->mftmirr_ino)
+ ntfs_commit_inode(vol->mftmirr_ino);
+ ntfs_commit_inode(vol->mft_ino);
+ } else {
+ ntfs_warning(sb, "Volume has errors. Leaving volume "
+ "marked dirty. Run chkdsk.");
+ }
+ }
+#endif /* NTFS_RW */
iput(vol->vol_ino);
vol->vol_ino = NULL;
iput(vol->logfile_ino);
vol->logfile_ino = NULL;
}
-
if (vol->mftmirr_ino) {
+ /* Re-commit the mft mirror and mft just in case. */
+ ntfs_commit_inode(vol->mftmirr_ino);
+ ntfs_commit_inode(vol->mft_ino);
iput(vol->mftmirr_ino);
vol->mftmirr_ino = NULL;
}
+ /*
+ * If any dirty inodes are left, throw away all mft data page cache
+ * pages to allow a clean umount. This should never happen any more
+ * due to mft.c::ntfs_mft_writepage() cleaning all the dirty pages as
+ * the underlying mft records are written out and cleaned. If it does,
+ * happen anyway, we want to know...
+ */
+ ntfs_commit_inode(vol->mft_ino);
+ write_inode_now(vol->mft_ino, 1);
+ if (!list_empty(&sb->s_dirty)) {
+ const char *s1, *s2;
+
+ down(&vol->mft_ino->i_sem);
+ truncate_inode_pages(vol->mft_ino->i_mapping, 0);
+ up(&vol->mft_ino->i_sem);
+ write_inode_now(vol->mft_ino, 1);
+ if (!list_empty(&sb->s_dirty)) {
+ static const char *_s1 = "inodes";
+ static const char *_s2 = "";
+ s1 = _s1;
+ s2 = _s2;
+ } else {
+ static const char *_s1 = "mft pages";
+ static const char *_s2 = "They have been thrown "
+ "away. ";
+ s1 = _s1;
+ s2 = _s2;
+ }
+ ntfs_error(sb, "Dirty %s found at umount time. %sYou should "
+ "run chkdsk. Please email "
+ "linux-ntfs-dev@lists.sourceforge.net and say "
+ "that you saw this message. Thank you.", s1,
+ s2);
+ }
#endif /* NTFS_RW */
iput(vol->mft_ino);
vol->upcase_len = 0;
/*
* Decrease the number of mounts and destroy the global default upcase
- * table if necessary. Also decrease the number of upcase users if we
+ * table if necessary. Also decrease the number of upcase users if we
* are a user.
*/
down(&ntfs_lock);
unload_nls(vol->nls_map);
vol->nls_map = NULL;
}
- vfs_sb->s_fs_info = NULL;
+ sb->s_fs_info = NULL;
kfree(vol);
return;
}
#ifdef NTFS_RW
//.dirty_inode = NULL, /* VFS: Called from
// __mark_inode_dirty(). */
- //.write_inode = NULL, /* VFS: Write dirty inode to
- // disk. */
+ .write_inode = ntfs_write_inode, /* VFS: Write dirty inode to
+ disk. */
//.drop_inode = NULL, /* VFS: Called just after the
// inode reference count has
// been decreased to zero.
#ifndef NTFS_RW
sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
#else
- // TODO: For now we enforce no atime and dir atime updates as they are
- // not implemented.
+ if (!(sb->s_flags & MS_NOATIME))
+ ntfs_warning(sb, "Atime updates are not implemented yet. "
+ "Disabling them.");
+ else if (!(sb->s_flags & MS_NODIRATIME))
+ ntfs_warning(sb, "Directory atime updates are not implemented "
+ "yet. Disabling them.");
sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
#endif
/* Allocate a new ntfs_volume and place it in sb->s_fs_info. */
If unsure, say N.
-config NEC98_PARTITION
- bool "NEC PC-9800 partition table support" if PARTITION_ADVANCED
- default y if !PARTITION_ADVANCED && X86_PC9800
- help
- Say Y here if you would like to be able to read the hard disk
- partition table format used by NEC PC-9800 machines.
-
config SGI_PARTITION
bool "SGI partition support" if PARTITION_ADVANCED
default y if !PARTITION_ADVANCED && (SGI_IP22 || SGI_IP27)
#include "ldm.h"
#include "mac.h"
#include "msdos.h"
-#include "nec98.h"
#include "osf.h"
#include "sgi.h"
#include "sun.h"
put_dev_sector(sect);
return 0;
}
+
+ /*
+ * Now that the 55aa signature is present, this is probably
+ * either the boot sector of a FAT filesystem or a DOS-type
+ * partition table. Reject this in case the boot indicator
+ * is not 0 or 0x80.
+ */
p = (struct partition *) (data + 0x1be);
+ for (slot = 1; slot <= 4; slot++, p++) {
+ if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+ put_dev_sector(sect);
+ return 0;
+ }
+ }
+
#ifdef CONFIG_EFI_PARTITION
+ p = (struct partition *) (data + 0x1be);
for (slot = 1 ; slot <= 4 ; slot++, p++) {
/* If this is an EFI GPT disk, msdos should ignore it. */
if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
return 0;
}
}
- p = (struct partition *) (data + 0x1be);
#endif
+ p = (struct partition *) (data + 0x1be);
/*
* Look for partitions in two passes:
};
#ifdef CONFIG_SECURITY
-static ssize_t proc_pid_attr_read(struct file * file, char * buf,
+static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
return count;
}
-static ssize_t proc_pid_attr_write(struct file * file, const char * buf,
+static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
struct inode * inode = file->f_dentry->d_inode;
*/
static unsigned int get_inode_number(void)
{
- unsigned int i, inum = 0;
+ int i, inum = 0;
+ int error;
retry:
if (idr_pre_get(&proc_inum_idr, GFP_KERNEL) == 0)
return 0;
spin_lock(&proc_inum_lock);
- i = idr_get_new(&proc_inum_idr, NULL);
+ error = idr_get_new(&proc_inum_idr, NULL, &i);
spin_unlock(&proc_inum_lock);
-
- if (i == -1)
+ if (error == -EAGAIN)
goto retry;
+ else if (error)
+ return 0;
inum = (i & MAX_ID_MASK) + PROC_DYNAMIC_FIRST;
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
-#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/div64.h>
/* Now we are sure filp is valid */
offset = v1_dqoff(dquot->dq_id);
+ /* Set structure to 0s in case read fails/is after end of file */
+ memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
fs = get_fs();
set_fs(KERNEL_DS);
filp->f_op->read(filp, (char *)&dqblk, sizeof(struct v1_disk_dqblk), &offset);
#define _ALLOC_hashed_formatted_nodes 7
#define _ALLOC_old_way 8
#define _ALLOC_hundredth_slices 9
+#define _ALLOC_dirid_groups 10
+#define _ALLOC_oid_groups 11
+#define _ALLOC_packing_groups 12
#define concentrating_formatted_nodes(s) test_bit(_ALLOC_concentrating_formatted_nodes, &SB_ALLOC_OPTS(s))
#define displacing_large_files(s) test_bit(_ALLOC_displacing_large_files, &SB_ALLOC_OPTS(s))
__wait_on_buffer (bi->bh);
}
- /* If we know that first zero bit is only one or first zero bit is
- closer to the end of bitmap than our start pointer */
- if (bi->first_zero_hint > *beg || bi->free_count == 1)
- *beg = bi->first_zero_hint;
-
while (1) {
cont:
if (bi->free_count < min)
while (--i >= *beg)
reiserfs_test_and_clear_le_bit (i, bi->bh->b_data);
reiserfs_restore_prepared_buffer (s, bi->bh);
- *beg = max(org, (int)bi->first_zero_hint);
+ *beg = org;
/* ... and search again in current block from beginning */
goto cont;
}
}
bi->free_count -= (end - *beg);
-
- /* if search started from zero_hint bit, and zero hint have not
- changed since, then we need to update first_zero_hint */
- if ( bi->first_zero_hint >= *beg)
- /* no point in looking for free bit if there is not any */
- bi->first_zero_hint = (bi->free_count > 0 ) ?
- reiserfs_find_next_zero_le_bit
- ((unsigned long*)(bi->bh->b_data), s->s_blocksize << 3, end) : (s->s_blocksize << 3);
-
journal_mark_dirty (th, s, bi->bh);
/* free block count calculation */
*beg = next;
}
}
- }
+}
+
+static int bmap_hash_id(struct super_block *s, u32 id) {
+ char * hash_in = NULL;
+ unsigned long hash;
+ unsigned bm;
+
+ if (id <= 2) {
+ bm = 1;
+ } else {
+ hash_in = (char *)(&id);
+ hash = keyed_hash(hash_in, 4);
+ bm = hash % SB_BMAP_NR(s);
+ if (!bm)
+ bm = 1;
+ }
+ return bm;
+}
+
+/*
+ * hashes the id and then returns > 0 if the block group for the
+ * corresponding hash is full
+ */
+static inline int block_group_used(struct super_block *s, u32 id) {
+ int bm;
+ bm = bmap_hash_id(s, id);
+ if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100) ) {
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * the packing is returned in disk byte order
+ */
+u32 reiserfs_choose_packing(struct inode *dir) {
+ u32 packing;
+ if (TEST_OPTION(packing_groups, dir->i_sb)) {
+ u32 parent_dir = le32_to_cpu(INODE_PKEY(dir)->k_dir_id);
+ /*
+ * some versions of reiserfsck expect packing locality 1 to be
+ * special
+ */
+ if (parent_dir == 1 || block_group_used(dir->i_sb,parent_dir))
+ packing = INODE_PKEY(dir)->k_objectid;
+ else
+ packing = INODE_PKEY(dir)->k_dir_id;
+ } else
+ packing = INODE_PKEY(dir)->k_objectid;
+ return packing;
+}
/* Tries to find contiguous zero bit window (given size) in given region of
* bitmap and place new blocks there. Returns number of allocated blocks. */
get_bit_address (s, *start, &bm, &off);
get_bit_address (s, finish, &end_bm, &end_off);
- // With this option set first we try to find a bitmap that is at least 10%
- // free, and if that fails, then we fall back to old whole bitmap scanning
+ /* When the bitmap is more than 10% free, anyone can allocate.
+ * When it's less than 10% free, only files that already use the
+ * bitmap are allowed. Once we pass 80% full, this restriction
+ * is lifted.
+ *
+ * We do this so that files that grow later still have space close to
+ * their original allocation. This improves locality, and presumably
+ * performance as a result.
+ *
+ * This is only an allocation policy and does not make up for getting a
+ * bad hint. Decent hinting must be implemented for this to work well.
+ */
if ( TEST_OPTION(skip_busy, s) && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s)/20 ) {
for (;bm < end_bm; bm++, off = 0) {
if ( ( off && (!unfm || (file_block != 0))) || SB_AP_BITMAP(s)[bm].free_count > (s->s_blocksize << 3) / 10 )
"free_block (%s:%lu)[dev:blocknr]: bit already cleared",
reiserfs_bdevname (s), block);
}
- if (offset < apbi[nr].first_zero_hint) {
- apbi[nr].first_zero_hint = offset;
- }
apbi[nr].free_count ++;
journal_mark_dirty (th, s, apbi[nr].bh);
__discard_prealloc(th, ei);
}
}
+
+void reiserfs_init_alloc_options (struct super_block *s)
+{
+ set_bit (_ALLOC_skip_busy, &SB_ALLOC_OPTS(s));
+ set_bit (_ALLOC_dirid_groups, &SB_ALLOC_OPTS(s));
+ set_bit (_ALLOC_packing_groups, &SB_ALLOC_OPTS(s));
+}
+
/* block allocator related options are parsed here */
int reiserfs_parse_alloc_options(struct super_block * s, char * options)
{
continue;
}
+ if (!strcmp(this_char, "dirid_groups")) {
+ SET_OPTION(dirid_groups);
+ continue;
+ }
+ if (!strcmp(this_char, "oid_groups")) {
+ SET_OPTION(oid_groups);
+ continue;
+ }
+ if (!strcmp(this_char, "packing_groups")) {
+ SET_OPTION(packing_groups);
+ continue;
+ }
if (!strcmp(this_char, "hashed_formatted_nodes")) {
SET_OPTION(hashed_formatted_nodes);
continue;
return 1;
}
+ reiserfs_warning (s, "allocator options = [%08x]\n", SB_ALLOC_OPTS(s));
return 0;
}
hint->search_start = hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
}
-static inline void get_left_neighbor(reiserfs_blocknr_hint_t *hint)
+/*
+ * Relocation based on dirid, hashing them into a given bitmap block
+ * files. Formatted nodes are unaffected, a seperate policy covers them
+ */
+static void
+dirid_groups (reiserfs_blocknr_hint_t *hint)
+{
+ unsigned long hash;
+ __u32 dirid = 0;
+ int bm = 0;
+ struct super_block *sb = hint->th->t_super;
+ if (hint->inode)
+ dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
+ else if (hint->formatted_node)
+ dirid = hint->key.k_dir_id;
+
+ if (dirid) {
+ bm = bmap_hash_id(sb, dirid);
+ hash = bm * (sb->s_blocksize << 3);
+ /* give a portion of the block group to metadata */
+ if (hint->inode)
+ hash += sb->s_blocksize/2;
+ hint->search_start = hash;
+ }
+}
+
+/*
+ * Relocation based on oid, hashing them into a given bitmap block
+ * files. Formatted nodes are unaffected, a seperate policy covers them
+ */
+static void
+oid_groups (reiserfs_blocknr_hint_t *hint)
+{
+ if (hint->inode) {
+ unsigned long hash;
+ __u32 oid;
+ __u32 dirid;
+ int bm;
+
+ dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
+
+ /* keep the root dir and it's first set of subdirs close to
+ * the start of the disk
+ */
+ if (dirid <= 2)
+ hash = (hint->inode->i_sb->s_blocksize << 3);
+ else {
+ oid = le32_to_cpu(INODE_PKEY(hint->inode)->k_objectid);
+ bm = bmap_hash_id(hint->inode->i_sb, oid);
+ hash = bm * (hint->inode->i_sb->s_blocksize << 3);
+ }
+ hint->search_start = hash;
+ }
+}
+
+/* returns 1 if it finds an indirect item and gets valid hint info
+ * from it, otherwise 0
+ */
+static int get_left_neighbor(reiserfs_blocknr_hint_t *hint)
{
struct path * path;
struct buffer_head * bh;
struct item_head * ih;
int pos_in_item;
__u32 * item;
+ int ret = 0;
if (!hint->path) /* reiserfs code can call this function w/o pointer to path
* structure supplied; then we rely on supplied search_start */
- return;
+ return 0;
path = hint->path;
bh = get_last_bh(path);
int t=get_block_num(item,pos_in_item);
if (t) {
hint->search_start = t;
+ ret = 1;
break;
}
pos_in_item --;
}
- } else {
- }
+ }
/* does result value fit into specified region? */
- return;
+ return ret;
}
/* should be, if formatted node, then try to put on first part of the device
}
}
-static inline void determine_search_start(reiserfs_blocknr_hint_t *hint,
+static void determine_search_start(reiserfs_blocknr_hint_t *hint,
int amount_needed)
{
struct super_block *s = hint->th->t_super;
+ int unfm_hint;
+
hint->beg = 0;
hint->end = SB_BLOCK_COUNT(s) - 1;
return;
}
- /* attempt to copy a feature from old block allocator code */
- if (TEST_OPTION(old_hashed_relocation, s) && !hint->formatted_node) {
- old_hashed_relocation(hint);
- }
-
/* if none of our special cases is relevant, use the left neighbor in the
tree order of the new node we are allocating for */
if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes,s)) {
- hash_formatted_node(hint);
+ hash_formatted_node(hint);
return;
- }
+ }
- get_left_neighbor(hint);
+ unfm_hint = get_left_neighbor(hint);
/* Mimic old block allocator behaviour, that is if VFS allowed for preallocation,
new blocks are displaced based on directory ID. Also, if suggested search_start
return;
}
- if (TEST_OPTION(old_hashed_relocation, s))
+ /* old_hashed_relocation only works on unformatted */
+ if (!unfm_hint && !hint->formatted_node &&
+ TEST_OPTION(old_hashed_relocation, s))
+ {
old_hashed_relocation(hint);
- if (TEST_OPTION(new_hashed_relocation, s))
+ }
+ /* new_hashed_relocation works with both formatted/unformatted nodes */
+ if ((!unfm_hint || hint->formatted_node) &&
+ TEST_OPTION(new_hashed_relocation, s))
+ {
new_hashed_relocation(hint);
+ }
+ /* dirid grouping works only on unformatted nodes */
+ if (!unfm_hint && !hint->formatted_node && TEST_OPTION(dirid_groups,s))
+ {
+ dirid_groups(hint);
+ }
+
+#ifdef DISPLACE_NEW_PACKING_LOCALITIES
+ if (hint->formatted_node && TEST_OPTION(dirid_groups,s))
+ {
+ dirid_groups(hint);
+ }
+#endif
+
+ /* oid grouping works only on unformatted nodes */
+ if (!unfm_hint && !hint->formatted_node && TEST_OPTION(oid_groups,s))
+ {
+ oid_groups(hint);
+ }
return;
}
static inline int allocate_without_wrapping_disk (reiserfs_blocknr_hint_t * hint,
b_blocknr_t * new_blocknrs,
b_blocknr_t start, b_blocknr_t finish,
+ int min,
int amount_needed, int prealloc_size)
{
int rest = amount_needed;
int nr_allocated;
while (rest > 0 && start <= finish) {
- nr_allocated = scan_bitmap (hint->th, &start, finish, 1,
+ nr_allocated = scan_bitmap (hint->th, &start, finish, min,
rest + prealloc_size, !hint->formatted_node,
hint->block);
struct super_block *s = hint->th->t_super;
b_blocknr_t start = hint->search_start;
b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
- int second_pass = 0;
+ int passno = 0;
int nr_allocated = 0;
+ int bigalloc = 0;
determine_prealloc_size(hint);
if (!hint->formatted_node) {
if (quota_ret)
hint->preallocate=hint->prealloc_size=0;
}
+ /* for unformatted nodes, force large allocations */
+ bigalloc = amount_needed + hint->prealloc_size;
+ /* try to make things even */
+ if (bigalloc & 1 && hint->prealloc_size)
+ bigalloc--;
}
- while((nr_allocated
- += allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish,
- amount_needed - nr_allocated, hint->prealloc_size))
- < amount_needed) {
-
- /* not all blocks were successfully allocated yet*/
- if (second_pass) { /* it was a second pass; we must free all blocks */
+ do {
+ /* in bigalloc mode, nr_allocated should stay zero until
+ * the entire allocation is filled
+ */
+ if (unlikely(bigalloc && nr_allocated)) {
+ reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n",
+ bigalloc, nr_allocated);
+ /* reset things to a sane value */
+ bigalloc = amount_needed - nr_allocated;
+ }
+ /*
+ * try pass 0 and pass 1 looking for a nice big
+ * contiguous allocation. Then reset and look
+ * for anything you can find.
+ */
+ if (passno == 2 && bigalloc) {
+ passno = 0;
+ bigalloc = 0;
+ }
+ switch (passno++) {
+ case 0: /* Search from hint->search_start to end of disk */
+ start = hint->search_start;
+ finish = SB_BLOCK_COUNT(s) - 1;
+ break;
+ case 1: /* Search from hint->beg to hint->search_start */
+ start = hint->beg;
+ finish = hint->search_start;
+ break;
+ case 2: /* Last chance: Search from 0 to hint->beg */
+ start = 0;
+ finish = hint->beg;
+ break;
+ default: /* We've tried searching everywhere, not enough space */
+ /* Free the blocks */
if (!hint->formatted_node) {
#ifdef REISERQUOTA_DEBUG
reiserfs_debug (s, "reiserquota: freeing (nospace) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated, hint->inode->i_uid);
#endif
DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */
}
- while (nr_allocated --)
+ while (nr_allocated --)
reiserfs_free_block(hint->th, hint->inode, new_blocknrs[nr_allocated], !hint->formatted_node);
return NO_DISK_SPACE;
- } else { /* refine search parameters for next pass */
- second_pass = 1;
- finish = start;
- start = 0;
- continue;
}
- }
+ } while ((nr_allocated += allocate_without_wrapping_disk (hint,
+ new_blocknrs + nr_allocated, start, finish,
+ bigalloc ? bigalloc : 1,
+ amount_needed - nr_allocated,
+ hint->prealloc_size))
+ < amount_needed);
if ( !hint->formatted_node &&
amount_needed + hint->prealloc_size >
nr_allocated + REISERFS_I(hint->inode)->i_prealloc_count) {
/* reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos);*/
+ path_to_entry.reada = PATH_READA;
while (1) {
research:
/* search the directory item, containing entry with specified key */
hint.formatted_node = 0; // We are allocating blocks for unformatted node.
/* only preallocate if this is a small write */
- if (blocks_to_allocate <
- REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize)
+ if (REISERFS_I(inode)->i_prealloc_count ||
+ (!(write_bytes & (inode->i_sb->s_blocksize -1)) &&
+ blocks_to_allocate <
+ REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
hint.preallocate = 1;
else
hint.preallocate = 0;
-
/* Call block allocator to allocate blocks */
res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
if ( res != CARRY_ON ) {
// the inode.
//
pathrelse(&path);
+ /*
+ * cleanup prellocation from previous writes
+ * if this is a partial block write
+ */
+ if (write_bytes & (inode->i_sb->s_blocksize -1))
+ reiserfs_discard_prealloc(th, inode);
reiserfs_write_unlock(inode->i_sb);
// go through all the pages/buffers and map the buffers to newly allocated
struct buffer_head *bh, *head;
unsigned long i_size_index = inode->i_size >> PAGE_CACHE_SHIFT;
int new;
+ int logit = reiserfs_file_data_log(inode);
+ struct super_block *s = inode->i_sb;
+ int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
+ struct reiserfs_transaction_handle th;
+ th.t_trans_id = 0;
blocksize = 1 << inode->i_blkbits;
+ if (logit) {
+ reiserfs_write_lock(s);
+ journal_begin(&th, s, bh_per_page + 1);
+ reiserfs_update_inode_transaction(inode);
+ }
for(bh = head = page_buffers(page), block_start = 0;
bh != head || !block_start;
block_start=block_end, bh = bh->b_this_page)
partial = 1;
} else {
set_buffer_uptodate(bh);
- if (!buffer_dirty(bh)) {
+ if (logit) {
+ reiserfs_prepare_for_journal(s, bh, 1);
+ journal_mark_dirty(&th, s, bh);
+ } else if (!buffer_dirty(bh)) {
mark_buffer_dirty(bh);
/* do data=ordered on any page past the end
* of file and any buffer marked BH_New.
}
}
}
-
+ if (logit) {
+ journal_end(&th, s, bh_per_page + 1);
+ reiserfs_write_unlock(s);
+ }
/*
* If this is a partial write which happened to make all buffers
* uptodate then we can optimize away a bogus readpage() for
journal_end(&th, th.t_super, th.t_blocks_allocated);
reiserfs_write_unlock(inode->i_sb);
}
+
if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
res = generic_osync_inode(inode, file->f_mapping, OSYNC_METADATA|OSYNC_DATA);
sb = dir->i_sb;
/* item head of new item */
- ih.ih_key.k_dir_id = INODE_PKEY (dir)->k_objectid;
+ ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
ih.ih_key.k_objectid = cpu_to_le32 (reiserfs_get_unused_objectid (th));
if (!ih.ih_key.k_objectid) {
err = -ENOMEM;
err = -EEXIST;
goto out_bad_inode;
}
-
if (old_format_only (sb)) {
if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
pathrelse (&path_to_key);
struct buffer_head *head, *bh;
int partial = 0 ;
int nr = 0;
+ int checked = PageChecked(page);
+ struct reiserfs_transaction_handle th;
+ struct super_block *s = inode->i_sb;
+ int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
+ th.t_trans_id = 0;
/* The page dirty bit is cleared before writepage is called, which
* means we have to tell create_empty_buffers to make dirty buffers
* in the BH_Uptodate is just a sanity check.
*/
if (!page_has_buffers(page)) {
- create_empty_buffers(page, inode->i_sb->s_blocksize,
+ create_empty_buffers(page, s->s_blocksize,
(1 << BH_Dirty) | (1 << BH_Uptodate));
}
head = page_buffers(page) ;
kunmap_atomic(kaddr, KM_USER0) ;
}
bh = head ;
- block = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits) ;
+ block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ;
/* first map all the buffers, logging any direct items we find */
do {
- if (buffer_dirty(bh) && (!buffer_mapped(bh) ||
+ if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
(buffer_mapped(bh) && bh->b_blocknr == 0))) {
/* not mapped yet, or it points to a direct item, search
* the btree for the mapping info, and log any direct
block++;
} while(bh != head) ;
+ /*
+ * we start the transaction after map_block_for_writepage,
+ * because it can create holes in the file (an unbounded operation).
+ * starting it here, we can make a reliable estimate for how many
+ * blocks we're going to log
+ */
+ if (checked) {
+ ClearPageChecked(page);
+ reiserfs_write_lock(s);
+ journal_begin(&th, s, bh_per_page + 1);
+ reiserfs_update_inode_transaction(inode);
+ }
/* now go through and lock any dirty buffers on the page */
do {
get_bh(bh);
if (buffer_mapped(bh) && bh->b_blocknr == 0)
continue;
+ if (checked) {
+ reiserfs_prepare_for_journal(s, bh, 1);
+ journal_mark_dirty(&th, s, bh);
+ continue;
+ }
/* from this point on, we know the buffer is mapped to a
* real block and not a direct item
*/
}
} while((bh = bh->b_this_page) != head);
+ if (checked) {
+ journal_end(&th, s, bh_per_page + 1);
+ reiserfs_write_unlock(s);
+ }
BUG_ON(PageWriteback(page));
set_page_writeback(page);
unlock_page(page);
/* the page is locked, and the only places that log a data buffer
* also lock the page.
*/
-#if 0
if (reiserfs_file_data_log(inode)) {
- /* very conservative, leave the buffer pinned if anyone might need it.
- ** this should be changed to drop the buffer if it is only in the
- ** current transaction
- */
+ /*
+ * very conservative, leave the buffer pinned if
+ * anyone might need it.
+ */
if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
ret = 0 ;
}
} else
-#endif
if (buffer_dirty(bh) || buffer_locked(bh)) {
struct reiserfs_journal_list *jl;
struct reiserfs_jh *jh = bh->b_private;
int ret = 1;
BUG_ON(!PageLocked(page));
+
+ if (offset == 0)
+ ClearPageChecked(page);
+
if (!page_has_buffers(page))
goto out;
return ret;
}
+static int reiserfs_set_page_dirty(struct page *page) {
+ struct inode *inode = page->mapping->host;
+ if (reiserfs_file_data_log(inode)) {
+ SetPageChecked(page);
+ return __set_page_dirty_nobuffers(page);
+ }
+ return __set_page_dirty_buffers(page);
+}
+
/*
* Returns 1 if the page's buffers were dropped. The page is locked.
*
struct buffer_head *bh ;
int ret = 1 ;
+ WARN_ON(PageChecked(page));
spin_lock(&j->j_dirty_buffers_lock) ;
head = page_buffers(page) ;
bh = head ;
.prepare_write = reiserfs_prepare_write,
.commit_write = reiserfs_commit_write,
.bmap = reiserfs_aop_bmap,
- .direct_IO = reiserfs_direct_IO
+ .direct_IO = reiserfs_direct_IO,
+ .set_page_dirty = reiserfs_set_page_dirty,
} ;
up(&jl->j_commit_lock);
put_jl:
put_journal_list(s, jl);
-
return 0 ;
}
unsigned long cur_len;
int ret;
int i;
+ int limit = 256;
struct reiserfs_journal_list *tjl;
struct reiserfs_journal_list *flush_jl;
unsigned long trans_id;
flush_jl = tjl = jl;
- /* flush for 256 transactions or 256 blocks, whichever comes first */
- for(i = 0 ; i < 256 && len < 256 ; i++) {
+ /* in data logging mode, try harder to flush a lot of blocks */
+ if (reiserfs_data_log(s))
+ limit = 1024;
+ /* flush for 256 transactions or limit blocks, whichever comes first */
+ for(i = 0 ; i < 256 && len < limit ; i++) {
if (atomic_read(&tjl->j_commit_left) ||
tjl->j_trans_id < jl->j_trans_id) {
break;
/* copy all the real blocks into log area. dirty log blocks */
if (test_bit(BH_JDirty, &cn->bh->b_state)) {
struct buffer_head *tmp_bh ;
+ char *addr;
+ struct page *page;
tmp_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
set_buffer_uptodate(tmp_bh);
- memcpy(tmp_bh->b_data, cn->bh->b_data, cn->bh->b_size) ;
+ page = cn->bh->b_page;
+ addr = kmap(page);
+ memcpy(tmp_bh->b_data, addr + offset_in_page(cn->bh->b_data),
+ cn->bh->b_size);
+ kunmap(page);
mark_buffer_dirty(tmp_bh);
jindex++ ;
set_bit(BH_JDirty_wait, &(cn->bh->b_state)) ;
-#ifdef SEARCH_BY_KEY_READA
+#define SEARCH_BY_KEY_READA 16
/* The function is NOT SCHEDULE-SAFE! */
-static void search_by_key_reada (struct super_block * s, int blocknr)
+static void search_by_key_reada (struct super_block * s,
+ struct buffer_head **bh,
+ unsigned long *b, int num)
{
- struct buffer_head * bh;
-
- if (blocknr == 0)
- return;
-
- bh = sb_getblk (s, blocknr);
+ int i,j;
- if (!buffer_uptodate (bh)) {
- ll_rw_block (READA, 1, &bh);
+ for (i = 0 ; i < num ; i++) {
+ bh[i] = sb_getblk (s, b[i]);
+ }
+ for (j = 0 ; j < i ; j++) {
+ /*
+ * note, this needs attention if we are getting rid of the BKL
+ * you have to make sure the prepared bit isn't set on this buffer
+ */
+ if (!buffer_uptodate(bh[j]))
+ ll_rw_block(READA, 1, bh + j);
+ brelse(bh[j]);
}
- bh->b_count --;
}
-#endif
-
/**************************************************************************
* Algorithm SearchByKey *
* look for item in the Disk S+Tree by its key *
int n_node_level, n_retval;
int right_neighbor_of_leaf_node;
int fs_gen;
+ struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
+ unsigned long reada_blocks[SEARCH_BY_KEY_READA];
+ int reada_count = 0;
#ifdef CONFIG_REISERFS_CHECK
int n_repeat_counter = 0;
p_s_last_element = PATH_OFFSET_PELEMENT(p_s_search_path, ++p_s_search_path->path_length);
fs_gen = get_generation (p_s_sb);
-#ifdef SEARCH_BY_KEY_READA
- /* schedule read of right neighbor */
- search_by_key_reada (p_s_sb, right_neighbor_of_leaf_node);
-#endif
-
/* Read the next tree node, and set the last element in the path to
have a pointer to it. */
- if ( ! (p_s_bh = p_s_last_element->pe_buffer =
- sb_bread(p_s_sb, n_block_number)) ) {
+ if ((p_s_bh = p_s_last_element->pe_buffer =
+ sb_getblk(p_s_sb, n_block_number)) ) {
+ if (!buffer_uptodate(p_s_bh) && reada_count > 1) {
+ search_by_key_reada (p_s_sb, reada_bh,
+ reada_blocks, reada_count);
+ }
+ ll_rw_block(READ, 1, &p_s_bh);
+ wait_on_buffer(p_s_bh);
+ if (!buffer_uptodate(p_s_bh))
+ goto io_error;
+ } else {
+io_error:
p_s_search_path->path_length --;
pathrelse(p_s_search_path);
return IO_ERROR;
}
+ reada_count = 0;
if (expected_level == -1)
expected_level = SB_TREE_HEIGHT (p_s_sb);
expected_level --;
position in the node. */
n_block_number = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position);
-#ifdef SEARCH_BY_KEY_READA
- /* if we are going to read leaf node, then calculate its right neighbor if possible */
- if (n_node_level == DISK_LEAF_NODE_LEVEL + 1 && p_s_last_element->pe_position < B_NR_ITEMS (p_s_bh))
- right_neighbor_of_leaf_node = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position + 1);
-#endif
+ /* if we are going to read leaf nodes, try for read ahead as well */
+ if ((p_s_search_path->reada & PATH_READA) &&
+ n_node_level == DISK_LEAF_NODE_LEVEL + 1)
+ {
+ int pos = p_s_last_element->pe_position;
+ int limit = B_NR_ITEMS(p_s_bh);
+ struct key *le_key;
+
+ if (p_s_search_path->reada & PATH_READA_BACK)
+ limit = 0;
+ while(reada_count < SEARCH_BY_KEY_READA) {
+ if (pos == limit)
+ break;
+ reada_blocks[reada_count++] = B_N_CHILD_NUM(p_s_bh, pos);
+ if (p_s_search_path->reada & PATH_READA_BACK)
+ pos--;
+ else
+ pos++;
+
+ /*
+ * check to make sure we're in the same object
+ */
+ le_key = B_N_PDELIM_KEY(p_s_bh, pos);
+ if (le32_to_cpu(le_key->k_objectid) !=
+ p_s_key->on_disk_key.k_objectid)
+ {
+ break;
+ }
+ }
+ }
}
}
reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
}
+static void
+unmap_buffers(struct page *page, loff_t pos) {
+ struct buffer_head *bh ;
+ struct buffer_head *head ;
+ struct buffer_head *next ;
+ unsigned long tail_index ;
+ unsigned long cur_index ;
+
+ if (page) {
+ if (page_has_buffers(page)) {
+ tail_index = pos & (PAGE_CACHE_SIZE - 1) ;
+ cur_index = 0 ;
+ head = page_buffers(page) ;
+ bh = head ;
+ do {
+ next = bh->b_this_page ;
+
+ /* we want to unmap the buffers that contain the tail, and
+ ** all the buffers after it (since the tail must be at the
+ ** end of the file). We don't want to unmap file data
+ ** before the tail, since it might be dirty and waiting to
+ ** reach disk
+ */
+ cur_index += bh->b_size ;
+ if (cur_index > tail_index) {
+ reiserfs_unmap_buffer(bh) ;
+ }
+ bh = next ;
+ } while (bh != head) ;
+ if ( PAGE_SIZE == bh->b_size ) {
+ clear_page_dirty(page);
+ }
+ }
+ }
+}
static int maybe_indirect_to_direct (struct reiserfs_transaction_handle *th,
struct inode * p_s_inode,
char c_mode; /* Mode of the balance. */
int retval2 = -1;
int quota_cut_bytes;
-
+ loff_t tail_pos = 0;
init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path, n_cut_size);
set_cpu_key_k_type (p_s_item_key, TYPE_INDIRECT);
p_s_item_key->key_length = 4;
n_new_file_size -= (n_new_file_size & (p_s_sb->s_blocksize - 1));
+ tail_pos = n_new_file_size;
set_cpu_key_k_offset (p_s_item_key, n_new_file_size + 1);
if ( search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND ){
print_block (PATH_PLAST_BUFFER (p_s_path), 3, PATH_LAST_POSITION (p_s_path) - 1, PATH_LAST_POSITION (p_s_path) + 1);
if ( n_is_inode_locked ) {
/* we've done an indirect->direct conversion. when the data block
** was freed, it was removed from the list of blocks that must
- ** be flushed before the transaction commits, so we don't need to
- ** deal with it here.
+ ** be flushed before the transaction commits, make sure to
+ ** unmap and invalidate it
*/
+ unmap_buffers(page, tail_pos);
REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
}
#ifdef REISERQUOTA_DEBUG
space, this file would have this file size */
n_file_size = offset + bytes - 1;
}
+ /*
+ * are we doing a full truncate or delete, if so
+ * kick in the reada code
+ */
+ if (n_new_file_size == 0)
+ s_search_path.reada = PATH_READA | PATH_READA_BACK;
if ( n_file_size == 0 || n_file_size < n_new_file_size ) {
goto update_and_out ;
REISERFS_I(inode)->i_acl_default = NULL;
}
-
struct super_operations reiserfs_sops =
{
.alloc_inode = reiserfs_alloc_inode,
reiserfs_warning (s, "head of option \"%s\" is only correct", opt->option_name);
return -1;
}
-
+
/* move to the argument, or to next option if argument is not required */
p ++;
memset (sbi, 0, sizeof (struct reiserfs_sb_info));
/* Set default values for options: non-aggressive tails */
REISERFS_SB(s)->s_mount_opt = ( 1 << REISERFS_SMALLTAIL );
- /* default block allocator option: skip_busy */
- REISERFS_SB(s)->s_alloc_options.bits = ( 1 << 5);
- /* If file grew past 4 blocks, start preallocation blocks for it. */
- REISERFS_SB(s)->s_alloc_options.preallocmin = 4;
+ /* no preallocation minimum, be smart in
+ reiserfs_file_write instead */
+ REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
/* Preallocate by 16 blocks (17-1) at once */
REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
/* Initialize the rwsem for xattr dir */
init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
+ /* setup default block allocator options */
+ reiserfs_init_alloc_options(s);
+
jdev_name = NULL;
if (reiserfs_parse_options (s, (char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name, &commit_max_age) == 0) {
goto error;
unlock_buffer(bh) ;
}
-static void
-unmap_buffers(struct page *page, loff_t pos) {
- struct buffer_head *bh ;
- struct buffer_head *head ;
- struct buffer_head *next ;
- unsigned long tail_index ;
- unsigned long cur_index ;
-
- if (page) {
- if (page_has_buffers(page)) {
- tail_index = pos & (PAGE_CACHE_SIZE - 1) ;
- cur_index = 0 ;
- head = page_buffers(page) ;
- bh = head ;
- do {
- next = bh->b_this_page ;
-
- /* we want to unmap the buffers that contain the tail, and
- ** all the buffers after it (since the tail must be at the
- ** end of the file). We don't want to unmap file data
- ** before the tail, since it might be dirty and waiting to
- ** reach disk
- */
- cur_index += bh->b_size ;
- if (cur_index > tail_index) {
- reiserfs_unmap_buffer(bh) ;
- }
- bh = next ;
- } while (bh != head) ;
- if ( PAGE_SIZE == bh->b_size ) {
- clear_page_dirty(page);
- }
- }
- }
-}
-
/* this first locks inode (neither reads nor sync are permitted),
reads tail through page cache, insert direct item. When direct item
inserted successfully inode is left locked. Return value is always
}
kunmap(page) ;
- /* this will invalidate all the buffers in the page after
- ** pos1
- */
- unmap_buffers(page, pos1) ;
-
/* make sure to get the i_blocks changes from reiserfs_insert_item */
reiserfs_update_sd(th, p_s_inode);
}
static ssize_t
-smb_file_read(struct file * file, char * buf, size_t count, loff_t *ppos)
+smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos)
{
struct dentry * dentry = file->f_dentry;
ssize_t status;
* Write to a file (through the page cache).
*/
static ssize_t
-smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
struct dentry * dentry = file->f_dentry;
ssize_t result;
uid_t uid32;
case SMB_IOC_GETMOUNTUID:
SET_UID(uid16, server->mnt->mounted_uid);
- result = put_user(uid16, (uid16_t *) arg);
+ result = put_user(uid16, (uid16_t __user *) arg);
break;
case SMB_IOC_GETMOUNTUID32:
SET_UID(uid32, server->mnt->mounted_uid);
- result = put_user(uid32, (uid_t *) arg);
+ result = put_user(uid32, (uid_t __user *) arg);
break;
case SMB_IOC_NEWCONN:
}
result = -EFAULT;
- if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
+ if (!copy_from_user(&opt, (void __user *)arg, sizeof(opt)))
result = smb_newconn(server, &opt);
break;
default:
/*
* called when there's work for us to do
*/
-void smbiod_wake_up()
+void smbiod_wake_up(void)
{
if (smbiod_state == SMBIOD_DEAD)
return;
tmp.st_ino = stat->ino;
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
+ if (tmp.st_nlink != stat->nlink)
+ return -EOVERFLOW;
SET_UID(tmp.st_uid, stat->uid);
SET_GID(tmp.st_gid, stat->gid);
tmp.st_rdev = old_encode_dev(stat->rdev);
tmp.st_ino = stat->ino;
tmp.st_mode = stat->mode;
tmp.st_nlink = stat->nlink;
+ if (tmp.st_nlink != stat->nlink)
+ return -EOVERFLOW;
SET_UID(tmp.st_uid, stat->uid);
SET_GID(tmp.st_gid, stat->gid);
#if BITS_PER_LONG == 32
int set_anon_super(struct super_block *s, void *data)
{
int dev;
+ int error;
- spin_lock(&unnamed_dev_lock);
- if (idr_pre_get(&unnamed_dev_idr, GFP_ATOMIC) == 0) {
- spin_unlock(&unnamed_dev_lock);
+ retry:
+ if (idr_pre_get(&unnamed_dev_idr, GFP_ATOMIC) == 0)
return -ENOMEM;
- }
- dev = idr_get_new(&unnamed_dev_idr, NULL);
+ spin_lock(&unnamed_dev_lock);
+ error = idr_get_new(&unnamed_dev_idr, NULL, &dev);
spin_unlock(&unnamed_dev_lock);
+ if (error == -EAGAIN)
+ /* We raced and lost with another CPU. */
+ goto retry;
+ else if (error)
+ return -EAGAIN;
if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) {
spin_lock(&unnamed_dev_lock);
return -ENOMEM;
count = ops->show(kobj,attr,buffer->page);
+ BUG_ON(count > PAGE_SIZE);
if (count >= 0)
buffer->count = count;
else
* July 21, 1997 - Andrew E. Mileski
* Adapted from OSTA-UDF(tm) 1.50 standard.
*/
-extern uint16_t
+uint16_t
udf_crc(uint8_t *data, uint32_t size, uint16_t crc)
{
while (size--)
.commit_write = udf_adinicb_commit_write,
};
-static ssize_t udf_file_write(struct file * file, const char * buf,
+static ssize_t udf_file_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
ssize_t retval;
switch (cmd)
{
case UDF_GETVOLIDENT:
- return copy_to_user((char *)arg,
+ return copy_to_user((char __user *)arg,
UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
case UDF_RELOCATE_BLOCKS:
{
long old, new;
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
- if (get_user(old, (long *)arg)) return -EFAULT;
+ if (get_user(old, (long __user *)arg)) return -EFAULT;
if ((result = udf_relocate_blocks(inode->i_sb,
old, &new)) == 0)
- result = put_user(new, (long *)arg);
+ result = put_user(new, (long __user *)arg);
return result;
}
case UDF_GETEASIZE:
- result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
+ result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg);
break;
case UDF_GETEABLOCK:
- result = copy_to_user((char *)arg, UDF_I_DATA(inode),
+ result = copy_to_user((char __user *)arg, UDF_I_DATA(inode),
UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
break;
}
#include "udf_i.h"
#include "udf_sb.h"
-extern struct buffer_head *
+struct buffer_head *
udf_tgetblk(struct super_block *sb, int block)
{
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
return sb_getblk(sb, block);
}
-extern struct buffer_head *
+struct buffer_head *
udf_tread(struct super_block *sb, int block)
{
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV))
return sb_bread(sb, block);
}
-extern struct genericFormat *
+struct genericFormat *
udf_add_extendedattr(struct inode * inode, uint32_t size, uint32_t type,
uint8_t loc)
{
return NULL;
}
-extern struct genericFormat *
+struct genericFormat *
udf_get_extendedattr(struct inode *inode, uint32_t type, uint8_t subtype)
{
struct genericFormat *gaf;
* July 1, 1997 - Andrew E. Mileski
* Written, tested, and released.
*/
-extern struct buffer_head *
+struct buffer_head *
udf_read_tagged(struct super_block *sb, uint32_t block, uint32_t location, uint16_t *ident)
{
tag *tag_p;
return NULL;
}
-extern struct buffer_head *
+struct buffer_head *
udf_read_ptagged(struct super_block *sb, lb_addr loc, uint32_t offset, uint16_t *ident)
{
return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
/* ACPI PCI Interrupt Link (pci_link.c) */
-int acpi_pci_link_check (void);
+int acpi_irq_penalty_init (void);
int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low);
/* ACPI PCI Interrupt Routing (pci_irq.c) */
#define RLIMIT_AS 7 /* address space limit(?) */
#define RLIMIT_NPROC 8 /* max number of processes */
#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */
-#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned. Fine, it's unsigned, but
{INR_OPEN, INR_OPEN}, /* RLIMIT_NOFILE */ \
{LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \
{LONG_MAX, LONG_MAX}, /* RLIMIT_NPROC */ \
- {PAGE_SIZE,PAGE_SIZE}, /* RLIMIT_MEMLOCK */ \
- {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \
+ {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \
+ {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \
+ {MAX_SIGPENDING, MAX_SIGPENDING}, /* RLIMIT_SIGPENDING */ \
+ {MQ_BYTES_MAX, MQ_BYTES_MAX}, /* RLIMIT_MSGQUEUE */ \
}
#endif /* __KERNEL__ */
#define writew(v,b) __writew(v,b)
#define writel(v,b) __writel(v,b)
-#define __arch_ioremap(cookie,sz,c) ((void *)(cookie))
+#define __arch_ioremap(cookie,sz,c,a) ((void *)(cookie))
#define __arch_iounmap(cookie) do { } while (0)
#endif
const char *irq_stat = (char *)0xff000000;
/* disable clock switching */
- asm volatile ("mcr%? p15, 0, ip, c15, c2, 2");
+ asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
/* wait for an interrupt to occur */
while (!*irq_stat);
/* enable clock switching */
- asm volatile ("mcr%? p15, 0, ip, c15, c1, 2");
+ asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
}
#define arch_reset(mode) cpu_reset(0x80000000)
* This is therefore not used to calculate the
* divisor.
*/
-//#define CLOCK_TICK_RATE 2000000
+#define CLOCK_TICK_RATE 47894000
*/
static void puts(const char *s)
{
- __asm__ __volatile__("
- ldrb %0, [%2], #1
- teq %0, #0
- beq 3f
-1: strb %0, [%3]
-2: ldrb %1, [%3, #0x14]
- and %1, %1, #0x60
- teq %1, #0x60
- bne 2b
- teq %0, #'\n'
- moveq %0, #'\r'
- beq 1b
- ldrb %0, [%2], #1
- teq %0, #0
- bne 1b
-3: ldrb %1, [%3, #0x14]
- and %1, %1, #0x60
- teq %1, #0x60
- bne 3b
- " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
+ __asm__ __volatile__(
+ "ldrb %0, [%2], #1\n"
+" teq %0, #0\n"
+" beq 3f\n"
+"1: strb %0, [%3]\n"
+"2: ldrb %1, [%3, #0x14]\n"
+" and %1, %1, #0x60\n"
+" teq %1, #0x60\n"
+" bne 2b\n"
+" teq %0, #'\n'\n"
+" moveq %0, #'\r'\n"
+" beq 1b\n"
+" ldrb %0, [%2], #1\n"
+" teq %0, #0\n"
+" bne 1b\n"
+"3: ldrb %1, [%3, #0x14]\n"
+" and %1, %1, #0x60\n"
+" teq %1, #0x60\n"
+" bne 3b"
+ : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
}
/*
struct device;
-void impd1_set_vco(struct device *dev, int vconr, unsigned long period);
void impd1_tweak_control(struct device *dev, u32 mask, u32 val);
# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
# define __REG(x) __REGP(io_p2v(x))
typedef struct { volatile u16 offset[4096]; } __regbase16;
-# define __REGP16(x) ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>2]
+# define __REGP16(x) ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>1]
# define __REG16(x) __REGP16(io_p2v(x))
typedef struct { volatile u8 offset[4096]; } __regbase8;
-# define __REGP8(x) ((__regbase8 *)((x)&~4095))->offset[((x)&4095)>>2]
+# define __REGP8(x) ((__regbase8 *)((x)&~4095))->offset[(x)&4095]
# define __REG8(x) __REGP8(io_p2v(x))
#endif
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
+ *
+ * Refer to <file:Documentation/arm/Sharp-LH/SDRAM> for more information.
+ *
*/
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-
-#define BANKS_PER_NODE 1 /* Define as either 1 or 2 */
-
/*
* Physical DRAM offset.
*/
#define __bus_to_virt(x) __phys_to_virt(x)
#ifdef CONFIG_DISCONTIGMEM
-/*
- * Because of the wide memory address space between physical RAM
- * banks, it's convenient to use Linux's NUMA support to represent our
- * memory map. Assuming all memory nodes have equal access
- * characteristics, we then have a generic discontiguous memory setup.
- *
- * Of course, all this isn't mandatory for implementations with only
- * one used memory bank. For those, simply undefine
- * CONFIG_DISCONTIGMEM. However, keep in mind that a featurefull
- * system will need more than 4MiB of RAM.
- *
- * The contiguous memory blocks are small enough that it pays to
- * aggregate two banks into one node. Setting BANKS_PER_NODE to 2
- * puts pairs of banks into a node.
- *
- * A typical layout would start like this:
- *
- * node 0: 0xc0000000
- * 0xc1000000
- * node 1: 0xc4000000
- * 0xc5000000
- * node 2: 0xc8000000
- * 0xc9000000
- *
- * The proximity of the pairs of blocks makes it feasible to combine them.
- *
- */
/*
* Given a kernel address, find the home node of the underlying memory.
*/
-#if BANKS_PER_NODE==1
-#define KVADDR_TO_NID(addr) \
+# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
+# define KVADDR_TO_NID(addr) \
( ((((unsigned long) (addr) - PAGE_OFFSET) >> 24) & 1)\
| ((((unsigned long) (addr) - PAGE_OFFSET) >> 25) & ~1))
-#else /* 2 banks per node */
-#define KVADDR_TO_NID(addr) \
- ((unsigned long) (addr) - PAGE_OFFSET) >> 26)
-#endif
+# else /* 2 banks per node */
+# define KVADDR_TO_NID(addr) \
+ (((unsigned long) (addr) - PAGE_OFFSET) >> 26)
+# endif
/*
* Given a page frame number, convert it to a node id.
*/
-#if BANKS_PER_NODE==1
-#define PFN_TO_NID(pfn) \
+# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
+# define PFN_TO_NID(pfn) \
(((((pfn) - PHYS_PFN_OFFSET) >> (24 - PAGE_SHIFT)) & 1)\
| ((((pfn) - PHYS_PFN_OFFSET) >> (25 - PAGE_SHIFT)) & ~1))
-#else /* 2 banks per node */
-#define PFN_TO_NID(addr) \
+# else /* 2 banks per node */
+# define PFN_TO_NID(pfn) \
(((pfn) - PHYS_PFN_OFFSET) >> (26 - PAGE_SHIFT))
#endif
* Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
* and return the mem_map of that node.
*/
-#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
+# define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
/*
* Given a page frame number, find the owning node of the memory
* and return the mem_map of that node.
*/
-#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
+# define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
/*
* Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
* node's mem_map.
*/
-#if BANKS_PER_NODE==1
-#define LOCAL_MAP_NR(addr) \
+# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
+# define LOCAL_MAP_NR(addr) \
(((unsigned long)(addr) & 0x003fffff) >> PAGE_SHIFT)
-#else /* 2 banks per node */
-#define LOCAL_MAP_NR(addr) \
+# else /* 2 banks per node */
+# define LOCAL_MAP_NR(addr) \
(((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT)
-#endif
+# endif
#else
-#define PFN_TO_NID(addr) (0)
+# define PFN_TO_NID(addr) (0)
#endif
* OMAP-1510 FPGA
* ---------------------------------------------------------------------------
*/
-#define OMAP1510P1_FPGA_BASE 0xE8000000 /* Virtual */
-#define OMAP1510P1_FPGA_SIZE SZ_4K
-#define OMAP1510P1_FPGA_START 0x08000000 /* Physical */
+#define OMAP1510_FPGA_BASE 0xE8000000 /* Virtual */
+#define OMAP1510_FPGA_SIZE SZ_4K
+#define OMAP1510_FPGA_START 0x08000000 /* Physical */
/* Revision */
-#define OMAP1510P1_FPGA_REV_LOW (OMAP1510P1_FPGA_BASE + 0x0)
-#define OMAP1510P1_FPGA_REV_HIGH (OMAP1510P1_FPGA_BASE + 0x1)
+#define OMAP1510_FPGA_REV_LOW (OMAP1510_FPGA_BASE + 0x0)
+#define OMAP1510_FPGA_REV_HIGH (OMAP1510_FPGA_BASE + 0x1)
-#define OMAP1510P1_FPGA_LCD_PANEL_CONTROL (OMAP1510P1_FPGA_BASE + 0x2)
-#define OMAP1510P1_FPGA_LED_DIGIT (OMAP1510P1_FPGA_BASE + 0x3)
-#define INNOVATOR_FPGA_HID_SPI (OMAP1510P1_FPGA_BASE + 0x4)
-#define OMAP1510P1_FPGA_POWER (OMAP1510P1_FPGA_BASE + 0x5)
+#define OMAP1510_FPGA_LCD_PANEL_CONTROL (OMAP1510_FPGA_BASE + 0x2)
+#define OMAP1510_FPGA_LED_DIGIT (OMAP1510_FPGA_BASE + 0x3)
+#define INNOVATOR_FPGA_HID_SPI (OMAP1510_FPGA_BASE + 0x4)
+#define OMAP1510_FPGA_POWER (OMAP1510_FPGA_BASE + 0x5)
/* Interrupt status */
-#define OMAP1510P1_FPGA_ISR_LO (OMAP1510P1_FPGA_BASE + 0x6)
-#define OMAP1510P1_FPGA_ISR_HI (OMAP1510P1_FPGA_BASE + 0x7)
+#define OMAP1510_FPGA_ISR_LO (OMAP1510_FPGA_BASE + 0x6)
+#define OMAP1510_FPGA_ISR_HI (OMAP1510_FPGA_BASE + 0x7)
/* Interrupt mask */
-#define OMAP1510P1_FPGA_IMR_LO (OMAP1510P1_FPGA_BASE + 0x8)
-#define OMAP1510P1_FPGA_IMR_HI (OMAP1510P1_FPGA_BASE + 0x9)
+#define OMAP1510_FPGA_IMR_LO (OMAP1510_FPGA_BASE + 0x8)
+#define OMAP1510_FPGA_IMR_HI (OMAP1510_FPGA_BASE + 0x9)
/* Reset registers */
-#define OMAP1510P1_FPGA_HOST_RESET (OMAP1510P1_FPGA_BASE + 0xa)
-#define OMAP1510P1_FPGA_RST (OMAP1510P1_FPGA_BASE + 0xb)
-
-#define OMAP1510P1_FPGA_AUDIO (OMAP1510P1_FPGA_BASE + 0xc)
-#define OMAP1510P1_FPGA_DIP (OMAP1510P1_FPGA_BASE + 0xe)
-#define OMAP1510P1_FPGA_FPGA_IO (OMAP1510P1_FPGA_BASE + 0xf)
-#define OMAP1510P1_FPGA_UART1 (OMAP1510P1_FPGA_BASE + 0x14)
-#define OMAP1510P1_FPGA_UART2 (OMAP1510P1_FPGA_BASE + 0x15)
-#define OMAP1510P1_FPGA_OMAP1510_STATUS (OMAP1510P1_FPGA_BASE + 0x16)
-#define OMAP1510P1_FPGA_BOARD_REV (OMAP1510P1_FPGA_BASE + 0x18)
-#define OMAP1510P1_PPT_DATA (OMAP1510P1_FPGA_BASE + 0x100)
-#define OMAP1510P1_PPT_STATUS (OMAP1510P1_FPGA_BASE + 0x101)
-#define OMAP1510P1_PPT_CONTROL (OMAP1510P1_FPGA_BASE + 0x102)
-
-#define OMAP1510P1_FPGA_TOUCHSCREEN (OMAP1510P1_FPGA_BASE + 0x204)
-
-#define INNOVATOR_FPGA_INFO (OMAP1510P1_FPGA_BASE + 0x205)
-#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510P1_FPGA_BASE + 0x206)
-#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510P1_FPGA_BASE + 0x207)
-#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510P1_FPGA_BASE + 0x208)
-#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510P1_FPGA_BASE + 0x209)
-#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510P1_FPGA_BASE + 0x20a)
-#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510P1_FPGA_BASE + 0x20b)
-#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510P1_FPGA_BASE + 0x20c)
-#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510P1_FPGA_BASE + 0x20d)
-#define INNOVATOR_FPGA_ISR2 (OMAP1510P1_FPGA_BASE + 0x20e)
-#define INNOVATOR_FPGA_IMR2 (OMAP1510P1_FPGA_BASE + 0x210)
-
-#define OMAP1510P1_FPGA_ETHR_START (OMAP1510P1_FPGA_START + 0x300)
-#define OMAP1510P1_FPGA_ETHR_BASE (OMAP1510P1_FPGA_BASE + 0x300)
+#define OMAP1510_FPGA_HOST_RESET (OMAP1510_FPGA_BASE + 0xa)
+#define OMAP1510_FPGA_RST (OMAP1510_FPGA_BASE + 0xb)
+
+#define OMAP1510_FPGA_AUDIO (OMAP1510_FPGA_BASE + 0xc)
+#define OMAP1510_FPGA_DIP (OMAP1510_FPGA_BASE + 0xe)
+#define OMAP1510_FPGA_FPGA_IO (OMAP1510_FPGA_BASE + 0xf)
+#define OMAP1510_FPGA_UART1 (OMAP1510_FPGA_BASE + 0x14)
+#define OMAP1510_FPGA_UART2 (OMAP1510_FPGA_BASE + 0x15)
+#define OMAP1510_FPGA_OMAP1510_STATUS (OMAP1510_FPGA_BASE + 0x16)
+#define OMAP1510_FPGA_BOARD_REV (OMAP1510_FPGA_BASE + 0x18)
+#define OMAP1510P1_PPT_DATA (OMAP1510_FPGA_BASE + 0x100)
+#define OMAP1510P1_PPT_STATUS (OMAP1510_FPGA_BASE + 0x101)
+#define OMAP1510P1_PPT_CONTROL (OMAP1510_FPGA_BASE + 0x102)
+
+#define OMAP1510_FPGA_TOUCHSCREEN (OMAP1510_FPGA_BASE + 0x204)
+
+#define INNOVATOR_FPGA_INFO (OMAP1510_FPGA_BASE + 0x205)
+#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510_FPGA_BASE + 0x206)
+#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510_FPGA_BASE + 0x207)
+#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510_FPGA_BASE + 0x208)
+#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510_FPGA_BASE + 0x209)
+#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510_FPGA_BASE + 0x20a)
+#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510_FPGA_BASE + 0x20b)
+#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510_FPGA_BASE + 0x20c)
+#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510_FPGA_BASE + 0x20d)
+#define INNOVATOR_FPGA_ISR2 (OMAP1510_FPGA_BASE + 0x20e)
+#define INNOVATOR_FPGA_IMR2 (OMAP1510_FPGA_BASE + 0x210)
+
+#define OMAP1510_FPGA_ETHR_START (OMAP1510_FPGA_START + 0x300)
+#define OMAP1510_FPGA_ETHR_BASE (OMAP1510_FPGA_BASE + 0x300)
/*
* Power up Giga UART driver, turn on HID clock.
* Turn off BT power, since we're not using it and it
* draws power.
*/
-#define OMAP1510P1_FPGA_RESET_VALUE 0x42
-
-#define OMAP1510P1_FPGA_PCR_IF_PD0 (1 << 7)
-#define OMAP1510P1_FPGA_PCR_COM2_EN (1 << 6)
-#define OMAP1510P1_FPGA_PCR_COM1_EN (1 << 5)
-#define OMAP1510P1_FPGA_PCR_EXP_PD0 (1 << 4)
-#define OMAP1510P1_FPGA_PCR_EXP_PD1 (1 << 3)
-#define OMAP1510P1_FPGA_PCR_48MHZ_CLK (1 << 2)
-#define OMAP1510P1_FPGA_PCR_4MHZ_CLK (1 << 1)
-#define OMAP1510P1_FPGA_PCR_RSRVD_BIT0 (1 << 0)
+#define OMAP1510_FPGA_RESET_VALUE 0x42
+
+#define OMAP1510_FPGA_PCR_IF_PD0 (1 << 7)
+#define OMAP1510_FPGA_PCR_COM2_EN (1 << 6)
+#define OMAP1510_FPGA_PCR_COM1_EN (1 << 5)
+#define OMAP1510_FPGA_PCR_EXP_PD0 (1 << 4)
+#define OMAP1510_FPGA_PCR_EXP_PD1 (1 << 3)
+#define OMAP1510_FPGA_PCR_48MHZ_CLK (1 << 2)
+#define OMAP1510_FPGA_PCR_4MHZ_CLK (1 << 1)
+#define OMAP1510_FPGA_PCR_RSRVD_BIT0 (1 << 0)
/*
* Innovator/OMAP1510 FPGA HID register bit definitions
* Device ID numbers for bus types
*/
#define OMAP_OCP_DEVID_USB 0
+
+#define OMAP_TIPB_DEVID_OHCI 0
#define OMAP_TIPB_DEVID_LCD 1
#define OMAP_TIPB_DEVID_MMC 2
+#define OMAP_TIPB_DEVID_OTG 3
+#define OMAP_TIPB_DEVID_UDC 4
/*
* Virtual bus definitions for OMAP
#define OMAP_DMA_EXT_NDMA_REQ 5
#define OMAP_DMA_EXT_NDMA_REQ2 6
#define OMAP_DMA_UWIRE_TX 7
-#define OMAP_DMA_MCBSP1_DMA_TX 8
-#define OMAP_DMA_MCBSP1_DMA_RX 9
-#define OMAP_DMA_MCBSP3_DMA_TX 10
-#define OMAP_DMA_MCBSP3_DMA_RX 11
+#define OMAP_DMA_MCBSP1_TX 8
+#define OMAP_DMA_MCBSP1_RX 9
+#define OMAP_DMA_MCBSP3_TX 10
+#define OMAP_DMA_MCBSP3_RX 11
#define OMAP_DMA_UART1_TX 12
#define OMAP_DMA_UART1_RX 13
#define OMAP_DMA_UART2_TX 14
#define OMAP_DMA_CRYPTO_DES_OUT 56
-#define OMAP_DMA_BASE 0xfffed800
-#define OMAP_DMA_GCR_REG (OMAP_DMA_BASE + 0x400)
-#define OMAP_DMA_GSCR_REG (OMAP_DMA_BASE + 0x404)
-#define OMAP_DMA_GRST_REG (OMAP_DMA_BASE + 0x408)
-#define OMAP_DMA_HW_ID_REG (OMAP_DMA_BASE + 0x442)
-#define OMAP_DMA_PCH2_ID_REG (OMAP_DMA_BASE + 0x444)
+#define OMAP_DMA_BASE (0xfffed800)
+#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400)
+#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404)
+#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408)
+#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442)
+#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444)
#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446)
#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448)
#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a)
#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c)
-#define OMAP_DMA_CAPS_0_U_REG (OMAP_DMA_BASE + 0x44e)
-#define OMAP_DMA_CAPS_0_L_REG (OMAP_DMA_BASE + 0x450)
-#define OMAP_DMA_CAPS_1_U_REG (OMAP_DMA_BASE + 0x452)
-#define OMAP_DMA_CAPS_1_L_REG (OMAP_DMA_BASE + 0x454)
-#define OMAP_DMA_CAPS_2_REG (OMAP_DMA_BASE + 0x456)
-#define OMAP_DMA_CAPS_3_REG (OMAP_DMA_BASE + 0x458)
-#define OMAP_DMA_CAPS_4_REG (OMAP_DMA_BASE + 0x45a)
-#define OMAP_DMA_PCH2_SR_REG (OMAP_DMA_BASE + 0x460)
-#define OMAP_DMA_PCH0_SR_REG (OMAP_DMA_BASE + 0x480)
-#define OMAP_DMA_PCH1_SR_REG (OMAP_DMA_BASE + 0x482)
-#define OMAP_DMA_PCHD_SR_REG (OMAP_DMA_BASE + 0x4c0)
-
-#define OMAP1510_DMA_LCD_CTRL 0xfffedb00
-#define OMAP1510_DMA_LCD_TOP_F1_L 0xfffedb02
-#define OMAP1510_DMA_LCD_TOP_F1_U 0xfffedb04
-#define OMAP1510_DMA_LCD_BOT_F1_L 0xfffedb06
-#define OMAP1510_DMA_LCD_BOT_F1_U 0xfffedb08
-
-#define OMAP1610_DMA_LCD_CSDP 0xfffee3c0
-#define OMAP1610_DMA_LCD_CCR 0xfffee3c2
-#define OMAP1610_DMA_LCD_CTRL 0xfffee3c4
-#define OMAP1610_DMA_LCD_TOP_B1_L 0xfffee3c8
-#define OMAP1610_DMA_LCD_TOP_B1_U 0xfffee3ca
-#define OMAP1610_DMA_LCD_BOT_B1_L 0xfffee3cc
-#define OMAP1610_DMA_LCD_BOT_B1_U 0xfffee3ce
-#define OMAP1610_DMA_LCD_TOP_B2_L 0xfffee3d0
-#define OMAP1610_DMA_LCD_TOP_B2_U 0xfffee3d2
-#define OMAP1610_DMA_LCD_BOT_B2_L 0xfffee3d4
-#define OMAP1610_DMA_LCD_BOT_B2_U 0xfffee3d6
-#define OMAP1610_DMA_LCD_SRC_EI_B1 0xfffee3d8
-#define OMAP1610_DMA_LCD_SRC_FI_B1_L 0xfffee3da
-#define OMAP1610_DMA_LCD_SRC_EN_B1 0xfffee3e0
-#define OMAP1610_DMA_LCD_SRC_FN_B1 0xfffee3e4
-#define OMAP1610_DMA_LCD_LCH_CTRL 0xfffee3ea
-#define OMAP1610_DMA_LCD_SRC_FI_B1_U 0xfffee3f4
+#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e)
+#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450)
+#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452)
+#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454)
+#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456)
+#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458)
+#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a)
+#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460)
+#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480)
+#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482)
+#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0)
+
+#define OMAP1510_DMA_LCD_BASE (0xfffedb00)
+#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00)
+#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02)
+#define OMAP1510_DMA_LCD_TOP_F1_U (OMAP1510_DMA_LCD_BASE + 0x04)
+#define OMAP1510_DMA_LCD_BOT_F1_L (OMAP1510_DMA_LCD_BASE + 0x06)
+#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08)
+
+#define OMAP1610_DMA_LCD_BASE (0xfffee300)
+#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2)
+#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4)
+#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8)
+#define OMAP1610_DMA_LCD_TOP_B1_U (OMAP1610_DMA_LCD_BASE + 0xca)
+#define OMAP1610_DMA_LCD_BOT_B1_L (OMAP1610_DMA_LCD_BASE + 0xcc)
+#define OMAP1610_DMA_LCD_BOT_B1_U (OMAP1610_DMA_LCD_BASE + 0xce)
+#define OMAP1610_DMA_LCD_TOP_B2_L (OMAP1610_DMA_LCD_BASE + 0xd0)
+#define OMAP1610_DMA_LCD_TOP_B2_U (OMAP1610_DMA_LCD_BASE + 0xd2)
+#define OMAP1610_DMA_LCD_BOT_B2_L (OMAP1610_DMA_LCD_BASE + 0xd4)
+#define OMAP1610_DMA_LCD_BOT_B2_U (OMAP1610_DMA_LCD_BASE + 0xd6)
+#define OMAP1610_DMA_LCD_SRC_EI_B1 (OMAP1610_DMA_LCD_BASE + 0xd8)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_L (OMAP1610_DMA_LCD_BASE + 0xda)
+#define OMAP1610_DMA_LCD_SRC_EN_B1 (OMAP1610_DMA_LCD_BASE + 0xe0)
+#define OMAP1610_DMA_LCD_SRC_FN_B1 (OMAP1610_DMA_LCD_BASE + 0xe4)
+#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4)
/* Every LCh has its own set of the registers below */
-#define OMAP_DMA_CSDP_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x00)
-#define OMAP_DMA_CCR_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x02)
-#define OMAP_DMA_CICR_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x04)
-#define OMAP_DMA_CSR_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x06)
-#define OMAP_DMA_CSSA_L_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x08)
-#define OMAP_DMA_CSSA_U_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
-#define OMAP_DMA_CDSA_L_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
-#define OMAP_DMA_CDSA_U_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
-#define OMAP_DMA_CEN_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x10)
-#define OMAP_DMA_CFN_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x12)
-#define OMAP_DMA_CSFI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x14)
-#define OMAP_DMA_CSEI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x16)
-#define OMAP_DMA_CSAC_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x18)
-#define OMAP_DMA_CDAC_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
-#define OMAP_DMA_CDEI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
-#define OMAP_DMA_CDFI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
-#define OMAP_DMA_COLOR_L_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x20)
-#define OMAP_DMA_COLOR_U_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x22)
-#define OMAP_DMA_CCR2_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x24)
-#define OMAP_DMA_CLNK_CTRL_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x28)
-#define OMAP_DMA_LCH_CTRL_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
+#define OMAP_DMA_CSDP(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x00)
+#define OMAP_DMA_CCR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x02)
+#define OMAP_DMA_CICR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x04)
+#define OMAP_DMA_CSR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x06)
+#define OMAP_DMA_CSSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x08)
+#define OMAP_DMA_CSSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
+#define OMAP_DMA_CDSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
+#define OMAP_DMA_CDSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
+#define OMAP_DMA_CEN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x10)
+#define OMAP_DMA_CFN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x12)
+#define OMAP_DMA_CSFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x14)
+#define OMAP_DMA_CSEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x16)
+#define OMAP_DMA_CSAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x18)
+#define OMAP_DMA_CDAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1a)
+#define OMAP_DMA_CDEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1c)
+#define OMAP_DMA_CDFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1e)
+#define OMAP_DMA_COLOR_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x20)
+#define OMAP_DMA_COLOR_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x22)
+#define OMAP_DMA_CCR2(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x24)
+#define OMAP_DMA_CLNK_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x28)
+#define OMAP_DMA_LCH_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
#define OMAP_DMA_TOUT_IRQ (1 << 0)
#define OMAP_DMA_DROP_IRQ (1 << 1)
OMAP_LCD_DMA_B2_BOTTOM
};
+enum {
+ OMAP_DMA_DATA_BURST_4,
+ OMAP_DMA_DATA_BURST_8
+};
+
extern int omap_request_dma(int dev_id, const char *dev_name,
void (* callback)(int lch, u16 ch_status, void *data),
void *data, int *dma_ch);
extern void omap_set_dma_transfer_params(int lch, int data_type,
int elem_count, int frame_count,
int sync_mode);
+extern void omap_set_dma_constant_fill(int lch, u32 color);
+extern void omap_set_dma_transparent_copy(int lch, u32 color);
+
extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
unsigned long src_start);
+extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_src_data_pack(int lch, int enable);
+extern void omap_set_dma_src_burst_mode(int lch, int burst_mode);
+
extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
unsigned long dest_start);
+extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_dest_data_pack(int lch, int enable);
+extern void omap_set_dma_dest_burst_mode(int lch, int burst_mode);
extern void omap_dma_link_lch (int lch_head, int lch_queue);
extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
#define OMAP_MPUIO_BASE 0xfffb5000
#define OMAP_MPUIO_INPUT_LATCH 0x00
-#define OMAP_MPUIO_OUTPUT_REG 0x04
+#define OMAP_MPUIO_OUTPUT 0x04
#define OMAP_MPUIO_IO_CNTL 0x08
#define OMAP_MPUIO_KBR_LATCH 0x10
-#define OMAP_MPUIO_KBC_REG 0x14
-#define OMAP_MPUIO_GPIO_EVENT_MODE_REG 0x18
-#define OMAP_MPUIO_GPIO_INT_EDGE_REG 0x1c
+#define OMAP_MPUIO_KBC 0x14
+#define OMAP_MPUIO_GPIO_EVENT_MODE 0x18
+#define OMAP_MPUIO_GPIO_INT_EDGE 0x1c
#define OMAP_MPUIO_KBD_INT 0x20
#define OMAP_MPUIO_GPIO_INT 0x24
#define OMAP_MPUIO_KBD_MASKIT 0x28
#define OMAP_MPUIO_GPIO_MASKIT 0x2c
-#define OMAP_MPUIO_GPIO_DEBOUNCING_REG 0x30
-#define OMAP_MPUIO_LATCH_REG 0x34
+#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30
+#define OMAP_MPUIO_LATCH 0x34
#define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr))
#define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES)
* Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
*
* Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ * and Dirk Behme <dirk.behme@de.bosch.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
#ifndef __ASSEMBLER__
#include <asm/types.h>
#endif
-
-/*
- * ----------------------------------------------------------------------------
- * I/O mapping
- * ----------------------------------------------------------------------------
- */
-#define IO_PHYS 0xFFFB0000
-#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
-#define IO_VIRT (IO_PHYS - IO_OFFSET)
-#define IO_SIZE 0x40000
-#define IO_ADDRESS(x) ((x) - IO_OFFSET)
-
-#define PCIO_BASE 0
-
-#define io_p2v(x) ((x) - IO_OFFSET)
-#define io_v2p(x) ((x) + IO_OFFSET)
-
-#ifndef __ASSEMBLER__
-
-/* 16 bit uses LDRH/STRH, base +/- offset_8 */
-typedef struct { volatile u16 offset[256]; } __regbase16;
-#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \
- ->offset[((vaddr)&0xff)>>1]
-#define __REG16(paddr) __REGV16(io_p2v(paddr))
-
-/* 8/32 bit uses LDR/STR, base +/- offset_12 */
-typedef struct { volatile u8 offset[4096]; } __regbase8;
-#define __REGV8(vaddr) ((__regbase8 *)((paddr)&~4095)) \
- ->offset[((paddr)&4095)>>0]
-#define __REG8(paddr) __REGV8(io_p2v(paddr))
-
-typedef struct { volatile u32 offset[4096]; } __regbase32;
-#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \
- ->offset[((vaddr)&4095)>>2]
-#define __REG32(paddr) __REGV32(io_p2v(paddr))
-
-#else
-
-#define __REG8(paddr) io_p2v(paddr)
-#define __REG16(paddr) io_p2v(paddr)
-#define __REG32(paddr) io_p2v(paddr)
-
-#endif
+#include <asm/arch/io.h>
/*
* ---------------------------------------------------------------------------
* Clocks
* ----------------------------------------------------------------------------
*/
-#define CLKGEN_RESET_BASE (0xfffece00)
-#define ARM_CKCTL (CLKGEN_RESET_BASE + 0x0)
-#define ARM_IDLECT1 (CLKGEN_RESET_BASE + 0x4)
-#define ARM_IDLECT2 (CLKGEN_RESET_BASE + 0x8)
-#define ARM_EWUPCT (CLKGEN_RESET_BASE + 0xC)
-#define ARM_RSTCT1 (CLKGEN_RESET_BASE + 0x10)
-#define ARM_RSTCT2 (CLKGEN_RESET_BASE + 0x14)
-#define ARM_SYSST (CLKGEN_RESET_BASE + 0x18)
+#define CLKGEN_REG_BASE (0xfffece00)
+#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
#define CK_RATEF 1
#define CK_IDLEF 2
#define SETARM_IDLE_SHIFT
/* DPLL control registers */
-#define DPLL_CTL_REG (0xfffecf00)
-#define CK_DPLL1 (0xfffecf00)
+#define DPLL_CTL (0xfffecf00)
-/* ULPD */
+/* DSP clock control */
+#define DSP_CONFIG_REG_BASE (0xe1008000)
+#define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4)
+#define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8)
+
+/*
+ * ---------------------------------------------------------------------------
+ * UPLD
+ * ---------------------------------------------------------------------------
+ */
#define ULPD_REG_BASE (0xfffe0800)
-#define ULPD_IT_STATUS_REG (ULPD_REG_BASE + 0x14)
-#define ULPD_CLOCK_CTRL_REG (ULPD_REG_BASE + 0x30)
-#define ULPD_SOFT_REQ_REG (ULPD_REG_BASE + 0x34)
-#define ULPD_DPLL_CTRL_REG (ULPD_REG_BASE + 0x3c)
-#define ULPD_STATUS_REQ_REG (ULPD_REG_BASE + 0x40)
-#define ULPD_APLL_CTRL_REG (ULPD_REG_BASE + 0x4c)
-#define ULPD_POWER_CTRL_REG (ULPD_REG_BASE + 0x50)
-#define ULPD_CAM_CLK_CTRL_REG (ULPD_REG_BASE + 0x7c)
+#define ULPD_IT_STATUS (ULPD_REG_BASE + 0x14)
+#define ULPD_CLOCK_CTRL (ULPD_REG_BASE + 0x30)
+#define ULPD_SOFT_REQ (ULPD_REG_BASE + 0x34)
+#define ULPD_DPLL_CTRL (ULPD_REG_BASE + 0x3c)
+#define ULPD_STATUS_REQ (ULPD_REG_BASE + 0x40)
+#define ULPD_APLL_CTRL (ULPD_REG_BASE + 0x4c)
+#define ULPD_POWER_CTRL (ULPD_REG_BASE + 0x50)
+#define ULPD_CAM_CLK_CTRL (ULPD_REG_BASE + 0x7c)
/*
* ---------------------------------------------------------------------------
#define TIMER32k_ARL (1<<3)
/* MPU Timer base addresses */
-#define OMAP_MPUTIMER_BASE 0xfffec500
-#define OMAP_MPUTIMER_OFF 0x00000100
-
-#define OMAP_TIMER1_BASE 0xfffec500
-#define OMAP_TIMER2_BASE 0xfffec600
-#define OMAP_TIMER3_BASE 0xfffec700
-#define OMAP_WATCHDOG_BASE 0xfffec800
+#define OMAP_TIMER1_BASE (0xfffec500)
+#define OMAP_TIMER2_BASE (0xfffec600)
+#define OMAP_TIMER3_BASE (0xfffec700)
+#define OMAP_MPUTIMER_BASE OMAP_TIMER1_BASE
+#define OMAP_MPUTIMER_OFFSET 0x100
/* MPU Timer Registers */
-#define CNTL_TIMER 0
-#define LOAD_TIM 4
-#define READ_TIM 8
+#define OMAP_TIMER1_CNTL (OMAP_TIMER_BASE1 + 0x0)
+#define OMAP_TIMER1_LOAD_TIM (OMAP_TIMER_BASE1 + 0x4)
+#define OMAP_TIMER1_READ_TIM (OMAP_TIMER_BASE1 + 0x8)
+
+#define OMAP_TIMER2_CNTL (OMAP_TIMER_BASE2 + 0x0)
+#define OMAP_TIMER2_LOAD_TIM (OMAP_TIMER_BASE2 + 0x4)
+#define OMAP_TIMER2_READ_TIM (OMAP_TIMER_BASE2 + 0x8)
+
+#define OMAP_TIMER3_CNTL (OMAP_TIMER_BASE3 + 0x0)
+#define OMAP_TIMER3_LOAD_TIM (OMAP_TIMER_BASE3 + 0x4)
+#define OMAP_TIMER3_READ_TIM (OMAP_TIMER_BASE3 + 0x8)
/* CNTL_TIMER register bits */
#define MPUTIM_FREE (1<<6)
#define MPUTIM_AR (1<<1)
#define MPUTIM_ST (1<<0)
+/* Watchdog */
+#define OMAP_WATCHDOG_BASE (0xfffec800)
+#define OMAP_WDT_TIMER (OMAP_WATCHDOG_BASE + 0x0)
+#define OMAP_WDT_LOAD_TIM (OMAP_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_READ_TIM (OMAP_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_TIMER_MODE (OMAP_WATCHDOG_BASE + 0x8)
+
/*
* ---------------------------------------------------------------------------
* Interrupts
*/
#define OMAP_IH1_BASE 0xfffecb00
#define OMAP_IH2_BASE 0xfffe0000
-#define OMAP_ITR 0x0
-#define OMAP_MASK 0x4
-
-#define IRQ_ITR 0x00
-#define IRQ_MIR 0x04
-#define IRQ_SIR_IRQ 0x10
-#define IRQ_SIR_FIQ 0x14
-#define IRQ_CONTROL_REG 0x18
-#define IRQ_ISR 0x9c
-#define IRQ_ILR0 0x1c
-
-/* OMAP-1610 specific interrupt handler registers */
-#define OMAP_IH2_SECT1 (OMAP_IH2_BASE)
-#define OMAP_IH2_SECT2 (OMAP_IH2_BASE + 0x100)
-#define OMAP_IH2_SECT3 (OMAP_IH2_BASE + 0x200)
-#define OMAP_IH2_SECT4 (OMAP_IH2_BASE + 0x300)
+
+#define OMAP_IH1_ITR (OMAP_IH1_BASE + 0x00)
+#define OMAP_IH1_MIR (OMAP_IH1_BASE + 0x04)
+#define OMAP_IH1_SIR_IRQ (OMAP_IH1_BASE + 0x10)
+#define OMAP_IH1_SIR_FIQ (OMAP_IH1_BASE + 0x14)
+#define OMAP_IH1_CONTROL (OMAP_IH1_BASE + 0x18)
+#define OMAP_IH1_ILR0 (OMAP_IH1_BASE + 0x1c)
+#define OMAP_IH1_ISR (OMAP_IH1_BASE + 0x9c)
+
+#define OMAP_IH2_ITR (OMAP_IH2_BASE + 0x00)
+#define OMAP_IH2_MIR (OMAP_IH2_BASE + 0x04)
+#define OMAP_IH2_SIR_IRQ (OMAP_IH2_BASE + 0x10)
+#define OMAP_IH2_SIR_FIQ (OMAP_IH2_BASE + 0x14)
+#define OMAP_IH2_CONTROL (OMAP_IH2_BASE + 0x18)
+#define OMAP_IH2_ILR0 (OMAP_IH2_BASE + 0x1c)
+#define OMAP_IH2_ISR (OMAP_IH2_BASE + 0x9c)
+
+#define IRQ_ITR_REG_OFFSET 0x00
+#define IRQ_MIR_REG_OFFSET 0x04
+#define IRQ_SIR_IRQ_REG_OFFSET 0x10
+#define IRQ_SIR_FIQ_REG_OFFSET 0x14
+#define IRQ_CONTROL_REG_OFFSET 0x18
+#define IRQ_ISR_REG_OFFSET 0x9c
+#define IRQ_ILR0_REG_OFFSET 0x1c
/*
* ---------------------------------------------------------------------------
*/
#define TCMIF_BASE 0xfffecc00
#define IMIF_PRIO (TCMIF_BASE + 0x00)
-#define EMIFS_PRIO_REG (TCMIF_BASE + 0x04)
-#define EMIFF_PRIO_REG (TCMIF_BASE + 0x08)
-#define EMIFS_CONFIG_REG (TCMIF_BASE + 0x0c)
+#define EMIFS_PRIO (TCMIF_BASE + 0x04)
+#define EMIFF_PRIO (TCMIF_BASE + 0x08)
+#define EMIFS_CONFIG (TCMIF_BASE + 0x0c)
#define EMIFS_CS0_CONFIG (TCMIF_BASE + 0x10)
#define EMIFS_CS1_CONFIG (TCMIF_BASE + 0x14)
#define EMIFS_CS2_CONFIG (TCMIF_BASE + 0x18)
#define TC_ENDIANISM (TCMIF_BASE + 0x34)
#define EMIFF_SDRAM_CONFIG_2 (TCMIF_BASE + 0x3c)
#define EMIF_CFG_DYNAMIC_WS (TCMIF_BASE + 0x40)
-
/*
* ----------------------------------------------------------------------------
* System control registers
* ---------------------------------------------------------------------------
*/
#define TIPB_PUBLIC_CNTL_BASE 0xfffed300
-#define MPU_PUBLIC_TIPB_CNTL_REG (TIPB_PUBLIC_CNTL_BASE + 0x8)
+#define MPU_PUBLIC_TIPB_CNTL (TIPB_PUBLIC_CNTL_BASE + 0x8)
#define TIPB_PRIVATE_CNTL_BASE 0xfffeca00
-#define MPU_PRIVATE_TIPB_CNTL_REG (TIPB_PRIVATE_CNTL_BASE + 0x8)
+#define MPU_PRIVATE_TIPB_CNTL (TIPB_PRIVATE_CNTL_BASE + 0x8)
/*
* ----------------------------------------------------------------------------
- * DSP control registers
+ * MPUI interface
* ----------------------------------------------------------------------------
*/
-/* MPUI Interface Registers */
-#define MPUI_CTRL_REG (0xfffec900)
-#define MPUI_DEBUG_ADDR (0xfffec904)
-#define MPUI_DEBUG_DATA (0xfffec908)
-#define MPUI_DEBUG_FLAG (0xfffec90c)
-#define MPUI_STATUS_REG (0xfffec910)
-#define MPUI_DSP_STATUS_REG (0xfffec914)
-#define MPUI_DSP_BOOT_CONFIG (0xfffec918)
-#define MPUI_DSP_API_CONFIG (0xfffec91c)
-
+#define MPUI_BASE (0xfffec900)
+#define MPUI_CTRL (MPUI_BASE + 0x0)
+#define MPUI_DEBUG_ADDR (MPUI_BASE + 0x4)
+#define MPUI_DEBUG_DATA (MPUI_BASE + 0x8)
+#define MPUI_DEBUG_FLAG (MPUI_BASE + 0xc)
+#define MPUI_STATUS_REG (MPUI_BASE + 0x10)
+#define MPUI_DSP_STATUS (MPUI_BASE + 0x14)
+#define MPUI_DSP_BOOT_CONFIG (MPUI_BASE + 0x18)
+#define MPUI_DSP_API_CONFIG (MPUI_BASE + 0x1c)
#ifndef __ASSEMBLER__
* Processor differentiation
* ---------------------------------------------------------------------------
*/
-#define OMAP_ID_REG __REG32(0xfffed404)
+#define OMAP_ID_BASE (0xfffed400)
+#define OMAP_ID_REG __REG32(OMAP_ID_BASE + 0x04)
+
+#define ID_SHIFT 12
+#define ID_MASK 0x7fff
/* See also uncompress.h */
-#define OMAP_ID_730 0xB55F
-#define OMAP_ID_1510 0xB470
-#define OMAP_ID_1610 0xB576
-#define OMAP_ID_1710 0xB5F7
-#define OMAP_ID_5912 0xB58C
+#define OMAP_ID_730 0x355F
+#define OMAP_ID_1510 0x3470
+#define OMAP_ID_1610 0x3576
+#define OMAP_ID_1710 0x35F7
+#define OMAP_ID_5912 0x358C
#ifdef CONFIG_ARCH_OMAP730
#include "omap730.h"
-#define cpu_is_omap730() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_730)
+#define cpu_is_omap730() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_730)
#else
#define cpu_is_omap730() 0
#endif
#ifdef CONFIG_ARCH_OMAP1510
#include "omap1510.h"
-#define cpu_is_omap1510() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1510)
+#define cpu_is_omap1510() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1510)
#else
#define cpu_is_omap1510() 0
#endif
#ifdef CONFIG_ARCH_OMAP1610
#include "omap1610.h"
-#define cpu_is_omap1710() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1710)
+#define cpu_is_omap1710() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1710)
/* Detect 1710 as 1610 for now */
-#define cpu_is_omap1610() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1610 \
+#define cpu_is_omap1610() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1610 \
|| cpu_is_omap1710())
#else
#define cpu_is_omap1610() 0
#ifdef CONFIG_ARCH_OMAP5912
#include "omap5912.h"
-#define cpu_is_omap5912() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_5912)
+#define cpu_is_omap5912() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_5912)
#else
#define cpu_is_omap5912() 0
#endif
/*
* linux/include/asm-arm/arch-omap/io.h
*
+ * IO definitions for TI OMAP processors and boards
+ *
* Copied from linux/include/asm-arm/arch-sa1100/io.h
* Copyright (C) 1997-1999 Russell King
*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
* Modifications:
* 06-12-1997 RMK Created.
* 07-04-1999 RMK Major cleanup
*/
+
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
#define __mem_pci(a) ((unsigned long)(a))
#define __mem_isa(a) ((unsigned long)(a))
+/*
+ * ----------------------------------------------------------------------------
+ * I/O mapping
+ * ----------------------------------------------------------------------------
+ */
+#define IO_PHYS 0xFFFB0000
+#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
+#define IO_VIRT (IO_PHYS - IO_OFFSET)
+#define IO_SIZE 0x40000
+#define IO_ADDRESS(x) ((x) - IO_OFFSET)
+
+#define PCIO_BASE 0
+
+#define io_p2v(x) ((x) - IO_OFFSET)
+#define io_v2p(x) ((x) + IO_OFFSET)
+
+#ifndef __ASSEMBLER__
+
/*
* Functions to access the OMAP IO region
*
#define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
#define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v))
+/* 16 bit uses LDRH/STRH, base +/- offset_8 */
+typedef struct { volatile u16 offset[256]; } __regbase16;
+#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \
+ ->offset[((vaddr)&0xff)>>1]
+#define __REG16(paddr) __REGV16(io_p2v(paddr))
+
+/* 8/32 bit uses LDR/STR, base +/- offset_12 */
+typedef struct { volatile u8 offset[4096]; } __regbase8;
+#define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095)) \
+ ->offset[((vaddr)&4095)>>0]
+#define __REG8(paddr) __REGV8(io_p2v(paddr))
+
+typedef struct { volatile u32 offset[4096]; } __regbase32;
+#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \
+ ->offset[((vaddr)&4095)>>2]
+#define __REG32(paddr) __REGV32(io_p2v(paddr))
+
+#else
+
+#define __REG8(paddr) io_p2v(paddr)
+#define __REG16(paddr) io_p2v(paddr)
+#define __REG32(paddr) io_p2v(paddr)
+
+#endif
+
#endif
R18_1510_USB_GPIO0,
W4_USB_PUEN,
W4_USB_CLKO,
+ W4_USB_HIGHZ,
+ W4_GPIO58,
/* USB1 master */
USB1_SUSP,
USB1_SEO,
+ W13_1610_USB1_SE0,
USB1_TXEN,
USB1_TXD,
USB1_VP,
USB1_VM,
USB1_RCV,
USB1_SPEED,
+ R13_1610_USB1_SPEED,
/* USB2 master */
USB2_SUSP,
/* OMAP-1610 GPIO */
P20_1610_GPIO4,
V9_1610_GPIO7,
+ W8_1610_GPIO9,
N19_1610_GPIO13,
P10_1610_GPIO22,
V5_1610_GPIO24,
MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
MUX_CFG("W4_USB_PUEN", D, 3, 0, 3, 5, 1, NA, 0, 1)
MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
+MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
+MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
/* USB1 master */
MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
+MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
+MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
/* USB2 master */
MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
/* OMAP-1610 GPIO */
MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
+MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
-MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, NA, 0, 0, NA, 0, 0)
+MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
/* First MMC interface, same on 1510 and 1610 */
MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
#define OMAP1610_DSPREG_SIZE SZ_128K
#define OMAP1610_DSPREG_START 0xE1000000
-#define OMAP_IH2_0_BASE 0xfffe0000
-#define OMAP_IH2_1_BASE 0xfffe0100
-#define OMAP_IH2_2_BASE 0xfffe0200
-#define OMAP_IH2_3_BASE 0xfffe0300
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_IH2_0_BASE (0xfffe0000)
+#define OMAP_IH2_1_BASE (0xfffe0100)
+#define OMAP_IH2_2_BASE (0xfffe0200)
+#define OMAP_IH2_3_BASE (0xfffe0300)
+
+#define OMAP_IH2_0_ITR (OMAP_IH2_0_BASE + 0x00)
+#define OMAP_IH2_0_MIR (OMAP_IH2_0_BASE + 0x04)
+#define OMAP_IH2_0_SIR_IRQ (OMAP_IH2_0_BASE + 0x10)
+#define OMAP_IH2_0_SIR_FIQ (OMAP_IH2_0_BASE + 0x14)
+#define OMAP_IH2_0_CONTROL (OMAP_IH2_0_BASE + 0x18)
+#define OMAP_IH2_0_ILR0 (OMAP_IH2_0_BASE + 0x1c)
+#define OMAP_IH2_0_ISR (OMAP_IH2_0_BASE + 0x9c)
+
+#define OMAP_IH2_1_ITR (OMAP_IH2_1_BASE + 0x00)
+#define OMAP_IH2_1_MIR (OMAP_IH2_1_BASE + 0x04)
+#define OMAP_IH2_1_SIR_IRQ (OMAP_IH2_1_BASE + 0x10)
+#define OMAP_IH2_1_SIR_FIQ (OMAP_IH2_1_BASE + 0x14)
+#define OMAP_IH2_1_CONTROL (OMAP_IH2_1_BASE + 0x18)
+#define OMAP_IH2_1_ILR1 (OMAP_IH2_1_BASE + 0x1c)
+#define OMAP_IH2_1_ISR (OMAP_IH2_1_BASE + 0x9c)
+
+#define OMAP_IH2_2_ITR (OMAP_IH2_2_BASE + 0x00)
+#define OMAP_IH2_2_MIR (OMAP_IH2_2_BASE + 0x04)
+#define OMAP_IH2_2_SIR_IRQ (OMAP_IH2_2_BASE + 0x10)
+#define OMAP_IH2_2_SIR_FIQ (OMAP_IH2_2_BASE + 0x14)
+#define OMAP_IH2_2_CONTROL (OMAP_IH2_2_BASE + 0x18)
+#define OMAP_IH2_2_ILR2 (OMAP_IH2_2_BASE + 0x1c)
+#define OMAP_IH2_2_ISR (OMAP_IH2_2_BASE + 0x9c)
+
+#define OMAP_IH2_3_ITR (OMAP_IH2_3_BASE + 0x00)
+#define OMAP_IH2_3_MIR (OMAP_IH2_3_BASE + 0x04)
+#define OMAP_IH2_3_SIR_IRQ (OMAP_IH2_3_BASE + 0x10)
+#define OMAP_IH2_3_SIR_FIQ (OMAP_IH2_3_BASE + 0x14)
+#define OMAP_IH2_3_CONTROL (OMAP_IH2_3_BASE + 0x18)
+#define OMAP_IH2_3_ILR3 (OMAP_IH2_3_BASE + 0x1c)
+#define OMAP_IH2_3_ISR (OMAP_IH2_3_BASE + 0x9c)
/*
* ----------------------------------------------------------------------------
- * System control registers
+ * Clocks
* ----------------------------------------------------------------------------
*/
+#define OMAP1610_ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
-#define OMAP1610_RESET_CONTROL 0xfffe1140
-#define OMAP1610_ARM_IDLECT3 (CLKGEN_RESET_BASE + 0x24)
-#define OMAP1610_CONF_VOLTAGE_CTRL_0 0xfffe1060
+/*
+ * ----------------------------------------------------------------------------
+ * Pin configuration registers
+ * ----------------------------------------------------------------------------
+ */
#define OMAP1610_CONF_VOLTAGE_VDDSHV6 (1 << 8)
#define OMAP1610_CONF_VOLTAGE_VDDSHV7 (1 << 9)
#define OMAP1610_CONF_VOLTAGE_VDDSHV8 (1 << 10)
* TIPB bus interface
* ---------------------------------------------------------------------------
*/
-
-#define OMAP1610_TIPB_SWITCH 0xfffbc800
-#define OMAP1610_TIPB_BRIDGE_INT 0xfffeca00 /* Private TIPB_CNTL */
-#define OMAP1610_PRIVATE_MPU_TIPB_CNTL 0xfffeca08
-#define OMAP1610_TIPB_BRIDGE_EXT 0xfffed300 /* Public (Shared) TIPB_CNTL */
-#define OMAP1610_PUBLIC_MPU_TIPB_CNTL 0xfffed308
-#define OMAP1610_TIPB_SWITCH_CFG OMAP_TIPB_SWITCH
-#define OMAP1610_MMCSD2_SSW_MPU_CONF (TIPB_SWITCH_CFG + 0x160)
+#define TIPB_SWITCH_BASE (0xfffbc800)
+#define OMAP1610_MMCSD2_SSW_MPU_CONF (TIPB_SWITCH_BASE + 0x160)
#endif /* __ASM_ARCH_OMAP1610_H */
#define OMAP5912_DSPREG_SIZE SZ_128K
#define OMAP5912_DSPREG_START 0xE1000000
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_IH2_0_BASE (0xfffe0000)
+#define OMAP_IH2_1_BASE (0xfffe0100)
+#define OMAP_IH2_2_BASE (0xfffe0200)
+#define OMAP_IH2_3_BASE (0xfffe0300)
+
+#define OMAP_IH2_0_ITR (OMAP_IH2_0_BASE + 0x00)
+#define OMAP_IH2_0_MIR (OMAP_IH2_0_BASE + 0x04)
+#define OMAP_IH2_0_SIR_IRQ (OMAP_IH2_0_BASE + 0x10)
+#define OMAP_IH2_0_SIR_FIQ (OMAP_IH2_0_BASE + 0x14)
+#define OMAP_IH2_0_CONTROL (OMAP_IH2_0_BASE + 0x18)
+#define OMAP_IH2_0_ILR0 (OMAP_IH2_0_BASE + 0x1c)
+#define OMAP_IH2_0_ISR (OMAP_IH2_0_BASE + 0x9c)
+
+#define OMAP_IH2_1_ITR (OMAP_IH2_1_BASE + 0x00)
+#define OMAP_IH2_1_MIR (OMAP_IH2_1_BASE + 0x04)
+#define OMAP_IH2_1_SIR_IRQ (OMAP_IH2_1_BASE + 0x10)
+#define OMAP_IH2_1_SIR_FIQ (OMAP_IH2_1_BASE + 0x14)
+#define OMAP_IH2_1_CONTROL (OMAP_IH2_1_BASE + 0x18)
+#define OMAP_IH2_1_ILR1 (OMAP_IH2_1_BASE + 0x1c)
+#define OMAP_IH2_1_ISR (OMAP_IH2_1_BASE + 0x9c)
+
+#define OMAP_IH2_2_ITR (OMAP_IH2_2_BASE + 0x00)
+#define OMAP_IH2_2_MIR (OMAP_IH2_2_BASE + 0x04)
+#define OMAP_IH2_2_SIR_IRQ (OMAP_IH2_2_BASE + 0x10)
+#define OMAP_IH2_2_SIR_FIQ (OMAP_IH2_2_BASE + 0x14)
+#define OMAP_IH2_2_CONTROL (OMAP_IH2_2_BASE + 0x18)
+#define OMAP_IH2_2_ILR2 (OMAP_IH2_2_BASE + 0x1c)
+#define OMAP_IH2_2_ISR (OMAP_IH2_2_BASE + 0x9c)
+
+#define OMAP_IH2_3_ITR (OMAP_IH2_3_BASE + 0x00)
+#define OMAP_IH2_3_MIR (OMAP_IH2_3_BASE + 0x04)
+#define OMAP_IH2_3_SIR_IRQ (OMAP_IH2_3_BASE + 0x10)
+#define OMAP_IH2_3_SIR_FIQ (OMAP_IH2_3_BASE + 0x14)
+#define OMAP_IH2_3_CONTROL (OMAP_IH2_3_BASE + 0x18)
+#define OMAP_IH2_3_ILR3 (OMAP_IH2_3_BASE + 0x1c)
+#define OMAP_IH2_3_ISR (OMAP_IH2_3_BASE + 0x9c)
+
/*
* ----------------------------------------------------------------------------
* System control registers
* ----------------------------------------------------------------------------
*/
-#define OMAP5912_ARM_IDLECT3 (CLKGEN_RESET_BASE + 0x24)
+#define OMAP5912_ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
#endif /* __ASM_ARCH_OMAP5912_H */
* OMAP730 PCC_UPLD configuration registers
* ----------------------------------------------------------------------------
*/
-#define OMAP730_PCC_UPLD_CTRL_REG_BASE (0xfffe0900)
-#define OMAP730_PCC_UPLD_CTRL_REG (OMAP730_PCC_UPLD_CTRL_REG_BASE + 0x00)
+#define OMAP730_PCC_UPLD_CTRL_BASE (0xfffe0900)
+#define OMAP730_PCC_UPLD_CTRL (OMAP730_PCC_UPLD_CTRL_BASE + 0x00)
#endif /* __ASM_ARCH_OMAP730_H */
#define mputimer_base(n) \
((volatile mputimer_regs_t*)IO_ADDRESS(OMAP_MPUTIMER_BASE + \
- (n)*OMAP_MPUTIMER_OFF))
+ (n)*OMAP_MPUTIMER_OFFSET))
static inline unsigned long timer32k_read(int reg) {
unsigned long val;
#define UART_OMAP_MDR1 0x08 /* mode definition register */
#define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0)
-#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & 0xffff
+#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK
static void
puts(const char *s)
#endif
-
-/*
- * Implementation specifics
- */
-
-#include "lubbock.h"
-#include "mainstone.h"
-#include "idp.h"
-
#endif /* _ASM_ARCH_HARDWARE_H */
#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C)
#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0)
-/* mask: 0=enable, 1=disable
- * 1 bit EINT, 4=EINT4, 23=EINT23
- * EINT0,1,2,3 are not handled here.
-*/
-#define S3C2410_EINTMASK S3C2410_GPIOREG(0xA4)
-#define S3C2410_EINTPEND S3C2410_GPIOREG(0xA8)
+/* removed EINTxxxx defs from here, not meant for this */
/* GSTATUS have miscellaneous information in them
*
#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018)
#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C)
+/* mask: 0=enable, 1=disable
+ * 1 bit EINT, 4=EINT4, 23=EINT23
+ * EINT0,1,2,3 are not handled here.
+*/
+
#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4)
#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8)
* about to change to user space. This is the same method as used on SPARC64.
* See update_mmu_cache for the user space part.
*/
-extern void __flush_dcache_page(struct page *);
-
-static inline void flush_dcache_page(struct page *page)
-{
- struct address_space *mapping = page_mapping(page);
-
- if (mapping && !mapping_mapped(mapping))
- set_bit(PG_dcache_dirty, &page->flags);
- else
- __flush_dcache_page(page);
-}
+extern void flush_dcache_page(struct page *);
#define flush_dcache_mmap_lock(mapping) \
spin_lock_irq(&(mapping)->tree_lock)
#define FP_SIZE 35
+#ifndef __ASSEMBLY__
+
+/*
+ * VFP storage area has:
+ * - FPEXC, FPSCR, FPINST and FPINST2.
+ * - 16 double precision data registers
+ * - an implementation-dependant word of state for FLDMX/FSTMX
+ *
+ * FPEXC will always be non-zero once the VFP has been used in this process.
+ */
+
+struct vfp_hard_struct {
+ __u64 fpregs[16];
+ __u32 fpmx_state;
+ __u32 fpexc;
+ __u32 fpscr;
+ /*
+ * VFP implementation specific state
+ */
+ __u32 fpinst;
+ __u32 fpinst2;
+};
+
+union vfp_state {
+ struct vfp_hard_struct hard;
+};
+
+extern void vfp_flush_thread(union vfp_state *);
+extern void vfp_release_thread(union vfp_state *);
+
struct fp_hard_struct {
unsigned int save[FP_SIZE]; /* as yet undefined */
};
};
#endif
+
+#endif
flush_pmd_entry(pmdp); \
} while (0)
+#define copy_pmd(pmdpd,pmdps) \
+ do { \
+ pmdpd[0] = pmdps[0]; \
+ pmdpd[1] = pmdps[1]; \
+ flush_pmd_entry(pmdpd); \
+ } while (0)
+
#define pmd_clear(pmdp) \
do { \
pmdp[0] = __pmd(0); \
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
#ifdef __KERNEL__
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING}, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX}, \
}
#endif /* __KERNEL__ */
#ifdef __KERNEL__
+#include <asm/fpstate.h>
+
#ifndef __ASSEMBLY__
struct task_struct;
struct exec_domain;
-#include <asm/fpstate.h>
#include <asm/ptrace.h>
#include <asm/types.h>
#include <asm/domain.h>
struct cpu_context_save cpu_context; /* cpu context */
__u8 used_cp[16]; /* thread used copro */
union fp_state fpstate;
- struct restart_block restart_block;
+ union vfp_state vfpstate;
+ struct restart_block restart_block;
};
#define INIT_THREAD_INFO(tsk) \
#define TI_CPU_SAVE 28
#define TI_USED_CP 76
#define TI_FPSTATE (TI_USED_CP+16)
+#define TI_VFPSTATE (TI_FPSTATE+FP_SIZE*4)
#endif
*/
#include <linux/sched.h>
#include <asm/errno.h>
-#include <asm/arch/memory.h>
+#include <asm/memory.h>
#include <asm/domain.h>
#include <asm/system.h>
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
#ifdef __KERNEL__
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING}, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX}, \
}
#endif /* __KERNEL__ */
#ifndef __ASMARM_TLB_H
#define __ASMARM_TLB_H
+#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
/*
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#define RLIMIT_NOFILE 7 /* max number of open files */
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
-#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
- { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#include <linux/config.h>
#include <linux/swap.h>
+#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
/*
static inline unsigned short _swapw(volatile unsigned short v)
{
- unsigned short r,t;
- __asm__("mov.b %w2,%x1\n\t"
- "mov.b %x2,%w1\n\t"
- "mov.w %1,%0"
- :"=r"(r),"=r"(t)
- :"r"(v));
+#ifndef H8300_IO_NOSWAP
+ unsigned short r;
+ __asm__("xor.b %w0,%x0\n\t"
+ "xor.b %x0,%w0\n\t"
+ "xor.b %w0,%x0"
+ :"=r"(r)
+ :"0"(v));
return r;
+#else
+ return v;
+#endif
}
-static inline unsigned int _swapl(volatile unsigned long v)
+static inline unsigned long _swapl(volatile unsigned long v)
{
- unsigned int r,t;
- __asm__("mov.b %w2,%x1\n\t"
- "mov.b %x2,%w1\n\t"
- "mov.w %f1,%e0\n\t"
- "mov.w %e2,%f1\n\t"
- "mov.b %w1,%x0\n\t"
- "mov.b %x1,%w0"
- :"=r"(r),"=r"(t)
- :"r"(v));
+#ifndef H8300_IO_NOSWAP
+ unsigned long r;
+ __asm__("xor.b %w0,%x0\n\t"
+ "xor.b %x0,%w0\n\t"
+ "xor.b %w0,%x0\n\t"
+ "xor.w %e0,%f0\n\t"
+ "xor.w %f0,%e0\n\t"
+ "xor.w %e0,%f0\n\t"
+ "xor.b %w0,%x0\n\t"
+ "xor.b %x0,%w0\n\t"
+ "xor.b %w0,%x0"
+ :"=r"(r)
+ :"0"(v));
return r;
+#else
+ return v;
+#endif
}
#define readb(addr) \
static inline void io_outsl(unsigned int addr, const void *buf, int len)
{
- volatile unsigned int *ap = (volatile unsigned int *) addr;
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
unsigned long *bp = (unsigned long *) buf;
while (len--)
*ap = _swapl(*bp++);
}
+static inline void io_outsw_noswap(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned short *ap = (volatile unsigned short *) addr;
+ unsigned short *bp = (unsigned short *) buf;
+ while (len--)
+ *ap = *bp++;
+}
+
+static inline void io_outsl_noswap(unsigned int addr, const void *buf, int len)
+{
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
+ unsigned long *bp = (unsigned long *) buf;
+ while (len--)
+ *ap = *bp++;
+}
+
static inline void io_insb(unsigned int addr, void *buf, int len)
{
volatile unsigned char *ap_b;
static inline void io_insl(unsigned int addr, void *buf, int len)
{
- volatile unsigned int *ap = (volatile unsigned int *) addr;
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
unsigned long *bp = (unsigned long *) buf;
while (len--)
*bp++ = _swapl(*ap);
}
+static inline void io_insw_noswap(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned short *ap = (volatile unsigned short *) addr;
+ unsigned short *bp = (unsigned short *) buf;
+ while (len--)
+ *bp++ = *ap;
+}
+
+static inline void io_insl_noswap(unsigned int addr, void *buf, int len)
+{
+ volatile unsigned long *ap = (volatile unsigned long *) addr;
+ unsigned long *bp = (unsigned long *) buf;
+ while (len--)
+ *bp++ = *ap;
+}
+
/*
* make the short names macros so specific devices
* can override them as required
#define inb(addr) ((h8300_buswidth(addr))?readw((addr) & ~1) & 0xff:readb(addr))
#define inw(addr) _swapw(readw(addr))
#define inl(addr) _swapl(readl(addr))
-#define outb(x,addr) ((void)((h8300_buswidth(addr) && ((addr) & 1))?writew(x,(addr) & ~1):writeb(x,addr)))
+#define outb(x,addr) ((void)((h8300_buswidth(addr) && \
+ ((addr) & 1))?writew(x,(addr) & ~1):writeb(x,addr)))
#define outw(x,addr) ((void) writew(_swapw(x),addr))
#define outl(x,addr) ((void) writel(_swapl(x),addr))
return *(volatile unsigned short*)addr;
}
-static __inline__ unsigned int ctrl_inl(unsigned long addr)
+static __inline__ unsigned long ctrl_inl(unsigned long addr)
{
return *(volatile unsigned long*)addr;
}
*(volatile unsigned short*)addr = b;
}
-static __inline__ void ctrl_outl(unsigned int b, unsigned long addr)
+static __inline__ void ctrl_outl(unsigned long b, unsigned long addr)
{
*(volatile unsigned long*)addr = b;
}
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
- { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#define FIX_ACPI_PAGES 4
extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
+extern int (*platform_rename_gsi)(int ioapic, int gsi);
+
#ifdef CONFIG_X86_IO_APIC
extern int skip_ioapic_setup;
extern int acpi_skip_timer_override;
do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
}
+int get_physical_broadcast(void);
+
#ifdef CONFIG_X86_GOOD_APIC
# define FORCE_READ_AROUND_WRITE 0
# define apic_read_around(x)
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-static __inline__ void set_bit(int nr, volatile unsigned long * addr)
+static inline void set_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
+static inline void __set_bit(int nr, volatile unsigned long * addr)
{
__asm__(
"btsl %1,%0"
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
-static __inline__ void clear_bit(int nr, volatile unsigned long * addr)
+static inline void clear_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
:"Ir" (nr));
}
-static __inline__ void __clear_bit(int nr, volatile unsigned long * addr)
+static inline void __clear_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__(
"btrl %1,%0"
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-static __inline__ void __change_bit(int nr, volatile unsigned long * addr)
+static inline void __change_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__(
"btcl %1,%0"
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-static __inline__ void change_bit(int nr, volatile unsigned long * addr)
+static inline void change_bit(int nr, volatile unsigned long * addr)
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr)
+static inline int test_and_set_bit(int nr, volatile unsigned long * addr)
{
int oldbit;
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr)
+static inline int __test_and_set_bit(int nr, volatile unsigned long * addr)
{
int oldbit;
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr)
+static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
{
int oldbit;
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
-static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
{
int oldbit;
}
/* WARNING: non atomic and it can be reordered! */
-static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
{
int oldbit;
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static __inline__ int test_and_change_bit(int nr, volatile unsigned long* addr)
+static inline int test_and_change_bit(int nr, volatile unsigned long* addr)
{
int oldbit;
return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
}
-static __inline__ int variable_test_bit(int nr, const volatile unsigned long * addr)
+static inline int variable_test_bit(int nr, const volatile unsigned long * addr)
{
int oldbit;
* Returns the bit-number of the first zero bit, not the number of the byte
* containing a bit.
*/
-static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned size)
+static inline int find_first_zero_bit(const unsigned long *addr, unsigned size)
{
int d0, d1, d2;
int res;
return res;
}
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+int find_next_zero_bit(const unsigned long *addr, int size, int offset);
+
/**
* find_first_bit - find the first set bit in a memory region
* @addr: The address to start the search at
* Returns the bit-number of the first set bit, not the number of the byte
* containing a bit.
*/
-static __inline__ int find_first_bit(const unsigned long *addr, unsigned size)
+static inline int find_first_bit(const unsigned long *addr, unsigned size)
{
int d0, d1;
int res;
return res;
}
-/**
- * find_next_zero_bit - find the first zero bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-static __inline__ int find_next_zero_bit(const unsigned long *addr, int size, int offset)
-{
- unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
- int set = 0, bit = offset & 31, res;
-
- if (bit) {
- /*
- * Look for zero in the first 32 bits.
- */
- __asm__("bsfl %1,%0\n\t"
- "jne 1f\n\t"
- "movl $32, %0\n"
- "1:"
- : "=r" (set)
- : "r" (~(*p >> bit)));
- if (set < (32 - bit))
- return set + offset;
- set = 32 - bit;
- p++;
- }
- /*
- * No zero yet, search remaining full bytes for a zero
- */
- res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
- return (offset + set + res);
-}
-
/**
* find_next_bit - find the first set bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
-static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset)
-{
- const unsigned long *p = addr + (offset >> 5);
- int set = 0, bit = offset & 31, res;
-
- if (bit) {
- /*
- * Look for nonzero in the first 32 bits:
- */
- __asm__("bsfl %1,%0\n\t"
- "jne 1f\n\t"
- "movl $32, %0\n"
- "1:"
- : "=r" (set)
- : "r" (*p >> bit));
- if (set < (32 - bit))
- return set + offset;
- set = 32 - bit;
- p++;
- }
- /*
- * No set bit yet, search remaining full words for a bit
- */
- res = find_first_bit (p, size - 32 * (p - addr));
- return (offset + set + res);
-}
+int find_next_bit(const unsigned long *addr, int size, int offset);
/**
* ffz - find first zero in word.
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
-static __inline__ unsigned long ffz(unsigned long word)
+static inline unsigned long ffz(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
*
* Undefined if no bit exists, so code should check against 0 first.
*/
-static __inline__ unsigned long __ffs(unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
-static __inline__ int ffs(int x)
+static inline int ffs(int x)
{
int r;
* Copy and checksum to user
*/
#define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, char *dst,
- int len, int sum, int *err_ptr)
+static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src,
+ char __user *dst,
+ int len, int sum,
+ int *err_ptr)
{
if (access_ok(VERIFY_WRITE, dst, len))
return direct_csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
return -1; /* invalid checksum */
}
-static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
+static __inline__ unsigned int csum_and_copy_to_user(const char *src, char __user *dst,
int len, int sum, int *err_ptr)
{
if (access_ok(VERIFY_WRITE, dst, len)) {
extern void __delay(unsigned long loops);
#define udelay(n) (__builtin_constant_p(n) ? \
- ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
+ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
__udelay(n))
#define ndelay(n) (__builtin_constant_p(n) ? \
#ifndef _ASM_I386_DMA_MAPPING_H
#define _ASM_I386_DMA_MAPPING_H
+#include <linux/device.h>
+#include <linux/mm.h>
+
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/scatterlist.h>
static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
{
if((unsigned int) addr >= (unsigned int) high_memory)
- return vfree((void *)addr);
+ vfree((void *)addr);
else
free_pages(addr, get_order(size));
}
cpumask_t (*target_cpus)(void);
int int_delivery_mode;
int int_dest_mode;
- int apic_broadcast_id;
int ESR_DISABLE;
int apic_destination_logical;
unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
.probe = aprobe, \
.int_delivery_mode = INT_DELIVERY_MODE, \
.int_dest_mode = INT_DEST_MODE, \
- .apic_broadcast_id = APIC_BROADCAST_ID, \
.no_balance_irq = NO_BALANCE_IRQ, \
.no_ioapic_check = NO_IOAPIC_CHECK, \
.ESR_DISABLE = esr_disable, \
#define HPET_ID_LEGSUP 0x00008000
#define HPET_ID_NUMBER 0x00001f00
#define HPET_ID_REV 0x000000ff
+#define HPET_ID_NUMBER_SHIFT 8
#define HPET_CFG_ENABLE 0x001
#define HPET_CFG_LEGACY 0x002
+#define HPET_LEGACY_8254 2
+#define HPET_LEGACY_RTC 8
#define HPET_TN_ENABLE 0x004
#define HPET_TN_PERIODIC 0x008
#define __clear_fpu( tsk ) \
do { \
if ((tsk)->thread_info->status & TS_USEDFPU) { \
- asm volatile("fwait"); \
+ asm volatile("fnclex ; fwait"); \
(tsk)->thread_info->status &= ~TS_USEDFPU; \
stts(); \
} \
static __inline__ int ide_default_irq(unsigned long base)
{
switch (base) {
-#ifdef CONFIG_X86_PC9800
- case 0x640: return 9;
-#endif
case 0x1f0: return 14;
case 0x170: return 15;
case 0x1e8: return 11;
static __inline__ unsigned long ide_default_io_base(int index)
{
switch (index) {
-#ifdef CONFIG_X86_PC9800
- case 0:
- case 1: return 0x640;
-#else
case 0: return 0x1f0;
case 1: return 0x170;
case 2: return 0x1e8;
case 3: return 0x168;
case 4: return 0x1e0;
case 5: return 0x160;
-#endif
default:
return 0;
}
}
-#ifdef CONFIG_X86_PC9800
-static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
- unsigned long ctrl_port, int *irq)
-{
- unsigned long reg = data_port;
- int i;
-
- unsigned long increment = data_port == 0x640 ? 2 : 1;
-
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += increment;
- }
- if (ctrl_port) {
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
- } else if (data_port == 0x640) {
- hw->io_ports[IDE_CONTROL_OFFSET] = 0x74c;
- } else {
- hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
- }
- if (irq != NULL)
- *irq = 0;
- hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-#endif
-
#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
*(IO_APIC_BASE(apic)+4) = value;
}
-/*
- * Synchronize the IO-APIC and the CPU by doing
- * a dummy read from the IO-APIC
- */
-static inline void io_apic_sync(unsigned int apic)
-{
- (void) *(IO_APIC_BASE(apic)+4);
-}
-
/* 1 if "noapic" boot option passed */
extern int skip_ioapic_setup;
#define INT_DELIVERY_MODE dest_Fixed
#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
-#define APIC_BROADCAST_ID (0xff)
static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
{
return 0;
#ifndef __ASM_MACH_MPSPEC_H
#define __ASM_MACH_MPSPEC_H
-/*
- * a maximum of 16 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 16
-
#define MAX_IRQ_SOURCES 256
#define MAX_MP_BUSSES 32
#define __ASM_MACH_APIC_H
#include <mach_apicdef.h>
+#include <asm/smp.h>
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
#define INT_DELIVERY_MODE dest_LowestPrio
#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
-/*
- * this isn't really broadcast, just a (potentially inaccurate) upper
- * bound for valid physical APIC id's
- */
-#define APIC_BROADCAST_ID 0x0F
-
static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
{
return physid_isset(apicid, bitmap);
static inline int cpu_present_to_apicid(int mps_cpu)
{
- return mps_cpu;
+ if (mps_cpu < get_physical_broadcast())
+ return mps_cpu;
+ else
+ return BAD_APICID;
}
static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
#ifndef __ASM_MACH_MPSPEC_H
#define __ASM_MACH_MPSPEC_H
-/*
- * a maximum of 16 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 16
-
#define MAX_IRQ_SOURCES 256
#define MAX_MP_BUSSES 32
#define WAKE_SECONDARY_VIA_INIT
#endif
-#define APIC_BROADCAST_ID (0xff)
#define NO_IOAPIC_CHECK (1)
static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
#ifndef __ASM_MACH_MPSPEC_H
#define __ASM_MACH_MPSPEC_H
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
#define MAX_IRQ_SOURCES 256
#define MAX_MP_BUSSES 32
#define esr_disable (genapic->ESR_DISABLE)
#define NO_BALANCE_IRQ (genapic->no_balance_irq)
#define NO_IOAPIC_CHECK (genapic->no_ioapic_check)
-#define APIC_BROADCAST_ID (genapic->apic_broadcast_id)
#define INT_DELIVERY_MODE (genapic->int_delivery_mode)
#define INT_DEST_MODE (genapic->int_dest_mode)
#undef APIC_DEST_LOGICAL
#ifndef __ASM_MACH_MPSPEC_H
#define __ASM_MACH_MPSPEC_H
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
#define MAX_IRQ_SOURCES 256
/* Summit or generic (i.e. installer) kernels need lots of bus entries. */
#define INT_DELIVERY_MODE dest_LowestPrio
#define INT_DEST_MODE 0 /* physical delivery on LOCAL quad */
-#define APIC_BROADCAST_ID 0x0F
#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap)
#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map)
#define apicid_cluster(apicid) (apicid & 0xF0)
#ifndef __ASM_MACH_MPSPEC_H
#define __ASM_MACH_MPSPEC_H
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
#define MAX_IRQ_SOURCES 512
#define MAX_MP_BUSSES 32
#define INT_DELIVERY_MODE (dest_Fixed)
#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
-#define APIC_BROADCAST_ID (0xFF)
static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
{
return 0;
#ifndef __ASM_MACH_MPSPEC_H
#define __ASM_MACH_MPSPEC_H
-/*
- * a maximum of 256 APICs with the current APIC ID architecture.
- */
-#define MAX_APICS 256
-
#define MAX_IRQ_SOURCES 256
/* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */
#define TARGET_CPUS cpumask_of_cpu(0)
#endif
-#define APIC_BROADCAST_ID 0x0F
#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap)
#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map)
static inline int cpu_present_to_apicid(int mps_cpu)
{
- return mps_cpu;
+ if (mps_cpu < get_physical_broadcast())
+ return mps_cpu;
+ else
+ return BAD_APICID;
}
static inline physid_mask_t apicid_to_cpu_present(int apicid)
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void);
-extern void mp_parse_prt (void);
+extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
#endif /*CONFIG_ACPI_BOOT*/
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
#define MAX_MPC_ENTRY 1024
+#define MAX_APICS 256
struct intel_mp_floating
{
#ifdef CONFIG_SMP
#define MSI_TARGET_CPU logical_smp_processor_id()
#else
-#define MSI_TARGET_CPU TARGET_CPUS
+#define MSI_TARGET_CPU cpu_to_logical_apicid(first_cpu(cpu_online_map))
#endif
#endif /* ASM_MSI_H */
static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
-static inline int ptep_test_and_clear_dirty(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
-static inline int ptep_test_and_clear_young(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); }
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+ if (!pte_dirty(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+ if (!pte_young(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
+}
+
static inline void ptep_set_wrprotect(pte_t *ptep) { clear_bit(_PAGE_BIT_RW, &ptep->pte_low); }
static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
/*
* Bus types (default is ISA, but people can check others with these..)
- * pc98 indicates PC98 systems (CBUS)
*/
extern int MCA_bus;
-#ifdef CONFIG_X86_PC9800
-#define pc98 1
-#else
-#define pc98 0
-#endif
static inline void __monitor(const void *eax, unsigned long ecx,
unsigned long edx)
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+
+#define RLIM_NLIMITS 13
-#define RLIM_NLIMITS 11
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
- { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-#ifndef CONFIG_X86_PC9800
#define STD_SERIAL_PORT_DEFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
-#else
-#define STD_SERIAL_PORT_DEFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x30, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x238, 5, STD_COM_FLAGS }, /* ttyS1 */
-#endif /* CONFIG_X86_PC9800 */
#ifdef CONFIG_SERIAL_MANY_PORTS
#include <linux/config.h>
#include <asm/msr.h>
-#ifdef CONFIG_X86_PC9800
- extern int CLOCK_TICK_RATE;
-#else
#ifdef CONFIG_X86_ELAN
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
#else
# define CLOCK_TICK_RATE 1193182 /* Underlying HZ */
#endif
-#endif
#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#include <linux/compiler.h>
#include <linux/types.h>
-
+#include <asm/bitops.h>
#include <asm/intrinsics.h>
/**
#endif /* __KERNEL__ */
-/*
- * Find next zero bit in a bitmap reasonably efficiently..
- */
-static inline int
-find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if (offset) {
- tmp = *(p++);
- tmp |= ~0UL >> (64-offset);
- if (size < 64)
- goto found_first;
- if (~tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while (size & ~63UL) {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if (!size)
- return result;
- tmp = *p;
-found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) /* any bits zero? */
- return result + size; /* nope */
-found_middle:
- return result + ffz(tmp);
-}
+extern int __find_next_zero_bit (void *addr, unsigned long size,
+ unsigned long offset);
+extern int __find_next_bit(const void *addr, unsigned long size,
+ unsigned long offset);
+
+#define find_next_zero_bit(addr, size, offset) \
+ __find_next_zero_bit((addr), (size), (offset))
+#define find_next_bit(addr, size, offset) \
+ __find_next_bit((addr), (size), (offset))
/*
* The optimizer actually does good code for this case..
*/
#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
-/*
- * Find next bit in a bitmap reasonably efficiently..
- */
-static inline int
-find_next_bit(const void *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if (offset) {
- tmp = *(p++);
- tmp &= ~0UL << offset;
- if (size < 64)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while (size & ~63UL) {
- if ((tmp = *(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if (!size)
- return result;
- tmp = *p;
- found_first:
- tmp &= ~0UL >> (64-size);
- if (tmp == 0UL) /* Are any bits set? */
- return result + size; /* Nope. */
- found_middle:
- return result + __ffs(tmp);
-}
-
#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
#ifdef __KERNEL__
unsigned int gsi_base);
extern int gsi_to_vector (unsigned int gsi);
extern int gsi_to_irq (unsigned int gsi);
-extern void __init iosapic_parse_prt (void);
extern void iosapic_enable_intr (unsigned int vector);
extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
unsigned long trigger);
ptep_test_and_clear_young (pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_young(*ptep))
+ return 0;
return test_and_clear_bit(_PAGE_A_BIT, ptep);
#else
pte_t pte = *ptep;
ptep_test_and_clear_dirty (pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_dirty(*ptep))
+ return 0;
return test_and_clear_bit(_PAGE_D_BIT, ptep);
#else
pte_t pte = *ptep;
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
# endif /* __KERNEL__ */
* the latest fph state from another CPU. In other words: eager save, lazy restore.
*/
# define switch_to(prev,next,last) do { \
- if (ia64_psr(ia64_task_regs(prev))->mfh) { \
+ if (ia64_psr(ia64_task_regs(prev))->mfh && ia64_is_local_fpu_owner(prev)) { \
ia64_psr(ia64_task_regs(prev))->mfh = 0; \
(prev)->thread.flags |= IA64_THREAD_FPH_VALID; \
__ia64_save_fpu((prev)->thread.fph); \
#define __NR_mq_notify 1266
#define __NR_mq_getsetattr 1267
#define __NR_kexec_load 1268
+#define __NR_vserver 1269
#ifdef __KERNEL__
# define __ARCH_WANT_SYS_SIGPENDING
# define __ARCH_WANT_SYS_SIGPROCMASK
#endif
+# define __ARCH_WANT_SYS_RT_SIGACTION
#if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
- { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
* Copy and checksum to user
*/
#define HAVE_CSUM_COPY_USER
-static inline unsigned int csum_and_copy_to_user (const char *src, char *dst,
+static inline unsigned int csum_and_copy_to_user (const char *src,
+ char __user *dst,
int len, int sum,
int *err_ptr)
{
#define RLIMIT_NPROC 8 /* max number of processes */
#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11 /* Number of limit flavors. */
+#define RLIM_NLIMITS 13 /* Number of limit flavors. */
#ifdef __KERNEL__
{ 0, 0 }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
# ifndef __mips64
# define __ARCH_WANT_STAT64
# endif
* Copy and checksum to user
*/
#define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
- int len, int sum, int *err_ptr)
+static __inline__ unsigned int csum_and_copy_to_user (const char *src,
+ char __user *dst,
+ int len, int sum,
+ int *err_ptr)
{
/* code stolen from include/asm-mips64 */
sum = csum_partial(src, len, sum);
static inline int ptep_test_and_clear_young(pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_young(*ptep))
+ return 0;
return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), ptep);
#else
pte_t pte = *ptep;
static inline int ptep_test_and_clear_dirty(pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_dirty(*ptep))
+ return 0;
return test_and_clear_bit(xlate_pabit(_PAGE_DIRTY_BIT), ptep);
#else
pte_t pte = *ptep;
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
/* mmap & mmap2 take 6 arguments */
: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
-#define BUG_ON(x) do { \
- __asm__ __volatile__( \
- "1: twnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%1,%2,%3\n" \
- ".previous" \
- : : "r" (x), "i" (__LINE__), "i" (__FILE__), \
- "i" (__FUNCTION__)); \
+#define BUG_ON(x) do { \
+ if (!__builtin_constant_p(x) || (x)) { \
+ __asm__ __volatile__( \
+ "1: twnei %0,0\n" \
+ ".section __bug_table,\"a\"\n\t" \
+ " .long 1b,%1,%2,%3\n" \
+ ".previous" \
+ : : "r" (x), "i" (__LINE__), "i" (__FILE__), \
+ "i" (__FUNCTION__)); \
+ } \
} while (0)
-#define PAGE_BUG(page) do { BUG(); } while (0)
+#define PAGE_BUG(page) BUG()
-#define WARN_ON(x) do { \
- __asm__ __volatile__( \
- "1: twnei %0,0\n" \
- ".section __bug_table,\"a\"\n\t" \
- " .long 1b,%1,%2,%3\n" \
- ".previous" \
- : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
- "i" (__FILE__), "i" (__FUNCTION__)); \
+#define WARN_ON(x) do { \
+ if (!__builtin_constant_p(x) || (x)) { \
+ __asm__ __volatile__( \
+ "1: twnei %0,0\n" \
+ ".section __bug_table,\"a\"\n\t" \
+ " .long 1b,%1,%2,%3\n" \
+ ".previous" \
+ : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
+ "i" (__FILE__), "i" (__FUNCTION__)); \
+ } \
} while (0)
#endif
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
#define ELF_NFPREG 33 /* includes fpscr */
#define ELF_NVRREG 33 /* includes vscr */
+#define ELF_NEVRREG 34 /* includes acc (as 2) */
/*
* These are used to set parameters in the core dumps.
#ifdef CONFIG_PREEMPT
# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+# define preemptible() (preempt_count() == 0 && !irqs_disabled())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+
#else
# define in_atomic() (preempt_count() != 0)
+# define preemptible() 0
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
+
#define irq_exit() \
do { \
preempt_count() -= IRQ_EXIT_OFFSET; \
#include <asm/mpc8xx.h>
#elif defined(CONFIG_8260)
#include <asm/mpc8260.h>
+#elif defined(CONFIG_85xx)
+#include <asm/mpc85xx.h>
#elif defined(CONFIG_APUS)
#define _IO_BASE 0
#define _ISA_MEM_BASE 0
#define PPC44x_TLB_SW 0x00000002 /* Super write */
#define PPC44x_TLB_SR 0x00000001 /* Super read */
+/* Book-E defined page sizes */
+#define BOOKE_PAGESZ_1K 0
+#define BOOKE_PAGESZ_4K 1
+#define BOOKE_PAGESZ_16K 2
+#define BOOKE_PAGESZ_64K 3
+#define BOOKE_PAGESZ_256K 4
+#define BOOKE_PAGESZ_1M 5
+#define BOOKE_PAGESZ_4M 6
+#define BOOKE_PAGESZ_16M 7
+#define BOOKE_PAGESZ_64M 8
+#define BOOKE_PAGESZ_256M 9
+#define BOOKE_PAGESZ_1GB 10
+#define BOOKE_PAGESZ_4GB 11
+#define BOOKE_PAGESZ_16GB 12
+#define BOOKE_PAGESZ_64GB 13
+#define BOOKE_PAGESZ_256GB 14
+#define BOOKE_PAGESZ_1TB 15
+
+/*
+ * Freescale Book-E MMU support
+ */
+
+#define MAS0_TLBSEL 0x10000000
+#define MAS0_ESEL 0x000F0000
+#define MAS0_NV 0x00000001
+
+#define MAS1_VALID 0x80000000
+#define MAS1_IPROT 0x40000000
+#define MAS1_TID 0x03FF0000
+#define MAS1_TS 0x00001000
+#define MAS1_TSIZE(x) (x << 8)
+
+#define MAS2_EPN 0xFFFFF000
+#define MAS2_SHAREN 0x00000200
+#define MAS2_X0 0x00000040
+#define MAS2_X1 0x00000020
+#define MAS2_W 0x00000010
+#define MAS2_I 0x00000008
+#define MAS2_M 0x00000004
+#define MAS2_G 0x00000002
+#define MAS2_E 0x00000001
+
+#define MAS3_RPN 0xFFFFF000
+#define MAS3_U0 0x00000200
+#define MAS3_U1 0x00000100
+#define MAS3_U2 0x00000080
+#define MAS3_U3 0x00000040
+#define MAS3_UX 0x00000020
+#define MAS3_SX 0x00000010
+#define MAS3_UW 0x00000008
+#define MAS3_SW 0x00000004
+#define MAS3_UR 0x00000002
+#define MAS3_SR 0x00000001
+
+#define MAS4_TLBSELD 0x10000000
+#define MAS4_TIDDSEL 0x00030000
+#define MAS4_DSHAREN 0x00001000
+#define MAS4_TSIZED(x) (x << 8)
+#define MAS4_X0D 0x00000040
+#define MAS4_X1D 0x00000020
+#define MAS4_WD 0x00000010
+#define MAS4_ID 0x00000008
+#define MAS4_MD 0x00000004
+#define MAS4_GD 0x00000002
+#define MAS4_ED 0x00000001
+
+#define MAS6_SPID 0x00FF0000
+#define MAS6_SAS 0x00000001
#endif /* _PPC_MMU_H_ */
#endif /* __KERNEL__ */
#define LAST_CONTEXT 255
#define FIRST_CONTEXT 1
+#elif CONFIG_E500
+#define NO_CONTEXT 256
+#define LAST_CONTEXT 255
+#define FIRST_CONTEXT 1
+
#else
/* PPC 6xx, 7xx CPUs */
#include <platforms/est8260.h>
#endif
+#ifdef CONFIG_SBC82xx
+#include <platforms/sbc82xx.h>
+#endif
+
#ifdef CONFIG_SBS8260
#include <platforms/sbs8260.h>
#endif
#include <asm/ibm_ocp.h>
#endif
+#ifdef CONFIG_FSL_OCP
+#include <asm/fsl_ocp.h>
+#endif
+
#endif /* CONFIG_PPC_OCP */
#endif /* __OCP_H__ */
#endif /* __KERNEL__ */
/* Memory devices 0x0090 - 0x009F */
#define OCP_FUNC_MAL 0x0090
+#define OCP_FUNC_DMA 0x0091
/* Display 0x00A0 - 0x00AF */
/* Network 0x0200 - 0x02FF */
#define OCP_FUNC_EMAC 0x0200
-#define OCP_FUNC_ENET 0x0201 /* TSEC & FEC */
+#define OCP_FUNC_GFAR 0x0201 /* TSEC & FEC */
/* Bridge devices 0xE00 - 0xEFF */
#define OCP_FUNC_OPB 0x0E00
/* ERPN in a PTE never gets cleared, ignore it */
#define _PTE_NONE_MASK 0xffffffff00000000ULL
+#elif defined(CONFIG_E500)
+
+/*
+ MMU Assist Register 3:
+
+ 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+ RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+ - PRESENT *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+
+ - FILE *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+*/
+
+/* Definitions for e500 core */
+#define _PAGE_PRESENT 0x001 /* S: PTE contains a translation */
+#define _PAGE_USER 0x002 /* S: User page (maps to UR) */
+#define _PAGE_FILE 0x002 /* S: when !present: nonlinear file mapping */
+#define _PAGE_ACCESSED 0x004 /* S: Page referenced */
+#define _PAGE_HWWRITE 0x008 /* H: Dirty & RW, set in exception */
+#define _PAGE_RW 0x010 /* S: Write permission */
+#define _PAGE_HWEXEC 0x020 /* H: UX permission */
+
+#define _PAGE_ENDIAN 0x040 /* H: E bit */
+#define _PAGE_GUARDED 0x080 /* H: G bit */
+#define _PAGE_COHERENT 0x100 /* H: M bit */
+#define _PAGE_NO_CACHE 0x200 /* H: I bit */
+#define _PAGE_WRITETHRU 0x400 /* H: W bit */
+#define _PAGE_DIRTY 0x800 /* S: Page dirty */
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+#define NUM_TLBCAMS (16)
+
#elif defined(CONFIG_8xx)
/* Definitions for 8xx embedded chips. */
#define _PAGE_PRESENT 0x0001 /* Page is valid */
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
pte_update(ptep, 0, bits);
}
+
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
- __ptep_set_access_flags(__ptep, __entry, __dirty)
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
/*
* Macro to mark a page protection value as "uncacheable".
#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base)
#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base)
+#define SAVE_EVR(n,s,base) evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
+#define SAVE_2EVR(n,s,base) SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
+#define SAVE_4EVR(n,s,base) SAVE_2EVR(n,s,base); SAVE_2EVR(n+2,s,base)
+#define SAVE_8EVR(n,s,base) SAVE_4EVR(n,s,base); SAVE_4EVR(n+4,s,base)
+#define SAVE_16EVR(n,s,base) SAVE_8EVR(n,s,base); SAVE_8EVR(n+8,s,base)
+#define SAVE_32EVR(n,s,base) SAVE_16EVR(n,s,base); SAVE_16EVR(n+16,s,base)
+
+#define REST_EVR(n,s,base) lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
+#define REST_2EVR(n,s,base) REST_EVR(n,s,base); REST_EVR(n+1,s,base)
+#define REST_4EVR(n,s,base) REST_2EVR(n,s,base); REST_2EVR(n+2,s,base)
+#define REST_8EVR(n,s,base) REST_4EVR(n,s,base); REST_4EVR(n+4,s,base)
+#define REST_16EVR(n,s,base) REST_8EVR(n,s,base); REST_8EVR(n+8,s,base)
+#define REST_32EVR(n,s,base) REST_16EVR(n,s,base); REST_16EVR(n+16,s,base)
+
#ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC \
BEGIN_FTR_SECTION \
bdnz 0b
#endif
-#if !defined(CONFIG_44x)
+#ifdef CONFIG_BOOKE
+#define tophys(rd,rs) \
+ addis rd,rs,0
+
+#define tovirt(rd,rs) \
+ addis rd,rs,0
+
+#else /* CONFIG_BOOKE */
/*
* On APUS (Amiga PowerPC cpu upgrade board), we don't know the
* physical base address of RAM at compile time.
.align 1; \
.long 0b; \
.previous
-#else /* CONFIG_44x */
-
-#define tophys(rd,rs) \
- mr rd,rs
-
-#define tovirt(rd,rs) \
- mr rd,rs
-
-#endif /* CONFIG_44x */
+#endif /* CONFIG_BOOKE */
/*
* On 64-bit cpus, we use the rfid instruction instead of rfi, but
#define vr30 30
#define vr31 31
+#define evr0 0
+#define evr1 1
+#define evr2 2
+#define evr3 3
+#define evr4 4
+#define evr5 5
+#define evr6 6
+#define evr7 7
+#define evr8 8
+#define evr9 9
+#define evr10 10
+#define evr11 11
+#define evr12 12
+#define evr13 13
+#define evr14 14
+#define evr15 15
+#define evr16 16
+#define evr17 17
+#define evr18 18
+#define evr19 19
+#define evr20 20
+#define evr21 21
+#define evr22 22
+#define evr23 23
+#define evr24 24
+#define evr25 25
+#define evr26 26
+#define evr27 27
+#define evr28 28
+#define evr29 29
+#define evr30 30
+#define evr31 31
+
/* some stab codes */
#define N_FUN 36
#define N_RSYM 64
unsigned long bi_flashoffset; /* reserved area for startup monitor */
unsigned long bi_sramstart; /* start of SRAM memory */
unsigned long bi_sramsize; /* size of SRAM memory */
-#if defined(CONFIG_8xx) || defined(CONFIG_8260)
+#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_85xx)
unsigned long bi_immr_base; /* base of IMMR register */
#endif
unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
#if defined(CONFIG_HYMOD)
hymod_conf_t bi_hymod_conf; /* hymod configuration information */
#endif
-#if defined(CONFIG_EVB64260)
+#if defined(CONFIG_EVB64260) || defined(CONFIG_85xx)
/* the board has three onboard ethernet ports */
unsigned char bi_enet1addr[6];
unsigned char bi_enet2addr[6];
.globl n;\
n:
+/*
+ * this is the minimum allowable io space due to the location
+ * of the io areas on prep (first one at 0x80000000) but
+ * as soon as I get around to remapping the io areas with the BATs
+ * to match the mac we can raise this. -- Cort
+ */
+#define TASK_SIZE (CONFIG_TASK_SIZE)
+
#ifndef __ASSEMBLY__
#ifdef CONFIG_PPC_MULTIPLATFORM
extern int _machine;
/* Lazy FPU handling on uni-processor */
extern struct task_struct *last_task_used_math;
extern struct task_struct *last_task_used_altivec;
-
-/*
- * this is the minimum allowable io space due to the location
- * of the io areas on prep (first one at 0x80000000) but
- * as soon as I get around to remapping the io areas with the BATs
- * to match the mac we can raise this. -- Cort
- */
-#define TASK_SIZE (CONFIG_TASK_SIZE)
+extern struct task_struct *last_task_used_spe;
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
void *pgdir; /* root of page-table tree */
int fpexc_mode; /* floating-point exception mode */
signed long last_syscall;
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
unsigned long dbcr0; /* debug control register values */
unsigned long dbcr1;
#endif
unsigned long vrsave;
int used_vr; /* set if process has used altivec */
#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+ unsigned long evr[32]; /* upper 32-bits of SPE regs */
+ u64 acc; /* Accumulator */
+ unsigned long spefscr; /* SPE & eFP status */
+ int used_spe; /* set if process has used spe */
+#endif /* CONFIG_SPE */
};
#define ARCH_MIN_TASKALIGN 16
#define PTRACE_GETVRREGS 18
#define PTRACE_SETVRREGS 19
+/* Get/set all the upper 32-bits of the SPE registers, accumulator, and
+ * spefscr, in one go */
+#define PTRACE_GETEVRREGS 20
+#define PTRACE_SETEVRREGS 21
+
#endif
#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */
#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
+#ifndef SPRN_SVR
+#define SPRN_SVR 0x11E /* System Version Register */
+#endif
#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */
/* these bits were defined in inverted endian sense originally, ugh, confusing */
#define THRM1_TIN (1 << 31)
#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */
#define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */
#define SRR3 SPRN_SRR3 /* Save and Restore Register 3 */
+#define SVR SPRN_SVR /* System Version Register */
#define ICTC SPRN_ICTC /* Instruction Cache Throttling Control Reg */
#define THRM1 SPRN_THRM1 /* Thermal Management Register 1 */
#define THRM2 SPRN_THRM2 /* Thermal Management Register 2 */
#define PVR_7400 0x000C0000
#define PVR_7410 0x800C0000
#define PVR_7450 0x80000000
+#define PVR_8540 0x80200000
+#define PVR_8560 0x80200000
/*
* For the 8xx processors, all of them report the same PVR family for
* the PowerPC core. The various versions of these processors must be
#define PVR_8245 0x80811014
#define PVR_8260 PVR_8240
+/* System Version Numbers */
+#define SVR_8540 0x80300000
+#define SVR_8541E 0x807A0000
+#define SVR_8555E 0x80790000
+#define SVR_8560 0x80700000
+
/* Segment Registers */
#define SR0 0
#define SR1 1
#ifndef __ASSEMBLY__
/* Device Control Registers */
-#define mfdcr(rn) mfdcr_or_dflt(rn, 0)
-#define mfdcr_or_dflt(rn,default_rval) \
- ({unsigned int rval; \
- if (rn == 0) \
- rval = default_rval; \
- else \
- asm volatile("mfdcr %0," __stringify(rn) : "=r" (rval)); \
+void __mtdcr(int reg, unsigned int val);
+unsigned int __mfdcr(int reg);
+#define mfdcr(rn) \
+ ({unsigned int rval; \
+ if (__builtin_constant_p(rn)) \
+ asm volatile("mfdcr %0," __stringify(rn) \
+ : "=r" (rval)); \
+ else \
+ rval = __mfdcr(rn); \
rval;})
-#define mtdcr(rn, v) \
-do { \
- if (rn != 0) \
- asm volatile("mtdcr " __stringify(rn) ",%0" : : "r" (v)); \
+#define mtdcr(rn, v) \
+do { \
+ if (__builtin_constant_p(rn)) \
+ asm volatile("mtdcr " __stringify(rn) ",%0" \
+ : : "r" (v)); \
+ else \
+ __mtdcr(rn, v); \
} while (0)
/* R/W of indirect DCRs make use of standard naming conventions for DCRs */
mtdcr(base ## _CFGADDR, base ## _ ## reg); \
mtdcr(base ## _CFGDATA, data); \
} while (0)
+
+/* Performance Monitor Registers */
+#define mfpmr(rn) ({unsigned int rval; \
+ asm volatile("mfpmr %0," __stringify(rn) \
+ : "=r" (rval)); rval;})
+#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
#endif /* __ASSEMBLY__ */
/* Machine State Register (MSR) Fields */
+#define MSR_UCLE (1<<26) /* User-mode cache lock enable */
+#define MSR_SPE (1<<25) /* Enable SPE */
#define MSR_DWE (1<<10) /* Debug Wait Enable */
+#define MSR_UBLE (1<<10) /* BTB lock enable (e500) */
#define MSR_IS MSR_IR /* Instruction Space */
#define MSR_DS MSR_DR /* Data Space */
+#define MSR_PMM (1<<2) /* Performance monitor mark bit */
/* Default MSR for kernel mode. */
#if defined (CONFIG_40x)
#define SPRN_IVOR13 0x19D /* Interrupt Vector Offset Register 13 */
#define SPRN_IVOR14 0x19E /* Interrupt Vector Offset Register 14 */
#define SPRN_IVOR15 0x19F /* Interrupt Vector Offset Register 15 */
+#define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */
+#define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */
+#define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */
+#define SPRN_IVOR32 0x210 /* Interrupt Vector Offset Register 32 */
+#define SPRN_IVOR33 0x211 /* Interrupt Vector Offset Register 33 */
+#define SPRN_IVOR34 0x212 /* Interrupt Vector Offset Register 34 */
+#define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */
#define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */
#define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */
#define SPRN_MCSR 0x23C /* Machine Check Status Register */
-#ifdef CONFIG_440A
-#define MCSR_MCS 0x80000000 /* Machine Check Summary */
-#define MCSR_IB 0x40000000 /* Instruction PLB Error */
-#define MCSR_DRB 0x20000000 /* Data Read PLB Error */
-#define MCSR_DWB 0x10000000 /* Data Write PLB Error */
-#define MCSR_TLBP 0x08000000 /* TLB Parity Error */
-#define MCSR_ICP 0x04000000 /* I-Cache Parity Error */
-#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */
-#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */
-#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */
-#endif
+#define SPRN_MCAR 0x23D /* Machine Check Address Register */
+#define SPRN_MAS0 0x270 /* MMU Assist Register 0 */
+#define SPRN_MAS1 0x271 /* MMU Assist Register 1 */
+#define SPRN_MAS2 0x272 /* MMU Assist Register 2 */
+#define SPRN_MAS3 0x273 /* MMU Assist Register 3 */
+#define SPRN_MAS4 0x274 /* MMU Assist Register 4 */
+#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */
+#define SPRN_MAS6 0x276 /* MMU Assist Register 6 */
+#define SPRN_PID1 0x279 /* Process ID Register 1 */
+#define SPRN_PID2 0x27A /* Process ID Register 2 */
+#define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */
+#define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */
#define SPRN_ZPR 0x3B0 /* Zone Protection Register (40x) */
#define SPRN_MMUCR 0x3B2 /* MMU Control Register */
#define SPRN_CCR0 0x3B3 /* Core Configuration Register */
#define SPRN_DCMP 0x3D1 /* Data TLB Compare Register */
#define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */
#define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */
+#define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */
+#define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */
#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */
#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */
+#define SPRN_SVR 0x3FF /* System Version Register */
/*
* SPRs which have conflicting definitions on true Book E versus classic,
*/
#ifdef CONFIG_BOOKE
#define SPRN_PID 0x030 /* Process ID */
+#define SPRN_PID0 SPRN_PID/* Process ID Register 0 */
#define SPRN_CSRR0 0x03A /* Critical Save and Restore Register 0 */
#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */
#define SPRN_DEAR 0x03D /* Data Error Address Register */
#define SPRN_CSRR1 SPRN_SRR3 /* Critical Save and Restore Register 1 */
#endif
+/* Bit definitions for the MCSR. */
+#ifdef CONFIG_440A
+#define MCSR_MCS 0x80000000 /* Machine Check Summary */
+#define MCSR_IB 0x40000000 /* Instruction PLB Error */
+#define MCSR_DRB 0x20000000 /* Data Read PLB Error */
+#define MCSR_DWB 0x10000000 /* Data Write PLB Error */
+#define MCSR_TLBP 0x08000000 /* TLB Parity Error */
+#define MCSR_ICP 0x04000000 /* I-Cache Parity Error */
+#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */
+#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */
+#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */
+#endif
+#ifdef CONFIG_E500
+#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
+#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */
+#define MCSR_DCP_PERR 0x20000000UL /* D-Cache Push Parity Error */
+#define MCSR_DCPERR 0x10000000UL /* D-Cache Parity Error */
+#define MCSR_GL_CI 0x00010000UL /* Guarded Load or Cache-Inhibited stwcx. */
+#define MCSR_BUS_IAERR 0x00000080UL /* Instruction Address Error */
+#define MCSR_BUS_RAERR 0x00000040UL /* Read Address Error */
+#define MCSR_BUS_WAERR 0x00000020UL /* Write Address Error */
+#define MCSR_BUS_IBERR 0x00000010UL /* Instruction Data Error */
+#define MCSR_BUS_RBERR 0x00000008UL /* Read Data Bus Error */
+#define MCSR_BUS_WBERR 0x00000004UL /* Write Data Bus Error */
+#define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */
+#define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */
+#endif
+
/* Bit definitions for the DBSR. */
/*
* DBSR bits which have conflicting definitions on true Book E versus IBM 40x.
#define DBSR_IC 0x08000000 /* Instruction Completion */
#define DBSR_BT 0x04000000 /* Branch Taken */
#define DBSR_TIE 0x01000000 /* Trap Instruction Event */
+#define DBSR_IAC1 0x00800000 /* Instr Address Compare 1 Event */
+#define DBSR_IAC2 0x00400000 /* Instr Address Compare 2 Event */
+#define DBSR_IAC3 0x00200000 /* Instr Address Compare 3 Event */
+#define DBSR_IAC4 0x00100000 /* Instr Address Compare 4 Event */
+#define DBSR_DAC1R 0x00080000 /* Data Addr Compare 1 Read Event */
+#define DBSR_DAC1W 0x00040000 /* Data Addr Compare 1 Write Event */
+#define DBSR_DAC2R 0x00020000 /* Data Addr Compare 2 Read Event */
+#define DBSR_DAC2W 0x00010000 /* Data Addr Compare 2 Write Event */
#endif
#ifdef CONFIG_40x
#define DBSR_IC 0x80000000 /* Instruction Completion */
#define DBSR_BT 0x40000000 /* Branch taken */
#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */
+#define DBSR_IAC1 0x00800000 /* Instruction Address Compare 1 Event */
+#define DBSR_IAC2 0x00400000 /* Instruction Address Compare 2 Event */
+#define DBSR_IAC3 0x00200000 /* Instruction Address Compare 3 Event */
+#define DBSR_IAC4 0x00100000 /* Instruction Address Compare 4 Event */
+#define DBSR_DAC1R 0x00080000 /* Data Address Compare 1 Read Event */
+#define DBSR_DAC1W 0x00040000 /* Data Address Compare 1 Write Event */
+#define DBSR_DAC2R 0x00020000 /* Data Address Compare 2 Read Event */
+#define DBSR_DAC2W 0x00010000 /* Data Address Compare 2 Write Event */
#endif
/* Bit definitions related to the ESR. */
#define ESR_DST 0x00800000 /* Storage Exception - Data miss */
#define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */
#define ESR_ST 0x00800000 /* Store Operation */
+#define ESR_DLK 0x00200000 /* Data Cache Locking */
+#define ESR_ILK 0x00100000 /* Instr. Cache Locking */
+#define ESR_BO 0x00020000 /* Byte Ordering */
/* Bit definitions related to the DBCR0. */
#define DBCR0_EDM 0x80000000 /* External Debug Mode */
#define ICCR_NOCACHE 0 /* Noncacheable */
#define ICCR_CACHE 1 /* Cacheable */
+/* Bit definitions for L1CSR0. */
+#define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */
+#define L1CSR0_DCE 0x00000001 /* Data Cache Enable */
+
+/* Bit definitions for L1CSR0. */
+#define L1CSR1_ICLFR 0x00000100 /* Instr Cache Lock Bits Flash Reset */
+#define L1CSR1_ICFI 0x00000002 /* Instr Cache Flash Invalidate */
+#define L1CSR1_ICE 0x00000001 /* Instr Cache Enable */
+
/* Bit definitions for SGR. */
#define SGR_NORMAL 0 /* Speculative fetching allowed. */
#define SGR_GUARDED 1 /* Speculative fetching disallowed. */
+/* Bit definitions for SPEFSCR. */
+#define SPEFSCR_SOVH 0x80000000 /* Summary integer overflow high */
+#define SPEFSCR_OVH 0x40000000 /* Integer overflow high */
+#define SPEFSCR_FGH 0x20000000 /* Embedded FP guard bit high */
+#define SPEFSCR_FXH 0x10000000 /* Embedded FP sticky bit high */
+#define SPEFSCR_FINVH 0x08000000 /* Embedded FP invalid operation high */
+#define SPEFSCR_FDBZH 0x04000000 /* Embedded FP div by zero high */
+#define SPEFSCR_FUNFH 0x02000000 /* Embedded FP underflow high */
+#define SPEFSCR_FOVFH 0x01000000 /* Embedded FP overflow high */
+#define SPEFSCR_FINXS 0x00200000 /* Embedded FP inexact sticky */
+#define SPEFSCR_FINVS 0x00100000 /* Embedded FP invalid op. sticky */
+#define SPEFSCR_FDBZS 0x00080000 /* Embedded FP div by zero sticky */
+#define SPEFSCR_FUNFS 0x00040000 /* Embedded FP underflow sticky */
+#define SPEFSCR_FOVFS 0x00020000 /* Embedded FP overflow sticky */
+#define SPEFSCR_MODE 0x00010000 /* Embedded FP mode */
+#define SPEFSCR_SOV 0x00008000 /* Integer summary overflow */
+#define SPEFSCR_OV 0x00004000 /* Integer overflow */
+#define SPEFSCR_FG 0x00002000 /* Embedded FP guard bit */
+#define SPEFSCR_FX 0x00001000 /* Embedded FP sticky bit */
+#define SPEFSCR_FINV 0x00000800 /* Embedded FP invalid operation */
+#define SPEFSCR_FDBZ 0x00000400 /* Embedded FP div by zero */
+#define SPEFSCR_FUNF 0x00000200 /* Embedded FP underflow */
+#define SPEFSCR_FOVF 0x00000100 /* Embedded FP overflow */
+#define SPEFSCR_FINXE 0x00000040 /* Embedded FP inexact enable */
+#define SPEFSCR_FINVE 0x00000020 /* Embedded FP invalid op. enable */
+#define SPEFSCR_FDBZE 0x00000010 /* Embedded FP div by zero enable */
+#define SPEFSCR_FUNFE 0x00000008 /* Embedded FP underflow enable */
+#define SPEFSCR_FOVFE 0x00000004 /* Embedded FP overflow enable */
+#define SPEFSCR_FRMC 0x00000003 /* Embedded FP rounding mode control */
+
/* Short-hand for various SPRs. */
#ifdef CONFIG_BOOKE
#define CSRR0 SPRN_CSRR0 /* Critical Save and Restore Register 0 */
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit(?) */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
#ifdef __KERNEL__
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#include <platforms/spruce.h>
#elif defined(CONFIG_4xx)
#include <asm/ibm4xx.h>
+#elif defined(CONFIG_85xx)
+#include <asm/mpc85xx.h>
#else
/*
extern void _raw_spin_lock(spinlock_t *lock);
extern void _raw_spin_unlock(spinlock_t *lock);
extern int _raw_spin_trylock(spinlock_t *lock);
-extern unsigned long __spin_trylock(volatile unsigned long *lock);
#endif
: "cr0", "memory");
}
+static __inline__ int _raw_write_trylock(rwlock_t *rw)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(
+"2: lwarx %0,0,%1 # write_trylock\n\
+ cmpwi 0,%0,0\n\
+ bne- 1f\n"
+ PPC405_ERR77(0,%1)
+" stwcx. %2,0,%1\n\
+ bne- 2b\n\
+ isync\n\
+1:"
+ : "=&r"(tmp)
+ : "r"(&rw->lock), "r"(-1)
+ : "cr0", "memory");
+
+ return tmp == 0;
+}
+
static __inline__ void _raw_write_lock(rwlock_t *rw)
{
unsigned int tmp;
extern void _raw_read_unlock(rwlock_t *rw);
extern void _raw_write_lock(rwlock_t *rw);
extern void _raw_write_unlock(rwlock_t *rw);
+extern int _raw_write_trylock(rwlock_t *rw);
#endif
extern void enable_kernel_fp(void);
extern void giveup_altivec(struct task_struct *);
extern void load_up_altivec(struct task_struct *);
+extern void giveup_spe(struct task_struct *);
+extern void load_up_spe(struct task_struct *);
extern int fix_alignment(struct pt_regs *);
extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
extern void cvt_df(double *from, float *to, unsigned long *fpscr);
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+ { _tlbie(vmaddr); }
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+ { __tlbia(); }
+static inline void flush_tlb_kernel_range(unsigned long start,
+ unsigned long end)
+ { __tlbia(); }
+
+#elif defined(CONFIG_FSL_BOOKE)
+
+/* TODO: determine if flush_tlb_range & flush_tlb_kernel_range
+ * are best implemented as tlbia vs specific tlbie's */
+
+#define __tlbia() _tlbia()
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+ { __tlbia(); }
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+ { _tlbie(vmaddr); }
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+ { _tlbie(vmaddr); }
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{ __tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{ _tlbie(vmaddr); }
+static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+ { _tlbie(vmaddr); }
static inline void flush_tlb_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{ __tlbia(); }
struct vm_area_struct;
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+extern void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
/*
* Forking from kernel space will result in the child getting a new,
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
- *
- * Use r13 for current since the ppc64 ABI reserves it - Anton
*/
#include <asm/thread_info.h>
-#define get_current() ((struct task_struct *)(get_paca()->xCurrent))
+#define get_current() (get_paca()->xCurrent)
#define current get_current()
#endif /* !(_PPC64_CURRENT_H) */
#ifdef CONFIG_PREEMPT
# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+# define preemptible() (preempt_count() == 0 && !irqs_disabled())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
# define in_atomic() (preempt_count() != 0)
+# define preemptible() 0
# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
#define irq_exit() \
static inline void out_be32(volatile unsigned *addr, int val)
{
- __asm__ __volatile__("stw%U0%X0 %1,%0; eieio"
+ __asm__ __volatile__("stw%U0%X0 %1,%0; sync"
: "=m" (*addr) : "r" (val));
}
: "=&r" (tmp) , "=&r" (val) : "1" (val) , "b" (addr) , "m" (*addr));
}
-static inline void out_be64(volatile unsigned long *addr, int val)
+static inline void out_be64(volatile unsigned long *addr, unsigned long val)
{
- __asm__ __volatile__("std %1,0(%0); sync" : "=m" (*addr) : "r" (val));
+ __asm__ __volatile__("std%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
}
#ifndef CONFIG_PPC_ISERIES
register struct paca_struct *local_paca asm("r13");
#define get_paca() local_paca
+struct task_struct;
+
/*============================================================================
* Name_______: paca
*
*/
struct ItLpPaca *xLpPacaPtr; /* Pointer to LpPaca for PLIC 0x00 */
struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC 0x08 */
- u64 xCurrent; /* Pointer to current 0x10 */
+ struct task_struct *xCurrent; /* Pointer to current 0x10 */
/* Note: the spinlock functions in arch/ppc64/lib/locks.c load lock_token and
xPacaIndex with a single lwz instruction, using the constant offset 24.
If you move either field, fix the spinlocks and rwlocks. */
u8 rsvd6[0x500 - 0x8];
/*=====================================================================================
- * CACHE_LINE_31 0x0F00 - 0x0F7F Exception stack
- *=====================================================================================
- */
- u8 exception_stack[N_EXC_STACK*EXC_FRAME_SIZE];
-
-/*=====================================================================================
- * CACHE_LINE_32 0x0F80 - 0x0FFF Reserved
+ * CACHE_LINE_31-32 0x0F00 - 0x0FFF Exception register save areas
*=====================================================================================
*/
- u8 rsvd7[0x80]; /* Give the stack some rope ... */
+ u64 exgen[8]; /* used for most interrupts/exceptions */
+ u64 exmc[8]; /* used for machine checks */
+ u64 exslb[8]; /* used for SLB/segment table misses
+ * on the linear mapping */
+ u64 exdsi[8]; /* used for linear mapping hash table misses */
/*=====================================================================================
- * Page 2 Reserved for guard page. Also used as a stack early in SMP boots before
- * relocation is enabled.
+ * Page 2 used as a stack when we detect a bad kernel stack pointer,
+ * and early in SMP boots before relocation is enabled.
*=====================================================================================
*/
- u8 guard[0x1000]; /* ... and then hang 'em */
+ u8 guard[0x1000];
};
#endif /* _PPC64_PACA_H */
DECLARE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
-static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage)
-{
- /* This is safe as we are holding page_table_lock */
- cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
- struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
-
- if (atomic_read(&tlb->mm->mm_users) < 2 ||
- cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
- pte_free(ptepage);
- return;
- }
-
- if (*batchp == NULL) {
- *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
- if (*batchp == NULL) {
- pte_free_now(ptepage);
- return;
- }
- (*batchp)->index = 0;
- }
- (*batchp)->pages[(*batchp)->index++] = ptepage;
- if ((*batchp)->index == PTE_FREELIST_SIZE) {
- pte_free_submit(*batchp);
- *batchp = NULL;
- }
-}
-
+void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage);
#define __pmd_free_tlb(tlb, pmd) __pte_free_tlb(tlb, virt_to_page(pmd))
#define check_pgt_cache() do { } while (0)
:"cc");
}
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
- __ptep_set_access_flags(__ptep, __entry, __dirty)
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
/*
* Macro to mark a page protection value as "uncacheable".
#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
+#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
+#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base)
+
#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base)
#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base)
#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
-#define CHECKANYINT(ra,rb) \
- mfspr rb,SPRG3; /* Get Paca address */\
- ld ra,PACALPPACA+LPPACAANYINT(rb); /* Get pending interrupt flags */\
- cmpldi 0,ra,0;
-
/* Macros to adjust thread priority for Iseries hardware multithreading */
#define HMT_LOW or 1,1,1
#define HMT_MEDIUM or 2,2,2
double fpr[32]; /* Complete floating point set */
unsigned long fpscr; /* Floating point status (plus pad) */
unsigned long fpexc_mode; /* Floating-point exception mode */
- unsigned long saved_msr; /* Save MSR across signal handlers */
- unsigned long saved_softe; /* Ditto for Soft Enable/Disable */
+ unsigned long pad[3]; /* was saved_msr, saved_softe */
#ifdef CONFIG_ALTIVEC
/* Complete AltiVec register set */
vector128 vr[32] __attribute((aligned(16)));
#define instruction_pointer(regs) ((regs)->nip)
#define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1)
+#define force_successful_syscall_return() \
+ (current_thread_info()->syscall_noerror = 1)
+
+/*
+ * We use the least-significant bit of the trap field to indicate
+ * whether we have saved the full set of registers, or only a
+ * partial set. A 1 there means the partial set.
+ */
+#define FULL_REGS(regs) (((regs)->trap & 1) == 0)
+#define TRAP(regs) ((regs)->trap & ~0xF)
+#define CHECK_FULL_REGS(regs) BUG_ON(regs->trap & 1)
+
/*
* Offsets used by 'ptrace' system call interface.
*/
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit(?) */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
#ifdef __KERNEL__
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
extern int _get_PVR(void);
extern void giveup_fpu(struct task_struct *);
extern void disable_kernel_fp(void);
+extern void flush_fp_to_thread(struct task_struct *);
+extern void flush_altivec_to_thread(struct task_struct *);
extern void enable_kernel_fp(void);
extern void giveup_altivec(struct task_struct *);
extern void disable_kernel_altivec(void);
(unsigned long)_n_, sizeof(*(ptr))); \
})
+/*
+ * We handle most unaligned accesses in hardware. On the other hand
+ * unaligned DMA can be very expensive on some ppc64 IO chips (it does
+ * powers of 2 writes until it reaches sufficient alignment).
+ *
+ * Based on this we disable the IP header alignment in network drivers.
+ */
+#define NET_IP_ALIGN 0
+
#endif /* __KERNEL__ */
#endif
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <asm/processor.h>
+#include <asm/page.h>
#include <linux/stringify.h>
/*
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
int cpu; /* cpu we're on */
- int preempt_count; /* not used at present */
+ int preempt_count;
struct restart_block restart_block;
+ /* set by force_successful_syscall_return */
+ unsigned char syscall_noerror;
};
/*
static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
- __asm__("clrrdi %0,1,14" : "=r"(ti));
+ __asm__("clrrdi %0,1,%1" : "=r"(ti) : "i" (THREAD_SHIFT));
return ti;
}
*
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
#define flush_tlb_mm(mm) flush_tlb_pending()
#define flush_tlb_page(vma, addr) flush_tlb_pending()
+#define flush_tlb_page_nohash(vma, addr) do { } while (0)
#define flush_tlb_range(vma, start, end) \
do { (void)(start); flush_tlb_pending(); } while (0)
#define flush_tlb_kernel_range(start, end) flush_tlb_pending()
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
unsigned long flags, unsigned long fd, off_t offset);
int vio_register_driver(struct vio_driver *drv);
void vio_unregister_driver(struct vio_driver *drv);
-const struct vio_device_id * vio_match_device(const struct vio_device_id *ids,
- const struct vio_dev *dev);
struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev);
void __devinit vio_unregister_device(struct vio_dev *dev);
const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length);
int vio_get_irq(struct vio_dev *dev);
-struct iommu_table * vio_build_iommu_table(struct vio_dev *dev);
int vio_enable_interrupts(struct vio_dev *dev);
int vio_disable_interrupts(struct vio_dev *dev);
* The vio_dev structure is used to describe virtual I/O devices.
*/
struct vio_dev {
- struct device_node *archdata; /* Open Firmware node */
- void *driver_data; /* data private to the driver */
struct iommu_table *iommu_table; /* vio_map_* uses this */
uint32_t unit_address;
unsigned int irq;
}
static __inline__ long long atomic64_inc_and_test(volatile atomic64_t * v)
{
- return __CSG_LOOP(v, 1, "agr") != 0;
+ return __CSG_LOOP(v, 1, "agr") == 0;
}
static __inline__ void atomic64_dec(volatile atomic64_t * v)
{
* Copy from userspace and compute checksum. If we catch an exception
* then zero the rest of the buffer.
*/
-static inline unsigned int
-csum_partial_copy_from_user (const char *src, char *dst,
+static inline unsigned int
+csum_partial_copy_from_user(const char __user *src, char *dst,
int len, unsigned int sum,
int *err_ptr)
{
*/
typedef u32 compat_uptr_t;
-static inline void *compat_ptr(compat_uptr_t uptr)
+static inline void __user *compat_ptr(compat_uptr_t uptr)
{
- return (void *)(unsigned long)(uptr & 0x7fffffffUL);
+ return (void __user *)(unsigned long)(uptr & 0x7fffffffUL);
}
-static inline void *compat_alloc_user_space(long len)
+static inline void __user *compat_alloc_user_space(long len)
{
unsigned long stack;
stack = KSTK_ESP(current);
if (test_thread_flag(TIF_31BIT))
stack &= 0x7fffffffUL;
- return (void *) (stack - len);
+ return (void __user *) (stack - len);
}
struct compat_ipc64_perm {
char* out_buf);
typedef int (debug_input_proc_t) (debug_info_t* id,
struct debug_view* view,
- struct file* file, const char* user_buf,
+ struct file* file,
+ const char __user *user_buf,
size_t in_buf_size, loff_t* offset);
int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view,
#define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
#endif /* DASD_DEBUG */
-#if DASD_DEBUG > 4
-#define INTERNAL_ERROR(x...) PRINT_FATAL ( INTERNAL_ERRMSG ( x ) )
-#elif DASD_DEBUG > 2
-#define INTERNAL_ERROR(x...) PRINT_ERR ( INTERNAL_ERRMSG ( x ) )
-#elif DASD_DEBUG > 0
-#define INTERNAL_ERROR(x...) PRINT_WARN ( INTERNAL_ERRMSG ( x ) )
-#else
-#define INTERNAL_ERROR(x...)
-#endif /* DASD_DEBUG */
-
-#if DASD_DEBUG > 5
-#define INTERNAL_CHECK(x...) PRINT_FATAL ( INTERNAL_CHKMSG ( x ) )
-#elif DASD_DEBUG > 3
-#define INTERNAL_CHECK(x...) PRINT_ERR ( INTERNAL_CHKMSG ( x ) )
-#elif DASD_DEBUG > 1
-#define INTERNAL_CHECK(x...) PRINT_WARN ( INTERNAL_CHKMSG ( x ) )
-#else
-#define INTERNAL_CHECK(x...)
-#endif /* DASD_DEBUG */
-
#undef DEBUG_MALLOC
#ifdef DEBUG_MALLOC
void *b;
* Copy count bytes from an idal buffer to user memory
*/
static inline size_t
-idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count)
+idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count)
{
size_t left;
int i;
left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE);
if (left)
return left + count - IDA_BLOCK_SIZE;
- to = (void *) to + IDA_BLOCK_SIZE;
+ to = (void __user *) to + IDA_BLOCK_SIZE;
count -= IDA_BLOCK_SIZE;
}
return copy_to_user(to, ib->data[i], count);
* Copy count bytes from user memory to an idal buffer
*/
static inline size_t
-idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count)
+idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count)
{
size_t left;
int i;
left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE);
if (left)
return left + count - IDA_BLOCK_SIZE;
- from = (void *) from + IDA_BLOCK_SIZE;
+ from = (void __user *) from + IDA_BLOCK_SIZE;
count -= IDA_BLOCK_SIZE;
}
return copy_from_user(ib->data[i], from, count);
* See arch/s390/kernel/sys_s390.c for ugly details..
*/
struct ipc_kludge {
- struct msgbuf *msgp;
+ struct msgbuf __user *msgp;
long msgtyp;
};
set_pte(ptep, entry);
}
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+ ptep_establish(__vma, __address, __ptep, __entry)
+
/*
* Test and clear dirty bit in storage key.
* We can't clear the changed bit atomically. This is a potential
__pte; \
})
-#define arch_set_page_uptodate(__page) \
+#define SetPageUptodate(_page) \
do { \
- asm volatile ("sske %0,%1" : : "d" (0), \
+ struct page *__page = (_page); \
+ if (!test_and_set_bit(PG_uptodate, &__page->flags)) \
+ asm volatile ("sske %0,%1" : : "d" (0), \
"a" (__pa((__page-mem_map) << PAGE_SHIFT)));\
} while (0)
#define pgtable_cache_init() do { } while (0)
#define __HAVE_ARCH_PTEP_ESTABLISH
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
*/
struct pt_regs
{
+ unsigned long args[1];
psw_t psw;
unsigned long gprs[NUM_GPRS];
unsigned long orig_gpr2;
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
-
-#define RLIM_NLIMITS 11
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define COMMAND_LINE_SIZE 896
#define RAMDISK_ORIGIN 0x800000
#define RAMDISK_SIZE 0x800000
+#define MEMORY_CHUNKS 16 /* max 0x7fff */
#ifndef __ASSEMBLY__
{
#ifndef __s390x__
unsigned int reg1, reg2;
- __asm__ __volatile(" bras %0,1f\n"
+ __asm__ __volatile__(" bras %0,1f\n"
"0: diag 0,0,68\n"
"1: slr %1,%1\n"
" cs %1,%0,0(%3)\n"
: "cc", "memory" );
#else /* __s390x__ */
unsigned long reg1, reg2;
- __asm__ __volatile(" bras %1,1f\n"
+ __asm__ __volatile__(" bras %1,1f\n"
"0: " __DIAG44_INSN " 0,%4\n"
"1: slr %0,%0\n"
" cs %0,%1,0(%3)\n"
unsigned long reg;
unsigned int result;
- __asm__ __volatile(" basr %1,0\n"
+ __asm__ __volatile__(" basr %1,0\n"
"0: cs %0,%1,0(%3)"
: "=d" (result), "=&d" (reg), "=m" (lp->lock)
: "a" (&lp->lock), "m" (lp->lock), "0" (0)
{
unsigned int old;
- __asm__ __volatile("cs %0,%3,0(%4)"
+ __asm__ __volatile__("cs %0,%3,0(%4)"
: "=d" (old), "=m" (lp->lock)
: "0" (lp->lock), "d" (0), "a" (lp)
: "cc", "memory" );
#include <linux/types.h>
#endif
-#define __HAVE_ARCH_MEMCHR
-#define __HAVE_ARCH_MEMCPY
-#define __HAVE_ARCH_MEMSET
-#define __HAVE_ARCH_STRCAT
-#define __HAVE_ARCH_STRCMP
-#define __HAVE_ARCH_STRCPY
-#define __HAVE_ARCH_STRLEN
-#define __HAVE_ARCH_STRNCPY
+#define __HAVE_ARCH_BCOPY /* arch function */
+#define __HAVE_ARCH_MEMCHR /* inline & arch function */
+#define __HAVE_ARCH_MEMCMP /* arch function */
+#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
+#define __HAVE_ARCH_MEMSCAN /* inline & arch function */
+#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
+#define __HAVE_ARCH_STRCAT /* inline & arch function */
+#define __HAVE_ARCH_STRCMP /* arch function */
+#define __HAVE_ARCH_STRCPY /* inline & arch function */
+#define __HAVE_ARCH_STRLCAT /* arch function */
+#define __HAVE_ARCH_STRLCPY /* arch function */
+#define __HAVE_ARCH_STRLEN /* inline & arch function */
+#define __HAVE_ARCH_STRNCAT /* arch function */
+#define __HAVE_ARCH_STRNCPY /* arch function */
+#define __HAVE_ARCH_STRNLEN /* inline & arch function */
+#define __HAVE_ARCH_STRRCHR /* arch function */
+#define __HAVE_ARCH_STRSTR /* arch function */
+
+/* Prototypes for non-inlined arch strings functions. */
+extern int memcmp(const void *, const void *, size_t);
+extern void *memcpy(void *, const void *, size_t);
+extern void *memset(void *, int, size_t);
+extern int strcmp(const char *,const char *);
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+extern char *strncat(char *, const char *, size_t);
+extern char *strncpy(char *, const char *, size_t);
+extern char *strrchr(const char *, int);
+extern char *strstr(const char *, const char *);
#undef __HAVE_ARCH_MEMMOVE
-#undef __HAVE_ARCH_STRNICMP
-#undef __HAVE_ARCH_STRNCAT
-#undef __HAVE_ARCH_STRNCMP
#undef __HAVE_ARCH_STRCHR
-#undef __HAVE_ARCH_STRRCHR
-#undef __HAVE_ARCH_STRNLEN
-#undef __HAVE_ARCH_STRSPN
+#undef __HAVE_ARCH_STRNCHR
+#undef __HAVE_ARCH_STRNCMP
+#undef __HAVE_ARCH_STRNICMP
#undef __HAVE_ARCH_STRPBRK
-#undef __HAVE_ARCH_STRTOK
-#undef __HAVE_ARCH_BCOPY
-#undef __HAVE_ARCH_MEMCMP
-#undef __HAVE_ARCH_MEMSCAN
-#undef __HAVE_ARCH_STRSTR
+#undef __HAVE_ARCH_STRSEP
+#undef __HAVE_ARCH_STRSPN
-extern void *memset(void *, int, size_t);
-extern void *memcpy(void *, const void *, size_t);
-extern void *memmove(void *, const void *, size_t);
-extern char *strncpy(char *, const char *, size_t);
-extern int strcmp(const char *,const char *);
+#if !defined(IN_ARCH_STRING_C)
-static inline void * memchr(const void * cs,int c,size_t count)
+static inline void *memchr(const void * s, int c, size_t n)
{
- void *ptr;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " lr 0,%2\n"
- " lr 1,%1\n"
- " la %0,0(%3,%1)\n"
- "0: srst %0,1\n"
- " jo 0b\n"
- " brc 13,1f\n"
- " slr %0,%0\n"
-#else /* __s390x__ */
- " lgr 0,%2\n"
- " lgr 1,%1\n"
- " la %0,0(%3,%1)\n"
- "0: srst %0,1\n"
- " jo 0b\n"
- " brc 13,1f\n"
- " slgr %0,%0\n"
-#endif /* __s390x__ */
- "1:"
- : "=&a" (ptr) : "a" (cs), "d" (c), "d" (count)
- : "cc", "0", "1" );
- return ptr;
+ register int r0 asm("0") = (char) c;
+ const void *ret = s + n;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b\n"
+ " jl 1f\n"
+ " la %0,0\n"
+ "1:"
+ : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+ return (void *) ret;
}
-static __inline__ char *strcpy(char *dest, const char *src)
+static inline void *memscan(void *s, int c, size_t n)
{
- char *tmp = dest;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " sr 0,0\n"
- "0: mvst %0,%1\n"
- " jo 0b"
-#else /* __s390x__ */
- " slgr 0,0\n"
- "0: mvst %0,%1\n"
- " jo 0b"
-#endif /* __s390x__ */
- : "+&a" (dest), "+&a" (src) :
- : "cc", "memory", "0" );
- return tmp;
+ register int r0 asm("0") = (char) c;
+ const void *ret = s + n;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b\n"
+ : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+ return (void *) ret;
}
-static __inline__ size_t strlen(const char *s)
+static inline char *strcat(char *dst, const char *src)
{
- size_t len;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " sr 0,0\n"
- " lr %0,%1\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lr %0,0\n"
- " sr %0,%1"
-#else /* __s390x__ */
- " slgr 0,0\n"
- " lgr %0,%1\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lgr %0,0\n"
- " sgr %0,%1"
-#endif /* __s390x__ */
- : "=&a" (len) : "a" (s)
- : "cc", "0" );
- return len;
+ register int r0 asm("0") = 0;
+ unsigned long dummy;
+ char *ret = dst;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b\n"
+ "1: mvst %0,%2\n"
+ " jo 1b"
+ : "=&a" (dummy), "+a" (dst), "+a" (src)
+ : "d" (r0), "0" (0) : "cc", "memory" );
+ return ret;
}
-static __inline__ char *strcat(char *dest, const char *src)
+static inline char *strcpy(char *dst, const char *src)
{
- char *tmp = dest;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " sr 0,0\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lr %0,0\n"
- " sr 0,0\n"
- "1: mvst %0,%1\n"
- " jo 1b"
-#else /* __s390x__ */
- " slgr 0,0\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lgr %0,0\n"
- " slgr 0,0\n"
- "1: mvst %0,%1\n"
- " jo 1b"
-#endif /* __s390x__ */
- : "+&a" (dest), "+&a" (src) :
- : "cc", "memory", "0" );
- return tmp;
+ register int r0 asm("0") = 0;
+ char *ret = dst;
+
+ asm volatile ("0: mvst %0,%1\n"
+ " jo 0b"
+ : "+&a" (dst), "+&a" (src) : "d" (r0)
+ : "cc", "memory" );
+ return ret;
}
-extern void *alloca(size_t);
+static inline size_t strlen(const char *s)
+{
+ register unsigned long r0 asm("0") = 0;
+ const char *tmp = s;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b"
+ : "+d" (r0), "+a" (tmp) : : "cc" );
+ return r0 - (unsigned long) s;
+}
+
+static inline size_t strnlen(const char * s, size_t n)
+{
+ register int r0 asm("0") = 0;
+ const char *tmp = s;
+ const char *end = s + n;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b"
+ : "+a" (end), "+a" (tmp) : "d" (r0) : "cc" );
+ return end - s;
+}
+
+#endif /* !IN_ARCH_STRING_C */
+
#endif /* __KERNEL__ */
#endif /* __S390_STRING_H_ */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTART_SVC 4 /* restart svc with new svc number */
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+#define TIF_SINGLE_STEP 6 /* single stepped svc */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT)
typedef u32 dma_addr_t;
+typedef unsigned int kmem_bufctl_t;
+
#ifndef __s390x__
typedef union {
unsigned long long pair;
#endif
#endif /* ! __s390x__ */
-
-typedef unsigned int kmem_bufctl_t;
-
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _S390_TYPES_H */
#define access_ok(type,addr,size) __access_ok(addr,size)
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+extern inline int verify_area(int type, const void __user *addr,
+ unsigned long size)
{
- return access_ok(type,addr,size)?0:-EFAULT;
+ return access_ok(type, addr, size) ? 0 : -EFAULT;
}
/*
})
#endif
+#ifndef __CHECKER__
#define __put_user(x, ptr) \
({ \
__typeof__(*(ptr)) __x = (x); \
} \
__pu_err; \
})
+#else
+#define __put_user(x, ptr) \
+({ \
+ void __user *p; \
+ p = (ptr); \
+ 0; \
+})
+#endif
#define put_user(x, ptr) \
({ \
})
#endif
+#ifndef __CHECKER__
#define __get_user(x, ptr) \
({ \
__typeof__(*(ptr)) __x; \
(x) = __x; \
__gu_err; \
})
+#else
+#define __get_user(x, ptr) \
+({ \
+ void __user *p; \
+ p = (ptr); \
+ 0; \
+})
+#endif
+
#define get_user(x, ptr) \
({ \
extern int __get_user_bad(void);
-extern long __copy_to_user_asm(const void *from, long n, void *to);
+extern long __copy_to_user_asm(const void *from, long n, void __user *to);
/**
* __copy_to_user: - Copy a block of data into user space, with less checking.
return n;
}
-extern long __copy_from_user_asm(void *to, long n, const void *from);
+extern long __copy_from_user_asm(void *to, long n, const void __user *from);
/**
* __copy_from_user: - Copy a block of data from user space, with less checking.
return n;
}
-extern long __copy_in_user_asm(const void *from, long n, void *to);
+extern unsigned long __copy_in_user_asm(const void __user *from, long n,
+ void __user *to);
static inline unsigned long
__copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
- __copy_in_user_asm(from, n, to);
+ return __copy_in_user_asm(from, n, to);
}
static inline unsigned long
/*
* Copy a null terminated string from userspace.
*/
-extern long __strncpy_from_user_asm(char *dst, const char *src, long count);
+extern long __strncpy_from_user_asm(long count, char *dst,
+ const char __user *src);
static inline long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
might_sleep();
if (access_ok(VERIFY_READ, src, 1))
- res = __strncpy_from_user_asm(dst, src, count);
+ res = __strncpy_from_user_asm(count, dst, src);
return res;
}
-extern long __strnlen_user_asm(const char *src, long count);
+extern long __strnlen_user_asm(long count, const char __user *src);
static inline unsigned long
-strnlen_user(const char * src, unsigned long n)
+strnlen_user(const char __user * src, unsigned long n)
{
might_sleep();
- return __strnlen_user_asm(src, n);
+ return __strnlen_user_asm(n, src);
}
/**
* Zero Userspace
*/
-extern long __clear_user_asm(void *to, long n);
+extern long __clear_user_asm(void __user *to, long n);
static inline unsigned long
-__clear_user(void *to, unsigned long n)
+__clear_user(void __user *to, unsigned long n)
{
return __clear_user_asm(to, n);
}
static inline unsigned long
-clear_user(void *to, unsigned long n)
+clear_user(void __user *to, unsigned long n)
{
might_sleep();
if (access_ok(VERIFY_WRITE, to, n))
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
# ifndef CONFIG_ARCH_S390X
# define __ARCH_WANT_STAT64
# endif
* Copy and checksum to user
*/
#define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
- int len, int sum, int *err_ptr)
+static __inline__ unsigned int csum_and_copy_to_user (const char *src,
+ char __user *dst,
+ int len, int sum,
+ int *err_ptr)
{
if (access_ok(VERIFY_WRITE, dst, len))
return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
#ifdef __KERNEL__
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
}
static inline unsigned int
-csum_partial_copy_to_user(const char *src, char *dst, int len,
+csum_partial_copy_to_user(const char *src, char __user *dst, int len,
unsigned int sum, int *err)
{
if (!access_ok (VERIFY_WRITE, dst, len)) {
#define _ASM_SPARC_DMA_MAPPING_H
#include <linux/config.h>
+#include <linux/device.h>
#ifdef CONFIG_PCI
#include <asm-generic/dma-mapping.h>
#include <asm/fixmap.h>
#include <asm/vaddrs.h>
#include <asm/kmap_types.h>
-#include <asm/pgtsrmmu.h>
+#include <asm/pgtable.h>
/* declarations for highmem.c */
extern unsigned long highstart_pfn, highend_pfn;
*/
#define LAST_PKMAP 1024
#define PKMAP_SIZE (LAST_PKMAP << PAGE_SHIFT)
-#define PKMAP_BASE SRMMU_PMD_ALIGN_SOFT(SRMMU_NOCACHE_VADDR + (SRMMU_MAX_NOCACHE_PAGES << PAGE_SHIFT))
+#define PKMAP_BASE PMD_ALIGN(SRMMU_NOCACHE_VADDR + (SRMMU_MAX_NOCACHE_PAGES << PAGE_SHIFT))
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
#define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT)
#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
#define mmu_translate_dvma(ba) BTFIXUP_CALL(mmu_translate_dvma)(ba)
-/*
- */
-BTFIXUPDEF_SIMM13(pmd_shift)
-BTFIXUPDEF_SETHI(pmd_size)
-BTFIXUPDEF_SETHI(pmd_mask)
-
-extern unsigned int pmd_align(unsigned int addr) __attribute_const__;
-extern __inline__ unsigned int pmd_align(unsigned int addr)
-{
- return ((addr + ~BTFIXUP_SETHI(pmd_mask)) & BTFIXUP_SETHI(pmd_mask));
-}
-
BTFIXUPDEF_SIMM13(pgdir_shift)
BTFIXUPDEF_SETHI(pgdir_size)
BTFIXUPDEF_SETHI(pgdir_mask)
-extern unsigned int pgdir_align(unsigned int addr) __attribute_const__;
-extern __inline__ unsigned int pgdir_align(unsigned int addr)
-{
- return ((addr + ~BTFIXUP_SETHI(pgdir_mask)) & BTFIXUP_SETHI(pgdir_mask));
-}
-
-BTFIXUPDEF_SIMM13(ptrs_per_pte)
BTFIXUPDEF_SIMM13(ptrs_per_pmd)
BTFIXUPDEF_SIMM13(ptrs_per_pgd)
BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
BTFIXUPDEF_INT(page_readonly)
BTFIXUPDEF_INT(page_kernel)
-#define PMD_SHIFT BTFIXUP_SIMM13(pmd_shift)
-#define PMD_SIZE BTFIXUP_SETHI(pmd_size)
-#define PMD_MASK BTFIXUP_SETHI(pmd_mask)
-#define PMD_ALIGN(addr) pmd_align(addr)
+#define PMD_SHIFT SUN4C_PMD_SHIFT
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+#define PMD_ALIGN(__addr) (((__addr) + ~PMD_MASK) & PMD_MASK)
#define PGDIR_SHIFT BTFIXUP_SIMM13(pgdir_shift)
#define PGDIR_SIZE BTFIXUP_SETHI(pgdir_size)
#define PGDIR_MASK BTFIXUP_SETHI(pgdir_mask)
-#define PGDIR_ALIGN pgdir_align(addr)
-#define PTRS_PER_PTE BTFIXUP_SIMM13(ptrs_per_pte)
+#define PTRS_PER_PTE 1024
#define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd)
#define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd)
#define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd)
#define FIRST_USER_PGD_NR 0
+#define PTE_SIZE (PTRS_PER_PTE*4)
#define PAGE_NONE __pgprot(BTFIXUP_INT(page_none))
#define PAGE_SHARED __pgprot(BTFIXUP_INT(page_shared))
#define SRMMU_MAX_CONTEXTS 65536
/* PMD_SHIFT determines the size of the area a second-level page table entry can map */
-#define SRMMU_PMD_SHIFT 18
-#define SRMMU_PMD_SIZE (1UL << SRMMU_PMD_SHIFT)
-#define SRMMU_PMD_MASK (~(SRMMU_PMD_SIZE-1))
-/* #define SRMMU_PMD_ALIGN(addr) (((addr)+SRMMU_PMD_SIZE-1)&SRMMU_PMD_MASK) */
+#define SRMMU_REAL_PMD_SHIFT 18
+#define SRMMU_REAL_PMD_SIZE (1UL << SRMMU_REAL_PMD_SHIFT)
+#define SRMMU_REAL_PMD_MASK (~(SRMMU_REAL_PMD_SIZE-1))
+#define SRMMU_REAL_PMD_ALIGN(__addr) (((__addr)+SRMMU_REAL_PMD_SIZE-1)&SRMMU_REAL_PMD_MASK)
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define SRMMU_PGDIR_SHIFT 24
#define SRMMU_PGDIR_MASK (~(SRMMU_PGDIR_SIZE-1))
#define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK)
-#define SRMMU_PTRS_PER_PTE 64
-#define SRMMU_PTRS_PER_PMD 64
-#define SRMMU_PTRS_PER_PGD 256
+#define SRMMU_REAL_PTRS_PER_PTE 64
+#define SRMMU_REAL_PTRS_PER_PMD 64
+#define SRMMU_PTRS_PER_PGD 256
-#define SRMMU_PTE_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */
-#define SRMMU_PMD_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */
-#define SRMMU_PGD_TABLE_SIZE 0x400 /* 256 entries, 4 bytes a piece */
+#define SRMMU_REAL_PTE_TABLE_SIZE (SRMMU_REAL_PTRS_PER_PTE*4)
+#define SRMMU_PMD_TABLE_SIZE (SRMMU_REAL_PTRS_PER_PMD*4)
+#define SRMMU_PGD_TABLE_SIZE (SRMMU_PTRS_PER_PGD*4)
/*
* To support pagetables in highmem, Linux introduces APIs which
* software tables.
*
* PMD_SHIFT determines the size of the area a second-level page table entry
- * can map, and our pmd_t is 16 times larger than normal.
+ * can map, and our pmd_t is 16 times larger than normal. The values which
+ * were once defined here are now generic for 4c and srmmu, so they're
+ * found in pgtable.h.
*/
-#define SRMMU_PTRS_PER_PTE_SOFT (PAGE_SIZE/4) /* 16 hard tables per 4K page */
-#define SRMMU_PTRS_PER_PMD_SOFT 4 /* Each pmd_t contains 16 hard PTPs */
-#define SRMMU_PTE_SZ_SOFT PAGE_SIZE /* same as above, in bytes */
-
-#define SRMMU_PMD_SHIFT_SOFT 22
-#define SRMMU_PMD_SIZE_SOFT (1UL << SRMMU_PMD_SHIFT_SOFT)
-#define SRMMU_PMD_MASK_SOFT (~(SRMMU_PMD_SIZE_SOFT-1))
-#define SRMMU_PMD_ALIGN_SOFT(addr) (((addr)+SRMMU_PMD_SIZE_SOFT-1)&SRMMU_PMD_MASK_SOFT)
+#define SRMMU_PTRS_PER_PMD 4
/* Definition of the values in the ET field of PTD's and PTE's */
#define SRMMU_ET_MASK 0x3
extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
{
- addr &= SRMMU_PMD_MASK;
+ addr &= SRMMU_REAL_PMD_MASK;
__asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
"r" (addr | 0x100), /* Flush TLB segment.. */
"i" (ASI_M_FLUSH_PROBE) : "memory");
/* PMD_SHIFT determines the size of the area a second-level page table can map */
#define SUN4C_PMD_SHIFT 23
-#define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT)
-#define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1))
-#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK)
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define SUN4C_PGDIR_SHIFT 23
/* PMD_SHIFT determines the size of the area a second-level page table can map */
#define SUN4C_PMD_SHIFT 22
-#define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT)
-#define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1))
-#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK)
/* PGDIR_SHIFT determines what a third-level page table entry can map */
#define SUN4C_PGDIR_SHIFT 22
#define RLIMIT_RSS 5 /* max resident set size */
#define RLIMIT_NOFILE 6 /* max number of open files */
#define RLIMIT_NPROC 7 /* max number of processes */
-#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
-#define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
+#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ 0, RLIM_INFINITY}, \
{RLIM_INFINITY, RLIM_INFINITY}, \
{INR_OPEN, INR_OPEN}, {0, 0}, \
- {PAGE_SIZE, PAGE_SIZE}, \
{RLIM_INFINITY, RLIM_INFINITY}, \
- {RLIM_INFINITY, RLIM_INFINITY} \
+ {RLIM_INFINITY, RLIM_INFINITY}, \
+ {RLIM_INFINITY, RLIM_INFINITY}, \
+ {MAX_SIGPENDING, MAX_SIGPENDING}, \
+ {MQ_BYTES_MAX, MQ_BYTES_MAX}, \
}
#endif /* __KERNEL__ */
: "=r" (val)
: "r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE));
if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
- vaddr &= ~SRMMU_PMD_MASK;
+ vaddr &= ~SRMMU_REAL_PMD_MASK;
vaddr >>= PAGE_SHIFT;
return val | (vaddr << 8);
}
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
-static __inline__ unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = addr + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if (offset) {
- tmp = *(p++);
- tmp &= (~0UL << offset);
- if (size < 64)
- goto found_first;
- if (tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while (size & ~63UL) {
- if ((tmp = *(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if (!size)
- return result;
- tmp = *p;
-
-found_first:
- tmp &= (~0UL >> (64 - size));
- if (tmp == 0UL) /* Are any bits set? */
- return result + size; /* Nope. */
-found_middle:
- return result + __ffs(tmp);
-}
+extern unsigned long find_next_bit(unsigned long *, unsigned long, unsigned long);
/**
* find_first_bit - find the first set bit in a memory region
* on Linus's ALPHA routines, which are pretty portable BTW.
*/
-static __inline__ unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = addr + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if (offset) {
- tmp = *(p++);
- tmp |= ~0UL >> (64-offset);
- if (size < 64)
- goto found_first;
- if (~tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while (size & ~63UL) {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if (!size)
- return result;
- tmp = *p;
-
-found_first:
- tmp |= ~0UL << size;
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffz(tmp);
-}
+extern unsigned long find_next_zero_bit(unsigned long *, unsigned long, unsigned long);
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
#define find_first_zero_le_bit(addr, size) \
find_next_zero_le_bit((addr), (size), 0)
-static __inline__ unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset)
-{
- unsigned long *p = addr + (offset >> 6);
- unsigned long result = offset & ~63UL;
- unsigned long tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 63UL;
- if(offset) {
- tmp = __swab64p(p++);
- tmp |= (~0UL >> (64-offset));
- if(size < 64)
- goto found_first;
- if(~tmp)
- goto found_middle;
- size -= 64;
- result += 64;
- }
- while(size & ~63) {
- if(~(tmp = __swab64p(p++)))
- goto found_middle;
- result += 64;
- size -= 64;
- }
- if(!size)
- return result;
- tmp = __swab64p(p);
-found_first:
- tmp |= (~0UL << size);
- if (tmp == ~0UL) /* Are any bits zero? */
- return result + size; /* Nope. */
-found_middle:
- return result + ffz(tmp);
-}
+extern unsigned long find_next_zero_le_bit(unsigned long *, unsigned long, unsigned long);
#ifdef __KERNEL__
*/
#define HAVE_CSUM_COPY_USER
extern unsigned int csum_partial_copy_user_sparc64(const char *src, char *dst, int len, unsigned int sum);
+
static __inline__ unsigned int
-csum_and_copy_to_user(const char *src, char *dst, int len,
+csum_and_copy_to_user(const char *src, char __user *dst, int len,
unsigned int sum, int *err)
{
__asm__ __volatile__ ("stx %0, [%%sp + 0x7ff + 128]"
#define RLIMIT_RSS 5 /* max resident set size */
#define RLIMIT_NOFILE 6 /* max number of open files */
#define RLIMIT_NPROC 7 /* max number of processes */
-#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
-#define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
+#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ 0, RLIM_INFINITY}, \
{RLIM_INFINITY, RLIM_INFINITY}, \
{INR_OPEN, INR_OPEN}, {0, 0}, \
- {PAGE_SIZE, PAGE_SIZE }, \
{RLIM_INFINITY, RLIM_INFINITY}, \
- {RLIM_INFINITY, RLIM_INFINITY} \
+ {RLIM_INFINITY, RLIM_INFINITY}, \
+ {RLIM_INFINITY, RLIM_INFINITY}, \
+ {MAX_SIGPENDING, MAX_SIGPENDING}, \
+ {MQ_BYTES_MAX, MQ_BYTES_MAX}, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE, PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
- { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifdef __KERNEL_SYSCALLS__
"repe; scasl\n\t"
"jz 1f\n\t"
"leaq -4(%%rdi),%%rdi\n\t"
- "bsfq (%%rdi),%%rax\n"
- "1:\tsubl %%ebx,%%edi\n\t"
+ "bsfl (%%rdi),%%eax\n"
+ "1:\tsubq %%rbx,%%rdi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%eax"
:"=a" (res), "=&c" (d0), "=&D" (d1)
- :"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
+ :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
return res;
}
-
/**
* find_next_bit - find the first set bit in a memory region
* @addr: The address to base the search on
int *src_err_ptr, int *dst_err_ptr);
-extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+extern unsigned int csum_partial_copy_from_user(const char __user *src, char *dst,
int len, unsigned int isum, int *errp);
-extern unsigned int csum_partial_copy_to_user(const char *src, char *dst,
+extern unsigned int csum_partial_copy_to_user(const char *src, char __user *dst,
int len, unsigned int isum, int *errp);
extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len,
unsigned int sum);
*/
typedef u32 compat_uptr_t;
-static inline void *compat_ptr(compat_uptr_t uptr)
+static inline void __user *compat_ptr(compat_uptr_t uptr)
{
- return (void *)(unsigned long)uptr;
+ return (void __user *)(unsigned long)uptr;
}
-static __inline__ void *compat_alloc_user_space(long len)
+static __inline__ void __user *compat_alloc_user_space(long len)
{
struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs);
- return (void *)regs->rsp - len;
+ return (void __user *)regs->rsp - len;
}
#endif /* _ASM_X86_64_COMPAT_H */
d.base1 = PTR_MIDDLE(tss) & 0xFF;
d.type = type;
d.p = 1;
- d.g = 1;
d.limit1 = (size >> 16) & 0xF;
d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF;
d.base3 = PTR_HIGH(tss);
static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
{
set_tssldt_descriptor(&cpu_gdt_table[cpu][GDT_ENTRY_LDT], (unsigned long)addr,
- DESC_LDT, size);
+ DESC_LDT, size * 8);
}
static inline void set_seg_base(unsigned cpu, int entry, void *base)
static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
{
if((unsigned long) addr >= (unsigned long) high_memory)
- return vfree((void *)addr);
+ vfree((void *)addr);
else
free_pages(addr, get_order(size));
}
struct _fpstate_ia32;
-int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave);
-int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf,
+int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave);
+int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf,
struct pt_regs *regs, int fsave);
#endif
extern unsigned int mxcsr_feature_mask;
extern void mxcsr_feature_mask_init(void);
extern void init_fpu(struct task_struct *child);
-extern int save_i387(struct _fpstate *buf);
+extern int save_i387(struct _fpstate __user *buf);
static inline int need_signal_i387(struct task_struct *me)
{
#define clear_fpu(tsk) do { \
if ((tsk)->thread_info->status & TS_USEDFPU) { \
- asm volatile("fwait"); \
+ asm volatile("fnclex ; fwait"); \
(tsk)->thread_info->status &= ~TS_USEDFPU; \
stts(); \
} \
/*
* ptrace request handers...
*/
-extern int get_fpregs(struct user_i387_struct *buf,
+extern int get_fpregs(struct user_i387_struct __user *buf,
struct task_struct *tsk);
extern int set_fpregs(struct task_struct *tsk,
- struct user_i387_struct *buf);
+ struct user_i387_struct __user *buf);
/*
* i387 state interaction
return err;
}
-static inline int save_i387_checking(struct i387_fxsave_struct *fx)
+static inline int save_i387_checking(struct i387_fxsave_struct __user *fx)
{
int err;
asm volatile("1: rex64 ; fxsave (%[fx])\n\t"
/*
* This restores directly out of user space. Exceptions are handled.
*/
-static inline int restore_i387(struct _fpstate *buf)
+static inline int restore_i387(struct _fpstate __user *buf)
{
return restore_fpu_checking((struct i387_fxsave_struct *)buf);
}
#ifdef __KERNEL__
struct user_desc;
struct siginfo_t;
-int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info);
-int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info);
+int do_get_thread_area(struct thread_struct *t, struct user_desc __user *info);
+int do_set_thread_area(struct thread_struct *t, struct user_desc __user *info);
int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs);
int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from);
int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from);
#define __NR_ia32_mq_timedreceive (__NR_ia32_mq_open+3)
#define __NR_ia32_mq_notify (__NR_ia32_mq_open+4)
#define __NR_ia32_mq_getsetattr (__NR_ia32_mq_open+5)
+#define __NR_ia32_kexec 283
-#define IA32_NR_syscalls 285 /* must be > than biggest syscall! */
+#define IA32_NR_syscalls 287 /* must be > than biggest syscall! */
#endif /* _ASM_X86_64_IA32_UNISTD_H_ */
-/*
- * linux/include/asm-x86_64/ide.h
- *
- * Copyright (C) 1994-1996 Linus Torvalds & authors
- */
-
-/*
- * This file contains the x86_64 architecture specific IDE code.
- */
-
-#ifndef __ASMx86_64_IDE_H
-#define __ASMx86_64_IDE_H
-
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-
-#ifndef MAX_HWIFS
-# ifdef CONFIG_BLK_DEV_IDEPCI
-#define MAX_HWIFS 10
-# else
-#define MAX_HWIFS 6
-# endif
-#endif
-
-static __inline__ int ide_default_irq(unsigned long base)
-{
- switch (base) {
- case 0x1f0: return 14;
- case 0x170: return 15;
- case 0x1e8: return 11;
- case 0x168: return 10;
- case 0x1e0: return 8;
- case 0x160: return 12;
- default:
- return 0;
- }
-}
-
-static __inline__ unsigned long ide_default_io_base(int index)
-{
- switch (index) {
- case 0: return 0x1f0;
- case 1: return 0x170;
- case 2: return 0x1e8;
- case 3: return 0x168;
- case 4: return 0x1e0;
- case 5: return 0x160;
- default:
- return 0;
- }
-}
-
-#define IDE_ARCH_OBSOLETE_INIT
-#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
-#define ide_init_default_irq(base) (0)
-#else
-#define ide_init_default_irq(base) ide_default_irq(base)
-#endif
-
-#include <asm-generic/ide_iops.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASMx86_64_IDE_H */
+#include <asm-i386/ide.h>
#define __raw_writel writel
#define __raw_writeq writeq
-void *memcpy_fromio(void*,const void*,unsigned);
-void *memcpy_toio(void*,const void*,unsigned);
+void *__memcpy_fromio(void*,unsigned long,unsigned);
+void *__memcpy_toio(unsigned long,const void*,unsigned);
+
+#define memcpy_fromio(to,from,len) \
+ __memcpy_fromio((to),(unsigned long)(from),(len))
+#define memcpy_toio(to,from,len) \
+ __memcpy_toio((unsigned long)(to),(from),(len))
#define memset_io(a,b,c) memset((void *)(a),(b),(c))
/*
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void);
-extern void mp_parse_prt (void);
+extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
#endif /*CONFIG_X86_IO_APIC*/
#endif
extern unsigned long vm_data_default_flags, vm_data_default_flags32;
extern unsigned long vm_force_exec32;
+#define __START_KERNEL 0xffffffff80100000UL
+#define __START_KERNEL_map 0xffffffff80000000UL
+#define __PAGE_OFFSET 0x0000010000000000UL /* 1 << 40 */
+
+#else
+#define __START_KERNEL 0xffffffff80100000
+#define __START_KERNEL_map 0xffffffff80000000
+#define __PAGE_OFFSET 0x0000010000000000 /* 1 << 40 */
#endif /* !__ASSEMBLY__ */
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/* See Documentation/x86_64/mm.txt for a description of the memory map. */
-#define __START_KERNEL 0xffffffff80100000
-#define __START_KERNEL_map 0xffffffff80000000
-#define __PAGE_OFFSET 0x0000010000000000 /* 1 << 40 */
#define __PHYSICAL_MASK_SHIFT 40
#define __PHYSICAL_MASK ((1UL << __PHYSICAL_MASK_SHIFT) - 1)
#define __VIRTUAL_MASK_SHIFT 48
#ifndef __ASSEMBLY__
-#define VMALLOC_START 0xffffff0000000000
-#define VMALLOC_END 0xffffff7fffffffff
-#define MODULES_VADDR 0xffffffffa0000000
-#define MODULES_END 0xffffffffafffffff
+#define VMALLOC_START 0xffffff0000000000UL
+#define VMALLOC_END 0xffffff7fffffffffUL
+#define MODULES_VADDR 0xffffffffa0000000UL
+#define MODULES_END 0xffffffffafffffffUL
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
-#define IOMAP_START 0xfffffe8000000000
+#define IOMAP_START 0xfffffe8000000000UL
#define _PAGE_BIT_PRESENT 0
#define _PAGE_BIT_RW 1
extern inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
extern inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
extern inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
-static inline int ptep_test_and_clear_dirty(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep); }
-static inline int ptep_test_and_clear_young(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); }
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+ if (!pte_dirty(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+ if (!pte_young(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+}
+
static inline void ptep_set_wrprotect(pte_t *ptep) { clear_bit(_PAGE_BIT_RW, ptep); }
static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, ptep); }
#define update_mmu_cache(vma,address,pte) do { } while (0)
+/* We only update the dirty/accessed state if we set
+ * the dirty bit by hand in the kernel, since the hardware
+ * will do the accessed bit for us, and we don't want to
+ * race with other CPU's that might be updating the dirty
+ * bit at the same time. */
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+ do { \
+ if (__dirty) { \
+ set_pte(__ptep, __entry); \
+ flush_tlb_page(__vma, __address); \
+ } \
+ } while (0)
+
/* Encode and de-code a swap entry */
#define __swp_type(x) (((x).val >> 1) & 0x3f)
#define __swp_offset(x) ((x).val >> 8)
/*
* User space process size: 512GB - 1GB (default).
*/
-#define TASK_SIZE (0x0000007fc0000000)
+#define TASK_SIZE (0x0000007fc0000000UL)
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
#define user_mode(regs) (!!((regs)->cs & 3))
#define instruction_pointer(regs) ((regs)->rip)
-void signal_fault(struct pt_regs *regs, void *frame, char *where);
+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
enum {
EF_CF = 0x00000001,
#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
#define RLIMIT_AS 9 /* address space limit */
#define RLIMIT_LOCKS 10 /* maximum file locks held */
+#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
+#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
-#define RLIM_NLIMITS 11
+#define RLIM_NLIMITS 13
/*
* SuS says limits have to be unsigned.
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ 0, 0 }, \
{ INR_OPEN, INR_OPEN }, \
- { PAGE_SIZE , PAGE_SIZE }, \
{ RLIM_INFINITY, RLIM_INFINITY }, \
- { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
+ { MAX_SIGPENDING, MAX_SIGPENDING }, \
+ { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
}
#endif /* __KERNEL__ */
atomic_t count;
int sleepers;
wait_queue_head_t wait;
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
long __magic;
#endif
};
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
# define __SEM_DEBUG_INIT(name) \
, (int)&(name).__magic
#else
atomic_set(&sem->count, val);
sem->sleepers = 0;
init_waitqueue_head(&sem->wait);
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
sem->__magic = (int)&sem->__magic;
#endif
}
*/
static inline void down(struct semaphore * sem)
{
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
might_sleep();
{
int result;
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
might_sleep();
{
int result;
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
*/
static inline void up(struct semaphore * sem)
{
-#if WAITQUEUE_DEBUG
+#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
__asm__ __volatile__(
#define _ASM_X86_64_SIGCONTEXT_H
#include <asm/types.h>
+#include <linux/compiler.h>
/* FXSAVE frame */
/* Note: reserved1/2 may someday contain valuable data. Always save/restore
unsigned long trapno;
unsigned long oldmask;
unsigned long cr2;
- struct _fpstate *fpstate; /* zero when no FPU context */
+ struct _fpstate __user *fpstate; /* zero when no FPU context */
unsigned long reserved1[8];
};
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFF)
+#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFFUL)
#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
#define get_ds() (KERNEL_DS)
*/
#define __range_not_ok(addr,size) ({ \
unsigned long flag,sum; \
+ __chk_user_ptr(addr); \
asm("# range_ok\n\r" \
"addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0" \
:"=&r" (flag), "=r" (sum) \
:"1" (addr),"g" ((long)(size)),"g" (current_thread_info()->addr_limit.seg)); \
flag; })
-#define access_ok(type,addr,size) (__range_not_ok(addr,size) == 0)
+#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+extern inline int verify_area(int type, const void __user * addr, unsigned long size)
{
return access_ok(type,addr,size) ? 0 : -EFAULT;
}
#define get_user(x,ptr) \
({ long __val_gu; \
int __ret_gu; \
+ __chk_user_ptr(ptr); \
switch(sizeof (*(ptr))) { \
case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \
#define __put_user_size(x,ptr,size,retval) \
do { \
retval = 0; \
+ __chk_user_ptr(ptr); \
switch (size) { \
case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\
case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\
#define __get_user_size(x,ptr,size,retval) \
do { \
retval = 0; \
+ __chk_user_ptr(ptr); \
switch (size) { \
case 1: __get_user_asm(x,ptr,retval,"b","b","=q",-EFAULT); break;\
case 2: __get_user_asm(x,ptr,retval,"w","w","=r",-EFAULT); break;\
/* Handles exceptions in both to and from, but doesn't do access_ok */
extern unsigned long copy_user_generic(void *to, const void *from, unsigned len);
-extern unsigned long copy_to_user(void *to, const void *from, unsigned len);
-extern unsigned long copy_from_user(void *to, const void *from, unsigned len);
-extern unsigned long copy_in_user(void *to, const void *from, unsigned len);
+extern unsigned long copy_to_user(void __user *to, const void *from, unsigned len);
+extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len);
+extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len);
-static inline int __copy_from_user(void *dst, const void *src, unsigned size)
+static inline int __copy_from_user(void *dst, const void __user *src, unsigned size)
{
int ret = 0;
if (!__builtin_constant_p(size))
- return copy_user_generic(dst,src,size);
+ return copy_user_generic(dst,(__force void *)src,size);
switch (size) {
- case 1:__get_user_asm(*(u8*)dst,(u8 *)src,ret,"b","b","=q",1);
+ case 1:__get_user_asm(*(u8*)dst,(u8 __user *)src,ret,"b","b","=q",1);
return ret;
- case 2:__get_user_asm(*(u16*)dst,(u16*)src,ret,"w","w","=r",2);
+ case 2:__get_user_asm(*(u16*)dst,(u16 __user *)src,ret,"w","w","=r",2);
return ret;
- case 4:__get_user_asm(*(u32*)dst,(u32*)src,ret,"l","k","=r",4);
+ case 4:__get_user_asm(*(u32*)dst,(u32 __user *)src,ret,"l","k","=r",4);
return ret;
- case 8:__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",8);
+ case 8:__get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",8);
return ret;
case 10:
- __get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
+ __get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
if (unlikely(ret)) return ret;
- __get_user_asm(*(u16*)(8+(char*)dst),(u16*)(8+(char*)src),ret,"w","w","=r",2);
+ __get_user_asm(*(u16*)(8+(char*)dst),(u16 __user *)(8+(char __user *)src),ret,"w","w","=r",2);
return ret;
case 16:
- __get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
+ __get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
if (unlikely(ret)) return ret;
- __get_user_asm(*(u64*)(8+(char*)dst),(u64*)(8+(char*)src),ret,"q","","=r",8);
+ __get_user_asm(*(u64*)(8+(char*)dst),(u64 __user *)(8+(char __user *)src),ret,"q","","=r",8);
return ret;
default:
- return copy_user_generic(dst,src,size);
+ return copy_user_generic(dst,(__force void *)src,size);
}
}
-static inline int __copy_to_user(void *dst, const void *src, unsigned size)
+static inline int __copy_to_user(void __user *dst, const void *src, unsigned size)
{
int ret = 0;
if (!__builtin_constant_p(size))
- return copy_user_generic(dst,src,size);
+ return copy_user_generic((__force void *)dst,src,size);
switch (size) {
- case 1:__put_user_asm(*(u8*)src,(u8 *)dst,ret,"b","b","iq",1);
+ case 1:__put_user_asm(*(u8*)src,(u8 __user *)dst,ret,"b","b","iq",1);
return ret;
- case 2:__put_user_asm(*(u16*)src,(u16*)dst,ret,"w","w","ir",2);
+ case 2:__put_user_asm(*(u16*)src,(u16 __user *)dst,ret,"w","w","ir",2);
return ret;
- case 4:__put_user_asm(*(u32*)src,(u32*)dst,ret,"l","k","ir",4);
+ case 4:__put_user_asm(*(u32*)src,(u32 __user *)dst,ret,"l","k","ir",4);
return ret;
- case 8:__put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",8);
+ case 8:__put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",8);
return ret;
case 10:
- __put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",10);
+ __put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",10);
if (unlikely(ret)) return ret;
asm("":::"memory");
- __put_user_asm(4[(u16*)src],4+(u16*)dst,ret,"w","w","ir",2);
+ __put_user_asm(4[(u16*)src],4+(u16 __user *)dst,ret,"w","w","ir",2);
return ret;
case 16:
- __put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",16);
+ __put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",16);
if (unlikely(ret)) return ret;
asm("":::"memory");
- __put_user_asm(1[(u64*)src],1+(u64*)dst,ret,"q","","ir",8);
+ __put_user_asm(1[(u64*)src],1+(u64 __user *)dst,ret,"q","","ir",8);
return ret;
default:
- return copy_user_generic(dst,src,size);
+ return copy_user_generic((__force void *)dst,src,size);
}
}
-static inline int __copy_in_user(void *dst, const void *src, unsigned size)
+static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
{
int ret = 0;
if (!__builtin_constant_p(size))
- return copy_user_generic(dst,src,size);
+ return copy_user_generic((__force void *)dst,(__force void *)src,size);
switch (size) {
case 1: {
u8 tmp;
- __get_user_asm(tmp,(u8 *)src,ret,"b","b","=q",1);
+ __get_user_asm(tmp,(u8 __user *)src,ret,"b","b","=q",1);
if (likely(!ret))
- __put_user_asm(tmp,(u8 *)dst,ret,"b","b","iq",1);
+ __put_user_asm(tmp,(u8 __user *)dst,ret,"b","b","iq",1);
return ret;
}
case 2: {
u16 tmp;
- __get_user_asm(tmp,(u16 *)src,ret,"w","w","=r",2);
+ __get_user_asm(tmp,(u16 __user *)src,ret,"w","w","=r",2);
if (likely(!ret))
- __put_user_asm(tmp,(u16 *)dst,ret,"w","w","ir",2);
+ __put_user_asm(tmp,(u16 __user *)dst,ret,"w","w","ir",2);
return ret;
}
case 4: {
u32 tmp;
- __get_user_asm(tmp,(u32 *)src,ret,"l","k","=r",4);
+ __get_user_asm(tmp,(u32 __user *)src,ret,"l","k","=r",4);
if (likely(!ret))
- __put_user_asm(tmp,(u32 *)dst,ret,"l","k","ir",4);
+ __put_user_asm(tmp,(u32 __user *)dst,ret,"l","k","ir",4);
return ret;
}
case 8: {
u64 tmp;
- __get_user_asm(tmp,(u64 *)src,ret,"q","","=r",8);
+ __get_user_asm(tmp,(u64 __user *)src,ret,"q","","=r",8);
if (likely(!ret))
- __put_user_asm(tmp,(u64 *)dst,ret,"q","","ir",8);
+ __put_user_asm(tmp,(u64 __user *)dst,ret,"q","","ir",8);
return ret;
}
default:
- return copy_user_generic(dst,src,size);
+ return copy_user_generic((__force void *)dst,(__force void *)src,size);
}
}
-long strncpy_from_user(char *dst, const char *src, long count);
-long __strncpy_from_user(char *dst, const char *src, long count);
-long strnlen_user(const char *str, long n);
-long strlen_user(const char *str);
-unsigned long clear_user(void *mem, unsigned long len);
-unsigned long __clear_user(void *mem, unsigned long len);
+long strncpy_from_user(char *dst, const char __user *src, long count);
+long __strncpy_from_user(char *dst, const char __user *src, long count);
+long strnlen_user(const char __user *str, long n);
+long strlen_user(const char __user *str);
+unsigned long clear_user(void __user *mem, unsigned long len);
+unsigned long __clear_user(void __user *mem, unsigned long len);
#endif /* __X86_64_UACCESS_H */
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
#endif
#ifndef __KERNEL_SYSCALLS__
#define _LINUX_ACCT_H
#include <linux/types.h>
+#include <asm/param.h>
/*
* comp_t is a 16-bit "floating" point number with a 3-bit base 8
- * exponent and a 13-bit fraction. See linux/kernel/acct.c for the
- * specific encoding system used.
+ * exponent and a 13-bit fraction.
+ * comp2_t is 24-bit with 5-bit base 2 exponent and 20 bit fraction
+ * (leading 1 not stored).
+ * See linux/kernel/acct.c for the specific encoding systems used.
*/
typedef __u16 comp_t;
+typedef __u32 comp2_t;
/*
* accounting file record
struct acct
{
- char ac_flag; /* Accounting Flags */
-/*
- * No binary format break with 2.0 - but when we hit 32bit uid we'll
- * have to bite one
- */
- __u16 ac_uid; /* Accounting Real User ID */
- __u16 ac_gid; /* Accounting Real Group ID */
- __u16 ac_tty; /* Accounting Control Terminal */
- __u32 ac_btime; /* Accounting Process Creation Time */
- comp_t ac_utime; /* Accounting User Time */
- comp_t ac_stime; /* Accounting System Time */
- comp_t ac_etime; /* Accounting Elapsed Time */
- comp_t ac_mem; /* Accounting Average Memory Usage */
- comp_t ac_io; /* Accounting Chars Transferred */
- comp_t ac_rw; /* Accounting Blocks Read or Written */
- comp_t ac_minflt; /* Accounting Minor Pagefaults */
- comp_t ac_majflt; /* Accounting Major Pagefaults */
- comp_t ac_swaps; /* Accounting Number of Swaps */
- __u32 ac_exitcode; /* Accounting Exitcode */
- char ac_comm[ACCT_COMM + 1]; /* Accounting Command Name */
- char ac_pad[10]; /* Accounting Padding Bytes */
+ char ac_flag; /* Flags */
+ char ac_version; /* Always set to ACCT_VERSION */
+ /* for binary compatibility back until 2.0 */
+ __u16 ac_uid16; /* LSB of Real User ID */
+ __u16 ac_gid16; /* LSB of Real Group ID */
+ __u16 ac_tty; /* Control Terminal */
+ __u32 ac_btime; /* Process Creation Time */
+ comp_t ac_utime; /* User Time */
+ comp_t ac_stime; /* System Time */
+ comp_t ac_etime; /* Elapsed Time */
+ comp_t ac_mem; /* Average Memory Usage */
+ comp_t ac_io; /* Chars Transferred */
+ comp_t ac_rw; /* Blocks Read or Written */
+ comp_t ac_minflt; /* Minor Pagefaults */
+ comp_t ac_majflt; /* Major Pagefaults */
+ comp_t ac_swaps; /* Number of Swaps */
+/* m68k had no padding here. */
+#if !defined(CONFIG_M68K) || !defined(__KERNEL__)
+ __u16 ac_ahz; /* AHZ */
+#endif
+ __u32 ac_exitcode; /* Exitcode */
+ char ac_comm[ACCT_COMM + 1]; /* Command Name */
+ __u8 ac_etime_hi; /* Elapsed Time MSB */
+ __u16 ac_etime_lo; /* Elapsed Time LSB */
+ __u32 ac_uid; /* Real User ID */
+ __u32 ac_gid; /* Real Group ID */
+};
+
+struct acct_v3
+{
+ char ac_flag; /* Flags */
+ char ac_version; /* Always set to ACCT_VERSION */
+ __u16 ac_tty; /* Control Terminal */
+ __u32 ac_exitcode; /* Exitcode */
+ __u32 ac_uid; /* Real User ID */
+ __u32 ac_gid; /* Real Group ID */
+ __u32 ac_pid; /* Process ID */
+ __u32 ac_ppid; /* Parent Process ID */
+ __u32 ac_btime; /* Process Creation Time */
+#ifdef __KERNEL__
+ __u32 ac_etime; /* Elapsed Time */
+#else
+ float ac_etime; /* Elapsed Time */
+#endif
+ comp_t ac_utime; /* User Time */
+ comp_t ac_stime; /* System Time */
+ comp_t ac_mem; /* Average Memory Usage */
+ comp_t ac_io; /* Chars Transferred */
+ comp_t ac_rw; /* Blocks Read or Written */
+ comp_t ac_minflt; /* Minor Pagefaults */
+ comp_t ac_majflt; /* Major Pagefaults */
+ comp_t ac_swaps; /* Number of Swaps */
+ char ac_comm[ACCT_COMM]; /* Command Name */
};
/*
#define ACOMPAT 0x04 /* ... used compatibility mode (VAX only not used) */
#define ACORE 0x08 /* ... dumped core */
#define AXSIG 0x10 /* ... was killed by a signal */
-
-#define AHZ 100
+#define ABYTESEX 0x80 /* always set, allows to detect byteorder */
#ifdef __KERNEL__
#define acct_process(x) do { } while (0)
#endif
+/*
+ * ACCT_VERSION numbers as yet defined:
+ * 0: old format (until 2.6.7) with 16 bit uid/gid
+ * 1: extended variant (binary compatible on M68K)
+ * 2: extended variant (binary compatible on everything except M68K)
+ * 3: new binary incompatible format (64 bytes)
+ * 4: new binary incompatible format (128 bytes)
+ * 5: new binary incompatible format (128 bytes, second half)
+ *
+ */
+
+#ifdef CONFIG_BSD_PROCESS_ACCT_V3
+#define ACCT_VERSION 3
+#define AHZ 100
+typedef struct acct_v3 acct_t;
+#else
+#ifdef CONFIG_M68K
+#define ACCT_VERSION 1
+#else
+#define ACCT_VERSION 2
+#endif
+#define AHZ (USER_HZ)
+typedef struct acct acct_t;
+#endif
+
+#else
+#define ACCT_VERSION 2
+#define AHZ (HZ)
#endif /* __KERNEL */
+#ifdef __KERNEL__
+/*
+ * Yet another set of HZ to *HZ helper functions.
+ * See <linux/times.h> for the original.
+ */
+
+static inline u32 jiffies_to_AHZ(unsigned long x)
+{
+#if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0
+ return x / (HZ / USER_HZ);
+#else
+ u64 tmp = (u64)x * TICK_NSEC;
+ do_div(tmp, (NSEC_PER_SEC / AHZ));
+ return (long)tmp;
+#endif
+}
+
+static inline u64 jiffies_64_to_AHZ(u64 x)
+{
+#if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0
+#if HZ != AHZ
+ do_div(x, HZ / AHZ);
+#endif
+#else
+ x *= TICK_NSEC;
+ do_div(x, (NSEC_PER_SEC / AHZ));
+#endif
+ return x;
+}
+
+#endif /* __KERNEL */
+
#endif /* _LINUX_ACCT_H */
#endif /*!CONFIG_ACPI_BOOT*/
+unsigned int acpi_register_gsi (u32 gsi, int edge_level, int active_high_low);
+int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
#ifdef CONFIG_ACPI_PCI
struct pci_dev;
int acpi_pci_irq_enable (struct pci_dev *dev);
-int acpi_pci_irq_init (void);
-int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
struct acpi_pci_driver {
struct acpi_pci_driver *next;
struct list_head ki_list; /* the aio core uses this
* for cancellation */
- void __user *ki_user_obj; /* pointer to userland's iocb */
+ union {
+ void __user *user;
+ struct task_struct *tsk;
+ } ki_obj;
__u64 ki_user_data; /* user's data for completion */
loff_t ki_pos;
(x)->ki_filp = (filp); \
(x)->ki_ctx = &tsk->active_mm->default_kioctx; \
(x)->ki_cancel = NULL; \
- (x)->ki_user_obj = tsk; \
+ (x)->ki_obj.tsk = tsk; \
} while (0)
#define AIO_RING_MAGIC 0xa10a10a1
extern void FASTCALL(exit_aio(struct mm_struct *mm));
extern struct kioctx *lookup_ioctx(unsigned long ctx_id);
extern int FASTCALL(io_submit_one(struct kioctx *ctx,
- struct iocb *user_iocb, struct iocb *iocb));
+ struct iocb __user *user_iocb, struct iocb *iocb));
/* semi private, but used by the 32bit emulations: */
struct kioctx *lookup_ioctx(unsigned long ctx_id);
-int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb *user_iocb,
+int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
struct iocb *iocb));
#define get_ioctx(kioctx) do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
#include <linux/socket.h>
#include <linux/types.h>
#endif
+#include <linux/compiler.h>
#include <linux/atmapi.h>
#include <linux/atmsap.h>
#include <linux/atmioc.h>
struct atmif_sioc {
int number;
int length;
- void *arg;
+ void __user *arg;
};
typedef unsigned short atm_backend_t;
void (*dev_close)(struct atm_dev *dev);
int (*open)(struct atm_vcc *vcc);
void (*close)(struct atm_vcc *vcc);
- int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg);
+ int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg);
int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen);
+ void __user *optval,int optlen);
int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
- void *optval,int optlen);
+ void __user *optval,int optlen);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
void (*phy_put)(struct atm_dev *dev,unsigned char value,
struct atmphy_ops {
int (*start)(struct atm_dev *dev);
- int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void *arg);
+ int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg);
void (*interrupt)(struct atm_dev *dev);
int (*stop)(struct atm_dev *dev);
};
#define CONFIG_EXPERIMENTAL 1
#define CONFIG_CLEAN_COMPILE 1
#define CONFIG_STANDALONE 1
+#define CONFIG_BROKEN_ON_SMP 1
/*
* General setup
#define CONFIG_SYSVIPC 1
#define CONFIG_POSIX_MQUEUE 1
#define CONFIG_BSD_PROCESS_ACCT 1
+#undef CONFIG_BSD_PROCESS_ACCT_V3
#define CONFIG_SYSCTL 1
-#undef CONFIG_AUDIT
+#define CONFIG_AUDIT 1
+#define CONFIG_AUDITSYSCALL 1
#define CONFIG_LOG_BUF_SHIFT 17
#define CONFIG_HOTPLUG 1
#undef CONFIG_IKCONFIG
#define CONFIG_OBSOLETE_MODPARM 1
#undef CONFIG_MODVERSIONS
#define CONFIG_KMOD 1
-#define CONFIG_STOP_MACHINE 1
/*
* Processor type and features
*/
-#undef CONFIG_X86_PC
+#define CONFIG_X86_PC 1
#undef CONFIG_X86_ELAN
#undef CONFIG_X86_VOYAGER
#undef CONFIG_X86_NUMAQ
#undef CONFIG_X86_SUMMIT
#undef CONFIG_X86_BIGSMP
#undef CONFIG_X86_VISWS
-#define CONFIG_X86_GENERICARCH 1
+#undef CONFIG_X86_GENERICARCH
#undef CONFIG_X86_ES7000
-#define CONFIG_X86_CYCLONE_TIMER 1
#undef CONFIG_M386
#undef CONFIG_M486
#undef CONFIG_M586
#define CONFIG_X86_HIGH_ENTRY 1
#define CONFIG_HPET_TIMER 1
#define CONFIG_HPET_EMULATE_RTC 1
-#define CONFIG_SMP 1
-#define CONFIG_NR_CPUS 32
-#define CONFIG_SCHED_SMT 1
+#undef CONFIG_SMP
#undef CONFIG_PREEMPT
-#define CONFIG_X86_LOCAL_APIC 1
-#define CONFIG_X86_IO_APIC 1
+#undef CONFIG_X86_UP_APIC
#define CONFIG_X86_TSC 1
#define CONFIG_X86_MCE 1
#undef CONFIG_X86_MCE_NONFATAL
-#define CONFIG_X86_MCE_P4THERMAL 1
#define CONFIG_TOSHIBA_MODULE 1
#define CONFIG_I8K_MODULE 1
#define CONFIG_MICROCODE_MODULE 1
*/
#define CONFIG_EDD_MODULE 1
#undef CONFIG_NOHIGHMEM
-#undef CONFIG_HIGHMEM4G
-#define CONFIG_HIGHMEM64G 1
+#define CONFIG_HIGHMEM4G 1
+#undef CONFIG_HIGHMEM64G
#define CONFIG_HIGHMEM 1
-#define CONFIG_X86_PAE 1
-#undef CONFIG_NUMA
#define CONFIG_HIGHPTE 1
#undef CONFIG_MATH_EMULATION
#define CONFIG_MTRR 1
#undef CONFIG_EFI
-#undef CONFIG_IRQBALANCE
-#define CONFIG_HAVE_DEC_LOCK 1
#define CONFIG_REGPARM 1
/*
#define CONFIG_PCI_BIOS 1
#define CONFIG_PCI_DIRECT 1
#define CONFIG_PCI_MMCONFIG 1
-#define CONFIG_PCI_USE_VECTOR 1
#define CONFIG_PCI_LEGACY_PROC 1
#undef CONFIG_PCI_NAMES
#define CONFIG_ISA 1
#undef CONFIG_HOTPLUG_PCI_FAKE
#define CONFIG_HOTPLUG_PCI_COMPAQ_MODULE 1
#undef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
-#define CONFIG_HOTPLUG_PCI_IBM_MODULE 1
#undef CONFIG_HOTPLUG_PCI_ACPI
#undef CONFIG_HOTPLUG_PCI_CPCI
#define CONFIG_HOTPLUG_PCI_PCIE_MODULE 1
*/
#define CONFIG_BINFMT_ELF 1
#undef CONFIG_BINFMT_AOUT
-#define CONFIG_BINFMT_MISC_MODULE 1
+#define CONFIG_BINFMT_MISC 1
/*
* Device Drivers
#undef CONFIG_BLK_DEV_HD_IDE
#define CONFIG_BLK_DEV_IDEDISK 1
#define CONFIG_IDEDISK_MULTI_MODE 1
-#undef CONFIG_IDEDISK_STROKE
#define CONFIG_BLK_DEV_IDECS_MODULE 1
#define CONFIG_BLK_DEV_IDECD 1
#define CONFIG_BLK_DEV_IDETAPE_MODULE 1
* SCSI low-level drivers
*/
#define CONFIG_BLK_DEV_3W_XXXX_RAID_MODULE 1
+#define CONFIG_SCSI_3W_9XXX_MODULE 1
#undef CONFIG_SCSI_7000FASST
#define CONFIG_SCSI_ACARD_MODULE 1
#define CONFIG_SCSI_AHA152X_MODULE 1
#define CONFIG_SCSI_SATA_VITESSE_MODULE 1
#define CONFIG_SCSI_BUSLOGIC_MODULE 1
#undef CONFIG_SCSI_OMIT_FLASHPOINT
-#undef CONFIG_SCSI_CPQFCTS
#undef CONFIG_SCSI_DMX3191D
#undef CONFIG_SCSI_DTC3280
#undef CONFIG_SCSI_EATA
#define CONFIG_MD_MULTIPATH_MODULE 1
#define CONFIG_BLK_DEV_DM_MODULE 1
#define CONFIG_DM_CRYPT_MODULE 1
+#define CONFIG_DM_SNAPSHOT_MODULE 1
+#define CONFIG_DM_MIRROR_MODULE 1
+#define CONFIG_DM_ZERO_MODULE 1
/*
* Fusion MPT device support
/*
* Old SIR device drivers
*/
+#define CONFIG_IRPORT_SIR_MODULE 1
/*
* Old Serial dongle support
*/
+#undef CONFIG_DONGLE_OLD
/*
* FIR device drivers
#define CONFIG_ULTRA_MODULE 1
#define CONFIG_SMC9194_MODULE 1
#define CONFIG_NET_VENDOR_RACAL 1
+#undef CONFIG_NI5010
#define CONFIG_NI52_MODULE 1
#define CONFIG_NI65_MODULE 1
#define CONFIG_WINBOND_840_MODULE 1
#define CONFIG_DM9102_MODULE 1
#define CONFIG_PCMCIA_XIRCOM_MODULE 1
+#undef CONFIG_PCMCIA_XIRTULIP
#undef CONFIG_AT1700
#define CONFIG_DEPCA_MODULE 1
#define CONFIG_HP100_MODULE 1
#define CONFIG_TLAN_MODULE 1
#define CONFIG_VIA_RHINE_MODULE 1
#define CONFIG_VIA_RHINE_MMIO 1
+#define CONFIG_VIA_VELOCITY_MODULE 1
#define CONFIG_NET_POCKET 1
#define CONFIG_ATP_MODULE 1
#define CONFIG_DE600_MODULE 1
#define CONFIG_DE620_MODULE 1
/*
- * Gigabit Ethernet (1000/10000 Mbit)
+ * Ethernet (1000 Mbit)
*/
-#define CONFIG_NET_GIGE 1
#define CONFIG_ACENIC_MODULE 1
#undef CONFIG_ACENIC_OMIT_TIGON_I
#define CONFIG_DL2K_MODULE 1
#define CONFIG_R8169_MODULE 1
#define CONFIG_SK98LIN_MODULE 1
#define CONFIG_TIGON3_MODULE 1
+
+/*
+ * Ethernet (10000 Mbit)
+ */
#define CONFIG_IXGB_MODULE 1
#define CONFIG_IXGB_NAPI 1
#define CONFIG_S2IO_MODULE 1
/*
* ISDN feature submodules
*/
+#define CONFIG_ISDN_DRV_LOOP_MODULE 1
/*
* ISDN4Linux hardware drivers
#define CONFIG_ISDN_DRV_SC_MODULE 1
#define CONFIG_ISDN_DRV_ACT2000_MODULE 1
#define CONFIG_ISDN_DRV_TPAM_MODULE 1
+#define CONFIG_HYSDN_MODULE 1
+#define CONFIG_HYSDN_CAPI 1
/*
* CAPI subsystem
* Active AVM cards
*/
#define CONFIG_CAPI_AVM 1
+#define CONFIG_ISDN_DRV_AVMB1_B1ISA_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCI_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCIV4 1
+#define CONFIG_ISDN_DRV_AVMB1_T1ISA_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_B1PCMCIA_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_AVM_CS_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_T1PCI_MODULE 1
+#define CONFIG_ISDN_DRV_AVMB1_C4_MODULE 1
/*
* Active Eicon DIVA Server cards
#define CONFIG_VT_CONSOLE 1
#define CONFIG_HW_CONSOLE 1
#define CONFIG_SERIAL_NONSTANDARD 1
+#undef CONFIG_COMPUTONE
#define CONFIG_ROCKETPORT_MODULE 1
#undef CONFIG_CYCLADES
+#undef CONFIG_DIGIEPCA
+#undef CONFIG_DIGI
+#undef CONFIG_ESPSERIAL
+#undef CONFIG_MOXA_INTELLIO
+#undef CONFIG_MOXA_SMARTIO
+#undef CONFIG_ISI
#define CONFIG_SYNCLINK_MODULE 1
#define CONFIG_SYNCLINKMP_MODULE 1
#define CONFIG_N_HDLC_MODULE 1
+#undef CONFIG_RISCOM8
+#undef CONFIG_SPECIALIX
+#undef CONFIG_SX
+#undef CONFIG_RIO
#define CONFIG_STALDRV 1
+#undef CONFIG_STALLION
+#undef CONFIG_ISTALLION
/*
* Serial drivers
/*
* Ftape, the floppy tape device driver
*/
+#undef CONFIG_FTAPE
#define CONFIG_AGP 1
#define CONFIG_AGP_ALI 1
#define CONFIG_AGP_ATI 1
#define CONFIG_SYNCLINK_CS_MODULE 1
#define CONFIG_MWAVE_MODULE 1
#undef CONFIG_RAW_DRIVER
+#undef CONFIG_HPET
#define CONFIG_HANGCHECK_TIMER_MODULE 1
/*
#define CONFIG_I2C_ALI15X3_MODULE 1
#define CONFIG_I2C_AMD756_MODULE 1
#define CONFIG_I2C_AMD8111_MODULE 1
+#undef CONFIG_I2C_ELEKTOR
#define CONFIG_I2C_I801_MODULE 1
#define CONFIG_I2C_I810_MODULE 1
#define CONFIG_I2C_ISA_MODULE 1
#define CONFIG_VIDEO_ZORAN_DC30_MODULE 1
#define CONFIG_VIDEO_ZORAN_LML33_MODULE 1
#define CONFIG_VIDEO_ZORAN_LML33R10_MODULE 1
+#define CONFIG_VIDEO_MEYE_MODULE 1
#define CONFIG_VIDEO_SAA7134_MODULE 1
#define CONFIG_VIDEO_MXB_MODULE 1
#define CONFIG_VIDEO_DPC_MODULE 1
/*
* Digital Video Broadcasting Devices
*/
-#undef CONFIG_DVB
+#define CONFIG_DVB 1
+#define CONFIG_DVB_CORE_MODULE 1
+
+/*
+ * Supported Frontend Modules
+ */
+#define CONFIG_DVB_TWINHAN_DST_MODULE 1
+#define CONFIG_DVB_STV0299_MODULE 1
+#undef CONFIG_DVB_SP887X
+#undef CONFIG_DVB_ALPS_TDLB7
+#define CONFIG_DVB_ALPS_TDMB7_MODULE 1
+#define CONFIG_DVB_ATMEL_AT76C651_MODULE 1
+#define CONFIG_DVB_CX24110_MODULE 1
+#define CONFIG_DVB_GRUNDIG_29504_491_MODULE 1
+#define CONFIG_DVB_GRUNDIG_29504_401_MODULE 1
+#define CONFIG_DVB_MT312_MODULE 1
+#define CONFIG_DVB_VES1820_MODULE 1
+#define CONFIG_DVB_VES1X93_MODULE 1
+#undef CONFIG_DVB_TDA1004X
+#define CONFIG_DVB_NXT6000_MODULE 1
+
+/*
+ * Supported SAA7146 based PCI Adapters
+ */
+#define CONFIG_DVB_AV7110_MODULE 1
+#define CONFIG_DVB_AV7110_OSD 1
+#define CONFIG_DVB_BUDGET_MODULE 1
+#define CONFIG_DVB_BUDGET_CI_MODULE 1
+#define CONFIG_DVB_BUDGET_AV_MODULE 1
+#define CONFIG_DVB_BUDGET_PATCH_MODULE 1
+
+/*
+ * Supported USB Adapters
+ */
+#define CONFIG_DVB_TTUSB_BUDGET_MODULE 1
+#define CONFIG_DVB_TTUSB_DEC_MODULE 1
+
+/*
+ * Supported FlexCopII (B2C2) Adapters
+ */
+#define CONFIG_DVB_B2C2_SKYSTAR_MODULE 1
+
+/*
+ * Supported BT878 Adapters
+ */
+#define CONFIG_DVB_BT8XX_MODULE 1
#define CONFIG_VIDEO_SAA7146_MODULE 1
#define CONFIG_VIDEO_SAA7146_VV_MODULE 1
#define CONFIG_VIDEO_VIDEOBUF_MODULE 1
#define CONFIG_FB_HGA_MODULE 1
#define CONFIG_FB_HGA_ACCEL 1
#define CONFIG_FB_RIVA_MODULE 1
+#undef CONFIG_FB_RIVA_I2C
#define CONFIG_FB_I810_MODULE 1
#define CONFIG_FB_I810_GTF 1
#define CONFIG_FB_MATROX_MODULE 1
#define CONFIG_USB_PRINTER_MODULE 1
#define CONFIG_USB_STORAGE_MODULE 1
#undef CONFIG_USB_STORAGE_DEBUG
+#define CONFIG_USB_STORAGE_RW_DETECT 1
#define CONFIG_USB_STORAGE_DATAFAB 1
#define CONFIG_USB_STORAGE_FREECOM 1
#define CONFIG_USB_STORAGE_ISD200 1
#define CONFIG_USB_SERIAL_MODULE 1
#define CONFIG_USB_SERIAL_GENERIC 1
#define CONFIG_USB_SERIAL_BELKIN_MODULE 1
+#define CONFIG_USB_SERIAL_WHITEHEAT_MODULE 1
#define CONFIG_USB_SERIAL_DIGI_ACCELEPORT_MODULE 1
#define CONFIG_USB_SERIAL_EMPEG_MODULE 1
#define CONFIG_USB_SERIAL_FTDI_SIO_MODULE 1
#define CONFIG_SOLARIS_X86_PARTITION 1
#define CONFIG_UNIXWARE_DISKLABEL 1
#undef CONFIG_LDM_PARTITION
-#undef CONFIG_NEC98_PARTITION
#define CONFIG_SGI_PARTITION 1
#undef CONFIG_ULTRIX_PARTITION
#define CONFIG_SUN_PARTITION 1
/*
* Profiling support
*/
-#define CONFIG_PROFILING 1
-#define CONFIG_OPROFILE_MODULE 1
+#undef CONFIG_PROFILING
/*
* Kernel hacking
#define CONFIG_DEBUG_INFO 1
#define CONFIG_DEBUG_SPINLOCK_SLEEP 1
#undef CONFIG_FRAME_POINTER
-#define CONFIG_X86_FIND_SMP_CONFIG 1
-#define CONFIG_X86_MPPARSE 1
/*
* Security options
#define CONFIG_LIBCRC32C_MODULE 1
#define CONFIG_ZLIB_INFLATE 1
#define CONFIG_ZLIB_DEFLATE_MODULE 1
-#define CONFIG_X86_SMP 1
-#define CONFIG_X86_HT 1
#define CONFIG_X86_BIOS_REBOOT 1
-#define CONFIG_X86_TRAMPOLINE 1
-#define CONFIG_X86_STD_RESOURCES 1
#define CONFIG_PC 1
char * interp; /* Name of the binary really executed. Most
of the time same as filename, but could be
different for binfmt_{misc,script} */
+ unsigned long interp_flags;
unsigned long loader, exec;
};
+#define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
+#define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
+
/*
* This structure defines the functions that are used to load the binary formats that
* linux accepts.
extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
extern void blk_dump_rq_flags(struct request *, char *);
extern void generic_unplug_device(request_queue_t *);
+extern inline void __generic_unplug_device(request_queue_t *);
extern long nr_blockdev_pages(void);
int blk_get_queue(request_queue_t *);
RequestBlock_struct Request;
ErrorInfo_struct error_info;
WORD buf_size; /* size in bytes of the buf */
- BYTE *buf;
+ BYTE __user *buf;
} IOCTL_Command_struct;
typedef struct _BIG_IOCTL_Command_struct {
DWORD malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
DWORD buf_size; /* size in bytes of the buf */
/* < malloc_size * MAXSGENTRIES */
- BYTE *buf;
+ BYTE __user *buf;
} BIG_IOCTL_Command_struct;
typedef struct _LogvolInfo_struct{
#define CCISS_REGNEWDISK _IOW(CCISS_IOC_MAGIC, 13, int)
#define CCISS_REGNEWD _IO(CCISS_IOC_MAGIC, 14)
+#define CCISS_RESCANDISK _IO(CCISS_IOC_MAGIC, 16)
#define CCISS_GETLUNINFO _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
#define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
+#ifdef __KERNEL__
+#ifdef CONFIG_COMPAT
+
+/* 32 bit compatible ioctl structs */
+typedef struct _IOCTL32_Command_struct {
+ LUNAddr_struct LUN_info;
+ RequestBlock_struct Request;
+ ErrorInfo_struct error_info;
+ WORD buf_size; /* size in bytes of the buf */
+ __u32 buf; /* 32 bit pointer to data buffer */
+} IOCTL32_Command_struct;
+
+typedef struct _BIG_IOCTL32_Command_struct {
+ LUNAddr_struct LUN_info;
+ RequestBlock_struct Request;
+ ErrorInfo_struct error_info;
+ DWORD malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
+ DWORD buf_size; /* size in bytes of the buf */
+ /* < malloc_size * MAXSGENTRIES */
+ __u32 buf; /* 32 bit pointer to data buffer */
+} BIG_IOCTL32_Command_struct;
+
+#define CCISS_PASSTHRU32 _IOWR(CCISS_IOC_MAGIC, 11, IOCTL32_Command_struct)
+#define CCISS_BIG_PASSTHRU32 _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL32_Command_struct)
+
+#endif /* CONFIG_COMPAT */
+#endif /* __KERNEL__ */
#endif
struct cdrom_read_audio
{
union cdrom_addr addr; /* frame address */
- __u8 addr_format; /* CDROM_LBA or CDROM_MSF */
+ __u8 addr_format; /* CDROM_LBA or CDROM_MSF */
int nframes; /* number of 2352-byte-frames to read at once */
- __u8 *buf; /* frame buffer (size: nframes*2352 bytes) */
+ __u8 __user *buf; /* frame buffer (size: nframes*2352 bytes) */
};
/* This struct is used with the CDROMMULTISESSION ioctl */
#define PIOCPARM_MASK 0x0000ffff
struct ViceIoctl {
- caddr_t in, out; /* Data to be transferred in, or out */
+ void __user *in; /* Data to be transferred in */
+ void __user *out; /* Data to be transferred out */
short in_size; /* Size of input buffer <= 2K */
short out_size; /* Maximum size of output buffer, <= 2K */
};
struct PioctlData {
- const char *path;
+ const char __user *path;
int follow;
struct ViceIoctl vi;
};
* data structure for /proc/sys/... files
*/
int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
- void * buffer, size_t * lenp );
+ void __user * buffer, size_t * lenp );
int do_reset_coda_cache_inv_stats( ctl_table * table, int write,
- struct file * filp, void * buffer,
+ struct file * filp, void __user * buffer,
size_t * lenp );
/* these functions are called to form the content of /proc/fs/coda/... files */
COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
/* DM */
COMPATIBLE_IOCTL(DM_VERSION_32)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
COMPATIBLE_IOCTL(DM_LIST_DEVICES_32)
COMPATIBLE_IOCTL(DM_DEV_CREATE_32)
COMPATIBLE_IOCTL(DM_DEV_REMOVE_32)
struct cpu {
int node_id; /* The node which contains the CPU */
+ int no_control; /* Should the sysfs control file be created? */
struct sys_device sysdev;
};
#define unlock_cpu_hotplug() up(&cpucontrol)
#define lock_cpu_hotplug_interruptible() down_interruptible(&cpucontrol)
#define hotcpu_notifier(fn, pri) { \
- static struct notifier_block fn##_nb = { fn, pri }; \
+ static struct notifier_block fn##_nb = \
+ { .notifier_call = fn, .priority = pri }; \
register_cpu_notifier(&fn##_nb); \
}
int cpu_down(unsigned int cpu);
#define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; })
#define cpu_present(cpu) ({ BUG_ON((cpu) != 0); 1; })
+#define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++)
#define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++)
#define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++)
#define for_each_present_cpu(cpu) for (cpu = 0; cpu < 1; cpu++)
u8 device;
u8 version;
u16 interface_support;
- u16 legacy_cylinders;
- u8 legacy_heads;
- u8 legacy_sectors;
+ u16 legacy_max_cylinder;
+ u8 legacy_max_head;
+ u8 legacy_sectors_per_track;
struct edd_device_params params;
} __attribute__ ((packed));
u16 length;
} __attribute ((packed));
-/*
- * efi_dir is allocated in arch/ia64/kernel/efi.c.
- */
-#ifdef CONFIG_PROC_FS
-extern struct proc_dir_entry *efi_dir;
-#endif
-
#endif /* _LINUX_EFI_H */
int (*phys_id)(struct net_device *, u32);
int (*get_stats_count)(struct net_device *);
void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
+ int (*begin)(struct net_device *);
+ void (*complete)(struct net_device *);
};
/* CMDs currently supported */
#undef EXT3FS_DEBUG
/*
- * Define EXT3_RESERVATION to reserve data blocks for expanding files
+ * Define EXT3_PREALLOCATE to preallocate data blocks for expanding files
*/
-#define EXT3_DEFAULT_RESERVE_BLOCKS 8
-#define EXT3_MAX_RESERVE_BLOCKS 1024
+#undef EXT3_PREALLOCATE /* @@@ Fix this! */
+#define EXT3_DEFAULT_PREALLOC_BLOCKS 8
+
/*
* Always enable hashed directories
*/
*/
#define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */
#define EXT3_STATE_NEW 0x00000002 /* inode is newly created */
-#define EXT3_STATE_RESIZE 0x00000004 /* fake inode for resizing */
-
-
-/* Used to pass group descriptor data when online resize is done */
-struct ext3_new_group_input {
- __u32 group; /* Group number for this data */
- __u32 block_bitmap; /* Absolute block number of block bitmap */
- __u32 inode_bitmap; /* Absolute block number of inode bitmap */
- __u32 inode_table; /* Absolute block number of inode table start */
- __u32 blocks_count; /* Total number of blocks in this group */
- __u16 reserved_blocks; /* Number of reserved blocks in this group */
- __u16 unused;
-};
-
-/* The struct ext3_new_group_input in kernel space, with free_blocks_count */
-struct ext3_new_group_data {
- __u32 group;
- __u32 block_bitmap;
- __u32 inode_bitmap;
- __u32 inode_table;
- __u32 blocks_count;
- __u16 reserved_blocks;
- __u16 unused;
- __u32 free_blocks_count;
-};
-
/*
* ioctl commands
#define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
#define EXT3_IOC_GETVERSION _IOR('f', 3, long)
#define EXT3_IOC_SETVERSION _IOW('f', 4, long)
-#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
-#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input)
#define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
#define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
#ifdef CONFIG_JBD_DEBUG
#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long)
#endif
-#define EXT3_IOC_GETRSVSZ _IOR('r', 1, long)
-#define EXT3_IOC_SETRSVSZ _IOW('r', 2, long)
/*
* Structure of an inode on the disk
/*
* Mount flags
*/
-#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */
-#define EXT3_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */
-#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */
-#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */
-#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */
-#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */
-#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */
-#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */
-#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/
-#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */
-#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */
-#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */
-#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */
-#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */
-#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */
-#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */
-#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */
-#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
-#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */
+#define EXT3_MOUNT_CHECK 0x0001 /* Do mount-time checks */
+#define EXT3_MOUNT_OLDALLOC 0x0002 /* Don't use the new Orlov allocator */
+#define EXT3_MOUNT_GRPID 0x0004 /* Create files with directory's group */
+#define EXT3_MOUNT_DEBUG 0x0008 /* Some debugging messages */
+#define EXT3_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
+#define EXT3_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
+#define EXT3_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
+#define EXT3_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
+#define EXT3_MOUNT_NOLOAD 0x0100 /* Don't use existing journal*/
+#define EXT3_MOUNT_ABORT 0x0200 /* Fatal error detected */
+#define EXT3_MOUNT_DATA_FLAGS 0x0C00 /* Mode for data writes: */
+ #define EXT3_MOUNT_JOURNAL_DATA 0x0400 /* Write data to journal */
+ #define EXT3_MOUNT_ORDERED_DATA 0x0800 /* Flush data before commit */
+ #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */
+#define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */
+#define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */
+#define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */
+#define EXT3_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef _LINUX_EXT2_FS_H
*/
__u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
__u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
- __u16 s_reserved_gdt_blocks; /* Per group desc for online growth */
+ __u16 s_padding1;
/*
* Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
*/
/* balloc.c */
extern int ext3_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group);
-extern int ext3_new_block (handle_t *, struct inode *, unsigned long, int *);
+extern int ext3_new_block (handle_t *, struct inode *, unsigned long,
+ __u32 *, __u32 *, int *);
extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long,
unsigned long);
extern unsigned long ext3_count_free_blocks (struct super_block *);
extern void ext3_delete_inode (struct inode *);
extern int ext3_sync_inode (handle_t *, struct inode *);
extern void ext3_discard_prealloc (struct inode *);
-extern void ext3_discard_reservation (struct inode *);
extern void ext3_dirty_inode(struct inode *);
extern int ext3_change_inode_journal_flag(struct inode *, int);
extern void ext3_truncate (struct inode *);
extern int ext3_orphan_del(handle_t *, struct inode *);
extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash,
__u32 start_minor_hash, __u32 *next_hash);
-
-/* resize.c */
-extern int ext3_group_add(struct super_block *sb,
- struct ext3_new_group_data *input);
-extern int ext3_group_extend(struct super_block *sb,
- struct ext3_super_block *es,
- unsigned long n_blocks_count);
/* super.c */
extern void ext3_error (struct super_block *, const char *, const char *, ...)
#include <linux/rwsem.h>
-struct reserve_window {
- struct list_head rsv_list;
- __u32 rsv_start;
- __u32 rsv_end;
- atomic_t rsv_goal_size;
- __u32 rsv_alloc_hit;
-};
-
/*
- * third extended file system inode data in memory
+ * second extended file system inode data in memory
*/
struct ext3_inode_info {
__u32 i_data[15];
* allocation when we detect linearly ascending requests.
*/
__u32 i_next_alloc_goal;
- /* block reservation window */
- struct reserve_window i_rsv_window;
-
+#ifdef EXT3_PREALLOCATE
+ __u32 i_prealloc_block;
+ __u32 i_prealloc_count;
+#endif
__u32 i_dir_start_lookup;
#ifdef CONFIG_EXT3_FS_XATTR
/*
struct percpu_counter s_dirs_counter;
struct blockgroup_lock s_blockgroup_lock;
- /* head of the per fs reservation window tree */
- spinlock_t s_rsv_window_lock;
- struct reserve_window s_rsv_window_head;
-
/* Journaling */
struct inode * s_journal_inode;
struct journal_s * s_journal;
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */
- __u32 accel; /* Type of acceleration available */
+ __u32 accel; /* Indicate to driver which */
+ /* specific chip/card we have */
__u16 reserved[3]; /* Reserved for future compatibility */
};
#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */
#define FB_ACTIVATE_FORCE 128 /* force apply even when no change*/
-#define FB_ACCELF_TEXT 1 /* text mode acceleration */
+#define FB_ACCELF_TEXT 1 /* (OBSOLETE) see fb_info.flags and vc_mode */
#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */
- __u32 accel_flags; /* acceleration flags (hints) */
+ __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u16 set; /* what to set */
__u16 enable; /* cursor on/off */
__u16 rop; /* bitop operation */
- char *mask; /* cursor mask bits */
+ const char *mask; /* cursor mask bits */
struct fbcurpos hot; /* cursor hot spot */
struct fb_image image; /* Cursor image */
};
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
- ssize_t (*fb_read)(struct file *file, char *buf, size_t count, loff_t *ppos);
- ssize_t (*fb_write)(struct file *file, const char *buf, size_t count, loff_t *ppos);
+ ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos);
+ ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
};
+/* FBINFO_* = fb_info.flags bit flags */
+#define FBINFO_MODULE 0x0001 /* Low-level driver is a module */
+#define FBINFO_HWACCEL_DISABLED 0x0002
+ /* When FBINFO_HWACCEL_DISABLED is set:
+ * Hardware acceleration is turned off. Software implementations
+ * of required functions (copyarea(), fillrect(), and imageblit())
+ * takes over; acceleration engine should be in a quiescent state */
+
+/* hints */
+#define FBINFO_PARTIAL_PAN_OK 0x0040 /* otw use pan only for double-buffering */
+#define FBINFO_READS_FAST 0x0080 /* soft-copy faster than rendering */
+
+/* hardware supported ops */
+/* semantics: when a bit is set, it indicates that the operation is
+ * accelerated by hardware.
+ * required functions will still work even if the bit is not set.
+ * optional functions may not even exist if the flag bit is not set.
+ */
+#define FBINFO_HWACCEL_NONE 0x0000
+#define FBINFO_HWACCEL_COPYAREA 0x0100 /* required */
+#define FBINFO_HWACCEL_FILLRECT 0x0200 /* required */
+#define FBINFO_HWACCEL_IMAGEBLIT 0x0400 /* required */
+#define FBINFO_HWACCEL_ROTATE 0x0800 /* optional */
+#define FBINFO_HWACCEL_XPAN 0x1000 /* optional */
+#define FBINFO_HWACCEL_YPAN 0x2000 /* optional */
+#define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */
+
+
struct fb_info {
int node;
int flags;
-#define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
};
#ifdef MODULE
-#define FBINFO_FLAG_DEFAULT FBINFO_FLAG_MODULE
+#define FBINFO_DEFAULT FBINFO_MODULE
#else
-#define FBINFO_FLAG_DEFAULT 0
+#define FBINFO_DEFAULT 0
#endif
+// This will go away
+#define FBINFO_FLAG_MODULE FBINFO_MODULE
+#define FBINFO_FLAG_DEFAULT FBINFO_DEFAULT
+
+/* This will go away
+ * fbset currently hacks in FB_ACCELF_TEXT into var.accel_flags
+ * when it wants to turn the acceleration engine on. This is
+ * really a separate operation, and should be modified via sysfs.
+ * But for now, we leave it broken with the following define
+ */
+#define STUPID_ACCELF_TEXT_SHIT
+
// This will go away
#if defined(__sparc__)
#define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */
#define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */
- void *data;
+ void __user *data;
char *kernel_data; /* location of data buffer in the kernel */
struct floppy_raw_cmd *next; /* used for chaining of raw cmd's
* within the kernel */
#ifndef __LINUX_FILTER_H__
#define __LINUX_FILTER_H__
+#include <linux/compiler.h>
+
/*
* Current version of the filter code architecture.
*/
struct sock_fprog /* Required for SO_ATTACH_FILTER. */
{
unsigned short len; /* Number of filter blocks */
- struct sock_filter *filter;
+ struct sock_filter __user *filter;
};
#ifdef __KERNEL__
return vma->vm_flags & VM_HUGETLB;
}
-int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void *, size_t *);
+int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *);
int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
int irq;
int short_req:1; /* Use small block sizes */
int dpt:1; /* Don't quiesce */
+ int raptor:1; /* split bar */
int promise:1; /* Promise controller */
#ifdef CONFIG_MTRR
int mtrr_reg0;
atomic_t users;
struct i2o_device *devices; /* I2O device chain */
struct i2o_controller *next; /* Controller chain */
- unsigned long post_port; /* Inbout port address */
- unsigned long reply_port; /* Outbound port address */
- unsigned long irq_mask; /* Interrupt register address */
+ void *post_port; /* Inbout port address */
+ void *reply_port; /* Outbound port address */
+ void *irq_mask; /* Interrupt register address */
/* Dynamic LCT related data */
struct semaphore lct_sem;
dma_addr_t hrt_phys;
u32 hrt_len;
- unsigned long mem_offset; /* MFA offset */
- unsigned long mem_phys; /* MFA physical */
+ void *base_virt; /* base virtual address */
+ unsigned long base_phys; /* base physical address */
+
+ void *msg_virt; /* messages virtual address */
+ unsigned long msg_phys; /* messages physical address */
int battery:1; /* Has a battery backup */
int io_alloc:1; /* An I/O resource was allocated */
ide_pdc4030, ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100, ide_acorn,
- ide_pc9800, ide_forced
+ ide_forced
} hwif_chipset_t;
/*
typedef enum {
ide_stopped, /* no drive operation was started */
ide_started, /* a drive operation was started, handler was set */
- ide_released, /* as ide_started, but bus also released */
} ide_startstop_t;
struct ide_driver_s;
u8 keep_settings; /* restore settings after drive reset */
u8 autodma; /* device can safely use dma on host */
u8 using_dma; /* disk is using dma for read/write */
- u8 using_tcq; /* disk is using queueing */
u8 retry_pio; /* retrying dma capable host in pio */
u8 state; /* retry state */
u8 waiting_for_dma; /* dma currently in progress */
unsigned remap_0_to_1 : 1; /* 0=noremap, 1=remap 0->1 (for EZDrive) */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
unsigned vdma : 1; /* 1=doing PIO over DMA 0=doing normal DMA */
+ unsigned stroke : 1; /* from: hdx=stroke */
unsigned addressing; /* : 3;
* 0=28-bit
* 1=48-bit
u8 sect; /* "real" sectors per track */
u8 bios_head; /* BIOS/fdisk/LILO number of heads */
u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */
- u8 queue_depth; /* max queue depth */
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
extern struct semaphore ide_setting_sem;
extern int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
-extern void ide_remove_setting(ide_drive_t *drive, char *name);
extern ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name);
extern int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
extern int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val);
extern void proc_ide_create(void);
extern void proc_ide_destroy(void);
-extern void destroy_proc_ide_device(ide_hwif_t *, ide_drive_t *);
extern void destroy_proc_ide_drives(ide_hwif_t *);
extern void create_proc_ide_interfaces(void);
extern void ide_add_proc_entries(struct proc_dir_entry *, ide_proc_entry_t *, void *);
*/
extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
+extern void try_to_flush_leftover_data(ide_drive_t *);
+
/*
* Issue ATA command and wait for completion.
* Use for implementing commands in kernel
extern int __ide_dma_timeout(ide_drive_t *);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-extern int __ide_dma_queued_on(ide_drive_t *drive);
-extern int __ide_dma_queued_off(ide_drive_t *drive);
-extern ide_startstop_t __ide_dma_queued_read(ide_drive_t *drive);
-extern ide_startstop_t __ide_dma_queued_write(ide_drive_t *drive);
-extern ide_startstop_t __ide_dma_queued_start(ide_drive_t *drive);
-#endif
-
#else
static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
#endif /* CONFIG_BLK_DEV_IDEDMA */
#define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable(); } while (0)
-#define IDE_MAX_TAG 32
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-static inline int ata_pending_commands(ide_drive_t *drive)
-{
- if (drive->using_tcq)
- return blk_queue_tag_depth(drive->queue);
-
- return 0;
-}
-
-static inline int ata_can_queue(ide_drive_t *drive)
-{
- if (drive->using_tcq)
- return blk_queue_tag_queue(drive->queue);
-
- return 1;
-}
-#else
-#define ata_pending_commands(drive) (0)
-#define ata_can_queue(drive) (1)
-#endif
-
extern struct bus_type ide_bus_type;
#endif /* _IDE_H */
#include <linux/types.h>
#include <asm/bitops.h>
-#define RESERVED_ID_BITS 8
-
#if BITS_PER_LONG == 32
# define IDR_BITS 5
# define IDR_FULL 0xfffffffful
+/* We can only use two of the bits in the top level because there is
+ only one possible bit in the top level (5 bits * 7 levels = 35
+ bits, but you only use 31 bits in the id). */
+# define TOP_LEVEL_FULL (IDR_FULL >> 30)
#elif BITS_PER_LONG == 64
# define IDR_BITS 6
# define IDR_FULL 0xfffffffffffffffful
+/* We can only use two of the bits in the top level because there is
+ only one possible bit in the top level (6 bits * 6 levels = 36
+ bits, but you only use 31 bits in the id). */
+# define TOP_LEVEL_FULL (IDR_FULL >> 62)
#else
# error "BITS_PER_LONG is not 32 or 64"
#endif
#define IDR_SIZE (1 << IDR_BITS)
#define IDR_MASK ((1 << IDR_BITS)-1)
-/* Define the size of the id's */
-#define BITS_PER_INT (sizeof(int)*8)
-
-#define MAX_ID_SHIFT (BITS_PER_INT - RESERVED_ID_BITS)
-#define MAX_ID_BIT (1 << MAX_ID_SHIFT)
+#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
+#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
#define MAX_ID_MASK (MAX_ID_BIT - 1)
/* Leave the possibility of an incomplete final layer */
#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
struct idr_layer {
- unsigned long bitmap; /* A zero bit means "space here" */
+ unsigned long bitmap; /* A zero bit means "space here" */
struct idr_layer *ary[1<<IDR_BITS];
- int count; /* When zero, we can release it */
+ int count; /* When zero, we can release it */
};
struct idr {
struct idr_layer *top;
struct idr_layer *id_free;
- long count;
int layers;
int id_free_cnt;
spinlock_t lock;
};
-#define IDR_INIT(name) \
+#define IDR_INIT(name) \
{ \
.top = NULL, \
.id_free = NULL, \
- .count = 0, \
.layers = 0, \
.id_free_cnt = 0, \
.lock = SPIN_LOCK_UNLOCKED, \
void *idr_find(struct idr *idp, int id);
int idr_pre_get(struct idr *idp, unsigned gfp_mask);
-int idr_get_new(struct idr *idp, void *ptr);
+int idr_get_new(struct idr *idp, void *ptr, int *id);
+int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
void idr_remove(struct idr *idp, int id);
void idr_init(struct idr *idp);
extern kmem_cache_t *idr_layer_cache;
-
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
- char __user * ifru_data;
+ void __user * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
};
int ifc_len; /* size of buffer */
union
{
- char * ifcu_buf;
- struct ifreq *ifcu_req;
+ char __user *ifcu_buf;
+ struct ifreq __user *ifcu_req;
} ifc_ifcu;
};
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
+#define ARPHRD_NONE 0xFFFE /* zero header length */
/* ARP protocol opcodes. */
#define ARPOP_REQUEST 1 /* ARP request */
#include <linux/netdevice.h>
-extern void brioctl_set(int (*ioctl_hook)(unsigned int, unsigned long));
+extern void brioctl_set(int (*ioctl_hook)(unsigned int, void __user *));
extern int (*br_handle_frame_hook)(struct sk_buff *skb);
extern int (*br_should_route_hook)(struct sk_buff **pskb);
int buffer; /* current buffer for S508 firmware */
};
-extern void dlci_ioctl_set(int (*hook)(unsigned int, void *));
+extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
#endif /* __KERNEL__ */
#define VLAN_VID_MASK 0xfff
/* found in socket.c */
-extern void vlan_ioctl_set(int (*hook)(unsigned long));
+extern void vlan_ioctl_set(int (*hook)(void __user *));
#define VLAN_NAME "vlan"
struct ff_envelope envelope;
/* Only used if waveform == FF_CUSTOM */
- __u32 custom_len; /* Number of samples */
+ __u32 custom_len; /* Number of samples */
__s16 *custom_data; /* Buffer of samples */
/* Note: the data pointed by custom_data is copied by the driver. You can
* therefore dispose of the memory after the upload/update */
#define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
-#define init_input_dev(dev) do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
-
#define SET_INPUT_KEYCODE(dev, scancode, val) \
({ unsigned __old; \
switch (dev->keycodesize) { \
#define to_handle(n) container_of(n,struct input_handle,d_node)
#define to_handle_h(n) container_of(n,struct input_handle,h_node)
+static inline void init_input_dev(struct input_dev *dev)
+{
+ INIT_LIST_HEAD(&dev->h_list);
+ INIT_LIST_HEAD(&dev->node);
+}
+
void input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
-#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
-#define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
-#define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
-#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c)
-#define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c)
-
-#define input_regs(a,b) do { (a)->regs = (b); } while (0)
-#define input_sync(a) do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0)
+static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
+{
+ input_event(dev, EV_KEY, code, !!value);
+}
+
+static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)
+{
+ input_event(dev, EV_REL, code, value);
+}
+
+static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
+{
+ input_event(dev, EV_ABS, code, value);
+}
+
+static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
+{
+ input_event(dev, EV_FF, code, value);
+}
+
+static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
+{
+ input_event(dev, EV_FF_STATUS, code, value);
+}
+
+static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
+{
+ dev->regs = regs;
+}
+
+static inline void input_sync(struct input_dev *dev)
+{
+ input_event(dev, EV_SYN, SYN_REPORT, 0);
+ dev->regs = NULL;
+}
+
+static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
+{
+ dev->absmin[axis] = min;
+ dev->absmax[axis] = max;
+ dev->absfuzz[axis] = fuzz;
+ dev->absflat[axis] = flat;
+
+ dev->absbit[LONG(axis)] |= BIT(axis);
+}
extern struct class_simple *input_class;
struct ipmi_recv_msg *supplied_recv,
int priority);
+/*
+ * Do polling on the IPMI interface the user is attached to. This
+ * causes the IPMI code to do an immediate check for information from
+ * the driver and handle anything that is immediately pending. This
+ * will not block in anyway. This is useful if you need to implement
+ * polling from the user like you need to send periodic watchdog pings
+ * from a crash dump, or something like that.
+ */
+void ipmi_poll_interface(ipmi_user_t user);
+
/*
* When commands come in to the SMS, the user can register to receive
* them. Only one user can be listening on a specific netfn/cmd pair
/* Messages sent to the interface are this format. */
struct ipmi_req
{
- unsigned char *addr; /* Address to send the message to. */
+ unsigned char __user *addr; /* Address to send the message to. */
unsigned int addr_len;
long msgid; /* The sequence number for the message. This
int recv_type; /* Is this a command, response or an
asyncronous event. */
- unsigned char *addr; /* Address the message was from is put
+ unsigned char __user *addr; /* Address the message was from is put
here. The caller must supply the
memory. */
unsigned int addr_len; /* The size of the address buffer.
#define IPMI_CC_NO_ERROR 0x00
#define IPMI_NODE_BUSY_ERR 0xc0
+#define IPMI_INVALID_COMMAND_ERR 0xc1
#define IPMI_ERR_MSG_TRUNCATED 0xc6
#define IPMI_LOST_ARBITRATION_ERR 0x81
#define IPMI_ERR_UNSPECIFIED 0xff
out and that none are pending, and any new requests are run
to completion immediately. */
void (*set_run_to_completion)(void *send_info, int run_to_completion);
+
+ /* Called to poll for work to do. This is so upper layers can
+ poll for operations during things like crash dumps. */
+ void (*poll)(void *send_info);
};
/* Add a low-level interface to the IPMI driver. */
__u16 dst1;
};
+#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
+
struct ipv6_pinfo {
struct in6_addr saddr;
struct in6_addr rcv_saddr;
extern struct buffer_head *isofs_bread(struct inode *, sector_t);
extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
+extern struct inode *isofs_iget(struct super_block *sb,
+ unsigned long block,
+ unsigned long offset);
+
+/* Because the inode number is no longer relevant to finding the
+ * underlying meta-data for an inode, we are free to choose a more
+ * convenient 32-bit number as the inode number. The inode numbering
+ * scheme was recommended by Sergey Vlasov and Eric Lammerts. */
+static inline unsigned long isofs_get_ino(unsigned long block,
+ unsigned long offset,
+ unsigned long bufbits)
+{
+ return (block << (bufbits - 5)) | (offset >> 5);
+}
+
+/* Every directory can have many redundant directory entries scattered
+ * throughout the directory tree. First there is the directory entry
+ * with the name of the directory stored in the parent directory.
+ * Then, there is the "." directory entry stored in the directory
+ * itself. Finally, there are possibly many ".." directory entries
+ * stored in all the subdirectories.
+ *
+ * In order for the NFS get_parent() method to work and for the
+ * general consistency of the dcache, we need to make sure the
+ * "i_iget5_block" and "i_iget5_offset" all point to exactly one of
+ * the many redundant entries for each directory. We normalize the
+ * block and offset by always making them point to the "." directory.
+ *
+ * Notice that we do not use the entry for the directory with the name
+ * that is located in the parent directory. Even though choosing this
+ * first directory is more natural, it is much easier to find the "."
+ * entry in the NFS get_parent() method because it is implicitly
+ * encoded in the "extent + ext_attr_length" fields of _all_ the
+ * redundant entries for the directory. Thus, it can always be
+ * reached regardless of which directory entry you have in hand.
+ *
+ * This works because the "." entry is simply the first directory
+ * record when you start reading the file that holds all the directory
+ * records, and this file starts at "extent + ext_attr_length" blocks.
+ * Because the "." entry is always the first entry listed in the
+ * directories file, the normalized "offset" value is always 0.
+ *
+ * You should pass the directory entry in "de". On return, "block"
+ * and "offset" will hold normalized values. Only directories are
+ * affected making it safe to call even for non-directory file
+ * types. */
+static void inline
+isofs_normalize_block_and_offset(struct iso_directory_record* de,
+ unsigned long *block,
+ unsigned long *offset)
+{
+ /* Only directories are normalized. */
+ if (de->flags[0] & 2) {
+ *offset = 0;
+ *block = (unsigned long)isonum_733(de->extent)
+ + (unsigned long)isonum_711(de->ext_attr_length);
+ }
+}
+
extern struct inode_operations isofs_dir_inode_operations;
extern struct file_operations isofs_dir_operations;
extern struct address_space_operations isofs_symlink_aops;
+extern struct export_operations isofs_export_ops;
/* The following macros are used to check for memory leaks. */
#ifdef LEAK_CHECK
* iso fs inode data in memory
*/
struct iso_inode_info {
+ unsigned long i_iget5_block;
+ unsigned long i_iget5_offset;
unsigned int i_first_extent;
unsigned char i_file_format;
unsigned char i_format_parm[3];
- unsigned long i_next_section_ino;
+ unsigned long i_next_section_block;
+ unsigned long i_next_section_offset;
off_t i_section_size;
struct inode vfs_inode;
};
typedef struct {
int elements_used;
IXJ_CADENCE_TERM termination;
- IXJ_CADENCE_ELEMENT *ce;
+ IXJ_CADENCE_ELEMENT __user *ce;
} IXJ_CADENCE;
#define IXJCTL_TONE_CADENCE _IOW ('q', 0xCA, IXJ_CADENCE *)
#include <linux/errno.h>
#include <linux/compiler.h>
+#define KMOD_PATH_LEN 256
+
#ifdef CONFIG_KMOD
/* modprobe exit status on success, -ve on error. Return value
* usually useless though. */
#include <linux/device.h>
/* get the platform specific defines */
+#ifdef CONFIG_MCA
#include <asm/mca.h>
+#endif
/* The detection of MCA bus is done in the real mode (using BIOS).
* The information is exported to the protected code, where this
struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,
unsigned long idx);
+extern void numa_default_policy(void);
+extern void numa_policy_init(void);
+
#else
struct mempolicy {};
#define vma_policy(vma) NULL
#define vma_set_policy(vma, pol) do {} while(0)
+static inline void numa_policy_init(void)
+{
+}
+
+static inline void numa_default_policy(void)
+{
+}
+
#endif /* CONFIG_NUMA */
#endif /* __KERNEL__ */
#define __LINUX_MII_H__
#include <linux/types.h>
+#include <linux/if.h>
/* Generic MII registers. */
};
+static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
+{
+ return (struct mii_ioctl_data *) &rq->ifr_ifru;
+}
+
+
/**
* mii_nway_result
* @negotiated: value of MII ANAR and'd with ANLPAR
#define SGI_STREAMS_KEYBOARD 150
/* drivers/sgi/char/usema.c */
#define SGI_USEMACLONE 151
+#define HPET_MINOR 152
#define TUN_MINOR 200
struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
unsigned long addr);
struct file *shmem_file_setup(char * name, loff_t size, unsigned long flags);
-int shmem_lock(struct file * file, int lock);
+void shmem_lock(struct file * file, int lock);
int shmem_zero_setup(struct vm_area_struct *);
-static inline int can_do_mlock(void)
-{
- if (capable(CAP_IPC_LOCK))
- return 1;
- if (current->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
- return 1;
- return 0;
-}
-
-
/*
* Parameter block passed down to zap_pte_range in exceptional cases.
*/
#include <linux/types.h>
#define MQ_PRIO_MAX 32768
+/* per-uid limit of kernel memory used by mqueue, in bytes */
+#define MQ_BYTES_MAX 819200
struct mq_attr {
long mq_flags; /* message queue flags */
extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
-extern int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg);
+extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
extern void ip_mr_init(void);
extern unsigned long netdev_fc_xoff;
extern atomic_t netdev_dropping;
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
-extern struct sk_buff * skb_checksum_help(struct sk_buff *skb);
+extern int skb_checksum_help(struct sk_buff **pskb, int inward);
#ifdef CONFIG_NET_FASTROUTE
extern int netdev_fastroute;
extern int netdev_fastroute_obstacles;
struct nf_info *info,
unsigned int verdict);
+extern inline struct ipt_target *
+ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+extern inline struct ip6t_target *
+ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+extern inline struct arpt_target *
+arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
extern void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
#ifdef CONFIG_NETFILTER_DEBUG
/* Number of counters (must be equal to current number of entries). */
unsigned int num_counters;
/* The old entries' counters. */
- struct arpt_counters *counters;
+ struct arpt_counters __user *counters;
/* The entries (hang off end: not really an array). */
struct arpt_entry entries[0];
/* Number of counters (must be equal to current number of entries). */
unsigned int num_counters;
/* The old entries' counters. */
- struct ipt_counters *counters;
+ struct ipt_counters __user *counters;
/* The entries (hang off end: not really an array). */
struct ipt_entry entries[0];
struct ipt_entry entrytable[0];
};
+extern struct semaphore ipt_mutex;
+
/* Standard return verdict, or do jump. */
#define IPT_STANDARD_TARGET ""
/* Error verdict. */
/*
* Main firewall chains definitions and global var's definitions.
*/
+static DECLARE_MUTEX(ipt_mutex);
#ifdef __KERNEL__
#include <linux/init.h>
struct module *me;
};
+extern struct ipt_target *
+ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+extern struct arpt_target *
+arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex);
+
extern int ipt_register_target(struct ipt_target *target);
extern void ipt_unregister_target(struct ipt_target *target);
u_int64_t pcnt, bcnt; /* Packet and byte counters */
};
+static DECLARE_MUTEX(ip6t_mutex);
+
/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
#define IP6T_F_PROTO 0x01 /* Set if rule cares about upper
protocols */
/* Number of counters (must be equal to current number of entries). */
unsigned int num_counters;
/* The old entries' counters. */
- struct ip6t_counters *counters;
+ struct ip6t_counters __user *counters;
/* The entries (hang off end: not really an array). */
struct ip6t_entry entries[0];
struct nfs_string {
unsigned int len;
- const char* data;
+ const char __user * data;
};
struct nfs4_mount_data {
struct nfs_string hostname; /* 1 */
/* Server IP address */
unsigned int host_addrlen; /* 1 */
- struct sockaddr* host_addr; /* 1 */
+ struct sockaddr __user * host_addr; /* 1 */
/* Transport protocol to use */
int proto; /* 1 */
/* Pseudo-flavours to use for authentication. See RFC2623 */
int auth_flavourlen; /* 1 */
- int *auth_flavours; /* 1 */
+ int __user *auth_flavours; /* 1 */
};
/* bits in the flags field */
*/
extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
unsigned long);
-extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char *buf,
+extern ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf,
size_t count, loff_t pos);
extern ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf,
size_t count, loff_t pos);
int err;
exp_get(exp);
expkey_put(&ek->h, &svc_expkey_cache);
- if (exp &&
- (err = cache_check(&svc_export_cache, &exp->h, reqp)))
+ if ((err = cache_check(&svc_export_cache, &exp->h, reqp)))
exp = ERR_PTR(err);
return exp;
} else
| FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \
| FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \
| FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \
- | FATTR4_WORD1_TIME_CREATE | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \
+ | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \
| FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
u32 * buffer;
int buflen;
u32 * offset;
+ u32 * offset1;
struct svc_rqst * rqstp;
};
unsigned long allocstall; /* direct reclaim calls */
unsigned long pgrotated; /* pages rotated to tail of the LRU */
-} ____cacheline_aligned;
+};
DECLARE_PER_CPU(struct page_state, page_states);
extern void get_page_state(struct page_state *ret);
extern void get_full_page_state(struct page_state *ret);
+extern unsigned long __read_page_state(unsigned offset);
+
+#define read_page_state(member) \
+ __read_page_state(offsetof(struct page_state, member))
#define mod_page_state(member, delta) \
do { \
#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags)
#define TestClearPageReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
-#ifndef arch_set_page_uptodate
-#define arch_set_page_uptodate(page) do { } while (0)
-#endif
-
#define PageUptodate(page) test_bit(PG_uptodate, &(page)->flags)
-#define SetPageUptodate(page) \
- do { \
- arch_set_page_uptodate(page); \
- set_bit(PG_uptodate, &(page)->flags); \
- } while (0)
+#ifndef SetPageUptodate
+#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags)
+#endif
#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
#define PageDirty(page) test_bit(PG_dirty, &(page)->flags)
#define PCI_DEVICE_ID_TI_1410 0xac50
#define PCI_DEVICE_ID_TI_1420 0xac51
#define PCI_DEVICE_ID_TI_1451A 0xac52
+#define PCI_DEVICE_ID_TI_1620 0xac54
#define PCI_DEVICE_ID_TI_1520 0xac55
#define PCI_DEVICE_ID_TI_1510 0xac56
#define PCI_VENDOR_ID_3WARE 0x13C1
#define PCI_DEVICE_ID_3WARE_1000 0x1000
+#define PCI_DEVICE_ID_3WARE_7000 0x1001
+#define PCI_DEVICE_ID_3WARE_9000 0x1002
#define PCI_VENDOR_ID_IOMEGA 0x13ca
#define PCI_DEVICE_ID_IOMEGA_BUZ 0x4231
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
+#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
+#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
#define PCI_DEVICE_ID_TIGON3_5782 0x1696
#define PCI_DEVICE_ID_TIGON3_5788 0x169c
+#define PCI_DEVICE_ID_TIGON3_5789 0x169d
#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
{
__u32 latency;
__u32 limit;
-};
+ __u32 loss;
+};
#endif
/* Get/set floating-point exception mode (if meaningful) */
#define PR_GET_FPEXC 11
#define PR_SET_FPEXC 12
+# define PR_FP_EXC_SW_ENABLE 0x80 /* Use FPEXC for FP exception enables */
+# define PR_FP_EXC_DIV 0x010000 /* floating point divide by zero */
+# define PR_FP_EXC_OVF 0x020000 /* floating point overflow */
+# define PR_FP_EXC_UND 0x040000 /* floating point underflow */
+# define PR_FP_EXC_RES 0x080000 /* floating point inexact result */
+# define PR_FP_EXC_INV 0x100000 /* floating point invalid operation */
# define PR_FP_EXC_DISABLED 0 /* FP exceptions disabled */
# define PR_FP_EXC_NONRECOV 1 /* async non-recoverable exc. mode */
# define PR_FP_EXC_ASYNC 2 /* async recoverable exception mode */
struct list_head all_mddevs;
};
+
+static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+ int faulty = rdev->faulty;
+ if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+}
+
struct mdk_personality_s
{
char *name;
int (*hot_remove_disk) (mddev_t *mddev, int number);
int (*spare_active) (mddev_t *mddev);
int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster);
+ int (*resize) (mddev_t *mddev, sector_t sectors);
+ int (*reshape) (mddev_t *mddev, int raid_disks);
};
sector_t head_position;
};
+/*
+ * memory pools need a pointer to the mddev, so they can force an unplug
+ * when memory is tight, and a count of the number of drives that the
+ * pool was allocated for, so they know how much to allocate and free.
+ * mddev->raid_disks cannot be used, as it can change while a pool is active
+ * These two datums are stored in a kmalloced struct.
+ */
+
+struct pool_info {
+ mddev_t *mddev;
+ int raid_disks;
+};
+
+
typedef struct r1bio_s r1bio_t;
struct r1_private_data_s {
wait_queue_head_t wait_idle;
wait_queue_head_t wait_resume;
+ struct pool_info *poolinfo;
+
mempool_t *r1bio_pool;
mempool_t *r1buf_pool;
};
gods only know how we are going to SMP the code that uses them.
znodes are the way! */
+#define PATH_READA 0x1 /* do read ahead */
+#define PATH_READA_BACK 0x2 /* read backwards */
+
struct path {
int path_length; /* Length of the array above. */
+ int reada;
struct path_element path_elements[EXTENDED_MAX_HEIGHT]; /* Array of the path elements. */
int pos_in_item;
};
#define pos_in_item(path) ((path)->pos_in_item)
#define INITIALIZE_PATH(var) \
-struct path var = {ILLEGAL_PATH_ELEMENT_OFFSET, }
+struct path var = {.path_length = ILLEGAL_PATH_ELEMENT_OFFSET, .reada = 0,}
/* Get path element by path and path position. */
#define PATH_OFFSET_PELEMENT(p_s_path,n_offset) ((p_s_path)->path_elements +(n_offset))
int reiserfs_add_ordered_list(struct inode *inode, struct buffer_head *bh);
int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
+static inline int
+reiserfs_file_data_log(struct inode *inode) {
+ if (reiserfs_data_log(inode->i_sb) ||
+ (REISERFS_I(inode)->i_flags & i_data_log))
+ return 1 ;
+ return 0 ;
+}
+
static inline int reiserfs_transaction_running(struct super_block *s) {
struct reiserfs_transaction_handle *th = current->journal_info ;
if (th && th->t_super == s)
typedef struct __reiserfs_blocknr_hint reiserfs_blocknr_hint_t;
int reiserfs_parse_alloc_options (struct super_block *, char *);
+void reiserfs_init_alloc_options (struct super_block *s);
+
+/*
+ * given a directory, this will tell you what packing locality
+ * to use for a new object underneat it. The locality is returned
+ * in disk byte order (le).
+ */
+u32 reiserfs_choose_packing(struct inode *dir);
+
int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value);
void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted);
int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, int);
i_link_saved_truncate_mask = 0x0020,
i_priv_object = 0x0080,
i_has_xattr_dir = 0x0100,
+ i_data_log = 0x0200,
} reiserfs_inode_flags;
extern void cpu_init (void);
extern void trap_init(void);
extern void update_process_times(int user);
-extern void update_one_process(struct task_struct *p, unsigned long user,
- unsigned long system, int cpu);
extern void scheduler_tick(int user_tick, int system);
extern unsigned long cache_decay_ticks;
atomic_t __count; /* reference count */
atomic_t processes; /* How many processes does this user have? */
atomic_t files; /* How many open files does this user have? */
+ atomic_t sigpending; /* How many pending signals does this user have? */
+ /* protected by mq_lock */
+ unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
/* Hash table maintenance information */
struct list_head uidhash_list;
gid_t *blocks[0];
};
+/*
+ * get_group_info() must be called with the owning task locked (via task_lock())
+ * when task != current. The reason being that the vast majority of callers are
+ * looking at current->group_info, which can not be changed except by the
+ * current task. Changing current->group_info requires the task lock, too.
+ */
#define get_group_info(group_info) do { \
atomic_inc(&(group_info)->usage); \
} while (0)
extern void sched_idle_next(void);
extern void set_user_nice(task_t *p, long nice);
-extern int task_prio(task_t *p);
-extern int task_nice(task_t *p);
-extern int task_curr(task_t *p);
+extern int task_prio(const task_t *p);
+extern int task_nice(const task_t *p);
+extern int task_curr(const task_t *p);
extern int idle_cpu(int cpu);
void yield(void);
/* per-UID process charging. */
extern struct user_struct * alloc_uid(uid_t);
+static inline struct user_struct *get_uid(struct user_struct *u)
+{
+ atomic_inc(&u->__count);
+ return u;
+}
extern void free_uid(struct user_struct *);
extern void switch_uid(struct user_struct *);
static inline void kick_process(struct task_struct *tsk) { }
static inline void wake_up_forked_thread(struct task_struct * tsk)
{
- return wake_up_forked_process(tsk);
+ wake_up_forked_process(tsk);
}
#endif
extern void FASTCALL(sched_fork(task_t * p));
#define while_each_thread(g, t) \
while ((t = next_thread(t)) != g)
-extern task_t * FASTCALL(next_thread(task_t *p));
+extern task_t * FASTCALL(next_thread(const task_t *p));
#define thread_group_leader(p) (p->pid == p->tgid)
extern void unhash_process(struct task_struct *p);
/*
- * Protects ->fs, ->files, ->mm, ->ptrace and synchronises with wait4().
+ * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info and synchronises with
+ * wait4().
+ *
* Nests both inside and outside of read_lock(&tasklist_lock).
* It must not be nested with write_lock_irq(&tasklist_lock),
* neither inside nor outside.
*/
#ifdef CONFIG_SMP
-static inline unsigned int task_cpu(struct task_struct *p)
+static inline unsigned int task_cpu(const struct task_struct *p)
{
return p->thread_info->cpu;
}
#else
-static inline unsigned int task_cpu(struct task_struct *p)
+static inline unsigned int task_cpu(const struct task_struct *p)
{
return 0;
}
struct sdla_mem {
int addr;
int len;
- void *data;
+ void __user *data;
};
#define SDLA_START (FRAD_LAST_IOCTL + 7)
extern int cap_syslog (int type);
extern int cap_vm_enough_memory (long pages);
-static inline int cap_netlink_send (struct sk_buff *skb)
+static inline int cap_netlink_send (struct sock *sk, struct sk_buff *skb)
{
NETLINK_CB (skb).eff_cap = current->cap_effective;
return 0;
* Save security information for a netlink message so that permission
* checking can be performed when the message is processed. The security
* information can be saved using the eff_cap field of the
- * netlink_skb_parms structure.
+ * netlink_skb_parms structure. Also may be used to provide fine
+ * grained control over message transmission.
+ * @sk associated sock of task sending the message.,
* @skb contains the sk_buff structure for the netlink message.
- * Return 0 if the information was successfully saved.
+ * Return 0 if the information was successfully saved and message
+ * is allowed to be transmitted.
* @netlink_recv:
* Check permission before processing the received netlink message in
* @skb.
int (*shm_associate) (struct shmid_kernel * shp, int shmflg);
int (*shm_shmctl) (struct shmid_kernel * shp, int cmd);
int (*shm_shmat) (struct shmid_kernel * shp,
- char *shmaddr, int shmflg);
+ char __user *shmaddr, int shmflg);
int (*sem_alloc_security) (struct sem_array * sma);
void (*sem_free_security) (struct sem_array * sma);
int (*sem_semop) (struct sem_array * sma,
struct sembuf * sops, unsigned nsops, int alter);
- int (*netlink_send) (struct sk_buff * skb);
+ int (*netlink_send) (struct sock * sk, struct sk_buff * skb);
int (*netlink_recv) (struct sk_buff * skb);
/* allow module stacking */
return security_ops->setprocattr(p, name, value, size);
}
-static inline int security_netlink_send(struct sk_buff * skb)
+static inline int security_netlink_send(struct sock *sk, struct sk_buff * skb)
{
- return security_ops->netlink_send(skb);
+ return security_ops->netlink_send(sk, skb);
}
static inline int security_netlink_recv(struct sk_buff * skb)
* (rather than hooking into the capability module) to reduce overhead
* in the networking code.
*/
-static inline int security_netlink_send (struct sk_buff *skb)
+static inline int security_netlink_send (struct sock *sk, struct sk_buff *skb)
{
- return cap_netlink_send (skb);
+ return cap_netlink_send (sk, skb);
}
static inline int security_netlink_recv (struct sk_buff *skb)
/* NEC v850. */
#define PORT_V850E_UART 40
-/* NEC PC-9800 */
-#define PORT_8251_PC98 41
-#define PORT_19K_PC98 42
-#define PORT_FIFO_PC98 43
-#define PORT_VFAST_PC98 44
-#define PORT_PC9861 45
-#define PORT_PC9801_101 46
-
/* DZ */
#define PORT_DZ 47
#define SERIO_8042 0x01000000UL
#define SERIO_RS232 0x02000000UL
#define SERIO_HIL_MLC 0x03000000UL
-#define SERIO_PC9800 0x04000000UL
#define SERIO_PS_PSTHRU 0x05000000UL
#define SERIO_8042_XL 0x06000000UL
#include <asm/siginfo.h>
#ifdef __KERNEL__
+
+#define MAX_SIGPENDING 1024
+
/*
* Real Time signals may be queued.
*/
spinlock_t *lock;
int flags;
siginfo_t info;
+ struct user_struct *user;
};
/* flags values. */
skb->tail += len;
}
+/*
+ * CPUs often take a performance hit when accessing unaligned memory
+ * locations. The actual performance hit varies, it can be small if the
+ * hardware handles it or large if we have to take an exception and fix it
+ * in software.
+ *
+ * Since an ethernet header is 14 bytes network drivers often end up with
+ * the IP header at an unaligned offset. The IP header can be aligned by
+ * shifting the start of the packet by 2 bytes. Drivers should do this
+ * with:
+ *
+ * skb_reserve(NET_IP_ALIGN);
+ *
+ * The downside to this alignment of the IP header is that the DMA is now
+ * unaligned. On some architectures the cost of an unaligned DMA is high
+ * and this cost outweighs the gains made by aligning the IP header.
+ *
+ * Since this trade off varies between architectures, we allow NET_IP_ALIGN
+ * to be overridden.
+ */
+#ifndef NET_IP_ALIGN
+#define NET_IP_ALIGN 2
+#endif
+
extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
unsigned long ino;
dev_t dev;
umode_t mode;
- nlink_t nlink;
+ unsigned int nlink;
uid_t uid;
gid_t gid;
dev_t rdev;
*/
struct auth_ops {
char * name;
+ struct module *owner;
int flavour;
int (*accept)(struct svc_rqst *rq, u32 *authp);
int (*release)(struct svc_rqst *rq);
asmlinkage long sys_waitpid(pid_t pid, unsigned int __user *stat_addr, int options);
asmlinkage long sys_set_tid_address(int __user *tidptr);
asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
- struct timespec __user *utime, u32 __user *uaddr2);
+ struct timespec __user *utime, u32 __user *uaddr2,
+ int val3);
asmlinkage long sys_init_module(void __user *umod, unsigned long len,
const char __user *uargs);
__u32 tcpi_snd_cwnd;
__u32 tcpi_advmss;
__u32 tcpi_reordering;
+
+ __u32 tcpi_rcv_rtt;
+ __u32 tcpi_rcv_space;
};
#ifdef __KERNEL__
__u8 urg_mode; /* In urgent mode */
__u32 snd_up; /* Urgent pointer */
- /* The syn_wait_lock is necessary only to avoid tcp_get_info having
+ /* The syn_wait_lock is necessary only to avoid proc interface having
* to grab the main lock sock while browsing the listening hash
* (otherwise it's deadlock prone).
- * This lock is acquired in read mode only from tcp_get_info() and
- * it's acquired in write mode _only_ from code that is actively
+ * This lock is acquired in read mode only from listening_get_next()
+ * and it's acquired in write mode _only_ from code that is actively
* changing the syn_wait_queue. All readers that are holding
* the master sock lock don't need to grab this lock in read mode
* too as the syn_wait_queue writes are always protected from
* Avoid unnecessary multiplications/divisions in the
* two most common HZ cases:
*/
-static inline unsigned int jiffies_to_msecs(unsigned long j)
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
{
#if HZ <= 1000 && !(1000 % HZ)
return (1000 / HZ) * j;
return (j * 1000) / HZ;
#endif
}
-static inline unsigned long msecs_to_jiffies(unsigned int m)
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
{
#if HZ <= 1000 && !(1000 % HZ)
return (m + (1000 / HZ) - 1) / (1000 / HZ);
* value to a scaled second value.
*/
static __inline__ unsigned long
-timespec_to_jiffies(struct timespec *value)
+timespec_to_jiffies(const struct timespec *value)
{
unsigned long sec = value->tv_sec;
long nsec = value->tv_nsec + TICK_NSEC - 1;
}
static __inline__ void
-jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
+jiffies_to_timespec(const unsigned long jiffies, struct timespec *value)
{
/*
* Convert jiffies to nanoseconds and separate with
* instruction above the way it was done above.
*/
static __inline__ unsigned long
-timeval_to_jiffies(struct timeval *value)
+timeval_to_jiffies(const struct timeval *value)
{
unsigned long sec = value->tv_sec;
long usec = value->tv_usec;
}
static __inline__ void
-jiffies_to_timeval(unsigned long jiffies, struct timeval *value)
+jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
{
/*
* Convert jiffies to nanoseconds and separate with
#define UDFFS_DATE "2004/29/09"
#define UDFFS_VERSION "0.9.8.1"
-#define UDFFS_DEBUG
+#undef UDFFS_DEBUG
#ifdef UDFFS_DEBUG
#define udf_debug(f, a...) \
/* mostly for devices emulating SCSI over USB */
extern int usb_reset_device(struct usb_device *dev);
+extern int __usb_reset_device(struct usb_device *dev);
extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
#define _LINUX_WATCHDOG_H
#include <linux/ioctl.h>
+#include <linux/types.h>
#define WATCHDOG_IOCTL_BASE 'W'
WF_{GET,SET}_CHANNEL above.
*/
- wavefront_any *hdrptr; /* user-space ptr to hdr bytes */
- UINT16 *dataptr; /* actual sample data */
+ wavefront_any __user *hdrptr; /* user-space ptr to hdr bytes */
+ UINT16 __user *dataptr; /* actual sample data */
wavefront_any hdr; /* kernel-space copy of hdr bytes */
} wavefront_patch_info;
/* ax25_route.c */
extern void ax25_rt_device_down(struct net_device *);
-extern int ax25_rt_ioctl(unsigned int, void *);
+extern int ax25_rt_ioctl(unsigned int, void __user *);
extern struct file_operations ax25_route_fops;
extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *,
int hci_dev_close(__u16 dev);
int hci_dev_reset(__u16 dev);
int hci_dev_reset_stat(__u16 dev);
-int hci_dev_cmd(unsigned int cmd, unsigned long arg);
-int hci_get_dev_list(unsigned long arg);
-int hci_get_dev_info(unsigned long arg);
-int hci_get_conn_list(unsigned long arg);
-int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
-int hci_inquiry(unsigned long arg);
+int hci_dev_cmd(unsigned int cmd, void __user *arg);
+int hci_get_dev_list(void __user *arg);
+int hci_get_dev_info(void __user *arg);
+int hci_get_conn_list(void __user *arg);
+int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
+int hci_inquiry(void __user *arg);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
struct rfcomm_dev_info dev_info[0];
};
-int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
int rfcomm_init_ttys(void);
void rfcomm_cleanup_ttys(void);
extern void dn_dev_init(void);
extern void dn_dev_cleanup(void);
-extern int dn_dev_ioctl(unsigned int cmd, void *arg);
+extern int dn_dev_ioctl(unsigned int cmd, void __user *arg);
extern void dn_dev_devices_off(void);
extern void dn_dev_devices_on(void);
struct xfrm_state *xfrm;
int (*input)(struct sk_buff*);
- int (*output)(struct sk_buff*);
+ int (*output)(struct sk_buff**);
#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
int (*gc)(void);
struct dst_entry * (*check)(struct dst_entry *, __u32 cookie);
void (*destroy)(struct dst_entry *);
+ void (*ifdown)(struct dst_entry *, int how);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
int err;
for (;;) {
- err = skb->dst->output(skb);
+ err = skb->dst->output(&skb);
if (likely(err == 0))
return err;
struct packet_type *pt);
extern int ip_local_deliver(struct sk_buff *skb);
extern int ip_mr_input(struct sk_buff *skb);
-extern int ip_output(struct sk_buff *skb);
-extern int ip_mc_output(struct sk_buff *skb);
+extern int ip_output(struct sk_buff **pskb);
+extern int ip_mc_output(struct sk_buff **pskb);
extern int ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*));
extern int ip_do_nat(struct sk_buff *skb);
extern void ip_send_check(struct iphdr *ip);
extern struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
struct neighbour *neigh,
struct in6_addr *addr,
- int (*output)(struct sk_buff *));
+ int (*output)(struct sk_buff **));
extern int ndisc_dst_gc(int *more);
extern void fib6_force_start_gc(void);
* skb processing functions
*/
-extern int ip6_output(struct sk_buff *skb);
-extern int ip6_output2(struct sk_buff *skb);
+extern int ip6_output(struct sk_buff **pskb);
extern int ip6_forward(struct sk_buff *skb);
extern int ip6_input(struct sk_buff *skb);
extern int ip6_mc_input(struct sk_buff *skb);
#ifndef IRDA_DEVICE_H
#define IRDA_DEVICE_H
+#include <linux/config.h>
#include <linux/tty.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/irda.h>
+#include <linux/types.h>
#include <net/pkt_sched.h>
#include <net/irda/irda.h>
int irda_device_dongle_cleanup(dongle_t *dongle);
#ifdef CONFIG_ISA
-void irda_setup_dma(int channel, char *buffer, int count, int mode);
+void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode);
#endif
void irda_task_delete(struct irda_task *task);
extern void nr_rt_device_down(struct net_device *);
extern struct net_device *nr_dev_first(void);
extern struct net_device *nr_dev_get(ax25_address *);
-extern int nr_rt_ioctl(unsigned int, void *);
+extern int nr_rt_ioctl(unsigned int, void __user *);
extern void nr_link_failed(ax25_cb *, int);
extern int nr_route_frame(struct sk_buff *, ax25_cb *);
extern struct file_operations nr_nodes_fops;
extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
extern struct net_device *rose_ax25_dev_get(char *);
extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *);
-extern int rose_rt_ioctl(unsigned int, void *);
+extern int rose_rt_ioctl(unsigned int, void __user *);
extern void rose_link_failed(ax25_cb *, int);
extern int rose_route_frame(struct sk_buff *, ax25_cb *);
extern void rose_rt_free(void);
SCTP_CMD_PROCESS_OPERR, /* Process an ERROR chunk. */
SCTP_CMD_REPORT_FWDTSN, /* Report new cumulative TSN Ack. */
SCTP_CMD_PROCESS_FWDTSN, /* Skips were reported, so process further. */
+ SCTP_CMD_CLEAR_INIT_TAG, /* Clears association peer's inittag. */
SCTP_CMD_LAST
} sctp_verb_t;
BUG();
}
+/* Check VTAG of the packet matches the sender's own tag. */
+static inline int
+sctp_vtag_verify(const struct sctp_chunk *chunk,
+ const struct sctp_association *asoc)
+{
+ /* RFC 2960 Sec 8.5 When receiving an SCTP packet, the endpoint
+ * MUST ensure that the value in the Verification Tag field of
+ * the received SCTP packet matches its own Tag. If the received
+ * Verification Tag value does not match the receiver's own
+ * tag value, the receiver shall silently discard the packet...
+ */
+ if (ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag)
+ return 1;
+
+ return 0;
+}
+
/* Check VTAG of the packet matches the sender's own tag OR its peer's
* tag and the T bit is set in the Chunk Flags.
*/
int (*setsockopt) (struct sock *sk,
int level,
int optname,
- char *optval,
+ char __user *optval,
int optlen);
int (*getsockopt) (struct sock *sk,
int level,
int optname,
- char *optval,
- int *optlen);
+ char __user *optval,
+ int __user *optlen);
struct dst_entry *(*get_dst) (struct sctp_association *asoc,
union sctp_addr *daddr,
union sctp_addr *saddr);
struct sctp_getaddrs {
sctp_assoc_t assoc_id;
int addr_num;
- struct sockaddr *addrs;
+ struct sockaddr __user *addrs;
};
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
return test_bit(flag, &sk->sk_flags);
}
+static inline void sk_acceptq_removed(struct sock *sk)
+{
+ sk->sk_ack_backlog--;
+}
+
+static inline void sk_acceptq_added(struct sock *sk)
+{
+ sk->sk_ack_backlog++;
+}
+
+static inline int sk_acceptq_is_full(struct sock *sk)
+{
+ return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
+}
+
+/*
+ * Compute minimal free write space needed to queue new packets.
+ */
+static inline int sk_stream_min_wspace(struct sock *sk)
+{
+ return sk->sk_wmem_queued / 2;
+}
+
+static inline int sk_stream_wspace(struct sock *sk)
+{
+ return sk->sk_sndbuf - sk->sk_wmem_queued;
+}
+
+extern void sk_stream_write_space(struct sock *sk);
+
/* The per-socket spinlock must be held here. */
#define sk_add_backlog(__sk, __skb) \
do { if (!(__sk)->sk_backlog.tail) { \
(__skb)->next = NULL; \
} while(0)
+#define sk_wait_event(__sk, __timeo, __condition) \
+({ int rc; \
+ release_sock(__sk); \
+ rc = __condition; \
+ if (!rc) { \
+ *(__timeo) = schedule_timeout(*(__timeo)); \
+ rc = __condition; \
+ } \
+ lock_sock(__sk); \
+ rc; \
+})
+
+extern int sk_wait_data(struct sock *sk, long *timeo);
+
/* IP protocol blocks we attach to sockets.
* socket layer -> transport layer interface
* transport -> network interface is defined by struct inet_proto
return dst;
}
+static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb)
+{
+ sk->sk_wmem_queued += skb->truesize;
+ sk->sk_forward_alloc -= skb->truesize;
+}
/*
* Queue a received datagram if it will fit. Stream and sequenced
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
}
+extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
+ unsigned long expires);
+
+extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
+
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
int err = 0;
sk->sk_stamp = *stamp;
}
+/**
+ * sk_eat_skb - Release a skb if it is no longer needed
+ * @sk - socket to eat this skb from
+ * @skb - socket buffer to eat
+ *
+ * This routine must be called with interrupts disabled or with the socket
+ * locked so that the sk_buff queue operation is ok.
+*/
+static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb)
+{
+ __skb_unlink(skb, &sk->sk_receive_queue);
+ __kfree_skb(skb);
+}
+
extern atomic_t netstamp_needed;
extern void sock_enable_timestamp(struct sock *sk);
extern void sock_disable_timestamp(struct sock *sk);
long timeout);
extern struct sock * tcp_accept(struct sock *sk, int flags, int *err);
extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
-extern void tcp_write_space(struct sock *sk);
extern int tcp_getsockopt(struct sock *sk, int level,
int optname,
extern const char timer_bug_msg[];
+/* tcp_diag.c */
+extern void tcp_get_info(struct sock *, struct tcp_info *);
+
/* Read 'sendfile()'-style from a TCP socket */
typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
unsigned int, size_t);
tp->pending = 0;
#ifdef TCP_CLEAR_TIMERS
- if (timer_pending(&tp->retransmit_timer) &&
- del_timer(&tp->retransmit_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &tp->retransmit_timer);
#endif
break;
case TCP_TIME_DACK:
tp->ack.pending = 0;
#ifdef TCP_CLEAR_TIMERS
- if (timer_pending(&tp->delack_timer) &&
- del_timer(&tp->delack_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &tp->delack_timer);
#endif
break;
default:
case TCP_TIME_PROBE0:
tp->pending = what;
tp->timeout = jiffies+when;
- if (!mod_timer(&tp->retransmit_timer, tp->timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
break;
case TCP_TIME_DACK:
tp->ack.pending |= TCP_ACK_TIMER;
tp->ack.timeout = jiffies+when;
- if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
break;
default:
#include <net/tcp_ecn.h>
-
-/*
- * Compute minimal free write space needed to queue new packets.
- */
-static inline int tcp_min_write_space(struct sock *sk)
-{
- return sk->sk_wmem_queued / 2;
-}
-
-static inline int tcp_wspace(struct sock *sk)
-{
- return sk->sk_sndbuf - sk->sk_wmem_queued;
-}
-
-
/* This determines how many packets are "in the network" to the best
* of our knowledge. In many cases it is conservative, but where
* detailed information is available from the receiver (via SACK
return tcp_win_from_space(sk->sk_rcvbuf);
}
-static inline void tcp_acceptq_removed(struct sock *sk)
-{
- sk->sk_ack_backlog--;
-}
-
-static inline void tcp_acceptq_added(struct sock *sk)
-{
- sk->sk_ack_backlog++;
-}
-
-static inline int tcp_acceptq_is_full(struct sock *sk)
-{
- return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
-}
-
static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
struct sock *child)
{
struct tcp_opt *tp = tcp_sk(sk);
req->sk = child;
- tcp_acceptq_added(sk);
+ sk_acceptq_added(sk);
if (!tp->accept_queue_tail) {
tp->accept_queue = req;
__kfree_skb(skb);
}
-static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb)
-{
- sk->sk_wmem_queued += skb->truesize;
- sk->sk_forward_alloc -= skb->truesize;
-}
-
extern void __tcp_mem_reclaim(struct sock *sk);
extern int tcp_mem_schedule(struct sock *sk, int size, int kind);
extern spinlock_t tux_module_lock;
extern struct module *tux_module;
-extern long (*sys_tux_ptr) (unsigned int action, user_req_t *u_info);
+extern asmlinkage long (*sys_tux_ptr) (unsigned int action, user_req_t *u_info);
#undef Dprintk
extern void x25_transmit_diagnostic(struct x25_neigh *, unsigned char);
extern void x25_transmit_clear_request(struct x25_neigh *, unsigned int, unsigned char);
extern void x25_transmit_link(struct sk_buff *, struct x25_neigh *);
-extern int x25_subscr_ioctl(unsigned int, void *);
+extern int x25_subscr_ioctl(unsigned int, void __user *);
extern struct x25_neigh *x25_get_neigh(struct net_device *);
extern void x25_link_free(void);
extern struct x25_route *x25_get_route(struct x25_address *addr);
extern struct net_device *x25_dev_get(char *);
extern void x25_route_device_down(struct net_device *dev);
-extern int x25_route_ioctl(unsigned int, void *);
+extern int x25_route_ioctl(unsigned int, void __user *);
extern void x25_route_free(void);
static __inline__ void x25_route_hold(struct x25_route *rt)
void (*destructor)(struct xfrm_state *);
int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
- int (*output)(struct sk_buff *skb);
+ int (*output)(struct sk_buff **pskb);
/* Estimate maximal size of result of transformation of a dgram */
u32 (*get_max_size)(struct xfrm_state *, int size);
};
#ifndef _SCSI_SCSI_EH_H
#define _SCSI_SCSI_EH_H
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+
extern void scsi_add_timer(struct scsi_cmnd *, int,
void (*)(struct scsi_cmnd *));
extern int scsi_delete_timer(struct scsi_cmnd *);
* here then you will get a call to slave_configure(), then the
* device will be used for however long it is kept around, then when
* the device is removed from the system (or * possibly at reboot
- * time), you will then get a call to slave_detach(). This is
+ * time), you will then get a call to slave_destroy(). This is
* assuming you implement slave_configure and slave_destroy.
* However, if you allocate memory and hang it off the device struct,
* then you must implement the slave_destroy() routine at a minimum
* specific setup basis...
* 6. Return 0 on success, non-0 on error. The device will be marked
* as offline on error so that no access will occur. If you return
- * non-0, your slave_detach routine will never get called for this
+ * non-0, your slave_destroy routine will never get called for this
* device, so don't leave any loose memory hanging around, clean
* up after yourself before returning non-0
*
*/
unsigned emulated:1;
+ /*
+ * True if the low-level driver performs its own reset-settle delays.
+ */
+ unsigned skip_settle_delay:1;
+
/*
* Countdown for host blocking with no commands outstanding
*/
} Scsi_FCTargAddress;
extern int scsi_ioctl(struct scsi_device *, int, void __user *);
-extern int kernel_scsi_ioctl(struct scsi_device *, int , void *);
extern int scsi_ioctl_send_command(struct scsi_device *,
struct scsi_ioctl_command __user *);
void *private_data;
int (*info)(void *private_data, gf1_info_t *info);
int (*put_sample)(void *private_data, gf1_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int (*get_sample)(void *private_data, gf1_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int (*remove_sample)(void *private_data, gf1_wave_t *wave,
int atomic);
void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
void *private_data;
int (*info)(void *private_data, iwffff_info_t *info);
int (*put_sample)(void *private_data, iwffff_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int (*get_sample)(void *private_data, iwffff_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int (*remove_sample)(void *private_data, iwffff_wave_t *wave,
int atomic);
void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
void *private_data;
int (*info)(void *private_data, simple_instrument_info_t *info);
int (*put_sample)(void *private_data, simple_instrument_t *instr,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int (*get_sample)(void *private_data, simple_instrument_t *instr,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int (*remove_sample)(void *private_data, simple_instrument_t *instr,
int atomic);
void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
struct sndrv_hwdep_dsp_image {
unsigned int index; /* W: DSP index */
unsigned char name[64]; /* W: ID (e.g. file name) */
- unsigned char *image; /* W: binary image */
+ unsigned char __user *image; /* W: binary image */
size_t length; /* W: size of image in bytes */
unsigned long driver_data; /* W: driver-specific data */
};
struct sndrv_xferi {
sndrv_pcm_sframes_t result;
- void *buf;
+ void __user *buf;
sndrv_pcm_uframes_t frames;
};
struct sndrv_xfern {
sndrv_pcm_sframes_t result;
- void **bufs;
+ void __user * __user *bufs;
sndrv_pcm_uframes_t frames;
};
unsigned int space; /* W: count of element IDs to get */
unsigned int used; /* R: count of element IDs set */
unsigned int count; /* R: count of all elements */
- struct sndrv_ctl_elem_id *pids; /* R: IDs */
+ struct sndrv_ctl_elem_id __user *pids; /* R: IDs */
unsigned char reserved[50];
};
#endif
void *snd_kcalloc(size_t size, int flags);
char *snd_kmalloc_strdup(const char *string, int flags);
-int copy_to_user_fromio(void *dst, unsigned long src, size_t count);
-int copy_from_user_toio(unsigned long dst, const void *src, size_t count);
+int copy_to_user_fromio(void __user *dst, unsigned long src, size_t count);
+int copy_from_user_toio(unsigned long dst, const void __user *src, size_t count);
/* init.c */
unsigned int gpr_map[0x100]; /* initializers */
unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
- emu10k1_fx8010_control_gpr_t *gpr_add_controls; /* GPR controls to add/replace */
+ emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */
unsigned int gpr_del_control_count; /* count of GPR controls to remove */
- snd_ctl_elem_id_t *gpr_del_controls; /* IDs of GPR controls to remove */
+ snd_ctl_elem_id_t __user *gpr_del_controls; /* IDs of GPR controls to remove */
unsigned int gpr_list_control_count; /* count of GPR controls to list */
unsigned int gpr_list_control_total; /* total count of GPR controls */
- emu10k1_fx8010_control_gpr_t *gpr_list_controls; /* listed GPR controls */
+ emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */
unsigned long tram_valid[0xa0/(sizeof(unsigned long)*8)]; /* bitmask of valid initializers */
unsigned int tram_data_map[0xa0]; /* data initializers */
void (*free_voice)(snd_emux_voice_t *vp);
void (*reset)(snd_emux_t *emu, int ch);
/* the first parameters are snd_emux_t */
- int (*sample_new)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void *data, long count);
+ int (*sample_new)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *data, long count);
int (*sample_free)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
void (*sample_reset)(snd_emux_t *emu);
int (*load_fx)(snd_emux_t *emu, int type, int arg, const void __user *data, long count);
#endif
/* gus_dram.c */
-int snd_gus_dram_write(snd_gus_card_t *gus, char *ptr,
+int snd_gus_dram_write(snd_gus_card_t *gus, char __user *ptr,
unsigned int addr, unsigned int size);
-int snd_gus_dram_read(snd_gus_card_t *gus, char *ptr,
+int snd_gus_dram_read(snd_gus_card_t *gus, char __user *ptr,
unsigned int addr, unsigned int size, int rom);
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
/* gus_instr.c */
int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int snd_gus_iwffff_remove_sample(void *private_data, iwffff_wave_t *wave,
int atomic);
int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int snd_gus_gf1_remove_sample(void *private_data, gf1_wave_t *wave,
int atomic);
int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
- char *data, long len, int atomic);
+ char __user *data, long len, int atomic);
int snd_gus_simple_remove_sample(void *private_data, simple_instrument_t *instr,
int atomic);
typedef struct _snd_hdsp_firmware hdsp_firmware_t;
struct _snd_hdsp_firmware {
- unsigned long *firmware_data; /* 24413 long words */
+ unsigned long __user *firmware_data; /* 24413 long words */
};
#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
typedef struct _snd_hwdep_ops {
long long (*llseek) (snd_hwdep_t *hw, struct file * file, long long offset, int orig);
- long (*read) (snd_hwdep_t * hw, char *buf, long count, loff_t *offset);
- long (*write) (snd_hwdep_t * hw, const char *buf, long count, loff_t *offset);
+ long (*read) (snd_hwdep_t * hw, char __user *buf, long count, loff_t *offset);
+ long (*write) (snd_hwdep_t * hw, const char __user *buf, long count, loff_t *offset);
int (*open) (snd_hwdep_t * hw, struct file * file);
int (*release) (snd_hwdep_t * hw, struct file * file);
unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
int (*release) (snd_info_entry_t * entry,
unsigned short mode, void *file_private_data);
long (*read) (snd_info_entry_t *entry, void *file_private_data,
- struct file * file, char *buf, long count);
+ struct file * file, char __user *buf, long count);
long (*write) (snd_info_entry_t *entry, void *file_private_data,
- struct file * file, const char *buf, long count);
+ struct file * file, const char __user *buf, long count);
long long (*llseek) (snd_info_entry_t *entry, void *file_private_data,
struct file * file, long long offset, int orig);
unsigned int (*poll) (snd_info_entry_t *entry, void *file_private_data,
int (*trigger)(snd_pcm_substream_t * substream, int cmd);
snd_pcm_uframes_t (*pointer)(snd_pcm_substream_t * substream);
int (*copy)(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos,
- void *buf, snd_pcm_uframes_t count);
+ void __user *buf, snd_pcm_uframes_t count);
int (*silence)(snd_pcm_substream_t *substream, int channel,
snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
extern rwlock_t snd_pcm_link_rwlock;
int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
-int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
+int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user *info);
int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status);
int snd_pcm_prepare(snd_pcm_substream_t *substream);
int snd_pcm_start(snd_pcm_substream_t *substream);
void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream);
void snd_pcm_period_elapsed(snd_pcm_substream_t *substream);
snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream,
- const void *buf, snd_pcm_uframes_t frames);
+ const void __user *buf,
+ snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream,
- void *buf, snd_pcm_uframes_t frames);
+ void __user *buf, snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
- void **bufs, snd_pcm_uframes_t frames);
+ void __user **bufs, snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
- void **bufs, snd_pcm_uframes_t frames);
+ void __user **bufs, snd_pcm_uframes_t frames);
int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime);
char *instr_type;
int (*info)(void *private_data, char *info_data, long len);
int (*put)(void *private_data, snd_seq_kinstr_t *kinstr,
- char *instr_data, long len, int atomic, int cmd);
+ char __user *instr_data, long len, int atomic, int cmd);
int (*get)(void *private_data, snd_seq_kinstr_t *kinstr,
- char *instr_data, long len, int atomic, int cmd);
+ char __user *instr_data, long len, int atomic, int cmd);
int (*get_size)(void *private_data, snd_seq_kinstr_t *kinstr, long *size);
int (*remove)(void *private_data, snd_seq_kinstr_t *kinstr, int atomic);
void (*notify)(void *private_data, snd_seq_kinstr_t *kinstr, int what);
extern int snd_seq_delete_kernel_client(int client);
extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
extern int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t *ev, int atomic, int hop);
-extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void __user *arg);
+extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
#define SNDRV_SEQ_EXT_MASK 0xc0000000
#define SNDRV_SEQ_EXT_USRPTR 0x80000000
struct sscape_microcode
{
- unsigned char *code;
+ unsigned char __user *code;
};
#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size);
int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk);
int snd_trident_synth_bzero(trident_t *trident, snd_util_memblk_t *blk, int offset, int size);
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char *data, int size);
+int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
#endif /* __SOUND_TRIDENT_H */
inline static void snd_vx_outb(vx_core_t *chip, int reg, unsigned char val)
{
snd_assert(chip->ops->out8, return);
- return chip->ops->out8(chip, reg, val);
+ chip->ops->out8(chip, reg, val);
}
inline static void snd_vx_outl(vx_core_t *chip, int reg, unsigned int val)
{
snd_assert(chip->ops->out32, return);
- return chip->ops->out32(chip, reg, val);
+ chip->ops->out32(chip, reg, val);
}
#define vx_inb(chip,reg) snd_vx_inb(chip, VX_##reg)
WF_{GET,SET}_CHANNEL above.
*/
- wavefront_any *hdrptr; /* user-space ptr to hdr bytes */
- u16 *dataptr; /* actual sample data */
+ wavefront_any __user *hdrptr; /* user-space ptr to hdr bytes */
+ u16 __user *dataptr; /* actual sample data */
wavefront_any hdr; /* kernel-space copy of hdr bytes */
} wavefront_patch_info;
#define TV_AVIDEO 0x00000100
#define TV_SVIDEO 0x00000200
#define TV_SCART 0x00000400
-#define VB_CONEXANT 0x00000800
+#define VB_CONEXANT 0x00000800 /* 661 series only */
+#define VB_TRUMPION VB_CONEXANT /* 300 series only */
#define TV_PALM 0x00001000
#define TV_PALN 0x00002000
#define TV_NTSCJ 0x00001000
#define VB_DISPMODE_DUAL VB_DUALVIEW_MODE
#define VB_DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
-/* *Never* change the order of the following enum */
-typedef enum _SIS_CHIP_TYPE {
- SIS_VGALegacy = 0, /* chip_id in sisfb_info */
- SIS_300,
- SIS_630,
- SIS_540,
- SIS_730,
- SIS_315H,
- SIS_315,
- SIS_315PRO,
- SIS_550,
- SIS_650,
- SIS_740,
- SIS_330,
- SIS_661,
- SIS_741,
- SIS_660,
- SIS_760,
- MAX_SIS_CHIP
-} SIS_CHIP_TYPE;
-
-/* Addtional IOCTLs for communication sisfb <> X driver */
-/* If changing this, vgatypes.h must also be changed (for X driver) */
-
-/* ioctl for identifying and giving some info (esp. memory heap start) */
-#define SISFB_GET_INFO _IOR('n',0xF8,__u32)
-/* ioctrl to get current vertical retrace status */
-#define SISFB_GET_VBRSTATUS _IOR('n',0xF9,__u32)
-/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
-#define SISFB_GET_AUTOMAXIMIZE _IOR('n',0xFA,__u32)
-#define SISFB_SET_AUTOMAXIMIZE _IOW('n',0xFA,__u32)
-
-/* TW: Structure argument for SISFB_GET_INFO ioctl */
+/* Structure argument for SISFB_GET_INFO ioctl */
typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
struct _SISFB_INFO {
- unsigned long sisfb_id; /* for identifying sisfb */
+ __u32 sisfb_id; /* for identifying sisfb */
#ifndef SISFB_ID
#define SISFB_ID 0x53495346 /* Identify myself with 'SISF' */
#endif
- int chip_id; /* PCI ID of detected chip */
- int memory; /* video memory in KB which sisfb manages */
- int heapstart; /* heap start (= sisfb "mem" argument) in KB */
- unsigned char fbvidmode; /* current sisfb mode */
+ __u32 chip_id; /* PCI-ID of detected chip */
+ __u32 memory; /* video memory in KB which sisfb manages */
+ __u32 heapstart; /* heap start (= sisfb "mem" argument) in KB */
+ __u8 fbvidmode; /* current sisfb mode */
- unsigned char sisfb_version;
- unsigned char sisfb_revision;
- unsigned char sisfb_patchlevel;
+ __u8 sisfb_version;
+ __u8 sisfb_revision;
+ __u8 sisfb_patchlevel;
- unsigned char sisfb_caps; /* Sisfb capabilities */
+ __u8 sisfb_caps; /* sisfb capabilities */
- int sisfb_tqlen; /* turbo queue length (in KB) */
+ __u32 sisfb_tqlen; /* turbo queue length (in KB) */
- unsigned int sisfb_pcibus; /* The card's PCI ID */
- unsigned int sisfb_pcislot;
- unsigned int sisfb_pcifunc;
+ __u32 sisfb_pcibus; /* The card's PCI ID */
+ __u32 sisfb_pcislot;
+ __u32 sisfb_pcifunc;
- unsigned char sisfb_lcdpdc; /* PanelDelayCompensation */
+ __u8 sisfb_lcdpdc; /* PanelDelayCompensation */
- unsigned char sisfb_lcda; /* Detected status of LCDA for low res/text modes */
+ __u8 sisfb_lcda; /* Detected status of LCDA for low res/text modes */
- unsigned long sisfb_vbflags;
- unsigned long sisfb_currentvbflags;
+ __u32 sisfb_vbflags;
+ __u32 sisfb_currentvbflags;
- int sisfb_scalelcd;
- unsigned long sisfb_specialtiming;
+ __u32 sisfb_scalelcd;
+ __u32 sisfb_specialtiming;
- unsigned char sisfb_haveemi;
- unsigned char sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
- unsigned char sisfb_haveemilcd;
+ __u8 sisfb_haveemi;
+ __u8 sisfb_emi30,sisfb_emi31,sisfb_emi32,sisfb_emi33;
+ __u8 sisfb_haveemilcd;
- char reserved[213]; /* for future use */
-};
+ __u8 sisfb_lcdpdca; /* PanelDelayCompensation for LCD-via-CRT1 */
-/* For fb memory manager */
-struct sis_memreq {
- unsigned long offset;
- unsigned long size;
-};
+ __u16 sisfb_tvxpos, sisfb_tvypos; /* Warning: Values + 32 ! */
-/* More or less deprecated stuff follows: */
-typedef enum _TVTYPE {
- TVMODE_NTSC = 0,
- TVMODE_PAL,
- TVMODE_HIVISION,
- TVMODE_TOTAL
-} SIS_TV_TYPE;
-
-typedef enum _TVPLUGTYPE {
- TVPLUG_Legacy = 0,
- TVPLUG_COMPOSITE,
- TVPLUG_SVIDEO,
- TVPLUG_SCART,
- TVPLUG_TOTAL
-} SIS_TV_PLUG;
-
-struct mode_info {
- int bpp;
- int xres;
- int yres;
- int v_xres; /* deprecated - use var instead */
- int v_yres; /* deprecated - use var instead */
- int org_x; /* deprecated - use var instead */
- int org_y; /* deprecated - use var instead */
- unsigned int vrate;
+ __u8 reserved[208]; /* for future use */
};
-struct ap_data {
- struct mode_info minfo;
- unsigned long iobase;
- unsigned int mem_size;
- unsigned long disp_state; /* deprecated */
- SIS_CHIP_TYPE chip;
- unsigned char hasVB;
- SIS_TV_TYPE TV_type; /* deprecated */
- SIS_TV_PLUG TV_plug; /* deprecated */
- unsigned long version;
- unsigned long vbflags; /* replaces deprecated entries above */
- unsigned long currentvbflags;
- char reserved[248];
+/* Addtional IOCTLs for communication sisfb <> X driver */
+/* If changing this, vgatypes.h must also be changed (for X driver) */
+
+/* ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO_SIZE _IOR(0xF3,0x00,__u32)
+#define SISFB_GET_INFO _IOR(0xF3,0x01,struct _SISFB_INFO)
+
+/* ioctrl to get current vertical retrace status */
+#define SISFB_GET_VBRSTATUS _IOR(0xF3,0x02,__u32)
+
+/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
+#define SISFB_GET_AUTOMAXIMIZE _IOR(0xF3,0x03,__u32)
+#define SISFB_SET_AUTOMAXIMIZE _IOW(0xF3,0x03,__u32)
+
+/* ioctls to relocate TV output (x=D[31:16], y=D[15:0], + 32)*/
+#define SISFB_GET_TVPOSOFFSET _IOR(0xF3,0x04,__u32)
+#define SISFB_SET_TVPOSOFFSET _IOW(0xF3,0x04,__u32)
+
+/* ioctl for locking sisfb (no register access during lock) */
+/* As of now, only used to avoid register access during
+ * the ioctls listed above.
+ */
+#define SISFB_SET_LOCK _IOW(0xF3,0x06,__u32)
+
+/* more to come soon */
+
+/* ioctls 0xF3 up to 0x3F reserved for sisfb */
+
+/****************************************************************/
+/* The following are deprecated and should not be used anymore: */
+/****************************************************************/
+/* ioctl for identifying and giving some info (esp. memory heap start) */
+#define SISFB_GET_INFO_OLD _IOR('n',0xF8,__u32)
+/* ioctrl to get current vertical retrace status */
+#define SISFB_GET_VBRSTATUS_OLD _IOR('n',0xF9,__u32)
+/* ioctl to enable/disable panning auto-maximize (like nomax parameter) */
+#define SISFB_GET_AUTOMAXIMIZE_OLD _IOR('n',0xFA,__u32)
+#define SISFB_SET_AUTOMAXIMIZE_OLD _IOW('n',0xFA,__u32)
+/****************************************************************/
+/* End of deprecated ioctl numbers */
+/****************************************************************/
+
+/* For fb memory manager (FBIO_ALLOC, FBIO_FREE) */
+struct sis_memreq {
+ __u32 offset;
+ __u32 size;
};
/**********************************************/
/* PRIVATE */
+/* (for IN-KERNEL usage only) */
/**********************************************/
#ifdef __KERNEL__
-#include <linux/spinlock.h>
-
-typedef enum _VGA_ENGINE {
- UNKNOWN_VGA = 0,
- SIS_300_VGA,
- SIS_315_VGA,
-} VGA_ENGINE;
-
-struct video_info {
- int chip_id;
- unsigned int video_size;
- unsigned long video_base;
- char * video_vbase;
- unsigned long mmio_base;
- char * mmio_vbase;
- unsigned long vga_base;
- unsigned long mtrr;
- unsigned long heapstart;
-
- int video_bpp;
- int video_cmap_len;
- int video_width;
- int video_height;
- int video_vwidth; /* DEPRECATED - use var instead */
- int video_vheight; /* DEPRECATED - use var instead */
- int org_x; /* DEPRECATED - use var instead */
- int org_y; /* DEPRECATED - use var instead */
- int video_linelength;
- unsigned int refresh_rate;
-
- unsigned long disp_state; /* DEPRECATED */
- unsigned char hasVB; /* DEPRECATED */
- unsigned char TV_type; /* DEPRECATED */
- unsigned char TV_plug; /* DEPRECATED */
-
- SIS_CHIP_TYPE chip;
- unsigned char revision_id;
-
- unsigned short DstColor; /* For 2d acceleration */
- unsigned long SiS310_AccelDepth;
- unsigned long CommandReg;
-
- spinlock_t lockaccel; /* Do not use outside of kernel! */
-
- unsigned int pcibus;
- unsigned int pcislot;
- unsigned int pcifunc;
-
- int accel;
-
- unsigned short subsysvendor;
- unsigned short subsysdevice;
-
- unsigned long vbflags; /* Replacing deprecated stuff from above */
- unsigned long currentvbflags;
-
- int current_bpp;
- int current_width;
- int current_height;
- int current_htotal;
- int current_vtotal;
- __u32 current_pixclock;
- int current_refresh_rate;
-
- char reserved[200];
-};
-
-extern struct video_info ivideo;
+#define UNKNOWN_VGA 0
+#define SIS_300_VGA 1
+#define SIS_315_VGA 2
extern void sis_malloc(struct sis_memreq *req);
-extern void sis_free(unsigned long base);
-extern void sis_dispinfo(struct ap_data *rec);
+extern void sis_free(u32 base);
#endif
+
#endif
up to the user level program to do useful things with this
information. This is generally a good idea, so say Y.
+config BSD_PROCESS_ACCT_V3
+ bool "BSD Process Accounting version 3 file format"
+ depends on BSD_PROCESS_ACCT
+ default n
+ help
+ If you say Y here, the process accounting information is written
+ in a new file format that also logs the process IDs of each
+ process and it's parent. Note that this file format is incompatible
+ with previous v0/v1/v2 file formats, so you will need updated tools
+ for processing it. A preliminary version of these tools is available
+ at <http://http://www.de.kernel.org/pub/linux/utils/acct/>.
+
config SYSCTL
bool "Sysctl support"
---help---
#include <linux/efi.h>
#include <linux/unistd.h>
#include <linux/rmap.h>
+#include <linux/mempolicy.h>
#include <asm/io.h>
#include <asm/bugs.h>
loops_per_jiffy = (1<<12);
printk("Calibrating delay loop... ");
- while (loops_per_jiffy <<= 1) {
+ while ((loops_per_jiffy <<= 1) != 0) {
/* wait for "start of" clock tick */
ticks = jiffies;
while (ticks == jiffies)
panic_later = "Too many boot env vars at `%s'";
panic_param = param;
}
+ if (!strncmp(param, envp_init[i], val - param))
+ break;
}
envp_init[i] = param;
} else {
static void noinline rest_init(void)
{
kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
+ numa_default_policy();
unlock_kernel();
cpu_idle();
}
#endif
mem_init();
kmem_cache_init();
+ numa_policy_init();
if (late_time_init)
late_time_init();
calibrate_delay();
* check if there is an early userspace init. If yes, let it do all
* the work
*/
- if (sys_access("/init", 0) == 0)
+ if (sys_access((const char __user *) "/init", 0) == 0)
execute_command = "/init";
else
prepare_namespace();
free_initmem();
unlock_kernel();
system_state = SYSTEM_RUNNING;
+ numa_default_policy();
- if (sys_open("/dev/console", O_RDWR, 0) < 0)
+ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
printk("Warning: unable to open an initial console.\n");
(void) sys_dup(0);
#define CTL_MSGSIZEMAX 4
/* default values */
-#define DFLT_QUEUESMAX 64 /* max number of message queues */
-#define DFLT_MSGMAX 40 /* max number of messages in each queue */
+#define DFLT_QUEUESMAX 256 /* max number of message queues */
+#define DFLT_MSGMAX 10 /* max number of messages in each queue */
#define HARD_MSGMAX (131072/sizeof(void*))
-#define DFLT_MSGSIZEMAX 16384 /* max message size */
+#define DFLT_MSGSIZEMAX 8192 /* max message size */
#define NOTIFY_COOKIE_LEN 32
struct sigevent notify;
pid_t notify_owner;
+ struct user_struct *user; /* user who created, for accouting */
struct sock *notify_sock;
struct sk_buff *notify_cookie;
if (S_ISREG(mode)) {
struct mqueue_inode_info *info;
+ struct task_struct *p = current;
+ struct user_struct *u = p->user;
+ unsigned long mq_bytes, mq_msg_tblsz;
inode->i_fop = &mqueue_file_operations;
inode->i_size = FILENT_SIZE;
init_waitqueue_head(&info->wait_q);
INIT_LIST_HEAD(&info->e_wait_q[0].list);
INIT_LIST_HEAD(&info->e_wait_q[1].list);
+ info->messages = NULL;
info->notify_owner = 0;
info->qsize = 0;
+ info->user = NULL; /* set when all is ok */
memset(&info->attr, 0, sizeof(info->attr));
info->attr.mq_maxmsg = DFLT_MSGMAX;
info->attr.mq_msgsize = DFLT_MSGSIZEMAX;
info->attr.mq_maxmsg = attr->mq_maxmsg;
info->attr.mq_msgsize = attr->mq_msgsize;
}
- info->messages = kmalloc(info->attr.mq_maxmsg * sizeof(struct msg_msg *), GFP_KERNEL);
+ mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *);
+ mq_bytes = (mq_msg_tblsz +
+ (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+
+ spin_lock(&mq_lock);
+ if (u->mq_bytes + mq_bytes < u->mq_bytes ||
+ u->mq_bytes + mq_bytes >
+ p->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
+ spin_unlock(&mq_lock);
+ goto out_inode;
+ }
+ u->mq_bytes += mq_bytes;
+ spin_unlock(&mq_lock);
+
+ info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
if (!info->messages) {
- make_bad_inode(inode);
- iput(inode);
- inode = NULL;
+ spin_lock(&mq_lock);
+ u->mq_bytes -= mq_bytes;
+ spin_unlock(&mq_lock);
+ goto out_inode;
}
+ /* all is ok */
+ info->user = get_uid(u);
} else if (S_ISDIR(mode)) {
inode->i_nlink++;
/* Some things misbehave if size == 0 on a directory */
}
}
return inode;
+out_inode:
+ make_bad_inode(inode);
+ iput(inode);
+ return NULL;
}
static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
static void mqueue_delete_inode(struct inode *inode)
{
struct mqueue_inode_info *info;
+ struct user_struct *user;
+ unsigned long mq_bytes;
int i;
if (S_ISDIR(inode->i_mode)) {
clear_inode(inode);
- if (info->messages) {
+ mq_bytes = (info->attr.mq_maxmsg * sizeof(struct msg_msg *) +
+ (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+ user = info->user;
+ if (user) {
spin_lock(&mq_lock);
+ user->mq_bytes -= mq_bytes;
queues_count--;
spin_unlock(&mq_lock);
+ free_uid(user);
}
}
info->notify_owner = 0;
}
+static int mq_attr_ok(struct mq_attr *attr)
+{
+ if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0)
+ return 0;
+ if (capable(CAP_SYS_RESOURCE)) {
+ if (attr->mq_maxmsg > HARD_MSGMAX)
+ return 0;
+ } else {
+ if (attr->mq_maxmsg > msg_max ||
+ attr->mq_msgsize > msgsize_max)
+ return 0;
+ }
+ /* check for overflow */
+ if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg)
+ return 0;
+ if ((unsigned long)(attr->mq_maxmsg * attr->mq_msgsize) +
+ (attr->mq_maxmsg * sizeof (struct msg_msg *)) <
+ (unsigned long)(attr->mq_maxmsg * attr->mq_msgsize))
+ return 0;
+ return 1;
+}
+
/*
* Invoked when creating a new queue via sys_mq_open
*/
if (u_attr != NULL) {
if (copy_from_user(&attr, u_attr, sizeof(attr)))
return ERR_PTR(-EFAULT);
-
- if (attr.mq_maxmsg <= 0 || attr.mq_msgsize <= 0)
+ if (!mq_attr_ok(&attr))
return ERR_PTR(-EINVAL);
- if (capable(CAP_SYS_RESOURCE)) {
- if (attr.mq_maxmsg > HARD_MSGMAX)
- return ERR_PTR(-EINVAL);
- } else {
- if (attr.mq_maxmsg > msg_max ||
- attr.mq_msgsize > msgsize_max)
- return ERR_PTR(-EINVAL);
- }
/* store for use during create */
dentry->d_fsdata = &attr;
}
case SHM_LOCK:
case SHM_UNLOCK:
{
- /* Allow superuser to lock segment in memory */
- if (!can_do_mlock()) {
+/* Allow superuser to lock segment in memory */
+/* Should the pages be faulted in here or leave it to user? */
+/* need to determine interaction with current->swappable */
+ if (!capable(CAP_IPC_LOCK)) {
err = -EPERM;
goto out;
}
+
shp = shm_lock(shmid);
if(shp==NULL) {
err = -EINVAL;
goto out_unlock;
if(cmd==SHM_LOCK) {
- if (!is_file_hugepages(shp->shm_file)) {
- err = shmem_lock(shp->shm_file, 1);
- if (!err)
- shp->shm_flags |= SHM_LOCKED;
- }
+ if (!is_file_hugepages(shp->shm_file))
+ shmem_lock(shp->shm_file, 1);
+ shp->shm_flags |= SHM_LOCKED;
} else {
if (!is_file_hugepages(shp->shm_file))
shmem_lock(shp->shm_file, 0);
granted_mode >>= 3;
/* is there some bit set in requested_mode but not in granted_mode? */
if ((requested_mode & ~granted_mode & 0007) &&
- !capable(CAP_IPC_OWNER)) {
- if (!can_do_mlock()) {
- return -1;
- }
- }
+ !capable(CAP_IPC_OWNER))
+ return -1;
return security_ipc_permission(ipcp, flag);
}
return exp;
}
+#if ACCT_VERSION==1 || ACCT_VERSION==2
+/*
+ * encode an u64 into a comp2_t (24 bits)
+ *
+ * Format: 5 bit base 2 exponent, 20 bits mantissa.
+ * The leading bit of the mantissa is not stored, but implied for
+ * non-zero exponents.
+ * Largest encodable value is 50 bits.
+ */
+
+#define MANTSIZE2 20 /* 20 bit mantissa. */
+#define EXPSIZE2 5 /* 5 bit base 2 exponent. */
+#define MAXFRACT2 ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */
+#define MAXEXP2 ((1 <<EXPSIZE2) - 1) /* Maximum exponent. */
+
+static comp2_t encode_comp2_t(u64 value)
+{
+ int exp, rnd;
+
+ exp = (value > (MAXFRACT2>>1));
+ rnd = 0;
+ while (value > MAXFRACT2) {
+ rnd = value & 1;
+ value >>= 1;
+ exp++;
+ }
+
+ /*
+ * If we need to round up, do it (and handle overflow correctly).
+ */
+ if (rnd && (++value > MAXFRACT2)) {
+ value >>= 1;
+ exp++;
+ }
+
+ if (exp > MAXEXP2) {
+ /* Overflow. Return largest representable number instead. */
+ return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
+ } else {
+ return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
+ }
+}
+#endif
+
+#if ACCT_VERSION==3
+/*
+ * encode an u64 into a 32 bit IEEE float
+ */
+static u32 encode_float(u64 value)
+{
+ unsigned exp = 190;
+ unsigned u;
+
+ if (value==0) return 0;
+ while ((s64)value > 0){
+ value <<= 1;
+ exp--;
+ }
+ u = (u32)(value >> 40) & 0x7fffffu;
+ return u | (exp << 23);
+}
+#endif
+
/*
* Write an accounting entry for an exiting process
*
*/
static void do_acct_process(long exitcode, struct file *file)
{
- struct acct ac;
+ acct_t ac;
mm_segment_t fs;
unsigned long vsize;
unsigned long flim;
* Fill the accounting struct with the needed info as recorded
* by the different kernel functions.
*/
- memset((caddr_t)&ac, 0, sizeof(struct acct));
+ memset((caddr_t)&ac, 0, sizeof(acct_t));
+ ac.ac_version = ACCT_VERSION;
strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));
- elapsed = jiffies_64_to_clock_t(get_jiffies_64() - current->start_time);
+ elapsed = jiffies_64_to_AHZ(get_jiffies_64() - current->start_time);
+#if ACCT_VERSION==3
+ ac.ac_etime = encode_float(elapsed);
+#else
ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
(unsigned long) elapsed : (unsigned long) -1l);
- do_div(elapsed, USER_HZ);
+#endif
+#if ACCT_VERSION==1 || ACCT_VERSION==2
+ {
+ /* new enlarged etime field */
+ comp2_t etime = encode_comp2_t(elapsed);
+ ac.ac_etime_hi = etime >> 16;
+ ac.ac_etime_lo = (u16) etime;
+ }
+#endif
+ do_div(elapsed, AHZ);
ac.ac_btime = xtime.tv_sec - elapsed;
- ac.ac_utime = encode_comp_t(jiffies_to_clock_t(current->utime));
- ac.ac_stime = encode_comp_t(jiffies_to_clock_t(current->stime));
+ ac.ac_utime = encode_comp_t(jiffies_to_AHZ(current->utime));
+ ac.ac_stime = encode_comp_t(jiffies_to_AHZ(current->stime));
/* we really need to bite the bullet and change layout */
ac.ac_uid = current->uid;
ac.ac_gid = current->gid;
+#if ACCT_VERSION==2
+ ac.ac_ahz = AHZ;
+#endif
+#if ACCT_VERSION==1 || ACCT_VERSION==2
+ /* backward-compatible 16 bit fields */
+ ac.ac_uid16 = current->uid;
+ ac.ac_gid16 = current->gid;
+#endif
+#if ACCT_VERSION==3
+ ac.ac_pid = current->pid;
+ ac.ac_ppid = current->parent->pid;
+#endif
read_lock(&tasklist_lock); /* pin current->signal */
ac.ac_tty = current->signal->tty ?
old_encode_dev(tty_devnum(current->signal->tty)) : 0;
read_unlock(&tasklist_lock);
- ac.ac_flag = 0;
+ /* ABYTESEX is always set to allow byte order detection */
+ ac.ac_flag = ABYTESEX;
if (current->flags & PF_FORKNOEXEC)
ac.ac_flag |= AFORK;
if (current->flags & PF_SUPERPRIV)
flim = current->rlim[RLIMIT_FSIZE].rlim_cur;
current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
file->f_op->write(file, (char *)&ac,
- sizeof(struct acct), &file->f_pos);
+ sizeof(acct_t), &file->f_pos);
current->rlim[RLIMIT_FSIZE].rlim_cur = flim;
set_fs(fs);
}
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_sigpending(&s);
+ ret = sys_sigpending((old_sigset_t __user *) &s);
set_fs(old_fs);
if (ret == 0)
ret = put_user(s, set);
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
+ ret = sys_sigprocmask(how,
+ set ? (old_sigset_t __user *) &s : NULL,
+ oset ? (old_sigset_t __user *) &s : NULL);
set_fs(old_fs);
if (ret == 0)
if (oset)
timeout = timespec_to_jiffies(&t) + 1;
}
if (op >= FUTEX_REQUEUE)
- val2 = (int) (long) utime;
+ val2 = (int) (unsigned long) utime;
return do_futex((unsigned long)uaddr, op, val, timeout,
(unsigned long)uaddr2, val2, val3);
if (r.rlim_max == COMPAT_RLIM_INFINITY)
r.rlim_max = RLIM_INFINITY;
set_fs(KERNEL_DS);
- ret = sys_setrlimit(resource, &r);
+ ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
set_fs(old_fs);
return ret;
}
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_getrlimit(resource, &r);
+ ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
set_fs(old_fs);
if (!ret) {
if (r.rlim_cur > COMPAT_RLIM_INFINITY)
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
- ret = sys_getrusage(who, &r);
+ ret = sys_getrusage(who, (struct rusage __user *) &r);
set_fs(old_fs);
if (ret)
mm_segment_t old_fs = get_fs();
set_fs (KERNEL_DS);
- ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
+ ret = sys_wait4(pid,
+ (stat_addr ?
+ (unsigned int __user *) &status : NULL),
+ options, (struct rusage __user *) &r);
set_fs (old_fs);
if (ret > 0) {
unsigned int len,
compat_ulong_t __user *user_mask_ptr)
{
- unsigned long kernel_mask;
+ unsigned long kern_mask;
mm_segment_t old_fs;
int ret;
- if (get_user(kernel_mask, user_mask_ptr))
+ if (get_user(kern_mask, user_mask_ptr))
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_sched_setaffinity(pid,
- sizeof(kernel_mask),
- &kernel_mask);
+ sizeof(kern_mask),
+ (unsigned long __user *) &kern_mask);
set_fs(old_fs);
return ret;
asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
compat_ulong_t __user *user_mask_ptr)
{
- unsigned long kernel_mask;
+ unsigned long kern_mask;
mm_segment_t old_fs;
int ret;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_sched_getaffinity(pid,
- sizeof(kernel_mask),
- &kernel_mask);
+ sizeof(kern_mask),
+ (unsigned long __user *) &kern_mask);
set_fs(old_fs);
if (ret > 0) {
ret = sizeof(compat_ulong_t);
- if (put_user(kernel_mask, user_mask_ptr))
+ if (put_user(kern_mask, user_mask_ptr))
return -EFAULT;
}
return -EFAULT;
oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sys_timer_settime(timer_id, flags, &newts, &oldts);
+ err = sys_timer_settime(timer_id, flags,
+ (struct itimerspec __user *) &newts,
+ (struct itimerspec __user *) &oldts);
set_fs(oldfs);
if (!err && old && put_compat_itimerspec(old, &oldts))
return -EFAULT;
long err;
mm_segment_t oldfs;
struct itimerspec ts;
+
oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sys_timer_gettime(timer_id, &ts);
+ err = sys_timer_gettime(timer_id,
+ (struct itimerspec __user *) &ts);
set_fs(oldfs);
if (!err && put_compat_itimerspec(setting, &ts))
return -EFAULT;
long err;
mm_segment_t oldfs;
struct timespec ts;
+
if (get_compat_timespec(&ts, tp))
return -EFAULT;
oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sys_clock_settime(which_clock, &ts);
+ err = sys_clock_settime(which_clock,
+ (struct timespec __user *) &ts);
set_fs(oldfs);
return err;
}
long err;
mm_segment_t oldfs;
struct timespec ts;
+
oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sys_clock_gettime(which_clock, &ts);
+ err = sys_clock_gettime(which_clock,
+ (struct timespec __user *) &ts);
set_fs(oldfs);
if (!err && put_compat_timespec(&ts, tp))
return -EFAULT;
long err;
mm_segment_t oldfs;
struct timespec ts;
+
oldfs = get_fs();
set_fs(KERNEL_DS);
- err = sys_clock_getres(which_clock, &ts);
+ err = sys_clock_getres(which_clock,
+ (struct timespec __user *) &ts);
set_fs(oldfs);
if (!err && put_compat_timespec(&ts, tp))
return -EFAULT;
long err;
mm_segment_t oldfs;
struct timespec in, out;
+
if (get_compat_timespec(&in, rqtp))
return -EFAULT;
+
oldfs = get_fs();
- set_fs(KERNEL_DS);
- err = sys_clock_nanosleep(which_clock, flags, &in, &out);
+ set_fs(KERNEL_DS);
+ err = sys_clock_nanosleep(which_clock, flags,
+ (struct timespec __user *) &in,
+ (struct timespec __user *) &out);
set_fs(oldfs);
if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
put_compat_timespec(&out, rmtp))
* Clear these here so that update_process_times() won't try to deliver
* itimer, profile or rlimit signals to this task while it is in late exit.
*/
- tsk->it_virt_incr = 0;
+ tsk->it_virt_value = 0;
tsk->it_prof_value = 0;
tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY;
do_exit((error_code&0xff)<<8);
}
-task_t fastcall *next_thread(task_t *p)
+task_t fastcall *next_thread(const task_t *p)
{
- struct pid_link *link = p->pids + PIDTYPE_TGID;
- struct list_head *tmp, *head = &link->pidptr->task_list;
+ const struct pid_link *link = p->pids + PIDTYPE_TGID;
+ const struct list_head *tmp, *head = &link->pidptr->task_list;
#ifdef CONFIG_SMP
if (!p->sighand)
struct vm_area_struct * mpnt, *tmp, **pprev;
struct rb_node **rb_link, *rb_parent;
int retval;
- unsigned long charge = 0;
+ unsigned long charge;
struct mempolicy *pol;
down_write(&oldmm->mmap_sem);
if(mpnt->vm_flags & VM_DONTCOPY)
continue;
+ charge = 0;
if (mpnt->vm_flags & VM_ACCOUNT) {
unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
if (security_vm_enough_memory(len))
goto fail_nomem;
- charge += len;
+ charge = len;
}
tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!tmp)
tmp->vm_ops->open(tmp);
if (retval)
- goto fail;
+ goto out;
}
retval = 0;
kmem_cache_free(vm_area_cachep, tmp);
fail_nomem:
retval = -ENOMEM;
-fail:
vm_unacct_memory(charge);
goto out;
}
+
static inline int mm_alloc_pgd(struct mm_struct * mm)
{
mm->pgd = pgd_alloc(mm);
* not set up a proper pointer then tough luck.
*/
put_user(0, tidptr);
- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL);
+ sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
}
}
#include <linux/futex.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
+#include <linux/syscalls.h>
#define FUTEX_HASHBITS 8
before *uaddr1. */
smp_mb();
- if (get_user(curval, (int *)uaddr1) != 0) {
+ if (get_user(curval, (int __user *)uaddr1) != 0) {
ret = -EFAULT;
goto out;
}
/*
modprobe_path is set via /proc/sys.
*/
-char modprobe_path[256] = "/sbin/modprobe";
+char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
/**
* request_module - try to load a kernel module
events. the command is expected to load drivers when
necessary, and may perform additional system setup.
*/
-char hotplug_path[256] = "/sbin/hotplug";
+char hotplug_path[KMOD_PATH_LEN] = "/sbin/hotplug";
EXPORT_SYMBOL(hotplug_path);
allow_signal(SIGCHLD);
pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
- if (pid < 0)
+ if (pid < 0) {
sub_info->retval = pid;
- else
- sys_wait4(pid, &sub_info->retval, 0, NULL);
+ } else {
+ /*
+ * Normally it is bogus to call wait4() from in-kernel because
+ * wait4() wants to write the exit code to a userspace address.
+ * But wait_for_helper() always runs as keventd, and put_user()
+ * to a kernel address works OK for kernel threads, due to their
+ * having an mm_segment_t which spans the entire address space.
+ *
+ * Thus the __user pointer cast is valid here.
+ */
+ sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL);
+ }
complete(sub_info->complete);
return 0;
#include <linux/stop_machine.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
-#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#if 0
}
asmlinkage long
-sys_delete_module(const char *name_user, unsigned int flags)
+sys_delete_module(const char __user *name_user, unsigned int flags)
{
return -ENOSYS;
}
if (!tmr)
return tmr;
memset(tmr, 0, sizeof (struct k_itimer));
- tmr->it_id = (timer_t)-1;
if (unlikely(!(tmr->sigq = sigqueue_alloc()))) {
kmem_cache_free(posix_timers_cache, tmr);
tmr = 0;
return tmr;
}
-static void release_posix_timer(struct k_itimer *tmr)
+#define IT_ID_SET 1
+#define IT_ID_NOT_SET 0
+static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
{
- if (tmr->it_id != -1) {
+ if (it_id_set) {
unsigned long flags;
spin_lock_irqsave(&idr_lock, flags);
idr_remove(&posix_timers_id, tmr->it_id);
{
int error = 0;
struct k_itimer *new_timer = NULL;
- timer_t new_timer_id;
+ int new_timer_id;
struct task_struct *process = 0;
unsigned long flags;
sigevent_t event;
+ int it_id_set = IT_ID_NOT_SET;
if ((unsigned) which_clock >= MAX_CLOCKS ||
!posix_clocks[which_clock].res)
return -EAGAIN;
spin_lock_init(&new_timer->it_lock);
- do {
- if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
- error = -EAGAIN;
- new_timer->it_id = (timer_t)-1;
- goto out;
- }
- spin_lock_irq(&idr_lock);
- new_timer_id = (timer_t) idr_get_new(&posix_timers_id,
- (void *) new_timer);
- spin_unlock_irq(&idr_lock);
- } while (unlikely(new_timer_id == -1));
+ retry:
+ if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
+ error = -EAGAIN;
+ goto out;
+ }
+ spin_lock_irq(&idr_lock);
+ error = idr_get_new(&posix_timers_id,
+ (void *) new_timer,
+ &new_timer_id);
+ spin_unlock_irq(&idr_lock);
+ if (error == -EAGAIN)
+ goto retry;
+ else if (error) {
+ /*
+ * Wierd looking, but we return EAGAIN if the IDR is
+ * full (proper POSIX return value for this)
+ */
+ error = -EAGAIN;
+ goto out;
+ }
+
+ it_id_set = IT_ID_SET;
+ new_timer->it_id = (timer_t) new_timer_id;
+ new_timer->it_clock = which_clock;
+ new_timer->it_incr = 0;
+ new_timer->it_overrun = -1;
+ init_timer(&new_timer->it_timer);
+ new_timer->it_timer.expires = 0;
+ new_timer->it_timer.data = (unsigned long) new_timer;
+ new_timer->it_timer.function = posix_timer_fn;
+ set_timer_inactive(new_timer);
- new_timer->it_id = new_timer_id;
/*
* return the timer_id now. The next step is hard to
* back out if there is an error.
error = -EFAULT;
goto out;
}
+ new_timer->it_sigev_notify = event.sigev_notify;
+ new_timer->it_sigev_signo = event.sigev_signo;
+ new_timer->it_sigev_value = event.sigev_value;
+
read_lock(&tasklist_lock);
if ((process = good_sigevent(&event))) {
/*
*/
spin_lock_irqsave(&process->sighand->siglock, flags);
if (!(process->flags & PF_EXITING)) {
+ new_timer->it_process = process;
list_add(&new_timer->list,
&process->signal->posix_timers);
spin_unlock_irqrestore(&process->sighand->siglock, flags);
error = -EINVAL;
goto out;
}
- new_timer->it_sigev_notify = event.sigev_notify;
- new_timer->it_sigev_signo = event.sigev_signo;
- new_timer->it_sigev_value = event.sigev_value;
} else {
new_timer->it_sigev_notify = SIGEV_SIGNAL;
new_timer->it_sigev_signo = SIGALRM;
new_timer->it_sigev_value.sival_int = new_timer->it_id;
process = current->group_leader;
spin_lock_irqsave(&process->sighand->siglock, flags);
+ new_timer->it_process = process;
list_add(&new_timer->list, &process->signal->posix_timers);
spin_unlock_irqrestore(&process->sighand->siglock, flags);
}
- new_timer->it_clock = which_clock;
- new_timer->it_incr = 0;
- new_timer->it_overrun = -1;
- init_timer(&new_timer->it_timer);
- new_timer->it_timer.expires = 0;
- new_timer->it_timer.data = (unsigned long) new_timer;
- new_timer->it_timer.function = posix_timer_fn;
- set_timer_inactive(new_timer);
-
- /*
- * Once we set the process, it can be found so do it last...
+ /*
+ * In the case of the timer belonging to another task, after
+ * the task is unlocked, the timer is owned by the other task
+ * and may cease to exist at any time. Don't use or modify
+ * new_timer after the unlock call.
*/
- new_timer->it_process = process;
+
out:
if (error)
- release_posix_timer(new_timer);
+ release_posix_timer(new_timer, it_id_set);
return error;
}
timer->it_process = NULL;
}
unlock_timer(timer, flags);
- release_posix_timer(timer);
+ release_posix_timer(timer, IT_ID_SET);
return 0;
}
/*
timer->it_process = NULL;
}
unlock_timer(timer, flags);
- release_posix_timer(timer);
+ release_posix_timer(timer, IT_ID_SET);
}
/*
/* More restore stuff */
-/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void __init copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
-{
- int i;
- char *topointer=(char *)to, *frompointer=(char *)from;
-
- for(i=0; i < 1 << pagedir_order; i++) {
- copy_page(topointer, frompointer);
- topointer += PAGE_SIZE;
- frompointer += PAGE_SIZE;
- }
-}
-
#define does_collide(addr) does_collide_order(pm_pagedir_nosave, addr, 0)
/*
* We have to avoid recursion (not to overflow kernel stack),
* and that's why code looks pretty cryptic
*/
- suspend_pagedir_t *new_pagedir, *old_pagedir = pm_pagedir_nosave;
+ suspend_pagedir_t *old_pagedir = pm_pagedir_nosave;
void **eaten_memory = NULL;
void **c = eaten_memory, *m, *f;
+ int err;
pr_debug("pmdisk: Relocating pagedir\n");
return 0;
}
+ err = -ENOMEM;
while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
- memset(m, 0, PAGE_SIZE);
- if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
+ if (!does_collide_order(old_pagedir, (unsigned long)m,
+ pagedir_order)) {
+ pm_pagedir_nosave =
+ memcpy(m, old_pagedir,
+ PAGE_SIZE << pagedir_order);
+ err = 0;
break;
+ }
eaten_memory = m;
printk( "." );
*eaten_memory = c;
c = eaten_memory;
}
- if (!m)
- return -ENOMEM;
-
- pm_pagedir_nosave = new_pagedir = m;
- copy_pagedir(new_pagedir, old_pagedir);
-
c = eaten_memory;
while(c) {
printk(":");
- f = *c;
+ f = c;
c = *c;
- if (f)
- free_pages((unsigned long)f, pagedir_order);
+ free_pages((unsigned long)f, pagedir_order);
}
printk("|\n");
- return 0;
+ return err;
}
if (!pbe)
continue;
pbe->orig_address = (long) page_address(page);
+ /* Copy page is dangerous: it likes to mess with
+ preempt count on specific cpus. Wrong preempt count is then copied,
+ oops. */
copy_page((void *)pbe->address, (void *)pbe->orig_address);
pbe++;
}
/* More restore stuff */
-/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
-static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
-{
- int i;
- char *topointer=(char *)to, *frompointer=(char *)from;
-
- for(i=0; i < 1 << pagedir_order; i++) {
- copy_page(topointer, frompointer);
- topointer += PAGE_SIZE;
- frompointer += PAGE_SIZE;
- }
-}
-
#define does_collide(addr) does_collide_order(pagedir_nosave, addr, 0)
/*
* We have to avoid recursion (not to overflow kernel stack),
* and that's why code looks pretty cryptic
*/
- suspend_pagedir_t *new_pagedir, *old_pagedir = pagedir_nosave;
+ suspend_pagedir_t *old_pagedir = pagedir_nosave;
void **eaten_memory = NULL;
void **c = eaten_memory, *m, *f;
+ int ret = 0;
- printk("Relocating pagedir");
+ printk("Relocating pagedir ");
if(!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
printk("not necessary\n");
}
while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
- memset(m, 0, PAGE_SIZE);
if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
break;
eaten_memory = m;
c = eaten_memory;
}
- if (!m)
- return -ENOMEM;
-
- pagedir_nosave = new_pagedir = m;
- copy_pagedir(new_pagedir, old_pagedir);
+ if (!m) {
+ printk("out of memory\n");
+ ret = -ENOMEM;
+ } else {
+ pagedir_nosave =
+ memcpy(m, old_pagedir, PAGE_SIZE << pagedir_order);
+ }
c = eaten_memory;
- while(c) {
+ while (c) {
printk(":");
- f = *c;
+ f = c;
c = *c;
- if (f)
- free_pages((unsigned long)f, pagedir_order);
+ free_pages((unsigned long)f, pagedir_order);
}
printk("|\n");
- return 0;
+ return ret;
}
/*
if (next->sibling->start > new->end)
break;
- /* existing resource overlaps end of new resource */
- if (next->end > new->end) {
+ /* existing resource includes new resource */
+ if (next->end >= new->end) {
parent = next;
result = 0;
goto begin;
* task_curr - is this task currently executing on a CPU?
* @p: the task in question.
*/
-inline int task_curr(task_t *p)
+inline int task_curr(const task_t *p)
{
return cpu_curr(task_cpu(p)) == p;
}
load = source_load(cpu);
this_load = target_load(this_cpu);
+ /*
+ * If sync wakeup then subtract the (maximum possible) effect of
+ * the currently running task from the load of the current CPU:
+ */
+ if (sync)
+ this_load -= SCHED_LOAD_SCALE;
+
/* Don't pull the task off an idle CPU to a busy one */
if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2)
goto out_set_cpu;
* RT tasks are offset by -200. Normal tasks are centered
* around 0, value goes from -16 to +15.
*/
-int task_prio(task_t *p)
+int task_prio(const task_t *p)
{
return p->prio - MAX_RT_PRIO;
}
* task_nice - return the nice value of a given task.
* @p: the task in question.
*/
-int task_nice(task_t *p)
+int task_nice(const task_t *p)
{
return TASK_NICE(p);
}
sd = rq->sd;
- printk(KERN_DEBUG "CPU%d: %s\n",
+ printk(KERN_WARNING "CPU%d: %s\n",
i, (cpu_online(i) ? " online" : "offline"));
do {
printk("domain %d: span %s\n", level, str);
if (!cpu_isset(i, sd->span))
- printk(KERN_DEBUG "ERROR domain->span does not contain CPU%d\n", i);
+ printk(KERN_WARNING "ERROR domain->span does not contain CPU%d\n", i);
if (!cpu_isset(i, group->cpumask))
- printk(KERN_DEBUG "ERROR domain->groups does not contain CPU%d\n", i);
+ printk(KERN_WARNING "ERROR domain->groups does not contain CPU%d\n", i);
if (!group->cpu_power)
- printk(KERN_DEBUG "ERROR domain->cpu_power not set\n");
+ printk(KERN_WARNING "ERROR domain->cpu_power not set\n");
- printk(KERN_DEBUG);
+ printk(KERN_WARNING);
for (j = 0; j < level + 2; j++)
printk(" ");
printk("groups:");
if (sd) {
cpus_and(tmp, groupmask, sd->span);
if (!cpus_equal(tmp, groupmask))
- printk(KERN_DEBUG "ERROR parent span is not a superset of domain->span\n");
+ printk(KERN_WARNING "ERROR parent span is not a superset of domain->span\n");
}
} while (sd);
static kmem_cache_t *sigqueue_cachep;
-atomic_t nr_queued_signals;
-int max_queued_signals = 1024;
-
/*
* In POSIX a signal is sent either to a specific thread (Linux task)
* or to the process as a whole (Linux thread group). How the signal
return sig;
}
-struct sigqueue *__sigqueue_alloc(void)
+static struct sigqueue *__sigqueue_alloc(void)
{
struct sigqueue *q = 0;
- if (atomic_read(&nr_queued_signals) < max_queued_signals)
+ if (atomic_read(¤t->user->sigpending) <
+ current->rlim[RLIMIT_SIGPENDING].rlim_cur)
q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
if (q) {
- atomic_inc(&nr_queued_signals);
INIT_LIST_HEAD(&q->list);
q->flags = 0;
q->lock = 0;
+ q->user = get_uid(current->user);
+ atomic_inc(&q->user->sigpending);
}
return(q);
}
{
if (q->flags & SIGQUEUE_PREALLOC)
return;
+ atomic_dec(&q->user->sigpending);
+ free_uid(q->user);
kmem_cache_free(sigqueue_cachep, q);
- atomic_dec(&nr_queued_signals);
}
static void flush_sigqueue(struct sigpending *queue)
}
}
-static int send_signal(int sig, struct siginfo *info, struct sigpending *signals)
+static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
+ struct sigpending *signals)
{
struct sigqueue * q = NULL;
int ret = 0;
make sure at least one signal gets delivered and don't
pass on the info struct. */
- if (atomic_read(&nr_queued_signals) < max_queued_signals)
+ if (atomic_read(&t->user->sigpending) <
+ t->rlim[RLIMIT_SIGPENDING].rlim_cur)
q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
if (q) {
- atomic_inc(&nr_queued_signals);
q->flags = 0;
+ q->user = get_uid(t->user);
+ atomic_inc(&q->user->sigpending);
list_add_tail(&q->list, &signals->list);
switch ((unsigned long) info) {
case 0:
if (LEGACY_QUEUE(&t->pending, sig))
goto out;
- ret = send_signal(sig, info, &t->pending);
+ ret = send_signal(sig, info, t, &t->pending);
if (!ret && !sigismember(&t->blocked, sig))
signal_wake_up(t, sig == SIGKILL);
out:
* We always use the shared queue for process-wide signals,
* to avoid several races.
*/
- ret = send_signal(sig, info, &p->signal->shared_pending);
+ ret = send_signal(sig, info, p, &p->signal->shared_pending);
if (unlikely(ret))
return ret;
struct task_struct *p;
struct list_head *l;
struct pid *pid;
- int retval;
- int found;
+ int retval, success;
if (pgrp <= 0)
return -EINVAL;
- found = 0;
- retval = 0;
+ success = 0;
+ retval = -ESRCH;
for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) {
- int err;
-
- found = 1;
- err = group_send_sig_info(sig, info, p);
- if (!retval)
- retval = err;
+ int err = group_send_sig_info(sig, info, p);
+ success |= !err;
+ retval = err;
}
- return found ? retval : -ESRCH;
+ return success ? 0 : retval;
}
int
out:
return error;
}
+#endif /* __ARCH_WANT_SYS_SIGPROCMASK */
-#endif /* SIGPROCMASK */
-
-#ifndef __sparc__
+#ifdef __ARCH_WANT_SYS_RT_SIGACTION
asmlinkage long
sys_rt_sigaction(int sig,
const struct sigaction __user *act,
out:
return ret;
}
-#endif /* __sparc__ */
+#endif /* __ARCH_WANT_SYS_RT_SIGACTION */
#ifdef __ARCH_WANT_SYS_SGETMASK
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
extern int max_threads;
-extern atomic_t nr_queued_signals;
-extern int max_queued_signals;
extern int sysrq_enabled;
extern int core_uses_pid;
extern char core_pattern[];
.ctl_name = KERN_OSTYPE,
.procname = "ostype",
.data = system_utsname.sysname,
- .maxlen = 64,
+ .maxlen = sizeof(system_utsname.sysname),
.mode = 0444,
.proc_handler = &proc_doutsstring,
.strategy = &sysctl_string,
.ctl_name = KERN_OSRELEASE,
.procname = "osrelease",
.data = system_utsname.release,
- .maxlen = 64,
+ .maxlen = sizeof(system_utsname.release),
.mode = 0444,
.proc_handler = &proc_doutsstring,
.strategy = &sysctl_string,
.ctl_name = KERN_VERSION,
.procname = "version",
.data = system_utsname.version,
- .maxlen = 64,
+ .maxlen = sizeof(system_utsname.version),
.mode = 0444,
.proc_handler = &proc_doutsstring,
.strategy = &sysctl_string,
.ctl_name = KERN_NODENAME,
.procname = "hostname",
.data = system_utsname.nodename,
- .maxlen = 64,
+ .maxlen = sizeof(system_utsname.nodename),
.mode = 0644,
.proc_handler = &proc_doutsstring,
.strategy = &sysctl_string,
.ctl_name = KERN_DOMAINNAME,
.procname = "domainname",
.data = system_utsname.domainname,
- .maxlen = 64,
+ .maxlen = sizeof(system_utsname.domainname),
.mode = 0644,
.proc_handler = &proc_doutsstring,
.strategy = &sysctl_string,
.ctl_name = KERN_MODPROBE,
.procname = "modprobe",
.data = &modprobe_path,
- .maxlen = 256,
+ .maxlen = KMOD_PATH_LEN,
.mode = 0644,
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
.ctl_name = KERN_HOTPLUG,
.procname = "hotplug",
.data = &hotplug_path,
- .maxlen = 256,
+ .maxlen = KMOD_PATH_LEN,
.mode = 0644,
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
.proc_handler = &proc_dointvec,
},
#endif
- {
- .ctl_name = KERN_RTSIGNR,
- .procname = "rtsig-nr",
- .data = &nr_queued_signals,
- .maxlen = sizeof(int),
- .mode = 0444,
- .proc_handler = &proc_dointvec,
- },
- {
- .ctl_name = KERN_RTSIGMAX,
- .procname = "rtsig-max",
- .data = &max_queued_signals,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
#ifdef CONFIG_SYSVIPC
{
.ctl_name = KERN_SHMMAX,
#else /* CONFIG_PROC_FS */
int proc_dostring(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_dointvec(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
}
int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
return -ENOSYS;
}
}
}
-void update_one_process(struct task_struct *p, unsigned long user,
+static void update_one_process(struct task_struct *p, unsigned long user,
unsigned long system, int cpu)
{
do_process_times(p, user, system);
asmlinkage long sys_setgid16(old_gid_t gid)
{
- return sys_setgid((gid_t)gid);
+ return sys_setgid(low2highgid(gid));
}
asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
asmlinkage long sys_setuid16(old_uid_t uid)
{
- return sys_setuid((uid_t)uid);
+ return sys_setuid(low2highuid(uid));
}
asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
asmlinkage long sys_setfsuid16(old_uid_t uid)
{
- return sys_setfsuid((uid_t)uid);
+ return sys_setfsuid(low2highuid(uid));
}
asmlinkage long sys_setfsgid16(old_gid_t gid)
{
- return sys_setfsgid((gid_t)gid);
+ return sys_setfsgid(low2highgid(gid));
}
static int groups16_to_user(old_gid_t __user *grouplist,
old_gid_t group;
for (i = 0; i < group_info->ngroups; i++) {
- group = (old_gid_t)GROUP_AT(group_info, i);
+ group = high2lowgid(GROUP_AT(group_info, i));
if (put_user(group, grouplist+i))
return -EFAULT;
}
for (i = 0; i < group_info->ngroups; i++) {
if (get_user(group, grouplist+i))
return -EFAULT;
- GROUP_AT(group_info, i) = (gid_t)group;
+ GROUP_AT(group_info, i) = low2highgid(group);
}
return 0;
struct user_struct root_user = {
.__count = ATOMIC_INIT(1),
.processes = ATOMIC_INIT(1),
- .files = ATOMIC_INIT(0)
+ .files = ATOMIC_INIT(0),
+ .sigpending = ATOMIC_INIT(0),
+ .mq_bytes = 0
};
/*
atomic_set(&new->__count, 1);
atomic_set(&new->processes, 0);
atomic_set(&new->files, 0);
+ atomic_set(&new->sigpending, 0);
+
+ new->mq_bytes = 0;
/*
* Before adding this, check whether we raced
return 0;
}
+static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
+{
+ if (cwq->thread == current) {
+ /*
+ * Probably keventd trying to flush its own queue. So simply run
+ * it by hand rather than deadlocking.
+ */
+ run_workqueue(cwq);
+ } else {
+ DEFINE_WAIT(wait);
+ long sequence_needed;
+
+ spin_lock_irq(&cwq->lock);
+ sequence_needed = cwq->insert_sequence;
+
+ while (sequence_needed - cwq->remove_sequence > 0) {
+ prepare_to_wait(&cwq->work_done, &wait,
+ TASK_UNINTERRUPTIBLE);
+ spin_unlock_irq(&cwq->lock);
+ schedule();
+ spin_lock_irq(&cwq->lock);
+ }
+ finish_wait(&cwq->work_done, &wait);
+ spin_unlock_irq(&cwq->lock);
+ }
+}
+
/*
* flush_workqueue - ensure that any scheduled work has run to completion.
*
*/
void fastcall flush_workqueue(struct workqueue_struct *wq)
{
- struct cpu_workqueue_struct *cwq;
- int cpu;
-
might_sleep();
- lock_cpu_hotplug();
- for_each_online_cpu(cpu) {
- DEFINE_WAIT(wait);
- long sequence_needed;
-
- if (is_single_threaded(wq))
- cwq = wq->cpu_wq + 0; /* Always use cpu 0's area. */
- else
- cwq = wq->cpu_wq + cpu;
-
- if (cwq->thread == current) {
- /*
- * Probably keventd trying to flush its own queue.
- * So simply run it by hand rather than deadlocking.
- */
- run_workqueue(cwq);
- continue;
- }
- spin_lock_irq(&cwq->lock);
- sequence_needed = cwq->insert_sequence;
+ if (is_single_threaded(wq)) {
+ /* Always use cpu 0's area. */
+ flush_cpu_workqueue(wq->cpu_wq + 0);
+ } else {
+ int cpu;
- while (sequence_needed - cwq->remove_sequence > 0) {
- prepare_to_wait(&cwq->work_done, &wait,
- TASK_UNINTERRUPTIBLE);
- spin_unlock_irq(&cwq->lock);
- schedule();
- spin_lock_irq(&cwq->lock);
- }
- finish_wait(&cwq->work_done, &wait);
- spin_unlock_irq(&cwq->lock);
+ lock_cpu_hotplug();
+ for_each_online_cpu(cpu)
+ flush_cpu_workqueue(wq->cpu_wq + cpu);
+ unlock_cpu_hotplug();
}
- unlock_cpu_hotplug();
}
static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
* so you don't need to be too concerned about locking and conflicts
* with the slab allocator.
- * A word on reuse. We reuse empty id slots as soon as we can, always
- * using the lowest one available. But we also merge a counter in the
- * high bits of the id. The counter is RESERVED_ID_BITS (8 at this time)
- * long. This means that if you allocate and release the same id in a
- * loop we will reuse an id after about 256 times around the loop. The
- * word about is used here as we will NOT return a valid id of -1 so if
- * you loop on the largest possible id (and that is 24 bits, wow!) we
- * will kick the counter to avoid -1. (Paranoid? You bet!)
- *
* What you need to do is, since we don't keep the counter as part of
* id / ptr pair, to keep a copy of it in the pointed to structure
* (or else where) so that when you ask for a ptr you can varify that
* sleep, so must not be called with any spinlocks held. If the system is
* REALLY out of memory this function returns 0, other wise 1.
- * int idr_get_new(struct idr *idp, void *ptr);
+ * int idr_get_new(struct idr *idp, void *ptr, int *id);
* This is the allocate id function. It should be called with any
* required locks. In fact, in the SMP case, you MUST lock prior to
- * calling this function to avoid possible out of memory problems. If
- * memory is required, it will return a -1, in which case you should
- * unlock and go back to the idr_pre_get() call. ptr is the pointer
- * you want associated with the id. In other words:
+ * calling this function to avoid possible out of memory problems.
+ * If memory is required, it will return -EAGAIN, you should unlock
+ * and go back to the idr_pre_get() call. If the idr is full, it
+ * will return a -ENOSPC. ptr is the pointer you want associated
+ * with the id. The value is returned in the "id" field. idr_get_new()
+ * returns a value in the range 0 ... 0x7fffffff
+
+ * int idr_get_new_above(struct idr *idp, void *ptr, int start_id, int *id);
+
+ * Like idr_get_new(), but the returned id is guaranteed to be at or
+ * above start_id.
* void *idr_find(struct idr *idp, int id);
* removes the given id, freeing that slot and any memory that may
* now be unused. See idr_find() for locking restrictions.
+ * int idr_full(struct idr *idp);
+
+ * Returns true if the idr is full and false if not.
+
*/
spin_lock(&idp->lock);
if (!(p = idp->id_free))
- BUG();
+ return NULL;
idp->id_free = p->ary[0];
idp->id_free_cnt--;
p->ary[0] = 0;
sh = IDR_BITS*l;
id = ((id >> sh) ^ n ^ m) << sh;
}
- if (id >= MAX_ID_BIT)
- return -1;
+ if ((id >= MAX_ID_BIT) || (id < 0))
+ return -3;
if (l == 0)
break;
/*
return(id);
}
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id)
+static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
{
struct idr_layer *p, *new;
int layers, v, id;
* Add a new layer to the top of the tree if the requested
* id is larger than the currently allocated space.
*/
- while (id >= (1 << (layers*IDR_BITS))) {
+ while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
layers++;
if (!p->count)
continue;
v = sub_alloc(idp, ptr, &id);
if (v == -2)
goto build_up;
- if ( likely(v >= 0 )) {
- idp->count++;
- v += (idp->count << MAX_ID_SHIFT);
- if ( unlikely( v == -1 ))
- v += (1L << MAX_ID_SHIFT);
- }
return(v);
}
+
+int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+{
+ int rv;
+ rv = idr_get_new_above_int(idp, ptr, starting_id);
+ /*
+ * This is a cheap hack until the IDR code can be fixed to
+ * return proper error values.
+ */
+ if (rv < 0) {
+ if (rv == -1)
+ return -EAGAIN;
+ else /* Will be -3 */
+ return -ENOSPC;
+ }
+ *id = rv;
+ return 0;
+}
EXPORT_SYMBOL(idr_get_new_above);
-int idr_get_new(struct idr *idp, void *ptr)
+int idr_get_new(struct idr *idp, void *ptr, int *id)
{
- return idr_get_new_above(idp, ptr, 0);
+ int rv;
+ rv = idr_get_new_above_int(idp, ptr, 0);
+ /*
+ * This is a cheap hack until the IDR code can be fixed to
+ * return proper error values.
+ */
+ if (rv < 0) {
+ if (rv == -1)
+ return -EAGAIN;
+ else /* Will be -3 */
+ return -ENOSPC;
+ }
+ *id = rv;
+ return 0;
}
EXPORT_SYMBOL(idr_get_new);
-
static void sub_remove(struct idr *idp, int shift, int id)
{
struct idr_layer *p = idp->top;
idp->layers = 0;
}
}
+
void idr_remove(struct idr *idp, int id)
{
struct idr_layer *p;
+ /* Mask off upper bits we don't use for the search. */
+ id &= MAX_ID_MASK;
+
sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
if ( idp->top && idp->top->count == 1 &&
(idp->layers > 1) &&
if ( unlikely( (id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS)))
return NULL;
#endif
+ /* Mask off upper bits we don't use for the search. */
+ id &= MAX_ID_MASK;
+
while (n > 0 && p) {
n -= IDR_BITS;
p = p->ary[(id >> n) & IDR_MASK];
/*
* handle the lock being released whilst there are processes blocked on it that can now run
- * - if we come here, then:
- * - the 'active part' of the count (&0x0000ffff) reached zero but has been re-incremented
+ * - if we come here from up_xxxx(), then:
+ * - the 'active part' of the count (&0x0000ffff) had reached zero (but may have changed)
* - the 'waiting part' of the count (&0xffff0000) is negative (and will still be so)
* - there must be someone on the queue
* - the spinlock must be held by the caller
* - woken process blocks are discarded from the list after having task zeroed
- * - writers are only woken if wakewrite is non-zero
+ * - writers are only woken if downgrading is false
*/
-static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int wakewrite)
+static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
{
struct rwsem_waiter *waiter;
struct task_struct *tsk;
rwsemtrace(sem,"Entering __rwsem_do_wake");
- if (!wakewrite)
+ if (downgrading)
goto dont_wake_writers;
- /* only wake someone up if we can transition the active part of the count from 0 -> 1 */
+ /* if we came through an up_xxxx() call, we only only wake someone up
+ * if we can transition the active part of the count from 0 -> 1
+ */
try_again:
oldcount = rwsem_atomic_update(RWSEM_ACTIVE_BIAS,sem) - RWSEM_ACTIVE_BIAS;
if (oldcount & RWSEM_ACTIVE_MASK)
if (waiter->flags & RWSEM_WAITING_FOR_WRITE)
goto out;
- /* grant an infinite number of read locks to the readers at the front of the queue
- * - note we increment the 'active part' of the count by the number of readers (less one
- * for the activity decrement we've already done) before waking any processes up
+ /* grant an infinite number of read locks to the readers at the front
+ * of the queue
+ * - note we increment the 'active part' of the count by the number of
+ * readers before waking any processes up
*/
readers_only:
woken = 0;
} while (waiter->flags & RWSEM_WAITING_FOR_READ);
loop = woken;
- woken *= RWSEM_ACTIVE_BIAS-RWSEM_WAITING_BIAS;
- woken -= RWSEM_ACTIVE_BIAS;
+ woken *= RWSEM_ACTIVE_BIAS - RWSEM_WAITING_BIAS;
+ if (!downgrading)
+ woken -= RWSEM_ACTIVE_BIAS; /* we'd already done one increment
+ * earlier */
rwsem_atomic_add(woken,sem);
next = sem->wait_list.next;
* - it might even be this process, since the waker takes a more active part
*/
if (!(count & RWSEM_ACTIVE_MASK))
- sem = __rwsem_do_wake(sem,1);
+ sem = __rwsem_do_wake(sem, 0);
spin_unlock(&sem->wait_lock);
/*
* handle waking up a waiter on the semaphore
- * - up_read has decremented the active part of the count if we come here
+ * - up_read/up_write has decremented the active part of the count if we come here
*/
struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem)
{
/* do nothing if list empty */
if (!list_empty(&sem->wait_list))
- sem = __rwsem_do_wake(sem,1);
+ sem = __rwsem_do_wake(sem, 0);
spin_unlock(&sem->wait_lock);
/* do nothing if list empty */
if (!list_empty(&sem->wait_list))
- sem = __rwsem_do_wake(sem,0);
+ sem = __rwsem_do_wake(sem, 1);
spin_unlock(&sem->wait_lock);
if (count) {
while (*dest)
dest++;
- while ((*dest++ = *src++)) {
+ while ((*dest++ = *src++) != 0) {
if (--count == 0) {
*dest = '\0';
break;
if (*cp == '0') {
base = 8;
cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
+ if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
cp++;
base = 16;
}
}
+ } else if (base == 16) {
+ if (cp[0] == '0' && toupper(cp[1]) == 'X')
+ cp += 2;
}
while (isxdigit(*cp) &&
(value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
if (*cp == '0') {
base = 8;
cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
+ if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
cp++;
base = 16;
}
}
+ } else if (base == 16) {
+ if (cp[0] == '0' && toupper(cp[1]) == 'X')
+ cp += 2;
}
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
? toupper(*cp) : *cp)-'A'+10) < base) {
int nonblock)
{
struct inode *inode = mapping->host;
- unsigned long index, offset;
+ unsigned long index, end_index, offset;
+ loff_t isize;
struct page *cached_page;
int error;
struct file_ra_state ra = *_ra;
index = *ppos >> PAGE_CACHE_SHIFT;
offset = *ppos & ~PAGE_CACHE_MASK;
+ isize = i_size_read(inode);
+ end_index = isize >> PAGE_CACHE_SHIFT;
+ if (index > end_index)
+ goto out;
+
for (;;) {
struct page *page;
- unsigned long end_index, nr, ret;
- loff_t isize = i_size_read(inode);
-
- end_index = isize >> PAGE_CACHE_SHIFT;
-
- if (index > end_index)
- break;
- nr = PAGE_CACHE_SIZE;
- if (index == end_index) {
- nr = isize & ~PAGE_CACHE_MASK;
- if (nr <= offset)
- break;
- }
+ unsigned long nr, ret;
cond_resched();
page_cache_readahead(mapping, &ra, filp, index);
- nr = nr - offset;
find_page:
page = find_get_page(mapping, index);
if (unlikely(page == NULL)) {
goto page_not_up_to_date;
}
page_ok:
+ /* nr is the maximum number of bytes to copy from this page */
+ nr = PAGE_CACHE_SIZE;
+ if (index == end_index) {
+ nr = isize & ~PAGE_CACHE_MASK;
+ if (nr <= offset) {
+ page_cache_release(page);
+ goto out;
+ }
+ }
+ nr = nr - offset;
+
/* If users can be writing to this page using arbitrary
* virtual addresses, take care about potential aliasing
* before reading the page on the kernel side.
page_cache_release(page);
if (ret == nr && desc->count)
continue;
- break;
+ goto out;
page_not_up_to_date:
/* Get exclusive access to the page ... */
}
readpage:
- /* ... and start the actual read. The read will unlock the page. */
+ /* Start the actual read. The read will unlock the page. */
error = mapping->a_ops->readpage(filp, page);
- if (!error) {
- if (PageUptodate(page))
- goto page_ok;
+ if (unlikely(error))
+ goto readpage_error;
+
+ if (!PageUptodate(page)) {
wait_on_page_locked(page);
- if (PageUptodate(page))
- goto page_ok;
- error = -EIO;
+ if (!PageUptodate(page)) {
+ error = -EIO;
+ goto readpage_error;
+ }
}
+ /*
+ * i_size must be checked after we have done ->readpage.
+ *
+ * Checking i_size after the readpage allows us to calculate
+ * the correct value for "nr", which means the zero-filled
+ * part of the page is not copied back to userspace (unless
+ * another truncate extends the file - this is desired though).
+ */
+ isize = i_size_read(inode);
+ end_index = isize >> PAGE_CACHE_SHIFT;
+ if (index > end_index) {
+ page_cache_release(page);
+ goto out;
+ }
+ goto page_ok;
+
+readpage_error:
/* UHHUH! A synchronous read error occurred. Report it */
desc->error = error;
page_cache_release(page);
- break;
+ goto out;
no_cached_page:
/*
cached_page = page_cache_alloc_cold(mapping);
if (!cached_page) {
desc->error = -ENOMEM;
- break;
+ goto out;
}
}
error = add_to_page_cache_lru(cached_page, mapping,
if (error == -EEXIST)
goto find_page;
desc->error = error;
- break;
+ goto out;
}
page = cached_page;
cached_page = NULL;
goto readpage;
}
+out:
*_ra = ra;
*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
count -= written;
}
- buf = iov->iov_base;
+ buf = iov->iov_base + written; /* handle partial DIO write */
do {
unsigned long index;
unsigned long offset;
unsigned long end = start + size;
struct vm_area_struct *vma;
int err = -EINVAL;
+ int has_write_lock = 0;
if (__prot)
return err;
#endif
/* We need down_write() to change vma->vm_flags. */
- down_write(&mm->mmap_sem);
+ down_read(&mm->mmap_sem);
+ retry:
vma = find_vma(mm, start);
/*
/* Must set VM_NONLINEAR before any pages are populated. */
if (pgoff != linear_page_index(vma, start) &&
!(vma->vm_flags & VM_NONLINEAR)) {
+ if (!has_write_lock) {
+ up_read(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
+ has_write_lock = 1;
+ goto retry;
+ }
mapping = vma->vm_file->f_mapping;
spin_lock(&mapping->i_mmap_lock);
flush_dcache_mmap_lock(mapping);
spin_unlock(&mapping->i_mmap_lock);
}
- /* ->populate can take a long time, so downgrade the lock. */
- downgrade_write(&mm->mmap_sem);
err = vma->vm_ops->populate(vma, start, size,
vma->vm_page_prot,
pgoff, flags & MAP_NONBLOCK);
* it after ->populate completes, and that would prevent
* downgrading the lock. (Locks can't be upgraded).
*/
+ }
+ if (likely(!has_write_lock))
up_read(&mm->mmap_sem);
- } else {
+ else
up_write(&mm->mmap_sem);
- }
return err;
}
#include <linux/init.h>
#include <linux/hash.h>
#include <linux/highmem.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
static mempool_t *page_pool, *isa_page_pool;
BUG_ON(page_count(page));
INIT_LIST_HEAD(&page->lru);
+ page[1].mapping = NULL;
spin_lock(&hugetlb_lock);
enqueue_huge_page(page);
#ifdef CONFIG_SYSCTL
int hugetlb_sysctl_handler(struct ctl_table *table, int write,
- struct file *file, void *buffer, size_t *length)
+ struct file *file, void __user *buffer,
+ size_t *length)
{
proc_doulongvec_minmax(table, write, file, buffer, length);
max_huge_pages = set_max_huge_pages(max_huge_pages);
if (pte_present(pte)) {
if (write && !pte_write(pte))
goto out;
- if (write && !pte_dirty(pte)) {
- struct page *page = pte_page(pte);
- if (!PageDirty(page))
- set_page_dirty(page);
- }
pfn = pte_pfn(pte);
if (pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
-
+ page = pfn_to_page(pfn);
+ if (write && !pte_dirty(pte) && !PageDirty(page))
+ set_page_dirty(page);
mark_page_accessed(page);
return page;
}
}
+#ifndef CONFIG_X86_4G
static inline int
untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
unsigned long address)
/* There is a pte slot for 'address' in 'mm'. */
return 0;
}
+#endif
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
* insanly big anonymously mapped areas that
* nobody touched so far. This is important
* for doing a core dump for these mappings.
+ *
+ * disable this for 4:4 - it prevents
+ * follow_page() from ever seeing these pages.
+ *
+ * (The 'fix' is dubious anyway, there's
+ * nothing that this code avoids which couldnt
+ * be triggered from userspace anyway.)
*/
+#ifndef CONFIG_X86_4G
if (!lookup_write &&
untouched_anonymous_page(mm,vma,start)) {
map = ZERO_PAGE(start);
break;
}
+#endif
spin_unlock(&mm->page_table_lock);
switch (handle_mm_fault(mm,vma,start,write)) {
case VM_FAULT_MINOR:
#include <linux/mempolicy.h>
#include <linux/mm.h>
+#include <linux/highmem.h>
#include <linux/hugetlb.h>
#include <linux/kernel.h>
#include <linux/sched.h>
up(&p->sem);
}
-static __init int numa_policy_init(void)
+/* assumes fs == KERNEL_DS */
+void __init numa_policy_init(void)
{
policy_cache = kmem_cache_create("numa_policy",
sizeof(struct mempolicy),
sn_cache = kmem_cache_create("shared_policy_node",
sizeof(struct sp_node),
0, SLAB_PANIC, NULL, NULL);
- return 0;
+
+ /* Set interleaving policy for system init. This way not all
+ the data structures allocated at system boot end up in node zero. */
+
+ if (sys_set_mempolicy(MPOL_INTERLEAVE, node_online_map, MAX_NUMNODES) < 0)
+ printk("numa_policy_init: interleaving failed\n");
+}
+
+/* Reset policy of current process to default.
+ * Assumes fs == KERNEL_DS */
+void numa_default_policy(void)
+{
+ sys_set_mempolicy(MPOL_DEFAULT, NULL, 0);
}
-module_init(numa_policy_init);
}
EXPORT_SYMBOL(mempool_create);
-/*
- * mempool_resize is disabled for now, because it has no callers. Feel free
- * to turn it back on if needed.
- */
-#if 0
/**
* mempool_resize - resize an existing memory pool
* @pool: pointer to the memory pool which was allocated via
return 0;
}
EXPORT_SYMBOL(mempool_resize);
-#endif
/**
* mempool_destroy - deallocate a memory pool
#include <asm/uaccess.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
/*
* Later we can get more picky about what "in core" means precisely.
struct vm_area_struct * vma, * next;
int error;
- if (on && !can_do_mlock())
+ if (on && !capable(CAP_IPC_LOCK))
return -EPERM;
len = PAGE_ALIGN(len);
end = start + len;
lock_limit >>= PAGE_SHIFT;
/* check against resource limits */
- if ( (locked <= lock_limit) || capable(CAP_IPC_LOCK))
+ if (locked <= lock_limit)
error = do_mlock(start, len, 1);
up_write(¤t->mm->mmap_sem);
return error;
unsigned int def_flags;
struct vm_area_struct * vma;
- if (!can_do_mlock())
+ if (!capable(CAP_IPC_LOCK))
return -EPERM;
def_flags = 0;
lock_limit >>= PAGE_SHIFT;
ret = -ENOMEM;
- if ((current->mm->total_vm <= lock_limit) || capable(CAP_IPC_LOCK))
+ if (current->mm->total_vm <= lock_limit)
ret = do_mlockall(flags);
out:
up_write(¤t->mm->mmap_sem);
#include <linux/rmap.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#include <asm/tlb.h>
struct vm_area_struct *prev, struct rb_node **rb_link,
struct rb_node *rb_parent)
{
- vma_prio_tree_init(vma);
__vma_link_list(mm, vma, prev, rb_parent);
__vma_link_rb(mm, vma, rb_link, rb_parent);
- __vma_link_file(vma);
__anon_vma_link(vma);
}
if (mapping)
spin_lock(&mapping->i_mmap_lock);
anon_vma_lock(vma);
+
__vma_link(mm, vma, prev, rb_link, rb_parent);
+ __vma_link_file(vma);
+
anon_vma_unlock(vma);
if (mapping)
spin_unlock(&mapping->i_mmap_lock);
}
/*
- * Insert vm structure into process list sorted by address and into the
- * inode's i_mmap tree. The caller should hold mm->mmap_sem and
- * ->f_mappping->i_mmap_lock if vm_file is non-NULL.
+ * Helper for vma_adjust in the split_vma insert case:
+ * insert vm structure into list and rbtree and anon_vma,
+ * but it has already been inserted into prio_tree earlier.
*/
static void
__insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
if (__vma && __vma->vm_start < vma->vm_end)
BUG();
__vma_link(mm, vma, prev, rb_link, rb_parent);
- mark_mm_hugetlb(mm, vma);
mm->map_count++;
- validate_mm(mm);
}
static inline void
if (next && !insert) {
if (end >= next->vm_end) {
+ /*
+ * vma expands, overlapping all the next, and
+ * perhaps the one after too (mprotect case 6).
+ */
again: remove_next = 1 + (end > next->vm_end);
end = next->vm_end;
anon_vma = next->anon_vma;
- } else if (end < vma->vm_end || end > next->vm_start) {
+ } else if (end > next->vm_start) {
/*
- * vma shrinks, and !insert tells it's not
- * split_vma inserting another: so it must
- * be mprotect shifting the boundary down.
- * Or:
* vma expands, overlapping part of the next:
- * must be mprotect shifting the boundary up.
+ * mprotect case 5 shifting the boundary up.
+ */
+ adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
+ anon_vma = next->anon_vma;
+ } else if (end < vma->vm_end) {
+ /*
+ * vma shrinks, and !insert tells it's not
+ * split_vma inserting another: so it must be
+ * mprotect case 4 shifting the boundary down.
*/
- BUG_ON(vma->vm_end != next->vm_start);
- adjust_next = end - next->vm_start;
+ adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
anon_vma = next->anon_vma;
}
}
if (!(vma->vm_flags & VM_NONLINEAR))
root = &mapping->i_mmap;
spin_lock(&mapping->i_mmap_lock);
+ if (insert) {
+ /*
+ * Put into prio_tree now, so instantiated pages
+ * are visible to arm/parisc __flush_dcache_page
+ * throughout; but we cannot insert into address
+ * space until vma start or end is updated.
+ */
+ __vma_link_file(insert);
+ }
}
/*
vma->vm_end = end;
vma->vm_pgoff = pgoff;
if (adjust_next) {
- next->vm_start += adjust_next;
- next->vm_pgoff += adjust_next >> PAGE_SHIFT;
+ next->vm_start += adjust_next << PAGE_SHIFT;
+ next->vm_pgoff += adjust_next;
}
if (root) {
mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
if (flags & MAP_LOCKED) {
- if (!can_do_mlock())
+ if (!capable(CAP_IPC_LOCK))
return -EPERM;
vm_flags |= VM_LOCKED;
}
/* mlock MCL_FUTURE? */
if (vm_flags & VM_LOCKED) {
- unsigned long locked, lock_limit;
- locked = mm->locked_vm << PAGE_SHIFT;
- lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ unsigned long locked = mm->locked_vm << PAGE_SHIFT;
locked += len;
- if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
return -EAGAIN;
}
/* most fields are the same, copy all, and then fixup */
*new = *vma;
+ vma_prio_tree_init(new);
if (new_below)
new->vm_end = addr;
* mlock MCL_FUTURE?
*/
if (mm->def_flags & VM_LOCKED) {
- unsigned long locked, lock_limit;
- locked = mm->locked_vm << PAGE_SHIFT;
- lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ unsigned long locked = mm->locked_vm << PAGE_SHIFT;
locked += len;
- if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
return -EAGAIN;
}
new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (new_vma) {
*new_vma = *vma;
+ vma_prio_tree_init(new_vma);
pol = mpol_copy(vma_policy(vma));
if (IS_ERR(pol)) {
kmem_cache_free(vm_area_cachep, new_vma);
#include <linux/mempolicy.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#include <linux/security.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
goto out;
}
if (vma->vm_flags & VM_LOCKED) {
- unsigned long locked, lock_limit;
- locked = current->mm->locked_vm << PAGE_SHIFT;
- lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
locked += new_len - old_len;
ret = -EAGAIN;
- if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
goto out;
}
ret = -ENOMEM;
#include <linux/pagemap.h>
#include <linux/mm.h>
#include <linux/mman.h>
+#include <linux/hugetlb.h>
#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
/*
dir = pgd_offset(vma->vm_mm, address);
flush_cache_range(vma, address, end);
+
+ /* For hugepages we can't go walking the page table normally,
+ * but that's ok, hugetlbfs is memory based, so we don't need
+ * to do anything more on an msync() */
+ if (is_vm_hugetlb_page(vma))
+ goto out;
+
if (address >= end)
BUG();
do {
* dirty bits.
*/
flush_tlb_range(vma, end - size, end);
-
+ out:
spin_unlock(&vma->vm_mm->page_table_lock);
return error;
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
-#include <asm/pgalloc.h>
#include <asm/uaccess.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
* If it's been a long time since last failure,
* we're not oom.
*/
- last = now;
if (since > 5*HZ)
goto reset;
static void background_writeout(unsigned long _min_pages);
+struct writeback_state
+{
+ unsigned long nr_dirty;
+ unsigned long nr_unstable;
+ unsigned long nr_mapped;
+ unsigned long nr_writeback;
+};
+
+static void get_writeback_state(struct writeback_state *wbs)
+{
+ wbs->nr_dirty = read_page_state(nr_dirty);
+ wbs->nr_unstable = read_page_state(nr_unstable);
+ wbs->nr_mapped = read_page_state(nr_mapped);
+ wbs->nr_writeback = read_page_state(nr_writeback);
+}
+
/*
* Work out the current dirty-memory clamping and background writeout
* thresholds.
* clamping level.
*/
static void
-get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty)
+get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty)
{
int background_ratio; /* Percentages */
int dirty_ratio;
long dirty;
struct task_struct *tsk;
- get_page_state(ps);
+ get_writeback_state(wbs);
- unmapped_ratio = 100 - (ps->nr_mapped * 100) / total_pages;
+ unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages;
dirty_ratio = vm_dirty_ratio;
if (dirty_ratio > unmapped_ratio / 2)
*/
static void balance_dirty_pages(struct address_space *mapping)
{
- struct page_state ps;
+ struct writeback_state wbs;
long nr_reclaimable;
long background_thresh;
long dirty_thresh;
.nr_to_write = write_chunk,
};
- get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
- nr_reclaimable = ps.nr_dirty + ps.nr_unstable;
- if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+ get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+ nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
+ if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
break;
dirty_exceeded = 1;
*/
if (nr_reclaimable) {
writeback_inodes(&wbc);
- get_dirty_limits(&ps, &background_thresh,
+ get_dirty_limits(&wbs, &background_thresh,
&dirty_thresh);
- nr_reclaimable = ps.nr_dirty + ps.nr_unstable;
- if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+ nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
+ if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
break;
pages_written += write_chunk - wbc.nr_to_write;
if (pages_written >= write_chunk)
blk_congestion_wait(WRITE, HZ/10);
}
- if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+ if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
dirty_exceeded = 0;
if (writeback_in_progress(bdi))
* which was newly dirtied. The function will periodically check the system's
* dirty state and will initiate writeback if needed.
*
- * On really big machines, get_page_state is expensive, so try to avoid calling
- * it too often (ratelimiting). But once we're over the dirty memory limit we
- * decrease the ratelimiting by a lot, to prevent individual processes from
- * overshooting the limit by (ratelimit_pages) each.
+ * On really big machines, get_writeback_state is expensive, so try to avoid
+ * calling it too often (ratelimiting). But once we're over the dirty memory
+ * limit we decrease the ratelimiting by a lot, to prevent individual processes
+ * from overshooting the limit by (ratelimit_pages) each.
*/
void balance_dirty_pages_ratelimited(struct address_space *mapping)
{
};
for ( ; ; ) {
- struct page_state ps;
+ struct writeback_state wbs;
long background_thresh;
long dirty_thresh;
- get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
- if (ps.nr_dirty + ps.nr_unstable < background_thresh
+ get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+ if (wbs.nr_dirty + wbs.nr_unstable < background_thresh
&& min_pages <= 0)
break;
wbc.encountered_congestion = 0;
int wakeup_bdflush(long nr_pages)
{
if (nr_pages == 0) {
- struct page_state ps;
+ struct writeback_state wbs;
- get_page_state(&ps);
- nr_pages = ps.nr_dirty + ps.nr_unstable;
+ get_writeback_state(&wbs);
+ nr_pages = wbs.nr_dirty + wbs.nr_unstable;
}
return pdflush_operation(background_writeout, nr_pages);
}
unsigned long start_jif;
unsigned long next_jif;
long nr_to_write;
- struct page_state ps;
+ struct writeback_state wbs;
struct writeback_control wbc = {
.bdi = NULL,
.sync_mode = WB_SYNC_NONE,
sync_supers();
- get_page_state(&ps);
+ get_writeback_state(&wbs);
oldest_jif = jiffies - (dirty_expire_centisecs * HZ) / 100;
start_jif = jiffies;
next_jif = start_jif + (dirty_writeback_centisecs * HZ) / 100;
- nr_to_write = ps.nr_dirty + ps.nr_unstable +
+ nr_to_write = wbs.nr_dirty + wbs.nr_unstable +
(inodes_stat.nr_inodes - inodes_stat.nr_unused);
while (nr_to_write > 0) {
wbc.encountered_congestion = 0;
/*
* If ratelimit_pages is too high then we can get into dirty-data overload
* if a large number of processes all perform writes at the same time.
- * If it is too low then SMP machines will call the (expensive) get_page_state
- * too often.
+ * If it is too low then SMP machines will call the (expensive)
+ * get_writeback_state too often.
*
* Here we set ratelimit_pages to a level which ensures that when all CPUs are
* dirtying in parallel, we cannot go more than 3% (1/32) over the dirty memory
EXPORT_SYMBOL(__alloc_pages);
-#ifdef CONFIG_NUMA
-/* Early boot: Everything is done by one cpu, but the data structures will be
- * used by all cpus - spread them on all nodes.
- */
-static __init unsigned long get_boot_pages(unsigned int gfp_mask, unsigned int order)
-{
-static int nodenr;
- int i = nodenr;
- struct page *page;
-
- for (;;) {
- if (i > nodenr + numnodes)
- return 0;
- if (node_present_pages(i%numnodes)) {
- struct zone **z;
- /* The node contains memory. Check that there is
- * memory in the intended zonelist.
- */
- z = NODE_DATA(i%numnodes)->node_zonelists[gfp_mask & GFP_ZONEMASK].zones;
- while (*z) {
- if ( (*z)->free_pages > (1UL<<order))
- goto found_node;
- z++;
- }
- }
- i++;
- }
-found_node:
- nodenr = i+1;
- page = alloc_pages_node(i%numnodes, gfp_mask, order);
- if (!page)
- return 0;
- return (unsigned long) page_address(page);
-}
-#endif
-
/*
* Common helper functions.
*/
fastcall unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
{
struct page * page;
-
-#ifdef CONFIG_NUMA
- if (unlikely(system_state == SYSTEM_BOOTING))
- return get_boot_pages(gfp_mask, order);
-#endif
page = alloc_pages(gfp_mask, order);
if (!page)
return 0;
__get_page_state(ret, sizeof(*ret) / sizeof(unsigned long));
}
+unsigned long __read_page_state(unsigned offset)
+{
+ unsigned long ret = 0;
+ int cpu;
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ unsigned long in;
+
+ if (!cpu_possible(cpu))
+ continue;
+
+ in = (unsigned long)&per_cpu(page_states, cpu) + offset;
+ ret += *((unsigned long *)in);
+ }
+ return ret;
+}
+
void get_zone_counts(unsigned long *active,
unsigned long *inactive, unsigned long *free)
{
* repeatedly from either page_referenced_anon or page_referenced_file.
*/
static int page_referenced_one(struct page *page,
- struct vm_area_struct *vma, unsigned int *mapcount, int *failed)
+ struct vm_area_struct *vma, unsigned int *mapcount)
{
struct mm_struct *mm = vma->vm_mm;
unsigned long address;
if (address == -EFAULT)
goto out;
- if (!spin_trylock(&mm->page_table_lock)) {
- /*
- * For debug we're currently warning if not all found,
- * but in this case that's expected: suppress warning.
- */
- (*failed)++;
+ if (!spin_trylock(&mm->page_table_lock))
goto out;
- }
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
if (page_to_pfn(page) != pte_pfn(*pte))
goto out_unmap;
- if (ptep_test_and_clear_young(pte))
+ if (ptep_clear_flush_young(vma, address, pte))
referenced++;
(*mapcount)--;
struct anon_vma *anon_vma = (struct anon_vma *) page->mapping;
struct vm_area_struct *vma;
int referenced = 0;
- int failed = 0;
spin_lock(&anon_vma->lock);
BUG_ON(list_empty(&anon_vma->head));
list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
- referenced += page_referenced_one(page, vma,
- &mapcount, &failed);
+ referenced += page_referenced_one(page, vma, &mapcount);
if (!mapcount)
- goto out;
+ break;
}
- WARN_ON(!failed);
-out:
spin_unlock(&anon_vma->lock);
return referenced;
}
struct vm_area_struct *vma = NULL;
struct prio_tree_iter iter;
int referenced = 0;
- int failed = 0;
if (!spin_trylock(&mapping->i_mmap_lock))
return 0;
if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE))
== (VM_LOCKED|VM_MAYSHARE)) {
referenced++;
- goto out;
+ break;
}
- referenced += page_referenced_one(page, vma,
- &mapcount, &failed);
+ referenced += page_referenced_one(page, vma, &mapcount);
if (!mapcount)
- goto out;
+ break;
}
- if (list_empty(&mapping->i_mmap_nonlinear))
- WARN_ON(!failed);
-out:
spin_unlock(&mapping->i_mmap_lock);
return referenced;
}
* skipped over this mm) then we should reactivate it.
*/
if ((vma->vm_flags & (VM_LOCKED|VM_RESERVED)) ||
- ptep_test_and_clear_young(pte)) {
+ ptep_clear_flush_young(vma, address, pte)) {
+ ret = SWAP_FAIL;
+ goto out_unmap;
+ }
+
+ /*
+ * Don't pull an anonymous page out from under get_user_pages.
+ * GUP carefully breaks COW and raises page count (while holding
+ * page_table_lock, as we have here) to make sure that the page
+ * cannot be freed. If we unmap that page here, a user write
+ * access to the virtual address will bring back the page, but
+ * its raised count will (ironically) be taken to mean it's not
+ * an exclusive swap page, do_wp_page will replace it by a copy
+ * page, and the user never get to see the data GUP was holding
+ * the original page for.
+ */
+ if (PageSwapCache(page) &&
+ page_count(page) != page->mapcount + 2) {
ret = SWAP_FAIL;
goto out_unmap;
}
if (PageReserved(page))
continue;
- if (ptep_test_and_clear_young(pte))
+ if (ptep_clear_flush_young(vma, address, pte))
continue;
/* Nuke the page table entry. */
}
#endif
-int shmem_lock(struct file *file, int lock)
+void shmem_lock(struct file *file, int lock)
{
struct inode *inode = file->f_dentry->d_inode;
struct shmem_inode_info *info = SHMEM_I(inode);
- struct mm_struct *mm = current->mm;
- unsigned long lock_limit, locked;
- int retval = -ENOMEM;
spin_lock(&info->lock);
- if (lock && !(info->flags & VM_LOCKED)) {
- locked = inode->i_size >> PAGE_SHIFT;
- locked += mm->locked_vm;
- lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur;
- lock_limit >>= PAGE_SHIFT;
- if ((locked > lock_limit) && !capable(CAP_IPC_LOCK))
- goto out_nomem;
- mm->locked_vm = locked;
- }
- if (!lock && (info->flags & VM_LOCKED) && mm) {
- locked = inode->i_size >> PAGE_SHIFT;
- mm->locked_vm -= locked;
- }
if (lock)
info->flags |= VM_LOCKED;
else
info->flags &= ~VM_LOCKED;
- retval = 0;
-out_nomem:
spin_unlock(&info->lock);
- return retval;
}
static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
*
* Rewritten to use page cache, (C) 1998 Stephen Tweedie
*/
-
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/swap.h>
/*
* swapper_space is a fiction, retained to simplify the path through
- * vmscan's shrink_list. Only those fields initialized below are used.
+ * vmscan's shrink_list, to make sync_page look nicer, and to allow
+ * future use of radix_tree tags in the swap cache.
*/
static struct address_space_operations swap_aops = {
.writepage = swap_writepage,
.page_tree = RADIX_TREE_INIT(GFP_ATOMIC),
.tree_lock = SPIN_LOCK_UNLOCKED,
.a_ops = &swap_aops,
+ .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
.backing_dev_info = &swap_backing_dev_info,
};
+EXPORT_SYMBOL(swapper_space);
#define INC_CACHE_INFO(x) do { swap_cache_info.x++; } while (0)
* where the page is seen to be mapped into process pagetables. In that case,
* the page is marked clean but is left attached to its address_space.
*
+ * The page is also marked not uptodate so that a subsequent pagefault will
+ * perform I/O to bringthe page's contents back into sync with its backing
+ * store.
+ *
* FIXME: invalidate_inode_pages2() is probably trivially livelockable.
*/
void invalidate_inode_pages2(struct address_space *mapping)
if (page->mapping == mapping) { /* truncate race? */
wait_on_page_writeback(page);
next = page->index + 1;
- if (page_mapped(page))
+ if (page_mapped(page)) {
clear_page_dirty(page);
- else
+ ClearPageUptodate(page);
+ } else {
invalidate_complete_page(mapping, page);
+ }
}
unlock_page(page);
}
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
-#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
unlock_page(page);
}
+/* possible outcome of pageout() */
+typedef enum {
+ /* failed to write page out, page is locked */
+ PAGE_KEEP,
+ /* move page to the active list, page is locked */
+ PAGE_ACTIVATE,
+ /* page has been sent to the disk successfully, page is unlocked */
+ PAGE_SUCCESS,
+ /* page is clean and locked */
+ PAGE_CLEAN,
+} pageout_t;
+
/*
- * shrink_list returns the number of reclaimed pages
+ * pageout is called by shrink_list() for each dirty page. Calls ->writepage().
*/
-static int
-shrink_list(struct list_head *page_list, unsigned int gfp_mask,
- int *nr_scanned, int do_writepage)
+static pageout_t pageout(struct page *page, struct address_space *mapping)
+{
+ /*
+ * If the page is dirty, only perform writeback if that write
+ * will be non-blocking. To prevent this allocation from being
+ * stalled by pagecache activity. But note that there may be
+ * stalls if we need to run get_block(). We could test
+ * PagePrivate for that.
+ *
+ * If this process is currently in generic_file_write() against
+ * this page's queue, we can perform writeback even if that
+ * will block.
+ *
+ * If the page is swapcache, write it back even if that would
+ * block, for some throttling. This happens by accident, because
+ * swap_backing_dev_info is bust: it doesn't reflect the
+ * congestion state of the swapdevs. Easy to fix, if needed.
+ * See swapfile.c:page_queue_congested().
+ */
+ if (!is_page_cache_freeable(page))
+ return PAGE_KEEP;
+ if (!mapping)
+ return PAGE_KEEP;
+ if (mapping->a_ops->writepage == NULL)
+ return PAGE_ACTIVATE;
+ if (!may_write_to_queue(mapping->backing_dev_info))
+ return PAGE_KEEP;
+
+ if (clear_page_dirty_for_io(page)) {
+ int res;
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_NONE,
+ .nr_to_write = SWAP_CLUSTER_MAX,
+ .nonblocking = 1,
+ .for_reclaim = 1,
+ };
+
+ SetPageReclaim(page);
+ res = mapping->a_ops->writepage(page, &wbc);
+ if (res < 0)
+ handle_write_error(mapping, page, res);
+ if (res == WRITEPAGE_ACTIVATE) {
+ ClearPageReclaim(page);
+ return PAGE_ACTIVATE;
+ }
+ if (!PageWriteback(page)) {
+ /* synchronous write or broken a_ops? */
+ ClearPageReclaim(page);
+ }
+
+ return PAGE_SUCCESS;
+ }
+
+ return PAGE_CLEAN;
+}
+
+struct scan_control {
+ /* Ask refill_inactive_zone, or shrink_cache to scan this many pages */
+ unsigned long nr_to_scan;
+
+ /* Incremented by the number of inactive pages that were scanned */
+ unsigned long nr_scanned;
+
+ /* Incremented by the number of pages reclaimed */
+ unsigned long nr_reclaimed;
+
+ unsigned long nr_mapped; /* From page_state */
+
+ /* Ask shrink_caches, or shrink_zone to scan at this priority */
+ unsigned int priority;
+
+ /* This context's GFP mask */
+ unsigned int gfp_mask;
+
+ int may_writepage;
+};
+
+/*
+ * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed
+ */
+static int shrink_list(struct list_head *page_list, struct scan_control *sc)
{
LIST_HEAD(ret_pages);
struct pagevec freed_pvec;
int pgactivate = 0;
- int ret = 0;
+ int reclaimed = 0;
cond_resched();
if (TestSetPageLocked(page))
goto keep;
- /* Double the slab pressure for mapped and swapcache pages */
- if (page_mapped(page) || PageSwapCache(page))
- (*nr_scanned)++;
-
BUG_ON(PageActive(page));
if (PageWriteback(page))
goto keep_locked;
+ sc->nr_scanned++;
+ /* Double the slab pressure for mapped and swapcache pages */
+ if (page_mapped(page) || PageSwapCache(page))
+ sc->nr_scanned++;
+
page_map_lock(page);
referenced = page_referenced(page);
if (referenced && page_mapping_inuse(page)) {
#endif /* CONFIG_SWAP */
mapping = page_mapping(page);
- may_enter_fs = (gfp_mask & __GFP_FS) ||
- (PageSwapCache(page) && (gfp_mask & __GFP_IO));
+ may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
+ (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
/*
* The page is mapped into the page tables of one or more
}
page_map_unlock(page);
- /*
- * If the page is dirty, only perform writeback if that write
- * will be non-blocking. To prevent this allocation from being
- * stalled by pagecache activity. But note that there may be
- * stalls if we need to run get_block(). We could test
- * PagePrivate for that.
- *
- * If this process is currently in generic_file_write() against
- * this page's queue, we can perform writeback even if that
- * will block.
- *
- * If the page is swapcache, write it back even if that would
- * block, for some throttling. This happens by accident, because
- * swap_backing_dev_info is bust: it doesn't reflect the
- * congestion state of the swapdevs. Easy to fix, if needed.
- * See swapfile.c:page_queue_congested().
- */
if (PageDirty(page)) {
if (referenced)
goto keep_locked;
- if (!is_page_cache_freeable(page))
- goto keep_locked;
- if (!mapping)
- goto keep_locked;
- if (mapping->a_ops->writepage == NULL)
- goto activate_locked;
if (!may_enter_fs)
goto keep_locked;
- if (!may_write_to_queue(mapping->backing_dev_info))
+ if (laptop_mode && !sc->may_writepage)
goto keep_locked;
- if (laptop_mode && !do_writepage)
+
+ /* Page is dirty, try to write it out here */
+ switch(pageout(page, mapping)) {
+ case PAGE_KEEP:
goto keep_locked;
- if (clear_page_dirty_for_io(page)) {
- int res;
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_NONE,
- .nr_to_write = SWAP_CLUSTER_MAX,
- .nonblocking = 1,
- .for_reclaim = 1,
- };
-
- SetPageReclaim(page);
- res = mapping->a_ops->writepage(page, &wbc);
- if (res < 0)
- handle_write_error(mapping, page, res);
- if (res == WRITEPAGE_ACTIVATE) {
- ClearPageReclaim(page);
- goto activate_locked;
- }
- if (!PageWriteback(page)) {
- /* synchronous write or broken a_ops? */
- ClearPageReclaim(page);
- }
- goto keep;
+ case PAGE_ACTIVATE:
+ goto activate_locked;
+ case PAGE_SUCCESS:
+ if (PageWriteback(page) || PageDirty(page))
+ goto keep;
+ /*
+ * A synchronous write - probably a ramdisk. Go
+ * ahead and try to reclaim the page.
+ */
+ if (TestSetPageLocked(page))
+ goto keep;
+ if (PageDirty(page) || PageWriteback(page))
+ goto keep_locked;
+ mapping = page_mapping(page);
+ case PAGE_CLEAN:
+ ; /* try to free the page below */
}
}
* the pages which were not successfully invalidated in
* truncate_complete_page(). We try to drop those buffers here
* and if that worked, and the page is no longer mapped into
- * process address space (page_count == 0) it can be freed.
+ * process address space (page_count == 1) it can be freed.
* Otherwise, leave the page on the LRU so it is swappable.
*/
if (PagePrivate(page)) {
- if (!try_to_release_page(page, gfp_mask))
+ if (!try_to_release_page(page, sc->gfp_mask))
goto activate_locked;
if (!mapping && page_count(page) == 1)
goto free_it;
free_it:
unlock_page(page);
- ret++;
+ reclaimed++;
if (!pagevec_add(&freed_pvec, page))
__pagevec_release_nonlru(&freed_pvec);
continue;
if (pagevec_count(&freed_pvec))
__pagevec_release_nonlru(&freed_pvec);
mod_page_state(pgactivate, pgactivate);
- return ret;
+ sc->nr_reclaimed += reclaimed;
+ return reclaimed;
}
/*
* a batch of pages and working on them outside the lock. Any pages which were
* not freed will be added back to the LRU.
*
- * shrink_cache() is passed the number of pages to scan and returns the number
- * of pages which were reclaimed.
+ * shrink_cache() adds the number of pages reclaimed to sc->nr_reclaimed
*
* For pagecache intensive workloads, the first loop here is the hottest spot
* in the kernel (apart from the copy_*_user functions).
*/
-static int
-shrink_cache(struct zone *zone, unsigned int gfp_mask,
- int max_scan, int *total_scanned, int do_writepage)
+static void shrink_cache(struct zone *zone, struct scan_control *sc)
{
LIST_HEAD(page_list);
struct pagevec pvec;
- int ret = 0;
+ int max_scan = sc->nr_to_scan;
pagevec_init(&pvec, 1);
mod_page_state_zone(zone, pgscan_kswapd, nr_scan);
else
mod_page_state_zone(zone, pgscan_direct, nr_scan);
- nr_freed = shrink_list(&page_list, gfp_mask,
- total_scanned, do_writepage);
- *total_scanned += nr_taken;
+ nr_freed = shrink_list(&page_list, sc);
if (current_is_kswapd())
mod_page_state(kswapd_steal, nr_freed);
mod_page_state_zone(zone, pgsteal, nr_freed);
- ret += nr_freed;
- if (nr_freed <= 0 && list_empty(&page_list))
- goto done;
-
spin_lock_irq(&zone->lru_lock);
/*
* Put back any unfreeable pages.
spin_unlock_irq(&zone->lru_lock);
done:
pagevec_release(&pvec);
- return ret;
}
/*
* But we had to alter page->flags anyway.
*/
static void
-refill_inactive_zone(struct zone *zone, const int nr_pages_in,
- struct page_state *ps)
+refill_inactive_zone(struct zone *zone, struct scan_control *sc)
{
int pgmoved;
int pgdeactivate = 0;
- int nr_pages = nr_pages_in;
+ int pgscanned = 0;
+ int nr_pages = sc->nr_to_scan;
LIST_HEAD(l_hold); /* The pages which were snipped off */
LIST_HEAD(l_inactive); /* Pages to go onto the inactive_list */
LIST_HEAD(l_active); /* Pages to go onto the active_list */
lru_add_drain();
pgmoved = 0;
spin_lock_irq(&zone->lru_lock);
- while (nr_pages && !list_empty(&zone->active_list)) {
+ while (pgscanned < nr_pages && !list_empty(&zone->active_list)) {
page = lru_to_page(&zone->active_list);
prefetchw_prev_lru_page(page, &zone->active_list, flags);
if (!TestClearPageLRU(page))
list_add(&page->lru, &l_hold);
pgmoved++;
}
- nr_pages--;
+ pgscanned++;
}
zone->nr_active -= pgmoved;
spin_unlock_irq(&zone->lru_lock);
* mapped memory instead of just pagecache. Work out how much memory
* is mapped.
*/
- mapped_ratio = (ps->nr_mapped * 100) / total_memory;
+ mapped_ratio = (sc->nr_mapped * 100) / total_memory;
/*
* Now decide how much we really want to unmap some pages. The mapped
spin_unlock_irq(&zone->lru_lock);
pagevec_release(&pvec);
- mod_page_state_zone(zone, pgrefill, nr_pages_in - nr_pages);
+ mod_page_state_zone(zone, pgrefill, pgscanned);
mod_page_state(pgdeactivate, pgdeactivate);
}
* Scan `nr_pages' from this zone. Returns the number of reclaimed pages.
* This is a basic per-zone page freer. Used by both kswapd and direct reclaim.
*/
-static int
-shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask,
- int *total_scanned, struct page_state *ps, int do_writepage)
+static void
+shrink_zone(struct zone *zone, struct scan_control *sc)
{
- unsigned long scan_active;
+ unsigned long scan_active, scan_inactive;
int count;
+ scan_inactive = (zone->nr_active + zone->nr_inactive) >> sc->priority;
+
/*
* Try to keep the active list 2/3 of the size of the cache. And
* make sure that refill_inactive is given a decent number of pages.
*/
if (zone->nr_active >= 4*(zone->nr_inactive*2 + 1)) {
/* Don't scan more than 4 times the inactive list scan size */
- scan_active = 4*max_scan;
+ scan_active = 4*scan_inactive;
} else {
unsigned long long tmp;
/* Cast to long long so the multiply doesn't overflow */
- tmp = (unsigned long long)max_scan * zone->nr_active;
+ tmp = (unsigned long long)scan_inactive * zone->nr_active;
do_div(tmp, zone->nr_inactive*2 + 1);
scan_active = (unsigned long)tmp;
}
count = atomic_read(&zone->nr_scan_active);
if (count >= SWAP_CLUSTER_MAX) {
atomic_set(&zone->nr_scan_active, 0);
- refill_inactive_zone(zone, count, ps);
+ sc->nr_to_scan = count;
+ refill_inactive_zone(zone, sc);
}
- atomic_add(max_scan, &zone->nr_scan_inactive);
+ atomic_add(scan_inactive, &zone->nr_scan_inactive);
count = atomic_read(&zone->nr_scan_inactive);
if (count >= SWAP_CLUSTER_MAX) {
atomic_set(&zone->nr_scan_inactive, 0);
- return shrink_cache(zone, gfp_mask, count,
- total_scanned, do_writepage);
+ sc->nr_to_scan = count;
+ shrink_cache(zone, sc);
}
- return 0;
}
/*
* If a zone is deemed to be full of pinned pages then just give it a light
* scan then give up on it.
*/
-static int
-shrink_caches(struct zone **zones, int priority, int *total_scanned,
- int gfp_mask, struct page_state *ps, int do_writepage)
+static void
+shrink_caches(struct zone **zones, struct scan_control *sc)
{
- int ret = 0;
int i;
for (i = 0; zones[i] != NULL; i++) {
struct zone *zone = zones[i];
- int max_scan;
- if (zone->free_pages < zone->pages_high)
- zone->temp_priority = priority;
+ zone->temp_priority = sc->priority;
+ if (zone->prev_priority > sc->priority)
+ zone->prev_priority = sc->priority;
- if (zone->all_unreclaimable && priority != DEF_PRIORITY)
+ if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */
- max_scan = (zone->nr_active + zone->nr_inactive) >> priority;
- ret += shrink_zone(zone, max_scan, gfp_mask,
- total_scanned, ps, do_writepage);
+ shrink_zone(zone, sc);
}
- return ret;
}
/*
*
* If the caller is !__GFP_FS then the probability of a failure is reasonably
* high - the zone may be full of dirty or under-writeback pages, which this
- * caller can't do much about. So for !__GFP_FS callers, we just perform a
- * small LRU walk and if that didn't work out, fail the allocation back to the
- * caller. GFP_NOFS allocators need to know how to deal with it. Kicking
- * bdflush, waiting and retrying will work.
- *
- * This is a fairly lame algorithm - it can result in excessive CPU burning and
- * excessive rotation of the inactive list, which is _supposed_ to be an LRU,
- * yes?
+ * caller can't do much about. We kick pdflush and take explicit naps in the
+ * hope that some of these pages can be written. But if the allocating task
+ * holds filesystem locks which prevent writeout this might not work, and the
+ * allocation attempt will fail.
*/
int try_to_free_pages(struct zone **zones,
unsigned int gfp_mask, unsigned int order)
{
int priority;
int ret = 0;
- int nr_reclaimed = 0;
+ int total_scanned = 0, total_reclaimed = 0;
struct reclaim_state *reclaim_state = current->reclaim_state;
+ struct scan_control sc;
int i;
- unsigned long total_scanned = 0;
- int do_writepage = 0;
+
+ sc.gfp_mask = gfp_mask;
+ sc.may_writepage = 0;
inc_page_state(allocstall);
zones[i]->temp_priority = DEF_PRIORITY;
for (priority = DEF_PRIORITY; priority >= 0; priority--) {
- int scanned = 0;
- struct page_state ps;
-
- get_page_state(&ps);
- nr_reclaimed += shrink_caches(zones, priority, &scanned,
- gfp_mask, &ps, do_writepage);
- shrink_slab(scanned, gfp_mask);
+ sc.nr_mapped = read_page_state(nr_mapped);
+ sc.nr_scanned = 0;
+ sc.nr_reclaimed = 0;
+ sc.priority = priority;
+ shrink_caches(zones, &sc);
+ shrink_slab(sc.nr_scanned, gfp_mask);
if (reclaim_state) {
- nr_reclaimed += reclaim_state->reclaimed_slab;
+ sc.nr_reclaimed += reclaim_state->reclaimed_slab;
reclaim_state->reclaimed_slab = 0;
}
- if (nr_reclaimed >= SWAP_CLUSTER_MAX) {
+ if (sc.nr_reclaimed >= SWAP_CLUSTER_MAX) {
ret = 1;
goto out;
}
- if (!(gfp_mask & __GFP_FS))
- break; /* Let the caller handle it */
+ total_scanned += sc.nr_scanned;
+ total_reclaimed += sc.nr_reclaimed;
+
/*
* Try to write back as many pages as we just scanned. This
* tends to cause slow streaming writers to write data to the
* that's undesirable in laptop mode, where we *want* lumpy
* writeout. So in laptop mode, write out the whole world.
*/
- total_scanned += scanned;
if (total_scanned > SWAP_CLUSTER_MAX + SWAP_CLUSTER_MAX/2) {
wakeup_bdflush(laptop_mode ? 0 : total_scanned);
- do_writepage = 1;
+ sc.may_writepage = 1;
}
/* Take a nap, wait for some writeback to complete */
- if (scanned && priority < DEF_PRIORITY - 2)
+ if (sc.nr_scanned && priority < DEF_PRIORITY - 2)
blk_congestion_wait(WRITE, HZ/10);
}
if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY))
* the page allocator fallback scheme to ensure that aging of pages is balanced
* across the zones.
*/
-static int balance_pgdat(pg_data_t *pgdat, int nr_pages, struct page_state *ps)
+static int balance_pgdat(pg_data_t *pgdat, int nr_pages)
{
int to_free = nr_pages;
int priority;
int i;
+ int total_scanned = 0, total_reclaimed = 0;
struct reclaim_state *reclaim_state = current->reclaim_state;
- unsigned long total_scanned = 0;
- unsigned long total_reclaimed = 0;
- int do_writepage = 0;
+ struct scan_control sc;
+
+ sc.gfp_mask = GFP_KERNEL;
+ sc.may_writepage = 0;
+ sc.nr_mapped = read_page_state(nr_mapped);
inc_page_state(pageoutrun);
zone->temp_priority = DEF_PRIORITY;
}
- for (priority = DEF_PRIORITY; priority; priority--) {
+ for (priority = DEF_PRIORITY; priority >= 0; priority--) {
int all_zones_ok = 1;
int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */
*/
for (i = 0; i <= end_zone; i++) {
struct zone *zone = pgdat->node_zones + i;
- int max_scan;
- int reclaimed;
- int scanned = 0;
if (zone->all_unreclaimable && priority != DEF_PRIORITY)
continue;
all_zones_ok = 0;
}
zone->temp_priority = priority;
- max_scan = (zone->nr_active + zone->nr_inactive)
- >> priority;
- reclaimed = shrink_zone(zone, max_scan, GFP_KERNEL,
- &scanned, ps, do_writepage);
- total_scanned += scanned;
+ if (zone->prev_priority > priority)
+ zone->prev_priority = priority;
+ sc.nr_scanned = 0;
+ sc.nr_reclaimed = 0;
+ sc.priority = priority;
+ shrink_zone(zone, &sc);
reclaim_state->reclaimed_slab = 0;
- shrink_slab(scanned, GFP_KERNEL);
- reclaimed += reclaim_state->reclaimed_slab;
- total_reclaimed += reclaimed;
- to_free -= reclaimed;
+ shrink_slab(sc.nr_scanned, GFP_KERNEL);
+ sc.nr_reclaimed += reclaim_state->reclaimed_slab;
+ total_reclaimed += sc.nr_reclaimed;
if (zone->all_unreclaimable)
continue;
if (zone->pages_scanned > zone->present_pages * 2)
*/
if (total_scanned > SWAP_CLUSTER_MAX * 2 &&
total_scanned > total_reclaimed+total_reclaimed/2)
- do_writepage = 1;
+ sc.may_writepage = 1;
}
- if (nr_pages && to_free > 0)
+ if (nr_pages && to_free > total_reclaimed)
continue; /* swsusp: need to do more work */
if (all_zones_ok)
break; /* kswapd: all done */
tsk->flags |= PF_MEMALLOC|PF_KSWAPD;
for ( ; ; ) {
- struct page_state ps;
-
if (current->flags & PF_FREEZE)
refrigerator(PF_FREEZE);
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
schedule();
finish_wait(&pgdat->kswapd_wait, &wait);
try_to_clip_inodes();
- get_page_state(&ps);
- balance_pgdat(pgdat, 0, &ps);
+
+ balance_pgdat(pgdat, 0);
}
}
current->reclaim_state = &reclaim_state;
for_each_pgdat(pgdat) {
int freed;
- struct page_state ps;
-
- get_page_state(&ps);
- freed = balance_pgdat(pgdat, nr_to_free, &ps);
+ freed = balance_pgdat(pgdat, nr_to_free);
ret += freed;
nr_to_free -= freed;
if (nr_to_free <= 0)
static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
static int vlan_device_event(struct notifier_block *, unsigned long, void *);
-static int vlan_ioctl_handler(unsigned long);
+static int vlan_ioctl_handler(void __user *);
static int unregister_vlan_dev(struct net_device *, unsigned short );
struct notifier_block vlan_notifier_block = {
/*
* VLAN IOCTL handler.
* o execute requested action or pass command to the device driver
- * arg is really a void* to a vlan_ioctl_args structure.
+ * arg is really a struct vlan_ioctl_args __user *.
*/
-static int vlan_ioctl_handler(unsigned long arg)
+static int vlan_ioctl_handler(void __user *arg)
{
int err = 0;
struct vlan_ioctl_args args;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (copy_from_user(&args, (void*)arg,
- sizeof(struct vlan_ioctl_args)))
+ if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
return -EFAULT;
/* Null terminate this sucker, just in case. */
/* ioctl calls. Shouldn't even need touching */
/* Device configuration ioctl calls */
-static int atif_ioctl(int cmd, void *arg)
+static int atif_ioctl(int cmd, void __user *arg)
{
static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF };
struct ifreq atreq;
}
/* Routing ioctl() calls */
-static int atrtr_ioctl(unsigned int cmd, void *arg)
+static int atrtr_ioctl(unsigned int cmd, void __user *arg)
{
struct rtentry rt;
struct atalk_route *rt;
int err;
- if (flags & ~MSG_DONTWAIT)
+ if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return -EINVAL;
if (len > DDP_MAXSZ)
{
int rc = -EINVAL;
struct sock *sk = sock->sk;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
/* Protocol layer */
if (amount < 0)
amount = 0;
- rc = put_user(amount, (int *)arg);
+ rc = put_user(amount, (int __user *)argp);
break;
}
case TIOCINQ: {
if (skb)
amount = skb->len - sizeof(struct ddpehdr);
- rc = put_user(amount, (int *)arg);
+ rc = put_user(amount, (int __user *)argp);
break;
}
case SIOCGSTAMP:
- rc = sock_get_timestamp(sk, (struct timeval __user *)arg);
+ rc = sock_get_timestamp(sk, argp);
break;
/* Routing */
case SIOCADDRT:
case SIOCDELRT:
rc = -EPERM;
if (capable(CAP_NET_ADMIN))
- rc = atrtr_ioctl(cmd, (void *)arg);
+ rc = atrtr_ioctl(cmd, argp);
break;
/* Interface */
case SIOCGIFADDR:
case SIOCSARP: /* proxy AARP */
case SIOCDARP: /* proxy AARP */
rtnl_lock();
- rc = atif_ioctl(cmd, (void *)arg);
+ rc = atif_ioctl(cmd, argp);
rtnl_unlock();
break;
/* Physical layer ioctl calls */
case SIOCGIFCOUNT:
case SIOCGIFINDEX:
case SIOCGIFNAME:
- rc = dev_ioctl(cmd, (void __user *)arg);
+ rc = dev_ioctl(cmd, argp);
break;
}
}
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size)
{
unsigned long flags;
struct atm_dev_addr *walk;
memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc));
spin_unlock_irqrestore(&dev->lock, flags);
error = total > size ? -E2BIG : total;
- if (copy_to_user(u_buf, tmp_buf, total < size ? total : size))
+ if (copy_to_user(buf, tmp_buf, total < size ? total : size))
error = -EFAULT;
kfree(tmp_buf);
return error;
void atm_reset_addr(struct atm_dev *dev);
int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size);
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size);
#endif
#ifdef CONFIG_ATM_BR2684_IPFILTER
/* this IOCTL is experimental. */
-static int br2684_setfilt(struct atm_vcc *atmvcc, unsigned long arg)
+static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg)
{
struct br2684_vcc *brvcc;
struct br2684_filter_set fs;
- if (copy_from_user(&fs, (void *) arg, sizeof fs))
+ if (copy_from_user(&fs, arg, sizeof fs))
return -EFAULT;
if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
/*
netif_rx(skb);
}
-static int br2684_regvcc(struct atm_vcc *atmvcc, unsigned long arg)
+static int br2684_regvcc(struct atm_vcc *atmvcc, void __user *arg)
{
/* assign a vcc to a dev
Note: we do not have explicit unassign, but look at _push()
struct net_device *net_dev;
struct atm_backend_br2684 be;
- if (copy_from_user(&be, (void *) arg, sizeof be))
+ if (copy_from_user(&be, arg, sizeof be))
return -EFAULT;
brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
if (!brvcc)
INIT_LIST_HEAD(&brdev->brvccs);
}
-static int br2684_create(unsigned long arg)
+static int br2684_create(void __user *arg)
{
int err;
struct net_device *netdev;
DPRINTK("br2684_create\n");
- if (copy_from_user(&ni, (void *) arg, sizeof ni)) {
+ if (copy_from_user(&ni, arg, sizeof ni)) {
return -EFAULT;
}
if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) {
unsigned long arg)
{
struct atm_vcc *atmvcc = ATM_SD(sock);
+ void __user *argp = (void __user *)arg;
int err;
switch(cmd) {
case ATM_SETBACKEND:
case ATM_NEWBACKENDIF: {
atm_backend_t b;
- err = get_user(b, (atm_backend_t *) arg);
+ err = get_user(b, (atm_backend_t __user *) argp);
if (err)
return -EFAULT;
if (b != ATM_BACKEND_BR2684)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (cmd == ATM_SETBACKEND)
- return br2684_regvcc(atmvcc, arg);
+ return br2684_regvcc(atmvcc, argp);
else
- return br2684_create(arg);
+ return br2684_create(argp);
}
#ifdef CONFIG_ATM_BR2684_IPFILTER
case BR2684_SETFILT:
return -ENOIOCTLCMD;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- err = br2684_setfilt(atmvcc, arg);
+ err = br2684_setfilt(atmvcc, argp);
return err;
#endif /* CONFIG_ATM_BR2684_IPFILTER */
}
struct atm_vcc *vcc;
struct sk_buff *skb;
int eff,error;
- const void *buff;
+ const void __user *buff;
int size;
lock_sock(sk);
}
int vcc_setsockopt(struct socket *sock, int level, int optname,
- char *optval, int optlen)
+ char __user *optval, int optlen)
{
struct atm_vcc *vcc;
unsigned long value;
return 0;
}
case SO_SETCLP:
- if (get_user(value,(unsigned long *) optval))
+ if (get_user(value,(unsigned long __user *)optval))
return -EFAULT;
if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
else vcc->atm_options &= ~ATM_ATMOPT_CLP;
int vcc_getsockopt(struct socket *sock, int level, int optname,
- char *optval, int *optlen)
+ char __user *optval, int __user *optlen)
{
struct atm_vcc *vcc;
int len;
-EFAULT : 0;
case SO_SETCLP:
return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 :
- 0,(unsigned long *) optval) ? -EFAULT : 0;
+ 0,(unsigned long __user *)optval) ? -EFAULT : 0;
case SO_ATMPVC:
{
struct sockaddr_atmpvc pvc;
size_t total_len);
unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
-int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
- int optlen);
-int vcc_getsockopt(struct socket *sock, int level, int optname, char *optval,
- int *optlen);
+int vcc_setsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int optlen);
+int vcc_getsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int __user *optlen);
void atm_shutdown_dev(struct atm_dev *dev);
struct atm_vcc *vcc;
int error;
struct list_head * pos;
+ void __user *argp = (void __user *)arg;
vcc = ATM_SD(sock);
switch (cmd) {
}
error = put_user(vcc->sk->sk_sndbuf -
atomic_read(&vcc->sk->sk_wmem_alloc),
- (int *) arg) ? -EFAULT : 0;
+ (int __user *) argp) ? -EFAULT : 0;
goto done;
case SIOCINQ:
{
}
skb = skb_peek(&vcc->sk->sk_receive_queue);
error = put_user(skb ? skb->len : 0,
- (int *) arg) ? -EFAULT : 0;
+ (int __user *)argp) ? -EFAULT : 0;
goto done;
}
case SIOCGSTAMP: /* borrowed from IP */
- error = sock_get_timestamp(vcc->sk,
- (struct timeval __user *) arg);
+ error = sock_get_timestamp(vcc->sk, argp);
goto done;
case ATM_SETSC:
printk(KERN_WARNING "ATM_SETSC is obsolete\n");
if (error != -ENOIOCTLCMD)
goto done;
- error = atm_dev_ioctl(cmd, arg);
+ error = atm_dev_ioctl(cmd, argp);
done:
return error;
}
int
-lec_vcc_attach(struct atm_vcc *vcc, void *arg)
+lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
{
struct lec_vcc_priv *vpriv;
int bytes_left;
err = lec_mcast_attach(vcc, (int) arg);
break;
case ATMLEC_DATA:
- err = lec_vcc_attach(vcc, (void *) arg);
+ err = lec_vcc_attach(vcc, (void __user *) arg);
break;
}
#define LEC_VCC_PRIV(vcc) ((struct lec_vcc_priv *)((vcc)->user_back))
int lecd_attach(struct atm_vcc *vcc, int arg);
-int lec_vcc_attach(struct atm_vcc *vcc, void *arg);
+int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg);
int lec_mcast_attach(struct atm_vcc *vcc, int arg);
struct net_device *get_dev_lec(int itf);
int make_lec(struct atm_vcc *vcc);
return retval;
}
-int atm_mpoa_vcc_attach(struct atm_vcc *vcc, long arg)
+int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
{
int bytes_left;
struct mpoa_client *mpc;
uint32_t ipaddr;
unsigned char *ip;
- bytes_left = copy_from_user(&ioc_data, (void *)arg, sizeof(struct atmmpc_ioc));
+ bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
if (bytes_left != 0) {
printk("mpoa: mpc_vcc_attach: Short read (missed %d bytes) from userland\n", bytes_left);
return -EFAULT;
return;
}
-static void mpc_timer_refresh()
+static void mpc_timer_refresh(void)
{
mpc_timer.expires = jiffies + (MPC_P2 * HZ);
mpc_timer.data = mpc_timer.expires;
sock->state = SS_CONNECTED;
break;
case ATMMPC_DATA:
- err = atm_mpoa_vcc_attach(vcc, arg);
+ err = atm_mpoa_vcc_attach(vcc, (void __user *)arg);
break;
default:
break;
/* Functions for ioctl(ATMMPC_*) operations */
int atm_mpoa_mpoad_attach(struct atm_vcc *vcc, int arg);
-int atm_mpoa_vcc_attach(struct atm_vcc *vcc, long arg);
+int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg);
struct mpoa_client {
struct mpoa_client *next;
extern struct mpoa_client *mpcs;
extern struct proc_dir_entry *atm_proc_root; /* from proc.c. */
-static ssize_t proc_mpc_read(struct file *file, char *buff,
+static ssize_t proc_mpc_read(struct file *file, char __user *buff,
size_t count, loff_t *pos);
-static ssize_t proc_mpc_write(struct file *file, const char *buff,
+static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
size_t nbytes, loff_t *ppos);
static int parse_qos(const char *buff, int len);
/*
* READING function - called when the /proc/atm/mpoa file is read from.
*/
-static ssize_t proc_mpc_read(struct file *file, char *buff,
+static ssize_t proc_mpc_read(struct file *file, char __user *buff,
size_t count, loff_t *pos){
unsigned long page = 0;
unsigned char *temp;
return length;
}
-static ssize_t proc_mpc_write(struct file *file, const char *buff,
+static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
size_t nbytes, loff_t *ppos)
{
int incoming, error, retval;
char *page, c;
- const char *tmp;
+ const char __user *tmp;
if (nbytes == 0) return 0;
if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1;
{
switch (cmd) {
case PPPIOCGFLAGS:
- return put_user(chan_to_pvcc(chan)->flags, (int *) arg)
+ return put_user(chan_to_pvcc(chan)->flags, (int __user *) arg)
? -EFAULT : 0;
case PPPIOCSFLAGS:
- return get_user(chan_to_pvcc(chan)->flags, (int *) arg)
+ return get_user(chan_to_pvcc(chan)->flags, (int __user *) arg)
? -EFAULT : 0;
}
return -ENOTTY;
.ioctl = pppoatm_devppp_ioctl,
};
-static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, unsigned long arg)
+static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg)
{
struct atm_backend_ppp be;
struct pppoatm_vcc *pvcc;
* prototypical one used to initialize them
*/
static const DECLARE_TASKLET(tasklet_proto, pppoatm_wakeup_sender, 0);
- if (copy_from_user(&be, (void *) arg, sizeof be))
+ if (copy_from_user(&be, arg, sizeof be))
return -EFAULT;
if (be.encaps != PPPOATM_ENCAPS_AUTODETECT &&
be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC)
unsigned long arg)
{
struct atm_vcc *atmvcc = ATM_SD(sock);
+ void __user *argp = (void __user *)arg;
if (cmd != ATM_SETBACKEND && atmvcc->push != pppoatm_push)
return -ENOIOCTLCMD;
switch (cmd) {
case ATM_SETBACKEND: {
atm_backend_t b;
- if (get_user(b, (atm_backend_t *) arg))
+ if (get_user(b, (atm_backend_t __user *) argp))
return -EFAULT;
if (b != ATM_BACKEND_PPP)
return -ENOIOCTLCMD;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- return pppoatm_assign_vcc(atmvcc, arg);
+ return pppoatm_assign_vcc(atmvcc, argp);
}
case PPPIOCGCHAN:
return put_user(ppp_channel_index(&atmvcc_to_pvcc(atmvcc)->
- chan), (int *) arg) ? -EFAULT : 0;
+ chan), (int __user *) argp) ? -EFAULT : 0;
case PPPIOCGUNIT:
return put_user(ppp_unit_number(&atmvcc_to_pvcc(atmvcc)->
- chan), (int *) arg) ? -EFAULT : 0;
+ chan), (int __user *) argp) ? -EFAULT : 0;
}
return -ENOIOCTLCMD;
}
#include "common.h" /* atm_proc_init prototype */
#include "signaling.h" /* to get sigd - ugly too */
-static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
+static ssize_t proc_dev_atm_read(struct file *file,char __user *buf,size_t count,
loff_t *pos);
static struct file_operations proc_atm_dev_ops = {
.release = vcc_seq_release,
};
-static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
- loff_t *pos)
+static ssize_t proc_dev_atm_read(struct file *file, char __user *buf,
+ size_t count, loff_t *pos)
{
struct atm_dev *dev;
unsigned long page;
}
-static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats *arg, int zero)
+static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats __user *arg, int zero)
{
struct atm_dev_stats tmp;
int error = 0;
}
-int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
+int atm_dev_ioctl(unsigned int cmd, void __user *arg)
{
- void *buf;
+ void __user *buf;
int error, len, number, size = 0;
struct atm_dev *dev;
struct list_head *p;
int *tmp_buf, *tmp_p;
-
+ struct atm_iobuf __user *iobuf = arg;
+ struct atmif_sioc __user *sioc = arg;
switch (cmd) {
case ATM_GETNAMES:
- if (get_user(buf, &((struct atm_iobuf *) arg)->buffer))
+ if (get_user(buf, &iobuf->buffer))
return -EFAULT;
- if (get_user(len, &((struct atm_iobuf *) arg)->length))
+ if (get_user(len, &iobuf->length))
return -EFAULT;
spin_lock(&atm_dev_lock);
list_for_each(p, &atm_devs)
}
spin_unlock(&atm_dev_lock);
error = ((copy_to_user(buf, tmp_buf, size)) ||
- put_user(size, &((struct atm_iobuf *) arg)->length))
+ put_user(size, &iobuf->length))
? -EFAULT : 0;
kfree(tmp_buf);
return error;
break;
}
- if (get_user(buf, &((struct atmif_sioc *) arg)->arg))
+ if (get_user(buf, &sioc->arg))
return -EFAULT;
- if (get_user(len, &((struct atmif_sioc *) arg)->length))
+ if (get_user(len, &sioc->length))
return -EFAULT;
- if (get_user(number, &((struct atmif_sioc *) arg)->number))
+ if (get_user(number, &sioc->number))
return -EFAULT;
if (!(dev = atm_dev_lookup(number)))
size = error;
/* may return 0, but later on size == 0 means "don't
write the length" */
- error = put_user(size, &((struct atmif_sioc *) arg)->length)
+ error = put_user(size, &sioc->length)
? -EFAULT : 0;
goto done;
case ATM_SETLOOP:
}
if (size)
- error = put_user(size, &((struct atmif_sioc *) arg)->length)
+ error = put_user(size, &sioc->length)
? -EFAULT : 0;
else
error = 0;
extern spinlock_t atm_dev_lock;
-int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
+int atm_dev_ioctl(unsigned int cmd, void __user *arg);
#ifdef CONFIG_PROC_FS
* includes a KILL command to abort any connection.
* VERY useful for debugging ;-)
*/
-static int ax25_ctl_ioctl(const unsigned int cmd, void *arg)
+static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)
{
struct ax25_ctl_struct ax25_ctl;
ax25_digi digi;
size_t size;
int lv, err, addr_len = msg->msg_namelen;
- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR)) {
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;
- }
lock_sock(sk);
ax25 = ax25_sk(sk);
static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
+ void __user *argp = (void __user *)arg;
int res = 0;
lock_sock(sk);
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- res = put_user(amount, (int *)arg);
+ res = put_user(amount, (int __user *)argp);
break;
}
/* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
- res = put_user(amount, (int *)arg);
+ res = put_user(amount, (int __user *)argp);
break;
}
case SIOCGSTAMP:
if (sk != NULL) {
- res = sock_get_timestamp(sk, (struct timeval __user *)arg);
+ res = sock_get_timestamp(sk, argp);
break;
}
res = -EINVAL;
case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */
case SIOCAX25GETUID: {
struct sockaddr_ax25 sax25;
- if (copy_from_user(&sax25, (void *)arg, sizeof(sax25))) {
+ if (copy_from_user(&sax25, argp, sizeof(sax25))) {
res = -EFAULT;
break;
}
res = -EPERM;
break;
}
- if (get_user(amount, (long *)arg)) {
+ if (get_user(amount, (long __user *)argp)) {
res = -EFAULT;
break;
}
res = -EPERM;
break;
}
- res = ax25_rt_ioctl(cmd, (void *)arg);
+ res = ax25_rt_ioctl(cmd, argp);
break;
case SIOCAX25CTLCON:
res = -EPERM;
break;
}
- res = ax25_ctl_ioctl(cmd, (void *)arg);
+ res = ax25_ctl_ioctl(cmd, argp);
break;
case SIOCAX25GETINFO:
warned=1;
}
- if (copy_to_user((void *)arg, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
+ if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct_deprecated))) {
res = -EFAULT;
break;
}
} else {
- if (copy_to_user((void *)arg, &ax25_info, sizeof(struct ax25_info_struct))) {
+ if (copy_to_user(argp, &ax25_info, sizeof(struct ax25_info_struct))) {
res = -EINVAL;
break;
}
res = -EPERM;
break;
}
- if (copy_from_user(&ax25_fwd, (void *)arg, sizeof(ax25_fwd))) {
+ if (copy_from_user(&ax25_fwd, argp, sizeof(ax25_fwd))) {
res = -EFAULT;
break;
}
break;
default:
- res = dev_ioctl(cmd, (void __user *)arg);
+ res = dev_ioctl(cmd, argp);
break;
}
release_sock(sk);
return err;
}
-int ax25_rt_ioctl(unsigned int cmd, void *arg)
+int ax25_rt_ioctl(unsigned int cmd, void __user *arg)
{
struct ax25_route_opt_struct rt_option;
struct ax25_routes_struct route;
struct bnep_conndel_req cd;
struct bnep_conninfo ci;
struct socket *nsock;
+ void __user *argp = (void __user *)arg;
int err;
BT_DBG("cmd %x arg %lx", cmd, arg);
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
+ if (copy_from_user(&ca, argp, sizeof(ca)))
return -EFAULT;
nsock = sockfd_lookup(ca.sock, &err);
err = bnep_add_connection(&ca, nsock);
if (!err) {
- if (copy_to_user((void *) arg, &ca, sizeof(ca)))
+ if (copy_to_user(argp, &ca, sizeof(ca)))
err = -EFAULT;
} else
fput(nsock->file);
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
+ if (copy_from_user(&cd, argp, sizeof(cd)))
return -EFAULT;
return bnep_del_connection(&cd);
case BNEPGETCONNLIST:
- if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
+ if (copy_from_user(&cl, argp, sizeof(cl)))
return -EFAULT;
if (cl.cnum <= 0)
return -EINVAL;
err = bnep_get_connlist(&cl);
- if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
+ if (!err && copy_to_user(argp, &cl, sizeof(cl)))
return -EFAULT;
return err;
case BNEPGETCONNINFO:
- if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
+ if (copy_from_user(&ci, argp, sizeof(ci)))
return -EFAULT;
err = bnep_get_conninfo(&ci);
- if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
+ if (!err && copy_to_user(argp, &ci, sizeof(ci)))
return -EFAULT;
return err;
struct cmtp_connlist_req {
__u32 cnum;
- struct cmtp_conninfo *ci;
+ struct cmtp_conninfo __user *ci;
};
int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
struct cmtp_connlist_req cl;
struct cmtp_conninfo ci;
struct socket *nsock;
+ void __user *argp = (void __user *)arg;
int err;
BT_DBG("cmd %x arg %lx", cmd, arg);
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
+ if (copy_from_user(&ca, argp, sizeof(ca)))
return -EFAULT;
nsock = sockfd_lookup(ca.sock, &err);
err = cmtp_add_connection(&ca, nsock);
if (!err) {
- if (copy_to_user((void *) arg, &ca, sizeof(ca)))
+ if (copy_to_user(argp, &ca, sizeof(ca)))
err = -EFAULT;
} else
fput(nsock->file);
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
+ if (copy_from_user(&cd, argp, sizeof(cd)))
return -EFAULT;
return cmtp_del_connection(&cd);
case CMTPGETCONNLIST:
- if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
+ if (copy_from_user(&cl, argp, sizeof(cl)))
return -EFAULT;
if (cl.cnum <= 0)
return -EINVAL;
err = cmtp_get_connlist(&cl);
- if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
+ if (!err && copy_to_user(argp, &cl, sizeof(cl)))
return -EFAULT;
return err;
case CMTPGETCONNINFO:
- if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
+ if (copy_from_user(&ci, argp, sizeof(ci)))
return -EFAULT;
err = cmtp_get_conninfo(&ci);
- if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
+ if (!err && copy_to_user(argp, &ci, sizeof(ci)))
return -EFAULT;
return err;
}
}
-int hci_get_conn_list(unsigned long arg)
+int hci_get_conn_list(void __user *arg)
{
struct hci_conn_list_req req, *cl;
struct hci_conn_info *ci;
struct list_head *p;
int n = 0, size, err;
- if (copy_from_user(&req, (void *) arg, sizeof(req)))
+ if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;
if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
hci_dev_put(hdev);
- err = copy_to_user((void *) arg, cl, size);
+ err = copy_to_user(arg, cl, size);
kfree(cl);
return err ? -EFAULT : 0;
}
-int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
+int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
{
struct hci_conn_info_req req;
struct hci_conn_info ci;
struct hci_conn *conn;
- char *ptr = (void *) arg + sizeof(req);
+ char __user *ptr = arg + sizeof(req);
- if (copy_from_user(&req, (void *) arg, sizeof(req)))
+ if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;
hci_dev_lock_bh(hdev);
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, sizeof(cp), &cp);
}
-int hci_inquiry(unsigned long arg)
+int hci_inquiry(void __user *arg)
{
+ __u8 __user *ptr = arg;
struct hci_inquiry_req ir;
struct hci_dev *hdev;
int err = 0, do_inquiry = 0, max_rsp;
long timeo;
- __u8 *buf, *ptr;
+ __u8 *buf;
- ptr = (void *) arg;
if (copy_from_user(&ir, ptr, sizeof(ir)))
return -EFAULT;
return ret;
}
-int hci_dev_cmd(unsigned int cmd, unsigned long arg)
+int hci_dev_cmd(unsigned int cmd, void __user *arg)
{
struct hci_dev *hdev;
struct hci_dev_req dr;
int err = 0;
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+ if (copy_from_user(&dr, arg, sizeof(dr)))
return -EFAULT;
if (!(hdev = hci_dev_get(dr.dev_id)))
return err;
}
-int hci_get_dev_list(unsigned long arg)
+int hci_get_dev_list(void __user *arg)
{
struct hci_dev_list_req *dl;
struct hci_dev_req *dr;
int n = 0, size, err;
__u16 dev_num;
- if (get_user(dev_num, (__u16 *) arg))
+ if (get_user(dev_num, (__u16 __user *) arg))
return -EFAULT;
if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
dl->dev_num = n;
size = sizeof(*dl) + n * sizeof(*dr);
- err = copy_to_user((void *) arg, dl, size);
+ err = copy_to_user(arg, dl, size);
kfree(dl);
return err ? -EFAULT : 0;
}
-int hci_get_dev_info(unsigned long arg)
+int hci_get_dev_info(void __user *arg)
{
struct hci_dev *hdev;
struct hci_dev_info di;
int err = 0;
- if (copy_from_user(&di, (void *) arg, sizeof(di)))
+ if (copy_from_user(&di, arg, sizeof(di)))
return -EFAULT;
if (!(hdev = hci_dev_get(di.dev_id)))
memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
memcpy(&di.features, &hdev->features, sizeof(di.features));
- if (copy_to_user((void *) arg, &di, sizeof(di)))
+ if (copy_to_user(arg, &di, sizeof(di)))
err = -EFAULT;
hci_dev_put(hdev);
return 0;
case HCIGETCONNINFO:
- return hci_get_conn_info(hdev, arg);
+ return hci_get_conn_info(hdev, (void __user *)arg);
default:
if (hdev->ioctl)
static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
+ void __user *argp = (void __user *)arg;
int err;
BT_DBG("cmd %x arg %lx", cmd, arg);
switch (cmd) {
case HCIGETDEVLIST:
- return hci_get_dev_list(arg);
+ return hci_get_dev_list(argp);
case HCIGETDEVINFO:
- return hci_get_dev_info(arg);
+ return hci_get_dev_info(argp);
case HCIGETCONNLIST:
- return hci_get_conn_list(arg);
+ return hci_get_conn_list(argp);
case HCIDEVUP:
if (!capable(CAP_NET_ADMIN))
case HCISETSCOMTU:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
- return hci_dev_cmd(cmd, arg);
+ return hci_dev_cmd(cmd, argp);
case HCIINQUIRY:
- return hci_inquiry(arg);
+ return hci_inquiry(argp);
default:
lock_sock(sk);
static void l2cap_sock_set_timer(struct sock *sk, long timeout)
{
BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
-
- if (!mod_timer(&sk->sk_timer, jiffies + timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
}
static void l2cap_sock_clear_timer(struct sock *sk)
{
BT_DBG("sock %p state %d", sk, sk->sk_state);
-
- if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &sk->sk_timer);
}
static void l2cap_sock_init_timer(struct sock *sk)
lock_sock(sk);
#ifdef CONFIG_BT_RFCOMM_TTY
- err = rfcomm_dev_ioctl(sk, cmd, arg);
+ err = rfcomm_dev_ioctl(sk, cmd, (void __user *)arg);
#else
err = -EOPNOTSUPP;
#endif
#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
-static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
+static int rfcomm_create_dev(struct sock *sk, void __user *arg)
{
struct rfcomm_dev_req req;
struct rfcomm_dlc *dlc;
int id;
- if (copy_from_user(&req, (void *) arg, sizeof(req)))
+ if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;
BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
return id;
}
-static int rfcomm_release_dev(unsigned long arg)
+static int rfcomm_release_dev(void __user *arg)
{
struct rfcomm_dev_req req;
struct rfcomm_dev *dev;
- if (copy_from_user(&req, (void *) arg, sizeof(req)))
+ if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;
BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
return 0;
}
-static int rfcomm_get_dev_list(unsigned long arg)
+static int rfcomm_get_dev_list(void __user *arg)
{
struct rfcomm_dev_list_req *dl;
struct rfcomm_dev_info *di;
BT_DBG("");
- if (get_user(dev_num, (u16 *) arg))
+ if (get_user(dev_num, (u16 __user *) arg))
return -EFAULT;
if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
dl->dev_num = n;
size = sizeof(*dl) + n * sizeof(*di);
- err = copy_to_user((void *) arg, dl, size);
+ err = copy_to_user(arg, dl, size);
kfree(dl);
return err ? -EFAULT : 0;
}
-static int rfcomm_get_dev_info(unsigned long arg)
+static int rfcomm_get_dev_info(void __user *arg)
{
struct rfcomm_dev *dev;
struct rfcomm_dev_info di;
BT_DBG("");
- if (copy_from_user(&di, (void *)arg, sizeof(di)))
+ if (copy_from_user(&di, arg, sizeof(di)))
return -EFAULT;
if (!(dev = rfcomm_dev_get(di.id)))
bacpy(&di.src, &dev->src);
bacpy(&di.dst, &dev->dst);
- if (copy_to_user((void *)arg, &di, sizeof(di)))
+ if (copy_to_user(arg, &di, sizeof(di)))
err = -EFAULT;
rfcomm_dev_put(dev);
return err;
}
-int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
{
- BT_DBG("cmd %d arg %ld", cmd, arg);
+ BT_DBG("cmd %d arg %p", cmd, arg);
switch (cmd) {
case RFCOMMCREATEDEV:
static void sco_sock_set_timer(struct sock *sk, long timeout)
{
BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
-
- if (!mod_timer(&sk->sk_timer, jiffies + timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
}
static void sco_sock_clear_timer(struct sock *sk)
{
BT_DBG("sock %p state %d", sk, sk->sk_state);
-
- if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &sk->sk_timer);
}
static void sco_sock_init_timer(struct sock *sk)
{
br_fdb_init();
- br_sysfs_init();
-
#ifdef CONFIG_BRIDGE_NETFILTER
if (br_netfilter_init())
return 1;
#endif
br_handle_frame_hook = NULL;
- br_sysfs_fini();
br_fdb_fini();
}
int err;
strncpy(ifr.ifr_name, dev->name, IFNAMSIZ);
- ifr.ifr_data = (void *) &ecmd;
+ ifr.ifr_data = (void __user *) &ecmd;
old_fs = get_fs();
set_fs(KERNEL_DS);
b.gc_timer_value = br_timer_value(&br->gc_timer);
rcu_read_unlock();
- if (copy_to_user((void *)args[1], &b, sizeof(b)))
+ if (copy_to_user((void __user *)args[1], &b, sizeof(b)))
return -EFAULT;
return 0;
memset(indices, 0, num*sizeof(int));
get_port_ifindices(br, indices, num);
- if (copy_to_user((void *)args[1], indices, num*sizeof(int)))
+ if (copy_to_user((void __user *)args[1], indices, num*sizeof(int)))
num = -EFAULT;
kfree(indices);
return num;
rcu_read_unlock();
- if (copy_to_user((void *)args[1], &p, sizeof(p)))
+ if (copy_to_user((void __user *)args[1], &p, sizeof(p)))
return -EFAULT;
return 0;
return -EOPNOTSUPP;
}
-static int old_deviceless(unsigned long uarg)
+static int old_deviceless(void __user *uarg)
{
unsigned long args[3];
- if (copy_from_user(args, (void *)uarg, sizeof(args)))
+ if (copy_from_user(args, uarg, sizeof(args)))
return -EFAULT;
switch (args[0]) {
memset(indices, 0, args[2]*sizeof(int));
args[2] = get_bridge_ifindices(indices, args[2]);
- ret = copy_to_user((void *)args[1], indices, args[2]*sizeof(int))
+ ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int))
? -EFAULT : args[2];
kfree(indices);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (copy_from_user(buf, (void *)args[1], IFNAMSIZ))
+ if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ))
return -EFAULT;
buf[IFNAMSIZ-1] = 0;
return -EOPNOTSUPP;
}
-int br_ioctl_deviceless_stub(unsigned int cmd, unsigned long uarg)
+int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
{
switch (cmd) {
case SIOCGIFBR:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (copy_from_user(buf, (void __user *) uarg, IFNAMSIZ))
+ if (copy_from_user(buf, uarg, IFNAMSIZ))
return -EFAULT;
buf[IFNAMSIZ-1] = 0;
skb_pull(skb, VLAN_HLEN);
skb->nh.raw += VLAN_HLEN;
}
- skb->dst->output(skb);
+ skb->dst->output(&skb);
return 0;
}
#ifdef CONFIG_SYSCTL
static
int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
int ret;
/* br_ioctl.c */
extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-extern int br_ioctl_deviceless_stub(unsigned int cmd, unsigned long arg);
+extern int br_ioctl_deviceless_stub(unsigned int cmd, void __user *arg);
/* br_netfilter.c */
extern int br_netfilter_init(void);
extern void br_sysfs_freeif(struct net_bridge_port *p);
/* br_sysfs_br.c */
-extern struct subsystem bridge_subsys;
-extern void br_sysfs_init(void);
-extern void br_sysfs_fini(void);
extern int br_sysfs_addbr(struct net_device *dev);
extern void br_sysfs_delbr(struct net_device *dev);
#define br_sysfs_addif(p) (0)
#define br_sysfs_removeif(p) do { } while(0)
#define br_sysfs_freeif(p) kfree(p)
-#define br_sysfs_init() do { } while(0)
-#define br_sysfs_fini() do { } while(0)
#define br_sysfs_addbr(dev) (0)
#define br_sysfs_delbr(dev) do { } while(0)
#endif /* CONFIG_SYSFS */
.read = brforward_read,
};
-
-/*
- * This is a dummy kset so bridge objects don't cause
- * hotplug events
- */
-struct subsystem bridge_subsys = {
- .kset = { .hotplug_ops = NULL },
-};
-
-void br_sysfs_init(void)
-{
- subsystem_register(&bridge_subsys);
-}
-
-void br_sysfs_fini(void)
-{
- subsystem_unregister(&bridge_subsys);
-}
-
/*
* Add entries in sysfs onto the existing network class device
* for the bridge.
kobject_set_name(&br->ifobj, SYSFS_BRIDGE_PORT_SUBDIR);
br->ifobj.ktype = NULL;
- br->ifobj.kset = &bridge_subsys.kset;
+ br->ifobj.kset = NULL;
br->ifobj.parent = brobj;
err = kobject_register(&br->ifobj);
kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
p->kobj.ktype = &brport_ktype;
p->kobj.parent = &(p->dev->class_dev.kobj);
- p->kobj.kset = &bridge_subsys.kset;
+ p->kobj.kset = NULL;
err = kobject_add(&p->kobj);
if(err)
# Makefile for the Linux networking core.
#
-obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
+obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o
obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
rcu_read_unlock();
}
-/* Calculate csum in the case, when packet is misrouted.
- * If it failed by some reason, ignore and send skb with wrong
- * checksum.
+/*
+ * Invalidate hardware checksum when packet is to be mangled, and
+ * complete checksum manually on outgoing path.
*/
-struct sk_buff *skb_checksum_help(struct sk_buff *skb)
+int skb_checksum_help(struct sk_buff **pskb, int inward)
{
unsigned int csum;
- int offset = skb->h.raw - skb->data;
+ int ret = 0, offset = (*pskb)->h.raw - (*pskb)->data;
+
+ if (inward) {
+ (*pskb)->ip_summed = CHECKSUM_NONE;
+ goto out;
+ }
- if (offset > (int)skb->len)
+ if (skb_shared(*pskb) || skb_cloned(*pskb)) {
+ struct sk_buff *newskb = skb_copy(*pskb, GFP_ATOMIC);
+ if (!newskb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ if ((*pskb)->sk)
+ skb_set_owner_w(newskb, (*pskb)->sk);
+ kfree_skb(*pskb);
+ *pskb = newskb;
+ }
+
+ if (offset > (int)(*pskb)->len)
BUG();
- csum = skb_checksum(skb, offset, skb->len-offset, 0);
+ csum = skb_checksum(*pskb, offset, (*pskb)->len-offset, 0);
- offset = skb->tail - skb->h.raw;
+ offset = (*pskb)->tail - (*pskb)->h.raw;
if (offset <= 0)
BUG();
- if (skb->csum + 2 > offset)
+ if ((*pskb)->csum + 2 > offset)
BUG();
- *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
- skb->ip_summed = CHECKSUM_NONE;
- return skb;
+ *(u16*)((*pskb)->h.raw + (*pskb)->csum) = csum_fold(csum);
+ (*pskb)->ip_summed = CHECKSUM_NONE;
+out:
+ return ret;
}
#ifdef CONFIG_HIGHMEM
if (skb->ip_summed == CHECKSUM_HW &&
(!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
(!(dev->features & NETIF_F_IP_CSUM) ||
- skb->protocol != htons(ETH_P_IP)))) {
- if ((skb = skb_checksum_help(skb)) == NULL)
- goto out;
- }
+ skb->protocol != htons(ETH_P_IP))))
+ if (skb_checksum_help(&skb, 0))
+ goto out_kfree_skb;
/* Grab device queue */
spin_lock_bh(&dev->queue_lock);
/* Finish processing unregister after unlock */
net_set_todo(dev);
+ synchronize_net();
+
dev_put(dev);
return 0;
}
spin_unlock(&dst_lock);
}
-static int dst_discard(struct sk_buff *skb)
+static int dst_discard_in(struct sk_buff *skb)
{
kfree_skb(skb);
return 0;
}
-static int dst_blackhole(struct sk_buff *skb)
+static int dst_discard_out(struct sk_buff **pskb)
{
- kfree_skb(skb);
+ kfree_skb(*pskb);
return 0;
}
dst->ops = ops;
dst->lastuse = jiffies;
dst->path = dst;
- dst->input = dst_discard;
- dst->output = dst_blackhole;
+ dst->input = dst_discard_in;
+ dst->output = dst_discard_out;
#if RT_CACHE_DEBUG >= 2
atomic_inc(&dst_total);
#endif
protocol module is unloaded.
*/
if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
- dst->input = dst_discard;
- dst->output = dst_blackhole;
+ dst->input = dst_discard_in;
+ dst->output = dst_discard_out;
}
dst->obsolete = 2;
}
return NULL;
}
+/* Dirty hack. We did it in 2.2 (in __dst_free),
+ * we have _very_ good reasons not to repeat
+ * this mistake in 2.3, but we have no choice
+ * now. _It_ _is_ _explicit_ _deliberate_
+ * _race_ _condition_.
+ *
+ * Commented and originally written by Alexey.
+ */
+static void dst_ifdown(struct dst_entry *dst, int unregister)
+{
+ struct net_device *dev = dst->dev;
+
+ if (!unregister) {
+ dst->input = dst_discard_in;
+ dst->output = dst_discard_out;
+ }
+
+ do {
+ if (unregister) {
+ dst->dev = &loopback_dev;
+ dev_hold(&loopback_dev);
+ dev_put(dev);
+ if (dst->neighbour && dst->neighbour->dev == dev) {
+ dst->neighbour->dev = &loopback_dev;
+ dev_put(dev);
+ dev_hold(&loopback_dev);
+ }
+ }
+
+ if (dst->ops->ifdown)
+ dst->ops->ifdown(dst, unregister);
+ } while ((dst = dst->child) && dst->flags & DST_NOHASH &&
+ dst->dev == dev);
+}
+
static int dst_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
case NETDEV_DOWN:
spin_lock_bh(&dst_lock);
for (dst = dst_garbage_list; dst; dst = dst->next) {
- if (dst->dev == dev) {
- /* Dirty hack. We did it in 2.2 (in __dst_free),
- we have _very_ good reasons not to repeat
- this mistake in 2.3, but we have no choice
- now. _It_ _is_ _explicit_ _deliberate_
- _race_ _condition_.
- */
- if (event!=NETDEV_DOWN &&
- dst->output == dst_blackhole) {
- dst->dev = &loopback_dev;
- dev_put(dev);
- dev_hold(&loopback_dev);
- dst->output = dst_discard;
- if (dst->neighbour && dst->neighbour->dev == dev) {
- dst->neighbour->dev = &loopback_dev;
- dev_put(dev);
- dev_hold(&loopback_dev);
- }
- } else {
- dst->input = dst_discard;
- dst->output = dst_blackhole;
- }
- }
+ if (dst->dev == dev)
+ dst_ifdown(dst, event != NETDEV_DOWN);
}
spin_unlock_bh(&dst_lock);
break;
int dev_ethtool(struct ifreq *ifr)
{
struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
- void __user *useraddr = (void __user *) ifr->ifr_data;
+ void __user *useraddr = ifr->ifr_data;
u32 ethcmd;
+ int rc;
/*
* XXX: This can be pushed down into the ethtool_* handlers that
if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd)))
return -EFAULT;
+ if(dev->ethtool_ops->begin)
+ if ((rc = dev->ethtool_ops->begin(dev)) < 0)
+ return rc;
+
switch (ethcmd) {
case ETHTOOL_GSET:
- return ethtool_get_settings(dev, useraddr);
+ rc = ethtool_get_settings(dev, useraddr);
+ break;
case ETHTOOL_SSET:
- return ethtool_set_settings(dev, useraddr);
+ rc = ethtool_set_settings(dev, useraddr);
+ break;
case ETHTOOL_GDRVINFO:
- return ethtool_get_drvinfo(dev, useraddr);
+ rc = ethtool_get_drvinfo(dev, useraddr);
+
+ break;
case ETHTOOL_GREGS:
- return ethtool_get_regs(dev, useraddr);
+ rc = ethtool_get_regs(dev, useraddr);
+ break;
case ETHTOOL_GWOL:
- return ethtool_get_wol(dev, useraddr);
+ rc = ethtool_get_wol(dev, useraddr);
+ break;
case ETHTOOL_SWOL:
- return ethtool_set_wol(dev, useraddr);
+ rc = ethtool_set_wol(dev, useraddr);
+ break;
case ETHTOOL_GMSGLVL:
- return ethtool_get_msglevel(dev, useraddr);
+ rc = ethtool_get_msglevel(dev, useraddr);
+ break;
case ETHTOOL_SMSGLVL:
- return ethtool_set_msglevel(dev, useraddr);
+ rc = ethtool_set_msglevel(dev, useraddr);
+ break;
case ETHTOOL_NWAY_RST:
- return ethtool_nway_reset(dev);
+ rc = ethtool_nway_reset(dev);
+ break;
case ETHTOOL_GLINK:
- return ethtool_get_link(dev, useraddr);
+ rc = ethtool_get_link(dev, useraddr);
+ break;
case ETHTOOL_GEEPROM:
- return ethtool_get_eeprom(dev, useraddr);
+ rc = ethtool_get_eeprom(dev, useraddr);
+ break;
case ETHTOOL_SEEPROM:
- return ethtool_set_eeprom(dev, useraddr);
+ rc = ethtool_set_eeprom(dev, useraddr);
+ break;
case ETHTOOL_GCOALESCE:
- return ethtool_get_coalesce(dev, useraddr);
+ rc = ethtool_get_coalesce(dev, useraddr);
+ break;
case ETHTOOL_SCOALESCE:
- return ethtool_set_coalesce(dev, useraddr);
+ rc = ethtool_set_coalesce(dev, useraddr);
+ break;
case ETHTOOL_GRINGPARAM:
- return ethtool_get_ringparam(dev, useraddr);
+ rc = ethtool_get_ringparam(dev, useraddr);
+ break;
case ETHTOOL_SRINGPARAM:
- return ethtool_set_ringparam(dev, useraddr);
+ rc = ethtool_set_ringparam(dev, useraddr);
+ break;
case ETHTOOL_GPAUSEPARAM:
- return ethtool_get_pauseparam(dev, useraddr);
+ rc = ethtool_get_pauseparam(dev, useraddr);
+ break;
case ETHTOOL_SPAUSEPARAM:
- return ethtool_set_pauseparam(dev, useraddr);
+ rc = ethtool_set_pauseparam(dev, useraddr);
+ break;
case ETHTOOL_GRXCSUM:
- return ethtool_get_rx_csum(dev, useraddr);
+ rc = ethtool_get_rx_csum(dev, useraddr);
+ break;
case ETHTOOL_SRXCSUM:
- return ethtool_set_rx_csum(dev, useraddr);
+ rc = ethtool_set_rx_csum(dev, useraddr);
+ break;
case ETHTOOL_GTXCSUM:
- return ethtool_get_tx_csum(dev, useraddr);
+ rc = ethtool_get_tx_csum(dev, useraddr);
+ break;
case ETHTOOL_STXCSUM:
- return ethtool_set_tx_csum(dev, useraddr);
+ rc = ethtool_set_tx_csum(dev, useraddr);
+ break;
case ETHTOOL_GSG:
- return ethtool_get_sg(dev, useraddr);
+ rc = ethtool_get_sg(dev, useraddr);
+ break;
case ETHTOOL_SSG:
- return ethtool_set_sg(dev, useraddr);
+ rc = ethtool_set_sg(dev, useraddr);
+ break;
case ETHTOOL_GTSO:
- return ethtool_get_tso(dev, useraddr);
+ rc = ethtool_get_tso(dev, useraddr);
+ break;
case ETHTOOL_STSO:
- return ethtool_set_tso(dev, useraddr);
+ rc = ethtool_set_tso(dev, useraddr);
+ break;
case ETHTOOL_TEST:
- return ethtool_self_test(dev, useraddr);
+ rc = ethtool_self_test(dev, useraddr);
+ break;
case ETHTOOL_GSTRINGS:
- return ethtool_get_strings(dev, useraddr);
+ rc = ethtool_get_strings(dev, useraddr);
+ break;
case ETHTOOL_PHYS_ID:
- return ethtool_phys_id(dev, useraddr);
+ rc = ethtool_phys_id(dev, useraddr);
+ break;
case ETHTOOL_GSTATS:
- return ethtool_get_stats(dev, useraddr);
+ rc = ethtool_get_stats(dev, useraddr);
+ break;
default:
- return -EOPNOTSUPP;
+ rc = -EOPNOTSUPP;
}
+
+ if(dev->ethtool_ops->complete)
+ dev->ethtool_ops->complete(dev);
+ return rc;
ioctl:
if (dev->do_ioctl)
}
while (len > 0) {
- u8 *base = iov->iov_base + offset;
+ u8 __user *base = iov->iov_base + offset;
int copy = min_t(unsigned int, len, iov->iov_len - offset);
offset = 0;
if ((ret = class_device_register(class_dev)))
goto out;
- for (i = 0; (attr = net_class_attributes[i]); i++) {
+ for (i = 0; (attr = net_class_attributes[i]) != NULL; i++) {
if ((ret = class_device_create_file(class_dev, attr)))
goto out_unreg;
}
unsigned int verdict;
int ret = 0;
- if (skb->ip_summed == CHECKSUM_HW) {
- if (outdev == NULL) {
- skb->ip_summed = CHECKSUM_NONE;
- } else {
- skb_checksum_help(skb);
- }
- }
-
/* We may already have this, but read-locks nest anyway */
rcu_read_lock();
return p - buf;
}
-static int count_trail_chars(const char *user_buffer, unsigned int maxlen)
+static int count_trail_chars(const char __user *user_buffer, unsigned int maxlen)
{
int i;
return i;
}
-static unsigned long num_arg(const char *user_buffer, unsigned long maxlen,
+static unsigned long num_arg(const char __user *user_buffer, unsigned long maxlen,
unsigned long *num)
{
int i = 0;
return i;
}
-static int strn_len(const char *user_buffer, unsigned int maxlen)
+static int strn_len(const char __user *user_buffer, unsigned int maxlen)
{
int i = 0;
return i;
}
-static int proc_write(struct file *file, const char *user_buffer,
+static int proc_write(struct file *file, const char __user *user_buffer,
unsigned long count, void *data)
{
int i = 0, max, len;
} while((skb = sk->sk_backlog.head) != NULL);
}
+/**
+ * sk_wait_data - wait for data to arrive at sk_receive_queue
+ * sk - sock to wait on
+ * timeo - for how long
+ *
+ * Now socket state including sk->sk_err is changed only under lock,
+ * hence we may omit checks after joining wait queue.
+ * We check receive queue before schedule() only as optimization;
+ * it is very likely that release_sock() added new data.
+ */
+int sk_wait_data(struct sock *sk, long *timeo)
+{
+ int rc;
+ DEFINE_WAIT(wait);
+
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue));
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ finish_wait(sk->sk_sleep, &wait);
+ return rc;
+}
+
+EXPORT_SYMBOL(sk_wait_data);
+
/*
* Set of default routines for initialising struct proto_ops when
* the protocol does not support a particular function. In certain
sk_wake_async(sk, 3, POLL_PRI);
}
+void sk_reset_timer(struct sock *sk, struct timer_list* timer,
+ unsigned long expires)
+{
+ if (!mod_timer(timer, expires))
+ sock_hold(sk);
+}
+
+EXPORT_SYMBOL(sk_reset_timer);
+
+void sk_stop_timer(struct sock *sk, struct timer_list* timer)
+{
+ if (timer_pending(timer) && del_timer(timer))
+ __sock_put(sk);
+}
+
+EXPORT_SYMBOL(sk_stop_timer);
+
void sock_init_data(struct socket *sock, struct sock *sk)
{
skb_queue_head_init(&sk->sk_receive_queue);
{
case SIOCGIFADDR:
case SIOCSIFADDR:
- return dn_dev_ioctl(cmd, (void *)arg);
+ return dn_dev_ioctl(cmd, (void __user *)arg);
case SIOCATMARK:
lock_sock(sk);
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- err = put_user(amount, (int *)arg);
+ err = put_user(amount, (int __user *)arg);
break;
case TIOCINQ:
}
}
release_sock(sk);
- err = put_user(amount, (int *)arg);
+ err = put_user(amount, (int __user *)arg);
break;
default:
return err;
}
-static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user __user *optval, int optlen, int flags)
+static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags)
{
struct sock *sk = sock->sk;
struct dn_scp *scp = DN_SK(sk);
unsigned char fctype;
long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
- if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE))
+ if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
return -EOPNOTSUPP;
if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
static int max_priority[] = { 127 }; /* From DECnet spec */
static int dn_forwarding_proc(ctl_table *, int, struct file *,
- void *, size_t *);
-static int dn_forwarding_sysctl(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
+ void __user *, size_t *);
+static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen,
void **context);
static struct dn_dev_sysctl_table {
static int dn_forwarding_proc(ctl_table *table, int write,
struct file *filep,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
#ifdef CONFIG_DECNET_ROUTER
struct net_device *dev = table->extra1;
#endif
}
-static int dn_forwarding_sysctl(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
+static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen,
void **context)
{
#ifdef CONFIG_DECNET_ROUTER
if (newlen != sizeof(int))
return -EINVAL;
- if (get_user(value, (int *)newval))
+ if (get_user(value, (int __user *)newval))
return -EFAULT;
if (value < 0)
return -EINVAL;
}
-int dn_dev_ioctl(unsigned int cmd, void *arg)
+int dn_dev_ioctl(unsigned int cmd, void __user *arg)
{
char buffer[DN_IFREQ_SIZE];
struct ifreq *ifr = (struct ifreq *)buffer;
return NET_RX_DROP;
}
-static int dn_output(struct sk_buff *skb)
+static int dn_output(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
struct dst_entry *dst = skb->dst;
struct dn_route *rt = (struct dn_route *)dst;
struct net_device *dev = dst->dev;
return NET_RX_BAD;
}
+static int dn_rt_bug_out(struct sk_buff **pskb)
+{
+ return dn_rt_bug(*pskb);
+}
+
static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
{
struct dn_fib_info *fi = res->fi;
rt->u.dst.neighbour = neigh;
rt->u.dst.dev = out_dev;
rt->u.dst.lastuse = jiffies;
- rt->u.dst.output = dn_rt_bug;
+ rt->u.dst.output = dn_rt_bug_out;
switch(res.type) {
case RTN_UNICAST:
rt->u.dst.input = dn_forward;
}
-static int dn_node_address_strategy(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
+static int dn_node_address_strategy(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen,
void **context)
{
size_t len;
if (len) {
if (len != sizeof(unsigned short))
return -EINVAL;
- if (put_user(decnet_address, (unsigned short *)oldval))
+ if (put_user(decnet_address, (unsigned short __user *)oldval))
return -EFAULT;
}
}
if (newval && newlen) {
if (newlen != sizeof(unsigned short))
return -EINVAL;
- if (get_user(addr, (unsigned short *)newval))
+ if (get_user(addr, (unsigned short __user *)newval))
return -EFAULT;
dn_dev_devices_off();
static int dn_node_address_handler(ctl_table *table, int write,
struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
char addr[DN_ASCBUF_LEN];
size_t len;
}
-static int dn_def_dev_strategy(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
+static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen,
void **context)
{
size_t len;
static int dn_def_dev_handler(ctl_table *table, int write,
struct file * filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
size_t len;
struct net_device *dev;
return 0;
}
+#ifdef CONFIG_ECONET_NATIVE
/*
* Queue a transmit result for the user to be told about.
*/
kfree_skb(skb);
}
-#ifdef CONFIG_ECONET_NATIVE
/*
* Called by the Econet hardware driver when a packet transmit
* has completed. Tell the user.
struct ec_addr addr;
int err;
unsigned char port, cb;
- struct sk_buff *skb;
- struct ec_cb *eb;
-#ifdef CONFIG_ECONET_NATIVE
- unsigned short proto = 0;
-#endif
#ifdef CONFIG_ECONET_AUNUDP
struct msghdr udpmsg;
struct iovec iov[msg->msg_iovlen+1];
* Check the flags.
*/
- if (msg->msg_flags&~MSG_DONTWAIT)
- return(-EINVAL);
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
+ return -EINVAL;
/*
* Get and verify the address.
{
/* Real hardware Econet. We're not worthy etc. */
#ifdef CONFIG_ECONET_NATIVE
+ struct ec_cb *eb;
+ struct sk_buff *skb;
+ unsigned short proto = 0;
+
dev_hold(dev);
skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev),
/* tack our header on the front of the iovec */
size = sizeof(struct aunhdr);
+ /*
+ * XXX: that is b0rken. We can't mix userland and kernel pointers
+ * in iovec, since on a lot of platforms copy_from_user() will
+ * *not* work with the kernel and userland ones at the same time,
+ * regardless of what we do with set_fs(). And we are talking about
+ * econet-over-ethernet here, so "it's only ARM anyway" doesn't
+ * apply. Any suggestions on fixing that code? -- AV
+ */
iov[0].iov_base = (void *)&ah;
iov[0].iov_len = size;
for (i = 0; i < msg->msg_iovlen; i++) {
- void *base = msg->msg_iov[i].iov_base;
+ void __user *base = msg->msg_iov[i].iov_base;
size_t len = msg->msg_iov[i].iov_len;
/* Check it now since we switch to KERNEL_DS later. */
if ((err = verify_area(VERIFY_READ, base, len)) < 0)
* Handle Econet specific ioctls
*/
-static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg)
+static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
{
struct ifreq ifr;
struct ec_device *edev;
static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
+ void __user *argp = (void __user *)arg;
switch(cmd) {
case SIOCGSTAMP:
- return sock_get_timestamp(sk,(struct timeval __user *)arg);
+ return sock_get_timestamp(sk, argp);
case SIOCSIFADDR:
case SIOCGIFADDR:
- return ec_dev_ioctl(sock, cmd, (void *)arg);
+ return ec_dev_ioctl(sock, cmd, argp);
break;
default:
- return dev_ioctl(cmd,(void __user *) arg);
+ return dev_ioctl(cmd, argp);
}
/*NOTREACHED*/
return 0;
#include <linux/smp_lock.h>
SOCKOPS_WRAP(econet, PF_ECONET);
+#ifdef CONFIG_ECONET_AUNUDP
/*
* Find the listening socket, if any, for the given data.
*/
return sock_queue_rcv_skb(sk, skb);
}
-#ifdef CONFIG_ECONET_AUNUDP
-
/*
* Send an AUN protocol response.
*/
return 0;
}
-static int ah_output(struct sk_buff *skb)
+static int ah_output(struct sk_buff **pskb)
{
int err;
- struct dst_entry *dst = skb->dst;
+ struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
struct iphdr *iph, *top_iph;
struct ip_auth_hdr *ah;
char buf[60];
} tmp_iph;
- if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
- err = -EINVAL;
- goto error_nolock;
+ if ((*pskb)->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ if (err)
+ goto error_nolock;
}
spin_lock_bh(&x->lock);
- err = xfrm_check_output(x, skb, AF_INET);
+ err = xfrm_check_output(x, *pskb, AF_INET);
if (err)
goto error;
- iph = skb->nh.iph;
+ iph = (*pskb)->nh.iph;
if (x->props.mode) {
- top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+ top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
top_iph->ihl = 5;
top_iph->version = 4;
top_iph->tos = 0;
- top_iph->tot_len = htons(skb->len);
+ top_iph->tot_len = htons((*pskb)->len);
top_iph->frag_off = 0;
if (!(iph->frag_off&htons(IP_DF)))
__ip_select_ident(top_iph, dst, 0);
ah = (struct ip_auth_hdr*)(top_iph+1);
ah->nexthdr = IPPROTO_IPIP;
} else {
- memcpy(&tmp_iph, skb->data, iph->ihl*4);
- top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+ memcpy(&tmp_iph, (*pskb)->data, iph->ihl*4);
+ top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
memcpy(top_iph, &tmp_iph, iph->ihl*4);
iph = &tmp_iph.iph;
top_iph->tos = 0;
- top_iph->tot_len = htons(skb->len);
+ top_iph->tot_len = htons((*pskb)->len);
top_iph->frag_off = 0;
top_iph->ttl = 0;
top_iph->protocol = IPPROTO_AH;
ah->reserved = 0;
ah->spi = x->id.spi;
ah->seq_no = htonl(++x->replay.oseq);
- ahp->icv(ahp, skb, ah->auth_data);
+ ahp->icv(ahp, *pskb, ah->auth_data);
top_iph->tos = iph->tos;
top_iph->ttl = iph->ttl;
if (x->props.mode) {
if (x->props.flags & XFRM_STATE_NOECN)
IP_ECN_clear(top_iph);
top_iph->frag_off = iph->frag_off&~htons(IP_MF|IP_OFFSET);
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+ memset(&(IPCB(*pskb)->opt), 0, sizeof(struct ip_options));
} else {
top_iph->frag_off = iph->frag_off;
top_iph->daddr = iph->daddr;
}
ip_send_check(top_iph);
- skb->nh.raw = skb->data;
+ (*pskb)->nh.raw = (*pskb)->data;
- x->curlft.bytes += skb->len;
+ x->curlft.bytes += (*pskb)->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
- if ((skb->dst = dst_pop(dst)) == NULL) {
+ if (((*pskb)->dst = dst_pop(dst)) == NULL) {
err = -EHOSTUNREACH;
goto error_nolock;
}
error:
spin_unlock_bh(&x->lock);
error_nolock:
- kfree_skb(skb);
+ kfree_skb(*pskb);
return err;
}
__u8 proto;
};
-int esp_output(struct sk_buff *skb)
+int esp_output(struct sk_buff **pskb)
{
int err;
- struct dst_entry *dst = skb->dst;
+ struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
struct iphdr *iph, *top_iph;
struct ip_esp_hdr *esph;
char buf[60];
} tmp_iph;
- /* First, if the skb is not checksummed, complete checksum. */
- if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
- err = -EINVAL;
- goto error_nolock;
+ if ((*pskb)->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ if (err)
+ goto error_nolock;
}
spin_lock_bh(&x->lock);
- err = xfrm_check_output(x, skb, AF_INET);
+ err = xfrm_check_output(x, *pskb, AF_INET);
if (err)
goto error;
err = -ENOMEM;
/* Strip IP header in transport mode. Save it. */
if (!x->props.mode) {
- iph = skb->nh.iph;
+ iph = (*pskb)->nh.iph;
memcpy(&tmp_iph, iph, iph->ihl*4);
- __skb_pull(skb, iph->ihl*4);
+ __skb_pull(*pskb, iph->ihl*4);
}
/* Now skb is pure payload to encrypt */
/* Round to block size */
- clen = skb->len;
+ clen = (*pskb)->len;
esp = x->data;
alen = esp->auth.icv_trunc_len;
if (esp->conf.padlen)
clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
- if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
+ if ((nfrags = skb_cow_data(*pskb, clen-(*pskb)->len+alen, &trailer)) < 0)
goto error;
/* Fill padding... */
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i=0; i<clen-(*pskb)->len - 2; i++)
*(u8*)(trailer->tail + i) = i+1;
} while (0);
- *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
- pskb_put(skb, trailer, clen - skb->len);
+ *(u8*)(trailer->tail + clen-(*pskb)->len - 2) = (clen - (*pskb)->len)-2;
+ pskb_put(*pskb, trailer, clen - (*pskb)->len);
encap = x->encap;
- iph = skb->nh.iph;
+ iph = (*pskb)->nh.iph;
if (x->props.mode) {
- top_iph = (struct iphdr*)skb_push(skb, x->props.header_len);
+ top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
esph = (struct ip_esp_hdr*)(top_iph+1);
if (encap && encap->encap_type) {
switch (encap->encap_type) {
top_iph->tos = iph->tos; /* DS disclosed */
if (x->props.flags & XFRM_STATE_NOECN)
IP_ECN_clear(top_iph);
- top_iph->tot_len = htons(skb->len + alen);
+ top_iph->tot_len = htons((*pskb)->len + alen);
top_iph->frag_off = iph->frag_off&htons(IP_DF);
if (!(top_iph->frag_off))
ip_select_ident(top_iph, dst, 0);
top_iph->check = 0;
top_iph->saddr = x->props.saddr.a4;
top_iph->daddr = x->id.daddr.a4;
- memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+ memset(&(IPCB(*pskb)->opt), 0, sizeof(struct ip_options));
} else {
- esph = (struct ip_esp_hdr*)skb_push(skb, x->props.header_len);
- top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4);
+ esph = (struct ip_esp_hdr*)skb_push(*pskb, x->props.header_len);
+ top_iph = (struct iphdr*)skb_push(*pskb, iph->ihl*4);
memcpy(top_iph, &tmp_iph, iph->ihl*4);
if (encap && encap->encap_type) {
switch (encap->encap_type) {
} else
top_iph->protocol = IPPROTO_ESP;
iph = &tmp_iph.iph;
- top_iph->tot_len = htons(skb->len + alen);
+ top_iph->tot_len = htons((*pskb)->len + alen);
top_iph->check = 0;
top_iph->frag_off = iph->frag_off;
*(u8*)(trailer->tail - 1) = iph->protocol;
if (encap && uh) {
uh->source = encap->encap_sport;
uh->dest = encap->encap_dport;
- uh->len = htons(skb->len + alen - sizeof(struct iphdr));
+ uh->len = htons((*pskb)->len + alen - sizeof(struct iphdr));
uh->check = 0;
}
if (!sg)
goto error;
}
- skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+ skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
crypto_cipher_encrypt(tfm, sg, sg, clen);
if (unlikely(sg != sgbuf))
kfree(sg);
}
if (esp->auth.icv_full_len) {
- esp->auth.icv(esp, skb, (u8*)esph-skb->data,
+ esp->auth.icv(esp, *pskb, (u8*)esph-(*pskb)->data,
sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
- pskb_put(skb, trailer, alen);
+ pskb_put(*pskb, trailer, alen);
}
ip_send_check(top_iph);
- skb->nh.raw = skb->data;
+ (*pskb)->nh.raw = (*pskb)->data;
- x->curlft.bytes += skb->len;
+ x->curlft.bytes += (*pskb)->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
- if ((skb->dst = dst_pop(dst)) == NULL) {
+ if (((*pskb)->dst = dst_pop(dst)) == NULL) {
err = -EHOSTUNREACH;
goto error_nolock;
}
error:
spin_unlock_bh(&x->lock);
error_nolock:
- kfree_skb(skb);
+ kfree_skb(*pskb);
return err;
}
ip_finish_output2);
}
-int ip_mc_output(struct sk_buff *skb)
+int ip_mc_output(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
struct sock *sk = skb->sk;
struct rtable *rt = (struct rtable*)skb->dst;
struct net_device *dev = rt->u.dst.dev;
&& ((rt->rt_flags&RTCF_LOCAL) || !(IPCB(skb)->flags&IPSKB_FORWARDED))
#endif
) {
- struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);
+ struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
if (newskb)
NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
newskb->dev,
}
if (rt->rt_flags&RTCF_BROADCAST) {
- struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);
+ struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
if (newskb)
NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
newskb->dev, ip_dev_loopback_xmit);
return ip_finish_output(skb);
}
-int ip_output(struct sk_buff *skb)
+int ip_output(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
+
IP_INC_STATS(OutRequests);
if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list) &&
err = ip_mc_join_group(sk, &mreq);
if (err)
break;
+ greqs.gsr_interface = mreq.imr_ifindex;
omode = MCAST_INCLUDE;
add = 1;
} else /* MCAST_LEAVE_SOURCE_GROUP */ {
skb->nh.raw = skb->data;
}
-static int ipcomp_output(struct sk_buff *skb)
+static int ipcomp_output(struct sk_buff **pskb)
{
int err;
- struct dst_entry *dst = skb->dst;
+ struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
struct iphdr *iph, *top_iph;
struct ip_comp_hdr *ipch;
} tmp_iph;
int hdr_len = 0;
- if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
- err = -EINVAL;
- goto error_nolock;
+ if ((*pskb)->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ if (err)
+ goto error_nolock;
}
spin_lock_bh(&x->lock);
- err = xfrm_check_output(x, skb, AF_INET);
+ err = xfrm_check_output(x, *pskb, AF_INET);
if (err)
goto error;
/* Don't bother compressing */
if (!x->props.mode) {
- iph = skb->nh.iph;
+ iph = (*pskb)->nh.iph;
hdr_len = iph->ihl * 4;
}
- if ((skb->len - hdr_len) < ipcd->threshold) {
+ if (((*pskb)->len - hdr_len) < ipcd->threshold) {
if (x->props.mode) {
- ipcomp_tunnel_encap(x, skb);
- iph = skb->nh.iph;
+ ipcomp_tunnel_encap(x, *pskb);
+ iph = (*pskb)->nh.iph;
iph->protocol = IPPROTO_IPIP;
ip_send_check(iph);
}
}
if (x->props.mode)
- ipcomp_tunnel_encap(x, skb);
+ ipcomp_tunnel_encap(x, *pskb);
- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
+ if ((skb_is_nonlinear(*pskb) || skb_cloned(*pskb)) &&
+ skb_linearize(*pskb, GFP_ATOMIC) != 0) {
err = -ENOMEM;
goto error;
}
- err = ipcomp_compress(x, skb);
+ err = ipcomp_compress(x, *pskb);
if (err) {
if (err == -EMSGSIZE) {
if (x->props.mode) {
- iph = skb->nh.iph;
+ iph = (*pskb)->nh.iph;
iph->protocol = IPPROTO_IPIP;
ip_send_check(iph);
}
}
/* Install ipcomp header, convert into ipcomp datagram. */
- iph = skb->nh.iph;
+ iph = (*pskb)->nh.iph;
memcpy(&tmp_iph, iph, iph->ihl * 4);
- top_iph = (struct iphdr *)skb_push(skb, sizeof(struct ip_comp_hdr));
+ top_iph = (struct iphdr *)skb_push(*pskb, sizeof(struct ip_comp_hdr));
memcpy(top_iph, &tmp_iph, iph->ihl * 4);
iph = top_iph;
if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
IP_ECN_clear(iph);
- iph->tot_len = htons(skb->len);
+ iph->tot_len = htons((*pskb)->len);
iph->protocol = IPPROTO_COMP;
iph->check = 0;
ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4);
ipch->flags = 0;
ipch->cpi = htons((u16 )ntohl(x->id.spi));
ip_send_check(iph);
- skb->nh.raw = skb->data;
+ (*pskb)->nh.raw = (*pskb)->data;
out_ok:
- x->curlft.bytes += skb->len;
+ x->curlft.bytes += (*pskb)->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
- if ((skb->dst = dst_pop(dst)) == NULL) {
+ if (((*pskb)->dst = dst_pop(dst)) == NULL) {
err = -EHOSTUNREACH;
goto error_nolock;
}
error:
spin_unlock_bh(&x->lock);
error_nolock:
- kfree_skb(skb);
+ kfree_skb(*pskb);
goto out_exit;
}
* The IP multicast ioctl support routines.
*/
-int ipmr_ioctl(struct sock *sk, int cmd, unsigned long arg)
+int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
{
struct sioc_sg_req sr;
struct sioc_vif_req vr;
switch(cmd)
{
case SIOCGETVIFCNT:
- if (copy_from_user(&vr,(void *)arg,sizeof(vr)))
+ if (copy_from_user(&vr,arg,sizeof(vr)))
return -EFAULT;
if(vr.vifi>=maxvif)
return -EINVAL;
vr.obytes=vif->bytes_out;
read_unlock(&mrt_lock);
- if (copy_to_user((void *)arg,&vr,sizeof(vr)))
+ if (copy_to_user(arg,&vr,sizeof(vr)))
return -EFAULT;
return 0;
}
read_unlock(&mrt_lock);
return -EADDRNOTAVAIL;
case SIOCGETSGCNT:
- if (copy_from_user(&sr,(void *)arg,sizeof(sr)))
+ if (copy_from_user(&sr,arg,sizeof(sr)))
return -EFAULT;
read_lock(&mrt_lock);
sr.wrong_if = c->mfc_un.res.wrong_if;
read_unlock(&mrt_lock);
- if (copy_to_user((void *)arg,&sr,sizeof(sr)))
+ if (copy_to_user(arg,&sr,sizeof(sr)))
return -EFAULT;
return 0;
}
if (skb->nfcache & NFC_IPVS_PROPERTY)
return NF_ACCEPT;
+ if (skb->ip_summed == CHECKSUM_HW) {
+ if (skb_checksum_help(pskb, (out == NULL)))
+ return NF_DROP;
+ if (skb != *pskb)
+ skb = *pskb;
+ }
+
iph = skb->nh.iph;
if (unlikely(iph->protocol == IPPROTO_ICMP)) {
int related, verdict = ip_vs_out_icmp(pskb, &related);
return NF_ACCEPT;
}
+ if (skb->ip_summed == CHECKSUM_HW) {
+ if (skb_checksum_help(pskb, (out == NULL)))
+ return NF_DROP;
+ if (skb != *pskb)
+ skb = *pskb;
+ }
+
iph = skb->nh.iph;
if (unlikely(iph->protocol == IPPROTO_ICMP)) {
int related, verdict = ip_vs_in_icmp(pskb, &related);
static int
proc_do_defense_mode(ctl_table *table, int write, struct file * filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
int *valp = table->data;
int val = *valp;
static int
proc_do_sync_threshold(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
int *valp = table->data;
int val[2];
return 0;
}
- /* Look for ifname matches; this should unroll nicely. */
- for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
- ret |= (((const unsigned long *)indev)[i]
- ^ ((const unsigned long *)arpinfo->iniface)[i])
- & ((const unsigned long *)arpinfo->iniface_mask)[i];
+ /* Look for ifname matches. */
+ for (i = 0, ret = 0; i < IFNAMSIZ; i++) {
+ ret |= (indev[i] ^ arpinfo->iniface[i])
+ & arpinfo->iniface_mask[i];
}
if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
}
#endif
-static inline struct arpt_table *find_table_lock(const char *name, int *error, struct semaphore *mutex)
+static inline struct arpt_table *arpt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
{
return find_inlist_lock(&arpt_tables, name, "arptable_", error, mutex);
}
-static inline struct arpt_target *find_target_lock(const char *name, int *error, struct semaphore *mutex)
+struct arpt_target *arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
{
return find_inlist_lock(&arpt_target, name, "arpt_", error, mutex);
}
}
t = arpt_get_target(e);
- target = find_target_lock(t->u.user.name, &ret, &arpt_mutex);
+ target = arpt_find_target_lock(t->u.user.name, &ret, &arpt_mutex);
if (!target) {
duprintf("check_entry: `%s' not found\n", t->u.user.name);
goto out;
int ret;
struct arpt_table *t;
- t = find_table_lock(entries->name, &ret, &arpt_mutex);
+ t = arpt_find_table_lock(entries->name, &ret, &arpt_mutex);
if (t) {
duprintf("t->private->number = %u\n",
t->private->number);
duprintf("arp_tables: Translated table\n");
- t = find_table_lock(tmp.name, &ret, &arpt_mutex);
+ t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
if (!t)
goto free_newinfo_counters_untrans;
goto free;
}
- t = find_table_lock(tmp.name, &ret, &arpt_mutex);
+ t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex);
if (!t)
goto free;
break;
}
name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
- t = find_table_lock(name, &ret, &arpt_mutex);
+ t = arpt_find_table_lock(name, &ret, &arpt_mutex);
if (t) {
struct arpt_getinfo info;
EXPORT_SYMBOL(arpt_register_table);
EXPORT_SYMBOL(arpt_unregister_table);
EXPORT_SYMBOL(arpt_do_table);
+EXPORT_SYMBOL(arpt_find_target_lock);
EXPORT_SYMBOL(arpt_register_target);
EXPORT_SYMBOL(arpt_unregister_target);
ip_conntrack_destroyed(ct);
WRITE_LOCK(&ip_conntrack_lock);
- /* Delete us from our own list to prevent corruption later */
- list_del(&ct->sibling_list);
+ /* Make sure don't leave any orphaned expectations lying around */
+ if (ct->expecting)
+ remove_expectations(ct, 1);
/* Delete our master expectation */
if (ct->master) {
DUMP_TUPLE(newreply);
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
- if (!conntrack->master)
- conntrack->helper = LIST_FIND(&helpers, helper_cmp,
- struct ip_conntrack_helper *,
- newreply);
+ if (!conntrack->master && list_empty(&conntrack->sibling_list))
+ conntrack->helper = ip_ct_find_helper(newreply);
WRITE_UNLOCK(&ip_conntrack_lock);
return 1;
if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &tcph, sizeof(tcph)) != 0)
return -1;
+ if (skb->len < skb->nh.iph->ihl * 4 + tcph.doff * 4)
+ return -1;
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
/* Assume worse case: any hook could change packet */
(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
if ((*pskb)->ip_summed == CHECKSUM_HW)
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ if (skb_checksum_help(pskb, (out == NULL)))
+ return NF_DROP;
switch (hooknum) {
case NF_IP_PRE_ROUTING:
/* If we had a hardware checksum before, it's now invalid */
if ((*pskb)->ip_summed == CHECKSUM_HW)
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ if (skb_checksum_help(pskb, (out == NULL)))
+ return NF_DROP;
ct = ip_conntrack_get(*pskb, &ctinfo);
/* Can't track? It's not due to stress, or conntrack would
#endif
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
-/* Mutex protects lists (only traversed in user context). */
-static DECLARE_MUTEX(ipt_mutex);
-
/* Must have mutex */
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
{
void *ret;
-#if 0
+#if 0
duprintf("find_inlist: searching for `%s' in %s.\n",
name, head == &ipt_target ? "ipt_target"
: head == &ipt_match ? "ipt_match"
#endif
static inline struct ipt_table *
-find_table_lock(const char *name, int *error, struct semaphore *mutex)
+ipt_find_table_lock(const char *name, int *error, struct semaphore *mutex)
{
return find_inlist_lock(&ipt_tables, name, "iptable_", error, mutex);
}
return find_inlist_lock(&ipt_match, name, "ipt_", error, mutex);
}
-static inline struct ipt_target *
-find_target_lock(const char *name, int *error, struct semaphore *mutex)
+struct ipt_target *
+ipt_find_target_lock(const char *name, int *error, struct semaphore *mutex)
{
return find_inlist_lock(&ipt_target, name, "ipt_", error, mutex);
}
goto cleanup_matches;
t = ipt_get_target(e);
- target = find_target_lock(t->u.user.name, &ret, &ipt_mutex);
+ target = ipt_find_target_lock(t->u.user.name, &ret, &ipt_mutex);
if (!target) {
duprintf("check_entry: `%s' not found\n", t->u.user.name);
goto cleanup_matches;
int ret;
struct ipt_table *t;
- t = find_table_lock(entries->name, &ret, &ipt_mutex);
+ t = ipt_find_table_lock(entries->name, &ret, &ipt_mutex);
if (t) {
duprintf("t->private->number = %u\n",
t->private->number);
duprintf("ip_tables: Translated table\n");
- t = find_table_lock(tmp.name, &ret, &ipt_mutex);
+ t = ipt_find_table_lock(tmp.name, &ret, &ipt_mutex);
if (!t)
goto free_newinfo_counters_untrans;
goto free;
}
- t = find_table_lock(tmp.name, &ret, &ipt_mutex);
+ t = ipt_find_table_lock(tmp.name, &ret, &ipt_mutex);
if (!t)
goto free;
break;
}
name[IPT_TABLE_MAXNAMELEN-1] = '\0';
- t = find_table_lock(name, &ret, &ipt_mutex);
+ t = ipt_find_table_lock(name, &ret, &ipt_mutex);
if (t) {
struct ipt_getinfo info;
EXPORT_SYMBOL(ipt_do_table);
EXPORT_SYMBOL(ipt_register_target);
EXPORT_SYMBOL(ipt_unregister_target);
+EXPORT_SYMBOL(ipt_find_target_lock);
module_init(init);
module_exit(fini);
/* Return 0 if there was an error. */
static inline int
-set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
+set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward)
{
struct tcphdr tcph;
u_int16_t diffs[2];
if (!skb_ip_make_writable(pskb,
(*pskb)->nh.iph->ihl*4+sizeof(tcph)))
return 0;
- tcph.check = csum_fold(csum_partial((char *)diffs,
- sizeof(diffs),
- tcph.check^0xFFFF));
+ if ((*pskb)->ip_summed != CHECKSUM_HW)
+ tcph.check = csum_fold(csum_partial((char *)diffs,
+ sizeof(diffs),
+ tcph.check^0xFFFF));
memcpy((*pskb)->data + (*pskb)->nh.iph->ihl*4,
&tcph, sizeof(tcph));
+ if ((*pskb)->ip_summed == CHECKSUM_HW)
+ if (skb_checksum_help(pskb, inward))
+ return 0;
(*pskb)->nfcache |= NFC_ALTERED;
}
return 1;
if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
&& (*pskb)->nh.iph->protocol == IPPROTO_TCP)
- if (!set_ect_tcp(pskb, einfo))
+ if (!set_ect_tcp(pskb, einfo, (out == NULL)))
return NF_DROP;
return IPT_CONTINUE;
newmss);
retmodified:
- /* If we had a hardware checksum before, it's now invalid */
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ /* We never hw checksum SYN packets. */
+ BUG_ON((*pskb)->ip_summed == CHECKSUM_HW);
+
(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
return IPT_CONTINUE;
}
* clear -- Flush table, remove all entries
*/
-static int ip_recent_ctrl(struct file *file, const char *input, unsigned long size, void *data)
+static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned long size, void *data)
{
static const u_int32_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
u_int32_t val;
default:
#ifdef CONFIG_IP_MROUTE
- return ipmr_ioctl(sk, cmd, arg);
+ return ipmr_ioctl(sk, cmd, (void __user *)arg);
#else
return -ENOIOCTLCMD;
#endif
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
static void ipv4_dst_destroy(struct dst_entry *dst);
+static void ipv4_dst_ifdown(struct dst_entry *dst, int how);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
.gc = rt_garbage_collect,
.check = ipv4_dst_check,
.destroy = ipv4_dst_destroy,
+ .ifdown = ipv4_dst_ifdown,
.negative_advice = ipv4_negative_advice,
.link_failure = ipv4_link_failure,
.update_pmtu = ip_rt_update_pmtu,
}
}
+static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
+{
+ struct rtable *rt = (struct rtable *) dst;
+ struct in_device *idev = rt->idev;
+ if (idev) {
+ rt->idev = NULL;
+ in_dev_put(idev);
+ }
+}
+
static void ipv4_link_failure(struct sk_buff *skb)
{
struct rtable *rt;
dst_set_expires(&rt->u.dst, 0);
}
-static int ip_rt_bug(struct sk_buff *skb)
+static int ip_rt_bug(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
+
printk(KERN_DEBUG "ip_rt_bug: %u.%u.%u.%u -> %u.%u.%u.%u, %s\n",
NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr),
skb->dev ? skb->dev->name : "?");
atomic_t tcp_orphan_count = ATOMIC_INIT(0);
-int sysctl_tcp_default_win_scale;
+int sysctl_tcp_default_win_scale = 7;
int sysctl_tcp_mem[3];
int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
mask |= POLLIN | POLLRDNORM;
if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
- if (tcp_wspace(sk) >= tcp_min_write_space(sk)) {
+ if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
mask |= POLLOUT | POLLWRNORM;
} else { /* send SIGIO later */
set_bit(SOCK_ASYNC_NOSPACE,
* wspace test but before the flags are set,
* IO signal will be lost.
*/
- if (tcp_wspace(sk) >= tcp_min_write_space(sk))
+ if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
mask |= POLLOUT | POLLWRNORM;
}
}
return mask;
}
-/*
- * TCP socket write_space callback.
- */
-void tcp_write_space(struct sock *sk)
-{
- struct socket *sock = sk->sk_socket;
-
- if (tcp_wspace(sk) >= tcp_min_write_space(sk) && sock) {
- clear_bit(SOCK_NOSPACE, &sock->flags);
-
- if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
- wake_up_interruptible(sk->sk_sleep);
-
- if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
- sock_wake_async(sock, 2, POLL_OUT);
- }
-}
-
int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
struct tcp_opt *tp = tcp_sk(sk);
local_bh_enable();
sock_put(child);
- tcp_acceptq_removed(sk);
+ sk_acceptq_removed(sk);
tcp_openreq_fastfree(req);
}
BUG_TRAP(!sk->sk_ack_backlog);
TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
TCP_SKB_CB(skb)->sacked = 0;
__skb_queue_tail(&sk->sk_write_queue, skb);
- tcp_charge_skb(sk, skb);
+ sk_charge_skb(sk, skb);
if (!tp->send_head)
tp->send_head = skb;
else if (tp->nonagle&TCP_NAGLE_PUSH)
return -EAGAIN;
}
-/*
- * Release a skb if it is no longer needed. This routine
- * must be called with interrupts disabled or with the
- * socket locked so that the sk_buff queue operation is ok.
- */
-
-static inline void tcp_eat_skb(struct sock *sk, struct sk_buff *skb)
-{
- __skb_unlink(skb, &sk->sk_receive_queue);
- __kfree_skb(skb);
-}
-
/* Clean up the receive buffer for full frames taken by the user,
* then send an ACK if necessary. COPIED is the number of bytes
* tcp_recvmsg has given to the user so far, it speeds up the
tcp_send_ack(sk);
}
-/* Now socket state including sk->sk_err is changed only under lock,
- * hence we may omit checks after joining wait queue.
- * We check receive queue before schedule() only as optimization;
- * it is very likely that release_sock() added new data.
- */
-
-static long tcp_data_wait(struct sock *sk, long timeo)
-{
- DEFINE_WAIT(wait);
-
- prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
-
- set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- release_sock(sk);
-
- if (skb_queue_empty(&sk->sk_receive_queue))
- timeo = schedule_timeout(timeo);
-
- lock_sock(sk);
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
-
- finish_wait(sk->sk_sleep, &wait);
- return timeo;
-}
-
static void tcp_prequeue_process(struct sock *sk)
{
struct sk_buff *skb;
break;
}
if (skb->h.th->fin) {
- tcp_eat_skb(sk, skb);
+ sk_eat_skb(sk, skb);
++seq;
break;
}
- tcp_eat_skb(sk, skb);
+ sk_eat_skb(sk, skb);
if (!desc->count)
break;
}
/* Do not sleep, just process backlog. */
release_sock(sk);
lock_sock(sk);
- } else {
- timeo = tcp_data_wait(sk, timeo);
- }
+ } else
+ sk_wait_data(sk, &timeo);
if (user_recv) {
int chunk;
if (skb->h.th->fin)
goto found_fin_ok;
if (!(flags & MSG_PEEK))
- tcp_eat_skb(sk, skb);
+ sk_eat_skb(sk, skb);
continue;
found_fin_ok:
/* Process the FIN. */
++*seq;
if (!(flags & MSG_PEEK))
- tcp_eat_skb(sk, skb);
+ sk_eat_skb(sk, skb);
break;
} while (len > 0);
tp->accept_queue_tail = NULL;
newsk = req->sk;
- tcp_acceptq_removed(sk);
+ sk_acceptq_removed(sk);
tcp_openreq_fastfree(req);
BUG_TRAP(newsk->sk_state != TCP_SYN_RECV);
release_sock(sk);
break;
case TCP_INFO: {
struct tcp_info info;
- u32 now = tcp_time_stamp;
if (get_user(len, optlen))
return -EFAULT;
- info.tcpi_state = sk->sk_state;
- info.tcpi_ca_state = tp->ca_state;
- info.tcpi_retransmits = tp->retransmits;
- info.tcpi_probes = tp->probes_out;
- info.tcpi_backoff = tp->backoff;
- info.tcpi_options = 0;
- if (tp->tstamp_ok)
- info.tcpi_options |= TCPI_OPT_TIMESTAMPS;
- if (tp->sack_ok)
- info.tcpi_options |= TCPI_OPT_SACK;
- if (tp->wscale_ok) {
- info.tcpi_options |= TCPI_OPT_WSCALE;
- info.tcpi_snd_wscale = tp->snd_wscale;
- info.tcpi_rcv_wscale = tp->rcv_wscale;
- } else {
- info.tcpi_snd_wscale = 0;
- info.tcpi_rcv_wscale = 0;
- }
- if (tp->ecn_flags & TCP_ECN_OK)
- info.tcpi_options |= TCPI_OPT_ECN;
-
- info.tcpi_rto = (1000000 * tp->rto) / HZ;
- info.tcpi_ato = (1000000 * tp->ack.ato) / HZ;
- info.tcpi_snd_mss = tp->mss_cache_std;
- info.tcpi_rcv_mss = tp->ack.rcv_mss;
-
- info.tcpi_unacked = tp->packets_out;
- info.tcpi_sacked = tp->sacked_out;
- info.tcpi_lost = tp->lost_out;
- info.tcpi_retrans = tp->retrans_out;
- info.tcpi_fackets = tp->fackets_out;
-
- info.tcpi_last_data_sent = ((now - tp->lsndtime) * 1000) / HZ;
- info.tcpi_last_ack_sent = 0;
- info.tcpi_last_data_recv = ((now -
- tp->ack.lrcvtime) * 1000) / HZ;
- info.tcpi_last_ack_recv = ((now - tp->rcv_tstamp) * 1000) / HZ;
-
- info.tcpi_pmtu = tp->pmtu_cookie;
- info.tcpi_rcv_ssthresh = tp->rcv_ssthresh;
- info.tcpi_rtt = ((1000000 * tp->srtt) / HZ) >> 3;
- info.tcpi_rttvar = ((1000000 * tp->mdev) / HZ) >> 2;
- info.tcpi_snd_ssthresh = tp->snd_ssthresh;
- info.tcpi_snd_cwnd = tp->snd_cwnd;
- info.tcpi_advmss = tp->advmss;
- info.tcpi_reordering = tp->reordering;
+
+ tcp_get_info(sk, &info);
len = min_t(unsigned int, len, sizeof(info));
if (put_user(len, optlen))
EXPORT_SYMBOL(tcp_sockets_allocated);
EXPORT_SYMBOL(tcp_statistics);
EXPORT_SYMBOL(tcp_timewait_cachep);
-EXPORT_SYMBOL(tcp_write_space);
EXPORT_SYMBOL_GPL(cleanup_rbuf);
rta->rta_len = rtalen; \
RTA_DATA(rta); })
+/* Return information about state of tcp endpoint in API format. */
+void tcp_get_info(struct sock *sk, struct tcp_info *info)
+{
+ struct tcp_opt *tp = tcp_sk(sk);
+ u32 now = tcp_time_stamp;
+
+ memset(info, 0, sizeof(*info));
+
+ info->tcpi_state = sk->sk_state;
+ info->tcpi_ca_state = tp->ca_state;
+ info->tcpi_retransmits = tp->retransmits;
+ info->tcpi_probes = tp->probes_out;
+ info->tcpi_backoff = tp->backoff;
+
+ if (tp->tstamp_ok)
+ info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
+ if (tp->sack_ok)
+ info->tcpi_options |= TCPI_OPT_SACK;
+ if (tp->wscale_ok) {
+ info->tcpi_options |= TCPI_OPT_WSCALE;
+ info->tcpi_snd_wscale = tp->snd_wscale;
+ info->tcpi_rcv_wscale = tp->rcv_wscale;
+ }
+
+ if (tp->ecn_flags&TCP_ECN_OK)
+ info->tcpi_options |= TCPI_OPT_ECN;
+
+ info->tcpi_rto = (1000000*tp->rto)/HZ;
+ info->tcpi_ato = (1000000*tp->ack.ato)/HZ;
+ info->tcpi_snd_mss = tp->mss_cache;
+ info->tcpi_rcv_mss = tp->ack.rcv_mss;
+
+ info->tcpi_unacked = tp->packets_out;
+ info->tcpi_sacked = tp->sacked_out;
+ info->tcpi_lost = tp->lost_out;
+ info->tcpi_retrans = tp->retrans_out;
+ info->tcpi_fackets = tp->fackets_out;
+
+ info->tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ;
+ info->tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ;
+ info->tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ;
+
+ info->tcpi_pmtu = tp->pmtu_cookie;
+ info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
+ info->tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3;
+ info->tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2;
+ info->tcpi_snd_ssthresh = tp->snd_ssthresh;
+ info->tcpi_snd_cwnd = tp->snd_cwnd;
+ info->tcpi_advmss = tp->advmss;
+ info->tcpi_reordering = tp->reordering;
+
+ info->tcpi_rcv_rtt = ((1000000*tp->rcv_rtt_est.rtt)/HZ)>>3;
+ info->tcpi_rcv_space = tp->rcvq_space.space;
+}
+
static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
int ext, u32 pid, u32 seq)
{
minfo->tcpdiag_tmem = atomic_read(&sk->sk_wmem_alloc);
}
- if (info) {
- u32 now = tcp_time_stamp;
-
- info->tcpi_state = sk->sk_state;
- info->tcpi_ca_state = tp->ca_state;
- info->tcpi_retransmits = tp->retransmits;
- info->tcpi_probes = tp->probes_out;
- info->tcpi_backoff = tp->backoff;
- info->tcpi_options = 0;
- if (tp->tstamp_ok)
- info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
- if (tp->sack_ok)
- info->tcpi_options |= TCPI_OPT_SACK;
- if (tp->wscale_ok) {
- info->tcpi_options |= TCPI_OPT_WSCALE;
- info->tcpi_snd_wscale = tp->snd_wscale;
- info->tcpi_rcv_wscale = tp->rcv_wscale;
- } else {
- info->tcpi_snd_wscale = 0;
- info->tcpi_rcv_wscale = 0;
- }
- if (tp->ecn_flags&TCP_ECN_OK)
- info->tcpi_options |= TCPI_OPT_ECN;
-
- info->tcpi_rto = (1000000*tp->rto)/HZ;
- info->tcpi_ato = (1000000*tp->ack.ato)/HZ;
- info->tcpi_snd_mss = tp->mss_cache;
- info->tcpi_rcv_mss = tp->ack.rcv_mss;
-
- info->tcpi_unacked = tp->packets_out;
- info->tcpi_sacked = tp->sacked_out;
- info->tcpi_lost = tp->lost_out;
- info->tcpi_retrans = tp->retrans_out;
- info->tcpi_fackets = tp->fackets_out;
-
- info->tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ;
- info->tcpi_last_ack_sent = 0;
- info->tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ;
- info->tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ;
-
- info->tcpi_pmtu = tp->pmtu_cookie;
- info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
- info->tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3;
- info->tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2;
- info->tcpi_snd_ssthresh = tp->snd_ssthresh;
- info->tcpi_snd_cwnd = tp->snd_cwnd;
- info->tcpi_advmss = tp->advmss;
- info->tcpi_reordering = tp->reordering;
- }
+ if (info)
+ tcp_get_info(sk, info);
if (vinfo) {
vinfo->tcpv_enabled = tp->vegas.doing_vegas_now;
int sysctl_tcp_westwood;
int sysctl_tcp_vegas_cong_avoid;
-int sysctl_tcp_moderate_rcvbuf;
+int sysctl_tcp_moderate_rcvbuf = 1;
/* Default values of the Vegas variables, in fixed-point representation
* with V_PARAM_SHIFT bits to the right of the binary point.
int sysctl_tcp_vegas_alpha = 1<<V_PARAM_SHIFT;
int sysctl_tcp_vegas_beta = 3<<V_PARAM_SHIFT;
int sysctl_tcp_vegas_gamma = 1<<V_PARAM_SHIFT;
-int sysctl_tcp_bic;
+int sysctl_tcp_bic = 1;
int sysctl_tcp_bic_fast_convergence = 1;
int sysctl_tcp_bic_low_window = 14;
tp->rcvq_space.space = space;
if (sysctl_tcp_moderate_rcvbuf) {
+ int new_clamp = space;
+
/* Receive space grows, normalize in order to
* take into account packet headers and sk_buff
* structure overhead.
space = 1;
rcvmem = (tp->advmss + MAX_TCP_HEADER +
16 + sizeof(struct sk_buff));
+ while (tcp_win_from_space(rcvmem) < tp->advmss)
+ rcvmem += 128;
space *= rcvmem;
space = min(space, sysctl_tcp_rmem[2]);
- if (space > sk->sk_rcvbuf)
+ if (space > sk->sk_rcvbuf) {
sk->sk_rcvbuf = space;
+
+ /* Make the window clamp follow along. */
+ tp->window_clamp = new_clamp;
+ }
}
}
* clogging syn queue with openreqs with exponentially increasing
* timeout.
*/
- if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+ if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
goto drop;
req = tcp_openreq_alloc();
struct tcp_opt *newtp;
struct sock *newsk;
- if (tcp_acceptq_is_full(sk))
+ if (sk_acceptq_is_full(sk))
goto exit_overflow;
if (!dst && (dst = tcp_v4_route_req(sk, req)) == NULL)
sk->sk_state = TCP_CLOSE;
- sk->sk_write_space = tcp_write_space;
+ sk->sk_write_space = sk_stream_write_space;
sk->sk_use_write_queue = 1;
tp->af_specific = &ipv4_specific;
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
newsk->sk_callback_lock = RW_LOCK_UNLOCKED;
skb_queue_head_init(&newsk->sk_error_queue);
- newsk->sk_write_space = tcp_write_space;
+ newsk->sk_write_space = sk_stream_write_space;
if ((filter = newsk->sk_filter) != NULL)
sk_filter_charge(newsk, filter);
/* Advance write_seq and place onto the write_queue. */
tp->write_seq = TCP_SKB_CB(skb)->end_seq;
__skb_queue_tail(&sk->sk_write_queue, skb);
- tcp_charge_skb(sk, skb);
+ sk_charge_skb(sk, skb);
/* Queue it, remembering where we must start sending. */
if (tp->send_head == NULL)
buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC);
if (buff == NULL)
return -ENOMEM; /* We'll just try again later. */
- tcp_charge_skb(sk, buff);
+ sk_charge_skb(sk, buff);
/* Correct the sequence numbers. */
TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
__skb_unlink(skb, &sk->sk_write_queue);
__skb_queue_head(&sk->sk_write_queue, nskb);
tcp_free_skb(sk, skb);
- tcp_charge_skb(sk, nskb);
+ sk_charge_skb(sk, nskb);
skb = nskb;
}
TCP_SKB_CB(buff)->when = tcp_time_stamp;
tp->retrans_stamp = TCP_SKB_CB(buff)->when;
__skb_queue_tail(&sk->sk_write_queue, buff);
- tcp_charge_skb(sk, buff);
+ sk_charge_skb(sk, buff);
tp->packets_out++;
tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
TCP_INC_STATS(TcpActiveOpens);
}
tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER;
tp->ack.timeout = timeout;
- if (!mod_timer(&tp->delack_timer, timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->delack_timer, timeout);
}
/* This routine sends an ack and also updates the window. */
struct tcp_opt *tp = tcp_sk(sk);
tp->pending = 0;
- if (timer_pending(&tp->retransmit_timer) &&
- del_timer(&tp->retransmit_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &tp->retransmit_timer);
tp->ack.pending = 0;
tp->ack.blocked = 0;
- if (timer_pending(&tp->delack_timer) &&
- del_timer(&tp->delack_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &tp->delack_timer);
- if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &sk->sk_timer);
}
static void tcp_write_err(struct sock *sk)
/* Try again later. */
tp->ack.blocked = 1;
NET_INC_STATS_BH(DelayedACKLocked);
- if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->delack_timer, jiffies + TCP_DELACK_MIN);
goto out_unlock;
}
goto out;
if (time_after(tp->ack.timeout, jiffies)) {
- if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
goto out;
}
tp->ack.pending &= ~TCP_ACK_TIMER;
bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
/* Try again later */
- if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20)))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->retransmit_timer, jiffies + (HZ / 20));
goto out_unlock;
}
goto out;
if (time_after(tp->timeout, jiffies)) {
- if (!mod_timer(&tp->retransmit_timer, tp->timeout))
- sock_hold(sk);
+ sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
goto out;
}
void tcp_delete_keepalive_timer (struct sock *sk)
{
- if (timer_pending(&sk->sk_timer) && del_timer (&sk->sk_timer))
- __sock_put(sk);
+ sk_stop_timer(sk, &sk->sk_timer);
}
void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
{
- if (!mod_timer(&sk->sk_timer, jiffies + len))
- sock_hold(sk);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
}
void tcp_set_keepalive(struct sock *sk, int val)
ipv6_only_sock(s) ||
(s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
continue;
- if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif))
+ if (!ip_mc_sf_allow(s, loc_addr, rmt_addr, dif))
continue;
goto found;
}
return ret;
}
-static int ipip_output(struct sk_buff *skb)
+static int ipip_output(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
struct dst_entry *dst = skb->dst;
struct xfrm_state *x = dst->xfrm;
struct iphdr *iph, *top_iph;
return nexthdr;
}
-int ah6_output(struct sk_buff *skb)
+int ah6_output(struct sk_buff **pskb)
{
int err;
int hdr_len = sizeof(struct ipv6hdr);
- struct dst_entry *dst = skb->dst;
+ struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
struct ipv6hdr *iph = NULL;
struct ip_auth_hdr *ah;
u16 nh_offset = 0;
u8 nexthdr;
- if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
- err = -EINVAL;
- goto error_nolock;
+ if ((*pskb)->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ if (err)
+ goto error_nolock;
}
spin_lock_bh(&x->lock);
- err = xfrm_check_output(x, skb, AF_INET6);
+ err = xfrm_check_output(x, *pskb, AF_INET6);
if (err)
goto error;
if (x->props.mode) {
- iph = skb->nh.ipv6h;
- skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, x->props.header_len);
- skb->nh.ipv6h->version = 6;
- skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
- skb->nh.ipv6h->nexthdr = IPPROTO_AH;
- ipv6_addr_copy(&skb->nh.ipv6h->saddr,
+ iph = (*pskb)->nh.ipv6h;
+ (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
+ (*pskb)->nh.ipv6h->version = 6;
+ (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+ (*pskb)->nh.ipv6h->nexthdr = IPPROTO_AH;
+ ipv6_addr_copy(&(*pskb)->nh.ipv6h->saddr,
(struct in6_addr *) &x->props.saddr);
- ipv6_addr_copy(&skb->nh.ipv6h->daddr,
+ ipv6_addr_copy(&(*pskb)->nh.ipv6h->daddr,
(struct in6_addr *) &x->id.daddr);
- ah = (struct ip_auth_hdr*)(skb->nh.ipv6h+1);
+ ah = (struct ip_auth_hdr*)((*pskb)->nh.ipv6h+1);
ah->nexthdr = IPPROTO_IPV6;
} else {
- hdr_len = skb->h.raw - skb->nh.raw;
+ hdr_len = (*pskb)->h.raw - (*pskb)->nh.raw;
iph = kmalloc(hdr_len, GFP_ATOMIC);
if (!iph) {
err = -ENOMEM;
goto error;
}
- memcpy(iph, skb->data, hdr_len);
- skb->nh.ipv6h = (struct ipv6hdr*)skb_push(skb, x->props.header_len);
- memcpy(skb->nh.ipv6h, iph, hdr_len);
- nexthdr = ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_OUT);
+ memcpy(iph, (*pskb)->data, hdr_len);
+ (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
+ memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
+ nexthdr = ipv6_clear_mutable_options(*pskb, &nh_offset, XFRM_POLICY_OUT);
if (nexthdr == 0)
goto error_free_iph;
- skb->nh.raw[nh_offset] = IPPROTO_AH;
- skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
- ah = (struct ip_auth_hdr*)(skb->nh.raw+hdr_len);
- skb->h.raw = (unsigned char*) ah;
+ (*pskb)->nh.raw[nh_offset] = IPPROTO_AH;
+ (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+ ah = (struct ip_auth_hdr*)((*pskb)->nh.raw+hdr_len);
+ (*pskb)->h.raw = (unsigned char*) ah;
ah->nexthdr = nexthdr;
}
- skb->nh.ipv6h->priority = 0;
- skb->nh.ipv6h->flow_lbl[0] = 0;
- skb->nh.ipv6h->flow_lbl[1] = 0;
- skb->nh.ipv6h->flow_lbl[2] = 0;
- skb->nh.ipv6h->hop_limit = 0;
+ (*pskb)->nh.ipv6h->priority = 0;
+ (*pskb)->nh.ipv6h->flow_lbl[0] = 0;
+ (*pskb)->nh.ipv6h->flow_lbl[1] = 0;
+ (*pskb)->nh.ipv6h->flow_lbl[2] = 0;
+ (*pskb)->nh.ipv6h->hop_limit = 0;
ahp = x->data;
ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) +
ah->reserved = 0;
ah->spi = x->id.spi;
ah->seq_no = htonl(++x->replay.oseq);
- ahp->icv(ahp, skb, ah->auth_data);
+ ahp->icv(ahp, *pskb, ah->auth_data);
if (x->props.mode) {
- skb->nh.ipv6h->hop_limit = iph->hop_limit;
- skb->nh.ipv6h->priority = iph->priority;
- skb->nh.ipv6h->flow_lbl[0] = iph->flow_lbl[0];
- skb->nh.ipv6h->flow_lbl[1] = iph->flow_lbl[1];
- skb->nh.ipv6h->flow_lbl[2] = iph->flow_lbl[2];
+ (*pskb)->nh.ipv6h->hop_limit = iph->hop_limit;
+ (*pskb)->nh.ipv6h->priority = iph->priority;
+ (*pskb)->nh.ipv6h->flow_lbl[0] = iph->flow_lbl[0];
+ (*pskb)->nh.ipv6h->flow_lbl[1] = iph->flow_lbl[1];
+ (*pskb)->nh.ipv6h->flow_lbl[2] = iph->flow_lbl[2];
if (x->props.flags & XFRM_STATE_NOECN)
- IP6_ECN_clear(skb->nh.ipv6h);
+ IP6_ECN_clear((*pskb)->nh.ipv6h);
} else {
- memcpy(skb->nh.ipv6h, iph, hdr_len);
- skb->nh.raw[nh_offset] = IPPROTO_AH;
- skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
+ memcpy((*pskb)->nh.ipv6h, iph, hdr_len);
+ (*pskb)->nh.raw[nh_offset] = IPPROTO_AH;
+ (*pskb)->nh.ipv6h->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
kfree (iph);
}
- skb->nh.raw = skb->data;
+ (*pskb)->nh.raw = (*pskb)->data;
- x->curlft.bytes += skb->len;
+ x->curlft.bytes += (*pskb)->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
- if ((skb->dst = dst_pop(dst)) == NULL) {
+ if (((*pskb)->dst = dst_pop(dst)) == NULL) {
err = -EHOSTUNREACH;
goto error_nolock;
}
error:
spin_unlock_bh(&x->lock);
error_nolock:
- kfree_skb(skb);
+ kfree_skb(*pskb);
return err;
}
struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
struct xfrm_state *x;
- if (type != ICMPV6_DEST_UNREACH ||
+ if (type != ICMPV6_DEST_UNREACH &&
type != ICMPV6_PKT_TOOBIG)
return;
(struct in6_addr *)(skb->nh.raw + serr->addr_offset));
if (np->sndflow)
sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
- if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
- sin->sin6_scope_id = opt->iif;
- }
+ if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+ sin->sin6_scope_id = IP6CB(skb)->iif;
} else {
ipv6_addr_set(&sin->sin6_addr, 0, 0,
htonl(0xffff),
ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr);
if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb);
- if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
- sin->sin6_scope_id = opt->iif;
- }
+ if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+ sin->sin6_scope_id = IP6CB(skb)->iif;
} else {
struct inet_opt *inet = inet_sk(sk);
int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
{
struct ipv6_pinfo *np = inet6_sk(sk);
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
+ struct inet6_skb_parm *opt = IP6CB(skb);
if (np->rxopt.bits.rxinfo) {
struct in6_pktinfo src_info;
#define MAX_SG_ONSTACK 4
-int esp6_output(struct sk_buff *skb)
+int esp6_output(struct sk_buff **pskb)
{
int err;
int hdr_len = 0;
- struct dst_entry *dst = skb->dst;
+ struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
struct ipv6hdr *iph = NULL, *top_iph;
struct ipv6_esp_hdr *esph;
u8 *prevhdr;
u8 nexthdr = 0;
- /* First, if the skb is not checksummed, complete checksum. */
- if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
- err = -EINVAL;
- goto error_nolock;
+ if ((*pskb)->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ if (err)
+ goto error_nolock;
}
spin_lock_bh(&x->lock);
- err = xfrm_check_output(x, skb, AF_INET6);
+ err = xfrm_check_output(x, *pskb, AF_INET6);
if (err)
goto error;
err = -ENOMEM;
/* Strip IP header in transport mode. Save it. */
if (!x->props.mode) {
- hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+ hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
nexthdr = *prevhdr;
*prevhdr = IPPROTO_ESP;
iph = kmalloc(hdr_len, GFP_ATOMIC);
err = -ENOMEM;
goto error;
}
- memcpy(iph, skb->nh.raw, hdr_len);
- __skb_pull(skb, hdr_len);
+ memcpy(iph, (*pskb)->nh.raw, hdr_len);
+ __skb_pull(*pskb, hdr_len);
}
/* Now skb is pure payload to encrypt */
/* Round to block size */
- clen = skb->len;
+ clen = (*pskb)->len;
esp = x->data;
alen = esp->auth.icv_trunc_len;
if (esp->conf.padlen)
clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1);
- if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {
+ if ((nfrags = skb_cow_data(*pskb, clen-(*pskb)->len+alen, &trailer)) < 0) {
if (!x->props.mode && iph) kfree(iph);
goto error;
}
/* Fill padding... */
do {
int i;
- for (i=0; i<clen-skb->len - 2; i++)
+ for (i=0; i<clen-(*pskb)->len - 2; i++)
*(u8*)(trailer->tail + i) = i+1;
} while (0);
- *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;
- pskb_put(skb, trailer, clen - skb->len);
+ *(u8*)(trailer->tail + clen-(*pskb)->len - 2) = (clen - (*pskb)->len)-2;
+ pskb_put(*pskb, trailer, clen - (*pskb)->len);
if (x->props.mode) {
- iph = skb->nh.ipv6h;
- top_iph = (struct ipv6hdr*)skb_push(skb, x->props.header_len);
+ iph = (*pskb)->nh.ipv6h;
+ top_iph = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
esph = (struct ipv6_esp_hdr*)(top_iph+1);
*(u8*)(trailer->tail - 1) = IPPROTO_IPV6;
top_iph->version = 6;
if (x->props.flags & XFRM_STATE_NOECN)
IP6_ECN_clear(top_iph);
top_iph->nexthdr = IPPROTO_ESP;
- top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
+ top_iph->payload_len = htons((*pskb)->len + alen - sizeof(struct ipv6hdr));
top_iph->hop_limit = iph->hop_limit;
ipv6_addr_copy(&top_iph->saddr,
(struct in6_addr *)&x->props.saddr);
ipv6_addr_copy(&top_iph->daddr,
(struct in6_addr *)&x->id.daddr);
} else {
- esph = (struct ipv6_esp_hdr*)skb_push(skb, x->props.header_len);
- skb->h.raw = (unsigned char*)esph;
- top_iph = (struct ipv6hdr*)skb_push(skb, hdr_len);
+ esph = (struct ipv6_esp_hdr*)skb_push(*pskb, x->props.header_len);
+ (*pskb)->h.raw = (unsigned char*)esph;
+ top_iph = (struct ipv6hdr*)skb_push(*pskb, hdr_len);
memcpy(top_iph, iph, hdr_len);
kfree(iph);
- top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
+ top_iph->payload_len = htons((*pskb)->len + alen - sizeof(struct ipv6hdr));
*(u8*)(trailer->tail - 1) = nexthdr;
}
if (!sg)
goto error;
}
- skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+ skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
crypto_cipher_encrypt(tfm, sg, sg, clen);
if (unlikely(sg != sgbuf))
kfree(sg);
}
if (esp->auth.icv_full_len) {
- esp->auth.icv(esp, skb, (u8*)esph-skb->data,
+ esp->auth.icv(esp, *pskb, (u8*)esph-(*pskb)->data,
sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);
- pskb_put(skb, trailer, alen);
+ pskb_put(*pskb, trailer, alen);
}
- skb->nh.raw = skb->data;
+ (*pskb)->nh.raw = (*pskb)->data;
- x->curlft.bytes += skb->len;
+ x->curlft.bytes += (*pskb)->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
- if ((skb->dst = dst_pop(dst)) == NULL) {
+ if (((*pskb)->dst = dst_pop(dst)) == NULL) {
err = -EHOSTUNREACH;
goto error_nolock;
}
error:
spin_unlock_bh(&x->lock);
error_nolock:
- kfree_skb(skb);
+ kfree_skb(*pskb);
return err;
}
struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset);
struct xfrm_state *x;
- if (type != ICMPV6_DEST_UNREACH ||
+ if (type != ICMPV6_DEST_UNREACH &&
type != ICMPV6_PKT_TOOBIG)
return;
static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
{
struct sk_buff *skb = *skbp;
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+ struct inet6_skb_parm *opt = IP6CB(skb);
if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
!pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
{
struct sk_buff *skb = *skbp;
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+ struct inet6_skb_parm *opt = IP6CB(skb);
struct in6_addr *addr;
struct in6_addr daddr;
int n, i;
return -1;
}
*skbp = skb = skb2;
- opt = (struct inet6_skb_parm *)skb2->cb;
+ opt = IP6CB(skb2);
hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
}
static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
{
if (skb->nh.raw[optoff+1] == 2) {
- ((struct inet6_skb_parm*)skb->cb)->ra = optoff;
+ IP6CB(skb)->ra = optoff;
return 1;
}
LIMIT_NETDEBUG(
int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
{
- ((struct inet6_skb_parm*)skb->cb)->hop = sizeof(struct ipv6hdr);
+ IP6CB(skb)->hop = sizeof(struct ipv6hdr);
if (ip6_parse_tlv(tlvprochopopt_lst, skb))
return sizeof(struct ipv6hdr);
return -1;
/* Store incoming device index. When the packet will
be queued, we cannot refer to skb->dev anymore.
*/
- ((struct inet6_skb_parm *)skb->cb)->iif = dev->ifindex;
+ IP6CB(skb)->iif = dev->ifindex;
if (skb->len < sizeof(struct ipv6hdr))
goto err;
#include <net/icmp.h>
#include <net/xfrm.h>
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
+static int ip6_fragment(struct sk_buff **pskb, int (*output)(struct sk_buff**));
static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
{
}
-int ip6_output2(struct sk_buff *skb)
+static int ip6_output2(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
struct dst_entry *dst = skb->dst;
struct net_device *dev = dst->dev;
if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
&skb->nh.ipv6h->saddr)) {
- struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC);
+ struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
/* Do not check for IFF_ALLMULTI; multicast routing
is not supported in any case.
return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
}
-int ip6_output(struct sk_buff *skb)
+int ip6_output(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
+
if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list))
- return ip6_fragment(skb, ip6_output2);
+ return ip6_fragment(pskb, ip6_output2);
else
- return ip6_output2(skb);
+ return ip6_output2(pskb);
}
#ifdef CONFIG_NETFILTER
{
struct dst_entry *dst = skb->dst;
struct ipv6hdr *hdr = skb->nh.ipv6h;
- struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb;
+ struct inet6_skb_parm *opt = IP6CB(skb);
if (ipv6_devconf.forwarding == 0)
goto error;
return offset;
}
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+static int ip6_fragment(struct sk_buff **pskb, int (*output)(struct sk_buff**))
{
struct net_device *dev;
+ struct sk_buff *frag, *skb = *pskb;
struct rt6_info *rt = (struct rt6_info*)skb->dst;
- struct sk_buff *frag;
struct ipv6hdr *tmp_hdr;
struct frag_hdr *fh;
unsigned int mtu, hlen, left, len;
frag->nh.ipv6h->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
ip6_copy_metadata(frag, skb);
}
- err = output(skb);
-
+
+ err = output(&skb);
if (err || !frag)
break;
IP6_INC_STATS(FragCreates);
- err = output(frag);
+ err = output(&frag);
if (err)
goto fail;
}
return err;
}
-static int ipcomp6_output(struct sk_buff *skb)
+static int ipcomp6_output(struct sk_buff **pskb)
{
int err;
- struct dst_entry *dst = skb->dst;
+ struct dst_entry *dst = (*pskb)->dst;
struct xfrm_state *x = dst->xfrm;
struct ipv6hdr *tmp_iph = NULL, *iph, *top_iph;
int hdr_len = 0;
int plen, dlen;
u8 *start, *scratch = ipcd->scratch;
- if (skb->ip_summed == CHECKSUM_HW && skb_checksum_help(skb) == NULL) {
- err = -EINVAL;
- goto error_nolock;
+ if ((*pskb)->ip_summed == CHECKSUM_HW) {
+ err = skb_checksum_help(pskb, 0);
+ if (err)
+ goto error_nolock;
}
spin_lock_bh(&x->lock);
- err = xfrm_check_output(x, skb, AF_INET6);
+ err = xfrm_check_output(x, *pskb, AF_INET6);
if (err)
goto error;
if (x->props.mode) {
hdr_len = sizeof(struct ipv6hdr);
nexthdr = IPPROTO_IPV6;
- iph = skb->nh.ipv6h;
- top_iph = (struct ipv6hdr *)skb_push(skb, sizeof(struct ipv6hdr));
+ iph = (*pskb)->nh.ipv6h;
+ top_iph = (struct ipv6hdr *)skb_push(*pskb, sizeof(struct ipv6hdr));
top_iph->version = 6;
top_iph->priority = iph->priority;
top_iph->flow_lbl[0] = iph->flow_lbl[0];
top_iph->flow_lbl[1] = iph->flow_lbl[1];
top_iph->flow_lbl[2] = iph->flow_lbl[2];
top_iph->nexthdr = IPPROTO_IPV6; /* initial */
- top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
+ top_iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
top_iph->hop_limit = iph->hop_limit;
memcpy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr, sizeof(struct in6_addr));
memcpy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr, sizeof(struct in6_addr));
- skb->nh.raw = skb->data; /* == top_iph */
- skb->h.raw = skb->nh.raw + hdr_len;
+ (*pskb)->nh.raw = (*pskb)->data; /* == top_iph */
+ (*pskb)->h.raw = (*pskb)->nh.raw + hdr_len;
} else {
- hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
+ hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
nexthdr = *prevhdr;
}
/* check whether datagram len is larger than threshold */
- if ((skb->len - hdr_len) < ipcd->threshold) {
+ if (((*pskb)->len - hdr_len) < ipcd->threshold) {
goto out_ok;
}
- if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
- skb_linearize(skb, GFP_ATOMIC) != 0) {
+ if ((skb_is_nonlinear(*pskb) || skb_cloned(*pskb)) &&
+ skb_linearize(*pskb, GFP_ATOMIC) != 0) {
err = -ENOMEM;
goto error;
}
/* compression */
- plen = skb->len - hdr_len;
+ plen = (*pskb)->len - hdr_len;
dlen = IPCOMP_SCRATCH_SIZE;
- start = skb->data + hdr_len;
+ start = (*pskb)->data + hdr_len;
err = crypto_comp_compress(ipcd->tfm, start, plen, scratch, &dlen);
if (err) {
goto out_ok;
}
memcpy(start, scratch, dlen);
- pskb_trim(skb, hdr_len+dlen);
+ pskb_trim(*pskb, hdr_len+dlen);
/* insert ipcomp header and replace datagram */
tmp_iph = kmalloc(hdr_len, GFP_ATOMIC);
err = -ENOMEM;
goto error;
}
- memcpy(tmp_iph, skb->nh.raw, hdr_len);
- top_iph = (struct ipv6hdr*)skb_push(skb, sizeof(struct ipv6_comp_hdr));
+ memcpy(tmp_iph, (*pskb)->nh.raw, hdr_len);
+ top_iph = (struct ipv6hdr*)skb_push(*pskb, sizeof(struct ipv6_comp_hdr));
memcpy(top_iph, tmp_iph, hdr_len);
kfree(tmp_iph);
if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
IP6_ECN_clear(top_iph);
- top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
- skb->nh.raw = skb->data; /* top_iph */
- ip6_find_1stfragopt(skb, &prevhdr);
+ top_iph->payload_len = htons((*pskb)->len - sizeof(struct ipv6hdr));
+ (*pskb)->nh.raw = (*pskb)->data; /* top_iph */
+ ip6_find_1stfragopt(*pskb, &prevhdr);
*prevhdr = IPPROTO_COMP;
ipch = (struct ipv6_comp_hdr *)((unsigned char *)top_iph + hdr_len);
ipch->flags = 0;
ipch->cpi = htons((u16 )ntohl(x->id.spi));
- skb->h.raw = (unsigned char*)ipch;
+ (*pskb)->h.raw = (unsigned char*)ipch;
out_ok:
- x->curlft.bytes += skb->len;
+ x->curlft.bytes += (*pskb)->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
- if ((skb->dst = dst_pop(dst)) == NULL) {
+ if (((*pskb)->dst = dst_pop(dst)) == NULL) {
err = -EHOSTUNREACH;
goto error_nolock;
}
error:
spin_unlock_bh(&x->lock);
error_nolock:
- kfree_skb(skb);
+ kfree_skb(*pskb);
goto out_exit;
}
err = -EADDRNOTAVAIL;
for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
- if (pmc->ifindex != pgsr->gsr_interface)
+ if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
continue;
if (ipv6_addr_cmp(&pmc->addr, group) == 0)
break;
ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr);
- dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+ dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
if (!dst)
return;
ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr);
- dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2);
+ dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
if (!dst)
return;
ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr);
- dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2);
+ dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output);
if (!dst)
return;
#endif
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
-/* Mutex protects lists (only traversed in user context). */
-static DECLARE_MUTEX(ip6t_mutex);
/* Must have mutex */
#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
#endif
static inline struct ip6t_table *
-find_table_lock(const char *name, int *error, struct semaphore *mutex)
+ip6t_find_table_lock(const char *name, int *error, struct semaphore *mutex)
{
return find_inlist_lock(&ip6t_tables, name, "ip6table_", error, mutex);
}
return find_inlist_lock(&ip6t_match, name, "ip6t_", error, mutex);
}
-static inline struct ip6t_target *
-find_target_lock(const char *name, int *error, struct semaphore *mutex)
+struct ip6t_target *
+ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex)
{
return find_inlist_lock(&ip6t_target, name, "ip6t_", error, mutex);
}
goto cleanup_matches;
t = ip6t_get_target(e);
- target = find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
+ target = ip6t_find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
if (!target) {
duprintf("check_entry: `%s' not found\n", t->u.user.name);
goto cleanup_matches;
static int
copy_entries_to_user(unsigned int total_size,
struct ip6t_table *table,
- void *userptr)
+ void __user *userptr)
{
unsigned int off, num, countersize;
struct ip6t_entry *e;
int ret;
struct ip6t_table *t;
- t = find_table_lock(entries->name, &ret, &ip6t_mutex);
+ t = ip6t_find_table_lock(entries->name, &ret, &ip6t_mutex);
if (t) {
duprintf("t->private->number = %u\n",
t->private->number);
duprintf("ip_tables: Translated table\n");
- t = find_table_lock(tmp.name, &ret, &ip6t_mutex);
+ t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
if (!t)
goto free_newinfo_counters_untrans;
goto free;
}
- t = find_table_lock(tmp.name, &ret, &ip6t_mutex);
+ t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex);
if (!t)
goto free;
break;
}
name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
- t = find_table_lock(name, &ret, &ip6t_mutex);
+ t = ip6t_find_table_lock(name, &ret, &ip6t_mutex);
if (t) {
struct ip6t_getinfo info;
EXPORT_SYMBOL(ip6t_register_table);
EXPORT_SYMBOL(ip6t_unregister_table);
EXPORT_SYMBOL(ip6t_do_table);
+EXPORT_SYMBOL(ip6t_find_target_lock);
EXPORT_SYMBOL(ip6t_register_match);
EXPORT_SYMBOL(ip6t_unregister_match);
EXPORT_SYMBOL(ip6t_register_target);
ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr);
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
- if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
- sin6->sin6_scope_id = opt->iif;
- }
+ if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+ sin6->sin6_scope_id = IP6CB(skb)->iif;
}
sock_recv_timestamp(msg, sk, skb);
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static void ip6_dst_destroy(struct dst_entry *);
+static void ip6_dst_ifdown(struct dst_entry *, int how);
static int ip6_dst_gc(void);
static int ip6_pkt_discard(struct sk_buff *skb);
+static int ip6_pkt_discard_out(struct sk_buff **pskb);
static void ip6_link_failure(struct sk_buff *skb);
static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
.gc_thresh = 1024,
.check = ip6_dst_check,
.destroy = ip6_dst_destroy,
+ .ifdown = ip6_dst_ifdown,
.negative_advice = ip6_negative_advice,
.link_failure = ip6_link_failure,
.update_pmtu = ip6_rt_update_pmtu,
.error = -ENETUNREACH,
.metrics = { [RTAX_HOPLIMIT - 1] = 255, },
.input = ip6_pkt_discard,
- .output = ip6_pkt_discard,
+ .output = ip6_pkt_discard_out,
.ops = &ip6_dst_ops,
.path = (struct dst_entry*)&ip6_null_entry,
}
static void ip6_dst_destroy(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *)dst;
- if (rt->rt6i_idev != NULL)
- in6_dev_put(rt->rt6i_idev);
-
+ struct inet6_dev *idev = rt->rt6i_idev;
+
+ if (idev != NULL) {
+ rt->rt6i_idev = NULL;
+ in6_dev_put(idev);
+ }
+}
+
+static void ip6_dst_ifdown(struct dst_entry *dst, int how)
+{
+ ip6_dst_destroy(dst);
}
/*
/* Protected by rt6_lock. */
static struct dst_entry *ndisc_dst_gc_list;
+static int ipv6_get_mtu(struct net_device *dev);
+static inline unsigned int ipv6_advmss(unsigned int mtu);
struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
struct neighbour *neigh,
struct in6_addr *addr,
- int (*output)(struct sk_buff *))
+ int (*output)(struct sk_buff **))
{
struct rt6_info *rt = ip6_dst_alloc();
rt->rt6i_metric = 0;
atomic_set(&rt->u.dst.__refcnt, 1);
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255;
+ rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev);
+ rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst));
rt->u.dst.output = output;
write_lock_bh(&rt6_lock);
dev_put(dev);
dev = &loopback_dev;
dev_hold(dev);
- rt->u.dst.output = ip6_pkt_discard;
+ rt->u.dst.output = ip6_pkt_discard_out;
rt->u.dst.input = ip6_pkt_discard;
rt->u.dst.error = -ENETUNREACH;
rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
return 0;
}
+int ip6_pkt_discard_out(struct sk_buff **pskb)
+{
+ return ip6_pkt_discard(*pskb);
+}
+
/*
* Add address
*/
static __inline__ int tcp_v6_iif(struct sk_buff *skb)
{
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
- return opt->iif;
+ return IP6CB(skb)->iif;
}
static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
np->rxopt.bits.srcrt == 2 &&
req->af.v6_req.pktopts) {
struct sk_buff *pktopts = req->af.v6_req.pktopts;
- struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
+ struct inet6_skb_parm *rxopt = IP6CB(pktopts);
if (rxopt->srcrt)
opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
}
static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
{
struct ipv6_pinfo *np = inet6_sk(sk);
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
+ struct inet6_skb_parm *opt = IP6CB(skb);
if (np->rxopt.all) {
if ((opt->hop && np->rxopt.bits.hopopts) ||
goto drop;
}
- if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+ if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
goto drop;
req = tcp_openreq_alloc();
opt = np->opt;
- if (tcp_acceptq_is_full(sk))
+ if (sk_acceptq_is_full(sk))
goto out_overflow;
if (np->rxopt.bits.srcrt == 2 &&
opt == NULL && req->af.v6_req.pktopts) {
- struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)req->af.v6_req.pktopts->cb;
+ struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts);
if (rxopt->srcrt)
opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt));
}
tp->af_specific = &ipv6_specific;
- sk->sk_write_space = tcp_write_space;
+ sk->sk_write_space = sk_stream_write_space;
sk->sk_use_write_queue = 1;
sk->sk_sndbuf = sysctl_tcp_wmem[1];
if (np->rxopt.all)
datagram_recv_ctl(sk, msg, skb);
- if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) {
- struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
- sin6->sin6_scope_id = opt->iif;
- }
+ if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+ sin6->sin6_scope_id = IP6CB(skb)->iif;
}
}
err = copied;
return -1;
}
- if (sk->sk_filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+ if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
UDP6_INC_STATS_BH(UdpInErrors);
kfree_skb(skb);
struct sk_buff *skb)
{
struct sock *sk, *sk2;
- struct sk_buff *buff;
int dif;
read_lock(&udp_hash_lock);
sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
dif = skb->dev->ifindex;
sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
- if (!sk)
- goto free_skb;
+ if (!sk) {
+ kfree_skb(skb);
+ goto out;
+ }
- buff = NULL;
sk2 = sk;
while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr,
uh->source, saddr, dif))) {
- if (!buff) {
- buff = skb_clone(skb, GFP_ATOMIC);
- if (!buff)
- continue;
- }
- if (udpv6_queue_rcv_skb(sk2, buff) >= 0)
- buff = NULL;
- }
- if (buff)
- kfree_skb(buff);
- if (udpv6_queue_rcv_skb(sk, skb) < 0) {
-free_skb:
- kfree_skb(skb);
+ struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
+ if (buff)
+ udpv6_queue_rcv_skb(sk2, buff);
}
+ udpv6_queue_rcv_skb(sk, skb);
+out:
read_unlock(&udp_hash_lock);
}
struct iovec *iov, int len, int noblock);
extern int ipxrtr_route_skb(struct sk_buff *skb);
extern struct ipx_route *ipxrtr_lookup(__u32 net);
-extern int ipxrtr_ioctl(unsigned int cmd, void *arg);
+extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
#undef IPX_REFCNT_DEBUG
#ifdef IPX_REFCNT_DEBUG
ipx_primary_net = ipx_interfaces_head();
}
-static int ipxcfg_get_config_data(struct ipx_config_data *arg)
+static int ipxcfg_get_config_data(struct ipx_config_data __user *arg)
{
struct ipx_config_data vals;
return intrfc;
}
-static int ipxitf_ioctl(unsigned int cmd, void *arg)
+static int ipxitf_ioctl(unsigned int cmd, void __user *arg)
{
int rc = -EINVAL;
struct ifreq ifr;
}
case SIOCAIPXITFCRT:
rc = -EFAULT;
- if (get_user(val, (unsigned char *) arg))
+ if (get_user(val, (unsigned char __user *) arg))
break;
rc = 0;
ipxcfg_auto_create_interfaces = val;
break;
case SIOCAIPXPRISLT:
rc = -EFAULT;
- if (get_user(val, (unsigned char *) arg))
+ if (get_user(val, (unsigned char __user *) arg))
break;
rc = 0;
ipxcfg_set_auto_select(val);
/* Socket gets bound below anyway */
/* if (sk->sk_zapped)
return -EIO; */ /* Socket not bound */
- if (flags & ~MSG_DONTWAIT)
+ if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
goto out;
/* Max possible packet size limited by 16 bit pktsize in header */
int rc = 0;
long amount = 0;
struct sock *sk = sock->sk;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case TIOCOUTQ:
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- rc = put_user(amount, (int *)arg);
+ rc = put_user(amount, (int __user *)argp);
break;
case TIOCINQ: {
struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
* user tasks fiddle here */
if (skb)
amount = skb->len - sizeof(struct ipxhdr);
- rc = put_user(amount, (int *)arg);
+ rc = put_user(amount, (int __user *)argp);
break;
}
case SIOCADDRT:
case SIOCDELRT:
rc = -EPERM;
if (capable(CAP_NET_ADMIN))
- rc = ipxrtr_ioctl(cmd, (void *)arg);
+ rc = ipxrtr_ioctl(cmd, argp);
break;
case SIOCSIFADDR:
case SIOCAIPXITFCRT:
if (!capable(CAP_NET_ADMIN))
break;
case SIOCGIFADDR:
- rc = ipxitf_ioctl(cmd, (void *)arg);
+ rc = ipxitf_ioctl(cmd, argp);
break;
case SIOCIPXCFGDATA:
- rc = ipxcfg_get_config_data((void *)arg);
+ rc = ipxcfg_get_config_data(argp);
break;
case SIOCIPXNCPCONN:
/*
if (!capable(CAP_NET_ADMIN))
break;
rc = get_user(ipx_sk(sk)->ipx_ncp_conn,
- (const unsigned short *)(arg));
+ (const unsigned short __user *)argp);
break;
case SIOCGSTAMP:
rc = -EINVAL;
if (sk)
- rc = sock_get_timestamp(sk, (struct timeval __user *)arg);
+ rc = sock_get_timestamp(sk, argp);
break;
case SIOCGIFDSTADDR:
case SIOCSIFDSTADDR:
rc = -EINVAL;
break;
default:
- rc = dev_ioctl(cmd,(void __user *) arg);
+ rc = dev_ioctl(cmd, argp);
break;
}
/*
* We use a normal struct rtentry for route handling
*/
-int ipxrtr_ioctl(unsigned int cmd, void *arg)
+int ipxrtr_ioctl(unsigned int cmd, void __user *arg)
{
struct rtentry rt; /* Use these to behave like 'other' stacks */
struct sockaddr_ipx *sg, *st;
IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
/* Note : socket.c set MSG_EOR on SEQPACKET sockets */
- if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;
if (sk->sk_shutdown & SEND_SHUTDOWN) {
IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return -EINVAL;
if (sk->sk_shutdown & SEND_SHUTDOWN) {
IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return -EINVAL;
if (sk->sk_shutdown & SEND_SHUTDOWN) {
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- if (put_user(amount, (unsigned int *)arg))
+ if (put_user(amount, (unsigned int __user *)arg))
return -EFAULT;
return 0;
}
/* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
- if (put_user(amount, (unsigned int *)arg))
+ if (put_user(amount, (unsigned int __user *)arg))
return -EFAULT;
return 0;
}
*
*/
static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
- struct serial_struct *retinfo)
+ struct serial_struct __user *retinfo)
{
struct serial_struct info;
*
*/
static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self,
- struct serial_struct *new_info)
+ struct serial_struct __user *new_info)
{
#if 0
struct serial_struct new_serial;
switch (cmd) {
case TIOCGSERIAL:
- ret = ircomm_tty_get_serial_info(self, (struct serial_struct *) arg);
+ ret = ircomm_tty_get_serial_info(self, (struct serial_struct __user *) arg);
break;
case TIOCSSERIAL:
- ret = ircomm_tty_set_serial_info(self, (struct serial_struct *) arg);
+ ret = ircomm_tty_set_serial_info(self, (struct serial_struct __user *) arg);
break;
case TIOCMIWAIT:
IRDA_DEBUG(0, "(), TIOCMIWAIT, not impl!\n");
save_flags(flags); cli();
cnow = driver->icount;
restore_flags(flags);
- p_cuser = (struct serial_icounter_struct *) arg;
+ p_cuser = (struct serial_icounter_struct __user *) arg;
if (put_user(cnow.cts, &p_cuser->cts) ||
put_user(cnow.dsr, &p_cuser->dsr) ||
put_user(cnow.rng, &p_cuser->rng) ||
* Setup the DMA channel. Commonly used by ISA FIR drivers
*
*/
-void irda_setup_dma(int channel, char *buffer, int count, int mode)
+void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode)
{
unsigned long flags;
disable_dma(channel);
clear_dma_ff(channel);
set_dma_mode(channel, mode);
- set_dma_addr(channel, isa_virt_to_bus(buffer));
+ set_dma_addr(channel, buffer);
set_dma_count(channel, count);
enable_dma(channel);
* Note : separate from irlmp_do_discovery() so that we can handle
* passive discovery properly.
*/
-void irlmp_do_expiry()
+void irlmp_do_expiry(void)
{
struct lap_cb *lap;
* Used by IrLAP to get the discovery info it needs when answering
* discovery requests by other devices.
*/
-discovery_t *irlmp_get_discovery_response()
+discovery_t *irlmp_get_discovery_response(void)
{
IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
*/
static inline ssize_t
irnet_ctrl_write(irnet_socket * ap,
- const char * buf,
+ const char __user *buf,
size_t count)
{
char command[IRNET_MAX_COMMAND];
static inline ssize_t
irnet_ctrl_read(irnet_socket * ap,
struct file * file,
- char * buf,
+ char __user * buf,
size_t count)
{
DECLARE_WAITQUEUE(wait, current);
*/
static ssize_t
dev_irnet_write(struct file * file,
- const char * buf,
+ const char __user *buf,
size_t count,
loff_t * ppos)
{
*/
static ssize_t
dev_irnet_read(struct file * file,
- char * buf,
+ char __user * buf,
size_t count,
loff_t * ppos)
{
irnet_socket * ap = (struct irnet_socket *) file->private_data;
int err;
int val;
+ void __user *argp = (void __user *)arg;
DENTER(FS_TRACE, "(file=0x%p, ap=0x%p, cmd=0x%X)\n",
file, ap, cmd);
{
/* Set discipline (should be N_SYNC_PPP or N_TTY) */
case TIOCSETD:
- if(get_user(val, (int *) arg))
+ if(get_user(val, (int __user *)argp))
break;
if((val == N_SYNC_PPP) || (val == N_PPP))
{
case PPPIOCGCHAN:
if(!ap->ppp_open)
break;
- if(put_user(ppp_channel_index(&ap->chan), (int *) arg))
+ if(put_user(ppp_channel_index(&ap->chan), (int __user *)argp))
break;
DEBUG(FS_INFO, "Query channel.\n");
err = 0;
case PPPIOCGUNIT:
if(!ap->ppp_open)
break;
- if(put_user(ppp_unit_number(&ap->chan), (int *) arg))
+ if(put_user(ppp_unit_number(&ap->chan), (int __user *)argp))
break;
DEBUG(FS_INFO, "Query unit number.\n");
err = 0;
/* Get termios */
case TCGETS:
DEBUG(FS_INFO, "Get termios.\n");
- if(kernel_termios_to_user_termios((struct termios *)arg, &ap->termios))
+ if(kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
break;
err = 0;
break;
/* Set termios */
case TCSETSF:
DEBUG(FS_INFO, "Set termios.\n");
- if(user_termios_to_kernel_termios(&ap->termios, (struct termios *) arg))
+ if(user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
break;
err = 0;
break;
case FIONREAD:
DEBUG(FS_INFO, "FIONREAD\n");
val = 0;
- if(put_user(val, (int *) arg))
+ if(put_user(val, (int __user *)argp))
break;
err = 0;
break;
int err;
int val;
u32 accm[8];
+ void __user *argp = (void __user *)arg;
DENTER(PPP_TRACE, "(channel=0x%p, ap=0x%p, cmd=0x%X)\n",
chan, ap, cmd);
/* PPP flags */
case PPPIOCGFLAGS:
val = ap->flags | ap->rbits;
- if(put_user(val, (int *) arg))
+ if(put_user(val, (int __user *) argp))
break;
err = 0;
break;
case PPPIOCSFLAGS:
- if(get_user(val, (int *) arg))
+ if(get_user(val, (int __user *) argp))
break;
ap->flags = val & ~SC_RCV_BITS;
ap->rbits = val & SC_RCV_BITS;
/* Async map stuff - all dummy to please pppd */
case PPPIOCGASYNCMAP:
- if(put_user(ap->xaccm[0], (u32 *) arg))
+ if(put_user(ap->xaccm[0], (u32 __user *) argp))
break;
err = 0;
break;
case PPPIOCSASYNCMAP:
- if(get_user(ap->xaccm[0], (u32 *) arg))
+ if(get_user(ap->xaccm[0], (u32 __user *) argp))
break;
err = 0;
break;
case PPPIOCGRASYNCMAP:
- if(put_user(ap->raccm, (u32 *) arg))
+ if(put_user(ap->raccm, (u32 __user *) argp))
break;
err = 0;
break;
case PPPIOCSRASYNCMAP:
- if(get_user(ap->raccm, (u32 *) arg))
+ if(get_user(ap->raccm, (u32 __user *) argp))
break;
err = 0;
break;
case PPPIOCGXASYNCMAP:
- if(copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm)))
+ if(copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm)))
break;
err = 0;
break;
case PPPIOCSXASYNCMAP:
- if(copy_from_user(accm, (void *) arg, sizeof(accm)))
+ if(copy_from_user(accm, argp, sizeof(accm)))
break;
accm[2] &= ~0x40000000U; /* can't escape 0x5e */
accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
/* Max PPP frame size */
case PPPIOCGMRU:
- if(put_user(ap->mru, (int *) arg))
+ if(put_user(ap->mru, (int __user *) argp))
break;
err = 0;
break;
case PPPIOCSMRU:
- if(get_user(val, (int *) arg))
+ if(get_user(val, (int __user *) argp))
break;
if(val < PPP_MRU)
val = PPP_MRU;
irnet_cleanup(void)
{
irda_irnet_cleanup();
- return ppp_irnet_cleanup();
+ ppp_irnet_cleanup();
}
/*------------------------------------------------------------------*/
struct file *);
static ssize_t
dev_irnet_write(struct file *,
- const char *,
+ const char __user *,
size_t,
loff_t *),
dev_irnet_read(struct file *,
- char *,
+ char __user *,
size_t,
loff_t *);
static unsigned int
* us on that - Jean II */
static int do_devname(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp)
+ void __user *buffer, size_t *lenp)
{
int ret;
int copied, err;
err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;
msg->msg_namelen = 0;
to corresponding kernel module. --ANK (980802)
*/
- err = security_netlink_send(skb);
- if (err) {
+ err = -EFAULT;
+ if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
kfree_skb(skb);
goto out;
}
- err = -EFAULT;
- if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
+ err = security_netlink_send(sk, skb);
+ if (err) {
kfree_skb(skb);
goto out;
}
* Write a message to the kernel side of a communication link
*/
-static ssize_t netlink_write(struct file * file, const char * buf,
+static ssize_t netlink_write(struct file * file, const char __user * buf,
size_t count, loff_t *pos)
{
struct inode *inode = file->f_dentry->d_inode;
struct msghdr msg;
struct iovec iov;
- iov.iov_base = (void*)buf;
+ iov.iov_base = (void __user*)buf;
iov.iov_len = count;
msg.msg_name=NULL;
msg.msg_namelen=0;
* Read a message from the kernel side of the communication link
*/
-static ssize_t netlink_read(struct file * file, char * buf,
+static ssize_t netlink_read(struct file * file, char __user * buf,
size_t count, loff_t *pos)
{
struct inode *inode = file->f_dentry->d_inode;
unsigned char *asmptr;
int size;
- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;
lock_sock(sk);
static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
+ void __user *argp = (void __user *)arg;
int ret;
lock_sock(sk);
if (amount < 0)
amount = 0;
release_sock(sk);
- return put_user(amount, (int *)arg);
+ return put_user(amount, (int __user *)argp);
}
case TIOCINQ: {
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
release_sock(sk);
- return put_user(amount, (int *)arg);
+ return put_user(amount, (int __user *)argp);
}
case SIOCGSTAMP:
ret = -EINVAL;
if (sk != NULL)
- ret = sock_get_timestamp(sk, (struct timeval __user *)arg);
+ ret = sock_get_timestamp(sk, argp);
release_sock(sk);
return ret;
case SIOCNRDECOBS:
release_sock(sk);
if (!capable(CAP_NET_ADMIN)) return -EPERM;
- return nr_rt_ioctl(cmd, (void *)arg);
+ return nr_rt_ioctl(cmd, argp);
default:
release_sock(sk);
- return dev_ioctl(cmd, (void __user *)arg);
+ return dev_ioctl(cmd, argp);
}
release_sock(sk);
/*
* Handle the ioctls that control the routing functions.
*/
-int nr_rt_ioctl(unsigned int cmd, void *arg)
+int nr_rt_ioctl(unsigned int cmd, void __user *arg)
{
struct nr_route_struct nr_route;
struct net_device *dev;
int copied, err;
err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;
#if 0
unsigned char *asmptr;
int n, size, qbit = 0;
- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_CMSG_COMPAT))
return -EINVAL;
if (sk->sk_zapped)
{
struct sock *sk = sock->sk;
rose_cb *rose = rose_sk(sk);
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case TIOCOUTQ: {
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- return put_user(amount, (unsigned int *)arg);
+ return put_user(amount, (unsigned int __user *)argp);
}
case TIOCINQ: {
/* These two are safe on a single CPU system as only user tasks fiddle here */
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
- return put_user(amount, (unsigned int *)arg);
+ return put_user(amount, (unsigned int __user *)argp);
}
case SIOCGSTAMP:
if (sk != NULL)
- return sock_get_timestamp(sk, (struct timeval __user *)arg);
+ return sock_get_timestamp(sk, (struct timeval __user *)argp);
return -EINVAL;
case SIOCGIFADDR:
case SIOCRSCLRRT:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- return rose_rt_ioctl(cmd, (void *)arg);
+ return rose_rt_ioctl(cmd, argp);
case SIOCRSGCAUSE: {
struct rose_cause_struct rose_cause;
rose_cause.cause = rose->cause;
rose_cause.diagnostic = rose->diagnostic;
- return copy_to_user((void *)arg, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
+ return copy_to_user(argp, &rose_cause, sizeof(struct rose_cause_struct)) ? -EFAULT : 0;
}
case SIOCRSSCAUSE: {
struct rose_cause_struct rose_cause;
- if (copy_from_user(&rose_cause, (void *)arg, sizeof(struct rose_cause_struct)))
+ if (copy_from_user(&rose_cause, argp, sizeof(struct rose_cause_struct)))
return -EFAULT;
rose->cause = rose_cause.cause;
rose->diagnostic = rose_cause.diagnostic;
if (!capable(CAP_NET_ADMIN)) return -EPERM;
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
ax25_listen_release(&rose_callsign, NULL);
- if (copy_from_user(&rose_callsign, (void *)arg, sizeof(ax25_address)))
+ if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address)))
return -EFAULT;
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
ax25_listen_register(&rose_callsign, NULL);
return 0;
case SIOCRSGL2CALL:
- return copy_to_user((void *)arg, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
+ return copy_to_user(argp, &rose_callsign, sizeof(ax25_address)) ? -EFAULT : 0;
case SIOCRSACCEPT:
if (rose->state == ROSE_STATE_5) {
return 0;
default:
- return dev_ioctl(cmd, (void __user *)arg);
+ return dev_ioctl(cmd, argp);
}
return 0;
/*
* Handle the ioctls that control the routing functions.
*/
-int rose_rt_ioctl(unsigned int cmd, void *arg)
+int rose_rt_ioctl(unsigned int cmd, void __user *arg)
{
struct rose_route_struct rose_route;
struct net_device *dev;
if (sch->q.qlen) {
sch->stats.overlimits++;
- if (q->wd_expires && !netif_queue_stopped(sch->dev)) {
+ if (q->wd_expires) {
long delay = PSCHED_US2JIFFIE(q->wd_expires);
if (delay <= 0)
delay = 1;
struct dly_sched_data {
u32 latency;
u32 limit;
+ u32 loss;
struct timer_list timer;
struct Qdisc *qdisc;
};
struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb;
int ret;
+ /* Random packet drop 0 => none, ~0 => all */
+ if (q->loss >= net_random()) {
+ sch->stats.drops++;
+ return 0; /* lie about loss so TCP doesn't know */
+ }
+
PSCHED_GET_TIME(cb->queuetime);
/* Queue to underlying scheduler */
sch->stats.bytes += skb->len;
sch->stats.packets++;
}
- return 0;
+ return ret;
}
/* Requeue packets but don't change time stamp */
static struct sk_buff *dly_dequeue(struct Qdisc *sch)
{
struct dly_sched_data *q = (struct dly_sched_data *)sch->data;
- struct sk_buff *skb = q->qdisc->dequeue(q->qdisc);
+ struct sk_buff *skb;
+ retry:
+ skb = q->qdisc->dequeue(q->qdisc);
if (skb) {
struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb;
psched_time_t now;
- long diff;
+ long diff, delay;
PSCHED_GET_TIME(now);
diff = q->latency - PSCHED_TDIFF(now, cb->queuetime);
return skb;
}
- if (!netif_queue_stopped(sch->dev)) {
- long delay = PSCHED_US2JIFFIE(diff);
- if (delay <= 0)
- delay = 1;
- mod_timer(&q->timer, jiffies+delay);
- }
-
if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
sch->q.qlen--;
sch->stats.drops++;
+ goto retry;
}
+
+ delay = PSCHED_US2JIFFIE(diff);
+ if (delay <= 0)
+ delay = 1;
+ mod_timer(&q->timer, jiffies+delay);
+
sch->flags |= TCQ_F_THROTTLED;
}
return NULL;
} else {
q->latency = qopt->latency;
q->limit = qopt->limit;
+ q->loss = qopt->loss;
}
return err;
}
qopt.latency = q->latency;
qopt.limit = q->limit;
+ qopt.loss = q->loss;
RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
cl = actlist_get_minvt(&q->root, cur_time);
if (cl == NULL) {
sch->stats.overlimits++;
- if (!netif_queue_stopped(sch->dev))
- hfsc_schedule_watchdog(sch, cur_time);
+ hfsc_schedule_watchdog(sch, cur_time);
return NULL;
}
}
static void htb_delay_by(struct Qdisc *sch,long delay)
{
struct htb_sched *q = (struct htb_sched *)sch->data;
- if (netif_queue_stopped(sch->dev)) return;
if (delay <= 0) delay = 1;
if (unlikely(delay > 5*HZ)) {
if (net_ratelimit())
if (skb) {
psched_time_t now;
- long toks;
+ long toks, delay;
long ptoks = 0;
unsigned int len = skb->len;
return skb;
}
- if (!netif_queue_stopped(sch->dev)) {
- long delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks));
+ delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks));
- if (delay == 0)
- delay = 1;
+ if (delay == 0)
+ delay = 1;
- mod_timer(&q->wd_timer, jiffies+delay);
- }
+ mod_timer(&q->wd_timer, jiffies+delay);
/* Maybe we have a shorter packet in the queue,
which can be sent now. It sounds cool,
/* Allocate storage for the negotiated streams if it is not a temporary * association.
*/
if (!asoc->temp) {
- sctp_assoc_t assoc_id;
+ int assoc_id;
+ int error;
asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
asoc->c.sinit_num_ostreams, gfp);
if (!asoc->ssnmap)
goto clean_up;
- do {
- if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
- goto clean_up;
- spin_lock_bh(&sctp_assocs_id_lock);
- assoc_id = (sctp_assoc_t)idr_get_new(&sctp_assocs_id,
- (void *)asoc);
- spin_unlock_bh(&sctp_assocs_id_lock);
- } while (unlikely((int)assoc_id == -1));
+ retry:
+ if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+ goto clean_up;
+ spin_lock_bh(&sctp_assocs_id_lock);
+ error = idr_get_new(&sctp_assocs_id,
+ (void *)asoc,
+ &assoc_id);
+ spin_unlock_bh(&sctp_assocs_id_lock);
+ if (error == -EAGAIN)
+ goto retry;
+ else if (error)
+ goto clean_up;
- asoc->assoc_id = assoc_id;
+ asoc->assoc_id = (sctp_assoc_t) assoc_id;
}
/* ADDIP Section 4.1 ASCONF Chunk Procedures
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
SCTP_ULPEVENT(event));
+ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+ SCTP_STATE(SCTP_STATE_CLOSED));
+
/* SEND_FAILED sent later when cleaning up the association. */
asoc->outqueue.error = error;
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED));
+ /* Set sk_err to ECONNRESET on a 1-1 style socket. */
+ if (!sctp_style(asoc->base.sk, UDP))
+ asoc->base.sk->sk_err = ECONNRESET;
+
/* SEND_FAILED sent later when cleaning up the association. */
asoc->outqueue.error = error;
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
case SCTP_CMD_PROCESS_OPERR:
sctp_cmd_process_operr(commands, asoc, chunk);
break;
+ case SCTP_CMD_CLEAR_INIT_TAG:
+ asoc->peer.i.init_tag = 0;
+ break;
default:
printk(KERN_WARNING "Impossible command: %u, %p\n",
cmd->verb, cmd->obj.ptr);
* Verification Tag field to Tag_A, and also provide its own
* Verification Tag (Tag_Z) in the Initiate Tag field.
*
- * Verification Tag: No checking.
+ * Verification Tag: Must be 0.
*
* Inputs
* (endpoint, asoc, chunk)
(sk->sk_ack_backlog >= sk->sk_max_ack_backlog)))
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+ /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
+ * Tag.
+ */
+ if (chunk->sctp_hdr->vtag != 0)
+ return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
if (!chunk->singleton)
return SCTP_DISPOSITION_VIOLATION;
+ if (!sctp_vtag_verify(chunk, asoc))
+ return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
/* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
const sctp_subtype_t type, void *arg,
sctp_cmd_seq_t *commands)
{
+ struct sctp_chunk *chunk = arg;
struct sctp_ulpevent *ev;
+ if (!sctp_vtag_verify(chunk, asoc))
+ return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
/* RFC 2960 5.1 Normal Establishment of an Association
*
* E) Upon reception of the COOKIE ACK, endpoint "A" will move
struct sctp_chunk *reply;
size_t paylen = 0;
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. If the received
- * Verification Tag value does not match the receiver's own
- * tag value, the receiver shall silently discard the packet...
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* 8.3 The receiver of the HEARTBEAT should immediately
sctp_sender_hb_info_t *hbinfo;
unsigned long max_interval;
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. ...
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
if (!chunk->singleton)
return SCTP_DISPOSITION_VIOLATION;
+ /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
+ * Tag.
+ */
+ if (chunk->sctp_hdr->vtag != 0)
+ return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+
/* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
sctp_init_chunk_t *peer_init;
struct sctp_ulpevent *ev;
struct sctp_chunk *repl;
+ struct sctp_chunk *err;
+ sctp_disposition_t disposition;
/* new_asoc is a brand-new association, so these are not yet
* side effects--it is safe to run them here.
return SCTP_DISPOSITION_CONSUME;
}
+ /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
+ * the peer has restarted (Action A), it MUST NOT setup a new
+ * association but instead resend the SHUTDOWN ACK and send an ERROR
+ * chunk with a "Cookie Received while Shutting Down" error cause to
+ * its peer.
+ */
+ if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
+ disposition = sctp_sf_do_9_2_reshutack(ep, asoc,
+ SCTP_ST_CHUNK(chunk->chunk_hdr->type),
+ chunk, commands);
+ if (SCTP_DISPOSITION_NOMEM == disposition)
+ goto nomem;
+
+ err = sctp_make_op_error(asoc, chunk,
+ SCTP_ERROR_COOKIE_IN_SHUTDOWN,
+ NULL, 0);
+ if (err)
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+ SCTP_CHUNK(err));
+
+ return SCTP_DISPOSITION_CONSUME;
+ }
+
/* For now, fail any unsent/unacked data. Consider the optional
* choice of resending of this data.
*/
sctp_addto_chunk(reply, sizeof(bht), &bht);
+ /* Clear peer's init_tag cached in assoc as we are sending a new INIT */
+ sctp_add_cmd_sf(commands, SCTP_CMD_CLEAR_INIT_TAG, SCTP_NULL());
+
/* Cast away the const modifier, as we want to just
* rerun it through as a sideffect.
*/
skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
chunk->subh.shutdown_hdr = sdh;
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. If the received
- * Verification Tag value does not match the receiver's own
- * tag value, the receiver shall silently discard the packet...
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Upon the reception of the SHUTDOWN, the peer endpoint shall
sctp_cwrhdr_t *cwr;
struct sctp_chunk *chunk = arg;
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. If the received
- * Verification Tag value does not match the receiver's own
- * tag value, the receiver shall silently discard the packet...
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
cwr = (sctp_cwrhdr_t *) chunk->skb->data;
sctp_ecnehdr_t *ecne;
struct sctp_chunk *chunk = arg;
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. If the received
- * Verification Tag value does not match the receiver's own
- * tag value, the receiver shall silently discard the packet...
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
ecne = (sctp_ecnehdr_t *) chunk->skb->data;
int tmp;
__u32 tsn;
- /* RFC 2960 8.5 Verification Tag
- *
- * When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag.
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+ if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
int tmp;
__u32 tsn;
- /* RFC 2960 8.5 Verification Tag
- *
- * When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag.
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+ if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
sctp_sackhdr_t *sackh;
__u32 ctsn;
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. ...
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Pull the SACK chunk from the data buffer */
struct sctp_chunk *reply;
struct sctp_ulpevent *ev;
+ if (!sctp_vtag_verify(chunk, asoc))
+ return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
/* 10.2 H) SHUTDOWN COMPLETE notification
*
* When SCTP completes the shutdown procedures (section 9.2) this
__u16 len;
__u32 tsn;
- /* RFC 2960 8.5 Verification Tag
- *
- * When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag.
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+ if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
__u16 len;
__u32 tsn;
- /* RFC 2960 8.5 Verification Tag
- *
- * When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag.
- */
- if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
+ if (!sctp_vtag_verify(chunk, asoc)) {
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
SCTP_NULL());
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
- * that the value in the Verification Tag field of the
- * received SCTP packet matches its own Tag. If the received
- * Verification Tag value does not match the receiver's own
- * tag value, the receiver shall silently discard the packet.
- */
- if (ntohl(unk_chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
+ if (!sctp_vtag_verify(unk_chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
switch (type.chunk & SCTP_CID_ACTION_MASK) {
if (!asoc) {
SCTP_DEBUG_PRINTK("There is no association yet.\n");
+ if (sinfo_flags & (MSG_EOF | MSG_ABORT)) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
/* Check for invalid stream against the stream counts,
* either the default or the user specified stream counts.
*/
if (len != sizeof(struct sctp_paddrparams))
return -EINVAL;
- if (copy_from_user(¶ms, optval, *optlen)) /* XXXXXX */
+ if (copy_from_user(¶ms, optval, len))
return -EFAULT;
trans = sctp_addr_id2transport(sk, ¶ms.spp_address,
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_sockaddr_entry *from;
- void *to;
+ void __user *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
int addrlen;
bp = &asoc->base.bind_addr;
}
- to = (void *)getaddrs.addrs;
+ to = getaddrs.addrs;
list_for_each(pos, &bp->address_list) {
from = list_entry(pos,
struct sctp_sockaddr_entry,
return err;
do_error:
- err = -ECONNREFUSED;
+ if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >=
+ asoc->max_init_attempts)
+ err = -ETIMEDOUT;
+ else
+ err = -ECONNREFUSED;
goto out;
do_interrupted:
return -EINVAL;
}
if (put_user((*(int *)(table->data) * 1000) / HZ,
- (int *)oldval) ||
+ (int __user *)oldval) ||
(oldlenp && put_user(sizeof (int), oldlenp)))
return -EFAULT;
}
if (newlen != sizeof (int))
return -EINVAL;
- if (get_user(new, (int *)newval))
+ if (get_user(new, (int __user *)newval))
return -EFAULT;
*(int *)(table->data) = (new * HZ) / 1000;
*/
static DECLARE_MUTEX(br_ioctl_mutex);
-static int (*br_ioctl_hook)(unsigned int cmd, unsigned long arg) = NULL;
+static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL;
-void brioctl_set(int (*hook)(unsigned int, unsigned long))
+void brioctl_set(int (*hook)(unsigned int, void __user *))
{
down(&br_ioctl_mutex);
br_ioctl_hook = hook;
EXPORT_SYMBOL(brioctl_set);
static DECLARE_MUTEX(vlan_ioctl_mutex);
-static int (*vlan_ioctl_hook)(unsigned long arg);
+static int (*vlan_ioctl_hook)(void __user *arg);
-void vlan_ioctl_set(int (*hook)(unsigned long))
+void vlan_ioctl_set(int (*hook)(void __user *))
{
down(&vlan_ioctl_mutex);
vlan_ioctl_hook = hook;
EXPORT_SYMBOL(vlan_ioctl_set);
static DECLARE_MUTEX(dlci_ioctl_mutex);
-static int (*dlci_ioctl_hook)(unsigned int, void *);
+static int (*dlci_ioctl_hook)(unsigned int, void __user *);
-void dlci_ioctl_set(int (*hook)(unsigned int, void *))
+void dlci_ioctl_set(int (*hook)(unsigned int, void __user *))
{
down(&dlci_ioctl_mutex);
dlci_ioctl_hook = hook;
unsigned long arg)
{
struct socket *sock;
+ void __user *argp = (void __user *)arg;
int pid, err;
unlock_kernel();
sock = SOCKET_I(inode);
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
- err = dev_ioctl(cmd, (void __user *)arg);
+ err = dev_ioctl(cmd, argp);
} else
#ifdef WIRELESS_EXT
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
- err = dev_ioctl(cmd, (void __user *)arg);
+ err = dev_ioctl(cmd, argp);
} else
#endif /* WIRELESS_EXT */
switch (cmd) {
case FIOSETOWN:
case SIOCSPGRP:
err = -EFAULT;
- if (get_user(pid, (int __user *)arg))
+ if (get_user(pid, (int __user *)argp))
break;
err = f_setown(sock->file, pid, 1);
break;
case FIOGETOWN:
case SIOCGPGRP:
- err = put_user(sock->file->f_owner.pid, (int __user *)arg);
+ err = put_user(sock->file->f_owner.pid, (int __user *)argp);
break;
case SIOCGIFBR:
case SIOCSIFBR:
down(&br_ioctl_mutex);
if (br_ioctl_hook)
- err = br_ioctl_hook(cmd, arg);
+ err = br_ioctl_hook(cmd, argp);
up(&br_ioctl_mutex);
break;
case SIOCGIFVLAN:
down(&vlan_ioctl_mutex);
if (vlan_ioctl_hook)
- err = vlan_ioctl_hook(arg);
+ err = vlan_ioctl_hook(argp);
up(&vlan_ioctl_mutex);
break;
case SIOCGIFDIVERT:
case SIOCSIFDIVERT:
/* Convert this to call through a hook */
- err = divert_ioctl(cmd, (struct divert_cf *)arg);
+ err = divert_ioctl(cmd, argp);
break;
case SIOCADDDLCI:
case SIOCDELDLCI:
if (dlci_ioctl_hook) {
down(&dlci_ioctl_mutex);
- err = dlci_ioctl_hook(cmd, (void *)arg);
+ err = dlci_ioctl_hook(cmd, argp);
up(&dlci_ioctl_mutex);
}
break;
spin_unlock(&gss_auth->lock);
rpc_release_client(clnt);
kfree(obj.data);
- dprintk("RPC: gss_pipe_downcall returning length %u\n", mlen);
+ dprintk("RPC: gss_pipe_downcall returning length %Zu\n", mlen);
return mlen;
err:
if (ctx)
new->handle.data = tmp->handle.data;
tmp->handle.data = NULL;
new->mechctx = NULL;
+ new->cred.cr_group_info = NULL;
}
static inline void
struct rsc rsci;
struct rsc *found;
- rsci.handle = *handle;
+ memset(&rsci, 0, sizeof(rsci));
+ if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
+ return NULL;
found = rsc_lookup(&rsci, 0);
+ rsc_free(&rsci);
if (!found)
return NULL;
if (cache_check(&rsc_cache, &found->h, NULL))
struct auth_ops svcauthops_gss = {
.name = "rpcsec_gss",
+ .owner = THIS_MODULE,
.flavour = RPC_AUTH_GSS,
.accept = svcauth_gss_accept,
.release = svcauth_gss_release,
int
gss_svc_init(void)
{
- cache_register(&rsc_cache);
- cache_register(&rsi_cache);
- svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
- return 0;
+ int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
+ if (rv == 0) {
+ cache_register(&rsc_cache);
+ cache_register(&rsi_cache);
+ }
+ return rv;
}
void
{
cache_unregister(&rsc_cache);
cache_unregister(&rsi_cache);
+ svc_auth_unregister(RPC_AUTH_GSS);
}
#include <linux/types.h>
#include <linux/sched.h>
+#include <linux/module.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/svcsock.h>
extern struct auth_ops svcauth_null;
extern struct auth_ops svcauth_unix;
+static spinlock_t authtab_lock = SPIN_LOCK_UNLOCKED;
static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = {
[0] = &svcauth_null,
[1] = &svcauth_unix,
flavor = ntohl(svc_getu32(&rqstp->rq_arg.head[0]));
dprintk("svc: svc_authenticate (%d)\n", flavor);
- if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])) {
+
+ spin_lock(&authtab_lock);
+ if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])
+ || !try_module_get(aops->owner)) {
+ spin_unlock(&authtab_lock);
*authp = rpc_autherr_badcred;
return SVC_DENIED;
}
+ spin_unlock(&authtab_lock);
rqstp->rq_authop = aops;
return aops->accept(rqstp, authp);
rqstp->rq_authop = NULL;
- if (aops)
+ if (aops) {
rv = aops->release(rqstp);
-
- /* FIXME should I count and release authops */
+ module_put(aops->owner);
+ }
return rv;
}
int
svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
{
- if (flavor >= RPC_AUTH_MAXFLAVOR || authtab[flavor])
- return -EINVAL;
- authtab[flavor] = aops;
- return 0;
+ int rv = -EINVAL;
+ spin_lock(&authtab_lock);
+ if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) {
+ authtab[flavor] = aops;
+ rv = 0;
+ }
+ spin_unlock(&authtab_lock);
+ return rv;
}
void
svc_auth_unregister(rpc_authflavor_t flavor)
{
+ spin_lock(&authtab_lock);
if (flavor < RPC_AUTH_MAXFLAVOR)
authtab[flavor] = NULL;
+ spin_unlock(&authtab_lock);
}
+EXPORT_SYMBOL(svc_auth_unregister);
/**************************************************
* cache for domain name to auth_domain
#include <linux/types.h>
#include <linux/sched.h>
+#include <linux/module.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/svcsock.h>
struct auth_ops svcauth_null = {
.name = "null",
+ .owner = THIS_MODULE,
.flavour = RPC_AUTH_NULL,
.accept = svcauth_null_accept,
.release = svcauth_null_release,
struct auth_ops svcauth_unix = {
.name = "unix",
+ .owner = THIS_MODULE,
.flavour = RPC_AUTH_UNIX,
.accept = svcauth_unix_accept,
.release = svcauth_unix_release,
int wspace;
if (svsk->sk_sock->type == SOCK_STREAM)
- wspace = tcp_wspace(svsk->sk_sk);
+ wspace = sk_stream_wspace(svsk->sk_sk);
else
wspace = sock_wspace(svsk->sk_sk);
/* Wait until we have enough socket memory */
if (xprt->stream) {
- /* from net/ipv4/tcp.c:tcp_write_space */
- if (tcp_wspace(sk) < tcp_min_write_space(sk))
+ /* from net/core/stream.c:sk_stream_write_space */
+ if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
goto out;
} else {
/* from net/core/sock.c:sock_def_write_space */
if (sk->sk_state != WANSOCK_CONNECTED)
return -ENOTCONN;
- if (msg->msg_flags&~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return(-EINVAL);
/* it was <=, now one can send
*/
static int wanrouter_device_setup(struct wan_device *wandev,
- wandev_conf_t *u_conf);
+ wandev_conf_t __user *u_conf);
static int wanrouter_device_stat(struct wan_device *wandev,
- wandev_stat_t *u_stat);
+ wandev_stat_t __user *u_stat);
static int wanrouter_device_shutdown(struct wan_device *wandev);
static int wanrouter_device_new_if(struct wan_device *wandev,
- wanif_conf_t *u_conf);
-static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name);
+ wanif_conf_t __user *u_conf);
+static int wanrouter_device_del_if(struct wan_device *wandev,
+ char __user *u_name);
/*
* Miscellaneous
int err = 0;
struct proc_dir_entry *dent;
struct wan_device *wandev;
+ void __user *data = (void __user *)arg;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
switch (cmd) {
case ROUTER_SETUP:
- err = wanrouter_device_setup(wandev, (void*)arg);
+ err = wanrouter_device_setup(wandev, data);
break;
case ROUTER_DOWN:
break;
case ROUTER_STAT:
- err = wanrouter_device_stat(wandev, (void*)arg);
+ err = wanrouter_device_stat(wandev, data);
break;
case ROUTER_IFNEW:
- err = wanrouter_device_new_if(wandev, (void*)arg);
+ err = wanrouter_device_new_if(wandev, data);
break;
case ROUTER_IFDEL:
- err = wanrouter_device_del_if(wandev, (void*)arg);
+ err = wanrouter_device_del_if(wandev, data);
break;
case ROUTER_IFSTAT:
*/
static int wanrouter_device_setup(struct wan_device *wandev,
- wandev_conf_t *u_conf)
+ wandev_conf_t __user *u_conf)
{
void *data = NULL;
wandev_conf_t *conf;
*/
static int wanrouter_device_stat(struct wan_device *wandev,
- wandev_stat_t *u_stat)
+ wandev_stat_t __user *u_stat)
{
wandev_stat_t stat;
*/
static int wanrouter_device_new_if(struct wan_device *wandev,
- wanif_conf_t *u_conf)
+ wanif_conf_t __user *u_conf)
{
wanif_conf_t *cnf;
struct net_device *dev = NULL;
* o copy configuration data to kernel address space
*/
-static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name)
+static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name)
{
char name[WAN_IFNAME_SZ + 1];
int err = 0;
size_t size;
int qbit = 0, rc = -EINVAL;
- if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR|MSG_CMSG_COMPAT))
goto out;
/* we currently don't support segmented records at the user interface */
{
struct sock *sk = sock->sk;
struct x25_opt *x25 = x25_sk(sk);
+ void __user *argp = (void __user *)arg;
int rc;
switch (cmd) {
atomic_read(&sk->sk_wmem_alloc);
if (amount < 0)
amount = 0;
- rc = put_user(amount, (unsigned int *)arg);
+ rc = put_user(amount, (unsigned int __user *)argp);
break;
}
*/
if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
amount = skb->len;
- rc = put_user(amount, (unsigned int *)arg);
+ rc = put_user(amount, (unsigned int __user *)argp);
break;
}
rc = -EINVAL;
if (sk)
rc = sock_get_timestamp(sk,
- (struct timeval __user *)arg);
+ (struct timeval __user *)argp);
break;
case SIOCGIFADDR:
case SIOCSIFADDR:
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
- rc = x25_route_ioctl(cmd, (void *)arg);
+ rc = x25_route_ioctl(cmd, argp);
break;
case SIOCX25GSUBSCRIP:
- rc = x25_subscr_ioctl(cmd, (void *)arg);
+ rc = x25_subscr_ioctl(cmd, argp);
break;
case SIOCX25SSUBSCRIP:
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
- rc = x25_subscr_ioctl(cmd, (void *)arg);
+ rc = x25_subscr_ioctl(cmd, argp);
break;
case SIOCX25GFACILITIES: {
struct x25_facilities fac = x25->facilities;
- rc = copy_to_user((void *)arg, &fac,
+ rc = copy_to_user(argp, &fac,
sizeof(fac)) ? -EFAULT : 0;
break;
}
case SIOCX25SFACILITIES: {
struct x25_facilities facilities;
rc = -EFAULT;
- if (copy_from_user(&facilities, (void *)arg,
+ if (copy_from_user(&facilities, argp,
sizeof(facilities)))
break;
rc = -EINVAL;
case SIOCX25GCALLUSERDATA: {
struct x25_calluserdata cud = x25->calluserdata;
- rc = copy_to_user((void *)arg, &cud,
+ rc = copy_to_user(argp, &cud,
sizeof(cud)) ? -EFAULT : 0;
break;
}
struct x25_calluserdata calluserdata;
rc = -EFAULT;
- if (copy_from_user(&calluserdata, (void *)arg,
+ if (copy_from_user(&calluserdata, argp,
sizeof(calluserdata)))
break;
rc = -EINVAL;
case SIOCX25GCAUSEDIAG: {
struct x25_causediag causediag;
causediag = x25->causediag;
- rc = copy_to_user((void *)arg, &causediag,
+ rc = copy_to_user(argp, &causediag,
sizeof(causediag)) ? -EFAULT : 0;
break;
}
default:
- rc = dev_ioctl(cmd, (void __user *)arg);
+ rc = dev_ioctl(cmd, argp);
break;
}
/*
* Handle the ioctls that control the subscription functions.
*/
-int x25_subscr_ioctl(unsigned int cmd, void *arg)
+int x25_subscr_ioctl(unsigned int cmd, void __user *arg)
{
struct x25_subscrip_struct x25_subscr;
struct x25_neigh *nb;
/*
* Handle the ioctls that control the routing functions.
*/
-int x25_route_ioctl(unsigned int cmd, void *arg)
+int x25_route_ioctl(unsigned int cmd, void __user *arg)
{
struct x25_route_struct rt;
struct net_device *dev;
/usr/include/features.h \
/usr/include/sys/cdefs.h \
/usr/include/gnu/stubs.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
/usr/include/bits/typesizes.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
/usr/include/bits/posix_opt.h \
/usr/include/bits/confname.h \
/usr/include/getopt.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/bits/sigaction.h \
/usr/include/bits/sigcontext.h \
/usr/include/asm/sigcontext.h \
- /usr/include/linux/compiler.h \
- /usr/include/linux/compiler-gcc3.h \
- /usr/include/linux/compiler-gcc.h \
/usr/include/bits/sigstack.h \
/usr/include/bits/sigthread.h \
/usr/include/sys/resource.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/endian.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/time.h \
/usr/include/bits/stat.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
- /usr/include/asm-generic/errno.h \
- /usr/include/asm-generic/errno-base.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/stdio.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
# $1 (first bracket) matches the size of the stack growth
#
# use anything else and feel the pain ;)
+my (@stack, $re, $x, $xs);
{
my $arch = shift;
if ($arch eq "") {
$x = "[0-9a-f]"; # hex character
$xs = "[0-9a-f ]"; # hex character or space
- if ($arch =~ /^arm$/) {
+ if ($arch eq 'arm') {
#c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
$re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
} elsif ($arch =~ /^i[3456]86$/) {
#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
$re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o;
- } elsif ($arch =~ /^ia64$/) {
+ } elsif ($arch eq 'ia64') {
#e0000000044011fc: 01 0f fc 8c adds r12=-384,r12
$re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
- } elsif ($arch =~ /^mips64$/) {
+ } elsif ($arch eq 'mips64') {
#8800402c: 67bdfff0 daddiu sp,sp,-16
$re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
- } elsif ($arch =~ /^mips$/) {
+ } elsif ($arch eq 'mips') {
#88003254: 27bdffe0 addiu sp,sp,-32
$re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
- } elsif ($arch =~ /^ppc$/) {
+ } elsif ($arch eq 'ppc') {
#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
$re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
- } elsif ($arch =~ /^ppc64$/) {
+ } elsif ($arch eq 'ppc64') {
#XXX
$re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
} elsif ($arch =~ /^s390x?$/) {
}
sub bysize($) {
+ my ($asize, $bsize);
($asize = $a) =~ s/.* +(.*)$/$1/;
($bsize = $b) =~ s/.* +(.*)$/$1/;
$bsize <=> $asize
#
# main()
#
-$funcre = qr/^$x* \<(.*)\>:$/;
-while ($line = <STDIN>) {
+my $funcre = qr/^$x* <(.*)>:$/;
+my $func;
+while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) {
$func = $1;
}
$size += 0x80000000;
}
- $line =~ m/^($xs*).*/;
+ next if $line !~ m/^($xs*)/;
my $addr = $1;
$addr =~ s/ /0/g;
$addr = "0x$addr";
$padlen -= 8;
}
next if ($size < 100);
- $stack[@stack] = "$intro$size\n";
+ push @stack, "$intro$size\n";
}
}
-@sortedstack = sort bysize @stack;
-
-foreach $i (@sortedstack) {
- print("$i");
-}
+print sort bysize @stack;
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
/usr/include/wchar.h \
/usr/include/bits/wchar.h \
/usr/include/gconv.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \
scripts/kconfig/lkc_proto.h \
scripts/kconfig/conf.o: $(deps_scripts/kconfig/conf.o)
/usr/include/bits/sigset.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/bits/signum.h \
/usr/include/time.h \
/usr/include/bits/sigaction.h \
/usr/include/bits/sigcontext.h \
/usr/include/asm/sigcontext.h \
- /usr/include/linux/compiler.h \
- /usr/include/linux/compiler-gcc3.h \
- /usr/include/linux/compiler-gcc.h \
/usr/include/bits/sigstack.h \
/usr/include/bits/pthreadtypes.h \
/usr/include/bits/sched.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
- /usr/include/asm-generic/errno.h \
- /usr/include/asm-generic/errno-base.h \
/usr/include/fcntl.h \
/usr/include/bits/fcntl.h \
/usr/include/sys/types.h \
/usr/include/sys/select.h \
/usr/include/bits/select.h \
/usr/include/sys/sysmacros.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
/usr/include/linux/limits.h \
/usr/include/bits/posix2_lim.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
/usr/include/stdlib.h \
/usr/include/alloca.h \
/usr/include/string.h \
/usr/include/bits/stdio_lim.h \
/usr/include/bits/sys_errlist.h \
/usr/include/bits/stdio.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \
scripts/kconfig/lkc_proto.h \
scripts/kconfig/mconf.o: $(deps_scripts/kconfig/mconf.o)
/usr/include/gnu/stubs.h \
/usr/include/bits/types.h \
/usr/include/bits/wordsize.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stddef.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \
/usr/include/bits/typesizes.h \
/usr/include/endian.h \
/usr/include/bits/endian.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdarg.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \
/usr/include/stdio.h \
/usr/include/libio.h \
/usr/include/_G_config.h \
/usr/include/string.h \
/usr/include/bits/string.h \
/usr/include/bits/string2.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/stdbool.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \
scripts/kconfig/lkc.h \
scripts/kconfig/expr.h \
scripts/kconfig/lkc_proto.h \
/usr/include/bits/errno.h \
/usr/include/linux/errno.h \
/usr/include/asm/errno.h \
- /usr/include/asm-generic/errno.h \
- /usr/include/asm-generic/errno-base.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/limits.h \
- /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.2/include/syslimits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \
/usr/include/limits.h \
/usr/include/bits/posix1_lim.h \
/usr/include/bits/local_lim.h \
if (($line =~ /\.init$/ || $line =~ /\.init\./) &&
($from !~ /\.init$/ &&
$from !~ /\.init\./ &&
+ $from !~ /\.eh_frame$/ &&
$from !~ /\.stab$/ &&
$from !~ /\.rodata$/ &&
$from !~ /\.text\.lock$/ &&
return 0;
}
-static int dummy_shm_shmat (struct shmid_kernel *shp, char *shmaddr,
+static int dummy_shm_shmat (struct shmid_kernel *shp, char __user *shmaddr,
int shmflg)
{
return 0;
return 0;
}
-static int dummy_netlink_send (struct sk_buff *skb)
+static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
{
if (current->euid == 0)
cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
-selinux-y := avc.o hooks.o selinuxfs.o netlink.o
+selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o
selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
#define XATTR_SELINUX_SUFFIX "selinux"
#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
+extern int policydb_loaded_version;
+extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
+
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
int selinux_enforcing = 0;
return SECCLASS_FILE;
}
-static inline u16 socket_type_to_security_class(int family, int type)
+static inline u16 socket_type_to_security_class(int family, int type, int protocol)
{
switch (family) {
case PF_UNIX:
return SECCLASS_RAWIP_SOCKET;
}
case PF_NETLINK:
- return SECCLASS_NETLINK_SOCKET;
+ switch (protocol) {
+ case NETLINK_ROUTE:
+ return SECCLASS_NETLINK_ROUTE_SOCKET;
+ case NETLINK_FIREWALL:
+ return SECCLASS_NETLINK_FIREWALL_SOCKET;
+ case NETLINK_TCPDIAG:
+ return SECCLASS_NETLINK_TCPDIAG_SOCKET;
+ case NETLINK_NFLOG:
+ return SECCLASS_NETLINK_NFLOG_SOCKET;
+ case NETLINK_XFRM:
+ return SECCLASS_NETLINK_XFRM_SOCKET;
+ case NETLINK_SELINUX:
+ return SECCLASS_NETLINK_SELINUX_SOCKET;
+ case NETLINK_AUDIT:
+ return SECCLASS_NETLINK_AUDIT_SOCKET;
+ case NETLINK_IP6_FW:
+ return SECCLASS_NETLINK_IP6FW_SOCKET;
+ case NETLINK_DNRTMSG:
+ return SECCLASS_NETLINK_DNRT_SOCKET;
+ default:
+ return SECCLASS_NETLINK_SOCKET;
+ }
case PF_PACKET:
return SECCLASS_PACKET_SOCKET;
case PF_KEY:
struct socket *sock = SOCKET_I(inode);
if (sock->sk) {
isec->sclass = socket_type_to_security_class(sock->sk->sk_family,
- sock->sk->sk_type);
+ sock->sk->sk_type,
+ sock->sk->sk_protocol);
} else {
isec->sclass = SECCLASS_SOCKET;
}
if (error)
return;
- return secondary_ops->capset_set(target, effective, inheritable, permitted);
+ secondary_ops->capset_set(target, effective, inheritable, permitted);
}
static int selinux_capable(struct task_struct *tsk, int cap)
return -ENOMEM;
}
-static int selinux_netlink_send(struct sk_buff *skb)
-{
- if (capable(CAP_NET_ADMIN))
- cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
- else
- NETLINK_CB(skb).eff_cap = 0;
- return 0;
-}
-
-static int selinux_netlink_recv(struct sk_buff *skb)
-{
- if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
- return -EPERM;
- return 0;
-}
-
/* binprm security operations */
static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
tsec = current->security;
err = avc_has_perm(tsec->sid, tsec->sid,
- socket_type_to_security_class(family, type),
- SOCKET__CREATE, NULL, NULL);
+ socket_type_to_security_class(family, type,
+ protocol), SOCKET__CREATE, NULL, NULL);
out:
return err;
isec = SOCK_INODE(sock)->i_security;
tsec = current->security;
- isec->sclass = socket_type_to_security_class(family, type);
+ isec->sclass = socket_type_to_security_class(family, type, protocol);
isec->sid = kern ? SECINITSID_KERNEL : tsec->sid;
return;
sk_free_security(sk);
}
+static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
+{
+ int err = 0;
+ u32 perm;
+ struct nlmsghdr *nlh;
+ struct socket *sock = sk->sk_socket;
+ struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
+
+ if (skb->len < NLMSG_SPACE(0)) {
+ err = -EINVAL;
+ goto out;
+ }
+ nlh = (struct nlmsghdr *)skb->data;
+
+ err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
+ if (err) {
+ /* Ignore */
+ if (err == -ENOENT)
+ err = 0;
+ goto out;
+ }
+
+ err = socket_has_perm(current, sock, perm);
+out:
+ return err;
+}
+
+static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
+{
+ int err = 0;
+
+ if (capable(CAP_NET_ADMIN))
+ cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
+ else
+ NETLINK_CB(skb).eff_cap = 0;
+
+ if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
+ err = selinux_nlmsg_perm(sk, skb);
+
+ return err;
+}
+
+static int selinux_netlink_recv(struct sk_buff *skb)
+{
+ if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
+ return -EPERM;
+ return 0;
+}
+
#ifdef CONFIG_NETFILTER
static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
static void selinux_msg_msg_free_security(struct msg_msg *msg)
{
- return msg_msg_free_security(msg);
+ msg_msg_free_security(msg);
}
/* message queue security operations */
}
static int selinux_shm_shmat(struct shmid_kernel *shp,
- char *shmaddr, int shmflg)
+ char __user *shmaddr, int shmflg)
{
u32 perms;
{ SECCLASS_SEM, common_ipc_perm_to_string, 0x00000200UL },
{ SECCLASS_MSGQ, common_ipc_perm_to_string, 0x00000200UL },
{ SECCLASS_SHM, common_ipc_perm_to_string, 0x00000200UL },
+ { SECCLASS_NETLINK_ROUTE_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_FIREWALL_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_TCPDIAG_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_NFLOG_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_XFRM_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_SELINUX_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_AUDIT_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_IP6FW_SOCKET, common_socket_perm_to_string, 0x00400000UL },
+ { SECCLASS_NETLINK_DNRT_SOCKET, common_socket_perm_to_string, 0x00400000UL },
};
{ SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto" },
{ SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn" },
{ SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom" },
+ { SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind" },
+ { SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind" },
+ { SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind" },
{ SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv" },
{ SECCLASS_NODE, NODE__TCP_SEND, "tcp_send" },
{ SECCLASS_NODE, NODE__UDP_RECV, "udp_recv" },
{ SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto" },
{ SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn" },
{ SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom" },
- { SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind" },
- { SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind" },
- { SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind" },
{ SECCLASS_PROCESS, PROCESS__FORK, "fork" },
{ SECCLASS_PROCESS, PROCESS__TRANSITION, "transition" },
{ SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld" },
{ SECCLASS_PASSWD, PASSWD__PASSWD, "passwd" },
{ SECCLASS_PASSWD, PASSWD__CHFN, "chfn" },
{ SECCLASS_PASSWD, PASSWD__CHSH, "chsh" },
+ { SECCLASS_PASSWD, PASSWD__ROOTOK, "rootok" },
+ { SECCLASS_DRAWABLE, DRAWABLE__CREATE, "create" },
+ { SECCLASS_DRAWABLE, DRAWABLE__DESTROY, "destroy" },
+ { SECCLASS_DRAWABLE, DRAWABLE__DRAW, "draw" },
+ { SECCLASS_DRAWABLE, DRAWABLE__COPY, "copy" },
+ { SECCLASS_DRAWABLE, DRAWABLE__GETATTR, "getattr" },
+ { SECCLASS_GC, GC__CREATE, "create" },
+ { SECCLASS_GC, GC__FREE, "free" },
+ { SECCLASS_GC, GC__GETATTR, "getattr" },
+ { SECCLASS_GC, GC__SETATTR, "setattr" },
+ { SECCLASS_WINDOW, WINDOW__ADDCHILD, "addchild" },
+ { SECCLASS_WINDOW, WINDOW__CREATE, "create" },
+ { SECCLASS_WINDOW, WINDOW__DESTROY, "destroy" },
+ { SECCLASS_WINDOW, WINDOW__MAP, "map" },
+ { SECCLASS_WINDOW, WINDOW__UNMAP, "unmap" },
+ { SECCLASS_WINDOW, WINDOW__CHSTACK, "chstack" },
+ { SECCLASS_WINDOW, WINDOW__CHPROPLIST, "chproplist" },
+ { SECCLASS_WINDOW, WINDOW__CHPROP, "chprop" },
+ { SECCLASS_WINDOW, WINDOW__LISTPROP, "listprop" },
+ { SECCLASS_WINDOW, WINDOW__GETATTR, "getattr" },
+ { SECCLASS_WINDOW, WINDOW__SETATTR, "setattr" },
+ { SECCLASS_WINDOW, WINDOW__SETFOCUS, "setfocus" },
+ { SECCLASS_WINDOW, WINDOW__MOVE, "move" },
+ { SECCLASS_WINDOW, WINDOW__CHSELECTION, "chselection" },
+ { SECCLASS_WINDOW, WINDOW__CHPARENT, "chparent" },
+ { SECCLASS_WINDOW, WINDOW__CTRLLIFE, "ctrllife" },
+ { SECCLASS_WINDOW, WINDOW__ENUMERATE, "enumerate" },
+ { SECCLASS_WINDOW, WINDOW__TRANSPARENT, "transparent" },
+ { SECCLASS_WINDOW, WINDOW__MOUSEMOTION, "mousemotion" },
+ { SECCLASS_WINDOW, WINDOW__CLIENTCOMEVENT, "clientcomevent" },
+ { SECCLASS_WINDOW, WINDOW__INPUTEVENT, "inputevent" },
+ { SECCLASS_WINDOW, WINDOW__DRAWEVENT, "drawevent" },
+ { SECCLASS_WINDOW, WINDOW__WINDOWCHANGEEVENT, "windowchangeevent" },
+ { SECCLASS_WINDOW, WINDOW__WINDOWCHANGEREQUEST, "windowchangerequest" },
+ { SECCLASS_WINDOW, WINDOW__SERVERCHANGEEVENT, "serverchangeevent" },
+ { SECCLASS_WINDOW, WINDOW__EXTENSIONEVENT, "extensionevent" },
+ { SECCLASS_FONT, FONT__LOAD, "load" },
+ { SECCLASS_FONT, FONT__FREE, "free" },
+ { SECCLASS_FONT, FONT__GETATTR, "getattr" },
+ { SECCLASS_FONT, FONT__USE, "use" },
+ { SECCLASS_COLORMAP, COLORMAP__CREATE, "create" },
+ { SECCLASS_COLORMAP, COLORMAP__FREE, "free" },
+ { SECCLASS_COLORMAP, COLORMAP__INSTALL, "install" },
+ { SECCLASS_COLORMAP, COLORMAP__UNINSTALL, "uninstall" },
+ { SECCLASS_COLORMAP, COLORMAP__LIST, "list" },
+ { SECCLASS_COLORMAP, COLORMAP__READ, "read" },
+ { SECCLASS_COLORMAP, COLORMAP__STORE, "store" },
+ { SECCLASS_COLORMAP, COLORMAP__GETATTR, "getattr" },
+ { SECCLASS_COLORMAP, COLORMAP__SETATTR, "setattr" },
+ { SECCLASS_PROPERTY, PROPERTY__CREATE, "create" },
+ { SECCLASS_PROPERTY, PROPERTY__FREE, "free" },
+ { SECCLASS_PROPERTY, PROPERTY__READ, "read" },
+ { SECCLASS_PROPERTY, PROPERTY__WRITE, "write" },
+ { SECCLASS_CURSOR, CURSOR__CREATE, "create" },
+ { SECCLASS_CURSOR, CURSOR__CREATEGLYPH, "createglyph" },
+ { SECCLASS_CURSOR, CURSOR__FREE, "free" },
+ { SECCLASS_CURSOR, CURSOR__ASSIGN, "assign" },
+ { SECCLASS_CURSOR, CURSOR__SETATTR, "setattr" },
+ { SECCLASS_XCLIENT, XCLIENT__KILL, "kill" },
+ { SECCLASS_XINPUT, XINPUT__LOOKUP, "lookup" },
+ { SECCLASS_XINPUT, XINPUT__GETATTR, "getattr" },
+ { SECCLASS_XINPUT, XINPUT__SETATTR, "setattr" },
+ { SECCLASS_XINPUT, XINPUT__SETFOCUS, "setfocus" },
+ { SECCLASS_XINPUT, XINPUT__WARPPOINTER, "warppointer" },
+ { SECCLASS_XINPUT, XINPUT__ACTIVEGRAB, "activegrab" },
+ { SECCLASS_XINPUT, XINPUT__PASSIVEGRAB, "passivegrab" },
+ { SECCLASS_XINPUT, XINPUT__UNGRAB, "ungrab" },
+ { SECCLASS_XINPUT, XINPUT__BELL, "bell" },
+ { SECCLASS_XINPUT, XINPUT__MOUSEMOTION, "mousemotion" },
+ { SECCLASS_XINPUT, XINPUT__RELABELINPUT, "relabelinput" },
+ { SECCLASS_XSERVER, XSERVER__SCREENSAVER, "screensaver" },
+ { SECCLASS_XSERVER, XSERVER__GETHOSTLIST, "gethostlist" },
+ { SECCLASS_XSERVER, XSERVER__SETHOSTLIST, "sethostlist" },
+ { SECCLASS_XSERVER, XSERVER__GETFONTPATH, "getfontpath" },
+ { SECCLASS_XSERVER, XSERVER__SETFONTPATH, "setfontpath" },
+ { SECCLASS_XSERVER, XSERVER__GETATTR, "getattr" },
+ { SECCLASS_XSERVER, XSERVER__GRAB, "grab" },
+ { SECCLASS_XSERVER, XSERVER__UNGRAB, "ungrab" },
+ { SECCLASS_XEXTENSION, XEXTENSION__QUERY, "query" },
+ { SECCLASS_XEXTENSION, XEXTENSION__USE, "use" },
+ { SECCLASS_PAX, PAX__PAGEEXEC, "pageexec" },
+ { SECCLASS_PAX, PAX__EMUTRAMP, "emutramp" },
+ { SECCLASS_PAX, PAX__MPROTECT, "mprotect" },
+ { SECCLASS_PAX, PAX__RANDMMAP, "randmmap" },
+ { SECCLASS_PAX, PAX__RANDEXEC, "randexec" },
+ { SECCLASS_PAX, PAX__SEGMEXEC, "segmexec" },
+ { SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read" },
+ { SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+ { SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read" },
+ { SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+ { SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read" },
+ { SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+ { SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read" },
+ { SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+ { SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read" },
+ { SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write" },
+ { SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read" },
+ { SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write" },
};
#define FILESYSTEM__QUOTAMOD 0x00000100UL
#define FILESYSTEM__QUOTAGET 0x00000200UL
-#define DIR__EXECUTE 0x00002000UL
-#define DIR__UNLINK 0x00000400UL
+#define DIR__IOCTL 0x00000001UL
+#define DIR__READ 0x00000002UL
+#define DIR__WRITE 0x00000004UL
+#define DIR__CREATE 0x00000008UL
+#define DIR__GETATTR 0x00000010UL
#define DIR__SETATTR 0x00000020UL
-#define DIR__QUOTAON 0x00008000UL
+#define DIR__LOCK 0x00000040UL
#define DIR__RELABELFROM 0x00000080UL
-#define DIR__LINK 0x00000800UL
-#define DIR__WRITE 0x00000004UL
-#define DIR__IOCTL 0x00000001UL
#define DIR__RELABELTO 0x00000100UL
-#define DIR__READ 0x00000002UL
-#define DIR__RENAME 0x00001000UL
#define DIR__APPEND 0x00000200UL
-#define DIR__LOCK 0x00000040UL
+#define DIR__UNLINK 0x00000400UL
+#define DIR__LINK 0x00000800UL
+#define DIR__RENAME 0x00001000UL
+#define DIR__EXECUTE 0x00002000UL
#define DIR__SWAPON 0x00004000UL
-#define DIR__GETATTR 0x00000010UL
+#define DIR__QUOTAON 0x00008000UL
#define DIR__MOUNTON 0x00010000UL
-#define DIR__CREATE 0x00000008UL
#define DIR__ADD_NAME 0x00020000UL
#define DIR__REMOVE_NAME 0x00040000UL
#define DIR__SEARCH 0x00100000UL
#define DIR__RMDIR 0x00200000UL
-#define FILE__EXECUTE 0x00002000UL
-#define FILE__UNLINK 0x00000400UL
+#define FILE__IOCTL 0x00000001UL
+#define FILE__READ 0x00000002UL
+#define FILE__WRITE 0x00000004UL
+#define FILE__CREATE 0x00000008UL
+#define FILE__GETATTR 0x00000010UL
#define FILE__SETATTR 0x00000020UL
-#define FILE__QUOTAON 0x00008000UL
+#define FILE__LOCK 0x00000040UL
#define FILE__RELABELFROM 0x00000080UL
-#define FILE__LINK 0x00000800UL
-#define FILE__WRITE 0x00000004UL
-#define FILE__IOCTL 0x00000001UL
#define FILE__RELABELTO 0x00000100UL
-#define FILE__READ 0x00000002UL
-#define FILE__RENAME 0x00001000UL
#define FILE__APPEND 0x00000200UL
-#define FILE__LOCK 0x00000040UL
+#define FILE__UNLINK 0x00000400UL
+#define FILE__LINK 0x00000800UL
+#define FILE__RENAME 0x00001000UL
+#define FILE__EXECUTE 0x00002000UL
#define FILE__SWAPON 0x00004000UL
-#define FILE__GETATTR 0x00000010UL
+#define FILE__QUOTAON 0x00008000UL
#define FILE__MOUNTON 0x00010000UL
-#define FILE__CREATE 0x00000008UL
#define FILE__EXECUTE_NO_TRANS 0x00020000UL
#define FILE__ENTRYPOINT 0x00040000UL
-#define LNK_FILE__EXECUTE 0x00002000UL
-#define LNK_FILE__UNLINK 0x00000400UL
+#define LNK_FILE__IOCTL 0x00000001UL
+#define LNK_FILE__READ 0x00000002UL
+#define LNK_FILE__WRITE 0x00000004UL
+#define LNK_FILE__CREATE 0x00000008UL
+#define LNK_FILE__GETATTR 0x00000010UL
#define LNK_FILE__SETATTR 0x00000020UL
-#define LNK_FILE__QUOTAON 0x00008000UL
+#define LNK_FILE__LOCK 0x00000040UL
#define LNK_FILE__RELABELFROM 0x00000080UL
-#define LNK_FILE__LINK 0x00000800UL
-#define LNK_FILE__WRITE 0x00000004UL
-#define LNK_FILE__IOCTL 0x00000001UL
#define LNK_FILE__RELABELTO 0x00000100UL
-#define LNK_FILE__READ 0x00000002UL
-#define LNK_FILE__RENAME 0x00001000UL
#define LNK_FILE__APPEND 0x00000200UL
-#define LNK_FILE__LOCK 0x00000040UL
+#define LNK_FILE__UNLINK 0x00000400UL
+#define LNK_FILE__LINK 0x00000800UL
+#define LNK_FILE__RENAME 0x00001000UL
+#define LNK_FILE__EXECUTE 0x00002000UL
#define LNK_FILE__SWAPON 0x00004000UL
-#define LNK_FILE__GETATTR 0x00000010UL
+#define LNK_FILE__QUOTAON 0x00008000UL
#define LNK_FILE__MOUNTON 0x00010000UL
-#define LNK_FILE__CREATE 0x00000008UL
-#define CHR_FILE__EXECUTE 0x00002000UL
-#define CHR_FILE__UNLINK 0x00000400UL
+#define CHR_FILE__IOCTL 0x00000001UL
+#define CHR_FILE__READ 0x00000002UL
+#define CHR_FILE__WRITE 0x00000004UL
+#define CHR_FILE__CREATE 0x00000008UL
+#define CHR_FILE__GETATTR 0x00000010UL
#define CHR_FILE__SETATTR 0x00000020UL
-#define CHR_FILE__QUOTAON 0x00008000UL
+#define CHR_FILE__LOCK 0x00000040UL
#define CHR_FILE__RELABELFROM 0x00000080UL
-#define CHR_FILE__LINK 0x00000800UL
-#define CHR_FILE__WRITE 0x00000004UL
-#define CHR_FILE__IOCTL 0x00000001UL
#define CHR_FILE__RELABELTO 0x00000100UL
-#define CHR_FILE__READ 0x00000002UL
-#define CHR_FILE__RENAME 0x00001000UL
#define CHR_FILE__APPEND 0x00000200UL
-#define CHR_FILE__LOCK 0x00000040UL
+#define CHR_FILE__UNLINK 0x00000400UL
+#define CHR_FILE__LINK 0x00000800UL
+#define CHR_FILE__RENAME 0x00001000UL
+#define CHR_FILE__EXECUTE 0x00002000UL
#define CHR_FILE__SWAPON 0x00004000UL
-#define CHR_FILE__GETATTR 0x00000010UL
+#define CHR_FILE__QUOTAON 0x00008000UL
#define CHR_FILE__MOUNTON 0x00010000UL
-#define CHR_FILE__CREATE 0x00000008UL
-#define BLK_FILE__EXECUTE 0x00002000UL
-#define BLK_FILE__UNLINK 0x00000400UL
+#define BLK_FILE__IOCTL 0x00000001UL
+#define BLK_FILE__READ 0x00000002UL
+#define BLK_FILE__WRITE 0x00000004UL
+#define BLK_FILE__CREATE 0x00000008UL
+#define BLK_FILE__GETATTR 0x00000010UL
#define BLK_FILE__SETATTR 0x00000020UL
-#define BLK_FILE__QUOTAON 0x00008000UL
+#define BLK_FILE__LOCK 0x00000040UL
#define BLK_FILE__RELABELFROM 0x00000080UL
-#define BLK_FILE__LINK 0x00000800UL
-#define BLK_FILE__WRITE 0x00000004UL
-#define BLK_FILE__IOCTL 0x00000001UL
#define BLK_FILE__RELABELTO 0x00000100UL
-#define BLK_FILE__READ 0x00000002UL
-#define BLK_FILE__RENAME 0x00001000UL
#define BLK_FILE__APPEND 0x00000200UL
-#define BLK_FILE__LOCK 0x00000040UL
+#define BLK_FILE__UNLINK 0x00000400UL
+#define BLK_FILE__LINK 0x00000800UL
+#define BLK_FILE__RENAME 0x00001000UL
+#define BLK_FILE__EXECUTE 0x00002000UL
#define BLK_FILE__SWAPON 0x00004000UL
-#define BLK_FILE__GETATTR 0x00000010UL
+#define BLK_FILE__QUOTAON 0x00008000UL
#define BLK_FILE__MOUNTON 0x00010000UL
-#define BLK_FILE__CREATE 0x00000008UL
-#define SOCK_FILE__EXECUTE 0x00002000UL
-#define SOCK_FILE__UNLINK 0x00000400UL
+#define SOCK_FILE__IOCTL 0x00000001UL
+#define SOCK_FILE__READ 0x00000002UL
+#define SOCK_FILE__WRITE 0x00000004UL
+#define SOCK_FILE__CREATE 0x00000008UL
+#define SOCK_FILE__GETATTR 0x00000010UL
#define SOCK_FILE__SETATTR 0x00000020UL
-#define SOCK_FILE__QUOTAON 0x00008000UL
+#define SOCK_FILE__LOCK 0x00000040UL
#define SOCK_FILE__RELABELFROM 0x00000080UL
-#define SOCK_FILE__LINK 0x00000800UL
-#define SOCK_FILE__WRITE 0x00000004UL
-#define SOCK_FILE__IOCTL 0x00000001UL
#define SOCK_FILE__RELABELTO 0x00000100UL
-#define SOCK_FILE__READ 0x00000002UL
-#define SOCK_FILE__RENAME 0x00001000UL
#define SOCK_FILE__APPEND 0x00000200UL
-#define SOCK_FILE__LOCK 0x00000040UL
+#define SOCK_FILE__UNLINK 0x00000400UL
+#define SOCK_FILE__LINK 0x00000800UL
+#define SOCK_FILE__RENAME 0x00001000UL
+#define SOCK_FILE__EXECUTE 0x00002000UL
#define SOCK_FILE__SWAPON 0x00004000UL
-#define SOCK_FILE__GETATTR 0x00000010UL
+#define SOCK_FILE__QUOTAON 0x00008000UL
#define SOCK_FILE__MOUNTON 0x00010000UL
-#define SOCK_FILE__CREATE 0x00000008UL
-#define FIFO_FILE__EXECUTE 0x00002000UL
-#define FIFO_FILE__UNLINK 0x00000400UL
+#define FIFO_FILE__IOCTL 0x00000001UL
+#define FIFO_FILE__READ 0x00000002UL
+#define FIFO_FILE__WRITE 0x00000004UL
+#define FIFO_FILE__CREATE 0x00000008UL
+#define FIFO_FILE__GETATTR 0x00000010UL
#define FIFO_FILE__SETATTR 0x00000020UL
-#define FIFO_FILE__QUOTAON 0x00008000UL
+#define FIFO_FILE__LOCK 0x00000040UL
#define FIFO_FILE__RELABELFROM 0x00000080UL
-#define FIFO_FILE__LINK 0x00000800UL
-#define FIFO_FILE__WRITE 0x00000004UL
-#define FIFO_FILE__IOCTL 0x00000001UL
#define FIFO_FILE__RELABELTO 0x00000100UL
-#define FIFO_FILE__READ 0x00000002UL
-#define FIFO_FILE__RENAME 0x00001000UL
#define FIFO_FILE__APPEND 0x00000200UL
-#define FIFO_FILE__LOCK 0x00000040UL
+#define FIFO_FILE__UNLINK 0x00000400UL
+#define FIFO_FILE__LINK 0x00000800UL
+#define FIFO_FILE__RENAME 0x00001000UL
+#define FIFO_FILE__EXECUTE 0x00002000UL
#define FIFO_FILE__SWAPON 0x00004000UL
-#define FIFO_FILE__GETATTR 0x00000010UL
+#define FIFO_FILE__QUOTAON 0x00008000UL
#define FIFO_FILE__MOUNTON 0x00010000UL
-#define FIFO_FILE__CREATE 0x00000008UL
#define FD__USE 0x00000001UL
-#define SOCKET__RELABELTO 0x00000100UL
-#define SOCKET__RECV_MSG 0x00080000UL
+#define SOCKET__IOCTL 0x00000001UL
+#define SOCKET__READ 0x00000002UL
+#define SOCKET__WRITE 0x00000004UL
+#define SOCKET__CREATE 0x00000008UL
+#define SOCKET__GETATTR 0x00000010UL
+#define SOCKET__SETATTR 0x00000020UL
+#define SOCKET__LOCK 0x00000040UL
#define SOCKET__RELABELFROM 0x00000080UL
-#define SOCKET__SETOPT 0x00008000UL
+#define SOCKET__RELABELTO 0x00000100UL
#define SOCKET__APPEND 0x00000200UL
-#define SOCKET__SETATTR 0x00000020UL
-#define SOCKET__SENDTO 0x00040000UL
-#define SOCKET__GETOPT 0x00004000UL
-#define SOCKET__READ 0x00000002UL
-#define SOCKET__SHUTDOWN 0x00010000UL
-#define SOCKET__LISTEN 0x00001000UL
#define SOCKET__BIND 0x00000400UL
-#define SOCKET__WRITE 0x00000004UL
-#define SOCKET__ACCEPT 0x00002000UL
#define SOCKET__CONNECT 0x00000800UL
-#define SOCKET__LOCK 0x00000040UL
-#define SOCKET__IOCTL 0x00000001UL
-#define SOCKET__CREATE 0x00000008UL
-#define SOCKET__NAME_BIND 0x00200000UL
-#define SOCKET__SEND_MSG 0x00100000UL
+#define SOCKET__LISTEN 0x00001000UL
+#define SOCKET__ACCEPT 0x00002000UL
+#define SOCKET__GETOPT 0x00004000UL
+#define SOCKET__SETOPT 0x00008000UL
+#define SOCKET__SHUTDOWN 0x00010000UL
#define SOCKET__RECVFROM 0x00020000UL
-#define SOCKET__GETATTR 0x00000010UL
+#define SOCKET__SENDTO 0x00040000UL
+#define SOCKET__RECV_MSG 0x00080000UL
+#define SOCKET__SEND_MSG 0x00100000UL
+#define SOCKET__NAME_BIND 0x00200000UL
-#define TCP_SOCKET__RELABELTO 0x00000100UL
-#define TCP_SOCKET__RECV_MSG 0x00080000UL
+#define TCP_SOCKET__IOCTL 0x00000001UL
+#define TCP_SOCKET__READ 0x00000002UL
+#define TCP_SOCKET__WRITE 0x00000004UL
+#define TCP_SOCKET__CREATE 0x00000008UL
+#define TCP_SOCKET__GETATTR 0x00000010UL
+#define TCP_SOCKET__SETATTR 0x00000020UL
+#define TCP_SOCKET__LOCK 0x00000040UL
#define TCP_SOCKET__RELABELFROM 0x00000080UL
-#define TCP_SOCKET__SETOPT 0x00008000UL
+#define TCP_SOCKET__RELABELTO 0x00000100UL
#define TCP_SOCKET__APPEND 0x00000200UL
-#define TCP_SOCKET__SETATTR 0x00000020UL
-#define TCP_SOCKET__SENDTO 0x00040000UL
-#define TCP_SOCKET__GETOPT 0x00004000UL
-#define TCP_SOCKET__READ 0x00000002UL
-#define TCP_SOCKET__SHUTDOWN 0x00010000UL
-#define TCP_SOCKET__LISTEN 0x00001000UL
#define TCP_SOCKET__BIND 0x00000400UL
-#define TCP_SOCKET__WRITE 0x00000004UL
-#define TCP_SOCKET__ACCEPT 0x00002000UL
#define TCP_SOCKET__CONNECT 0x00000800UL
-#define TCP_SOCKET__LOCK 0x00000040UL
-#define TCP_SOCKET__IOCTL 0x00000001UL
-#define TCP_SOCKET__CREATE 0x00000008UL
-#define TCP_SOCKET__NAME_BIND 0x00200000UL
-#define TCP_SOCKET__SEND_MSG 0x00100000UL
+#define TCP_SOCKET__LISTEN 0x00001000UL
+#define TCP_SOCKET__ACCEPT 0x00002000UL
+#define TCP_SOCKET__GETOPT 0x00004000UL
+#define TCP_SOCKET__SETOPT 0x00008000UL
+#define TCP_SOCKET__SHUTDOWN 0x00010000UL
#define TCP_SOCKET__RECVFROM 0x00020000UL
-#define TCP_SOCKET__GETATTR 0x00000010UL
+#define TCP_SOCKET__SENDTO 0x00040000UL
+#define TCP_SOCKET__RECV_MSG 0x00080000UL
+#define TCP_SOCKET__SEND_MSG 0x00100000UL
+#define TCP_SOCKET__NAME_BIND 0x00200000UL
#define TCP_SOCKET__CONNECTTO 0x00400000UL
#define TCP_SOCKET__NEWCONN 0x00800000UL
#define TCP_SOCKET__ACCEPTFROM 0x01000000UL
#define TCP_SOCKET__NODE_BIND 0x02000000UL
-#define UDP_SOCKET__RELABELTO 0x00000100UL
-#define UDP_SOCKET__RECV_MSG 0x00080000UL
+#define UDP_SOCKET__IOCTL 0x00000001UL
+#define UDP_SOCKET__READ 0x00000002UL
+#define UDP_SOCKET__WRITE 0x00000004UL
+#define UDP_SOCKET__CREATE 0x00000008UL
+#define UDP_SOCKET__GETATTR 0x00000010UL
+#define UDP_SOCKET__SETATTR 0x00000020UL
+#define UDP_SOCKET__LOCK 0x00000040UL
#define UDP_SOCKET__RELABELFROM 0x00000080UL
-#define UDP_SOCKET__SETOPT 0x00008000UL
+#define UDP_SOCKET__RELABELTO 0x00000100UL
#define UDP_SOCKET__APPEND 0x00000200UL
-#define UDP_SOCKET__SETATTR 0x00000020UL
-#define UDP_SOCKET__SENDTO 0x00040000UL
-#define UDP_SOCKET__GETOPT 0x00004000UL
-#define UDP_SOCKET__READ 0x00000002UL
-#define UDP_SOCKET__SHUTDOWN 0x00010000UL
-#define UDP_SOCKET__LISTEN 0x00001000UL
#define UDP_SOCKET__BIND 0x00000400UL
-#define UDP_SOCKET__WRITE 0x00000004UL
-#define UDP_SOCKET__ACCEPT 0x00002000UL
#define UDP_SOCKET__CONNECT 0x00000800UL
-#define UDP_SOCKET__LOCK 0x00000040UL
-#define UDP_SOCKET__IOCTL 0x00000001UL
-#define UDP_SOCKET__CREATE 0x00000008UL
-#define UDP_SOCKET__NAME_BIND 0x00200000UL
-#define UDP_SOCKET__SEND_MSG 0x00100000UL
+#define UDP_SOCKET__LISTEN 0x00001000UL
+#define UDP_SOCKET__ACCEPT 0x00002000UL
+#define UDP_SOCKET__GETOPT 0x00004000UL
+#define UDP_SOCKET__SETOPT 0x00008000UL
+#define UDP_SOCKET__SHUTDOWN 0x00010000UL
#define UDP_SOCKET__RECVFROM 0x00020000UL
-#define UDP_SOCKET__GETATTR 0x00000010UL
+#define UDP_SOCKET__SENDTO 0x00040000UL
+#define UDP_SOCKET__RECV_MSG 0x00080000UL
+#define UDP_SOCKET__SEND_MSG 0x00100000UL
+#define UDP_SOCKET__NAME_BIND 0x00200000UL
+
#define UDP_SOCKET__NODE_BIND 0x00400000UL
-#define RAWIP_SOCKET__RELABELTO 0x00000100UL
-#define RAWIP_SOCKET__RECV_MSG 0x00080000UL
+#define RAWIP_SOCKET__IOCTL 0x00000001UL
+#define RAWIP_SOCKET__READ 0x00000002UL
+#define RAWIP_SOCKET__WRITE 0x00000004UL
+#define RAWIP_SOCKET__CREATE 0x00000008UL
+#define RAWIP_SOCKET__GETATTR 0x00000010UL
+#define RAWIP_SOCKET__SETATTR 0x00000020UL
+#define RAWIP_SOCKET__LOCK 0x00000040UL
#define RAWIP_SOCKET__RELABELFROM 0x00000080UL
-#define RAWIP_SOCKET__SETOPT 0x00008000UL
+#define RAWIP_SOCKET__RELABELTO 0x00000100UL
#define RAWIP_SOCKET__APPEND 0x00000200UL
-#define RAWIP_SOCKET__SETATTR 0x00000020UL
-#define RAWIP_SOCKET__SENDTO 0x00040000UL
-#define RAWIP_SOCKET__GETOPT 0x00004000UL
-#define RAWIP_SOCKET__READ 0x00000002UL
-#define RAWIP_SOCKET__SHUTDOWN 0x00010000UL
-#define RAWIP_SOCKET__LISTEN 0x00001000UL
#define RAWIP_SOCKET__BIND 0x00000400UL
-#define RAWIP_SOCKET__WRITE 0x00000004UL
-#define RAWIP_SOCKET__ACCEPT 0x00002000UL
#define RAWIP_SOCKET__CONNECT 0x00000800UL
-#define RAWIP_SOCKET__LOCK 0x00000040UL
-#define RAWIP_SOCKET__IOCTL 0x00000001UL
-#define RAWIP_SOCKET__CREATE 0x00000008UL
-#define RAWIP_SOCKET__NAME_BIND 0x00200000UL
-#define RAWIP_SOCKET__SEND_MSG 0x00100000UL
+#define RAWIP_SOCKET__LISTEN 0x00001000UL
+#define RAWIP_SOCKET__ACCEPT 0x00002000UL
+#define RAWIP_SOCKET__GETOPT 0x00004000UL
+#define RAWIP_SOCKET__SETOPT 0x00008000UL
+#define RAWIP_SOCKET__SHUTDOWN 0x00010000UL
#define RAWIP_SOCKET__RECVFROM 0x00020000UL
-#define RAWIP_SOCKET__GETATTR 0x00000010UL
+#define RAWIP_SOCKET__SENDTO 0x00040000UL
+#define RAWIP_SOCKET__RECV_MSG 0x00080000UL
+#define RAWIP_SOCKET__SEND_MSG 0x00100000UL
+#define RAWIP_SOCKET__NAME_BIND 0x00200000UL
+
#define RAWIP_SOCKET__NODE_BIND 0x00400000UL
#define NODE__TCP_RECV 0x00000001UL
#define NETIF__RAWIP_RECV 0x00000010UL
#define NETIF__RAWIP_SEND 0x00000020UL
-#define NETLINK_SOCKET__RELABELTO 0x00000100UL
-#define NETLINK_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_SOCKET__READ 0x00000002UL
+#define NETLINK_SOCKET__WRITE 0x00000004UL
+#define NETLINK_SOCKET__CREATE 0x00000008UL
+#define NETLINK_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_SOCKET__LOCK 0x00000040UL
#define NETLINK_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_SOCKET__RELABELTO 0x00000100UL
#define NETLINK_SOCKET__APPEND 0x00000200UL
-#define NETLINK_SOCKET__SETATTR 0x00000020UL
-#define NETLINK_SOCKET__SENDTO 0x00040000UL
-#define NETLINK_SOCKET__GETOPT 0x00004000UL
-#define NETLINK_SOCKET__READ 0x00000002UL
-#define NETLINK_SOCKET__SHUTDOWN 0x00010000UL
-#define NETLINK_SOCKET__LISTEN 0x00001000UL
#define NETLINK_SOCKET__BIND 0x00000400UL
-#define NETLINK_SOCKET__WRITE 0x00000004UL
-#define NETLINK_SOCKET__ACCEPT 0x00002000UL
#define NETLINK_SOCKET__CONNECT 0x00000800UL
-#define NETLINK_SOCKET__LOCK 0x00000040UL
-#define NETLINK_SOCKET__IOCTL 0x00000001UL
-#define NETLINK_SOCKET__CREATE 0x00000008UL
-#define NETLINK_SOCKET__NAME_BIND 0x00200000UL
-#define NETLINK_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_SOCKET__SHUTDOWN 0x00010000UL
#define NETLINK_SOCKET__RECVFROM 0x00020000UL
-#define NETLINK_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_SOCKET__NAME_BIND 0x00200000UL
-#define PACKET_SOCKET__RELABELTO 0x00000100UL
-#define PACKET_SOCKET__RECV_MSG 0x00080000UL
+#define PACKET_SOCKET__IOCTL 0x00000001UL
+#define PACKET_SOCKET__READ 0x00000002UL
+#define PACKET_SOCKET__WRITE 0x00000004UL
+#define PACKET_SOCKET__CREATE 0x00000008UL
+#define PACKET_SOCKET__GETATTR 0x00000010UL
+#define PACKET_SOCKET__SETATTR 0x00000020UL
+#define PACKET_SOCKET__LOCK 0x00000040UL
#define PACKET_SOCKET__RELABELFROM 0x00000080UL
-#define PACKET_SOCKET__SETOPT 0x00008000UL
+#define PACKET_SOCKET__RELABELTO 0x00000100UL
#define PACKET_SOCKET__APPEND 0x00000200UL
-#define PACKET_SOCKET__SETATTR 0x00000020UL
-#define PACKET_SOCKET__SENDTO 0x00040000UL
-#define PACKET_SOCKET__GETOPT 0x00004000UL
-#define PACKET_SOCKET__READ 0x00000002UL
-#define PACKET_SOCKET__SHUTDOWN 0x00010000UL
-#define PACKET_SOCKET__LISTEN 0x00001000UL
#define PACKET_SOCKET__BIND 0x00000400UL
-#define PACKET_SOCKET__WRITE 0x00000004UL
-#define PACKET_SOCKET__ACCEPT 0x00002000UL
#define PACKET_SOCKET__CONNECT 0x00000800UL
-#define PACKET_SOCKET__LOCK 0x00000040UL
-#define PACKET_SOCKET__IOCTL 0x00000001UL
-#define PACKET_SOCKET__CREATE 0x00000008UL
-#define PACKET_SOCKET__NAME_BIND 0x00200000UL
-#define PACKET_SOCKET__SEND_MSG 0x00100000UL
+#define PACKET_SOCKET__LISTEN 0x00001000UL
+#define PACKET_SOCKET__ACCEPT 0x00002000UL
+#define PACKET_SOCKET__GETOPT 0x00004000UL
+#define PACKET_SOCKET__SETOPT 0x00008000UL
+#define PACKET_SOCKET__SHUTDOWN 0x00010000UL
#define PACKET_SOCKET__RECVFROM 0x00020000UL
-#define PACKET_SOCKET__GETATTR 0x00000010UL
+#define PACKET_SOCKET__SENDTO 0x00040000UL
+#define PACKET_SOCKET__RECV_MSG 0x00080000UL
+#define PACKET_SOCKET__SEND_MSG 0x00100000UL
+#define PACKET_SOCKET__NAME_BIND 0x00200000UL
-#define KEY_SOCKET__RELABELTO 0x00000100UL
-#define KEY_SOCKET__RECV_MSG 0x00080000UL
+#define KEY_SOCKET__IOCTL 0x00000001UL
+#define KEY_SOCKET__READ 0x00000002UL
+#define KEY_SOCKET__WRITE 0x00000004UL
+#define KEY_SOCKET__CREATE 0x00000008UL
+#define KEY_SOCKET__GETATTR 0x00000010UL
+#define KEY_SOCKET__SETATTR 0x00000020UL
+#define KEY_SOCKET__LOCK 0x00000040UL
#define KEY_SOCKET__RELABELFROM 0x00000080UL
-#define KEY_SOCKET__SETOPT 0x00008000UL
+#define KEY_SOCKET__RELABELTO 0x00000100UL
#define KEY_SOCKET__APPEND 0x00000200UL
-#define KEY_SOCKET__SETATTR 0x00000020UL
-#define KEY_SOCKET__SENDTO 0x00040000UL
-#define KEY_SOCKET__GETOPT 0x00004000UL
-#define KEY_SOCKET__READ 0x00000002UL
-#define KEY_SOCKET__SHUTDOWN 0x00010000UL
-#define KEY_SOCKET__LISTEN 0x00001000UL
#define KEY_SOCKET__BIND 0x00000400UL
-#define KEY_SOCKET__WRITE 0x00000004UL
-#define KEY_SOCKET__ACCEPT 0x00002000UL
#define KEY_SOCKET__CONNECT 0x00000800UL
-#define KEY_SOCKET__LOCK 0x00000040UL
-#define KEY_SOCKET__IOCTL 0x00000001UL
-#define KEY_SOCKET__CREATE 0x00000008UL
-#define KEY_SOCKET__NAME_BIND 0x00200000UL
-#define KEY_SOCKET__SEND_MSG 0x00100000UL
+#define KEY_SOCKET__LISTEN 0x00001000UL
+#define KEY_SOCKET__ACCEPT 0x00002000UL
+#define KEY_SOCKET__GETOPT 0x00004000UL
+#define KEY_SOCKET__SETOPT 0x00008000UL
+#define KEY_SOCKET__SHUTDOWN 0x00010000UL
#define KEY_SOCKET__RECVFROM 0x00020000UL
-#define KEY_SOCKET__GETATTR 0x00000010UL
+#define KEY_SOCKET__SENDTO 0x00040000UL
+#define KEY_SOCKET__RECV_MSG 0x00080000UL
+#define KEY_SOCKET__SEND_MSG 0x00100000UL
+#define KEY_SOCKET__NAME_BIND 0x00200000UL
-#define UNIX_STREAM_SOCKET__RELABELTO 0x00000100UL
-#define UNIX_STREAM_SOCKET__RECV_MSG 0x00080000UL
+#define UNIX_STREAM_SOCKET__IOCTL 0x00000001UL
+#define UNIX_STREAM_SOCKET__READ 0x00000002UL
+#define UNIX_STREAM_SOCKET__WRITE 0x00000004UL
+#define UNIX_STREAM_SOCKET__CREATE 0x00000008UL
+#define UNIX_STREAM_SOCKET__GETATTR 0x00000010UL
+#define UNIX_STREAM_SOCKET__SETATTR 0x00000020UL
+#define UNIX_STREAM_SOCKET__LOCK 0x00000040UL
#define UNIX_STREAM_SOCKET__RELABELFROM 0x00000080UL
-#define UNIX_STREAM_SOCKET__SETOPT 0x00008000UL
+#define UNIX_STREAM_SOCKET__RELABELTO 0x00000100UL
#define UNIX_STREAM_SOCKET__APPEND 0x00000200UL
-#define UNIX_STREAM_SOCKET__SETATTR 0x00000020UL
-#define UNIX_STREAM_SOCKET__SENDTO 0x00040000UL
-#define UNIX_STREAM_SOCKET__GETOPT 0x00004000UL
-#define UNIX_STREAM_SOCKET__READ 0x00000002UL
-#define UNIX_STREAM_SOCKET__SHUTDOWN 0x00010000UL
-#define UNIX_STREAM_SOCKET__LISTEN 0x00001000UL
#define UNIX_STREAM_SOCKET__BIND 0x00000400UL
-#define UNIX_STREAM_SOCKET__WRITE 0x00000004UL
-#define UNIX_STREAM_SOCKET__ACCEPT 0x00002000UL
#define UNIX_STREAM_SOCKET__CONNECT 0x00000800UL
-#define UNIX_STREAM_SOCKET__LOCK 0x00000040UL
-#define UNIX_STREAM_SOCKET__IOCTL 0x00000001UL
-#define UNIX_STREAM_SOCKET__CREATE 0x00000008UL
-#define UNIX_STREAM_SOCKET__NAME_BIND 0x00200000UL
-#define UNIX_STREAM_SOCKET__SEND_MSG 0x00100000UL
+#define UNIX_STREAM_SOCKET__LISTEN 0x00001000UL
+#define UNIX_STREAM_SOCKET__ACCEPT 0x00002000UL
+#define UNIX_STREAM_SOCKET__GETOPT 0x00004000UL
+#define UNIX_STREAM_SOCKET__SETOPT 0x00008000UL
+#define UNIX_STREAM_SOCKET__SHUTDOWN 0x00010000UL
#define UNIX_STREAM_SOCKET__RECVFROM 0x00020000UL
-#define UNIX_STREAM_SOCKET__GETATTR 0x00000010UL
+#define UNIX_STREAM_SOCKET__SENDTO 0x00040000UL
+#define UNIX_STREAM_SOCKET__RECV_MSG 0x00080000UL
+#define UNIX_STREAM_SOCKET__SEND_MSG 0x00100000UL
+#define UNIX_STREAM_SOCKET__NAME_BIND 0x00200000UL
#define UNIX_STREAM_SOCKET__CONNECTTO 0x00400000UL
#define UNIX_STREAM_SOCKET__NEWCONN 0x00800000UL
#define UNIX_STREAM_SOCKET__ACCEPTFROM 0x01000000UL
-#define UNIX_DGRAM_SOCKET__RELABELTO 0x00000100UL
-#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL
+#define UNIX_DGRAM_SOCKET__IOCTL 0x00000001UL
+#define UNIX_DGRAM_SOCKET__READ 0x00000002UL
+#define UNIX_DGRAM_SOCKET__WRITE 0x00000004UL
+#define UNIX_DGRAM_SOCKET__CREATE 0x00000008UL
+#define UNIX_DGRAM_SOCKET__GETATTR 0x00000010UL
+#define UNIX_DGRAM_SOCKET__SETATTR 0x00000020UL
+#define UNIX_DGRAM_SOCKET__LOCK 0x00000040UL
#define UNIX_DGRAM_SOCKET__RELABELFROM 0x00000080UL
-#define UNIX_DGRAM_SOCKET__SETOPT 0x00008000UL
+#define UNIX_DGRAM_SOCKET__RELABELTO 0x00000100UL
#define UNIX_DGRAM_SOCKET__APPEND 0x00000200UL
-#define UNIX_DGRAM_SOCKET__SETATTR 0x00000020UL
-#define UNIX_DGRAM_SOCKET__SENDTO 0x00040000UL
-#define UNIX_DGRAM_SOCKET__GETOPT 0x00004000UL
-#define UNIX_DGRAM_SOCKET__READ 0x00000002UL
-#define UNIX_DGRAM_SOCKET__SHUTDOWN 0x00010000UL
-#define UNIX_DGRAM_SOCKET__LISTEN 0x00001000UL
#define UNIX_DGRAM_SOCKET__BIND 0x00000400UL
-#define UNIX_DGRAM_SOCKET__WRITE 0x00000004UL
-#define UNIX_DGRAM_SOCKET__ACCEPT 0x00002000UL
#define UNIX_DGRAM_SOCKET__CONNECT 0x00000800UL
-#define UNIX_DGRAM_SOCKET__LOCK 0x00000040UL
-#define UNIX_DGRAM_SOCKET__IOCTL 0x00000001UL
-#define UNIX_DGRAM_SOCKET__CREATE 0x00000008UL
-#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL
-#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL
+#define UNIX_DGRAM_SOCKET__LISTEN 0x00001000UL
+#define UNIX_DGRAM_SOCKET__ACCEPT 0x00002000UL
+#define UNIX_DGRAM_SOCKET__GETOPT 0x00004000UL
+#define UNIX_DGRAM_SOCKET__SETOPT 0x00008000UL
+#define UNIX_DGRAM_SOCKET__SHUTDOWN 0x00010000UL
#define UNIX_DGRAM_SOCKET__RECVFROM 0x00020000UL
-#define UNIX_DGRAM_SOCKET__GETATTR 0x00000010UL
+#define UNIX_DGRAM_SOCKET__SENDTO 0x00040000UL
+#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL
+#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL
+#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL
#define PROCESS__FORK 0x00000001UL
#define PROCESS__TRANSITION 0x00000002UL
#define PROCESS__SETRLIMIT 0x00200000UL
#define PROCESS__RLIMITINH 0x00400000UL
+#define IPC__CREATE 0x00000001UL
+#define IPC__DESTROY 0x00000002UL
+#define IPC__GETATTR 0x00000004UL
#define IPC__SETATTR 0x00000008UL
#define IPC__READ 0x00000010UL
+#define IPC__WRITE 0x00000020UL
#define IPC__ASSOCIATE 0x00000040UL
-#define IPC__DESTROY 0x00000002UL
-#define IPC__UNIX_WRITE 0x00000100UL
-#define IPC__CREATE 0x00000001UL
#define IPC__UNIX_READ 0x00000080UL
-#define IPC__GETATTR 0x00000004UL
-#define IPC__WRITE 0x00000020UL
+#define IPC__UNIX_WRITE 0x00000100UL
+#define SEM__CREATE 0x00000001UL
+#define SEM__DESTROY 0x00000002UL
+#define SEM__GETATTR 0x00000004UL
#define SEM__SETATTR 0x00000008UL
#define SEM__READ 0x00000010UL
+#define SEM__WRITE 0x00000020UL
#define SEM__ASSOCIATE 0x00000040UL
-#define SEM__DESTROY 0x00000002UL
-#define SEM__UNIX_WRITE 0x00000100UL
-#define SEM__CREATE 0x00000001UL
#define SEM__UNIX_READ 0x00000080UL
-#define SEM__GETATTR 0x00000004UL
-#define SEM__WRITE 0x00000020UL
+#define SEM__UNIX_WRITE 0x00000100UL
+#define MSGQ__CREATE 0x00000001UL
+#define MSGQ__DESTROY 0x00000002UL
+#define MSGQ__GETATTR 0x00000004UL
#define MSGQ__SETATTR 0x00000008UL
#define MSGQ__READ 0x00000010UL
+#define MSGQ__WRITE 0x00000020UL
#define MSGQ__ASSOCIATE 0x00000040UL
-#define MSGQ__DESTROY 0x00000002UL
-#define MSGQ__UNIX_WRITE 0x00000100UL
-#define MSGQ__CREATE 0x00000001UL
#define MSGQ__UNIX_READ 0x00000080UL
-#define MSGQ__GETATTR 0x00000004UL
-#define MSGQ__WRITE 0x00000020UL
+#define MSGQ__UNIX_WRITE 0x00000100UL
#define MSGQ__ENQUEUE 0x00000200UL
#define MSG__SEND 0x00000001UL
#define MSG__RECEIVE 0x00000002UL
+#define SHM__CREATE 0x00000001UL
+#define SHM__DESTROY 0x00000002UL
+#define SHM__GETATTR 0x00000004UL
#define SHM__SETATTR 0x00000008UL
#define SHM__READ 0x00000010UL
+#define SHM__WRITE 0x00000020UL
#define SHM__ASSOCIATE 0x00000040UL
-#define SHM__DESTROY 0x00000002UL
-#define SHM__UNIX_WRITE 0x00000100UL
-#define SHM__CREATE 0x00000001UL
#define SHM__UNIX_READ 0x00000080UL
-#define SHM__GETATTR 0x00000004UL
-#define SHM__WRITE 0x00000020UL
+#define SHM__UNIX_WRITE 0x00000100UL
#define SHM__LOCK 0x00000200UL
#define PASSWD__PASSWD 0x00000001UL
#define PASSWD__CHFN 0x00000002UL
#define PASSWD__CHSH 0x00000004UL
-
+#define PASSWD__ROOTOK 0x00000008UL
+
+#define DRAWABLE__CREATE 0x00000001UL
+#define DRAWABLE__DESTROY 0x00000002UL
+#define DRAWABLE__DRAW 0x00000004UL
+#define DRAWABLE__COPY 0x00000008UL
+#define DRAWABLE__GETATTR 0x00000010UL
+
+#define GC__CREATE 0x00000001UL
+#define GC__FREE 0x00000002UL
+#define GC__GETATTR 0x00000004UL
+#define GC__SETATTR 0x00000008UL
+
+#define WINDOW__ADDCHILD 0x00000001UL
+#define WINDOW__CREATE 0x00000002UL
+#define WINDOW__DESTROY 0x00000004UL
+#define WINDOW__MAP 0x00000008UL
+#define WINDOW__UNMAP 0x00000010UL
+#define WINDOW__CHSTACK 0x00000020UL
+#define WINDOW__CHPROPLIST 0x00000040UL
+#define WINDOW__CHPROP 0x00000080UL
+#define WINDOW__LISTPROP 0x00000100UL
+#define WINDOW__GETATTR 0x00000200UL
+#define WINDOW__SETATTR 0x00000400UL
+#define WINDOW__SETFOCUS 0x00000800UL
+#define WINDOW__MOVE 0x00001000UL
+#define WINDOW__CHSELECTION 0x00002000UL
+#define WINDOW__CHPARENT 0x00004000UL
+#define WINDOW__CTRLLIFE 0x00008000UL
+#define WINDOW__ENUMERATE 0x00010000UL
+#define WINDOW__TRANSPARENT 0x00020000UL
+#define WINDOW__MOUSEMOTION 0x00040000UL
+#define WINDOW__CLIENTCOMEVENT 0x00080000UL
+#define WINDOW__INPUTEVENT 0x00100000UL
+#define WINDOW__DRAWEVENT 0x00200000UL
+#define WINDOW__WINDOWCHANGEEVENT 0x00400000UL
+#define WINDOW__WINDOWCHANGEREQUEST 0x00800000UL
+#define WINDOW__SERVERCHANGEEVENT 0x01000000UL
+#define WINDOW__EXTENSIONEVENT 0x02000000UL
+
+#define FONT__LOAD 0x00000001UL
+#define FONT__FREE 0x00000002UL
+#define FONT__GETATTR 0x00000004UL
+#define FONT__USE 0x00000008UL
+
+#define COLORMAP__CREATE 0x00000001UL
+#define COLORMAP__FREE 0x00000002UL
+#define COLORMAP__INSTALL 0x00000004UL
+#define COLORMAP__UNINSTALL 0x00000008UL
+#define COLORMAP__LIST 0x00000010UL
+#define COLORMAP__READ 0x00000020UL
+#define COLORMAP__STORE 0x00000040UL
+#define COLORMAP__GETATTR 0x00000080UL
+#define COLORMAP__SETATTR 0x00000100UL
+
+#define PROPERTY__CREATE 0x00000001UL
+#define PROPERTY__FREE 0x00000002UL
+#define PROPERTY__READ 0x00000004UL
+#define PROPERTY__WRITE 0x00000008UL
+
+#define CURSOR__CREATE 0x00000001UL
+#define CURSOR__CREATEGLYPH 0x00000002UL
+#define CURSOR__FREE 0x00000004UL
+#define CURSOR__ASSIGN 0x00000008UL
+#define CURSOR__SETATTR 0x00000010UL
+
+#define XCLIENT__KILL 0x00000001UL
+
+#define XINPUT__LOOKUP 0x00000001UL
+#define XINPUT__GETATTR 0x00000002UL
+#define XINPUT__SETATTR 0x00000004UL
+#define XINPUT__SETFOCUS 0x00000008UL
+#define XINPUT__WARPPOINTER 0x00000010UL
+#define XINPUT__ACTIVEGRAB 0x00000020UL
+#define XINPUT__PASSIVEGRAB 0x00000040UL
+#define XINPUT__UNGRAB 0x00000080UL
+#define XINPUT__BELL 0x00000100UL
+#define XINPUT__MOUSEMOTION 0x00000200UL
+#define XINPUT__RELABELINPUT 0x00000400UL
+
+#define XSERVER__SCREENSAVER 0x00000001UL
+#define XSERVER__GETHOSTLIST 0x00000002UL
+#define XSERVER__SETHOSTLIST 0x00000004UL
+#define XSERVER__GETFONTPATH 0x00000008UL
+#define XSERVER__SETFONTPATH 0x00000010UL
+#define XSERVER__GETATTR 0x00000020UL
+#define XSERVER__GRAB 0x00000040UL
+#define XSERVER__UNGRAB 0x00000080UL
+
+#define XEXTENSION__QUERY 0x00000001UL
+#define XEXTENSION__USE 0x00000002UL
+
+#define PAX__PAGEEXEC 0x00000001UL
+#define PAX__EMUTRAMP 0x00000002UL
+#define PAX__MPROTECT 0x00000004UL
+#define PAX__RANDMMAP 0x00000008UL
+#define PAX__RANDEXEC 0x00000010UL
+#define PAX__SEGMEXEC 0x00000020UL
+
+#define NETLINK_ROUTE_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_ROUTE_SOCKET__READ 0x00000002UL
+#define NETLINK_ROUTE_SOCKET__WRITE 0x00000004UL
+#define NETLINK_ROUTE_SOCKET__CREATE 0x00000008UL
+#define NETLINK_ROUTE_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_ROUTE_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_ROUTE_SOCKET__LOCK 0x00000040UL
+#define NETLINK_ROUTE_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_ROUTE_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_ROUTE_SOCKET__APPEND 0x00000200UL
+#define NETLINK_ROUTE_SOCKET__BIND 0x00000400UL
+#define NETLINK_ROUTE_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_ROUTE_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_ROUTE_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_ROUTE_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_ROUTE_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_ROUTE_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_ROUTE_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_ROUTE_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_ROUTE_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_ROUTE_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_ROUTE_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_ROUTE_SOCKET__NLMSG_READ 0x00400000UL
+#define NETLINK_ROUTE_SOCKET__NLMSG_WRITE 0x00800000UL
+
+#define NETLINK_FIREWALL_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_FIREWALL_SOCKET__READ 0x00000002UL
+#define NETLINK_FIREWALL_SOCKET__WRITE 0x00000004UL
+#define NETLINK_FIREWALL_SOCKET__CREATE 0x00000008UL
+#define NETLINK_FIREWALL_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_FIREWALL_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_FIREWALL_SOCKET__LOCK 0x00000040UL
+#define NETLINK_FIREWALL_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_FIREWALL_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_FIREWALL_SOCKET__APPEND 0x00000200UL
+#define NETLINK_FIREWALL_SOCKET__BIND 0x00000400UL
+#define NETLINK_FIREWALL_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_FIREWALL_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_FIREWALL_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_FIREWALL_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_FIREWALL_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_FIREWALL_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_FIREWALL_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_FIREWALL_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_FIREWALL_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_FIREWALL_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_FIREWALL_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_FIREWALL_SOCKET__NLMSG_READ 0x00400000UL
+#define NETLINK_FIREWALL_SOCKET__NLMSG_WRITE 0x00800000UL
+
+#define NETLINK_TCPDIAG_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_TCPDIAG_SOCKET__READ 0x00000002UL
+#define NETLINK_TCPDIAG_SOCKET__WRITE 0x00000004UL
+#define NETLINK_TCPDIAG_SOCKET__CREATE 0x00000008UL
+#define NETLINK_TCPDIAG_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_TCPDIAG_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_TCPDIAG_SOCKET__LOCK 0x00000040UL
+#define NETLINK_TCPDIAG_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_TCPDIAG_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_TCPDIAG_SOCKET__APPEND 0x00000200UL
+#define NETLINK_TCPDIAG_SOCKET__BIND 0x00000400UL
+#define NETLINK_TCPDIAG_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_TCPDIAG_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_TCPDIAG_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_TCPDIAG_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_TCPDIAG_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_TCPDIAG_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_TCPDIAG_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_TCPDIAG_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_TCPDIAG_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_TCPDIAG_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_TCPDIAG_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_TCPDIAG_SOCKET__NLMSG_READ 0x00400000UL
+#define NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE 0x00800000UL
+
+#define NETLINK_NFLOG_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_NFLOG_SOCKET__READ 0x00000002UL
+#define NETLINK_NFLOG_SOCKET__WRITE 0x00000004UL
+#define NETLINK_NFLOG_SOCKET__CREATE 0x00000008UL
+#define NETLINK_NFLOG_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_NFLOG_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_NFLOG_SOCKET__LOCK 0x00000040UL
+#define NETLINK_NFLOG_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_NFLOG_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_NFLOG_SOCKET__APPEND 0x00000200UL
+#define NETLINK_NFLOG_SOCKET__BIND 0x00000400UL
+#define NETLINK_NFLOG_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_NFLOG_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_NFLOG_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_NFLOG_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_NFLOG_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_NFLOG_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_NFLOG_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_NFLOG_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_NFLOG_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_NFLOG_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_NFLOG_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_XFRM_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_XFRM_SOCKET__READ 0x00000002UL
+#define NETLINK_XFRM_SOCKET__WRITE 0x00000004UL
+#define NETLINK_XFRM_SOCKET__CREATE 0x00000008UL
+#define NETLINK_XFRM_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_XFRM_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_XFRM_SOCKET__LOCK 0x00000040UL
+#define NETLINK_XFRM_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_XFRM_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_XFRM_SOCKET__APPEND 0x00000200UL
+#define NETLINK_XFRM_SOCKET__BIND 0x00000400UL
+#define NETLINK_XFRM_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_XFRM_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_XFRM_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_XFRM_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_XFRM_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_XFRM_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_XFRM_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_XFRM_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_XFRM_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_XFRM_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_XFRM_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_XFRM_SOCKET__NLMSG_READ 0x00400000UL
+#define NETLINK_XFRM_SOCKET__NLMSG_WRITE 0x00800000UL
+
+#define NETLINK_SELINUX_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_SELINUX_SOCKET__READ 0x00000002UL
+#define NETLINK_SELINUX_SOCKET__WRITE 0x00000004UL
+#define NETLINK_SELINUX_SOCKET__CREATE 0x00000008UL
+#define NETLINK_SELINUX_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_SELINUX_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_SELINUX_SOCKET__LOCK 0x00000040UL
+#define NETLINK_SELINUX_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_SELINUX_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_SELINUX_SOCKET__APPEND 0x00000200UL
+#define NETLINK_SELINUX_SOCKET__BIND 0x00000400UL
+#define NETLINK_SELINUX_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_SELINUX_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_SELINUX_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_SELINUX_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_SELINUX_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_SELINUX_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_SELINUX_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_SELINUX_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_SELINUX_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_SELINUX_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_SELINUX_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_AUDIT_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_AUDIT_SOCKET__READ 0x00000002UL
+#define NETLINK_AUDIT_SOCKET__WRITE 0x00000004UL
+#define NETLINK_AUDIT_SOCKET__CREATE 0x00000008UL
+#define NETLINK_AUDIT_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_AUDIT_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_AUDIT_SOCKET__LOCK 0x00000040UL
+#define NETLINK_AUDIT_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_AUDIT_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_AUDIT_SOCKET__APPEND 0x00000200UL
+#define NETLINK_AUDIT_SOCKET__BIND 0x00000400UL
+#define NETLINK_AUDIT_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_AUDIT_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_AUDIT_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_AUDIT_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_AUDIT_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_AUDIT_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_AUDIT_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_AUDIT_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_AUDIT_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_AUDIT_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_AUDIT_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_AUDIT_SOCKET__NLMSG_READ 0x00400000UL
+#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL
+
+#define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_IP6FW_SOCKET__READ 0x00000002UL
+#define NETLINK_IP6FW_SOCKET__WRITE 0x00000004UL
+#define NETLINK_IP6FW_SOCKET__CREATE 0x00000008UL
+#define NETLINK_IP6FW_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_IP6FW_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_IP6FW_SOCKET__LOCK 0x00000040UL
+#define NETLINK_IP6FW_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_IP6FW_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_IP6FW_SOCKET__APPEND 0x00000200UL
+#define NETLINK_IP6FW_SOCKET__BIND 0x00000400UL
+#define NETLINK_IP6FW_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_IP6FW_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_IP6FW_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_IP6FW_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_IP6FW_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_IP6FW_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_IP6FW_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_IP6FW_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_IP6FW_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_IP6FW_SOCKET__SEND_MSG 0x00100000UL
+#define NETLINK_IP6FW_SOCKET__NAME_BIND 0x00200000UL
+
+#define NETLINK_IP6FW_SOCKET__NLMSG_READ 0x00400000UL
+#define NETLINK_IP6FW_SOCKET__NLMSG_WRITE 0x00800000UL
+
+#define NETLINK_DNRT_SOCKET__IOCTL 0x00000001UL
+#define NETLINK_DNRT_SOCKET__READ 0x00000002UL
+#define NETLINK_DNRT_SOCKET__WRITE 0x00000004UL
+#define NETLINK_DNRT_SOCKET__CREATE 0x00000008UL
+#define NETLINK_DNRT_SOCKET__GETATTR 0x00000010UL
+#define NETLINK_DNRT_SOCKET__SETATTR 0x00000020UL
+#define NETLINK_DNRT_SOCKET__LOCK 0x00000040UL
+#define NETLINK_DNRT_SOCKET__RELABELFROM 0x00000080UL
+#define NETLINK_DNRT_SOCKET__RELABELTO 0x00000100UL
+#define NETLINK_DNRT_SOCKET__APPEND 0x00000200UL
+#define NETLINK_DNRT_SOCKET__BIND 0x00000400UL
+#define NETLINK_DNRT_SOCKET__CONNECT 0x00000800UL
+#define NETLINK_DNRT_SOCKET__LISTEN 0x00001000UL
+#define NETLINK_DNRT_SOCKET__ACCEPT 0x00002000UL
+#define NETLINK_DNRT_SOCKET__GETOPT 0x00004000UL
+#define NETLINK_DNRT_SOCKET__SETOPT 0x00008000UL
+#define NETLINK_DNRT_SOCKET__SHUTDOWN 0x00010000UL
+#define NETLINK_DNRT_SOCKET__RECVFROM 0x00020000UL
+#define NETLINK_DNRT_SOCKET__SENDTO 0x00040000UL
+#define NETLINK_DNRT_SOCKET__RECV_MSG 0x00080000UL
+#define NETLINK_DNRT_SOCKET__SEND_MSG 0x00100000UL
/* FLASK */
"shm",
"ipc",
"passwd",
+ "drawable",
+ "window",
+ "gc",
+ "font",
+ "colormap",
+ "property",
+ "cursor",
+ "xclient",
+ "xinput",
+ "xserver",
+ "xextension",
+ "pax",
+ "netlink_route_socket",
+ "netlink_firewall_socket",
+ "netlink_tcpdiag_socket",
+ "netlink_nflog_socket",
+ "netlink_xfrm_socket",
+ "netlink_selinux_socket",
+ "netlink_audit_socket",
+ "netlink_ip6fw_socket",
+ "netlink_dnrt_socket",
};
#define SECCLASS_SHM 28
#define SECCLASS_IPC 29
#define SECCLASS_PASSWD 30
+#define SECCLASS_DRAWABLE 31
+#define SECCLASS_WINDOW 32
+#define SECCLASS_GC 33
+#define SECCLASS_FONT 34
+#define SECCLASS_COLORMAP 35
+#define SECCLASS_PROPERTY 36
+#define SECCLASS_CURSOR 37
+#define SECCLASS_XCLIENT 38
+#define SECCLASS_XINPUT 39
+#define SECCLASS_XSERVER 40
+#define SECCLASS_XEXTENSION 41
+#define SECCLASS_PAX 42
+#define SECCLASS_NETLINK_ROUTE_SOCKET 43
+#define SECCLASS_NETLINK_FIREWALL_SOCKET 44
+#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45
+#define SECCLASS_NETLINK_NFLOG_SOCKET 46
+#define SECCLASS_NETLINK_XFRM_SOCKET 47
+#define SECCLASS_NETLINK_SELINUX_SOCKET 48
+#define SECCLASS_NETLINK_AUDIT_SOCKET 49
+#define SECCLASS_NETLINK_IP6FW_SOCKET 50
+#define SECCLASS_NETLINK_DNRT_SOCKET 51
/*
* Security identifier indices for initial entities
#define SELINUX_MAGIC 0xf97cff8c
/* Identify specific policy version changes */
-#define POLICYDB_VERSION_BASE 15
-#define POLICYDB_VERSION_BOOL 16
-#define POLICYDB_VERSION_IPV6 17
+#define POLICYDB_VERSION_BASE 15
+#define POLICYDB_VERSION_BOOL 16
+#define POLICYDB_VERSION_IPV6 17
+#define POLICYDB_VERSION_NLCLASS 18
/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_IPV6
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_NLCLASS
#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
extern int selinux_enabled;
SEL_DISABLE /* disable SELinux until next reboot */
};
-static ssize_t sel_read_enforce(struct file *filp, char *buf,
+static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char *page;
}
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
-static ssize_t sel_write_enforce(struct file * file, const char * buf,
+static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
};
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
-static ssize_t sel_write_disable(struct file * file, const char * buf,
+static ssize_t sel_write_disable(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
.write = sel_write_disable,
};
-static ssize_t sel_read_policyvers(struct file *filp, char *buf,
+static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char *page;
/* declaration for sel_write_load */
static int sel_make_bools(void);
-static ssize_t sel_read_mls(struct file *filp, char *buf,
+static ssize_t sel_read_mls(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char *page;
.read = sel_read_mls,
};
-static ssize_t sel_write_load(struct file * file, const char * buf,
+static ssize_t sel_write_load(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
};
-static ssize_t sel_write_context(struct file * file, const char * buf,
+static ssize_t sel_write_context(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
* possibly a read which collects the result - which is stored in a
* file-local buffer.
*/
-static ssize_t TA_write(struct file *file, const char *buf, size_t size, loff_t *pos)
+static ssize_t TA_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
{
ino_t ino = file->f_dentry->d_inode->i_ino;
struct argresp *ar;
return rv;
}
-static ssize_t TA_read(struct file *file, char *buf, size_t size, loff_t *pos)
+static ssize_t TA_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
{
struct argresp *ar;
ssize_t rv = 0;
#define BOOL_INO_OFFSET 30
-static ssize_t sel_read_bool(struct file *filep, char *buf,
+static ssize_t sel_read_bool(struct file *filep, char __user *buf,
size_t count, loff_t *ppos)
{
char *page = NULL;
return ret;
}
-static ssize_t sel_write_bool(struct file *filep, const char *buf,
+static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
size_t count, loff_t *ppos)
{
char *page = NULL;
.write = sel_write_bool,
};
-static ssize_t sel_commit_bools_write(struct file *filep, const char *buf,
+static ssize_t sel_commit_bools_write(struct file *filep,
+ const char __user *buf,
size_t count, loff_t *ppos)
{
char *page = NULL;
if (rc)
goto out;
}
- *scontext = p;
+ *scontext = ++p;
rc = 0;
out:
return rc;
};
#endif
+int policydb_loaded_version;
+
static unsigned int symtab_sizes[SYM_NUM] = {
2,
32,
.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
},
+ {
+ .version = POLICYDB_VERSION_NLCLASS,
+ .sym_num = SYM_NUM,
+ .ocon_num = OCON_NUM,
+ },
};
static struct policydb_compat_info *policydb_lookup_compat(int version)
struct role_trans *tr, *ltr;
struct ocontext *l, *c, *newc;
struct genfs *genfs_p, *genfs, *newgenfs;
- int i, j, rc, r_policyvers;
+ int i, j, rc, r_policyvers = 0;
u32 *buf, len, len2, config, nprim, nel, nel2;
char *policydb_str;
struct policydb_compat_info *info;
if (rc)
goto bad;
out:
+ policydb_loaded_version = r_policyvers;
return rc;
bad_newc:
ocontext_destroy(newc,OCON_FSUSE);
#include "mls.h"
extern void selnl_notify_policyload(u32 seqno);
+extern int policydb_loaded_version;
static rwlock_t policy_rwlock = RW_LOCK_UNLOCKED;
#define POLICY_RDLOCK read_lock(&policy_rwlock)
struct avtab_datum *avdatum;
struct class_datum *tclass_datum;
+ /*
+ * Remap extended Netlink classes for old policy versions.
+ * Do this here rather than socket_type_to_security_class()
+ * in case a newer policy version is loaded, allowing sockets
+ * to remain in the correct class.
+ */
+ if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
+ if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
+ tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
+ tclass = SECCLASS_NETLINK_SOCKET;
+
if (!tclass || tclass > policydb.p_classes.nprim) {
printk(KERN_ERR "security_compute_av: unrecognized class %d\n",
tclass);
if (rc)
goto out_unlock;
+ if ((p - scontext2) < scontext_len) {
+ rc = -EINVAL;
+ goto out_unlock;
+ }
+
/* Check the validity of the new context. */
if (!policydb_context_isvalid(&policydb, &context)) {
rc = -EINVAL;
}
static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, void __user *arg)
{
snd_ctl_card_info_t info;
strlcpy(info.mixername, card->mixername, sizeof(info.mixername));
strlcpy(info.components, card->components, sizeof(info.components));
up_read(&snd_ioctl_rwsem);
- if (copy_to_user((void *) arg, &info, sizeof(snd_ctl_card_info_t)))
+ if (copy_to_user(arg, &info, sizeof(snd_ctl_card_info_t)))
return -EFAULT;
return 0;
}
-static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t *_list)
+static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t __user *_list)
{
struct list_head *plist;
snd_ctl_elem_list_t list;
return 0;
}
-static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *_info)
+static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t __user *_info)
{
snd_card_t *card = ctl->card;
snd_ctl_elem_info_t info;
return result;
}
-static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control)
+static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
{
snd_ctl_elem_value_t *control;
snd_kcontrol_t *kctl;
return result;
}
-static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t *_control)
+static int snd_ctl_elem_write(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
{
snd_card_t *card = file->card;
snd_ctl_elem_value_t *control;
return result;
}
-static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
+static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
{
snd_card_t *card = file->card;
snd_ctl_elem_id_t id;
return result;
}
-static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
+static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
{
snd_card_t *card = file->card;
snd_ctl_elem_id_t id;
kfree(kcontrol->private_data);
}
-static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *_info, int replace)
+static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t __user *_info, int replace)
{
snd_card_t *card = file->card;
snd_ctl_elem_info_t info;
return 0;
}
-static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t *_id)
+static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
{
snd_ctl_elem_id_t id;
return snd_ctl_remove_unlocked_id(file, &id);
}
-static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int *ptr)
+static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int __user *ptr)
{
int subscribe;
if (get_user(subscribe, ptr))
snd_card_t *card;
struct list_head *list;
snd_kctl_ioctl_t *p;
+ void __user *argp = (void __user *)arg;
+ int __user *ip = argp;
int err;
ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
snd_assert(card != NULL, return -ENXIO);
switch (cmd) {
case SNDRV_CTL_IOCTL_PVERSION:
- return put_user(SNDRV_CTL_VERSION, (int *)arg) ? -EFAULT : 0;
+ return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
case SNDRV_CTL_IOCTL_CARD_INFO:
- return snd_ctl_card_info(card, ctl, cmd, arg);
+ return snd_ctl_card_info(card, ctl, cmd, argp);
case SNDRV_CTL_IOCTL_ELEM_LIST:
- return snd_ctl_elem_list(ctl->card, (snd_ctl_elem_list_t *) arg);
+ return snd_ctl_elem_list(ctl->card, argp);
case SNDRV_CTL_IOCTL_ELEM_INFO:
- return snd_ctl_elem_info(ctl, (snd_ctl_elem_info_t *) arg);
+ return snd_ctl_elem_info(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_READ:
- return snd_ctl_elem_read(ctl->card, (snd_ctl_elem_value_t *) arg);
+ return snd_ctl_elem_read(ctl->card, argp);
case SNDRV_CTL_IOCTL_ELEM_WRITE:
- return snd_ctl_elem_write(ctl, (snd_ctl_elem_value_t *) arg);
+ return snd_ctl_elem_write(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_LOCK:
- return snd_ctl_elem_lock(ctl, (snd_ctl_elem_id_t *) arg);
+ return snd_ctl_elem_lock(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_UNLOCK:
- return snd_ctl_elem_unlock(ctl, (snd_ctl_elem_id_t *) arg);
+ return snd_ctl_elem_unlock(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_ADD:
- return snd_ctl_elem_add(ctl, (snd_ctl_elem_info_t *) arg, 0);
+ return snd_ctl_elem_add(ctl, argp, 0);
case SNDRV_CTL_IOCTL_ELEM_REPLACE:
- return snd_ctl_elem_add(ctl, (snd_ctl_elem_info_t *) arg, 1);
+ return snd_ctl_elem_add(ctl, argp, 1);
case SNDRV_CTL_IOCTL_ELEM_REMOVE:
- return snd_ctl_elem_remove(ctl, (snd_ctl_elem_id_t *) arg);
+ return snd_ctl_elem_remove(ctl, argp);
case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
- return snd_ctl_subscribe_events(ctl, (int *) arg);
+ return snd_ctl_subscribe_events(ctl, ip);
case SNDRV_CTL_IOCTL_POWER:
- if (get_user(err, (int *)arg))
+ if (get_user(err, ip))
return -EFAULT;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
return err;
case SNDRV_CTL_IOCTL_POWER_STATE:
#ifdef CONFIG_PM
- return put_user(card->power_state, (int *)arg) ? -EFAULT : 0;
+ return put_user(card->power_state, ip) ? -EFAULT : 0;
#else
- return put_user(SNDRV_CTL_POWER_D0, (int *)arg) ? -EFAULT : 0;
+ return put_user(SNDRV_CTL_POWER_D0, ip) ? -EFAULT : 0;
#endif
}
down_read(&snd_ioctl_rwsem);
return -ENOTTY;
}
-static ssize_t snd_ctl_read(struct file *file, char *buffer, size_t count, loff_t * offset)
+static ssize_t snd_ctl_read(struct file *file, char __user *buffer, size_t count, loff_t * offset)
{
snd_ctl_file_t *ctl;
int err = 0;
return -ENXIO;
}
-static ssize_t snd_hwdep_read(struct file * file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_hwdep_read(struct file * file, char __user *buf, size_t count, loff_t *offset)
{
snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
if (hw->ops.read)
return -ENXIO;
}
-static ssize_t snd_hwdep_write(struct file * file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_hwdep_write(struct file * file, const char __user *buf, size_t count, loff_t *offset)
{
snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
if (hw->ops.write)
return 0;
}
-static int snd_hwdep_info(snd_hwdep_t *hw, snd_hwdep_info_t *_info)
+static int snd_hwdep_info(snd_hwdep_t *hw, snd_hwdep_info_t __user *_info)
{
snd_hwdep_info_t info;
return 0;
}
-static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *_info)
+static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t __user *_info)
{
snd_hwdep_dsp_status_t info;
int err;
return 0;
}
-static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *_info)
+static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t __user *_info)
{
snd_hwdep_dsp_image_t info;
int err;
unsigned int cmd, unsigned long arg)
{
snd_hwdep_t *hw = snd_magic_cast(snd_hwdep_t, file->private_data, return -ENXIO);
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case SNDRV_HWDEP_IOCTL_PVERSION:
- return put_user(SNDRV_HWDEP_VERSION, (int *)arg);
+ return put_user(SNDRV_HWDEP_VERSION, (int __user *)argp);
case SNDRV_HWDEP_IOCTL_INFO:
- return snd_hwdep_info(hw, (snd_hwdep_info_t *)arg);
+ return snd_hwdep_info(hw, argp);
case SNDRV_HWDEP_IOCTL_DSP_STATUS:
- return snd_hwdep_dsp_status(hw, (snd_hwdep_dsp_status_t *)arg);
+ return snd_hwdep_dsp_status(hw, argp);
case SNDRV_HWDEP_IOCTL_DSP_LOAD:
- return snd_hwdep_dsp_load(hw, (snd_hwdep_dsp_image_t *)arg);
+ return snd_hwdep_dsp_load(hw, argp);
}
if (hw->ops.ioctl)
return hw->ops.ioctl(hw, file, cmd, arg);
{
int device;
- if (get_user(device, (int *)arg))
+ if (get_user(device, (int __user *)arg))
return -EFAULT;
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_MINOR_HWDEPS) {
}
if (device >= SNDRV_MINOR_HWDEPS)
device = -1;
- if (put_user(device, (int *)arg))
+ if (put_user(device, (int __user *)arg))
return -EFAULT;
return 0;
}
case SNDRV_CTL_IOCTL_HWDEP_INFO:
{
- snd_hwdep_info_t *info = (snd_hwdep_info_t *)arg;
+ snd_hwdep_info_t __user *info = (snd_hwdep_info_t __user *)arg;
int device;
snd_hwdep_t *hwdep;
return ret;
}
-static ssize_t snd_info_entry_read(struct file *file, char *buffer,
+static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
size_t count, loff_t * offset)
{
snd_info_private_data_t *data;
return size;
}
-static ssize_t snd_info_entry_write(struct file *file, const char *buffer,
+static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer,
size_t count, loff_t * offset)
{
snd_info_private_data_t *data;
*
* Returns zero if successful, or non-zero on failure.
*/
-int copy_to_user_fromio(void *dst, unsigned long src, size_t count)
+int copy_to_user_fromio(void __user *dst, unsigned long src, size_t count)
{
#if defined(__i386__) || defined(CONFIG_SPARC32)
return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
*
* Returns zero if successful, or non-zero on failure.
*/
-int copy_from_user_toio(unsigned long dst, const void *src, size_t count)
+int copy_from_user_toio(unsigned long dst, const void __user *src, size_t count)
{
#if defined(__i386__) || defined(CONFIG_SPARC32)
return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
}
static int snd_mixer_oss_info(snd_mixer_oss_file_t *fmixer,
- mixer_info *_info)
+ mixer_info __user *_info)
{
snd_card_t *card = fmixer->card;
snd_mixer_oss_t *mixer = fmixer->mixer;
}
static int snd_mixer_oss_info_obsolete(snd_mixer_oss_file_t *fmixer,
- _old_mixer_info *_info)
+ _old_mixer_info __user *_info)
{
snd_card_t *card = fmixer->card;
snd_mixer_oss_t *mixer = fmixer->mixer;
static int snd_mixer_oss_ioctl1(snd_mixer_oss_file_t *fmixer, unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
int tmp;
snd_assert(fmixer != NULL, return -ENXIO);
if (((cmd >> 8) & 0xff) == 'M') {
switch (cmd) {
case SOUND_MIXER_INFO:
- return snd_mixer_oss_info(fmixer, (mixer_info *)arg);
+ return snd_mixer_oss_info(fmixer, argp);
case SOUND_OLD_MIXER_INFO:
- return snd_mixer_oss_info_obsolete(fmixer, (_old_mixer_info *)arg);
+ return snd_mixer_oss_info_obsolete(fmixer, argp);
case SOUND_MIXER_WRITE_RECSRC:
- if (get_user(tmp, (int *)arg))
+ if (get_user(tmp, p))
return -EFAULT;
tmp = snd_mixer_oss_set_recsrc(fmixer, tmp);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
case OSS_GETVERSION:
- return put_user(SNDRV_OSS_VERSION, (int *) arg);
+ return put_user(SNDRV_OSS_VERSION, p);
case OSS_ALSAEMULVER:
- return put_user(1, (int *) arg);
+ return put_user(1, p);
case SOUND_MIXER_READ_DEVMASK:
tmp = snd_mixer_oss_devmask(fmixer);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
case SOUND_MIXER_READ_STEREODEVS:
tmp = snd_mixer_oss_stereodevs(fmixer);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
case SOUND_MIXER_READ_RECMASK:
tmp = snd_mixer_oss_recmask(fmixer);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
case SOUND_MIXER_READ_CAPS:
tmp = snd_mixer_oss_caps(fmixer);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
case SOUND_MIXER_READ_RECSRC:
tmp = snd_mixer_oss_get_recsrc(fmixer);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
}
}
if (cmd & SIOC_IN) {
- if (get_user(tmp, (int *)arg))
+ if (get_user(tmp, p))
return -EFAULT;
tmp = snd_mixer_oss_set_volume(fmixer, cmd & 0xff, tmp);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
} else if (cmd & SIOC_OUT) {
tmp = snd_mixer_oss_get_volume(fmixer, cmd & 0xff);
if (tmp < 0)
return tmp;
- return put_user(tmp, (int *)arg);
+ return put_user(tmp, p);
}
return -ENXIO;
}
return bytes;
}
-static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char *buf, size_t bytes)
+static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __user *buf, size_t bytes)
{
size_t xfer = 0;
ssize_t tmp;
return bytes;
}
-static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char *buf, size_t bytes)
+static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char __user *buf, size_t bytes)
{
size_t xfer = 0;
ssize_t tmp;
snd_pcm_lib_write(substream, runtime->oss.buffer, size1);
}
} else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
- void *buffers[runtime->channels];
+ void __user *buffers[runtime->channels];
memset(buffers, 0, runtime->channels * sizeof(void *));
- snd_pcm_lib_writev(substream, (void **)buffers, size);
+ snd_pcm_lib_writev(substream, buffers, size);
}
}
/*
return snd_pcm_oss_bytes(substream, delay);
}
-static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info * _info)
+static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info __user * _info)
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
return 0;
}
-static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info *_info)
+static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
return 0;
}
-static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc * _info)
+static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
{
// it won't be probably implemented
// snd_printd("TODO: snd_pcm_oss_get_mapbuf\n");
unsigned int cmd, unsigned long arg)
{
snd_pcm_oss_file_t *pcm_oss_file;
+ int __user *p = (int __user *)arg;
int res;
pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO);
if (cmd == OSS_GETVERSION)
- return put_user(SNDRV_OSS_VERSION, (int *)arg);
+ return put_user(SNDRV_OSS_VERSION, p);
if (cmd == OSS_ALSAEMULVER)
- return put_user(1, (int *)arg);
+ return put_user(1, p);
#if defined(CONFIG_SND_MIXER_OSS) || (defined(MODULE) && defined(CONFIG_SND_MIXER_OSS_MODULE))
if (((cmd >> 8) & 0xff) == 'M') { /* mixer ioctl - for OSS compatibility */
snd_pcm_substream_t *substream;
case SNDCTL_DSP_SYNC:
return snd_pcm_oss_sync(pcm_oss_file);
case SNDCTL_DSP_SPEED:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_READ_RATE:
res = snd_pcm_oss_get_rate(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_STEREO:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = res > 0 ? 2 : 1;
if ((res = snd_pcm_oss_set_channels(pcm_oss_file, res)) < 0)
return res;
- return put_user(--res, (int *)arg);
+ return put_user(--res, p);
case SNDCTL_DSP_GETBLKSIZE:
res = snd_pcm_oss_get_block_size(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_SETFMT:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = snd_pcm_oss_set_format(pcm_oss_file, res);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_READ_BITS:
res = snd_pcm_oss_get_format(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_CHANNELS:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = snd_pcm_oss_set_channels(pcm_oss_file, res);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_READ_CHANNELS:
res = snd_pcm_oss_get_channels(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_WRITE_FILTER:
case SOUND_PCM_READ_FILTER:
return -EIO;
case SNDCTL_DSP_POST:
return snd_pcm_oss_post(pcm_oss_file);
case SNDCTL_DSP_SUBDIVIDE:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = snd_pcm_oss_set_subdivide(pcm_oss_file, res);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
return snd_pcm_oss_set_fragment(pcm_oss_file, res);
case SNDCTL_DSP_GETFMTS:
res = snd_pcm_oss_get_formats(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_GETOSPACE:
case SNDCTL_DSP_GETISPACE:
return snd_pcm_oss_get_space(pcm_oss_file,
cmd == SNDCTL_DSP_GETISPACE ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct audio_buf_info *) arg);
+ (struct audio_buf_info __user *) arg);
case SNDCTL_DSP_NONBLOCK:
return snd_pcm_oss_nonblock(file);
case SNDCTL_DSP_GETCAPS:
res = snd_pcm_oss_get_caps(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_GETTRIGGER:
res = snd_pcm_oss_get_trigger(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
return snd_pcm_oss_set_trigger(pcm_oss_file, res);
case SNDCTL_DSP_GETIPTR:
return snd_pcm_oss_get_ptr(pcm_oss_file,
cmd == SNDCTL_DSP_GETIPTR ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct count_info *) arg);
+ (struct count_info __user *) arg);
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
return snd_pcm_oss_get_mapbuf(pcm_oss_file,
cmd == SNDCTL_DSP_MAPINBUF ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct buffmem_desc *) arg);
+ (struct buffmem_desc __user *) arg);
case SNDCTL_DSP_SETSYNCRO:
/* stop DMA now.. */
return 0;
res = snd_pcm_oss_get_odelay(pcm_oss_file);
if (res < 0) {
/* it's for sure, some broken apps don't check for error codes */
- put_user(0, (int *)arg);
+ put_user(0, p);
return res;
}
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_PROFILE:
return 0; /* silently ignore */
default:
return -EINVAL;
}
-static ssize_t snd_pcm_oss_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
snd_pcm_oss_file_t *pcm_oss_file;
snd_pcm_substream_t *substream;
#endif
}
-static ssize_t snd_pcm_oss_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
snd_pcm_oss_file_t *pcm_oss_file;
snd_pcm_substream_t *substream;
{
int device;
- if (get_user(device, (int *)arg))
+ if (get_user(device, (int __user *)arg))
return -EFAULT;
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_PCM_DEVICES) {
}
if (device == SNDRV_PCM_DEVICES)
device = -1;
- if (put_user(device, (int *)arg))
+ if (put_user(device, (int __user *)arg))
return -EFAULT;
return 0;
}
case SNDRV_CTL_IOCTL_PCM_INFO:
{
- snd_pcm_info_t *info = (snd_pcm_info_t *)arg;
+ snd_pcm_info_t __user *info;
unsigned int device, subdevice;
snd_pcm_stream_t stream;
snd_pcm_t *pcm;
snd_pcm_str_t *pstr;
snd_pcm_substream_t *substream;
+ info = (snd_pcm_info_t __user *)arg;
if (get_user(device, &info->device))
return -EFAULT;
if (device >= SNDRV_PCM_DEVICES)
{
int val;
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)arg))
return -EFAULT;
control->prefer_pcm_subdevice = val;
return 0;
static int snd_pcm_lib_write_transfer(snd_pcm_substream_t *substream,
unsigned int hwoff,
- void *data, unsigned int off,
+ unsigned long data, unsigned int off,
snd_pcm_uframes_t frames)
{
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- char *buf = (char *) data + frames_to_bytes(runtime, off);
+ char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
if (substream->ops->copy) {
if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
return err;
}
typedef int (*transfer_f)(snd_pcm_substream_t *substream, unsigned int hwoff,
- void *data, unsigned int off, snd_pcm_uframes_t size);
+ unsigned long data, unsigned int off,
+ snd_pcm_uframes_t size);
static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
- const void *data, snd_pcm_uframes_t size,
+ unsigned long data,
+ snd_pcm_uframes_t size,
int nonblock,
transfer_f transfer)
{
appl_ptr = runtime->control->appl_ptr;
appl_ofs = appl_ptr % runtime->buffer_size;
snd_pcm_stream_unlock_irq(substream);
- if ((err = transfer(substream, appl_ofs, (void *)data, offset, frames)) < 0)
+ if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
goto _end;
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
}
-snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void *buf, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void __user *buf, snd_pcm_uframes_t size)
{
snd_pcm_runtime_t *runtime;
int nonblock;
if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
runtime->channels > 1)
return -EINVAL;
- return snd_pcm_lib_write1(substream, buf, size, nonblock,
+ return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock,
snd_pcm_lib_write_transfer);
}
static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream,
unsigned int hwoff,
- void *data, unsigned int off,
+ unsigned long data, unsigned int off,
snd_pcm_uframes_t frames)
{
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- void **bufs = data;
+ void __user **bufs = (void __user **)data;
int channels = runtime->channels;
int c;
if (substream->ops->copy) {
if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
return err;
} else {
- char *buf = *bufs + samples_to_bytes(runtime, off);
+ char __user *buf = *bufs + samples_to_bytes(runtime, off);
if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
return err;
}
if (*bufs == NULL) {
snd_pcm_format_set_silence(runtime->format, hwbuf, frames);
} else {
- char *buf = *bufs + samples_to_bytes(runtime, off);
+ char __user *buf = *bufs + samples_to_bytes(runtime, off);
if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames)))
return -EFAULT;
}
return 0;
}
-snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream, void **bufs,
+snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
+ void __user **bufs,
snd_pcm_uframes_t frames)
{
snd_pcm_runtime_t *runtime;
if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
return -EINVAL;
- return snd_pcm_lib_write1(substream, bufs, frames, nonblock,
- snd_pcm_lib_writev_transfer);
+ return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames,
+ nonblock, snd_pcm_lib_writev_transfer);
}
static int snd_pcm_lib_read_transfer(snd_pcm_substream_t *substream,
unsigned int hwoff,
- void *data, unsigned int off,
+ unsigned long data, unsigned int off,
snd_pcm_uframes_t frames)
{
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- char *buf = (char *) data + frames_to_bytes(runtime, off);
+ char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
if (substream->ops->copy) {
if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
return err;
return 0;
}
-static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void *data, snd_pcm_uframes_t size, int nonblock,
+static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream,
+ unsigned long data,
+ snd_pcm_uframes_t size,
+ int nonblock,
transfer_f transfer)
{
snd_pcm_runtime_t *runtime = substream->runtime;
appl_ptr = runtime->control->appl_ptr;
appl_ofs = appl_ptr % runtime->buffer_size;
snd_pcm_stream_unlock_irq(substream);
- if ((err = transfer(substream, appl_ofs, (void *)data, offset, frames)) < 0)
+ if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
goto _end;
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
}
-snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void *buf, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void __user *buf, snd_pcm_uframes_t size)
{
snd_pcm_runtime_t *runtime;
int nonblock;
#endif
if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
return -EINVAL;
- return snd_pcm_lib_read1(substream, buf, size, nonblock, snd_pcm_lib_read_transfer);
+ return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
}
static int snd_pcm_lib_readv_transfer(snd_pcm_substream_t *substream,
unsigned int hwoff,
- void *data, unsigned int off,
+ unsigned long data, unsigned int off,
snd_pcm_uframes_t frames)
{
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
- void **bufs = data;
+ void __user **bufs = (void __user **)data;
int channels = runtime->channels;
int c;
if (substream->ops->copy) {
for (c = 0; c < channels; ++c, ++bufs) {
- char *buf;
+ char __user *buf;
if (*bufs == NULL)
continue;
buf = *bufs + samples_to_bytes(runtime, off);
snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
snd_assert(runtime->dma_area, return -EFAULT);
for (c = 0; c < channels; ++c, ++bufs) {
- char *hwbuf, *buf;
+ char *hwbuf;
+ char __user *buf;
if (*bufs == NULL)
continue;
return 0;
}
-snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream, void **bufs,
+snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
+ void __user **bufs,
snd_pcm_uframes_t frames)
{
snd_pcm_runtime_t *runtime;
if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
return -EINVAL;
- return snd_pcm_lib_read1(substream, bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
+ return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
}
/*
#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old)
#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old)
-static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams);
-static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams);
+static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams);
+static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams);
/*
*
return 0;
}
-int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t * _info)
+int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user * _info)
{
snd_pcm_info_t info;
int err = snd_pcm_info(substream, &info);
return 0;
}
-static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * _params)
+static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params)
{
snd_pcm_hw_params_t params;
int err;
return err;
}
-static int snd_pcm_hw_params_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * _params)
+static int snd_pcm_hw_params_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params)
{
snd_pcm_hw_params_t params;
int err;
return 0;
}
-static int snd_pcm_sw_params_user(snd_pcm_substream_t * substream, snd_pcm_sw_params_t * _params)
+static int snd_pcm_sw_params_user(snd_pcm_substream_t * substream, snd_pcm_sw_params_t __user * _params)
{
snd_pcm_sw_params_t params;
int err;
return 0;
}
-static int snd_pcm_status_user(snd_pcm_substream_t * substream, snd_pcm_status_t * _status)
+static int snd_pcm_status_user(snd_pcm_substream_t * substream, snd_pcm_status_t __user * _status)
{
snd_pcm_status_t status;
snd_pcm_runtime_t *runtime;
return 0;
}
-static int snd_pcm_channel_info(snd_pcm_substream_t * substream, snd_pcm_channel_info_t * _info)
+static int snd_pcm_channel_info(snd_pcm_substream_t * substream, snd_pcm_channel_info_t __user * _info)
{
snd_pcm_channel_info_t info;
snd_pcm_runtime_t *runtime;
return err;
}
-static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t *res)
+static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t __user *res)
{
snd_pcm_runtime_t *runtime = substream->runtime;
int err;
return err;
}
-static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_sync_ptr *_sync_ptr)
+static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_sync_ptr __user *_sync_ptr)
{
snd_pcm_runtime_t *runtime = substream->runtime;
struct sndrv_pcm_sync_ptr sync_ptr;
int err;
memset(&sync_ptr, 0, sizeof(sync_ptr));
- if (get_user(sync_ptr.flags, (unsigned int *) &(_sync_ptr->flags)))
+ if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
return -EFAULT;
if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct sndrv_pcm_mmap_control)))
return -EFAULT;
}
static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
- unsigned int cmd, void *arg);
+ unsigned int cmd, void __user *arg);
static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
- unsigned int cmd, void *arg);
+ unsigned int cmd, void __user *arg);
static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
- unsigned int cmd, void *arg)
+ unsigned int cmd, void __user *arg)
{
snd_assert(substream != NULL, return -ENXIO);
switch (cmd) {
case SNDRV_PCM_IOCTL_PVERSION:
- return put_user(SNDRV_PCM_VERSION, (int *)arg) ? -EFAULT : 0;
+ return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
case SNDRV_PCM_IOCTL_INFO:
- return snd_pcm_info_user(substream, (snd_pcm_info_t *) arg);
+ return snd_pcm_info_user(substream, arg);
case SNDRV_PCM_IOCTL_TSTAMP:
{
int xarg;
- if (get_user(xarg, (int *) arg))
+ if (get_user(xarg, (int __user *)arg))
return -EFAULT;
substream->runtime->tstamp_timespec = xarg ? 1 : 0;
return 0;
}
case SNDRV_PCM_IOCTL_HW_REFINE:
- return snd_pcm_hw_refine_user(substream, (snd_pcm_hw_params_t *) arg);
+ return snd_pcm_hw_refine_user(substream, arg);
case SNDRV_PCM_IOCTL_HW_PARAMS:
- return snd_pcm_hw_params_user(substream, (snd_pcm_hw_params_t *) arg);
+ return snd_pcm_hw_params_user(substream, arg);
case SNDRV_PCM_IOCTL_HW_FREE:
return snd_pcm_hw_free(substream);
case SNDRV_PCM_IOCTL_SW_PARAMS:
- return snd_pcm_sw_params_user(substream, (snd_pcm_sw_params_t *) arg);
+ return snd_pcm_sw_params_user(substream, arg);
case SNDRV_PCM_IOCTL_STATUS:
- return snd_pcm_status_user(substream, (snd_pcm_status_t *) arg);
+ return snd_pcm_status_user(substream, arg);
case SNDRV_PCM_IOCTL_CHANNEL_INFO:
- return snd_pcm_channel_info(substream, (snd_pcm_channel_info_t *) arg);
+ return snd_pcm_channel_info(substream, arg);
case SNDRV_PCM_IOCTL_PREPARE:
return snd_pcm_prepare(substream);
case SNDRV_PCM_IOCTL_RESET:
case SNDRV_PCM_IOCTL_START:
return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, 0, 0);
case SNDRV_PCM_IOCTL_LINK:
- return snd_pcm_link(substream, (long) arg);
+ return snd_pcm_link(substream, (int)(unsigned long) arg);
case SNDRV_PCM_IOCTL_UNLINK:
return snd_pcm_unlink(substream);
case SNDRV_PCM_IOCTL_RESUME:
case SNDRV_PCM_IOCTL_HWSYNC:
return snd_pcm_hwsync(substream);
case SNDRV_PCM_IOCTL_DELAY:
- return snd_pcm_delay(substream, (snd_pcm_sframes_t *) arg);
+ return snd_pcm_delay(substream, arg);
case SNDRV_PCM_IOCTL_SYNC_PTR:
- return snd_pcm_sync_ptr(substream, (struct sndrv_pcm_sync_ptr *) arg);
+ return snd_pcm_sync_ptr(substream, arg);
case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
- return snd_pcm_hw_refine_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
+ return snd_pcm_hw_refine_old_user(substream, arg);
case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
- return snd_pcm_hw_params_old_user(substream, (struct sndrv_pcm_hw_params_old *) arg);
+ return snd_pcm_hw_params_old_user(substream, arg);
}
snd_printd("unknown ioctl = 0x%x\n", cmd);
return -ENOTTY;
}
static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
- unsigned int cmd, void *arg)
+ unsigned int cmd, void __user *arg)
{
snd_assert(substream != NULL, return -ENXIO);
snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL);
switch (cmd) {
case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
{
- snd_xferi_t xferi, *_xferi = arg;
+ snd_xferi_t xferi;
+ snd_xferi_t __user *_xferi = arg;
snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
}
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
{
- snd_xfern_t xfern, *_xfern = arg;
+ snd_xfern_t xfern;
+ snd_xfern_t __user *_xfern = arg;
snd_pcm_runtime_t *runtime = substream->runtime;
- void *bufs;
+ void __user **bufs;
snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
}
case SNDRV_PCM_IOCTL_REWIND:
{
- snd_pcm_uframes_t frames, *_frames = arg;
+ snd_pcm_uframes_t frames;
+ snd_pcm_uframes_t __user *_frames = arg;
snd_pcm_sframes_t result;
if (get_user(frames, _frames))
return -EFAULT;
}
case SNDRV_PCM_IOCTL_FORWARD:
{
- snd_pcm_uframes_t frames, *_frames = arg;
+ snd_pcm_uframes_t frames;
+ snd_pcm_uframes_t __user *_frames = arg;
snd_pcm_sframes_t result;
if (get_user(frames, _frames))
return -EFAULT;
{
int res;
snd_pcm_stream_lock_irq(substream);
- res = snd_pcm_pause(substream, (long) arg);
+ res = snd_pcm_pause(substream, (int)(unsigned long)arg);
snd_pcm_stream_unlock_irq(substream);
return res;
}
}
static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
- unsigned int cmd, void *arg)
+ unsigned int cmd, void __user *arg)
{
snd_assert(substream != NULL, return -ENXIO);
snd_assert(substream->stream == SNDRV_PCM_STREAM_CAPTURE, return -EINVAL);
switch (cmd) {
case SNDRV_PCM_IOCTL_READI_FRAMES:
{
- snd_xferi_t xferi, *_xferi = arg;
+ snd_xferi_t xferi;
+ snd_xferi_t __user *_xferi = arg;
snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_sframes_t result;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
}
case SNDRV_PCM_IOCTL_READN_FRAMES:
{
- snd_xfern_t xfern, *_xfern = arg;
+ snd_xfern_t xfern;
+ snd_xfern_t __user *_xfern = arg;
snd_pcm_runtime_t *runtime = substream->runtime;
void *bufs;
snd_pcm_sframes_t result;
}
case SNDRV_PCM_IOCTL_REWIND:
{
- snd_pcm_uframes_t frames, *_frames = arg;
+ snd_pcm_uframes_t frames;
+ snd_pcm_uframes_t __user *_frames = arg;
snd_pcm_sframes_t result;
if (get_user(frames, _frames))
return -EFAULT;
}
case SNDRV_PCM_IOCTL_FORWARD:
{
- snd_pcm_uframes_t frames, *_frames = arg;
+ snd_pcm_uframes_t frames;
+ snd_pcm_uframes_t __user *_frames = arg;
snd_pcm_sframes_t result;
if (get_user(frames, _frames))
return -EFAULT;
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
- return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void *) arg);
+ return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
}
static int snd_pcm_capture_ioctl(struct inode *inode, struct file *file,
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
- return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void *) arg);
+ return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
}
int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream,
}
}
-static ssize_t snd_pcm_read(struct file *file, char *buf, size_t count, loff_t * offset)
+static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, loff_t * offset)
{
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
return result;
}
-static ssize_t snd_pcm_write(struct file *file, const char *buf, size_t count, loff_t * offset)
+static ssize_t snd_pcm_write(struct file *file, const char __user *buf, size_t count, loff_t * offset)
{
snd_pcm_file_t *pcm_file;
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result;
unsigned long i;
- void **bufs;
+ void __user **bufs;
snd_pcm_uframes_t frames;
pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, return -ENXIO);
snd_pcm_runtime_t *runtime;
snd_pcm_sframes_t result;
unsigned long i;
- void **bufs;
+ void __user **bufs;
snd_pcm_uframes_t frames;
pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
oparams->fifo_size = params->fifo_size;
}
-static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams)
+static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams)
{
snd_pcm_hw_params_t params;
struct sndrv_pcm_hw_params_old oparams;
return err;
}
-static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old * _oparams)
+static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams)
{
snd_pcm_hw_params_t params;
struct sndrv_pcm_hw_params_old oparams;
return 0;
}
-static int snd_rawmidi_info_user(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t * _info)
+static int snd_rawmidi_info_user(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t __user * _info)
{
snd_rawmidi_info_t info;
int err;
}
static int snd_rawmidi_info_select_user(snd_card_t *card,
- snd_rawmidi_info_t *_info)
+ snd_rawmidi_info_t __user *_info)
{
int err;
snd_rawmidi_info_t info;
unsigned int cmd, unsigned long arg)
{
snd_rawmidi_file_t *rfile;
+ void __user *argp = (void __user *)arg;
rfile = snd_magic_cast(snd_rawmidi_file_t, file->private_data, return -ENXIO);
if (((cmd >> 8) & 0xff) != 'W')
return -ENOTTY;
switch (cmd) {
case SNDRV_RAWMIDI_IOCTL_PVERSION:
- return put_user(SNDRV_RAWMIDI_VERSION, (int *)arg) ? -EFAULT : 0;
+ return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0;
case SNDRV_RAWMIDI_IOCTL_INFO:
{
snd_rawmidi_stream_t stream;
- snd_rawmidi_info_t *info = (snd_rawmidi_info_t *) arg;
+ snd_rawmidi_info_t __user *info = argp;
if (get_user(stream, &info->stream))
return -EFAULT;
switch (stream) {
case SNDRV_RAWMIDI_IOCTL_PARAMS:
{
snd_rawmidi_params_t params;
- if (copy_from_user(¶ms, (snd_rawmidi_params_t *) arg, sizeof(snd_rawmidi_params_t)))
+ if (copy_from_user(¶ms, argp, sizeof(snd_rawmidi_params_t)))
return -EFAULT;
switch (params.stream) {
case SNDRV_RAWMIDI_STREAM_OUTPUT:
{
int err = 0;
snd_rawmidi_status_t status;
- if (copy_from_user(&status, (snd_rawmidi_status_t *) arg, sizeof(snd_rawmidi_status_t)))
+ if (copy_from_user(&status, argp, sizeof(snd_rawmidi_status_t)))
return -EFAULT;
switch (status.stream) {
case SNDRV_RAWMIDI_STREAM_OUTPUT:
}
if (err < 0)
return err;
- if (copy_to_user((snd_rawmidi_status_t *) arg, &status, sizeof(snd_rawmidi_status_t)))
+ if (copy_to_user(argp, &status, sizeof(snd_rawmidi_status_t)))
return -EFAULT;
return 0;
}
case SNDRV_RAWMIDI_IOCTL_DROP:
{
int val;
- if (get_user(val, (long *) arg))
+ if (get_user(val, (long __user *) argp))
return -EFAULT;
switch (val) {
case SNDRV_RAWMIDI_STREAM_OUTPUT:
case SNDRV_RAWMIDI_IOCTL_DRAIN:
{
int val;
- if (get_user(val, (long *) arg))
+ if (get_user(val, (long __user *) argp))
return -EFAULT;
switch (val) {
case SNDRV_RAWMIDI_STREAM_OUTPUT:
int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
unsigned int tmp;
tmp = card->number * SNDRV_RAWMIDI_DEVICES;
{
int device;
- if (get_user(device, (int *)arg))
+ if (get_user(device, (int __user *)argp))
return -EFAULT;
device = device < 0 ? 0 : device + 1;
while (device < SNDRV_RAWMIDI_DEVICES) {
}
if (device == SNDRV_RAWMIDI_DEVICES)
device = -1;
- if (put_user(device, (int *)arg))
+ if (put_user(device, (int __user *)argp))
return -EFAULT;
return 0;
}
{
int val;
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
control->prefer_rawmidi_subdevice = val;
return 0;
}
case SNDRV_CTL_IOCTL_RAWMIDI_INFO:
- return snd_rawmidi_info_select_user(card, (snd_rawmidi_info_t *)arg);
+ return snd_rawmidi_info_select_user(card, argp);
}
return -ENOIOCTLCMD;
}
return snd_rawmidi_kernel_read1(substream, buf, count, 1);
}
-static ssize_t snd_rawmidi_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
long result;
int count1;
return snd_rawmidi_kernel_write1(substream, buf, count, 1);
}
-static ssize_t snd_rawmidi_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
long result, timeout;
int count1;
obj-$(call sequencer,$(CONFIG_SND_CS4231)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4236)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
-obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ES1688)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_CS4232)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_CS4236)) += snd-ainstr-fm.o
-obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_ES1688)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
char *snd_seq_fm_id = SNDRV_SEQ_INSTR_ID_OPL2_3;
static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len, int atomic, int cmd)
{
fm_instrument_t *ip;
fm_xinstrument_t ix;
}
static int snd_seq_fm_get(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len, int atomic,
+ int cmd)
{
fm_instrument_t *ip;
fm_xinstrument_t ix;
static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
gf1_instrument_t *ip,
- char **data,
+ char __user **data,
long *len,
int atomic)
{
}
static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len, int atomic,
+ int cmd)
{
snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
gf1_instrument_t *ip;
static int snd_seq_gf1_copy_wave_to_stream(snd_gf1_ops_t *ops,
gf1_instrument_t *ip,
- char **data,
+ char __user **data,
long *len,
int atomic)
{
}
static int snd_seq_gf1_get(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len, int atomic,
+ int cmd)
{
snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
gf1_instrument_t *ip;
iwffff_layer_t *lp,
iwffff_env_t *ep,
iwffff_xenv_t *ex,
- char **data,
+ char __user **data,
long *len,
int gfp_mask)
{
static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops,
iwffff_layer_t *lp,
- char **data,
+ char __user **data,
long *len,
int atomic)
{
}
static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len, int atomic,
+ int cmd)
{
snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
iwffff_instrument_t *ip;
iwffff_layer_t *lp,
iwffff_xenv_t *ex,
iwffff_env_t *ep,
- char **data,
+ char __user **data,
long *len)
{
iwffff_env_record_t *rp;
static int snd_seq_iwffff_copy_wave_to_stream(snd_iwffff_ops_t *ops,
iwffff_layer_t *lp,
- char **data,
+ char __user **data,
long *len,
int atomic)
{
}
static int snd_seq_iwffff_get(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len, int atomic, int cmd)
{
snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
iwffff_instrument_t *ip;
iwffff_xinstrument_t ix;
iwffff_layer_t *lp;
iwffff_xlayer_t lx;
- char *layer_instr_data;
+ char __user *layer_instr_data;
int err;
if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
}
static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len,
+ int atomic, int cmd)
{
snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
simple_instrument_t *ip;
}
static int snd_seq_simple_get(void *private_data, snd_seq_kinstr_t *instr,
- char *instr_data, long len, int atomic, int cmd)
+ char __user *instr_data, long len,
+ int atomic, int cmd)
{
snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
simple_instrument_t *ip;
static int odev_open(struct inode *inode, struct file *file);
static int odev_release(struct inode *inode, struct file *file);
-static ssize_t odev_read(struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t odev_write(struct file *file, const char *buf, size_t count, loff_t *offset);
+static ssize_t odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
+static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
static int odev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static unsigned int odev_poll(struct file *file, poll_table * wait);
#ifdef CONFIG_PROC_FS
}
static ssize_t
-odev_read(struct file *file, char *buf, size_t count, loff_t *offset)
+odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
seq_oss_devinfo_t *dp;
dp = file->private_data;
static ssize_t
-odev_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
seq_oss_devinfo_t *dp;
dp = file->private_data;
struct midi_info minf;
unsigned char ev[8];
void __user *arg = (void __user *)carg;
+ int __user *p = arg;
snd_seq_event_t tmpev;
switch (cmd) {
case SNDCTL_SEQ_TESTMIDI:
debug_printk(("test midi\n"));
- if (get_user(dev, (int *)arg))
+ if (get_user(dev, p))
return -EFAULT;
return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
debug_printk(("get in count\n"));
if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
return 0;
- return put_user(dp->readq->qlen, (int *)arg) ? -EFAULT : 0;
+ return put_user(dp->readq->qlen, p) ? -EFAULT : 0;
case SNDCTL_SEQ_GETOUTCOUNT:
debug_printk(("get out count\n"));
if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
return 0;
- return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), (int *)arg) ? -EFAULT : 0;
+ return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;
case SNDCTL_SEQ_GETTIME:
debug_printk(("get time\n"));
- return put_user(snd_seq_oss_timer_cur_tick(dp->timer), (int *)arg) ? -EFAULT : 0;
+ return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0;
case SNDCTL_SEQ_RESETSAMPLES:
debug_printk(("reset samples\n"));
- if (get_user(dev, (int *)arg))
+ if (get_user(dev, p))
return -EFAULT;
return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
case SNDCTL_SEQ_NRSYNTHS:
debug_printk(("nr synths\n"));
- return put_user(dp->max_synthdev, (int *)arg) ? -EFAULT : 0;
+ return put_user(dp->max_synthdev, p) ? -EFAULT : 0;
case SNDCTL_SEQ_NRMIDIS:
debug_printk(("nr midis\n"));
- return put_user(dp->max_mididev, (int *)arg) ? -EFAULT : 0;
+ return put_user(dp->max_mididev, p) ? -EFAULT : 0;
case SNDCTL_SYNTH_MEMAVL:
debug_printk(("mem avail\n"));
- if (get_user(dev, (int *)arg))
+ if (get_user(dev, p))
return -EFAULT;
val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
- return put_user(val, (int *)arg) ? -EFAULT : 0;
+ return put_user(val, p) ? -EFAULT : 0;
case SNDCTL_FM_4OP_ENABLE:
debug_printk(("4op\n"));
- if (get_user(dev, (int *)arg))
+ if (get_user(dev, p))
return -EFAULT;
snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
return 0;
debug_printk(("threshold\n"));
if (! is_write_mode(dp->file_mode))
return 0;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val < 1)
val = 1;
debug_printk(("pretime\n"));
if (dp->readq == NULL || !is_read_mode(dp->file_mode))
return 0;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val <= 0)
val = -1;
else
val = (HZ * val) / 10;
dp->readq->pre_event_timeout = val;
- return put_user(val, (int *)arg) ? -EFAULT : 0;
+ return put_user(val, p) ? -EFAULT : 0;
default:
debug_printk(("others\n"));
switch (cmd) {
case SNDRV_SEQ_IOCTL_PVERSION:
/* return sequencer version number */
- return put_user(SNDRV_SEQ_VERSION, (int *)arg) ? -EFAULT : 0;
+ return put_user(SNDRV_SEQ_VERSION, (int __user *)arg) ? -EFAULT : 0;
case SNDRV_SEQ_IOCTL_CLIENT_ID:
/* return the id of this client */
- return put_user(client->number, (int *)arg) ? -EFAULT : 0;
+ return put_user(client->number, (int __user *)arg) ? -EFAULT : 0;
}
if (! arg)
return -EFAULT;
for (p = ioctl_tables; p->cmd; p++) {
if (p->cmd == cmd)
- return p->func(client, (void __user *) arg);
+ return p->func(client, arg);
}
snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n",
cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
* exported, called by kernel clients to perform same functions as with
* userland ioctl()
*/
-int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void __user *arg)
+int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
{
client_t *client;
mm_segment_t fs;
if (event->data.ext.len & SNDRV_SEQ_EXT_USRPTR) {
char buf[32];
- char *curptr = event->data.ext.ptr;
+ char __user *curptr = event->data.ext.ptr;
while (len > 0) {
int size = sizeof(buf);
if (len < size)
id->subdevice = timer->tmr_subdevice;
}
-static int snd_timer_user_next_device(snd_timer_id_t *_tid)
+static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
{
snd_timer_id_t id;
snd_timer_t *timer;
return 0;
}
-static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t *_ginfo)
+static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
{
snd_timer_ginfo_t ginfo;
snd_timer_id_t tid;
return err;
}
-static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t *_gparams)
+static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams)
{
snd_timer_gparams_t gparams;
snd_timer_t *t;
return err;
}
-static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t *_gstatus)
+static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus)
{
snd_timer_gstatus_t gstatus;
snd_timer_id_t tid;
err = -ENODEV;
}
up(®ister_mutex);
- if (err >= 0 && copy_from_user(_gstatus, &gstatus, sizeof(gstatus)))
+ if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
err = -EFAULT;
return err;
}
-static int snd_timer_user_tselect(struct file *file, snd_timer_select_t *_tselect)
+static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect)
{
snd_timer_user_t *tu;
snd_timer_select_t tselect;
return 0;
}
-static int snd_timer_user_info(struct file *file, snd_timer_info_t *_info)
+static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
{
snd_timer_user_t *tu;
snd_timer_info_t info;
return 0;
}
-static int snd_timer_user_params(struct file *file, snd_timer_params_t *_params)
+static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
{
snd_timer_user_t *tu;
snd_timer_params_t params;
return err;
}
-static int snd_timer_user_status(struct file *file, snd_timer_status_t *_status)
+static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status)
{
snd_timer_user_t *tu;
snd_timer_status_t status;
unsigned int cmd, unsigned long arg)
{
snd_timer_user_t *tu;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO);
switch (cmd) {
case SNDRV_TIMER_IOCTL_PVERSION:
- return put_user(SNDRV_TIMER_VERSION, (int *)arg) ? -EFAULT : 0;
+ return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0;
case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
- return snd_timer_user_next_device((snd_timer_id_t *)arg);
+ return snd_timer_user_next_device(argp);
case SNDRV_TIMER_IOCTL_TREAD:
{
int xarg;
if (tu->timeri) /* too late */
return -EBUSY;
- if (get_user(xarg, (int *) arg))
+ if (get_user(xarg, p))
return -EFAULT;
tu->tread = xarg ? 1 : 0;
return 0;
}
case SNDRV_TIMER_IOCTL_GINFO:
- return snd_timer_user_ginfo(file, (snd_timer_ginfo_t *)arg);
+ return snd_timer_user_ginfo(file, argp);
case SNDRV_TIMER_IOCTL_GPARAMS:
- return snd_timer_user_gparams(file, (snd_timer_gparams_t *)arg);
+ return snd_timer_user_gparams(file, argp);
case SNDRV_TIMER_IOCTL_GSTATUS:
- return snd_timer_user_gstatus(file, (snd_timer_gstatus_t *)arg);
+ return snd_timer_user_gstatus(file, argp);
case SNDRV_TIMER_IOCTL_SELECT:
- return snd_timer_user_tselect(file, (snd_timer_select_t *)arg);
+ return snd_timer_user_tselect(file, argp);
case SNDRV_TIMER_IOCTL_INFO:
- return snd_timer_user_info(file, (snd_timer_info_t *)arg);
+ return snd_timer_user_info(file, argp);
case SNDRV_TIMER_IOCTL_PARAMS:
- return snd_timer_user_params(file, (snd_timer_params_t *)arg);
+ return snd_timer_user_params(file, argp);
case SNDRV_TIMER_IOCTL_STATUS:
- return snd_timer_user_status(file, (snd_timer_status_t *)arg);
+ return snd_timer_user_status(file, argp);
case SNDRV_TIMER_IOCTL_START:
return snd_timer_user_start(file);
case SNDRV_TIMER_IOCTL_STOP:
return 0;
}
-static ssize_t snd_timer_user_read(struct file *file, char *buffer, size_t count, loff_t *offset)
+static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset)
{
snd_timer_user_t *tu;
long result = 0, unit;
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
-#ifdef CONFIG_X86_PC9800
-static int pc98ii[SNDRV_CARDS]; /* PC98-II dauther board */
-#endif
static int boot_devs;
module_param_array(index, int, boot_devs, 0444);
module_param_array(irq, int, boot_devs, 0444);
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
-#ifdef CONFIG_X86_PC9800
-module_param_array(pc98ii, bool, boot_devs, 0444);
-MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
-MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
-#endif
#ifndef CONFIG_ACPI_BUS
struct acpi_device;
}
#endif
if (snd_mpu401_uart_new(card, 0,
-#ifdef CONFIG_X86_PC9800
- pc98ii[dev] ? MPU401_HW_PC98II :
-#endif
MPU401_HW_MPU401,
port[dev], 0,
irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
case OPL3_HW_OPL3_CS:
case OPL3_HW_OPL3_FM801:
opl3->command = &snd_opl3_command;
- break;
- case OPL3_HW_OPL3_PC98:
- opl3->command = &snd_opl3_command;
-
- /* Initialize? */
- opl3->command(opl3, OPL3_RIGHT | 0x05, 0x05);
- opl3->command(opl3, OPL3_RIGHT | 0x08, 0x04);
- opl3->command(opl3, OPL3_RIGHT | 0x08, 0x00);
- opl3->command(opl3, OPL3_LEFT | 0xf7, 0x00);
- opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
- opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
- inb(opl3->l_port);
-
- opl3->command(opl3, OPL3_LEFT | 0x02, 0xff);
- opl3->command(opl3, OPL3_LEFT | 0x04, 0x21);
- inb(opl3->l_port);
-
- opl3->command(opl3, OPL3_LEFT | 0x04, 0x60);
- opl3->command(opl3, OPL3_LEFT | 0x04, 0x80);
-
break;
case OPL3_HW_OPL3_CS4281:
opl3->command = &snd_opl3_cs4281_command;
unsigned int cmd, unsigned long arg)
{
opl3_t *opl3 = snd_magic_cast(opl3_t, hw->private_data, return -ENXIO);
+ void __user *argp = (void __user *)arg;
snd_assert(opl3 != NULL, return -EINVAL);
info.fm_mode = opl3->fm_mode;
info.rhythm = opl3->rhythm;
- if (copy_to_user((snd_dm_fm_info_t *) arg, &info, sizeof(snd_dm_fm_info_t)))
+ if (copy_to_user(argp, &info, sizeof(snd_dm_fm_info_t)))
return -EFAULT;
return 0;
}
#endif
{
snd_dm_fm_note_t note;
- if (copy_from_user(¬e, (snd_dm_fm_note_t *) arg, sizeof(snd_dm_fm_note_t)))
+ if (copy_from_user(¬e, argp, sizeof(snd_dm_fm_note_t)))
return -EFAULT;
return snd_opl3_play_note(opl3, ¬e);
}
#endif
{
snd_dm_fm_voice_t voice;
- if (copy_from_user(&voice, (snd_dm_fm_voice_t *) arg, sizeof(snd_dm_fm_voice_t)))
+ if (copy_from_user(&voice, argp, sizeof(snd_dm_fm_voice_t)))
return -EFAULT;
return snd_opl3_set_voice(opl3, &voice);
}
#endif
{
snd_dm_fm_params_t params;
- if (copy_from_user(¶ms, (snd_dm_fm_params_t *) arg, sizeof(snd_dm_fm_params_t)))
+ if (copy_from_user(¶ms, argp, sizeof(snd_dm_fm_params_t)))
return -EFAULT;
return snd_opl3_set_params(opl3, ¶ms);
}
}
static long snd_opl4_mem_proc_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *_buf, long count)
+ struct file *file, char __user *_buf, long count)
{
opl4_t *opl4 = snd_magic_cast(opl4_t, entry->private_data, return -ENXIO);
long size;
}
static long snd_opl4_mem_proc_write(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, const char *_buf, long count)
+ struct file *file, const char __user *_buf, long count)
{
opl4_t *opl4 = snd_magic_cast(opl4_t, entry->private_data, return -ENXIO);
long size;
Say 'Y' or 'M' to include support for CS4235,CS4236,CS4237B,CS4238B,CS4239
chips from Cirrus Logic - Crystal Semiconductors.
-config SND_PC98_CS4232
- tristate "NEC PC9800 CS4232 driver"
- depends on SND && X86_PC9800
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_PCM
- help
- Say 'Y' or 'M' to include support for NEC PC-9801/PC-9821 on-board
- soundchip based on CS4232.
-
config SND_ES968
tristate "Generic ESS ES968 driver"
depends on SND && ISAPNP
snd-cs4231-objs := cs4231.o
snd-cs4232-objs := cs4232.o
snd-cs4236-objs := cs4236.o
-snd-pc98-cs4232-objs := pc98.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.o
obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-cs4231-lib.o
obj-$(CONFIG_SND_WAVEFRONT) += snd-cs4231-lib.o
obj-$(CONFIG_SND_SSCAPE) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_PC98_CS4232) += snd-pc98-cs4232.o snd-cs4231-lib.o
obj-m := $(sort $(obj-m))
#include <sound/info.h>
-static int snd_gus_dram_poke(snd_gus_card_t *gus, char *_buffer,
+static int snd_gus_dram_poke(snd_gus_card_t *gus, char __user *_buffer,
unsigned int address, unsigned int size)
{
unsigned long flags;
}
-int snd_gus_dram_write(snd_gus_card_t *gus, char *buffer,
+int snd_gus_dram_write(snd_gus_card_t *gus, char __user *buffer,
unsigned int address, unsigned int size)
{
return snd_gus_dram_poke(gus, buffer, address, size);
}
-static int snd_gus_dram_peek(snd_gus_card_t *gus, char *_buffer,
+static int snd_gus_dram_peek(snd_gus_card_t *gus, char __user *_buffer,
unsigned int address, unsigned int size,
int rom)
{
return 0;
}
-int snd_gus_dram_read(snd_gus_card_t *gus, char *buffer,
+int snd_gus_dram_read(snd_gus_card_t *gus, char __user *buffer,
unsigned int address, unsigned int size,
int rom)
{
*/
int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
snd_gf1_mem_block_t *block;
}
int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
*/
int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
snd_gf1_mem_block_t *block;
}
int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
*/
int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
snd_gf1_mem_block_t *block;
}
int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return -ENXIO);
} gus_proc_private_t;
static long snd_gf1_mem_proc_dump(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
long size;
gus_proc_private_t *priv = snd_magic_cast(gus_proc_private_t, entry->private_data, return -ENXIO);
static int snd_gf1_pcm_playback_copy(snd_pcm_substream_t *substream,
int voice,
snd_pcm_uframes_t pos,
- void *src,
+ void __user *src,
snd_pcm_uframes_t count)
{
snd_pcm_runtime_t *runtime = substream->runtime;
unsigned short c;
if (mode & SNDRV_SFNT_SAMPLE_8BITS) {
unsigned char cc;
- get_user(cc, (unsigned char*)buf + offset);
+ get_user(cc, (unsigned char __user *)buf + offset);
c = cc << 8; /* convert 8bit -> 16bit */
} else {
#ifdef SNDRV_LITTLE_ENDIAN
- get_user(c, (unsigned short*)buf + offset);
+ get_user(c, (unsigned short __user *)buf + offset);
#else
unsigned short cc;
- get_user(cc, (unsigned short*)buf + offset);
+ get_user(cc, (unsigned short __user *)buf + offset);
c = swab16(cc);
#endif
}
static int emu8k_pcm_copy(snd_pcm_substream_t *subs,
int voice,
snd_pcm_uframes_t pos,
- void *src,
+ void __user *src,
snd_pcm_uframes_t count)
{
emu8k_pcm_t *rec = subs->runtime->private_data;
emu8000_t *emu = rec->emu;
- unsigned short *buf = src;
+ unsigned short __user *buf = src;
snd_emu8000_write_wait(emu, 1);
EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]);
static int set_mode_register(sb_t *chip, unsigned char mode);
static int get_version(sb_t *chip);
-static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t * code);
+static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * code);
static int snd_sb_csp_unload(snd_sb_csp_t * p);
-static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, int load_flags);
+static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags);
static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode);
static int snd_sb_csp_check_version(snd_sb_csp_t * p);
info.run_width = p->run_width;
info.version = p->version;
info.state = p->running;
- if (copy_to_user((void *) arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
err = -EFAULT;
else
err = 0;
/* load CSP microcode */
case SNDRV_SB_CSP_IOCTL_LOAD_CODE:
err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
- -EBUSY : snd_sb_csp_riff_load(p, (snd_sb_csp_microcode_t *) arg));
+ -EBUSY : snd_sb_csp_riff_load(p, (snd_sb_csp_microcode_t __user *) arg));
break;
case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE:
err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
/* change CSP running state */
case SNDRV_SB_CSP_IOCTL_START:
- if (copy_from_user(&start_info, (void *) arg, sizeof(start_info)))
+ if (copy_from_user(&start_info, (void __user *) arg, sizeof(start_info)))
err = -EFAULT;
else
err = snd_sb_csp_start(p, start_info.sample_width, start_info.channels);
* load microcode via ioctl:
* code is user-space pointer
*/
-static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t * mcode)
+static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * mcode)
{
snd_sb_csp_mc_header_t info;
- unsigned char *data_ptr, *data_end;
+ unsigned char __user *data_ptr;
+ unsigned char __user *data_end;
unsigned short func_nr = 0;
riff_header_t file_h, item_h, code_h;
if (code_h.name != INIT_HEADER)
break;
data_ptr += sizeof(code_h);
- err = snd_sb_csp_load(p, data_ptr, LE_INT(code_h.len),
- SNDRV_SB_CSP_LOAD_INITBLOCK | SNDRV_SB_CSP_LOAD_FROMUSER);
+ err = snd_sb_csp_load_user(p, data_ptr, LE_INT(code_h.len),
+ SNDRV_SB_CSP_LOAD_INITBLOCK);
if (err)
return err;
data_ptr += LE_INT(code_h.len);
return -EINVAL;
}
data_ptr += sizeof(code_h);
- err = snd_sb_csp_load(p, data_ptr, LE_INT(code_h.len),
- SNDRV_SB_CSP_LOAD_FROMUSER);
+ err = snd_sb_csp_load_user(p, data_ptr,
+ LE_INT(code_h.len), 0);
if (err)
return err;
/* Send high byte */
snd_sbdsp_command(p->chip, (unsigned char)((size - 1) >> 8));
/* send microcode sequence */
- if (load_flags & SNDRV_SB_CSP_LOAD_FROMUSER) {
- /* copy microcode from user space */
- unsigned char *kbuf, *_kbuf;
- _kbuf = kbuf = kmalloc (size, GFP_KERNEL);
- if (copy_from_user(kbuf, buf, size)) {
- result = -EFAULT;
- kfree (_kbuf);
+ /* load from kernel space */
+ while (size--) {
+ if (!snd_sbdsp_command(p->chip, *buf++))
goto __fail;
- }
- while (size--) {
- if (!snd_sbdsp_command(p->chip, *kbuf++)) {
- kfree (_kbuf);
- goto __fail;
- }
- }
- kfree (_kbuf);
- } else {
- /* load from kernel space */
- while (size--) {
- if (!snd_sbdsp_command(p->chip, *buf++))
- goto __fail;
- }
}
if (snd_sbdsp_get_byte(p->chip))
goto __fail;
spin_unlock_irqrestore(&p->chip->reg_lock, flags);
return result;
}
+
+static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags)
+{
+ int err = -ENOMEM;
+ unsigned char *kbuf = kmalloc(size, GFP_KERNEL);
+ if (kbuf) {
+ if (copy_from_user(kbuf, buf, size))
+ err = -EFAULT;
+ else
+ err = snd_sb_csp_load(p, kbuf, size, load_flags);
+ kfree(kbuf);
+ }
+ return err;
+}
#include "sb16_csp_codecs.h"
* Upload a byte-stream into the SoundScape using DMA channel A.
*/
static int upload_dma_data(struct soundscape *s,
- const unsigned char *data,
+ const unsigned char __user *data,
size_t size)
{
unsigned long flags;
* However, we have already verified its memory
* addresses by the time we get here.
*/
-static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_bootblock *bb)
+static int sscape_upload_bootblock(struct soundscape *sscape, struct sscape_bootblock __user *bb)
{
unsigned long flags;
int data = 0;
* SPACE, and save ourselves from copying it at all.
*/
static int sscape_upload_microcode(struct soundscape *sscape,
- const struct sscape_microcode *mc)
+ const struct sscape_microcode __user *mc)
{
unsigned long flags;
- char *code;
+ char __user *code;
int err, ret;
/*
switch (cmd) {
case SND_SSCAPE_LOAD_BOOTB:
{
- register struct sscape_bootblock *bb = (struct sscape_bootblock *) arg;
+ register struct sscape_bootblock __user *bb = (struct sscape_bootblock __user *) arg;
/*
* We are going to have to copy this data into a special
case SND_SSCAPE_LOAD_MCODE:
{
- register const struct sscape_microcode *mc = (const struct sscape_microcode *) arg;
+ register const struct sscape_microcode __user *mc = (const struct sscape_microcode __user *) arg;
err = sscape_upload_microcode(sscape, mc);
}
acard = card->private_data;
dev = &acard->wavefront;
- if (copy_from_user (&r, (unsigned char *) arg, sizeof (wavefront_fx_info)))
+ if (copy_from_user (&r, (void __user *)arg, sizeof (wavefront_fx_info)))
return -EFAULT;
switch (r.request) {
return -EIO;
}
if (copy_from_user (page_data,
- (unsigned char *) r.data[3],
+ (unsigned char __user *) r.data[3],
r.data[2]))
return -EFAULT;
pd = page_data;
static int
wavefront_send_sample (snd_wavefront_t *dev,
wavefront_patch_info *header,
- u16 *dataptr,
+ u16 __user *dataptr,
int data_is_unsigned)
{
u16 sample_short;
u32 length;
- u16 *data_end = 0;
+ u16 __user *data_end = 0;
unsigned int i;
const unsigned int max_blksize = 4096/2;
unsigned int written;
#endif
static int
-wavefront_load_patch (snd_wavefront_t *dev, const char *addr)
+wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr)
{
wavefront_patch_info header;
switch (header.subkey) {
case WF_ST_SAMPLE: /* sample or sample_header, based on patch->size */
- if (copy_from_user ((unsigned char *) &header.hdr.s,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user (&header.hdr.s, header.hdrptr,
sizeof (wavefront_sample)))
return -EFAULT;
case WF_ST_MULTISAMPLE:
- if (copy_from_user ((unsigned char *) &header.hdr.s,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user (&header.hdr.s, header.hdrptr,
sizeof (wavefront_multisample)))
return -EFAULT;
case WF_ST_ALIAS:
- if (copy_from_user ((unsigned char *) &header.hdr.a,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user (&header.hdr.a, header.hdrptr,
sizeof (wavefront_alias)))
return -EFAULT;
return wavefront_send_alias (dev, &header);
case WF_ST_DRUM:
- if (copy_from_user ((unsigned char *) &header.hdr.d,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user (&header.hdr.d, header.hdrptr,
sizeof (wavefront_drum)))
return -EFAULT;
return wavefront_send_drum (dev, &header);
case WF_ST_PATCH:
- if (copy_from_user ((unsigned char *) &header.hdr.p,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user (&header.hdr.p, header.hdrptr,
sizeof (wavefront_patch)))
return -EFAULT;
return wavefront_send_patch (dev, &header);
case WF_ST_PROGRAM:
- if (copy_from_user ((unsigned char *) &header.hdr.pr,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user (&header.hdr.pr, header.hdrptr,
sizeof (wavefront_program)))
return -EFAULT;
snd_wavefront_t *dev;
snd_wavefront_card_t *acard;
wavefront_control wc;
+ void __user *argp = (void __user *)arg;
card = (snd_card_t *) hw->card;
switch (cmd) {
case WFCTL_LOAD_SPP:
- if (wavefront_load_patch (dev, (char *) arg) != 0) {
+ if (wavefront_load_patch (dev, argp) != 0) {
return -EIO;
}
break;
case WFCTL_WFCMD:
- if (copy_from_user (&wc, (void *) arg, sizeof (wc)))
+ if (copy_from_user (&wc, argp, sizeof (wc)))
return -EFAULT;
if (wavefront_synth_control (acard, &wc) < 0) {
return -EIO;
}
- if (copy_to_user ((void *) arg, &wc, sizeof (wc)))
+ if (copy_to_user (argp, &wc, sizeof (wc)))
return -EFAULT;
break;
/************************* /dev/dsp interfaces ************************* */
-static ssize_t ad1889_read(struct file *file, char *buffer, size_t count,
+static ssize_t ad1889_read(struct file *file, char __user *buffer, size_t count,
loff_t *ppos)
{
return 0;
}
-static ssize_t ad1889_write(struct file *file, const char *buffer, size_t count,
+static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t count,
loff_t *ppos)
{
ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
struct dmabuf *dmabuf;
audio_buf_info abinfo;
+ int __user *p = (int __user *)arg;
switch (cmd)
{
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_RESET:
break;
case SNDCTL_DSP_SPEED:
/* set sampling rate */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val > 5400 && val < 48000)
{
return 0;
case SNDCTL_DSP_STEREO: /* undocumented? */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
val = AD1889_READW(ad1889_dev, AD_DSWSMC);
return 0;
case SNDCTL_DSP_GETBLKSIZE:
- return put_user(DMA_SIZE, (int *)arg);
+ return put_user(DMA_SIZE, p);
case SNDCTL_DSP_GETFMTS:
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ)
if (file->f_mode & FMODE_WRITE)
ad1889_set_wav_fmt(dev, val);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_CHANNELS:
break;
case SNDCTL_DSP_SETFRAGMENT:
/* not supported; uses fixed fragment sizes */
- return put_user(DMA_SIZE, (int *)arg);
+ return put_user(DMA_SIZE, p);
case SNDCTL_DSP_GETOSPACE:
case SNDCTL_DSP_GETISPACE:
abinfo.fragstotal = 1;
abinfo.fragsize = DMA_SIZE;
abinfo.bytes = DMA_SIZE;
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(p, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SNDCTL_DSP_GETTRIGGER:
case SNDCTL_DSP_SETTRIGGER:
break;
case SOUND_PCM_READ_RATE:
- return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), (int *)arg);
+ return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), p);
case SOUND_PCM_READ_CHANNELS:
case SOUND_PCM_READ_BITS:
waiting to be copied to the user's buffer. It is filled by the dma
machine and drained by this loop. */
-static ssize_t ali_read(struct file *file, char *buffer,
+static ssize_t ali_read(struct file *file, char __user *buffer,
size_t count, loff_t * ppos)
{
struct ali_state *state = (struct ali_state *) file->private_data;
/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
the soundcard. it is drained by the dma machine and filled by this loop. */
static ssize_t ali_write(struct file *file,
- const char *buffer, size_t count, loff_t * ppos)
+ const char __user *buffer, size_t count, loff_t * ppos)
{
struct ali_state *state = (struct ali_state *) file->private_data;
struct ali_card *card = state ? state->card : 0;
unsigned int i_scr;
int val = 0, ret;
struct ac97_codec *codec = state->card->ac97_codec[0];
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+
#ifdef DEBUG
printk("ali_audio: ali_ioctl, arg=0x%x, cmd=",
- arg ? *(int *) arg : 0);
+ arg ? *p : 0);
#endif
switch (cmd) {
case OSS_GETVERSION:
#ifdef DEBUG
printk("OSS_GETVERSION\n");
#endif
- return put_user(SOUND_VERSION, (int *) arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_RESET:
#ifdef DEBUG
printk("SNDCTL_DSP_RESET\n");
#ifdef DEBUG
printk("SNDCTL_DSP_SPEED\n");
#endif
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_WRITE) {
spin_unlock_irqrestore(&state->card->lock, flags);
}
}
- return put_user(dmabuf->rate, (int *) arg);
+ return put_user(dmabuf->rate, p);
case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
#ifdef DEBUG
printk("SNDCTL_DSP_STEREO\n");
if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
stop_spdifout(state);
}
- return put_user(1, (int *) arg);
+ return put_user(1, p);
case SNDCTL_DSP_GETBLKSIZE:
if (file->f_mode & FMODE_WRITE) {
if (codec_independent_spdif_locked > 0) {
#ifdef DEBUG
printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
#endif
- return put_user(dmabuf->userfragsize, (int *) arg);
+ return put_user(dmabuf->userfragsize, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format */
#ifdef DEBUG
printk("SNDCTL_DSP_GETFMTS\n");
#endif
- return put_user(AFMT_S16_LE, (int *) arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_SETFMT: /* Select sample format */
#ifdef DEBUG
printk("SNDCTL_DSP_SETFMT\n");
#endif
- return put_user(AFMT_S16_LE, (int *) arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_CHANNELS: // add support 4,6 channel
#ifdef DEBUG
printk("SNDCTL_DSP_CHANNELS\n");
#endif
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (val > 0) {
if (dmabuf->enable & DAC_RUNNING) {
stop_adc(state);
}
} else {
- return put_user(state->card->channels, (int *) arg);
+ return put_user(state->card->channels, p);
}
i_scr = inl(state->card->iobase + ALI_SCR);
val = ret;
break;
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */
/* we update the swptr to the end of the last sg segment then return */
#ifdef DEBUG
case SNDCTL_DSP_SUBDIVIDE:
if (dmabuf->subdivision)
return -EINVAL;
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
dmabuf->ready = 0;
return 0;
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
dmabuf->ossfragsize = 1 << (val & 0xffff);
dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
abinfo.bytes, abinfo.fragsize, abinfo.fragments,
abinfo.fragstotal);
#endif
- return copy_to_user((void *) arg, &abinfo,
+ return copy_to_user(argp, &abinfo,
sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
cinfo.blocks, cinfo.ptr, dmabuf->count);
#endif
- return copy_to_user((void *) arg, &cinfo, sizeof(cinfo))? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
return -EINVAL;
abinfo.bytes, abinfo.fragsize, abinfo.fragments,
abinfo.fragstotal);
#endif
- return copy_to_user((void *) arg, &abinfo,
+ return copy_to_user(argp, &abinfo,
sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
cinfo.blocks, cinfo.ptr, dmabuf->count);
#endif
- return copy_to_user((void *) arg, &cinfo, sizeof(cinfo))? -EFAULT: 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT: 0;
case SNDCTL_DSP_NONBLOCK:
#ifdef DEBUG
printk("SNDCTL_DSP_NONBLOCK\n");
printk("SNDCTL_DSP_GETCAPS\n");
#endif
return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
- DSP_CAP_MMAP | DSP_CAP_BIND, (int *) arg);
+ DSP_CAP_MMAP | DSP_CAP_BIND, p);
case SNDCTL_DSP_GETTRIGGER:
val = 0;
#ifdef DEBUG
printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
#endif
- return put_user(dmabuf->trigger, (int *) arg);
+ return put_user(dmabuf->trigger, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
#if defined(DEBUG) || defined(DEBUG_MMAP)
printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
#ifdef DEBUG
printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
#endif
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SOUND_PCM_READ_RATE:
#ifdef DEBUG
printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate);
#endif
- return put_user(dmabuf->rate, (int *) arg);
+ return put_user(dmabuf->rate, p);
case SOUND_PCM_READ_CHANNELS:
#ifdef DEBUG
printk("SOUND_PCM_READ_CHANNELS\n");
#endif
- return put_user(2, (int *) arg);
+ return put_user(2, p);
case SOUND_PCM_READ_BITS:
#ifdef DEBUG
printk("SOUND_PCM_READ_BITS\n");
#endif
- return put_user(AFMT_S16_LE, (int *) arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_SETSPDIF: /* Set S/PDIF Control register */
#ifdef DEBUG
printk("SNDCTL_DSP_SETSPDIF\n");
#endif
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
/* Check to make sure the codec supports S/PDIF transmitter */
if ((state->card->ac97_features & 4)) {
else
printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
#endif
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETSPDIF: /* Get S/PDIF Control register */
#ifdef DEBUG
printk("SNDCTL_DSP_GETSPDIF\n");
#endif
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
/* Check to make sure the codec supports S/PDIF transmitter */
if (!(state->card->ac97_features & 4)) {
val = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
//end add support spdif out
//add support 4,6 channel
case SNDCTL_DSP_GETCHANNELMASK:
#ifdef DEBUG
printk("SNDCTL_DSP_GETCHANNELMASK\n");
#endif
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
/* Based on AC'97 DAC support, not ICH hardware */
val = DSP_BIND_FRONT;
val |= DSP_BIND_SURR;
if (state->card->ac97_features & 0x0140)
val |= DSP_BIND_CENTER_LFE;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_BIND_CHANNEL:
#ifdef DEBUG
printk("SNDCTL_DSP_BIND_CHANNEL\n");
#endif
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (val == DSP_BIND_QUERY) {
val = DSP_BIND_FRONT; /* Always report this as being enabled */
val &= ~DSP_BIND_CENTER_LFE;
}
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
case SNDCTL_DSP_SETSYNCRO:
/* read from user buffer */
if (readbuf_flags & AWE_SAMPLE_8BITS) {
unsigned char cc;
- get_user(cc, (unsigned __user char*)(readbuf_addr + readbuf_offs + pos));
+ get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
} else {
- get_user(c, (unsigned __user short*)(readbuf_addr + readbuf_offs + pos * 2));
+ get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
}
if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
c ^= 0x8000; /* unsigned -> signed */
{
struct btaudio *bta = file->private_data;
int ret,val=0,i=0;
+ void __user *argp = (void __user *)arg;
if (cmd == SOUND_MIXER_INFO) {
mixer_info info;
strlcpy(info.id,"bt878",sizeof(info.id));
strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
info.modify_counter = bta->mixcount;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
memset(&info,0,sizeof(info));
strlcpy(info.id,"bt878",sizeof(info.id)-1);
strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, (int __user *)argp);
/* read */
if (_SIOC_DIR(cmd) & _SIOC_WRITE)
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
switch (cmd) {
default:
return -EINVAL;
}
- if (put_user(ret, (int *)arg))
+ if (put_user(ret, (int __user *)argp))
return -EFAULT;
return 0;
}
return 0;
}
-static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
+static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
size_t swcount, loff_t *ppos)
{
struct btaudio *bta = file->private_data;
} else if (!bta->analog) {
/* stereo => mono (digital audio) */
__s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset);
- __s16 *dst = (__s16*)(buffer + ret);
+ __s16 __user *dst = (__s16 __user *)(buffer + ret);
__s16 avg;
int n = ndst>>1;
if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
for (; n; n--, dst++) {
avg = (__s16)le16_to_cpu(*src) / 2; src++;
avg += (__s16)le16_to_cpu(*src) / 2; src++;
- __put_user(cpu_to_le16(avg),(__u16*)(dst));
+ __put_user(cpu_to_le16(avg),dst);
}
} else if (8 == bta->bits) {
/* copy + byte downsampling (audio A/D) */
__u8 *src = bta->buf_cpu + bta->read_offset;
- __u8 *dst = buffer + ret;
+ __u8 __user *dst = buffer + ret;
int n = ndst;
if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
if (0 == ret)
break;
}
for (; n; n--, src += (1 << bta->sampleshift), dst++)
- __put_user(*src,(__u8*)(dst));
+ __put_user(*src, dst);
} else {
/* copy + word downsampling (audio A/D) */
__u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset);
- __u16 *dst = (__u16*)(buffer + ret);
+ __u16 __user *dst = (__u16 __user *)(buffer + ret);
int n = ndst>>1;
if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
if (0 == ret)
break;
}
for (; n; n--, src += (1 << bta->sampleshift), dst++)
- __put_user(*src,(__u16*)(dst));
+ __put_user(*src, dst);
}
ret += ndst;
return ret;
}
-static ssize_t btaudio_dsp_write(struct file *file, const char *buffer,
+static ssize_t btaudio_dsp_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
return -EINVAL;
{
struct btaudio *bta = file->private_data;
int s, i, ret, val = 0;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_GETCAPS:
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int*)arg))
+ if (get_user(val, p))
return -EFAULT;
if (bta->analog) {
for (s = 0; s < 16; s++)
/* fall through */
case SOUND_PCM_READ_RATE:
if (bta->analog) {
- return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, (int*)arg);
+ return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, p);
} else {
- return put_user(bta->rate, (int*)arg);
+ return put_user(bta->rate, p);
}
case SNDCTL_DSP_STEREO:
if (!bta->analog) {
- if (get_user(val, (int*)arg))
+ if (get_user(val, p))
return -EFAULT;
bta->channels = (val > 0) ? 2 : 1;
bta->sampleshift = (bta->channels == 2) ? 0 : 1;
"btaudio: stereo=0 channels=1\n");
}
}
- return put_user((bta->channels)-1, (int *)arg);
+ return put_user((bta->channels)-1, p);
case SNDCTL_DSP_CHANNELS:
if (!bta->analog) {
- if (get_user(val, (int*)arg))
+ if (get_user(val, p))
return -EFAULT;
bta->channels = (val > 1) ? 2 : 1;
bta->sampleshift = (bta->channels == 2) ? 0 : 1;
}
/* fall through */
case SOUND_PCM_READ_CHANNELS:
- return put_user(bta->channels, (int *)arg);
+ return put_user(bta->channels, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
if (bta->analog)
- return put_user(AFMT_S16_LE|AFMT_S8, (int*)arg);
+ return put_user(AFMT_S16_LE|AFMT_S8, p);
else
- return put_user(AFMT_S16_LE, (int*)arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int*)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
if (bta->analog)
if (debug)
printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits);
return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8,
- (int*)arg);
+ p);
break;
case SOUND_PCM_READ_BITS:
- return put_user(bta->bits, (int*)arg);
+ return put_user(bta->bits, p);
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
if (0 != (ret = make_risc(bta)))
return ret;
}
- return put_user(bta->block_bytes>>bta->sampleshift,(int*)arg);
+ return put_user(bta->block_bytes>>bta->sampleshift,p);
case SNDCTL_DSP_SYNC:
/* NOP */
"returns %d/%d/%d/%d\n",
info.fragsize, info.fragstotal,
info.bytes, info.fragments);
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
spin_unlock_irqrestore(&s->lock, flags);
}
-static int trans_ac3(struct cm_state *s, void *dest, const char *source, int size)
+static int trans_ac3(struct cm_state *s, void *dest, const char __user *source, int size)
{
int i = size / 2;
unsigned long data;
unsigned short data16;
unsigned long *dst = (unsigned long *) dest;
- unsigned short *src = (unsigned short *)source;
+ unsigned short __user *src = (unsigned short __user *)source;
int err;
do {
unsigned long flags;
int i, val, j;
unsigned char l, r, rl, rr;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
if (cmd == SOUND_MIXER_INFO) {
strlcpy(info.id, "cmpci", sizeof(info.id));
strlcpy(info.name, "C-Media PCI", sizeof(info.name));
info.modify_counter = s->mix.modcnt;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
memset(&info, 0, sizeof(info));
strlcpy(info.id, "cmpci", sizeof(info.id));
strlcpy(info.name, "C-Media cmpci", sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
if (_SIOC_DIR(cmd) == _SIOC_READ) {
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
val = mixer_recmask(s);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
val = mixer_outmask(s);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].type)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].rec)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].play)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_CAPS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
default:
i = _IOC_NR(cmd);
return -EINVAL;
if (!volidx[i])
return -EINVAL;
- return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
+ return put_user(s->mix.vol[volidx[i]-1], p);
}
}
if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
s->mix.modcnt++;
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
i = generic_hweight32(val);
for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
return 0;
case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
if (!(val & (1 << i)))
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = val & 0xff;
r = (val >> 8) & 0xff;
if (!volidx[i])
return -EINVAL;
s->mix.vol[volidx[i]-1] = val;
- return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
+ return put_user(s->mix.vol[volidx[i]-1], p);
}
}
/* --------------------------------------------------------------------- */
-static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t cm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct cm_state *s = (struct cm_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
}
if (s->status & DO_BIGENDIAN_R) {
int i, err;
- unsigned char *src, *dst;
+ unsigned char *src;
+ char __user *dst = buffer;
unsigned char data[2];
src = (unsigned char *) (s->dma_adc.rawbuf + swptr);
- dst = (unsigned char *) buffer;
// copy left/right sample at one time
for (i = 0; i < cnt / 2; i++) {
data[0] = src[1];
return ret;
}
-static ssize_t cm_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t cm_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct cm_state *s = (struct cm_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
} else if ((s->status & DO_DUAL_DAC) && (s->status & DO_BIGENDIAN_W)) {
int i, err;
- unsigned char *src, *dst0, *dst1;
+ const char __user *src = buffer;
+ unsigned char *dst0, *dst1;
unsigned char data[8];
- src = (unsigned char *) buffer;
dst0 = (unsigned char *) (s->dma_dac.rawbuf + swptr);
dst1 = (unsigned char *) (s->dma_adc.rawbuf + swptr);
// copy left/right sample at one time
swptr = (swptr + cnt) % s->dma_dac.dmasize;
} else if (s->status & DO_DUAL_DAC) {
int i, err;
- unsigned long *src, *dst0, *dst1;
+ unsigned long __user *src = (unsigned long __user *) buffer;
+ unsigned long *dst0, *dst1;
- src = (unsigned long *) buffer;
dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
// copy left/right sample at one time
swptr = (swptr + cnt) % s->dma_dac.dmasize;
} else if (s->status & DO_BIGENDIAN_W) {
int i, err;
- unsigned char *src, *dst;
+ const char __user *src = buffer;
+ unsigned char *dst;
unsigned char data[2];
- src = (unsigned char *) buffer;
dst = (unsigned char *) (s->dma_dac.rawbuf + swptr);
// swap hi/lo bytes for each sample
for (i = 0; i < cnt / 2; i++) {
count_info cinfo;
int val, mapped, ret;
unsigned char fmtm, fmtd;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, p);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
set_dac_rate(s, val);
}
}
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
fmtd = 0;
fmtm = ~0;
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
fmtd = 0;
if ((s->capability & CAN_MULTI_CH)
&& (file->f_mode & FMODE_WRITE)) {
val = set_dac_channels(s, val);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
}
}
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
- : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
+ : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
return put_user(AFMT_S16_BE|AFMT_S16_LE|AFMT_U8|
- ((s->capability & CAN_AC3) ? AFMT_AC3 : 0), (int *)arg);
+ ((s->capability & CAN_AC3) ? AFMT_AC3 : 0), p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
fmtd = 0;
}
set_fmt(s, fmtm, fmtd);
}
- if (s->status & DO_AC3) return put_user(AFMT_AC3, (int *)arg);
+ if (s->status & DO_AC3) return put_user(AFMT_AC3, p);
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
- : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, (int *)arg);
+ : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, p);
case SNDCTL_DSP_POST:
return 0;
(s->enable & ENDAC) &&
(s->enable & ENADC))
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
}
if (file->f_mode & FMODE_READ && s->enable & ENADC)
val |= PCM_ENABLE_INPUT;
if (file->f_mode & FMODE_WRITE && s->enable & ENDAC)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragstotal = s->dma_dac.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
cm_update_ptr(s);
val = s->dma_dac.count;
spin_unlock_irqrestore(&s->lock, flags);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
s->dma_adc.count &= s->dma_adc.fragsize-1;
}
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETBLKSIZE:
if (file->f_mode & FMODE_WRITE) {
if (s->status & DO_DUAL_DAC) {
if ((val = prog_dmabuf(s, 1)))
return val;
- return put_user(2 * s->dma_dac.fragsize, (int *)arg);
+ return put_user(2 * s->dma_dac.fragsize, p);
}
- return put_user(s->dma_dac.fragsize, (int *)arg);
+ return put_user(s->dma_dac.fragsize, p);
}
if ((val = prog_dmabuf(s, 1)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SOUND_PCM_READ_CHANNELS:
- return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, (int *)arg);
+ return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
- return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, (int *)arg);
+ return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, p);
case SOUND_PCM_READ_FILTER:
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SNDCTL_DSP_GETCHANNELMASK:
- return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, (int *)arg);
+ return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, p);
case SNDCTL_DSP_BIND_CHANNEL:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val == DSP_BIND_QUERY) {
val = DSP_BIND_FRONT;
}
}
}
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_SETSYNCRO:
return -EINVAL;
case SNDCTL_SPDIF_COPYRIGHT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdif_copyright(s, val);
return 0;
case SNDCTL_SPDIF_LOOP:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdif_loop(s, val);
return 0;
case SNDCTL_SPDIF_MONITOR:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdif_monitor(s, val);
return 0;
case SNDCTL_SPDIF_LEVEL:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdifout_level(s, val);
return 0;
case SNDCTL_SPDIF_INV:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdifin_inverse(s, val);
return 0;
case SNDCTL_SPDIF_SEL2:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdifin_channel2(s, val);
return 0;
case SNDCTL_SPDIF_VALID:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdifin_valid(s, val);
return 0;
case SNDCTL_SPDIFOUT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdifout(s, val ? s->ratedac : 0);
return 0;
case SNDCTL_SPDIFIN:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_spdifin(s, val ? s->rateadc : 0);
return 0;
MODULE_DESCRIPTION("CM8x38 Audio Driver");
MODULE_LICENSE("GPL");
-static void __devinit cm_remove(struct pci_dev *dev)
+static void __devexit cm_remove(struct pci_dev *dev)
{
struct cm_state *s = pci_get_drvdata(dev);
.name = "cmpci",
.id_table = id_table,
.probe = cm_probe,
- .remove = cm_remove
+ .remove = __devexit_p(cm_remove)
};
static int __init init_cmpci(void)
#define DMABUF_MINORDER 1 // ==> min buffer size = 8K.
-extern void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
{
struct page *map, *mapend;
SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
};
+ void __user *argp = (void __user *)arg;
// Index of mixtable1[] member is Device ID
// and must be <= SOUND_MIXER_NRDEVICES.
case SOUND_MIXER_CS_GETDBGMASK:
return put_user(cs_debugmask,
- (unsigned long *) arg);
+ (unsigned long __user *) argp);
case SOUND_MIXER_CS_GETDBGLEVEL:
return put_user(cs_debuglevel,
- (unsigned long *) arg);
+ (unsigned long __user *) argp);
case SOUND_MIXER_CS_SETDBGMASK:
- if (get_user(val, (unsigned long *) arg))
+ if (get_user(val, (unsigned long __user *) argp))
return -EFAULT;
cs_debugmask = val;
return 0;
case SOUND_MIXER_CS_SETDBGLEVEL:
- if (get_user(val, (unsigned long *) arg))
+ if (get_user(val, (unsigned long __user *) argp))
return -EFAULT;
cs_debuglevel = val;
return 0;
#ifndef NOT_CS4281_PM
case SOUND_MIXER_CS_APM:
- if (get_user(val, (unsigned long *) arg))
+ if (get_user(val, (unsigned long __user *) argp))
return -EFAULT;
if(val == CS_IOCTL_CMD_SUSPEND)
cs4281_suspend(s);
if (cmd == SOUND_MIXER_PRIVATE1) {
// enable/disable/query mixer preamp
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *) argp))
return -EFAULT;
if (val != -1) {
cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
}
cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
val = (temp1 & 0x40) ? 1 : 0;
- return put_user(val, (int *) arg);
+ return put_user(val, (int __user *) argp);
}
if (cmd == SOUND_MIXER_PRIVATE2) {
// enable/disable/query spatializer
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
if (val != -1) {
temp1 = (val & 0x3f) >> 2;
temp1 | 0x2000);
}
cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
- return put_user((temp1 << 2) | 3, (int *) arg);
+ return put_user((temp1 << 2) | 3, (int __user *)argp);
}
if (cmd == SOUND_MIXER_INFO) {
mixer_info info;
strlcpy(info.id, "CS4281", sizeof(info.id));
strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
info.modify_counter = s->mix.modcnt;
- if (copy_to_user((void *) arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
_old_mixer_info info;
strlcpy(info.id, "CS4281", sizeof(info.id));
strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
- if (copy_to_user((void *) arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *) arg);
+ return put_user(SOUND_VERSION, (int __user *) argp);
if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
if (_SIOC_DIR(cmd) == _SIOC_READ) {
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source
- cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT,
- &temp1);
- return put_user(mixer_src[temp1 & 7], (int *) arg);
+ cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1);
+ return put_user(mixer_src[temp1&7], (int __user *)argp);
case SOUND_MIXER_DEVMASK: // Arg contains a bit for each supported device
return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
SOUND_MASK_LINE1 | SOUND_MASK_MIC |
SOUND_MASK_VOLUME |
SOUND_MASK_RECLEV |
- SOUND_MASK_SPEAKER, (int *) arg);
+ SOUND_MASK_SPEAKER, (int __user *)argp);
case SOUND_MIXER_RECMASK: // Arg contains a bit for each supported recording source
return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC |
SOUND_MASK_CD | SOUND_MASK_VOLUME |
- SOUND_MASK_LINE1, (int *) arg);
+ SOUND_MASK_LINE1, (int __user *) argp);
case SOUND_MIXER_STEREODEVS: // Mixer channels supporting stereo
return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
SOUND_MASK_CD | SOUND_MASK_LINE |
SOUND_MASK_LINE1 | SOUND_MASK_MIC |
SOUND_MASK_VOLUME |
- SOUND_MASK_RECLEV, (int *) arg);
+ SOUND_MASK_RECLEV, (int __user *)argp);
case SOUND_MIXER_CAPS:
- return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
+ return put_user(SOUND_CAP_EXCL_INPUT, (int __user *)argp);
default:
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES
|| !(vidx = mixtable1[i]))
return -EINVAL;
- return put_user(s->mix.vol[vidx - 1], (int *) arg);
+ return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
}
}
// If ioctl doesn't have both the SIOC_READ and
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
i = hweight32(val); // i = # bits on in val.
if (i != 1) // One & only 1 bit must be on.
return 0;
case SOUND_MIXER_VOLUME:
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[8] = val;
#endif
- return put_user(s->mix.vol[8], (int *) arg);
+ return put_user(s->mix.vol[8], (int __user *)argp);
case SOUND_MIXER_SPEAKER:
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[6] = val;
#endif
- return put_user(s->mix.vol[6], (int *) arg);
+ return put_user(s->mix.vol[6], (int __user *)argp);
case SOUND_MIXER_RECLEV:
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[7] = val;
#endif
- return put_user(s->mix.vol[7], (int *) arg);
+ return put_user(s->mix.vol[7], (int __user *)argp);
case SOUND_MIXER_MIC:
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[5] = val;
#endif
- return put_user(s->mix.vol[5], (int *) arg);
+ return put_user(s->mix.vol[5], (int __user *)argp);
case SOUND_MIXER_SYNTH:
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
l = val & 0xff;
if (l > 100)
l = 100;
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
r = (val >> 8) & 0xff;
if (r > 100)
#else
s->mix.vol[4] = val;
#endif
- return put_user(s->mix.vol[4], (int *) arg);
+ return put_user(s->mix.vol[4], (int __user *)argp);
default:
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
return -EINVAL;
- if (get_user(val, (int *) arg))
+ if (get_user(val, (int __user *)argp))
return -EFAULT;
l = val & 0xff;
if (l > 100)
"write ac97 mixreg[%d]=0x%x mix.vol[]=0x%x\n",
vidx-1,temp1,s->mix.vol[vidx-1]));
#endif
- return put_user(s->mix.vol[vidx - 1], (int *) arg);
+ return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
}
}
// issues with 8 bit capture, so the driver always captures data in 16 bit
// and then if the user requested 8 bit, converts from 16 to 8 bit.
//
-static unsigned cs_copy_to_user(struct cs4281_state *s, void *dest,
+static unsigned cs_copy_to_user(struct cs4281_state *s, void __user *dest,
unsigned *hwsrc, unsigned cnt,
unsigned *copied)
{
// ---------------------------------------------------------------------
-static ssize_t cs4281_read(struct file *file, char *buffer, size_t count,
+static ssize_t cs4281_read(struct file *file, char __user *buffer, size_t count,
loff_t * ppos)
{
struct cs4281_state *s =
}
-static ssize_t cs4281_write(struct file *file, const char *buffer,
+static ssize_t cs4281_write(struct file *file, const char __user *buffer,
size_t count, loff_t * ppos)
{
struct cs4281_state *s =
audio_buf_info abinfo;
count_info cinfo;
int val, mapped, ret;
+ int __user *p = (int __user *)arg;
CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): file=%p cmd=0x%.8x\n", file, cmd));
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n",
SOUND_VERSION));
- return put_user(SOUND_VERSION, (int *) arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
case SNDCTL_DSP_GETCAPS:
return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
DSP_CAP_TRIGGER | DSP_CAP_MMAP,
- (int *) arg);
+ p);
case SNDCTL_DSP_RESET:
CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n", val));
else if (file->f_mode & FMODE_READ)
val = s->prop_adc.rate;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n", val));
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n",
else if (file->f_mode & FMODE_READ)
val = s->prop_adc.channels;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETFMTS: // Returns a mask
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
AFMT_U8));
return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
- AFMT_U8, (int *) arg);
+ AFMT_U8, p);
case SNDCTL_DSP_SETFMT:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n",
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
"cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n",
val));
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_POST:
CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
val |= PCM_ENABLE_INPUT;
if (file->f_mode & s->ena & FMODE_WRITE)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
abinfo.fragments));
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *) arg, &abinfo,
+ return copy_to_user(p, &abinfo,
sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
abinfo.bytes >> s->dma_adc.fragshift;
}
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *) arg, &abinfo,
+ return copy_to_user(p, &abinfo,
sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
cs4281_update_ptr(s,CS_FALSE);
val = s->dma_dac.count;
spin_unlock_irqrestore(&s->lock, flags);
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize - 1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(p, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (s->dma_dac.mapped)
s->dma_dac.count &= s->dma_dac.fragsize - 1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(p, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf_dac(s)))
return val;
- return put_user(s->dma_dac.fragsize, (int *) arg);
+ return put_user(s->dma_dac.fragsize, p);
}
if ((val = prog_dmabuf_adc(s)))
return val;
if (s->conversion)
- return put_user(s->dma_adc.fragsize / 2,
- (int *) arg);
+ return put_user(s->dma_adc.fragsize / 2, p);
else
- return put_user(s->dma_adc.fragsize, (int *) arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
return 0; // Say OK, but do nothing.
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
|| (file->f_mode & FMODE_WRITE
&& s->dma_dac.subdivision)) return -EINVAL;
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
case SOUND_PCM_READ_RATE:
if (file->f_mode & FMODE_READ)
- return put_user(s->prop_adc.rate, (int *) arg);
+ return put_user(s->prop_adc.rate, p);
else if (file->f_mode & FMODE_WRITE)
- return put_user(s->prop_dac.rate, (int *) arg);
+ return put_user(s->prop_dac.rate, p);
case SOUND_PCM_READ_CHANNELS:
if (file->f_mode & FMODE_READ)
- return put_user(s->prop_adc.channels, (int *) arg);
+ return put_user(s->prop_adc.channels, p);
else if (file->f_mode & FMODE_WRITE)
- return put_user(s->prop_dac.channels, (int *) arg);
+ return put_user(s->prop_dac.channels, p);
case SOUND_PCM_READ_BITS:
if (file->f_mode & FMODE_READ)
put_user(
(s->prop_adc.
fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
- (int *) arg);
+ p);
else if (file->f_mode & FMODE_WRITE)
return
put_user(
(s->prop_dac.
fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
- (int *) arg);
+ p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
// ---------------------------------------------------------------------
-static ssize_t cs4281_midi_read(struct file *file, char *buffer,
+static ssize_t cs4281_midi_read(struct file *file, char __user *buffer,
size_t count, loff_t * ppos)
{
struct cs4281_state *s =
}
-static ssize_t cs4281_midi_write(struct file *file, const char *buffer,
+static ssize_t cs4281_midi_write(struct file *file, const char __user *buffer,
size_t count, loff_t * ppos)
{
struct cs4281_state *s =
/**********************************************************************/
-static ssize_t cs_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct cs_card *card = (struct cs_card *)file->private_data;
ssize_t ret;
}
-static ssize_t cs_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct cs_card *card = (struct cs_card *)file->private_data;
ssize_t ret;
*/
static unsigned cs_copy_to_user(
struct cs_state *s,
- void *dest,
+ void __user *dest,
void *hwsrc,
unsigned cnt,
unsigned *copied)
void *src = hwsrc; /* default to the standard destination buffer addr */
CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO
- "cs_copy_to_user()+ fmt=0x%x cnt=%d dest=0x%.8x\n",
- dmabuf->fmt,(unsigned)cnt,(unsigned)dest) );
+ "cs_copy_to_user()+ fmt=0x%x cnt=%d dest=%p\n",
+ dmabuf->fmt,(unsigned)cnt,dest) );
if(cnt > dmabuf->dmasize)
{
if (copy_to_user(dest, src, cnt))
{
CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
- "cs46xx: cs_copy_to_user()- fault dest=0x%x src=0x%x cnt=%d\n",
- (unsigned)dest,(unsigned)src,cnt) );
+ "cs46xx: cs_copy_to_user()- fault dest=%p src=%p cnt=%d\n",
+ dest,src,cnt) );
*copied = 0;
return -EFAULT;
}
/* in this loop, dmabuf.count signifies the amount of data that is waiting to be copied to
the user's buffer. it is filled by the dma machine and drained by this loop. */
-static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct cs_card *card = (struct cs_card *) file->private_data;
struct cs_state *state;
CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
"_read() copy_to cnt=%d count=%d ", cnt,count) );
CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
- " .dmasize=%d .count=%d buffer=0x%.8x ret=%d\n",
- dmabuf->dmasize,dmabuf->count,(unsigned)buffer,ret) );
+ " .dmasize=%d .count=%d buffer=%p ret=%d\n",
+ dmabuf->dmasize,dmabuf->count,buffer,ret) );
if (cs_copy_to_user(state, buffer,
(void *)((unsigned)dmabuf->rawbuf + swptr), cnt, &copied))
/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
the soundcard. it is drained by the dma machine and filled by this loop. */
-static ssize_t cs_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t cs_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct cs_card *card = (struct cs_card *) file->private_data;
struct cs_state *state;
audio_buf_info abinfo;
count_info cinfo;
int val, valsave, mapped, ret;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
state = (struct cs_state *)card->states[0];
if(state)
switch (cmd)
{
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_RESET:
/* FIXME: spin_lock ? */
return 0;
case SNDCTL_DSP_SPEED: /* set sample rate */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
file->f_mode & FMODE_WRITE ? "DAC" : "",
file->f_mode & FMODE_READ ? "ADC" : "",
dmabuf->rate ) );
- return put_user(dmabuf->rate, (int *)arg);
+ return put_user(dmabuf->rate, p);
}
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_WRITE) {
state = (struct cs_state *)card->states[1];
dmabuf = &state->dmabuf;
if ((val = prog_dmabuf(state)))
return val;
- return put_user(dmabuf->fragsize, (int *)arg);
+ return put_user(dmabuf->fragsize, p);
}
}
if (file->f_mode & FMODE_READ) {
if ((val = prog_dmabuf(state)))
return val;
return put_user(dmabuf->fragsize/dmabuf->divisor,
- (int *)arg);
+ p);
}
}
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
- return put_user(AFMT_S16_LE | AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE | AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Select sample format */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(
"cs46xx: cs_ioctl() DSP_SETFMT %s %s %s %s\n",
if(dmabuf)
{
if(dmabuf->fmt & CS_FMT_16BIT)
- return put_user(AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_S16_LE, p);
else
- return put_user(AFMT_U8, (int *)arg);
+ return put_user(AFMT_U8, p);
}
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
if (file->f_mode & FMODE_WRITE) {
}
}
return put_user((dmabuf->fmt & CS_FMT_STEREO) ? 2 : 1,
- (int *)arg);
+ p);
case SNDCTL_DSP_POST:
/*
dmabuf = &state->dmabuf;
if (dmabuf->subdivision)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2)
return -EINVAL;
dmabuf = &state->dmabuf;
if (dmabuf->subdivision)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2)
return -EINVAL;
return 0;
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_WRITE) {
abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->card->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
}
return -ENODEV;
abinfo.fragstotal = dmabuf->numfrag;
abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->card->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
}
return -ENODEV;
case SNDCTL_DSP_GETCAPS:
return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
- (int *)arg);
+ p);
case SNDCTL_DSP_GETTRIGGER:
val = 0;
}
}
CS_DBGOUT(CS_IOCTL, 2, printk("cs46xx: DSP_GETTRIGGER()- val=0x%x\n",val) );
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
state = (struct cs_state *)card->states[0];
cinfo.blocks = dmabuf->count/dmabuf->divisor >> dmabuf->fragshift;
cinfo.ptr = dmabuf->hwptr/dmabuf->divisor;
spin_unlock_irqrestore(&state->card->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
}
"cs46xx: GETOPTR bytes=%d blocks=%d ptr=%d\n",
cinfo.bytes,cinfo.blocks,cinfo.ptr) );
spin_unlock_irqrestore(&state->card->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
}
}
else
val = 0;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_PCM_READ_RATE:
if(file->f_mode & FMODE_READ)
if(state)
{
dmabuf = &state->dmabuf;
- return put_user(dmabuf->rate, (int *)arg);
+ return put_user(dmabuf->rate, p);
}
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SOUND_PCM_READ_CHANNELS:
{
dmabuf = &state->dmabuf;
return put_user((dmabuf->fmt & CS_FMT_STEREO) ? 2 : 1,
- (int *)arg);
+ p);
}
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SOUND_PCM_READ_BITS:
if(file->f_mode & FMODE_READ)
{
dmabuf = &state->dmabuf;
return put_user((dmabuf->fmt & CS_FMT_16BIT) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
+ AFMT_S16_LE : AFMT_U8, p);
}
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
struct cs_card *card=NULL;
struct list_head *entry;
+ unsigned long __user *p = (long __user *)arg;
#if CSDEBUG_INTERFACE
int val;
{
case SOUND_MIXER_CS_GETDBGMASK:
- return put_user(cs_debugmask, (unsigned long *)arg);
+ return put_user(cs_debugmask, p);
case SOUND_MIXER_CS_GETDBGLEVEL:
- return put_user(cs_debuglevel, (unsigned long *)arg);
+ return put_user(cs_debuglevel, p);
case SOUND_MIXER_CS_SETDBGMASK:
- if (get_user(val, (unsigned long *)arg))
+ if (get_user(val, p))
return -EFAULT;
cs_debugmask = val;
return 0;
case SOUND_MIXER_CS_SETDBGLEVEL:
- if (get_user(val, (unsigned long *)arg))
+ if (get_user(val, p))
return -EFAULT;
cs_debuglevel = val;
return 0;
case SOUND_MIXER_CS_APM:
- if (get_user(val, (unsigned long *) arg))
+ if (get_user(val, p))
return -EFAULT;
if(val == CS_IOCTL_CMD_SUSPEND)
{
#include <linux/spinlock.h>
#include <linux/interrupt.h>
-#include <asm/pgalloc.h>
#include <asm/uaccess.h>
#include <asm/atariints.h>
#include <asm/atari_stram.h>
static void calculate_ifrag(struct wiinst *);
/* Audio file operations */
-static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
+static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
{
struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
struct wiinst *wiinst = wave_dev->wiinst;
|| (bytestocopy >= count)) {
bytestocopy = min_t(u32, bytestocopy, count);
- emu10k1_wavein_xferdata(wiinst, (u8 *) buffer, &bytestocopy);
+ emu10k1_wavein_xferdata(wiinst, (u8 __user *)buffer, &bytestocopy);
count -= bytestocopy;
buffer += bytestocopy;
return ret;
}
-static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+static ssize_t emu10k1_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
{
struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
struct woinst *woinst = wave_dev->woinst;
bytestocopy = min_t(u32, bytestocopy, count);
- emu10k1_waveout_xferdata(woinst, (u8 *) buffer, &bytestocopy);
+ emu10k1_waveout_xferdata(woinst, (u8 __user *) buffer, &bytestocopy);
count -= bytestocopy;
buffer += bytestocopy * woinst->num_voices;
int val = 0;
u32 bytestocopy;
unsigned long flags;
+ int __user *p = (int __user *)arg;
DPF(4, "emu10k1_audio_ioctl()\n");
switch (cmd) {
case OSS_GETVERSION:
DPF(2, "OSS_GETVERSION:\n");
- return put_user(SOUND_VERSION, (int *) arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_RESET:
DPF(2, "SNDCTL_DSP_RESET:\n");
DPF(2, "SNDCTL_DSP_GETCAPS:\n");
return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
DSP_CAP_TRIGGER | DSP_CAP_MMAP |
- DSP_CAP_COPROC| DSP_CAP_MULTI, (int *) arg);
+ DSP_CAP_COPROC| DSP_CAP_MULTI, p);
case SNDCTL_DSP_SPEED:
DPF(2, "SNDCTL_DSP_SPEED:\n");
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
DPD(2, "val is %d\n", val);
DPD(2, "set playback sampling rate -> %d\n", val);
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
} else {
if (file->f_mode & FMODE_READ)
val = wiinst->format.samplingrate;
else if (file->f_mode & FMODE_WRITE)
val = woinst->format.samplingrate;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
}
break;
case SNDCTL_DSP_STEREO:
DPF(2, "SNDCTL_DSP_STEREO:\n");
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
DPD(2, " val is %d\n", val);
DPD(2, "set playback stereo -> %d\n", val);
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
break;
case SNDCTL_DSP_CHANNELS:
DPF(2, "SNDCTL_DSP_CHANNELS:\n");
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
DPD(2, " val is %d\n", val);
DPD(2, "set playback number of channels -> %d\n", val);
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
} else {
if (file->f_mode & FMODE_READ)
val = wiinst->format.channels;
else if (file->f_mode & FMODE_WRITE)
val = woinst->format.channels;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
}
break;
wave_dev->card->pt.enable_gpr_name) >= 0)
val |= AFMT_AC3;
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */
DPF(2, "SNDCTL_DSP_SETFMT:\n");
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
DPD(2, " val is %d\n", val);
DPD(2, "set playback format -> %d\n", val);
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
} else {
if (file->f_mode & FMODE_READ)
val = wiinst->format.id;
else if (file->f_mode & FMODE_WRITE)
val = woinst->format.id;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
}
break;
else if (file->f_mode & FMODE_WRITE)
val = woinst->format.bitsperchannel;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SOUND_PCM_READ_RATE:
else if (file->f_mode & FMODE_WRITE)
val = woinst->format.samplingrate;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SOUND_PCM_READ_CHANNELS:
else if (file->f_mode & FMODE_WRITE)
val = woinst->format.channels;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SOUND_PCM_WRITE_FILTER:
DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
val |= PCM_ENABLE_INPUT;
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_WRITE) {
info.fragstotal = woinst->buffer.numfrags * woinst->num_voices;
info.fragments = info.bytes / info.fragsize;
- if (copy_to_user((int *) arg, &info, sizeof(info)))
+ if (copy_to_user(p, &info, sizeof(info)))
return -EFAULT;
}
break;
info.fragments = info.bytes / wiinst->buffer.fragment_size;
info.fragsize = wiinst->buffer.fragment_size;
- if (copy_to_user((int *) arg, &info, sizeof(info)))
+ if (copy_to_user(p, &info, sizeof(info)))
return -EFAULT;
}
break;
val *= woinst->num_voices;
spin_unlock_irqrestore(&woinst->lock, flags);
- return put_user(val, (int *) arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETIPTR:
{
spin_unlock_irqrestore(&wiinst->lock, flags);
- if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(p, &cinfo, sizeof(cinfo)))
return -EFAULT;
}
break;
spin_unlock_irqrestore(&woinst->lock, flags);
- if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(p, &cinfo, sizeof(cinfo)))
return -EFAULT;
}
break;
spin_unlock_irqrestore(&wiinst->lock, flags);
}
- return put_user(val, (int *) arg);
+ return put_user(val, p);
break;
case SNDCTL_DSP_SETFRAGMENT:
DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
return -EFAULT;
DPD(2, "val is %#x\n", val);
if (!buf)
return -ENOMEM;
- if (copy_from_user(buf, (copr_buffer *) arg, sizeof(copr_buffer))) {
+ if (copy_from_user(buf, p, sizeof(copr_buffer))) {
kfree (buf);
return -EFAULT;
}
for (i = 0; i < buf->len; i++)
((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, buf->flags);
- if (copy_to_user((copr_buffer *) arg, buf, sizeof(copr_buffer))) {
+ if (copy_to_user(p, buf, sizeof(copr_buffer))) {
kfree(buf);
return -EFAULT;
}
}
}
-static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
+static void copy_block(u8 __user *dst, u8 * src, u32 str, u32 len, u8 cov)
{
if (cov == 1)
__copy_to_user(dst, src + str, len);
}
}
-void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 * data, u32 * size)
+void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 __user *data, u32 * size)
{
struct wavein_buffer *buffer = &wiinst->buffer;
u32 sizetocopy, sizetocopy_now, start;
void emu10k1_wavein_start(struct emu10k1_wavedevice *);
void emu10k1_wavein_stop(struct emu10k1_wavedevice *);
void emu10k1_wavein_getxfersize(struct wiinst *, u32 *);
-void emu10k1_wavein_xferdata(struct wiinst *, u8 *, u32 *);
+void emu10k1_wavein_xferdata(struct wiinst *, u8 __user *, u32 *);
int emu10k1_wavein_setformat(struct emu10k1_wavedevice *, struct wave_format *);
void emu10k1_wavein_update(struct emu10k1_card *, struct wiinst *);
* Notice that the voice buffer is actually a set of disjointed memory pages.
*
*/
-static void copy_block(void **dst, u32 str, u8 *src, u32 len)
+static void copy_block(void **dst, u32 str, u8 __user *src, u32 len)
{
unsigned int pg;
unsigned int pgoff;
* Notice that the voice buffer is actually a set of disjointed memory pages.
*
*/
-static void copy_ilv_block(struct woinst *woinst, u32 str, u8 *src, u32 len)
+static void copy_ilv_block(struct woinst *woinst, u32 str, u8 __user *src, u32 len)
{
unsigned int pg;
unsigned int pgoff;
* previously added to the buffer are overwritten.
*
*/
-void emu10k1_waveout_xferdata(struct woinst *woinst, u8 *data, u32 *size)
+void emu10k1_waveout_xferdata(struct woinst *woinst, u8 __user *data, u32 *size)
{
struct waveout_buffer *buffer = &woinst->buffer;
struct voice_mem *mem = &woinst->voice[0].mem;
void emu10k1_waveout_start(struct emu10k1_wavedevice *);
void emu10k1_waveout_stop(struct emu10k1_wavedevice *);
void emu10k1_waveout_getxfersize(struct woinst*, u32 *);
-void emu10k1_waveout_xferdata(struct woinst*, u8*, u32 *);
+void emu10k1_waveout_xferdata(struct woinst*, u8 __user *, u32 *);
void emu10k1_waveout_fillsilence(struct woinst*);
int emu10k1_waveout_setformat(struct emu10k1_wavedevice*, struct wave_format*);
void emu10k1_waveout_update(struct woinst*);
return 0;
}
-static ssize_t emu10k1_midi_read(struct file *file, char *buffer, size_t count, loff_t * pos)
+static ssize_t emu10k1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t * pos)
{
struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
ssize_t ret = 0;
return ret;
}
-static ssize_t emu10k1_midi_write(struct file *file, const char *buffer, size_t count, loff_t * pos)
+static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t * pos)
{
struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
struct midi_hdr *midihdr;
u32 size, page;
int addr, size_reg, i, ret;
unsigned int id, ch;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
if (ctl == NULL)
return -ENOMEM;
- if (copy_from_user(ctl, (void *) arg, sizeof(struct mixer_private_ioctl))) {
+ if (copy_from_user(ctl, argp, sizeof(struct mixer_private_ioctl))) {
kfree(ctl);
return -EFAULT;
}
case CMD_READFN0:
ctl->val[2] = emu10k1_readfn0(card, ctl->val[0]);
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
ctl->val[2] = sblive_readptr(card, ctl->val[0], ctl->val[1]);
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
case CMD_GETRECSRC:
ctl->val[0] = card->wavein.recsrc;
ctl->val[1] = card->wavein.fxwc;
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
ctl->val[4] = card->waveout.send_routing[2];
ctl->val[5] = card->waveout.send_dcba[2];
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
case CMD_GETPATCH:
if (ctl->val[0] == 0) {
- if (copy_to_user((void *) arg, &card->mgr.rpatch, sizeof(struct dsp_rpatch)))
+ if (copy_to_user(argp, &card->mgr.rpatch, sizeof(struct dsp_rpatch)))
ret = -EFAULT;
} else {
if ((ctl->val[0] - 1) / PATCHES_PER_PAGE >= card->mgr.current_pages) {
break;
}
- if (copy_to_user((void *) arg, PATCH(&card->mgr, ctl->val[0] - 1), sizeof(struct dsp_patch)))
+ if (copy_to_user(argp, PATCH(&card->mgr, ctl->val[0] - 1), sizeof(struct dsp_patch)))
ret = -EFAULT;
}
break;
}
- if (copy_to_user((void *) arg, &card->mgr.gpr[id], sizeof(struct dsp_gpr)))
+ if (copy_to_user(argp, &card->mgr.gpr[id], sizeof(struct dsp_gpr)))
ret = -EFAULT;
break;
addr = emu10k1_find_control_gpr(&card->mgr, (char *) ctl->val, &((char *) ctl->val)[PATCH_NAME_SIZE]);
ctl->val[0] = sblive_readptr(card, addr, 0);
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
ctl->val[2] = card->mgr.ctrl_gpr[id][ch];
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
if (card->is_audigy)
ctl->val[4]=emu10k1_readfn0(card, 0x18);
- if (copy_to_user((void *) arg, ctl, sizeof(struct mixer_private_ioctl)))
+ if (copy_to_user(argp, ctl, sizeof(struct mixer_private_ioctl)))
ret = -EFAULT;
break;
case SOUND_MIXER_PRIVATE4:
- if (copy_from_user(&size, (void *) arg, sizeof(size)))
+ if (copy_from_user(&size, argp, sizeof(size)))
return -EFAULT;
DPD(2, "External tram size %#x\n", size);
card->ac97->modcnt++;
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)arg))
return -EFAULT;
/* cleanse input a little */
info.modify_counter = card->ac97->modcnt;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
return 0;
}
-ssize_t emu10k1_pt_write(struct file *file, const char *buffer, size_t count)
+ssize_t emu10k1_pt_write(struct file *file, const char __user *buffer, size_t count)
{
struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
struct emu10k1_card *card = wave_dev->card;
blocks = (count-bytes_copied)/PT_BLOCKSIZE;
blocks_copied = 0;
while (blocks > 0) {
- u16 *bufptr = (u16 *) buffer + (bytes_copied/2);
+ u16 __user *bufptr = (u16 __user *) buffer + (bytes_copied/2);
copy_from_user(pt->buf, bufptr, PT_BLOCKSIZE);
- bufptr = (u16 *) pt->buf;
- r = pt_putblock(wave_dev, bufptr, nonblock);
+ r = pt_putblock(wave_dev, (u16 *)pt->buf, nonblock);
if (r) {
if (bytes_copied)
return bytes_copied;
#define USE_PT_METHOD2 (card->is_audigy)
#define USE_PT_METHOD1 !USE_PT_METHOD2
-ssize_t emu10k1_pt_write(struct file *file, const char *buf, size_t count);
+ssize_t emu10k1_pt_write(struct file *file, const char __user *buf, size_t count);
int emu10k1_pt_setup(struct emu10k1_wavedevice *wave_dev);
void emu10k1_pt_stop(struct emu10k1_card *card);
unsigned long flags;
int i, val;
unsigned char l, r, rl, rr;
+ int __user *p = (int __user *)arg;
VALIDATE_STATE(s);
if (cmd == SOUND_MIXER_PRIVATE1) {
/* enable/disable/query mixer preamp */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != -1) {
s->mix.micpreamp = !!val;
wrcodec(s, 0x19, s->mix.micpreamp);
}
- return put_user(s->mix.micpreamp, (int *)arg);
+ return put_user(s->mix.micpreamp, p);
}
if (cmd == SOUND_MIXER_PRIVATE2) {
/* enable/disable/query use of linein as second lineout */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != -1) {
spin_lock_irqsave(&s->lock, flags);
outl(s->ctrl, s->io+ES1370_REG_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, (int *)arg);
+ return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, p);
}
if (cmd == SOUND_MIXER_PRIVATE3) {
/* enable/disable/query microphone impedance setting */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != -1) {
spin_lock_irqsave(&s->lock, flags);
outl(s->ctrl, s->io+ES1370_REG_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, (int *)arg);
+ return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, p);
}
if (cmd == SOUND_MIXER_INFO) {
mixer_info info;
strncpy(info.id, "ES1370", sizeof(info.id));
strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
info.modify_counter = s->mix.modcnt;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
_old_mixer_info info;
strncpy(info.id, "ES1370", sizeof(info.id));
strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
if (_SIOC_DIR(cmd) == _SIOC_READ) {
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- return put_user(s->mix.recsrc, (int *)arg);
+ return put_user(s->mix.recsrc, p);
case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
val = SOUND_MASK_IMIX;
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].avail)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].recmask)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].stereo)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_CAPS:
- return put_user(0, (int *)arg);
+ return put_user(0, p);
case SOUND_MIXER_IMIX:
- return put_user(s->mix.imix, (int *)arg);
+ return put_user(s->mix.imix, p);
default:
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
return -EINVAL;
- return put_user(s->mix.vol[mixtable[i].volidx], (int *)arg);
+ return put_user(s->mix.vol[mixtable[i].volidx], p);
}
}
if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_IMIX:
- if (get_user(s->mix.imix, (int *)arg))
+ if (get_user(s->mix.imix, p))
return -EFAULT;
set_recsrc(s, s->mix.recsrc);
return 0;
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
set_recsrc(s, val);
return 0;
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[mixtable[i].volidx] = val;
#endif
- return put_user(s->mix.vol[mixtable[i].volidx], (int *)arg);
+ return put_user(s->mix.vol[mixtable[i].volidx], p);
}
}
/* --------------------------------------------------------------------- */
-static ssize_t es1370_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct es1370_state *s = (struct es1370_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t es1370_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct es1370_state *s = (struct es1370_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
count_info cinfo;
int count;
int val, mapped, ret;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
outl(s->ctrl, s->io+ES1370_REG_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg);
+ return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
stop_adc(s);
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
if (file->f_mode & FMODE_READ) {
spin_unlock_irqrestore(&s->lock, flags);
}
}
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
if (file->f_mode & FMODE_READ) {
}
}
return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
+ AFMT_S16_LE : AFMT_U8, p);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragstotal = s->dma_dac2.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
spin_unlock_irqrestore(&s->lock, flags);
if (count < 0)
count = 0;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (s->dma_dac2.mapped)
s->dma_dac2.count &= s->dma_dac2.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf_dac2(s)))
return val;
- return put_user(s->dma_dac2.fragsize, (int *)arg);
+ return put_user(s->dma_dac2.fragsize, p);
}
if ((val = prog_dmabuf_adc(s)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg);
+ return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
case SOUND_PCM_READ_CHANNELS:
return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ?
- 2 : 1, (int *)arg);
+ 2 : 1, p);
case SOUND_PCM_READ_BITS:
return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ?
- 16 : 8, (int *)arg);
+ 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
/* --------------------------------------------------------------------- */
-static ssize_t es1370_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1370_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct es1370_state *s = (struct es1370_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
int count;
unsigned ctrl;
int val, ret;
+ int __user *p = (int __user *)arg;
VALIDATE_STATE(s);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
return -EINVAL;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
stop_dac1(s);
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
stop_dac1(s);
outl(s->ctrl, s->io+ES1370_REG_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg);
+ return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
stop_dac1(s);
s->dma_dac1.ready = 0;
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
if (s->dma_dac1.mapped)
outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
stop_dac1(s);
outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
case SNDCTL_DSP_POST:
return 0;
case SNDCTL_DSP_GETTRIGGER:
- return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, (int *)arg);
+ return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val & PCM_ENABLE_OUTPUT) {
if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
abinfo.fragstotal = s->dma_dac1.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
spin_unlock_irqrestore(&s->lock, flags);
if (count < 0)
count = 0;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
case SNDCTL_DSP_GETOPTR:
if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
if (s->dma_dac1.mapped)
s->dma_dac1.count &= s->dma_dac1.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
case SNDCTL_DSP_GETBLKSIZE:
if ((val = prog_dmabuf_dac1(s)))
return val;
- return put_user(s->dma_dac1.fragsize, (int *)arg);
+ return put_user(s->dma_dac1.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
s->dma_dac1.ossfragshift = val & 0xffff;
s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
case SNDCTL_DSP_SUBDIVIDE:
if (s->dma_dac1.subdivision)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg);
+ return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
case SOUND_PCM_READ_CHANNELS:
- return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
- return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
/* --------------------------------------------------------------------- */
-static ssize_t es1370_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1370_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct es1370_state *s = (struct es1370_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t es1370_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1370_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct es1370_state *s = (struct es1370_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return 0;
case SOUND_MIXER_WRITE_PCM: /* use SRC for PCM volume */
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)arg))
return -EFAULT;
right = ((val >> 8) & 0xff);
left = (val & 0xff);
return 0;
case SOUND_MIXER_READ_PCM:
- return put_user(s->spdif_volume, (int *)arg);
+ return put_user(s->spdif_volume, (int __user *)arg);
}
return codec->mixer_ioctl(codec, cmd, arg);
}
/* --------------------------------------------------------------------- */
-static ssize_t es1371_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct es1371_state *s = (struct es1371_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t es1371_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct es1371_state *s = (struct es1371_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
count_info cinfo;
int count;
int val, mapped, ret;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
set_dac2_rate(s, val);
}
}
- return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
stop_adc(s);
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
if (file->f_mode & FMODE_READ) {
spin_unlock_irqrestore(&s->lock, flags);
}
}
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
if (file->f_mode & FMODE_READ) {
}
}
return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ?
- AFMT_S16_LE : AFMT_U8, (int *)arg);
+ AFMT_S16_LE : AFMT_U8, p);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragstotal = s->dma_dac2.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
spin_unlock_irqrestore(&s->lock, flags);
if (count < 0)
count = 0;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (s->dma_dac2.mapped)
s->dma_dac2.count &= s->dma_dac2.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf_dac2(s)))
return val;
- return put_user(s->dma_dac2.fragsize, (int *)arg);
+ return put_user(s->dma_dac2.fragsize, p);
}
if ((val = prog_dmabuf_adc(s)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
case SOUND_PCM_READ_CHANNELS:
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, (int *)arg);
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
/* --------------------------------------------------------------------- */
-static ssize_t es1371_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct es1371_state *s = (struct es1371_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
count_info cinfo;
int count;
int val, ret;
+ int __user *p = (int __user *)arg;
VALIDATE_STATE(s);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
return -EINVAL;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
stop_dac1(s);
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
stop_dac1(s);
s->dma_dac1.ready = 0;
set_dac1_rate(s, val);
}
- return put_user(s->dac1rate, (int *)arg);
+ return put_user(s->dac1rate, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
stop_dac1(s);
s->dma_dac1.ready = 0;
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
stop_dac1(s);
outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
stop_dac1(s);
outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
}
- return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
case SNDCTL_DSP_POST:
return 0;
case SNDCTL_DSP_GETTRIGGER:
- return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, (int *)arg);
+ return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val & PCM_ENABLE_OUTPUT) {
if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
abinfo.fragstotal = s->dma_dac1.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
spin_unlock_irqrestore(&s->lock, flags);
if (count < 0)
count = 0;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
case SNDCTL_DSP_GETOPTR:
if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
if (s->dma_dac1.mapped)
s->dma_dac1.count &= s->dma_dac1.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
case SNDCTL_DSP_GETBLKSIZE:
if ((val = prog_dmabuf_dac1(s)))
return val;
- return put_user(s->dma_dac1.fragsize, (int *)arg);
+ return put_user(s->dma_dac1.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
s->dma_dac1.ossfragshift = val & 0xffff;
s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
case SNDCTL_DSP_SUBDIVIDE:
if (s->dma_dac1.subdivision)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user(s->dac1rate, (int *)arg);
+ return put_user(s->dac1rate, p);
case SOUND_PCM_READ_CHANNELS:
- return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
- return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg);
+ return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
/* --------------------------------------------------------------------- */
-static ssize_t es1371_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct es1371_state *s = (struct es1371_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t es1371_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct es1371_state *s = (struct es1371_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
};
unsigned char l, r, rl, rr, vidx;
int i, val;
+ int __user *p = (int __user *)arg;
VALIDATE_STATE(s);
if (cmd == SOUND_MIXER_PRIVATE1) {
/* enable/disable/query mixer preamp */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != -1) {
val = val ? 0xff : 0xf7;
write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val);
}
val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
}
if (cmd == SOUND_MIXER_PRIVATE2) {
/* enable/disable/query spatializer */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != -1) {
val &= 0x3f;
write_mixer(s, 0x52, val);
write_mixer(s, 0x50, val ? 0x08 : 0);
}
- return put_user(read_mixer(s, 0x52), (int *)arg);
+ return put_user(read_mixer(s, 0x52), p);
}
if (cmd == SOUND_MIXER_INFO) {
mixer_info info;
strncpy(info.id, "Solo1", sizeof(info.id));
strncpy(info.name, "ESS Solo1", sizeof(info.name));
info.modify_counter = s->mix.modcnt;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
_old_mixer_info info;
strncpy(info.id, "Solo1", sizeof(info.id));
strncpy(info.name, "ESS Solo1", sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
if (_SIOC_DIR(cmd) == _SIOC_READ) {
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- return put_user(mixer_src[read_mixer(s, 0x1c) & 7], (int *)arg);
+ return put_user(mixer_src[read_mixer(s, 0x1c) & 7], p);
case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV |
- SOUND_MASK_SPEAKER, (int *)arg);
+ SOUND_MASK_SPEAKER, p);
case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
- return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, (int *)arg);
+ return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, p);
case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
- SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, (int *)arg);
+ SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, p);
case SOUND_MIXER_CAPS:
- return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+ return put_user(SOUND_CAP_EXCL_INPUT, p);
default:
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
return -EINVAL;
- return put_user(s->mix.vol[vidx-1], (int *)arg);
+ return put_user(s->mix.vol[vidx-1], p);
}
}
if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
0xb4, read_ctrl(s, 0xb4));
}
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
i = hweight32(val);
if (i == 0)
return 0;
case SOUND_MIXER_VOLUME:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[9] = val;
#endif
- return put_user(s->mix.vol[9], (int *)arg);
+ return put_user(s->mix.vol[9], p);
case SOUND_MIXER_SPEAKER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = val & 0xff;
if (l > 100)
#else
s->mix.vol[7] = val;
#endif
- return put_user(s->mix.vol[7], (int *)arg);
+ return put_user(s->mix.vol[7], p);
case SOUND_MIXER_RECLEV:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = (val << 1) & 0x1fe;
if (l > 200)
#else
s->mix.vol[8] = val;
#endif
- return put_user(s->mix.vol[8], (int *)arg);
+ return put_user(s->mix.vol[8], p);
default:
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = (val << 1) & 0x1fe;
if (l > 200)
#else
s->mix.vol[vidx-1] = val;
#endif
- return put_user(s->mix.vol[vidx-1], (int *)arg);
+ return put_user(s->mix.vol[vidx-1], p);
}
}
/* --------------------------------------------------------------------- */
-static ssize_t solo1_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t solo1_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct solo1_state *s = (struct solo1_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t solo1_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t solo1_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct solo1_state *s = (struct solo1_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
int val, mapped, ret, count;
int div1, div2;
unsigned rate1, rate2;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
stop_adc(s);
s->clkdiv = div1;
prog_codec(s);
}
- return put_user(s->rate, (int *)arg);
+ return put_user(s->rate, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
stop_adc(s);
stop_dac(s);
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
stop_adc(s);
s->channels = (val >= 2) ? 2 : 1;
prog_codec(s);
}
- return put_user(s->channels, (int *)arg);
+ return put_user(s->channels, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
stop_adc(s);
s->fmt = val;
prog_codec(s);
}
- return put_user(s->fmt, (int *)arg);
+ return put_user(s->fmt, p);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if (file->f_mode & s->ena & FMODE_WRITE)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragstotal = s->dma_dac.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
spin_unlock_irqrestore(&s->lock, flags);
if (count < 0)
count = 0;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
#endif
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf_dac(s)))
return val;
- return put_user(s->dma_dac.fragsize, (int *)arg);
+ return put_user(s->dma_dac.fragsize, p);
}
if ((val = prog_dmabuf_adc(s)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user(s->rate, (int *)arg);
+ return put_user(s->rate, p);
case SOUND_PCM_READ_CHANNELS:
- return put_user(s->channels, (int *)arg);
+ return put_user(s->channels, p);
case SOUND_PCM_READ_BITS:
- return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, (int *)arg);
+ return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
/* --------------------------------------------------------------------- */
-static ssize_t solo1_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t solo1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct solo1_state *s = (struct solo1_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t solo1_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t solo1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct solo1_state *s = (struct solo1_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return 0;
case FM_IOCTL_PLAY_NOTE:
- if (copy_from_user(&n, (void *)arg, sizeof(n)))
+ if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
return -EFAULT;
if (n.voice >= 18)
return -EINVAL;
return 0;
case FM_IOCTL_SET_VOICE:
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
return -EFAULT;
if (v.voice >= 18)
return -EINVAL;
return 0;
case FM_IOCTL_SET_PARAMS:
- if (copy_from_user(&p, (void *)arg, sizeof(p)))
+ if (copy_from_user(&p, (void __user *)arg, sizeof(p)))
return -EFAULT;
outb(0x08, s->sbbase);
outb((p.kbd_split & 1) << 6, s->sbbase+1);
struct forte_chip *chip;
struct audio_buf_info abi;
struct count_info cinfo;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
chip = file->private_data;
switch (cmd) {
case OSS_GETVERSION:
- return put_user (SOUND_VERSION, (int *) arg);
+ return put_user (SOUND_VERSION, p);
case SNDCTL_DSP_GETCAPS:
DPRINTK ("%s: GETCAPS\n", __FUNCTION__);
ival = FORTE_CAPS; /* DUPLEX */
- return put_user (ival, (int *) arg);
+ return put_user (ival, p);
case SNDCTL_DSP_GETFMTS:
DPRINTK ("%s: GETFMTS\n", __FUNCTION__);
ival = FORTE_FMTS; /* U8, 16LE */
- return put_user (ival, (int *) arg);
+ return put_user (ival, p);
case SNDCTL_DSP_SETFMT: /* U8, 16LE */
DPRINTK ("%s: SETFMT\n", __FUNCTION__);
- if (get_user (ival, (int *) arg))
+ if (get_user (ival, p))
return -EFAULT;
spin_lock_irq (&chip->lock);
spin_unlock_irq (&chip->lock);
- return put_user (rval, (int *) arg);
+ return put_user (rval, p);
case SNDCTL_DSP_STEREO: /* 0 - mono, 1 - stereo */
DPRINTK ("%s: STEREO\n", __FUNCTION__);
- if (get_user (ival, (int *) arg))
+ if (get_user (ival, p))
return -EFAULT;
spin_lock_irq (&chip->lock);
spin_unlock_irq (&chip->lock);
- return put_user (rval, (int *) arg);
+ return put_user (rval, p);
case SNDCTL_DSP_CHANNELS: /* 1 - mono, 2 - stereo */
DPRINTK ("%s: CHANNELS\n", __FUNCTION__);
- if (get_user (ival, (int *) arg))
+ if (get_user (ival, p))
return -EFAULT;
spin_lock_irq (&chip->lock);
spin_unlock_irq (&chip->lock);
- return put_user (rval, (int *) arg);
+ return put_user (rval, p);
case SNDCTL_DSP_SPEED:
DPRINTK ("%s: SPEED\n", __FUNCTION__);
- if (get_user (ival, (int *) arg))
+ if (get_user (ival, p))
return -EFAULT;
spin_lock_irq (&chip->lock);
spin_unlock_irq (&chip->lock);
- return put_user(rval, (int*) arg);
+ return put_user(rval, p);
case SNDCTL_DSP_GETBLKSIZE:
DPRINTK ("%s: GETBLKSIZE\n", __FUNCTION__);
spin_unlock_irq (&chip->lock);
- return put_user (ival, (int *) arg);
+ return put_user (ival, p);
case SNDCTL_DSP_RESET:
DPRINTK ("%s: RESET\n", __FUNCTION__);
case SNDCTL_DSP_SETFRAGMENT:
DPRINTK ("%s: SETFRAGMENT\n", __FUNCTION__);
- if (get_user (ival, (int *) arg))
+ if (get_user (ival, p))
return -EFAULT;
spin_lock_irq (&chip->lock);
spin_unlock_irq (&chip->lock);
- return put_user (ival, (int *) arg);
+ return put_user (ival, p);
case SNDCTL_DSP_GETISPACE:
DPRINTK ("%s: GETISPACE\n", __FUNCTION__);
spin_unlock_irq (&chip->lock);
- return copy_to_user ((void *) arg, &abi, sizeof (abi)) ? -EFAULT : 0;
+ return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
case SNDCTL_DSP_GETIPTR:
DPRINTK ("%s: GETIPTR\n", __FUNCTION__);
spin_unlock_irq (&chip->lock);
- return copy_to_user ((void *) arg, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
+ return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETOSPACE:
if (!wr)
spin_unlock_irq (&chip->lock);
- return copy_to_user ((void *) arg, &abi, sizeof (abi)) ? -EFAULT : 0;
+ return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
case SNDCTL_DSP_GETOPTR:
if (!wr)
spin_unlock_irq (&chip->lock);
- return copy_to_user ((void *) arg, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
+ return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETODELAY:
if (!wr)
spin_unlock_irq (&chip->lock);
- return put_user (ival, (int *) arg);
+ return put_user (ival, p);
case SNDCTL_DSP_SETDUPLEX:
DPRINTK ("%s: SETDUPLEX\n", __FUNCTION__);
case SNDCTL_DSP_GETTRIGGER:
DPRINTK ("%s: GETTRIGGER\n", __FUNCTION__);
- return put_user (chip->trigger, (int *) arg);
+ return put_user (chip->trigger, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user (ival, (int *) arg))
+ if (get_user (ival, p))
return -EFAULT;
DPRINTK ("%s: SETTRIGGER %d\n", __FUNCTION__, ival);
case SOUND_PCM_READ_RATE:
DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__);
- return put_user (chip->play.rate, (int *) arg);
+ return put_user (chip->play.rate, p);
case SOUND_PCM_READ_CHANNELS:
DPRINTK ("%s: PCM_READ_CHANNELS\n", __FUNCTION__);
- return put_user (chip->play.stereo, (int *) arg);
+ return put_user (chip->play.stereo, p);
case SOUND_PCM_READ_BITS:
DPRINTK ("%s: PCM_READ_BITS\n", __FUNCTION__);
- return put_user (chip->play.format, (int *) arg);
+ return put_user (chip->play.format, p);
case SNDCTL_DSP_NONBLOCK:
DPRINTK ("%s: DSP_NONBLOCK\n", __FUNCTION__);
return 0;
default:
- DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, (void *) arg);
+ DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, argp);
break;
}
*/
static ssize_t
-forte_dsp_write (struct file *file, const char *buffer, size_t bytes,
+forte_dsp_write (struct file *file, const char __user *buffer, size_t bytes,
loff_t *ppos)
{
struct forte_chip *chip;
*/
static ssize_t
-forte_dsp_read (struct file *file, char *buffer, size_t bytes,
+forte_dsp_read (struct file *file, char __user *buffer, size_t bytes,
loff_t *ppos)
{
struct forte_chip *chip;
waiting to be copied to the user's buffer. It is filled by the dma
machine and drained by this loop. */
-static ssize_t i810_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t i810_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct i810_state *state = (struct i810_state *)file->private_data;
struct i810_card *card=state ? state->card : 0;
/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
the soundcard. it is drained by the dma machine and filled by this loop. */
-static ssize_t i810_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t i810_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct i810_state *state = (struct i810_state *)file->private_data;
struct i810_card *card=state ? state->card : 0;
unsigned int i_glob_cnt;
int val = 0, ret;
struct ac97_codec *codec = state->card->ac97_codec[0];
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
#ifdef DEBUG
- printk("i810_audio: i810_ioctl, arg=0x%x, cmd=", arg ? *(int *)arg : 0);
+ printk("i810_audio: i810_ioctl, arg=0x%x, cmd=", arg ? *p : 0);
#endif
switch (cmd)
#ifdef DEBUG
printk("OSS_GETVERSION\n");
#endif
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_RESET:
#ifdef DEBUG
#ifdef DEBUG
printk("SNDCTL_DSP_SPEED\n");
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_WRITE) {
spin_unlock_irqrestore(&state->card->lock, flags);
}
}
- return put_user(dmabuf->rate, (int *)arg);
+ return put_user(dmabuf->rate, p);
case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
#ifdef DEBUG
if (dmabuf->enable & ADC_RUNNING) {
stop_adc(state);
}
- return put_user(1, (int *)arg);
+ return put_user(1, p);
case SNDCTL_DSP_GETBLKSIZE:
if (file->f_mode & FMODE_WRITE) {
#ifdef DEBUG
printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
#endif
- return put_user(dmabuf->userfragsize, (int *)arg);
+ return put_user(dmabuf->userfragsize, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
#ifdef DEBUG
printk("SNDCTL_DSP_GETFMTS\n");
#endif
- return put_user(AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_SETFMT: /* Select sample format */
#ifdef DEBUG
printk("SNDCTL_DSP_SETFMT\n");
#endif
- return put_user(AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_CHANNELS:
#ifdef DEBUG
printk("SNDCTL_DSP_CHANNELS\n");
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val > 0) {
stop_adc(state);
}
} else {
- return put_user(state->card->channels, (int *)arg);
+ return put_user(state->card->channels, p);
}
/* ICH and ICH0 only support 2 channels */
if ( state->card->pci_id == PCI_DEVICE_ID_INTEL_82801AA_5
|| state->card->pci_id == PCI_DEVICE_ID_INTEL_82801AB_5)
- return put_user(2, (int *)arg);
+ return put_user(2, p);
/* Multi-channel support was added with ICH2. Bits in */
/* Global Status and Global Control register are now */
break;
}
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */
/* we update the swptr to the end of the last sg segment then return */
case SNDCTL_DSP_SUBDIVIDE:
if (dmabuf->subdivision)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
dmabuf->ossfragsize = 1<<(val & 0xffff);
printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n", abinfo.bytes,
abinfo.fragsize, abinfo.fragments, abinfo.fragstotal);
#endif
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETOPTR:
if (!(file->f_mode & FMODE_WRITE))
printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
cinfo.blocks, cinfo.ptr, dmabuf->count);
#endif
- return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n", abinfo.bytes,
abinfo.fragsize, abinfo.fragments, abinfo.fragstotal);
#endif
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
cinfo.blocks, cinfo.ptr, dmabuf->count);
#endif
- return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
#ifdef DEBUG
printk("SNDCTL_DSP_GETCAPS\n");
#endif
return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP|DSP_CAP_BIND,
- (int *)arg);
+ p);
case SNDCTL_DSP_GETTRIGGER:
val = 0;
#ifdef DEBUG
printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
#endif
- return put_user(dmabuf->trigger, (int *)arg);
+ return put_user(dmabuf->trigger, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
#if defined(DEBUG) || defined(DEBUG_MMAP)
printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
#ifdef DEBUG
printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
#endif
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_PCM_READ_RATE:
#ifdef DEBUG
printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate);
#endif
- return put_user(dmabuf->rate, (int *)arg);
+ return put_user(dmabuf->rate, p);
case SOUND_PCM_READ_CHANNELS:
#ifdef DEBUG
printk("SOUND_PCM_READ_CHANNELS\n");
#endif
- return put_user(2, (int *)arg);
+ return put_user(2, p);
case SOUND_PCM_READ_BITS:
#ifdef DEBUG
printk("SOUND_PCM_READ_BITS\n");
#endif
- return put_user(AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_SETSPDIF: /* Set S/PDIF Control register */
#ifdef DEBUG
printk("SNDCTL_DSP_SETSPDIF\n");
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
/* Check to make sure the codec supports S/PDIF transmitter */
else
printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n");
#endif
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETSPDIF: /* Get S/PDIF Control register */
#ifdef DEBUG
printk("SNDCTL_DSP_GETSPDIF\n");
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
/* Check to make sure the codec supports S/PDIF transmitter */
} else {
val = i810_ac97_get(codec, AC97_SPDIF_CONTROL);
}
- //return put_user((val & 0xcfff), (int *)arg);
- return put_user(val, (int *)arg);
+ //return put_user((val & 0xcfff), p);
+ return put_user(val, p);
case SNDCTL_DSP_GETCHANNELMASK:
#ifdef DEBUG
printk("SNDCTL_DSP_GETCHANNELMASK\n");
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
/* Based on AC'97 DAC support, not ICH hardware */
if ( state->card->ac97_features & 0x0140 )
val |= DSP_BIND_CENTER_LFE;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_BIND_CHANNEL:
#ifdef DEBUG
printk("SNDCTL_DSP_BIND_CHANNEL\n");
#endif
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if ( val == DSP_BIND_QUERY ) {
val = DSP_BIND_FRONT; /* Always report this as being enabled */
val &= ~DSP_BIND_CENTER_LFE;
}
}
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
static void __devexit kahlua_cleanup_module(void)
{
- return pci_unregister_driver(&kahlua_driver);
+ pci_unregister_driver(&kahlua_driver);
}
static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
{
int i, val=0;
- unsigned long flags;
+ unsigned long flags;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_CARD(card);
if (cmd == SOUND_MIXER_INFO) {
strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
info.modify_counter = card->mix.modcnt;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
memset(&info, 0, sizeof(info));
strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
break;
}
- return put_user(val,(int *)arg);
+ return put_user(val, p);
}
if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
card->mix.modcnt++;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
switch (_IOC_NR(cmd)) {
to be copied to the user's buffer. it is filled by the interrupt
handler and drained by this loop. */
static ssize_t
-ess_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct ess_state *s = (struct ess_state *)file->private_data;
ssize_t ret;
}
static ssize_t
-ess_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+ess_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct ess_state *s = (struct ess_state *)file->private_data;
ssize_t ret;
count_info cinfo;
int val, mapped, ret;
unsigned char fmtm, fmtd;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
/* printk("maestro: ess_ioctl: cmd %d\n", cmd);*/
((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
set_dac_rate(s, val);
}
}
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
fmtd = 0;
fmtm = ~0;
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
fmtd = 0;
set_fmt(s, fmtm, fmtd);
}
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT)
- : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+ : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_U8|AFMT_S16_LE, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
fmtd = 0;
: (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ?
AFMT_S16_LE :
AFMT_U8,
- (int *)arg);
+ p);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING))
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragstotal = s->dma_dac.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
ess_update_ptr(s);
val = s->dma_dac.count;
spin_unlock_irqrestore(&s->lock, flags);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (s->dma_dac.mapped)
s->dma_dac.count &= s->dma_dac.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf(s, 0)))
return val;
- return put_user(s->dma_dac.fragsize, (int *)arg);
+ return put_user(s->dma_dac.fragsize, p);
}
if ((val = prog_dmabuf(s, 1)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
M_printk("maestro: SETFRAGMENT: %0x\n",val);
if (file->f_mode & FMODE_READ) {
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SOUND_PCM_READ_CHANNELS:
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT)
- : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+ : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT)
- : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, (int *)arg);
+ : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
return 0;
}
-static ssize_t m3_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t m3_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct m3_state *s = (struct m3_state *)file->private_data;
ssize_t ret;
return ret;
}
-static ssize_t m3_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t m3_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct m3_state *s = (struct m3_state *)file->private_data;
ssize_t ret;
count_info cinfo;
int val, mapped, ret;
unsigned char fmtm, fmtd;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
spin_lock_irqsave(&card->lock, flags);
return 0;
case SNDCTL_DSP_SPEED:
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
spin_lock_irqsave(&card->lock, flags);
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
}
}
spin_unlock_irqrestore(&card->lock, flags);
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SNDCTL_DSP_STEREO:
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
spin_lock_irqsave(&card->lock, flags);
fmtd = 0;
fmtm = ~0;
return 0;
case SNDCTL_DSP_CHANNELS:
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
spin_lock_irqsave(&card->lock, flags);
if (val != 0) {
fmtd = 0;
}
spin_unlock_irqrestore(&card->lock, flags);
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT)
- : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+ : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_U8|AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_U8|AFMT_S16_LE, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
spin_lock_irqsave(&card->lock, flags);
if (val != AFMT_QUERY) {
fmtd = 0;
: (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ?
AFMT_S16_LE :
AFMT_U8,
- (int *)arg);
+ p);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING))
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
abinfo.fragstotal = s->dma_dac.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
spin_unlock_irqrestore(&card->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&card->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
m3_update_ptr(s);
val = s->dma_dac.count;
spin_unlock_irqrestore(&card->lock, flags);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&card->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (s->dma_dac.mapped)
s->dma_dac.count &= s->dma_dac.fragsize-1;
spin_unlock_irqrestore(&card->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf(s, 0)))
return val;
- return put_user(s->dma_dac.fragsize, (int *)arg);
+ return put_user(s->dma_dac.fragsize, p);
}
if ((val = prog_dmabuf(s, 1)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
spin_lock_irqsave(&card->lock, flags);
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
return -EINVAL;
- get_user_ret(val, (int *)arg, -EFAULT);
+ get_user_ret(val, p, -EFAULT);
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
if (file->f_mode & FMODE_READ)
return 0;
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SOUND_PCM_READ_CHANNELS:
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT)
- : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+ : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT)
- : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, (int *)arg);
+ : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
f->len = f->tail = f->head = 0;
}
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user)
+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len)
{
int count = 0;
- if (f->len == f->n)
- return 0;
-
while ((count < len) && (f->len != f->n)) {
int nwritten;
nwritten = len - count;
}
- if (user) {
- if (copy_from_user(f->data + f->tail, buf, nwritten))
- return -EFAULT;
- } else
- isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten);
+ isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten);
count += nwritten;
buf += nwritten;
return count;
}
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user)
+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len)
{
int count = 0;
- if (f->len == 0)
- return f->len;
-
while ((count < len) && (f->len > 0)) {
int nread;
nread = len - count;
}
- if (user) {
- if (copy_to_user(buf, f->data + f->head, nread))
- return -EFAULT;
- } else
- isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread);
+ isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread);
count += nread;
buf += nread;
void msnd_fifo_free(msnd_fifo *f);
int msnd_fifo_alloc(msnd_fifo *f, size_t n);
void msnd_fifo_make_empty(msnd_fifo *f);
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user);
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user);
+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len);
+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len);
int msnd_wait_TXDE(multisound_dev_t *dev);
int msnd_wait_HC0(multisound_dev_t *dev);
LPDAQD lpDAQ, lpDARQ;
audio_buf_info abinfo;
unsigned long flags;
+ int __user *p = (int __user *)arg;
lpDAQ = dev.base + DAPQ_DATA_BUFF;
lpDARQ = dev.base + DARQ_DATA_BUFF;
abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
abinfo.fragments = abinfo.bytes / abinfo.fragsize;
spin_unlock_irqrestore(&dev.lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
abinfo.fragments = abinfo.bytes / abinfo.fragsize;
spin_unlock_irqrestore(&dev.lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_RESET:
dev.nresets = 0;
case SNDCTL_DSP_GETBLKSIZE:
tmp = dsp_get_frag_size();
- if (put_user(tmp, (int *)arg))
+ if (put_user(tmp, p))
return -EFAULT;
return 0;
case SNDCTL_DSP_GETFMTS:
val = AFMT_S16_LE | AFMT_U8;
- if (put_user(val, (int *)arg))
+ if (put_user(val, p))
return -EFAULT;
return 0;
case SNDCTL_DSP_SETFMT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_WRITE)
? dev.rec_sample_size
: dsp_set_format(file, val);
- if (put_user(data, (int *)arg))
+ if (put_user(data, p))
return -EFAULT;
return 0;
case SNDCTL_DSP_GETCAPS:
val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
- if (put_user(val, (int *)arg))
+ if (put_user(val, p))
return -EFAULT;
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val < 8000)
if (file->f_mode & FMODE_READ)
dev.rec_sample_rate = data;
- if (put_user(data, (int *)arg))
+ if (put_user(data, p))
return -EFAULT;
return 0;
case SNDCTL_DSP_CHANNELS:
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (cmd == SNDCTL_DSP_CHANNELS) {
if (file->f_mode & FMODE_READ)
dev.rec_channels = data;
- if (put_user(val, (int *)arg))
+ if (put_user(val, p))
return -EFAULT;
return 0;
}
mixer_info info;
set_mixer_info();
info.modify_counter = dev.mixer_mod_count;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
} else if (cmd == SOUND_OLD_MIXER_INFO) {
_old_mixer_info info;
set_mixer_info();
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
} else if (cmd == SOUND_MIXER_PRIVATE1) {
if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
switch (cmd & 0xff) {
case SOUND_MIXER_RECSRC:
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)arg))
return -EFAULT;
val = set_recsrc(val);
break;
default:
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int __user *)arg))
return -EFAULT;
val = mixer_set(cmd & 0xff, val);
break;
}
++dev.mixer_mod_count;
- return put_user(val, (int *)arg);
+ return put_user(val, (int __user *)arg);
} else {
switch (cmd & 0xff) {
case SOUND_MIXER_RECSRC:
}
}
- return put_user(val, (int *)arg);
+ return put_user(val, (int __user *)arg);
}
return -EINVAL;
if (cmd == OSS_GETVERSION) {
int sound_version = SOUND_VERSION;
- return put_user(sound_version, (int *)arg);
+ return put_user(sound_version, (int __user *)arg);
}
if (minor == dev.dsp_minor)
static __inline__ int pack_DARQ_to_DARF(register int bank)
{
- register int size, n, timeout = 3;
+ register int size, timeout = 3;
register WORD wTmp;
LPDAQD DAQD;
/* Read data from the head (unprotected bank 1 access okay
since this is only called inside an interrupt) */
outb(HPBLKSEL_1, dev.io + HP_BLKS);
- if ((n = msnd_fifo_write(
+ msnd_fifo_write(
&dev.DARF,
(char *)(dev.base + bank * DAR_BUFF_SIZE),
- size, 0)) <= 0) {
- outb(HPBLKSEL_0, dev.io + HP_BLKS);
- return n;
- }
+ size);
outb(HPBLKSEL_0, dev.io + HP_BLKS);
return 1;
if (protect) {
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
- if ((n = msnd_fifo_read(
+ n = msnd_fifo_read(
&dev.DAPF,
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
- DAP_BUFF_SIZE, 0)) < 0) {
- spin_unlock_irqrestore(&dev.lock, flags);
- return n;
- }
+ DAP_BUFF_SIZE);
spin_unlock_irqrestore(&dev.lock, flags);
} else {
- if ((n = msnd_fifo_read(
+ n = msnd_fifo_read(
&dev.DAPF,
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
- DAP_BUFF_SIZE, 0)) < 0) {
- return n;
- }
+ DAP_BUFF_SIZE);
}
if (!n)
break;
return nbanks;
}
-static int dsp_read(char *buf, size_t len)
+static int dsp_read(char __user *buf, size_t len)
{
int count = len;
+ char *page = (char *)__get_free_page(PAGE_SIZE);
+
+ if (!page)
+ return -ENOMEM;
while (count > 0) {
- int n;
+ int n, k;
unsigned long flags;
+ k = PAGE_SIZE;
+ if (k > count)
+ k = count;
+
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
- if ((n = msnd_fifo_read(&dev.DARF, buf, count, 1)) < 0) {
- printk(KERN_WARNING LOGNAME ": FIFO read error\n");
- spin_unlock_irqrestore(&dev.lock, flags);
- return n;
- }
+ n = msnd_fifo_read(&dev.DARF, page, k);
spin_unlock_irqrestore(&dev.lock, flags);
+ if (copy_to_user(buf, page, n)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
buf += n;
count -= n;
+ if (n == k && count)
+ continue;
+
if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
dev.last_recbank = -1;
if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
set_bit(F_READING, &dev.flags);
}
- if (dev.rec_ndelay)
+ if (dev.rec_ndelay) {
+ free_page((unsigned long)page);
return count == len ? -EAGAIN : len - count;
+ }
if (count > 0) {
set_bit(F_READBLOCK, &dev.flags);
get_rec_delay_jiffies(DAR_BUFF_SIZE)))
clear_bit(F_READING, &dev.flags);
clear_bit(F_READBLOCK, &dev.flags);
- if (signal_pending(current))
+ if (signal_pending(current)) {
+ free_page((unsigned long)page);
return -EINTR;
+ }
}
}
-
+ free_page((unsigned long)page);
return len - count;
}
-static int dsp_write(const char *buf, size_t len)
+static int dsp_write(const char __user *buf, size_t len)
{
int count = len;
+ char *page = (char *)__get_free_page(GFP_KERNEL);
+
+ if (!page)
+ return -ENOMEM;
while (count > 0) {
- int n;
+ int n, k;
unsigned long flags;
+ k = PAGE_SIZE;
+ if (k > count)
+ k = count;
+
+ if (copy_from_user(page, buf, k)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
+
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
- if ((n = msnd_fifo_write(&dev.DAPF, buf, count, 1)) < 0) {
- printk(KERN_WARNING LOGNAME ": FIFO write error\n");
- spin_unlock_irqrestore(&dev.lock, flags);
- return n;
- }
+ n = msnd_fifo_write(&dev.DAPF, page, k);
spin_unlock_irqrestore(&dev.lock, flags);
buf += n;
count -= n;
+ if (count && n == k)
+ continue;
+
if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
dev.last_playbank = -1;
if (pack_DAPF_to_DAPQ(1) > 0)
set_bit(F_WRITING, &dev.flags);
}
- if (dev.play_ndelay)
+ if (dev.play_ndelay) {
+ free_page((unsigned long)page);
return count == len ? -EAGAIN : len - count;
+ }
if (count > 0) {
set_bit(F_WRITEBLOCK, &dev.flags);
&dev.writeblock,
get_play_delay_jiffies(DAP_BUFF_SIZE));
clear_bit(F_WRITEBLOCK, &dev.flags);
- if (signal_pending(current))
+ if (signal_pending(current)) {
+ free_page((unsigned long)page);
return -EINTR;
+ }
}
}
+ free_page((unsigned long)page);
return len - count;
}
-static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
+static ssize_t dev_read(struct file *file, char __user *buf, size_t count, loff_t *off)
{
int minor = iminor(file->f_dentry->d_inode);
if (minor == dev.dsp_minor)
return -EINVAL;
}
-static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off)
+static ssize_t dev_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
int minor = iminor(file->f_dentry->d_inode);
if (minor == dev.dsp_minor)
{
}
-static int opl3_load_patch(int dev, int format, const char *addr,
+static int opl3_load_patch(int dev, int format, const char __user *addr,
int offs, int count, int pmgr_flag)
{
struct sbi_instrument ins;
return -EINVAL;
}
- if(copy_from_user(&((char *) &ins)[offs], &(addr)[offs], sizeof(ins) - offs))
+ /*
+ * What the fuck is going on here? We leave junk in the beginning
+ * of ins and then check the field pretty close to that beginning?
+ */
+ if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs))
return -EFAULT;
if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
}
-inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count,int hop)
+inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop)
{
int swptr = dma->writeptr;
switch (dma->format) {
case AFMT_S32_BLOCKED:
{
- char* buf = (char*)buffer;
+ char __user * buf = (char __user *)buffer;
int cnt = count/dma->outchannels;
int i;
for (i=0;i < dma->outchannels;i++) {
int i,j;
int cnt = count/dma->outchannels;
for (i=0;i < dma->outchannels + dma->mono;i++) {
- short* sbuf = (short*)buffer + i*(!dma->mono);
+ short __user * sbuf = (short __user *)buffer + i*(!dma->mono);
short* hwbuf =(short*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];
hwbuf+=(swptr>>1);
for (j=0;j<(cnt>>1);j++) {
}
/* The count argument is the number of bytes */
-inline int rme96xx_copytouser(struct dmabuf* dma,const char* buffer,int count,int hop)
+inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop)
{
int swptr = dma->readptr;
switch (dma->format) {
case AFMT_S32_BLOCKED:
{
- char* buf = (char*)buffer;
+ char __user * buf = (char __user *)buffer;
int cnt = count/dma->inchannels;
int i;
int i,j;
int cnt = count/dma->inchannels;
for (i=0;i < dma->inchannels;i++) {
- short* sbuf = (short*)buffer + i;
+ short __user * sbuf = (short __user *)buffer + i;
short* hwbuf =(short*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];
hwbuf+=(swptr>>1);
for (j=0;j<(cnt>>1);j++) {
static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg)
{
-
struct dmabuf * dma = (struct dmabuf *)file->private_data;
rme96xx_info *s = dma->s;
unsigned long flags;
count_info cinfo;
int count;
int val = 0;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
#if 0
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
// rme96xx_clearbufs(dma);
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
/* generally it's not a problem if we change the speed
spin_unlock_irqrestore(&s->lock, flags);
}
DBG(printk("speed set to %d\n",val));
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (!val) {
return 0;
case SNDCTL_DSP_CHANNELS:
/* remember to check for resonable offset/channel pairs here */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_WRITE) {
dma->mono=0;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(RME96xx_FMT, (int *)arg);
+ return put_user(RME96xx_FMT, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
DBG(printk("setting to format %x\n",val));
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
if (val & RME96xx_FMT)
break;
}
}
- return put_user(dma->format, (int *)arg);
+ return put_user(dma->format, p);
case SNDCTL_DSP_POST:
return 0;
if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN)
val |= PCM_ENABLE_OUTPUT;
#endif
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
#if 0
if (file->f_mode & FMODE_READ) {
abinfo.fragstotal = 2;
abinfo.fragments = (count > s->fragsize);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.bytes = (count*dma->inchannels)>>dma->formatshift;
abinfo.fragstotal = 2;
abinfo.fragments = count > s->fragsize;
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
if (count < 0)
count += s->fragsize<<1;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
/* check out how to use mmaped mode (can only be blocked !!!) */
dma->readptr &= s->fragsize<<1;
spin_unlock_irqrestore(&s->lock,flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (dma->mmapped)
dma->writeptr &= s->fragsize<<1;
spin_unlock_irqrestore(&s->lock,flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
case SNDCTL_DSP_GETBLKSIZE:
- return put_user(s->fragsize, (int *)arg);
+ return put_user(s->fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
val&=0xffff;
val -= 7;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
case SOUND_PCM_READ_RATE:
/* HP20020201 */
s->rate = rme96xx_get_sample_rate_status(s);
- return put_user(s->rate, (int *)arg);
+ return put_user(s->rate, p);
case SOUND_PCM_READ_CHANNELS:
- return put_user(dma->outchannels, (int *)arg);
+ return put_user(dma->outchannels, p);
case SOUND_PCM_READ_BITS:
switch (dma->format) {
val = 16;
break;
}
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
}
-static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t rme96xx_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct dmabuf *dma = (struct dmabuf *)file->private_data;
ssize_t ret = 0;
return ret;
}
-static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t rme96xx_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct dmabuf *dma = (struct dmabuf *)file->private_data;
ssize_t ret = 0;
rme96xx_info *s = (rme96xx_info *)file->private_data;
u32 status;
int spdifrate;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
status = readl(s->iobase + RME96xx_status_register);
/* hack to convert rev 1.5 SPDIF rate to "crystalrate" format HP 20020201 */
VALIDATE_STATE(s);
if (cmd == SOUND_MIXER_PRIVATE1) {
rme_mixer mixer;
- if (copy_from_user(&mixer,(void*)arg,sizeof(mixer)))
+ if (copy_from_user(&mixer,argp,sizeof(mixer)))
return -EFAULT;
mixer.devnr &= RME96xx_MASK_DEVS;
mixer.o_offset = s->dma[mixer.devnr].outoffset;
mixer.i_offset = s->dma[mixer.devnr].inoffset;
- return copy_to_user((void *)arg, &mixer, sizeof(mixer)) ? -EFAULT : 0;
+ return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0;
}
if (cmd == SOUND_MIXER_PRIVATE2) {
- return put_user(status, (int *)arg);
+ return put_user(status, p);
}
if (cmd == SOUND_MIXER_PRIVATE3) {
u32 control;
- if (copy_from_user(&control,(void*)arg,sizeof(control)))
+ if (copy_from_user(&control,argp,sizeof(control)))
return -EFAULT;
if (file->f_mode & FMODE_WRITE) {
s->control_register &= ~RME96xx_mixer_allowed;
writel(control,s->iobase + RME96xx_control_register);
}
- return put_user(s->control_register, (int *)arg);
+ return put_user(s->control_register, p);
}
return -1;
}
static void
sb16_copy_from_user(int dev,
char *localbuf, int localoffs,
- const char *userbuf, int useroffs,
+ const char __user *userbuf, int useroffs,
int max_in, int max_out,
int *used, int *returned,
int len)
/* If either PnP or Legacy registered a card then return
* success */
- return (pres > 0 || lres > 0) ? 0 : -ENODEV;
+ if (pres <= 0 && lres <= 0) {
+#ifdef CONFIG_PNP
+ pnp_unregister_card_driver(&sb_pnp_driver);
+#endif
+ return -ENODEV;
+ }
+ return 0;
}
static void __exit sb_exit(void)
{
unsigned long flags;
- if (devc->model == MDL_ESS) return ess_setmixer (devc, port, value);
+ if (devc->model == MDL_ESS) {
+ ess_setmixer (devc, port, value);
+ return;
+ }
spin_lock_irqsave(&devc->lock, flags);
unsigned long flags;
int i, val;
unsigned char l, r, rl, rr;
+ int __user *p = (int __user *)arg;
VALIDATE_STATE(s);
if (cmd == SOUND_MIXER_INFO) {
strlcpy(info.id, "SonicVibes", sizeof(info.id));
strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
info.modify_counter = s->mix.modcnt;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
memset(&info, 0, sizeof(info));
strlcpy(info.id, "SonicVibes", sizeof(info.id));
strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
if (cmd == OSS_GETVERSION)
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
if (cmd == SOUND_MIXER_PRIVATE1) { /* SRS settings */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
spin_lock_irqsave(&s->lock, flags);
if (val & 1) {
r = rdindir(s, SV_CISRSCENTER);
spin_unlock_irqrestore(&s->lock, flags);
if (l & 0x80)
- return put_user(0, (int *)arg);
- return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, (int *)arg);
+ return put_user(0, p);
+ return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, p);
}
if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
return -EINVAL;
if (_SIOC_DIR(cmd) == _SIOC_READ) {
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- return put_user(mixer_recmask(s), (int *)arg);
+ return put_user(mixer_recmask(s), p);
case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].type)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].rec)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
val |= 1 << i;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_MIXER_CAPS:
- return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+ return put_user(SOUND_CAP_EXCL_INPUT, p);
default:
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
return -EINVAL;
#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- return return_mixval(s, i, (int *)arg);
+ return return_mixval(s, i, p);
#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
if (!volidx[i])
return -EINVAL;
- return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
+ return put_user(s->mix.vol[volidx[i]-1], p);
#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
}
}
s->mix.modcnt++;
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
i = hweight32(val);
if (i == 0)
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
l = val & 0xff;
r = (val >> 8) & 0xff;
}
spin_unlock_irqrestore(&s->lock, flags);
#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- return return_mixval(s, i, (int *)arg);
+ return return_mixval(s, i, p);
#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
if (!volidx[i])
return -EINVAL;
s->mix.vol[volidx[i]-1] = val;
- return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
+ return put_user(s->mix.vol[volidx[i]-1], p);
#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
}
}
/* --------------------------------------------------------------------- */
-static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t sv_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct sv_state *s = (struct sv_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t sv_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t sv_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct sv_state *s = (struct sv_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
int count;
int val, mapped, ret;
unsigned char fmtm, fmtd;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
if (file->f_mode & FMODE_WRITE)
return 0;
case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
case SNDCTL_DSP_RESET:
if (file->f_mode & FMODE_WRITE) {
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val >= 0) {
if (file->f_mode & FMODE_READ) {
set_dac_rate(s, val);
}
}
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SNDCTL_DSP_STEREO:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
fmtd = 0;
fmtm = ~0;
return 0;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 0) {
fmtd = 0;
set_fmt(s, fmtm, fmtd);
}
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT)
- : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg);
+ : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != AFMT_QUERY) {
fmtd = 0;
set_fmt(s, fmtm, fmtd);
}
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT)
- : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, (int *)arg);
+ : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, p);
case SNDCTL_DSP_POST:
return 0;
val |= PCM_ENABLE_INPUT;
if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE)
val |= PCM_ENABLE_OUTPUT;
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) {
abinfo.fragstotal = s->dma_dac.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
abinfo.fragstotal = s->dma_adc.numfrag;
abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
spin_unlock_irqrestore(&s->lock, flags);
if (count < 0)
count = 0;
- return put_user(count, (int *)arg);
+ return put_user(count, p);
case SNDCTL_DSP_GETIPTR:
if (!(file->f_mode & FMODE_READ))
if (s->dma_adc.mapped)
s->dma_adc.count &= s->dma_adc.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (s->dma_dac.mapped)
s->dma_dac.count &= s->dma_dac.fragsize-1;
spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+ if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
return -EFAULT;
return 0;
if (file->f_mode & FMODE_WRITE) {
if ((val = prog_dmabuf(s, 0)))
return val;
- return put_user(s->dma_dac.fragsize, (int *)arg);
+ return put_user(s->dma_dac.fragsize, p);
}
if ((val = prog_dmabuf(s, 1)))
return val;
- return put_user(s->dma_adc.fragsize, (int *)arg);
+ return put_user(s->dma_adc.fragsize, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = val & 0xffff;
if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
(file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
return -EINVAL;
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
if (val != 1 && val != 2 && val != 4)
return -EINVAL;
return 0;
case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
case SOUND_PCM_READ_CHANNELS:
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT)
- : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg);
+ : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
case SOUND_PCM_READ_BITS:
return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT)
- : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, (int *)arg);
+ : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
/* --------------------------------------------------------------------- */
-static ssize_t sv_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t sv_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct sv_state *s = (struct sv_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return ret;
}
-static ssize_t sv_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t sv_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct sv_state *s = (struct sv_state *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
return 0;
case FM_IOCTL_PLAY_NOTE:
- if (copy_from_user(&n, (void *)arg, sizeof(n)))
+ if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
return -EFAULT;
if (n.voice >= 18)
return -EINVAL;
return 0;
case FM_IOCTL_SET_VOICE:
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
return -EFAULT;
if (v.voice >= 18)
return -EINVAL;
return 0;
case FM_IOCTL_SET_PARAMS:
- if (copy_from_user(&p, (void *)arg, sizeof(p)))
+ if (copy_from_user(&p, (void *__user )arg, sizeof(p)))
return -EFAULT;
outb(0x08, s->iosynth);
outb((p.kbd_split & 1) << 6, s->iosynth+1);
static void ali_disable_spdif_in(struct trident_card *card);
static void ali_disable_special_channel(struct trident_card *card, int ch);
static void ali_setup_spdif_out(struct trident_card *card, int flag);
-static int ali_write_5_1(struct trident_state *state, const char *buffer,
+static int ali_write_5_1(struct trident_state *state,
+ const char __user *buffer,
int cnt_for_multi_channel, unsigned int *copy_count,
unsigned int *state_cnt);
static int ali_allocate_other_states_resources(struct trident_state *state,
/* to be copied to the user's buffer. it is filled by the dma machine and */
/* drained by this loop. */
static ssize_t
-trident_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
+trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
{
struct trident_state *state = (struct trident_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
the soundcard. it is drained by the dma machine and filled by this loop. */
static ssize_t
-trident_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+trident_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos)
{
struct trident_state *state = (struct trident_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
audio_buf_info abinfo;
count_info cinfo;
int val, mapped, ret = 0;
-
struct trident_card *card = state->card;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(state);
mapped = ((file->f_mode & (FMODE_WRITE | FMODE_READ)) && dmabuf->mapped);
pr_debug("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",
- _IOC_NR(cmd), arg ? *(int *) arg : 0);
+ _IOC_NR(cmd), arg ? *p : 0);
switch (cmd) {
case OSS_GETVERSION:
- ret = put_user(SOUND_VERSION, (int *) arg);
+ ret = put_user(SOUND_VERSION, p);
break;
case SNDCTL_DSP_RESET:
break;
case SNDCTL_DSP_SPEED: /* set smaple rate */
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
spin_unlock_irqrestore(&state->card->lock, flags);
}
}
- ret = put_user(dmabuf->rate, (int *) arg);
+ ret = put_user(dmabuf->rate, p);
break;
case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
if ((val = prog_dmabuf_playback(state)))
ret = val;
else
- ret = put_user(dmabuf->fragsize, (int *) arg);
+ ret = put_user(dmabuf->fragsize, p);
break;
}
if (file->f_mode & FMODE_READ) {
if ((val = prog_dmabuf_record(state)))
ret = val;
else
- ret = put_user(dmabuf->fragsize, (int *) arg);
+ ret = put_user(dmabuf->fragsize, p);
break;
}
/* neither READ nor WRITE? is this even possible? */
case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format */
ret = put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
- AFMT_U8, (int *) arg);
+ AFMT_U8, p);
break;
case SNDCTL_DSP_SETFMT: /* Select sample format */
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
}
unlock_set_fmt(state);
ret = put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ? AFMT_S16_LE :
- AFMT_U8, (int *) arg);
+ AFMT_U8, p);
break;
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
}
unlock_set_fmt(state);
}
- ret = put_user(val, (int *) arg);
+ ret = put_user(val, p);
break;
case SNDCTL_DSP_POST:
ret = -EINVAL;
break;
}
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
break;
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
abinfo.fragstotal = dmabuf->numfrag;
abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->card->lock, flags);
- ret = copy_to_user((void *) arg, &abinfo, sizeof (abinfo)) ?
+ ret = copy_to_user(argp, &abinfo, sizeof (abinfo)) ?
-EFAULT : 0;
break;
abinfo.fragstotal = dmabuf->numfrag;
abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->card->lock, flags);
- ret = copy_to_user((void *) arg, &abinfo, sizeof (abinfo)) ?
+ ret = copy_to_user(argp, &abinfo, sizeof (abinfo)) ?
-EFAULT : 0;
break;
case SNDCTL_DSP_GETCAPS:
ret = put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
- DSP_CAP_MMAP | DSP_CAP_BIND, (int *) arg);
+ DSP_CAP_MMAP | DSP_CAP_BIND, p);
break;
case SNDCTL_DSP_GETTRIGGER:
val |= PCM_ENABLE_INPUT;
if ((file->f_mode & FMODE_WRITE) && dmabuf->enable)
val |= PCM_ENABLE_OUTPUT;
- ret = put_user(val, (int *) arg);
+ ret = put_user(val, p);
break;
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
if (dmabuf->mapped)
dmabuf->count &= dmabuf->fragsize - 1;
spin_unlock_irqrestore(&state->card->lock, flags);
- ret = copy_to_user((void *) arg, &cinfo, sizeof (cinfo)) ?
+ ret = copy_to_user(argp, &cinfo, sizeof (cinfo)) ?
-EFAULT : 0;
break;
if (dmabuf->mapped)
dmabuf->count &= dmabuf->fragsize - 1;
spin_unlock_irqrestore(&state->card->lock, flags);
- ret = copy_to_user((void *) arg, &cinfo, sizeof (cinfo)) ?
+ ret = copy_to_user(argp, &cinfo, sizeof (cinfo)) ?
-EFAULT : 0;
break;
trident_update_ptr(state);
val = dmabuf->count;
spin_unlock_irqrestore(&state->card->lock, flags);
- ret = put_user(val, (int *) arg);
+ ret = put_user(val, p);
break;
case SOUND_PCM_READ_RATE:
- ret = put_user(dmabuf->rate, (int *) arg);
+ ret = put_user(dmabuf->rate, p);
break;
case SOUND_PCM_READ_CHANNELS:
ret = put_user((dmabuf->fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
- (int *) arg);
+ p);
break;
case SOUND_PCM_READ_BITS:
ret = put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ? AFMT_S16_LE :
- AFMT_U8, (int *) arg);
+ AFMT_U8, p);
break;
case SNDCTL_DSP_GETCHANNELMASK:
ret = put_user(DSP_BIND_FRONT | DSP_BIND_SURR |
- DSP_BIND_CENTER_LFE, (int *) arg);
+ DSP_BIND_CENTER_LFE, p);
break;
case SNDCTL_DSP_BIND_CHANNEL:
break;
}
- if (get_user(val, (int *) arg)) {
+ if (get_user(val, p)) {
ret = -EFAULT;
break;
}
SRC_ENABLE);
dmabuf->channel->attribute |= mask2attr[ffs(val)];
}
- ret = put_user(val, (int *) arg);
+ ret = put_user(val, p);
break;
case SNDCTL_DSP_MAPINBUF:
state DMA is protected by a spinlock.
*/
static int
-ali_write_5_1(struct trident_state *state, const char *buf,
+ali_write_5_1(struct trident_state *state, const char __user *buf,
int cnt_for_multi_channel, unsigned int *copy_count,
unsigned int *state_cnt)
{
struct dmabuf *dmabuf = &state->dmabuf;
struct dmabuf *dmabuf_temp;
- const char *buffer = buf;
+ const char __user *buffer = buf;
unsigned swptr, other_dma_nums, sample_s;
unsigned int i, loop;
struct proc_dir_entry *res;
static int
-ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+ali_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
struct trident_card *card = (struct trident_card *) data;
unsigned long flags;
UINT16 sample_short;
UINT32 length;
- UINT16 *data_end = 0;
+ UINT16 __user *data_end = 0;
unsigned int i;
const int max_blksize = 4096/2;
unsigned int written;
int initial_skip = 0;
DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
- "type %d, %d bytes from 0x%x\n",
+ "type %d, %d bytes from %p\n",
header->size ? "" : "header ",
header->number, header->subkey,
header->size,
- (int) header->dataptr);
+ header->dataptr);
if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
int x;
case WF_ST_MULTISAMPLE:
- if (copy_from_user((unsigned char *) &header.hdr.s,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user(&header.hdr.s, header.hdrptr,
sizeof(wavefront_multisample)))
return -EFAULT;
case WF_ST_ALIAS:
- if (copy_from_user((unsigned char *) &header.hdr.a,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user(&header.hdr.a, header.hdrptr,
sizeof (wavefront_alias)))
return -EFAULT;
return wavefront_send_alias (&header);
case WF_ST_DRUM:
- if (copy_from_user((unsigned char *) &header.hdr.d,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user(&header.hdr.d, header.hdrptr,
sizeof (wavefront_drum)))
return -EFAULT;
return wavefront_send_drum (&header);
case WF_ST_PATCH:
- if (copy_from_user((unsigned char *) &header.hdr.p,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user(&header.hdr.p, header.hdrptr,
sizeof (wavefront_patch)))
return -EFAULT;
return wavefront_send_patch (&header);
case WF_ST_PROGRAM:
- if (copy_from_user((unsigned char *) &header.hdr.pr,
- (unsigned char *) header.hdrptr,
+ if (copy_from_user(&header.hdr.pr, header.hdrptr,
sizeof (wavefront_program)))
return -EFAULT;
return -(EINVAL);
}
if (copy_from_user(page_data,
- (unsigned char *)r->data[3],
+ (unsigned char __user *)r->data[3],
r->data[2]))
return -EFAULT;
pd = page_data;
* machine and drained by this loop.
*/
static ssize_t
-ymf_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+ymf_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct ymf_state *state = (struct ymf_state *)file->private_data;
struct ymf_dmabuf *dmabuf = &state->rpcm.dmabuf;
}
static ssize_t
-ymf_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+ymf_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct ymf_state *state = (struct ymf_state *)file->private_data;
struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
count_info cinfo;
int redzone;
int val;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
switch (cmd) {
case OSS_GETVERSION:
YMFDBGX("ymf_ioctl: cmd 0x%x(GETVER) arg 0x%lx\n", cmd, arg);
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_RESET:
YMFDBGX("ymf_ioctl: cmd 0x%x(RESET)\n", cmd);
return 0;
case SNDCTL_DSP_SPEED: /* set smaple rate */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
YMFDBGX("ymf_ioctl: cmd 0x%x(SPEED) sp %d\n", cmd, val);
if (val >= 8000 && val <= 48000) {
spin_unlock_irqrestore(&state->unit->reg_lock, flags);
}
}
- return put_user(state->format.rate, (int *)arg);
+ return put_user(state->format.rate, p);
/*
* OSS manual does not mention SNDCTL_DSP_STEREO at all.
* However, mpg123 calls it. I wonder, why Michael Hipp used it.
*/
case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
YMFDBGX("ymf_ioctl: cmd 0x%x(STEREO) st %d\n", cmd, val);
if (file->f_mode & FMODE_WRITE) {
return val;
val = state->wpcm.dmabuf.fragsize;
YMFDBGX("ymf_ioctl: GETBLK w %d\n", val);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
}
if (file->f_mode & FMODE_READ) {
if ((val = prog_dmabuf(state, 1)))
return val;
val = state->rpcm.dmabuf.fragsize;
YMFDBGX("ymf_ioctl: GETBLK r %d\n", val);
- return put_user(val, (int *)arg);
+ return put_user(val, p);
}
return -EINVAL;
case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
YMFDBGX("ymf_ioctl: cmd 0x%x(GETFMTS)\n", cmd);
- return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+ return put_user(AFMT_S16_LE|AFMT_U8, p);
case SNDCTL_DSP_SETFMT: /* Select sample format */
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
YMFDBGX("ymf_ioctl: cmd 0x%x(SETFMT) fmt %d\n", cmd, val);
if (val == AFMT_S16_LE || val == AFMT_U8) {
spin_unlock_irqrestore(&state->unit->reg_lock, flags);
}
}
- return put_user(state->format.format, (int *)arg);
+ return put_user(state->format.format, p);
case SNDCTL_DSP_CHANNELS:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
YMFDBGX("ymf_ioctl: cmd 0x%x(CHAN) ch %d\n", cmd, val);
if (val != 0) {
}
}
}
- return put_user(state->format.voices, (int *)arg);
+ return put_user(state->format.voices, p);
case SNDCTL_DSP_POST:
YMFDBGX("ymf_ioctl: cmd 0x%x(POST)\n", cmd);
return 0;
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, (int *)arg))
+ if (get_user(val, p))
return -EFAULT;
YMFDBGX("ymf_ioctl: cmd 0x%x(SETFRAG) fr 0x%04x:%04x(%d:%d)\n",
cmd,
abinfo.fragstotal = dmabuf->numfrag;
abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->unit->reg_lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
YMFDBGX("ymf_ioctl: cmd 0x%x(GETISPACE)\n", cmd);
abinfo.fragstotal = dmabuf->numfrag;
abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
spin_unlock_irqrestore(&state->unit->reg_lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_NONBLOCK:
YMFDBGX("ymf_ioctl: cmd 0x%x(NONBLOCK)\n", cmd);
case SNDCTL_DSP_GETCAPS:
YMFDBGX("ymf_ioctl: cmd 0x%x(GETCAPS)\n", cmd);
/* return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
- (int *)arg); */
- return put_user(0, (int *)arg);
+ p); */
+ return put_user(0, p);
case SNDCTL_DSP_GETIPTR:
YMFDBGX("ymf_ioctl: cmd 0x%x(GETIPTR)\n", cmd);
spin_unlock_irqrestore(&state->unit->reg_lock, flags);
YMFDBGX("ymf_ioctl: GETIPTR ptr %d bytes %d\n",
cinfo.ptr, cinfo.bytes);
- return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETOPTR:
YMFDBGX("ymf_ioctl: cmd 0x%x(GETOPTR)\n", cmd);
spin_unlock_irqrestore(&state->unit->reg_lock, flags);
YMFDBGX("ymf_ioctl: GETOPTR ptr %d bytes %d\n",
cinfo.ptr, cinfo.bytes);
- return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
+ return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_SETDUPLEX:
YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd);
case SOUND_PCM_READ_RATE:
YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd);
- return put_user(state->format.rate, (int *)arg);
+ return put_user(state->format.rate, p);
case SOUND_PCM_READ_CHANNELS:
YMFDBGX("ymf_ioctl: cmd 0x%x(READ_CH)\n", cmd);
- return put_user(state->format.voices, (int *)arg);
+ return put_user(state->format.voices, p);
case SOUND_PCM_READ_BITS:
YMFDBGX("ymf_ioctl: cmd 0x%x(READ_BITS)\n", cmd);
- return put_user(AFMT_S16_LE, (int *)arg);
+ return put_user(AFMT_S16_LE, p);
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
}
static long snd_cs4281_BA0_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
long size;
cs4281_t *chip = snd_magic_cast(cs4281_t, entry->private_data, return -ENXIO);
}
static long snd_cs4281_BA1_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
long size;
cs4281_t *chip = snd_magic_cast(cs4281_t, entry->private_data, return -ENXIO);
*/
static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
long size;
snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data;
if ((entry = snd_info_create_card_entry(ins->snd_card, scb->scb_name,
ins->proc_dsp_dir)) != NULL) {
scb_info = kmalloc(sizeof(proc_scb_info_t), GFP_KERNEL);
+ if (!scb_info) {
+ snd_info_free_entry(entry);
+ entry = NULL;
+ goto out;
+ }
+
scb_info->chip = chip;
scb_info->scb_desc = scb;
entry = NULL;
}
}
-
+out:
scb->proc_info = entry;
}
}
static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
unsigned int i;
- snd_ctl_elem_id_t *_id, id;
- emu10k1_fx8010_control_gpr_t *_gctl, gctl;
+ snd_ctl_elem_id_t __user *_id;
+ snd_ctl_elem_id_t id;
+ emu10k1_fx8010_control_gpr_t __user *_gctl;
+ emu10k1_fx8010_control_gpr_t gctl;
for (i = 0, _id = icode->gpr_del_controls;
i < icode->gpr_del_control_count; i++, _id++) {
static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
unsigned int i, j;
- emu10k1_fx8010_control_gpr_t *_gctl, gctl;
+ emu10k1_fx8010_control_gpr_t __user *_gctl;
+ emu10k1_fx8010_control_gpr_t gctl;
snd_emu10k1_fx8010_ctl_t *ctl, nctl;
snd_kcontrol_new_t knew;
snd_kcontrol_t *kctl;
static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
{
unsigned int i;
- snd_ctl_elem_id_t *_id, id;
+ snd_ctl_elem_id_t id;
+ snd_ctl_elem_id_t __user *_id;
snd_emu10k1_fx8010_ctl_t *ctl;
snd_card_t *card = emu->card;
{
unsigned int i = 0, j;
unsigned int total = 0;
- emu10k1_fx8010_control_gpr_t *_gctl, gctl;
+ emu10k1_fx8010_control_gpr_t gctl;
+ emu10k1_fx8010_control_gpr_t __user *_gctl;
snd_emu10k1_fx8010_ctl_t *ctl;
snd_ctl_elem_id_t *id;
struct list_head *list;
emu10k1_fx8010_code_t *icode;
emu10k1_fx8010_pcm_t *ipcm;
unsigned int addr;
+ void __user *argp = (void __user *)arg;
int res;
switch (cmd) {
kfree(info);
return res;
}
- if (copy_to_user((void *)arg, info, sizeof(*info))) {
+ if (copy_to_user(argp, info, sizeof(*info))) {
kfree(info);
return -EFAULT;
}
icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
if (icode == NULL)
return -ENOMEM;
- if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
+ if (copy_from_user(icode, argp, sizeof(*icode))) {
kfree(icode);
return -EFAULT;
}
icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
if (icode == NULL)
return -ENOMEM;
- if (copy_from_user(icode, (void *)arg, sizeof(*icode))) {
+ if (copy_from_user(icode, argp, sizeof(*icode))) {
kfree(icode);
return -EFAULT;
}
res = snd_emu10k1_icode_peek(emu, icode);
- if (res == 0 && copy_to_user((void *)arg, icode, sizeof(*icode))) {
+ if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
kfree(icode);
return -EFAULT;
}
ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
if (ipcm == NULL)
return -ENOMEM;
- if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
+ if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
kfree(ipcm);
return -EFAULT;
}
ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
if (ipcm == NULL)
return -ENOMEM;
- if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
+ if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
kfree(ipcm);
return -EFAULT;
}
res = snd_emu10k1_ipcm_peek(emu, ipcm);
- if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) {
+ if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
kfree(ipcm);
return -EFAULT;
}
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (get_user(addr, (unsigned int *)arg))
+ if (get_user(addr, (unsigned int __user *)argp))
return -EFAULT;
down(&emu->fx8010.lock);
res = snd_emu10k1_fx8010_tram_setup(emu, addr);
case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (get_user(addr, (unsigned int *)arg))
+ if (get_user(addr, (unsigned int __user *)argp))
return -EFAULT;
if (addr > 0x1ff)
return -EINVAL;
addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
else
addr = snd_emu10k1_ptr_read(emu, DBG, 0);
- if (put_user(addr, (unsigned int *)arg))
+ if (put_user(addr, (unsigned int __user *)argp))
return -EFAULT;
return 0;
}
#define TOTAL_SIZE_CODE (0x200*8)
static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
long size;
emu10k1_t *emu = snd_magic_cast(emu10k1_t, entry->private_data, return -ENXIO);
static int snd_es1938_capture_copy(snd_pcm_substream_t *substream,
int channel,
snd_pcm_uframes_t pos,
- void *dst,
+ void __user *dst,
snd_pcm_uframes_t count)
{
snd_pcm_runtime_t *runtime = substream->runtime;
} else {
if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
return -EFAULT;
- if (put_user(runtime->dma_area[0], ((unsigned char *)dst) + count - 1))
+ if (put_user(runtime->dma_area[0], ((unsigned char __user *)dst) + count - 1))
return -EFAULT;
}
return 0;
return 0;
}
-static int snd_korg1212_copy_to(korg1212_t *korg1212, void *dst, int pos, int count, int offset, int size)
+static int snd_korg1212_copy_to(korg1212_t *korg1212, void __user *dst, int pos, int count, int offset, int size)
{
KorgAudioFrame * src = korg1212->recordDataBufsPtr[0].bufferData + pos;
int i, rc;
return -EFAULT;
}
#endif
- rc = copy_to_user((void*) dst + offset, src, size);
+ rc = copy_to_user(dst + offset, src, size);
if (rc) {
#if K1212_DEBUG_LEVEL > 0
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
return 0;
}
-static int snd_korg1212_copy_from(korg1212_t *korg1212, void *src, int pos, int count, int offset, int size)
+static int snd_korg1212_copy_from(korg1212_t *korg1212, void __user *src, int pos, int count, int offset, int size)
{
KorgAudioFrame * dst = korg1212->playDataBufsPtr[0].bufferData + pos;
int i, rc;
static int snd_korg1212_playback_copy(snd_pcm_substream_t *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *src,
+ void __user *src,
snd_pcm_uframes_t count)
{
korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
static int snd_korg1212_capture_copy(snd_pcm_substream_t *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *dst,
+ void __user *dst,
snd_pcm_uframes_t count)
{
korg1212_t *korg1212 = _snd_pcm_substream_chip(substream);
mixart_BA0 proc interface for BAR 0 - read callback
*/
static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
mixart_mgr_t *mgr = snd_magic_cast(mixart_mgr_t, entry->private_data, return -ENXIO);
mixart_BA1 proc interface for BAR 1 - read callback
*/
static long snd_mixart_BA1_read(snd_info_entry_t *entry, void *file_private_data,
- struct file *file, char *buf, long count)
+ struct file *file, char __user *buf, long count)
{
mixart_mgr_t *mgr = snd_magic_cast(mixart_mgr_t, entry->private_data, return -ENXIO);
snd_nm256_playback_copy(snd_pcm_substream_t *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *src,
+ void __user *src,
snd_pcm_uframes_t count)
{
snd_pcm_runtime_t *runtime = substream->runtime;
static int snd_rme32_playback_copy(snd_pcm_substream_t * substream, int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *src, snd_pcm_uframes_t count)
+ void __user *src, snd_pcm_uframes_t count)
{
rme32_t *rme32 = _snd_pcm_substream_chip(substream);
count <<= rme32->playback_frlog;
static int snd_rme32_capture_copy(snd_pcm_substream_t * substream, int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *dst, snd_pcm_uframes_t count)
+ void __user *dst, snd_pcm_uframes_t count)
{
rme32_t *rme32 = _snd_pcm_substream_chip(substream);
count <<= rme32->capture_frlog;
snd_rme96_playback_copy(snd_pcm_substream_t *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *src,
+ void __user *src,
snd_pcm_uframes_t count)
{
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
snd_rme96_capture_copy(snd_pcm_substream_t *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
- void *dst,
+ void __user *dst,
snd_pcm_uframes_t count)
{
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
{
/* the hardware already does the relevant bit-mask with 0xff */
if (id) {
- return hdsp_write(hdsp, HDSP_midiDataOut1, val);
+ hdsp_write(hdsp, HDSP_midiDataOut1, val);
} else {
- return hdsp_write(hdsp, HDSP_midiDataOut0, val);
+ hdsp_write(hdsp, HDSP_midiDataOut0, val);
}
}
}
static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
- snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count)
+ snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
{
hdsp_t *hdsp = _snd_pcm_substream_chip(substream);
char *channel_buf;
}
static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel,
- snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count)
+ snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
{
hdsp_t *hdsp = _snd_pcm_substream_chip(substream);
char *channel_buf;
static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg)
{
hdsp_t *hdsp = (hdsp_t *)hw->private_data;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
- hdsp_peak_rms_t *peak_rms;
+ hdsp_peak_rms_t __user *peak_rms;
int i;
if (hdsp->io_type == H9652) {
int doublespeed = 0;
if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
doublespeed = 1;
- peak_rms = (hdsp_peak_rms_t *)arg;
+ peak_rms = (hdsp_peak_rms_t __user *)arg;
for (i = 0; i < 26; ++i) {
if (!(doublespeed && (i & 4))) {
- if (copy_to_user_fromio((void *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0)
+ if (copy_to_user_fromio((void __user *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0)
return -EFAULT;
- if (copy_to_user_fromio((void *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
+ if (copy_to_user_fromio((void __user *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
return -EFAULT;
- if (copy_to_user_fromio((void *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
+ if (copy_to_user_fromio((void __user *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0)
return -EFAULT;
rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8) & 0xFFFFFF00;
rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8+4) & 0xFFFFFF00;
rms_high += (rms_low >> 24);
rms_low <<= 8;
- if (copy_to_user((void *)peak_rms->input_rms+i*8, &rms_low, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &rms_low, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0)
return -EFAULT;
rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
rms_high += (rms_low >> 24);
rms_low <<= 8;
- if (copy_to_user((void *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0)
return -EFAULT;
rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00;
rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00;
rms_high += (rms_low >> 24);
rms_low <<= 8;
- if (copy_to_user((void *)peak_rms->output_rms+i*8, &rms_low, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &rms_low, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0)
return -EFAULT;
}
}
if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
doublespeed = 1;
m = (hdsp_9632_meters_t *)(hdsp->iobase+HDSP_9632_metersBase);
- peak_rms = (hdsp_peak_rms_t *)arg;
+ peak_rms = (hdsp_peak_rms_t __user *)arg;
for (i = 0, j = 0; i < 16; ++i, ++j) {
- if (copy_to_user((void *)peak_rms->input_peaks+i*4, &(m->input_peak[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, &(m->input_peak[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->playback_peaks+i*4, &(m->playback_peak[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, &(m->playback_peak[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->output_peaks+i*4, &(m->output_peak[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, &(m->output_peak[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->input_rms+i*8, &(m->input_rms_low[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &(m->input_rms_low[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->playback_rms+i*8, &(m->playback_rms_low[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &(m->playback_rms_low[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->output_rms+i*8, &(m->output_rms_low[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &(m->output_rms_low[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->input_rms+i*8+4, &(m->input_rms_high[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &(m->input_rms_high[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, &(m->playback_rms_high[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &(m->playback_rms_high[j]), 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->output_rms+i*8+4, &(m->output_rms_high[j]), 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &(m->output_rms_high[j]), 4) != 0)
return -EFAULT;
if (doublespeed && i == 3) i += 4;
}
snd_printk("firmware needs to be uploaded to the card.\n");
return -EINVAL;
}
- peak_rms = (hdsp_peak_rms_t *)arg;
+ peak_rms = (hdsp_peak_rms_t __user *)arg;
for (i = 0; i < 26; ++i) {
- if (copy_to_user((void *)peak_rms->playback_peaks+i*4, (void *)hdsp->iobase+HDSP_playbackPeakLevel+i*4, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, (void *)hdsp->iobase+HDSP_playbackPeakLevel+i*4, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->input_peaks+i*4, (void *)hdsp->iobase+HDSP_inputPeakLevel+i*4, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, (void *)hdsp->iobase+HDSP_inputPeakLevel+i*4, 4) != 0)
return -EFAULT;
}
for (i = 0; i < 26; ++i) {
- if (copy_to_user((void *)peak_rms->playback_rms+i*8+4, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->playback_rms+i*8, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8+4, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8+4, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->input_rms+i*8+4, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8, 4) != 0)
return -EFAULT;
- if (copy_to_user((void *)peak_rms->input_rms+i*8, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8+4, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->input_rms+i*8, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8+4, 4) != 0)
return -EFAULT;
}
for (i = 0; i < 28; ++i) {
- if (copy_to_user((void *)peak_rms->output_peaks+i*4, (void *)hdsp->iobase+HDSP_outputPeakLevel+i*4, 4) != 0)
+ if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, (void *)hdsp->iobase+HDSP_outputPeakLevel+i*4, 4) != 0)
return -EFAULT;
}
break;
info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
}
spin_unlock_irqrestore(&hdsp->lock, flags);
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
break;
}
if (hdsp->io_type != H9632) return -EINVAL;
h9632_aeb.aebi = hdsp->ss_in_channels - H9632_SS_CHANNELS;
h9632_aeb.aebo = hdsp->ss_out_channels - H9632_SS_CHANNELS;
- if (copy_to_user((void *)arg, &h9632_aeb, sizeof(h9632_aeb)))
+ if (copy_to_user(argp, &h9632_aeb, sizeof(h9632_aeb)))
return -EFAULT;
break;
}
}
hdsp_version.io_type = hdsp->io_type;
hdsp_version.firmware_rev = hdsp->firmware_rev;
- if ((err = copy_to_user((void *)arg, &hdsp_version, sizeof(hdsp_version)))) {
+ if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
return -EFAULT;
}
break;
}
case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
- hdsp_firmware_t *firmware;
- unsigned long *firmware_data;
+ hdsp_firmware_t __user *firmware;
+ unsigned long __user *firmware_data;
int err;
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
if (hdsp->io_type == Undefined) return -EINVAL;
snd_printk("initializing firmware upload\n");
- firmware = (hdsp_firmware_t *)arg;
+ firmware = (hdsp_firmware_t __user *)argp;
if (get_user(firmware_data, &firmware->firmware_data)) {
return -EFAULT;
break;
}
case SNDRV_HDSP_IOCTL_GET_MIXER: {
- hdsp_mixer_t *mixer;
-
- mixer = (hdsp_mixer_t *)arg;
+ hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp;
if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
return -EFAULT;
break;
}
static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel,
- snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count)
+ snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
{
rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
char *channel_buf;
}
static int snd_rme9652_capture_copy(snd_pcm_substream_t *substream, int channel,
- snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count)
+ snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
{
rme9652_t *rme9652 = _snd_pcm_substream_chip(substream);
char *channel_buf;
/*
* copy_from_user(blk + offset, data, size)
*/
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char *data, int size)
+int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
{
int page, nextofs, end_offset, temp, temp1;
*/
static int snd_trident_simple_put_sample(void *private_data, simple_instrument_t * instr,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
trident_t *trident = snd_magic_cast(trident_t, private_data, return -ENXIO);
int size = instr->size;
}
static int snd_trident_simple_get_sample(void *private_data, simple_instrument_t * instr,
- char *data, long len, int atomic)
+ char __user *data, long len, int atomic)
{
//trident_t *trident = snd_magic_cast(trident_t, private_data, return -ENXIO);
int size = instr->size;
{
unsigned int i;
unsigned int port;
- unsigned char *image, data;
+ unsigned char data;
+ unsigned char __user *image;
/* XILINX reset (wait at least 1 milisecond between reset on and off). */
vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
unsigned int i;
int c;
int regCSUER, regRUER;
- unsigned char *image, data;
+ unsigned char __user *image;
+ unsigned char data;
/* Switch to programmation mode */
chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
/* Prototypes for static functions */
-static int open_patch(snd_sf_list_t *sflist, const char *data, int count, int client);
+static int open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client);
static snd_soundfont_t *newsf(snd_sf_list_t *sflist, int type, char *name);
static int is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name);
static int close_patch(snd_sf_list_t *sflist);