Jody McIntyre 2006-01-05 08:03:40 -05:00
commit 0a75c23a00
1256 changed files with 87998 additions and 44890 deletions

1
.gitignore vendored
View File

@ -23,6 +23,7 @@ Module.symvers
# Generated include files # Generated include files
# #
include/asm include/asm
include/asm-*/asm-offsets.h
include/config include/config
include/linux/autoconf.h include/linux/autoconf.h
include/linux/compile.h include/linux/compile.h

View File

@ -1883,6 +1883,7 @@ N: Jaya Kumar
E: jayalk@intworks.biz E: jayalk@intworks.biz
W: http://www.intworks.biz W: http://www.intworks.biz
D: Arc monochrome LCD framebuffer driver, x86 reboot fixups D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
D: pirq addr, CS5535 alsa audio driver
S: Gurgaon, India S: Gurgaon, India
S: Kuala Lumpur, Malaysia S: Kuala Lumpur, Malaysia

View File

@ -253,6 +253,7 @@
!Edrivers/usb/core/urb.c !Edrivers/usb/core/urb.c
!Edrivers/usb/core/message.c !Edrivers/usb/core/message.c
!Edrivers/usb/core/file.c !Edrivers/usb/core/file.c
!Edrivers/usb/core/driver.c
!Edrivers/usb/core/usb.c !Edrivers/usb/core/usb.c
!Edrivers/usb/core/hub.c !Edrivers/usb/core/hub.c
</chapter> </chapter>

View File

@ -158,7 +158,7 @@ Even if the maintainer did not respond in step #4, make sure to ALWAYS
copy the maintainer when you change their code. copy the maintainer when you change their code.
For small patches you may want to CC the Trivial Patch Monkey For small patches you may want to CC the Trivial Patch Monkey
trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial" trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
patches. Trivial patches must qualify for one of the following rules: patches. Trivial patches must qualify for one of the following rules:
Spelling fixes in documentation Spelling fixes in documentation
Spelling fixes which could break grep(1). Spelling fixes which could break grep(1).
@ -171,7 +171,7 @@ patches. Trivial patches must qualify for one of the following rules:
since people copy, as long as it's trivial) since people copy, as long as it's trivial)
Any fix by the author/maintainer of the file. (ie. patch monkey Any fix by the author/maintainer of the file. (ie. patch monkey
in re-transmission mode) in re-transmission mode)
URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/> URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>

View File

@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this
document: document:
Christoph Hellwig <hch@infradead.org> Christoph Hellwig <hch@infradead.org>
Arjan van de Ven <arjanv@redhat.com> Arjan van de Ven <arjanv@redhat.com>
Randy Dunlap <rddunlap@osdl.org> Randy Dunlap <rdunlap@xenotime.net>
Andre Hedrick <andre@linux-ide.org> Andre Hedrick <andre@linux-ide.org>
The following people helped with fixes/contributions to the bio patches The following people helped with fixes/contributions to the bio patches

View File

@ -27,6 +27,7 @@ Contents:
2.2 Powersave 2.2 Powersave
2.3 Userspace 2.3 Userspace
2.4 Ondemand 2.4 Ondemand
2.5 Conservative
3. The Governor Interface in the CPUfreq Core 3. The Governor Interface in the CPUfreq Core
@ -110,9 +111,64 @@ directory.
The CPUfreq govenor "ondemand" sets the CPU depending on the The CPUfreq govenor "ondemand" sets the CPU depending on the
current usage. To do this the CPU must have the capability to current usage. To do this the CPU must have the capability to
switch the frequency very fast. switch the frequency very quickly. There are a number of sysfs file
accessible parameters:
sampling_rate: measured in uS (10^-6 seconds), this is how often you
want the kernel to look at the CPU usage and to make decisions on
what to do about the frequency. Typically this is set to values of
around '10000' or more.
show_sampling_rate_(min|max): the minimum and maximum sampling rates
available that you may set 'sampling_rate' to.
up_threshold: defines what the average CPU usaged between the samplings
of 'sampling_rate' needs to be for the kernel to make a decision on
whether it should increase the frequency. For example when it is set
to its default value of '80' it means that between the checking
intervals the CPU needs to be on average more than 80% in use to then
decide that the CPU frequency needs to be increased.
sampling_down_factor: this parameter controls the rate that the CPU
makes a decision on when to decrease the frequency. When set to its
default value of '5' it means that at 1/5 the sampling_rate the kernel
makes a decision to lower the frequency. Five "lower rate" decisions
have to be made in a row before the CPU frequency is actually lower.
If set to '1' then the frequency decreases as quickly as it increases,
if set to '2' it decreases at half the rate of the increase.
ignore_nice_load: this parameter takes a value of '0' or '1', when set
to '0' (its default) then all processes are counted towards towards the
'cpu utilisation' value. When set to '1' then processes that are
run with a 'nice' value will not count (and thus be ignored) in the
overal usage calculation. This is useful if you are running a CPU
intensive calculation on your laptop that you do not care how long it
takes to complete as you can 'nice' it and prevent it from taking part
in the deciding process of whether to increase your CPU frequency.
2.5 Conservative
----------------
The CPUfreq governor "conservative", much like the "ondemand"
governor, sets the CPU depending on the current usage. It differs in
behaviour in that it gracefully increases and decreases the CPU speed
rather than jumping to max speed the moment there is any load on the
CPU. This behaviour more suitable in a battery powered environment.
The governor is tweaked in the same manner as the "ondemand" governor
through sysfs with the addition of:
freq_step: this describes what percentage steps the cpu freq should be
increased and decreased smoothly by. By default the cpu frequency will
increase in 5% chunks of your maximum cpu frequency. You can change this
value to anywhere between 0 and 100 where '0' will effectively lock your
CPU at a speed regardless of its load whilst '100' will, in theory, make
it behave identically to the "ondemand" governor.
down_threshold: same as the 'up_threshold' found for the "ondemand"
governor but for the opposite direction. For example when set to its
default value of '20' it means that if the CPU usage needs to be below
20% between samples to have the frequency decreased.
3. The Governor Interface in the CPUfreq Core 3. The Governor Interface in the CPUfreq Core
============================================= =============================================

View File

@ -18,8 +18,6 @@ devfs/
- directory containing devfs documentation. - directory containing devfs documentation.
ext2.txt ext2.txt
- info, mount options and specifications for the Ext2 filesystem. - info, mount options and specifications for the Ext2 filesystem.
fat_cvf.txt
- info on the Compressed Volume Files extension to the FAT filesystem
hpfs.txt hpfs.txt
- info and mount options for the OS/2 HPFS. - info and mount options for the OS/2 HPFS.
isofs.txt isofs.txt

View File

@ -162,9 +162,8 @@ get_sb() method fills in is the "s_op" field. This is a pointer to
a "struct super_operations" which describes the next level of the a "struct super_operations" which describes the next level of the
filesystem implementation. filesystem implementation.
Usually, a filesystem uses generic one of the generic get_sb() Usually, a filesystem uses one of the generic get_sb() implementations
implementations and provides a fill_super() method instead. The and provides a fill_super() method instead. The generic methods are:
generic methods are:
get_sb_bdev: mount a filesystem residing on a block device get_sb_bdev: mount a filesystem residing on a block device

View File

@ -38,7 +38,7 @@ included in the kernel tree.
What is covered within this file is mainly information to authors What is covered within this file is mainly information to authors
of modules. The author of an external modules should supply of modules. The author of an external modules should supply
a makefile that hides most of the complexity so one only has to type a makefile that hides most of the complexity so one only has to type
'make' to buld the module. A complete example will be present in 'make' to build the module. A complete example will be present in
chapter ¤. Creating a kbuild file for an external module". chapter ¤. Creating a kbuild file for an external module".
@ -69,7 +69,7 @@ when building an external module.
--- 2.2 Available targets --- 2.2 Available targets
$KDIR refers to path to kernel source top-level directory $KDIR refers to the path to the kernel source top-level directory
make -C $KDIR M=`pwd` make -C $KDIR M=`pwd`
Will build the module(s) located in current directory. Will build the module(s) located in current directory.
@ -87,11 +87,11 @@ when building an external module.
make -C $KDIR M=$PWD modules_install make -C $KDIR M=$PWD modules_install
Install the external module(s). Install the external module(s).
Installation default is in /lib/modules/<kernel-version>/extra, Installation default is in /lib/modules/<kernel-version>/extra,
but may be prefixed with INSTALL_MOD_PATH - see separate chater. but may be prefixed with INSTALL_MOD_PATH - see separate chapter.
make -C $KDIR M=$PWD clean make -C $KDIR M=$PWD clean
Remove all generated files for the module - the kernel Remove all generated files for the module - the kernel
source directory is not moddified. source directory is not modified.
make -C $KDIR M=`pwd` help make -C $KDIR M=`pwd` help
help will list the available target when building external help will list the available target when building external
@ -99,7 +99,7 @@ when building an external module.
--- 2.3 Available options: --- 2.3 Available options:
$KDIR refer to path to kernel src $KDIR refers to the path to the kernel source top-level directory
make -C $KDIR make -C $KDIR
Used to specify where to find the kernel source. Used to specify where to find the kernel source.
@ -206,11 +206,11 @@ following files:
KERNELDIR := /lib/modules/`uname -r`/build KERNELDIR := /lib/modules/`uname -r`/build
all:: all::
$(MAKE) -C $KERNELDIR M=`pwd` $@ $(MAKE) -C $(KERNELDIR) M=`pwd` $@
# Module specific targets # Module specific targets
genbin: genbin:
echo "X" > 8123_bini.o_shipped echo "X" > 8123_bin.o_shipped
endif endif
@ -341,13 +341,13 @@ directory and therefore needs to deal with this in their kbuild file.
EXTRA_CFLAGS := -Iinclude EXTRA_CFLAGS := -Iinclude
8123-y := 8123_if.o 8123_pci.o 8123_bin.o 8123-y := 8123_if.o 8123_pci.o 8123_bin.o
Note that in the assingment there is no space between -I and the path. Note that in the assignment there is no space between -I and the path.
This is a kbuild limitation and no space must be present. This is a kbuild limitation: there must be no space present.
=== 6. Module installation === 6. Module installation
Modules which are included in the kernel is installed in the directory: Modules which are included in the kernel are installed in the directory:
/lib/modules/$(KERNELRELEASE)/kernel /lib/modules/$(KERNELRELEASE)/kernel
@ -365,7 +365,7 @@ External modules are installed in the directory:
=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
example above be specified on the commandline when calling make. example above be specified on the command line when calling make.
INSTALL_MOD_PATH has effect both when installing modules included in INSTALL_MOD_PATH has effect both when installing modules included in
the kernel as well as when installing external modules. the kernel as well as when installing external modules.
@ -384,7 +384,7 @@ External modules are installed in the directory:
=== 7. Module versioning === 7. Module versioning
Module versioning are enabled by the CONFIG_MODVERSIONS tag. Module versioning is enabled by the CONFIG_MODVERSIONS tag.
Module versioning is used as a simple ABI consistency check. The Module Module versioning is used as a simple ABI consistency check. The Module
versioning creates a CRC value of the full prototype for an exported symbol and versioning creates a CRC value of the full prototype for an exported symbol and

View File

@ -633,6 +633,14 @@ running once the system is up.
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
Format: <irq> Format: <irq>
combined_mode= [HW] control which driver uses IDE ports in combined
mode: legacy IDE driver, libata, or both
(in the libata case, libata.atapi_enabled=1 may be
useful as well). Note that using the ide or libata
options may affect your device naming (e.g. by
changing hdc to sdb).
Format: combined (default), ide, or libata
inttest= [IA64] inttest= [IA64]
io7= [HW] IO7 for Marvel based alpha systems io7= [HW] IO7 for Marvel based alpha systems

View File

@ -0,0 +1,72 @@
The Gianfar Ethernet Driver
Sysfs File description
Author: Andy Fleming <afleming@freescale.com>
Updated: 2005-07-28
SYSFS
Several of the features of the gianfar driver are controlled
through sysfs files. These are:
bd_stash:
To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
bd_stash, echo 'off' or '0' to disable
rx_stash_len:
To stash the first n bytes of the packet in L2, echo the number
of bytes to buf_stash_len. echo 0 to disable.
WARNING: You could really screw these up if you set them too low or high!
fifo_threshold:
To change the number of bytes the controller needs in the
fifo before it starts transmission, echo the number of bytes to
fifo_thresh. Range should be 0-511.
fifo_starve:
When the FIFO has less than this many bytes during a transmit, it
enters starve mode, and increases the priority of TX memory
transactions. To change, echo the number of bytes to
fifo_starve. Range should be 0-511.
fifo_starve_off:
Once in starve mode, the FIFO remains there until it has this
many bytes. To change, echo the number of bytes to
fifo_starve_off. Range should be 0-511.
CHECKSUM OFFLOADING
The eTSEC controller (first included in parts from late 2005 like
the 8548) has the ability to perform TCP, UDP, and IP checksums
in hardware. The Linux kernel only offloads the TCP and UDP
checksums (and always performs the pseudo header checksums), so
the driver only supports checksumming for TCP/IP and UDP/IP
packets. Use ethtool to enable or disable this feature for RX
and TX.
VLAN
In order to use VLAN, please consult Linux documentation on
configuring VLANs. The gianfar driver supports hardware insertion and
extraction of VLAN headers, but not filtering. Filtering will be
done by the kernel.
MULTICASTING
The gianfar driver supports using the group hash table on the
TSEC (and the extended hash table on the eTSEC) for multicast
filtering. On the eTSEC, the exact-match MAC registers are used
before the hash tables. See Linux documentation on how to join
multicast groups.
PADDING
The gianfar driver supports padding received frames with 2 bytes
to align the IP header to a 16-byte boundary, when supported by
hardware.
ETHTOOL
The gianfar driver supports the use of ethtool for many
configuration options. You must run ethtool only on currently
open interfaces. See ethtool documentation for details.

View File

@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER
for the hash secret) for IP fragments. for the hash secret) for IP fragments.
Default: 600 Default: 600
ipfrag_max_dist - INTEGER
ipfrag_max_dist is a non-negative integer value which defines the
maximum "disorder" which is allowed among fragments which share a
common IP source address. Note that reordering of packets is
not unusual, but if a large number of fragments arrive from a source
IP address while a particular fragment queue remains incomplete, it
probably indicates that one or more fragments belonging to that queue
have been lost. When ipfrag_max_dist is positive, an additional check
is done on fragments before they are added to a reassembly queue - if
ipfrag_max_dist (or more) fragments have arrived from a particular IP
address between additions to any IP fragment queue using that source
address, it's presumed that one or more fragments in the queue are
lost. The existing fragment queue will be dropped, and a new one
started. An ipfrag_max_dist value of zero disables this check.
Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
result in unnecessarily dropping fragment queues when normal
reordering of packets occurs, which could lead to poor application
performance. Using a very large value, e.g. 50000, increases the
likelihood of incorrectly reassembling IP fragments that originate
from different IP datagrams, which could result in data corruption.
Default: 64
INET peer storage: INET peer storage:
inet_peer_threshold - INTEGER inet_peer_threshold - INTEGER

View File

@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
At this time, a generic EEH recovery mechanism has been implemented, At this time, a generic EEH recovery mechanism has been implemented,
so that individual device drivers do not need to be modified to support so that individual device drivers do not need to be modified to support
EEH recovery. This generic mechanism piggy-backs on the PCI hotplug EEH recovery. This generic mechanism piggy-backs on the PCI hotplug
infrastructure, and percolates events up through the hotplug/udev infrastructure, and percolates events up through the userspace/udev
infrastructure. Followiing is a detailed description of how this is infrastructure. Followiing is a detailed description of how this is
accomplished. accomplished.
@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in
drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events(). drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter(). It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
This last call causes the device driver for the card to be stopped, This last call causes the device driver for the card to be stopped,
which causes hotplug events to go out to user space. This triggers which causes uevents to go out to user space. This triggers
user-space scripts that might issue commands such as "ifdown eth0" user-space scripts that might issue commands such as "ifdown eth0"
for ethernet cards, and so on. This handler then sleeps for 5 seconds, for ethernet cards, and so on. This handler then sleeps for 5 seconds,
hoping to give the user-space scripts enough time to complete. hoping to give the user-space scripts enough time to complete.
@ -258,29 +258,30 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
calls calls
pci_destroy_dev (struct pci_dev *) { pci_destroy_dev (struct pci_dev *) {
calls calls
device_unregister (&dev->dev) { // in /drivers/base/core.c device_unregister (&dev->dev) { // in /drivers/base/core.c
calls calls
device_del(struct device * dev) { // in /drivers/base/core.c device_del(struct device * dev) { // in /drivers/base/core.c
calls calls
kobject_del() { //in /libs/kobject.c kobject_del() { //in /libs/kobject.c
calls calls
kobject_hotplug() { // in /libs/kobject.c kobject_uevent() { // in /libs/kobject.c
calls calls
kset_hotplug() { // in /lib/kobject.c kset_uevent() { // in /lib/kobject.c
calls calls
kset->hotplug_ops->hotplug() which is really just kset->uevent_ops->uevent() // which is really just
a call to a call to
dev_hotplug() { // in /drivers/base/core.c dev_uevent() { // in /drivers/base/core.c
calls calls
dev->bus->hotplug() which is really just a call to dev->bus->uevent() which is really just a call to
pci_hotplug () { // in drivers/pci/hotplug.c pci_uevent () { // in drivers/pci/hotplug.c
which prints device name, etc.... which prints device name, etc....
} }
} }
then kset_hotplug() calls then kobject_uevent() sends a netlink uevent to userspace
call_usermodehelper () with --> userspace uevent
argv[0]=hotplug_path[] which is "/sbin/hotplug" (during early boot, nobody listens to netlink events and
--> event to userspace, kobject_uevent() executes uevent_helper[], which runs the
event process /sbin/hotplug)
} }
} }
kobject_del() then calls sysfs_remove_dir(), which would kobject_del() then calls sysfs_remove_dir(), which would

View File

@ -1,3 +1,38 @@
Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
1. Sorted out PCI IDs to remove megaraid support overlaps.
Based on the patch from Daniel, sorted out PCI IDs along with
charactor node name change from 'megadev' to 'megadev_legacy' to avoid
conflict.
---
Hopefully we'll be getting the build restriction zapped much sooner,
but we should also be thinking about totally removing the hardware
support overlap in the megaraid drivers.
This patch pencils in a date of Feb 06 for this, and performs some
printk abuse in hope that existing legacy users might pick up on what's
going on.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
---
2. Fixed a issue: megaraid always fails to reset handler.
---
I found that the megaraid driver always fails to reset the
adapter with the following message:
megaraid: resetting the host...
megaraid mbox: reset sequence completed successfully
megaraid: fast sync command timed out
megaraid: reservation reset failed
when the "Cluster mode" of the adapter BIOS is enabled.
So, whenever the reset occurs, the adapter goes to
offline and just become unavailable.
Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
---
Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com> Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module) Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module) Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)

View File

@ -150,7 +150,8 @@ scsi devices of which only the first 2 respond:
LLD mid level LLD LLD mid level LLD
===-------------------=========--------------------===------ ===-------------------=========--------------------===------
scsi_host_alloc() --> scsi_host_alloc() -->
scsi_add_host() --------+ scsi_add_host() ---->
scsi_scan_host() -------+
| |
slave_alloc() slave_alloc()
slave_configure() --> scsi_adjust_queue_depth() slave_configure() --> scsi_adjust_queue_depth()
@ -196,7 +197,7 @@ of the issues involved. See the section on reference counting below.
The hotplug concept may be extended to SCSI devices. Currently, when an The hotplug concept may be extended to SCSI devices. Currently, when an
HBA is added, the scsi_add_host() function causes a scan for SCSI devices HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
attached to the HBA's SCSI transport. On newer SCSI transports the HBA attached to the HBA's SCSI transport. On newer SCSI transports the HBA
may become aware of a new SCSI device _after_ the scan has completed. may become aware of a new SCSI device _after_ the scan has completed.
An LLD can use this sequence to make the mid level aware of a SCSI device: An LLD can use this sequence to make the mid level aware of a SCSI device:
@ -372,7 +373,7 @@ names all start with "scsi_".
Summary: Summary:
scsi_activate_tcq - turn on tag command queueing scsi_activate_tcq - turn on tag command queueing
scsi_add_device - creates new scsi device (lu) instance scsi_add_device - creates new scsi device (lu) instance
scsi_add_host - perform sysfs registration and SCSI bus scan. scsi_add_host - perform sysfs registration and set up transport class
scsi_adjust_queue_depth - change the queue depth on a SCSI device scsi_adjust_queue_depth - change the queue depth on a SCSI device
scsi_assign_lock - replace default host_lock with given lock scsi_assign_lock - replace default host_lock with given lock
scsi_bios_ptable - return copy of block device's partition table scsi_bios_ptable - return copy of block device's partition table
@ -386,6 +387,7 @@ Summary:
scsi_remove_device - detach and remove a SCSI device scsi_remove_device - detach and remove a SCSI device
scsi_remove_host - detach and remove all SCSI devices owned by host scsi_remove_host - detach and remove all SCSI devices owned by host
scsi_report_bus_reset - report scsi _bus_ reset observed scsi_report_bus_reset - report scsi _bus_ reset observed
scsi_scan_host - scan SCSI bus
scsi_track_queue_full - track successive QUEUE_FULL events scsi_track_queue_full - track successive QUEUE_FULL events
scsi_unblock_requests - allow further commands to be queued to given host scsi_unblock_requests - allow further commands to be queued to given host
scsi_unregister - [calls scsi_host_put()] scsi_unregister - [calls scsi_host_put()]
@ -425,10 +427,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
* Might block: yes * Might block: yes
* *
* Notes: This call is usually performed internally during a scsi * Notes: This call is usually performed internally during a scsi
* bus scan when an HBA is added (i.e. scsi_add_host()). So it * bus scan when an HBA is added (i.e. scsi_scan_host()). So it
* should only be called if the HBA becomes aware of a new scsi * should only be called if the HBA becomes aware of a new scsi
* device (lu) after scsi_add_host() has completed. If successful * device (lu) after scsi_scan_host() has completed. If successful
* this call we lead to slave_alloc() and slave_configure() callbacks * this call can lead to slave_alloc() and slave_configure() callbacks
* into the LLD. * into the LLD.
* *
* Defined in: drivers/scsi/scsi_scan.c * Defined in: drivers/scsi/scsi_scan.c
@ -439,7 +441,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
/** /**
* scsi_add_host - perform sysfs registration and SCSI bus scan. * scsi_add_host - perform sysfs registration and set up transport class
* @shost: pointer to scsi host instance * @shost: pointer to scsi host instance
* @dev: pointer to struct device of type scsi class * @dev: pointer to struct device of type scsi class
* *
@ -448,7 +450,11 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
* Might block: no * Might block: no
* *
* Notes: Only required in "hotplug initialization model" after a * Notes: Only required in "hotplug initialization model" after a
* successful call to scsi_host_alloc(). * successful call to scsi_host_alloc(). This function does not
* scan the bus; this can be done by calling scsi_scan_host() or
* in some other transport-specific way. The LLD must set up
* the transport template before calling this function and may only
* access the transport class data after this function has been called.
* *
* Defined in: drivers/scsi/hosts.c * Defined in: drivers/scsi/hosts.c
**/ **/
@ -559,7 +565,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
* area for the LLD's exclusive use. * area for the LLD's exclusive use.
* Both associated refcounting objects have their refcount set to 1. * Both associated refcounting objects have their refcount set to 1.
* Full registration (in sysfs) and a bus scan are performed later when * Full registration (in sysfs) and a bus scan are performed later when
* scsi_add_host() is called. * scsi_add_host() and scsi_scan_host() are called.
* *
* Defined in: drivers/scsi/hosts.c . * Defined in: drivers/scsi/hosts.c .
**/ **/
@ -698,6 +704,19 @@ int scsi_remove_host(struct Scsi_Host *shost)
void scsi_report_bus_reset(struct Scsi_Host * shost, int channel) void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
/**
* scsi_scan_host - scan SCSI bus
* @shost: a pointer to a scsi host instance
*
* Might block: yes
*
* Notes: Should be called after scsi_add_host()
*
* Defined in: drivers/scsi/scsi_scan.c
**/
void scsi_scan_host(struct Scsi_Host *shost)
/** /**
* scsi_track_queue_full - track successive QUEUE_FULL events on given * scsi_track_queue_full - track successive QUEUE_FULL events on given
* device to determine if and when there is a need * device to determine if and when there is a need
@ -1433,7 +1452,7 @@ The following people have contributed to this document:
Christoph Hellwig <hch at infradead dot org> Christoph Hellwig <hch at infradead dot org>
Doug Ledford <dledford at redhat dot com> Doug Ledford <dledford at redhat dot com>
Andries Brouwer <Andries dot Brouwer at cwi dot nl> Andries Brouwer <Andries dot Brouwer at cwi dot nl>
Randy Dunlap <rddunlap at osdl dot org> Randy Dunlap <rdunlap at xenotime dot net>
Alan Stern <stern at rowland dot harvard dot edu> Alan Stern <stern at rowland dot harvard dot edu>

View File

@ -105,7 +105,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Each of top level sound card module takes the following options. Each of top level sound card module takes the following options.
index - index (slot #) of sound card index - index (slot #) of sound card
- Values: 0 through 7 or negative - Values: 0 through 31 or negative
- If nonnegative, assign that index number - If nonnegative, assign that index number
- if negative, interpret as a bitmask of permissible - if negative, interpret as a bitmask of permissible
indices; the first free permitted index is assigned indices; the first free permitted index is assigned
@ -134,7 +134,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for AD1816A chip (PnP setup) dma2 - second DMA # for AD1816A chip (PnP setup)
clockfreq - Clock frequency for AD1816A chip (default = 0, 33000Hz) clockfreq - Clock frequency for AD1816A chip (default = 0, 33000Hz)
Module supports up to 8 cards, autoprobe and PnP. This module supports multiple cards, autoprobe and PnP.
Module snd-ad1848 Module snd-ad1848
----------------- -----------------
@ -145,9 +145,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # for AD1848 chip irq - IRQ # for AD1848 chip
dma1 - DMA # for AD1848 chip (0,1,3) dma1 - DMA # for AD1848 chip (0,1,3)
Module supports up to 8 cards. This module does not support autoprobe This module supports multiple cards. It does not support autoprobe
thus main port must be specified!!! Other ports are optional. thus main port must be specified!!! Other ports are optional.
The power-management is supported.
Module snd-ad1889 Module snd-ad1889
----------------- -----------------
@ -156,7 +158,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_quirk - AC'97 workaround for strange hardware ac97_quirk - AC'97 workaround for strange hardware
See the description of intel8x0 module for details. See the description of intel8x0 module for details.
This module supports up to 8 cards. This module supports multiple cards.
Module snd-ali5451 Module snd-ali5451
------------------ ------------------
@ -184,7 +186,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 (PnP setup) mpu_irq - IRQ # for MPU-401 (PnP setup)
fm_port - port # for OPL3 FM (PnP setup) fm_port - port # for OPL3 FM (PnP setup)
Module supports up to 8 cards, autoprobe and PnP. This module supports multiple cards, autoprobe and PnP.
The power-management is supported.
Module snd-als4000 Module snd-als4000
------------------ ------------------
@ -194,7 +198,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick_port - port # for legacy joystick support. joystick_port - port # for legacy joystick support.
0 = disabled (default), 1 = auto-detect 0 = disabled (default), 1 = auto-detect
Module supports up to 8 cards, autoprobe and PnP. This module supports multiple cards, autoprobe and PnP.
The power-management is supported.
Module snd-atiixp Module snd-atiixp
----------------- -----------------
@ -213,6 +219,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
implementation depends on the motherboard, and you'll need to implementation depends on the motherboard, and you'll need to
choose the correct one via spdif_aclink module option. choose the correct one via spdif_aclink module option.
The power-management is supported.
Module snd-atiixp-modem Module snd-atiixp-modem
----------------------- -----------------------
@ -223,6 +231,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.
The power-management is supported.
Module snd-au8810, snd-au8820, snd-au8830 Module snd-au8810, snd-au8820, snd-au8830
----------------------------------------- -----------------------------------------
@ -263,8 +273,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma1 - 1st DMA # for AZT2320 (WSS) chip (PnP setup) dma1 - 1st DMA # for AZT2320 (WSS) chip (PnP setup)
dma2 - 2nd DMA # for AZT2320 (WSS) chip (PnP setup) dma2 - 2nd DMA # for AZT2320 (WSS) chip (PnP setup)
Module supports up to 8 cards, PnP and autoprobe. This module supports multiple cards, PnP and autoprobe.
The power-management is supported.
Module snd-azt3328 Module snd-azt3328
------------------ ------------------
@ -272,7 +284,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick - Enable joystick (default off) joystick - Enable joystick (default off)
Module supports up to 8 cards. This module supports multiple cards.
Module snd-bt87x Module snd-bt87x
---------------- ----------------
@ -282,7 +294,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
digital_rate - Override the default digital rate (Hz) digital_rate - Override the default digital rate (Hz)
load_all - Load the driver even if the card model isn't known load_all - Load the driver even if the card model isn't known
Module supports up to 8 cards. This module supports multiple cards.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.
@ -292,7 +304,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for Creative Audigy LS and SB Live 24bit Module for Creative Audigy LS and SB Live 24bit
Module supports up to 8 cards. This module supports multiple cards.
Module snd-cmi8330 Module snd-cmi8330
@ -308,7 +320,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
sbdma8 - 8bit DMA # for CMI8330 chip (SB16) sbdma8 - 8bit DMA # for CMI8330 chip (SB16)
sbdma16 - 16bit DMA # for CMI8330 chip (SB16) sbdma16 - 16bit DMA # for CMI8330 chip (SB16)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
The power-management is supported.
Module snd-cmipci Module snd-cmipci
----------------- -----------------
@ -321,8 +335,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
(default = 1) (default = 1)
joystick_port - Joystick port address (0 = disable, 1 = auto-detect) joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
Module supports autoprobe and multiple chips (max 8). This module supports autoprobe and multiple cards.
The power-management is supported.
Module snd-cs4231 Module snd-cs4231
----------------- -----------------
@ -335,7 +351,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma1 - first DMA # for CS4231 chip dma1 - first DMA # for CS4231 chip
dma2 - second DMA # for CS4231 chip dma2 - second DMA # for CS4231 chip
Module supports up to 8 cards. This module does not support autoprobe This module supports multiple cards. This module does not support autoprobe
thus main port must be specified!!! Other ports are optional. thus main port must be specified!!! Other ports are optional.
The power-management is supported. The power-management is supported.
@ -355,7 +371,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
Module supports up to 8 cards. This module does not support autoprobe This module supports multiple cards. This module does not support autoprobe
thus main port must be specified!!! Other ports are optional. thus main port must be specified!!! Other ports are optional.
The power-management is supported. The power-management is supported.
@ -376,7 +392,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for CS4236 chip (0,1,3), -1 = disable dma2 - second DMA # for CS4236 chip (0,1,3), -1 = disable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
Module supports up to 8 cards. This module does not support autoprobe This module supports multiple cards. This module does not support autoprobe
(if ISA PnP is not used) thus main port and control port must be (if ISA PnP is not used) thus main port and control port must be
specified!!! Other ports are optional. specified!!! Other ports are optional.
@ -389,7 +405,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dual_codec - Secondary codec ID (0 = disable, default) dual_codec - Secondary codec ID (0 = disable, default)
Module supports up to 8 cards. This module supports multiple cards.
The power-management is supported. The power-management is supported.
@ -403,13 +419,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
thinkpad - Force to enable Thinkpad's CLKRUN control. thinkpad - Force to enable Thinkpad's CLKRUN control.
mmap_valid - Support OSS mmap mode (default = 0). mmap_valid - Support OSS mmap mode (default = 0).
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Usually external amp and CLKRUN controls are detected automatically Usually external amp and CLKRUN controls are detected automatically
from PCI sub vendor/device ids. If they don't work, give the options from PCI sub vendor/device ids. If they don't work, give the options
above explicitly. above explicitly.
The power-management is supported. The power-management is supported.
Module snd-cs5535audio
----------------------
Module for multifunction CS5535 companion PCI device
This module supports multiple cards.
Module snd-dt019x Module snd-dt019x
----------------- -----------------
@ -423,9 +446,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 (PnP setup) mpu_irq - IRQ # for MPU-401 (PnP setup)
dma8 - DMA # (PnP setup) dma8 - DMA # (PnP setup)
Module supports up to 8 cards. This module is enabled only with This module supports multiple cards. This module is enabled only with
ISA PnP support. ISA PnP support.
The power-management is supported.
Module snd-dummy Module snd-dummy
---------------- ----------------
@ -433,6 +458,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
or input, but you may use this module for any application which or input, but you may use this module for any application which
requires a sound card (like RealPlayer). requires a sound card (like RealPlayer).
The power-management is supported.
Module snd-emu10k1 Module snd-emu10k1
------------------ ------------------
@ -450,7 +477,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
given in MB unit. Default value is 128. given in MB unit. Default value is 128.
enable_ir - enable IR enable_ir - enable IR
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Input & Output configurations [extin/extout] Input & Output configurations [extin/extout]
* Creative Card wo/Digital out [0x0003/0x1f03] * Creative Card wo/Digital out [0x0003/0x1f03]
@ -466,12 +493,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
* Creative Card 5.1 (c) 2003 [0x3fc3/0x7cff] * Creative Card 5.1 (c) 2003 [0x3fc3/0x7cff]
* Creative Card all ins and outs [0x3fff/0x7fff] * Creative Card all ins and outs [0x3fff/0x7fff]
The power-management is supported.
Module snd-emu10k1x Module snd-emu10k1x
------------------- -------------------
Module for Creative Emu10k1X (SB Live Dell OEM version) Module for Creative Emu10k1X (SB Live Dell OEM version)
Module supports up to 8 cards. This module supports multiple cards.
Module snd-ens1370 Module snd-ens1370
------------------ ------------------
@ -482,7 +511,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick - Enable joystick (default off) joystick - Enable joystick (default off)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Module snd-ens1371 Module snd-ens1371
------------------ ------------------
@ -495,7 +524,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
joystick_port - port # for joystick (0x200,0x208,0x210,0x218), joystick_port - port # for joystick (0x200,0x208,0x210,0x218),
0 = disable (default), 1 = auto-detect 0 = disable (default), 1 = auto-detect
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Module snd-es968 Module snd-es968
---------------- ----------------
@ -506,8 +535,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # for ES968 (SB8) chip (PnP setup) irq - IRQ # for ES968 (SB8) chip (PnP setup)
dma1 - DMA # for ES968 (SB8) chip (PnP setup) dma1 - DMA # for ES968 (SB8) chip (PnP setup)
Module supports up to 8 cards, PnP and autoprobe. This module supports multiple cards, PnP and autoprobe.
The power-management is supported.
Module snd-es1688 Module snd-es1688
----------------- -----------------
@ -519,7 +550,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - IRQ # for MPU-401 port (5,7,9,10) mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
dma8 - DMA # for ES-1688 chip (0,1,3) dma8 - DMA # for ES-1688 chip (0,1,3)
Module supports up to 8 cards and autoprobe (without MPU-401 port). This module supports multiple cards and autoprobe (without MPU-401 port).
Module snd-es18xx Module snd-es18xx
----------------- -----------------
@ -534,8 +565,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - first DMA # for ES-18xx chip (0,1,3) dma2 - first DMA # for ES-18xx chip (0,1,3)
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
Module supports up to 8 cards ISA PnP and autoprobe (without MPU-401 port This module supports multiple cards, ISA PnP and autoprobe (without MPU-401
if native ISA PnP routines are not used). port if native ISA PnP routines are not used).
When dma2 is equal with dma1, the driver works as half-duplex. When dma2 is equal with dma1, the driver works as half-duplex.
The power-management is supported. The power-management is supported.
@ -545,7 +576,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips. Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips.
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
The power-management is supported.
Module snd-es1968 Module snd-es1968
----------------- -----------------
@ -561,7 +594,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
enable_mpu - enable MPU401 (0 = off, 1 = on, 2 = auto (default)) enable_mpu - enable MPU401 (0 = off, 1 = on, 2 = auto (default))
joystick - enable joystick (default off) joystick - enable joystick (default off)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
The power-management is supported. The power-management is supported.
@ -577,8 +610,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
- High 16-bits are video (radio) device number + 1 - High 16-bits are video (radio) device number + 1
- example: 0x10002 (MediaForte 256-PCPR, device 1) - example: 0x10002 (MediaForte 256-PCPR, device 1)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
The power-management is supported.
Module snd-gusclassic Module snd-gusclassic
--------------------- ---------------------
@ -592,7 +627,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
voices - GF1 voices limit (14-32) voices - GF1 voices limit (14-32)
pcm_voices - reserved PCM voices pcm_voices - reserved PCM voices
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Module snd-gusextreme Module snd-gusextreme
--------------------- ---------------------
@ -611,7 +646,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
voices - GF1 voices limit (14-32) voices - GF1 voices limit (14-32)
pcm_voices - reserved PCM voices pcm_voices - reserved PCM voices
Module supports up to 8 cards and autoprobe (without MPU-401 port). This module supports multiple cards and autoprobe (without MPU-401 port).
Module snd-gusmax Module snd-gusmax
----------------- -----------------
@ -626,7 +661,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
voices - GF1 voices limit (14-32) voices - GF1 voices limit (14-32)
pcm_voices - reserved PCM voices pcm_voices - reserved PCM voices
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Module snd-hda-intel Module snd-hda-intel
-------------------- --------------------
@ -688,12 +723,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
(Usually SD_LPLIB register is more accurate than the (Usually SD_LPLIB register is more accurate than the
position buffer.) position buffer.)
The power-management is supported.
Module snd-hdsp Module snd-hdsp
--------------- ---------------
Module for RME Hammerfall DSP audio interface(s) Module for RME Hammerfall DSP audio interface(s)
Module supports up to 8 cards. This module supports multiple cards.
Note: The firmware data can be automatically loaded via hotplug Note: The firmware data can be automatically loaded via hotplug
when CONFIG_FW_LOADER is set. Otherwise, you need to load when CONFIG_FW_LOADER is set. Otherwise, you need to load
@ -751,7 +788,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever) cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
in msec resolution, default value is 500 (0.5 sec) in msec resolution, default value is 500 (0.5 sec)
Module supports up to 8 cards and autoprobe. Note: The consumer part This module supports multiple cards and autoprobe. Note: The consumer part
is not used with all Envy24 based cards (for example in the MidiMan Delta is not used with all Envy24 based cards (for example in the MidiMan Delta
serie). serie).
@ -787,7 +824,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
aureon71, universe, k8x800, phase22, phase28, ms300, aureon71, universe, k8x800, phase22, phase28, ms300,
av710 av710
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Note: The supported board is detected by reading EEPROM or PCI Note: The supported board is detected by reading EEPROM or PCI
SSID (if EEPROM isn't available). You can override the SSID (if EEPROM isn't available). You can override the
@ -839,6 +876,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.
The power-management is supported.
Module snd-interwave Module snd-interwave
-------------------- --------------------
@ -855,7 +894,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
effect - 1 = InterWave effects enable (default 0); effect - 1 = InterWave effects enable (default 0);
requires 8 voices requires 8 voices
Module supports up to 8 cards, autoprobe and ISA PnP. This module supports multiple cards, autoprobe and ISA PnP.
Module snd-interwave-stb Module snd-interwave-stb
------------------------ ------------------------
@ -875,14 +914,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
effect - 1 = InterWave effects enable (default 0); effect - 1 = InterWave effects enable (default 0);
requires 8 voices requires 8 voices
Module supports up to 8 cards, autoprobe and ISA PnP. This module supports multiple cards, autoprobe and ISA PnP.
Module snd-korg1212 Module snd-korg1212
------------------- -------------------
Module for Korg 1212 IO PCI card Module for Korg 1212 IO PCI card
Module supports up to 8 cards. This module supports multiple cards.
Module snd-maestro3 Module snd-maestro3
------------------- -------------------
@ -894,7 +933,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
-1 for default pin (8 for allegro, 1 for -1 for default pin (8 for allegro, 1 for
others) others)
Module supports autoprobe and multiple chips (max 8). This module supports autoprobe and multiple chips.
Note: the binding of amplifier is dependent on hardware. Note: the binding of amplifier is dependent on hardware.
If there is no sound even though all channels are unmuted, try to If there is no sound even though all channels are unmuted, try to
@ -909,7 +948,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for Digigram miXart8 sound cards. Module for Digigram miXart8 sound cards.
Module supports multiple cards. This module supports multiple cards.
Note: One miXart8 board will be represented as 4 alsa cards. Note: One miXart8 board will be represented as 4 alsa cards.
See MIXART.txt for details. See MIXART.txt for details.
@ -928,7 +967,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ number or -1 (disable) irq - IRQ number or -1 (disable)
pnp - PnP detection - 0 = disable, 1 = enable (default) pnp - PnP detection - 0 = disable, 1 = enable (default)
Module supports multiple devices (max 8) and PnP. This module supports multiple devices and PnP.
Module snd-mtpav Module snd-mtpav
---------------- ----------------
@ -1014,7 +1053,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable dma2 - second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
Module supports up to 8 cards and ISA PnP. This module does not support This module supports multiple cards and ISA PnP. It does not support
autoprobe (if ISA PnP is not used) thus all ports must be specified!!! autoprobe (if ISA PnP is not used) thus all ports must be specified!!!
The power-management is supported. The power-management is supported.
@ -1064,6 +1103,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports only one card, autoprobe and PnP. This module supports only one card, autoprobe and PnP.
Module snd-pcxhr
----------------
Module for Digigram PCXHR boards
This module supports multiple cards.
Module snd-powermac (on ppc only) Module snd-powermac (on ppc only)
--------------------------------- ---------------------------------
@ -1084,20 +1130,22 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
For ARM architecture only. For ARM architecture only.
The power-management is supported.
Module snd-rme32 Module snd-rme32
---------------- ----------------
Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32,
Prodif96 and Prodif Gold) sound cards. Prodif96 and Prodif Gold) sound cards.
Module supports up to 8 cards. This module supports multiple cards.
Module snd-rme96 Module snd-rme96
---------------- ----------------
Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards. Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards.
Module supports up to 8 cards. This module supports multiple cards.
Module snd-rme9652 Module snd-rme9652
------------------ ------------------
@ -1107,7 +1155,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
precise_ptr - Enable precise pointer (doesn't work reliably). precise_ptr - Enable precise pointer (doesn't work reliably).
(default = 0) (default = 0)
Module supports up to 8 cards. This module supports multiple cards.
Note: snd-page-alloc module does the job which snd-hammerfall-mem Note: snd-page-alloc module does the job which snd-hammerfall-mem
module did formerly. It will allocate the buffers in advance module did formerly. It will allocate the buffers in advance
@ -1124,6 +1172,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module supports only one card. Module supports only one card.
Module has no enable and index options. Module has no enable and index options.
The power-management is supported.
Module snd-sb8 Module snd-sb8
-------------- --------------
@ -1135,8 +1185,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # for SB DSP chip (5,7,9,10) irq - IRQ # for SB DSP chip (5,7,9,10)
dma8 - DMA # for SB DSP chip (1,3) dma8 - DMA # for SB DSP chip (1,3)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
The power-management is supported.
Module snd-sb16 and snd-sbawe Module snd-sb16 and snd-sbawe
----------------------------- -----------------------------
@ -1155,7 +1207,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
csp - ASP/CSP chip support - 0 = disable (default), 1 = enable csp - ASP/CSP chip support - 0 = disable (default), 1 = enable
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
Module supports up to 8 cards, autoprobe and ISA PnP. This module supports multiple cards, autoprobe and ISA PnP.
Note: To use Vibra16X cards in 16-bit half duplex mode, you must Note: To use Vibra16X cards in 16-bit half duplex mode, you must
disable 16bit DMA with dma16 = -1 module parameter. disable 16bit DMA with dma16 = -1 module parameter.
@ -1163,6 +1215,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
half duplex mode through 8-bit DMA channel by disabling their half duplex mode through 8-bit DMA channel by disabling their
16-bit DMA channel. 16-bit DMA channel.
The power-management is supported.
Module snd-sgalaxy Module snd-sgalaxy
------------------ ------------------
@ -1173,7 +1227,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
irq - IRQ # (7,9,10,11) irq - IRQ # (7,9,10,11)
dma1 - DMA # dma1 - DMA #
Module supports up to 8 cards. This module supports multiple cards.
The power-management is supported.
Module snd-sscape Module snd-sscape
----------------- -----------------
@ -1185,7 +1241,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mpu_irq - MPU-401 IRQ # (PnP setup) mpu_irq - MPU-401 IRQ # (PnP setup)
dma - DMA # (PnP setup) dma - DMA # (PnP setup)
Module supports up to 8 cards. ISA PnP must be enabled. This module supports multiple cards. ISA PnP must be enabled.
You need sscape_ctl tool in alsa-tools package for loading You need sscape_ctl tool in alsa-tools package for loading
the microcode. the microcode.
@ -1194,21 +1250,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for AMD7930 sound chips found on Sparcs. Module for AMD7930 sound chips found on Sparcs.
Module supports up to 8 cards. This module supports multiple cards.
Module snd-sun-cs4231 (on sparc only) Module snd-sun-cs4231 (on sparc only)
------------------------------------- -------------------------------------
Module for CS4231 sound chips found on Sparcs. Module for CS4231 sound chips found on Sparcs.
Module supports up to 8 cards. This module supports multiple cards.
Module snd-sun-dbri (on sparc only) Module snd-sun-dbri (on sparc only)
----------------------------------- -----------------------------------
Module for DBRI sound chips found on Sparcs. Module for DBRI sound chips found on Sparcs.
Module supports up to 8 cards. This module supports multiple cards.
Module snd-wavefront Module snd-wavefront
-------------------- --------------------
@ -1228,7 +1284,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - DMA2 # for CS4232 PCM interface. dma2 - DMA2 # for CS4232 PCM interface.
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
Module supports up to 8 cards and ISA PnP. This module supports multiple cards and ISA PnP.
Module snd-sonicvibes Module snd-sonicvibes
--------------------- ---------------------
@ -1240,7 +1296,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
- SoundCard must have onboard SRAM for this. - SoundCard must have onboard SRAM for this.
mge - Mic Gain Enable - 1 = enable, 0 = disable (default) mge - Mic Gain Enable - 1 = enable, 0 = disable (default)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
Module snd-serial-u16550 Module snd-serial-u16550
------------------------ ------------------------
@ -1259,7 +1315,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A, 0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A,
3 = MS-124W M/B, 4 = Generic 3 = MS-124W M/B, 4 = Generic
Module supports up to 8 cards. This module does not support autoprobe This module supports multiple cards. This module does not support autoprobe
thus the main port must be specified!!! Other options are optional. thus the main port must be specified!!! Other options are optional.
Module snd-trident Module snd-trident
@ -1278,7 +1334,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
pcm_channels - max channels (voices) reserved for PCM pcm_channels - max channels (voices) reserved for PCM
wavetable_size - max wavetable size in kB (4-?kb) wavetable_size - max wavetable size in kB (4-?kb)
Module supports up to 8 cards and autoprobe. This module supports multiple cards and autoprobe.
The power-management is supported. The power-management is supported.
@ -1290,14 +1346,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
vid - Vendor ID for the device (optional) vid - Vendor ID for the device (optional)
pid - Product ID for the device (optional) pid - Product ID for the device (optional)
This module supports up to 8 cards, autoprobe and hotplugging. This module supports multiple devices, autoprobe and hotplugging.
Module snd-usb-usx2y Module snd-usb-usx2y
-------------------- --------------------
Module for Tascam USB US-122, US-224 and US-428 devices. Module for Tascam USB US-122, US-224 and US-428 devices.
This module supports up to 8 cards, autoprobe and hotplugging. This module supports multiple devices, autoprobe and hotplugging.
Note: you need to load the firmware via usx2yloader utility included Note: you need to load the firmware via usx2yloader utility included
in alsa-tools and alsa-firmware packages. in alsa-tools and alsa-firmware packages.
@ -1356,6 +1412,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: for the MPU401 on VIA823x, use snd-mpu401 driver Note: for the MPU401 on VIA823x, use snd-mpu401 driver
additionally. The mpu_port option is for VIA686 chips only. additionally. The mpu_port option is for VIA686 chips only.
The power-management is supported.
Module snd-via82xx-modem Module snd-via82xx-modem
------------------------ ------------------------
@ -1368,6 +1426,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.
The power-management is supported.
Module snd-virmidi Module snd-virmidi
------------------ ------------------
@ -1375,9 +1435,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module creates virtual rawmidi devices which communicate This module creates virtual rawmidi devices which communicate
to the corresponding ALSA sequencer ports. to the corresponding ALSA sequencer ports.
midi_devs - MIDI devices # (1-8, default=4) midi_devs - MIDI devices # (1-4, default=4)
Module supports up to 8 cards. This module supports multiple cards.
Module snd-vx222 Module snd-vx222
---------------- ----------------
@ -1387,7 +1447,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
mic - Enable Microphone on V222 Mic (NYI) mic - Enable Microphone on V222 Mic (NYI)
ibl - Capture IBL size. (default = 0, minimum size) ibl - Capture IBL size. (default = 0, minimum size)
Module supports up to 8 cards. This module supports multiple cards.
When the driver is compiled as a module and the hotplug firmware When the driver is compiled as a module and the hotplug firmware
is supported, the firmware data is loaded via hotplug automatically. is supported, the firmware data is loaded via hotplug automatically.
@ -1406,6 +1466,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
size is chosen. The possible IBL values can be found in size is chosen. The possible IBL values can be found in
/proc/asound/cardX/vx-status proc file. /proc/asound/cardX/vx-status proc file.
The power-management is supported.
Module snd-vxpocket Module snd-vxpocket
------------------- -------------------
@ -1413,7 +1475,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ibl - Capture IBL size. (default = 0, minimum size) ibl - Capture IBL size. (default = 0, minimum size)
Module supports up to 8 cards. The module is compiled only when This module supports multiple cards. The module is compiled only when
PCMCIA is supported on kernel. PCMCIA is supported on kernel.
With the older 2.6.x kernel, to activate the driver via the card With the older 2.6.x kernel, to activate the driver via the card
@ -1434,6 +1496,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note2: snd-vxp440 driver is merged to snd-vxpocket driver since Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
ALSA 1.0.10. ALSA 1.0.10.
The power-management is supported.
Module snd-ymfpci Module snd-ymfpci
----------------- -----------------
@ -1447,7 +1511,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1 (auto-detect) 1 (auto-detect)
rear_switch - enable shared rear/line-in switch (bool) rear_switch - enable shared rear/line-in switch (bool)
Module supports autoprobe and multiple chips (max 8). This module supports autoprobe and multiple chips.
The power-management is supported. The power-management is supported.
@ -1458,6 +1522,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Note: the driver is build only when CONFIG_ISA is set. Note: the driver is build only when CONFIG_ISA is set.
The power-management is supported.
AC97 Quirk Option AC97 Quirk Option
================= =================
@ -1474,7 +1540,7 @@ the proper value with this option.
The following strings are accepted: The following strings are accepted:
- default Don't override the default setting - default Don't override the default setting
- disable Disable the quirk - none Disable the quirk
- hp_only Bind Master and Headphone controls as a single control - hp_only Bind Master and Headphone controls as a single control
- swap_hp Swap headphone and master controls - swap_hp Swap headphone and master controls
- swap_surround Swap master and surround controls - swap_surround Swap master and surround controls

File diff suppressed because it is too large Load Diff

View File

@ -138,6 +138,22 @@ card*/codec97#0/ac97#?-?+regs
# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs # echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
USB Audio Streams
-----------------
card*/stream*
Shows the assignment and the current status of each audio stream
of the given card. This information is very useful for debugging.
HD-Audio Codecs
---------------
card*/codec#*
Shows the general codec information and the attribute of each
widget node.
Sequencer Information Sequencer Information
--------------------- ---------------------

View File

@ -63,7 +63,7 @@ The bus instance is created via snd_hda_bus_new(). You need to pass
the card instance, the template, and the pointer to store the the card instance, the template, and the pointer to store the
resultant bus instance. resultant bus instance.
int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp, int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
struct hda_bus **busp); struct hda_bus **busp);
It returns zero if successful. A negative return value means any It returns zero if successful. A negative return value means any
@ -166,14 +166,14 @@ The ops field contains the following callback functions:
struct hda_pcm_ops { struct hda_pcm_ops {
int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
unsigned int stream_tag, unsigned int format, unsigned int stream_tag, unsigned int format,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
}; };
All are non-NULL, so you can call them safely without NULL check. All are non-NULL, so you can call them safely without NULL check.
@ -284,7 +284,7 @@ parameter, and PCI subsystem IDs. If the matching entry is found, it
returns the config field value. returns the config field value.
snd_hda_add_new_ctls() can be used to create and add control entries. snd_hda_add_new_ctls() can be used to create and add control entries.
Pass the zero-terminated array of snd_kcontrol_new_t. The same array Pass the zero-terminated array of struct snd_kcontrol_new. The same array
can be passed to snd_hda_resume_ctls() for resume. can be passed to snd_hda_resume_ctls() for resume.
Note that this will call control->put callback of these entries. So, Note that this will call control->put callback of these entries. So,
put callback should check codec->in_resume and force to restore the put callback should check codec->in_resume and force to restore the
@ -292,7 +292,7 @@ given value if it's non-zero even if the value is identical with the
cached value. cached value.
Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
used for the entry of snd_kcontrol_new_t. used for the entry of struct snd_kcontrol_new.
The input MUX helper callbacks for such a control are provided, too: The input MUX helper callbacks for such a control are provided, too:
snd_hda_input_mux_info() and snd_hda_input_mux_put(). See snd_hda_input_mux_info() and snd_hda_input_mux_put(). See

View File

@ -202,17 +202,13 @@ you must call __handle_sysrq_nolock instead.
* I have more questions, who can I ask? * I have more questions, who can I ask?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You may feel free to send email to myrdraal@deathsdoor.com, and I will
respond as soon as possible.
-Myrdraal
And I'll answer any questions about the registration system you got, also And I'll answer any questions about the registration system you got, also
responding as soon as possible. responding as soon as possible.
-Crutcher -Crutcher
* Credits * Credits
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Written by Mydraal <myrdraal@deathsdoor.com> Written by Mydraal <vulpyne@vulpyne.net>
Updated by Adam Sulmicki <adam@cfar.umd.edu> Updated by Adam Sulmicki <adam@cfar.umd.edu>
Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59 Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com> Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>

View File

@ -650,6 +650,11 @@ L: linux-crypto@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
S: Maintained S: Maintained
CS5535 Audio ALSA driver
P: Jaya Kumar
M: jayakumar.alsa@gmail.com
S: Maintained
CYBERPRO FB DRIVER CYBERPRO FB DRIVER
P: Russell King P: Russell King
M: rmk@arm.linux.org.uk M: rmk@arm.linux.org.uk
@ -1465,7 +1470,6 @@ P: Several
L: kernel-janitors@osdl.org L: kernel-janitors@osdl.org
W: http://www.kerneljanitors.org/ W: http://www.kerneljanitors.org/
W: http://sf.net/projects/kernel-janitor/ W: http://sf.net/projects/kernel-janitor/
W: http://developer.osdl.org/rddunlap/kj-patches/
S: Maintained S: Maintained
KERNEL NFSD KERNEL NFSD
@ -1476,17 +1480,11 @@ W: http://nfs.sourceforge.net/
W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
S: Maintained S: Maintained
KERNEL EVENT LAYER (KOBJECT_UEVENT)
P: Robert Love
M: rml@novell.com
L: linux-kernel@vger.kernel.org
S: Maintained
KEXEC KEXEC
P: Eric Biederman P: Eric Biederman
P: Randy Dunlap P: Randy Dunlap
M: ebiederm@xmission.com M: ebiederm@xmission.com
M: rddunlap@osdl.org M: rdunlap@xenotime.net
W: http://www.xmission.com/~ebiederm/files/kexec/ W: http://www.xmission.com/~ebiederm/files/kexec/
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
L: fastboot@osdl.org L: fastboot@osdl.org
@ -2587,7 +2585,6 @@ S: Maintained
UDF FILESYSTEM UDF FILESYSTEM
P: Ben Fennema P: Ben Fennema
M: bfennema@falcon.csc.calpoly.edu M: bfennema@falcon.csc.calpoly.edu
L: linux_udf@hpesjro.fc.hp.com
W: http://linux-udf.sourceforge.net W: http://linux-udf.sourceforge.net
S: Maintained S: Maintained
@ -2640,6 +2637,12 @@ L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB ISP116X DRIVER
P: Olav Kongas
M: ok@artecdesign.ee
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB KAWASAKI LSI DRIVER USB KAWASAKI LSI DRIVER
P: Oliver Neukum P: Oliver Neukum
M: oliver@neukum.name M: oliver@neukum.name
@ -2651,7 +2654,7 @@ USB MASS STORAGE DRIVER
P: Matthew Dharm P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net M: mdharm-usb@one-eyed-alien.net
L: linux-usb-users@lists.sourceforge.net L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: usb-storage@lists.one-eyed-alien.net
S: Maintained S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ W: http://www.one-eyed-alien.net/~mdharm/linux-usb/

View File

@ -286,10 +286,6 @@ export quiet Q KBUILD_VERBOSE
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
# For backward compatibility
check_gcc = $(warning check_gcc is deprecated - use cc-option) \
$(call cc-option, $(1),$(2))
# cc-option-yn # cc-option-yn
# Usage: flag := $(call cc-option-yn, -march=winchip-c6) # Usage: flag := $(call cc-option-yn, -march=winchip-c6)
cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
@ -481,18 +477,20 @@ ifeq ($(dot-config),1)
# Read in dependencies to all Kconfig* files, make sure to run # Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected. # oldconfig if changes are detected.
-include .config.cmd -include .kconfig.d
include .config include .config
# If .config needs to be updated, it will be done via the dependency # If .config needs to be updated, it will be done via the dependency
# that autoconf has on .config. # that autoconf has on .config.
# To avoid any implicit rule to kick in, define an empty command # To avoid any implicit rule to kick in, define an empty command
.config: ; .config .kconfig.d: ;
# If .config is newer than include/linux/autoconf.h, someone tinkered # If .config is newer than include/linux/autoconf.h, someone tinkered
# with it and forgot to run make oldconfig # with it and forgot to run make oldconfig.
include/linux/autoconf.h: .config # If kconfig.d is missing then we are probarly in a cleaned tree so
# we execute the config step to be sure to catch updated Kconfig files
include/linux/autoconf.h: .kconfig.d .config
$(Q)mkdir -p include/linux $(Q)mkdir -p include/linux
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else else
@ -1066,7 +1064,7 @@ help:
@echo ' all - Build all targets marked with [*]' @echo ' all - Build all targets marked with [*]'
@echo '* vmlinux - Build the bare kernel' @echo '* vmlinux - Build the bare kernel'
@echo '* modules - Build all modules' @echo '* modules - Build all modules'
@echo ' modules_install - Install all modules' @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
@echo ' dir/ - Build all files in dir and below' @echo ' dir/ - Build all files in dir and below'
@echo ' dir/file.[ois] - Build specified target only' @echo ' dir/file.[ois] - Build specified target only'
@echo ' dir/file.ko - Build module including final link' @echo ' dir/file.ko - Build module including final link'
@ -1240,8 +1238,11 @@ cscope: FORCE
quiet_cmd_TAGS = MAKE $@ quiet_cmd_TAGS = MAKE $@
define cmd_TAGS define cmd_TAGS
rm -f $@; \ rm -f $@; \
ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \ ETAGSF=`etags --version | grep -i exuberant >/dev/null && \
$(all-sources) | xargs etags $$ETAGSF -a echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs etags $$ETAGSF -a
endef endef
TAGS: FORCE TAGS: FORCE
@ -1251,8 +1252,11 @@ TAGS: FORCE
quiet_cmd_tags = MAKE $@ quiet_cmd_tags = MAKE $@
define cmd_tags define cmd_tags
rm -f $@; \ rm -f $@; \
CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \ CTAGSF=`ctags --version | grep -i exuberant >/dev/null && \
$(all-sources) | xargs ctags $$CTAGSF -a echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs ctags $$CTAGSF -a
endef endef
tags: FORCE tags: FORCE

View File

@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
} }
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
{ {
struct amba_device *pcdev = to_amba_device(dev); struct amba_device *pcdev = to_amba_device(dev);
@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
return 0; return 0;
} }
#else #else
#define amba_hotplug NULL #define amba_uevent NULL
#endif #endif
static int amba_suspend(struct device *dev, pm_message_t state) static int amba_suspend(struct device *dev, pm_message_t state)
@ -88,7 +88,7 @@ static int amba_resume(struct device *dev)
static struct bus_type amba_bustype = { static struct bus_type amba_bustype = {
.name = "amba", .name = "amba",
.match = amba_match, .match = amba_match,
.hotplug = amba_hotplug, .uevent = amba_uevent,
.suspend = amba_suspend, .suspend = amba_suspend,
.resume = amba_resume, .resume = amba_resume,
}; };

View File

@ -43,6 +43,7 @@
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h> #include <asm/arch/mmc.h>
#include <asm/arch/irda.h> #include <asm/arch/irda.h>
#include <asm/arch/ohci.h>
#include "generic.h" #include "generic.h"
@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = {
&mst_flash_device[1], &mst_flash_device[1],
}; };
static int mainstone_ohci_init(struct device *dev)
{
/* setup Port1 GPIO pin. */
pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
/* Set the Power Control Polarity Low and Power Sense
Polarity Low to active low. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
return 0;
}
static struct pxaohci_platform_data mainstone_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = mainstone_ohci_init,
};
static void __init mainstone_init(void) static void __init mainstone_init(void)
{ {
int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
@ -424,6 +444,7 @@ static void __init mainstone_init(void)
pxa_set_mci_info(&mainstone_mci_platform_data); pxa_set_mci_info(&mainstone_mci_platform_data);
pxa_set_ficp_info(&mainstone_ficp_platform_data); pxa_set_ficp_info(&mainstone_ficp_platform_data);
pxa_set_ohci_info(&mainstone_ohci_platform_data);
} }

View File

@ -21,6 +21,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#include <asm/arch/ohci.h>
#include "generic.h" #include "generic.h"
@ -194,6 +195,11 @@ static struct platform_device ohci_device = {
.resource = pxa27x_ohci_resources, .resource = pxa27x_ohci_resources,
}; };
void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
{
ohci_device.dev.platform_data = info;
}
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&ohci_device, &ohci_device,
}; };

View File

@ -46,10 +46,9 @@ typedef struct task_struct* PTASK;
#ifdef MODULE #ifdef MODULE
void fp_send_sig(unsigned long sig, PTASK p, int priv); void fp_send_sig(unsigned long sig, PTASK p, int priv);
#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>"); MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
MODULE_DESCRIPTION("NWFPE floating point emulator"); MODULE_DESCRIPTION("NWFPE floating point emulator");
#endif
#else #else
#define fp_send_sig send_sig #define fp_send_sig send_sig

View File

@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb)
*/ */
static int nforce2_set_fsb(unsigned int fsb) static int nforce2_set_fsb(unsigned int fsb)
{ {
u32 pll, temp = 0; u32 temp = 0;
unsigned int tfsb; unsigned int tfsb;
int diff; int diff;
int pll = 0;
if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);

View File

@ -45,7 +45,7 @@
#define PFX "powernow-k8: " #define PFX "powernow-k8: "
#define BFX PFX "BIOS error: " #define BFX PFX "BIOS error: "
#define VERSION "version 1.50.4" #define VERSION "version 1.60.0"
#include "powernow-k8.h" #include "powernow-k8.h"
/* serialize freq changes */ /* serialize freq changes */
@ -216,10 +216,10 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
do { do {
wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
if (i++ > 100) { if (i++ > 100) {
printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
return 1; return 1;
} }
} while (query_current_values_with_pending_wait(data)); } while (query_current_values_with_pending_wait(data));
if (savefid != data->currfid) { if (savefid != data->currfid) {
@ -336,7 +336,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
/* Phase 2 - core frequency transition */ /* Phase 2 - core frequency transition */
static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
{ {
u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid; u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n", printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@ -359,9 +359,11 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
: vcoreqfid - vcocurrfid; : vcoreqfid - vcocurrfid;
while (vcofiddiff > 2) { while (vcofiddiff > 2) {
(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
if (reqfid > data->currfid) { if (reqfid > data->currfid) {
if (data->currfid > LO_FID_TABLE_TOP) { if (data->currfid > LO_FID_TABLE_TOP) {
if (write_new_fid(data, data->currfid + 2)) { if (write_new_fid(data, data->currfid + fid_interval)) {
return 1; return 1;
} }
} else { } else {
@ -371,7 +373,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
} }
} }
} else { } else {
if (write_new_fid(data, data->currfid - 2)) if (write_new_fid(data, data->currfid - fid_interval))
return 1; return 1;
} }
@ -464,7 +466,7 @@ static int check_supported_cpu(unsigned int cpu)
set_cpus_allowed(current, cpumask_of_cpu(cpu)); set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu) { if (smp_processor_id() != cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", cpu); printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
goto out; goto out;
} }
@ -474,7 +476,7 @@ static int check_supported_cpu(unsigned int cpu)
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
((eax & CPUID_XFAM) != CPUID_XFAM_K8) || ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) { ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
goto out; goto out;
} }
@ -517,22 +519,24 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j); printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
return -ENODEV; return -ENODEV;
} }
if ((pst[j].fid > MAX_FID) if (pst[j].fid > MAX_FID) {
|| (pst[j].fid & 1) printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
|| (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) { return -ENODEV;
}
if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
/* Only first fid is allowed to be in "low" range */ /* Only first fid is allowed to be in "low" range */
printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid); printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
return -EINVAL; return -EINVAL;
} }
if (pst[j].fid < lastfid) if (pst[j].fid < lastfid)
lastfid = pst[j].fid; lastfid = pst[j].fid;
} }
if (lastfid & 1) { if (lastfid & 1) {
printk(KERN_ERR PFX "lastfid invalid\n"); printk(KERN_ERR BFX "lastfid invalid\n");
return -EINVAL; return -EINVAL;
} }
if (lastfid > LO_FID_TABLE_TOP) if (lastfid > LO_FID_TABLE_TOP)
printk(KERN_INFO PFX "first fid not from lo freq table\n"); printk(KERN_INFO BFX "first fid not from lo freq table\n");
return 0; return 0;
} }
@ -631,7 +635,7 @@ static int find_psb_table(struct powernow_k8_data *data)
dprintk("table vers: 0x%x\n", psb->tableversion); dprintk("table vers: 0x%x\n", psb->tableversion);
if (psb->tableversion != PSB_VERSION_1_4) { if (psb->tableversion != PSB_VERSION_1_4) {
printk(KERN_INFO BFX "PSB table is not v1.4\n"); printk(KERN_ERR BFX "PSB table is not v1.4\n");
return -ENODEV; return -ENODEV;
} }
@ -689,7 +693,7 @@ static int find_psb_table(struct powernow_k8_data *data)
* BIOS and Kernel Developer's Guide, which is available on * BIOS and Kernel Developer's Guide, which is available on
* www.amd.com * www.amd.com
*/ */
printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n"); printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
return -ENODEV; return -ENODEV;
} }
@ -912,7 +916,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
if (smp_processor_id() != pol->cpu) { if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
goto err_out; goto err_out;
} }
@ -982,6 +986,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
cpumask_t oldmask = CPU_MASK_ALL; cpumask_t oldmask = CPU_MASK_ALL;
int rc, i; int rc, i;
if (!cpu_online(pol->cpu))
return -ENODEV;
if (!check_supported_cpu(pol->cpu)) if (!check_supported_cpu(pol->cpu))
return -ENODEV; return -ENODEV;
@ -1021,7 +1028,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
if (smp_processor_id() != pol->cpu) { if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
goto err_out; goto err_out;
} }
@ -1162,10 +1169,9 @@ static void __exit powernowk8_exit(void)
cpufreq_unregister_driver(&cpufreq_amd64_driver); cpufreq_unregister_driver(&cpufreq_amd64_driver);
} }
MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com."); MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
late_initcall(powernowk8_init); late_initcall(powernowk8_init);
module_exit(powernowk8_exit); module_exit(powernowk8_exit);

View File

@ -42,7 +42,7 @@ struct powernow_k8_data {
#define CPUID_XFAM 0x0ff00000 /* extended family */ #define CPUID_XFAM 0x0ff00000 /* extended family */
#define CPUID_XFAM_K8 0 #define CPUID_XFAM_K8 0
#define CPUID_XMOD 0x000f0000 /* extended model */ #define CPUID_XMOD 0x000f0000 /* extended model */
#define CPUID_XMOD_REV_F 0x00040000 #define CPUID_XMOD_REV_G 0x00060000
#define CPUID_USE_XFAM_XMOD 0x00000f00 #define CPUID_USE_XFAM_XMOD 0x00000f00
#define CPUID_GET_MAX_CAPABILITIES 0x80000000 #define CPUID_GET_MAX_CAPABILITIES 0x80000000
#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
@ -86,13 +86,14 @@ struct powernow_k8_data {
* low fid table * low fid table
* - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
* in the low fid table * in the low fid table
* - the parts can only step at 200 MHz intervals, so 1.9 GHz is never valid * - the parts can only step at <= 200 MHz intervals, odd fid values are
* supported in revision G and later revisions.
* - lowest frequency must be >= interprocessor hypertransport link speed * - lowest frequency must be >= interprocessor hypertransport link speed
* (only applies to MP systems obviously) * (only applies to MP systems obviously)
*/ */
/* fids (frequency identifiers) are arranged in 2 tables - lo and hi */ /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
#define LO_FID_TABLE_TOP 6 /* fid values marking the boundary */ #define LO_FID_TABLE_TOP 7 /* fid values marking the boundary */
#define HI_FID_TABLE_BOTTOM 8 /* between the low and high tables */ #define HI_FID_TABLE_BOTTOM 8 /* between the low and high tables */
#define LO_VCOFREQ_TABLE_TOP 1400 /* corresponding vco frequency values */ #define LO_VCOFREQ_TABLE_TOP 1400 /* corresponding vco frequency values */
@ -106,7 +107,7 @@ struct powernow_k8_data {
#define MIN_FREQ 800 /* Min and max freqs, per spec */ #define MIN_FREQ 800 /* Min and max freqs, per spec */
#define MAX_FREQ 5000 #define MAX_FREQ 5000
#define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */ #define INVALID_FID_MASK 0xffffffc0 /* not a valid fid if these bits are set */
#define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */ #define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */
#define VID_OFF 0x3f #define VID_OFF 0x3f

View File

@ -40,6 +40,7 @@ static struct pci_dev *speedstep_chipset_dev;
*/ */
static unsigned int speedstep_processor = 0; static unsigned int speedstep_processor = 0;
static u32 pmbase;
/* /*
* There are only two frequency states for each processor. Values * There are only two frequency states for each processor. Values
@ -55,6 +56,33 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-ich", msg) #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-ich", msg)
/**
* speedstep_find_register - read the PMBASE address
*
* Returns: -ENODEV if no register could be found
*/
static int speedstep_find_register (void)
{
if (!speedstep_chipset_dev)
return -ENODEV;
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01)) {
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
return -ENODEV;
}
pmbase &= 0xFFFFFFFE;
if (!pmbase) {
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
return -ENODEV;
}
dprintk("pmbase is 0x%x\n", pmbase);
return 0;
}
/** /**
* speedstep_set_state - set the SpeedStep state * speedstep_set_state - set the SpeedStep state
* @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
@ -63,27 +91,13 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
*/ */
static void speedstep_set_state (unsigned int state) static void speedstep_set_state (unsigned int state)
{ {
u32 pmbase;
u8 pm2_blk; u8 pm2_blk;
u8 value; u8 value;
unsigned long flags; unsigned long flags;
if (!speedstep_chipset_dev || (state > 0x1)) if (state > 0x1)
return; return;
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01)) {
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
return;
}
pmbase &= 0xFFFFFFFE;
if (!pmbase) {
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
return;
}
/* Disable IRQs */ /* Disable IRQs */
local_irq_save(flags); local_irq_save(flags);
@ -315,10 +329,11 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
cpus_allowed = current->cpus_allowed; cpus_allowed = current->cpus_allowed;
set_cpus_allowed(current, policy->cpus); set_cpus_allowed(current, policy->cpus);
/* detect low and high frequency */ /* detect low and high frequency and transition latency */
result = speedstep_get_freqs(speedstep_processor, result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency, &speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency, &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
&policy->cpuinfo.transition_latency,
&speedstep_set_state); &speedstep_set_state);
set_cpus_allowed(current, cpus_allowed); set_cpus_allowed(current, cpus_allowed);
if (result) if (result)
@ -335,7 +350,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */ /* cpuinfo and default policy values */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = speed; policy->cur = speed;
result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@ -400,6 +414,9 @@ static int __init speedstep_init(void)
return -EINVAL; return -EINVAL;
} }
if (speedstep_find_register())
return -ENODEV;
return cpufreq_register_driver(&speedstep_driver); return cpufreq_register_driver(&speedstep_driver);
} }

View File

@ -320,11 +320,13 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
unsigned int speedstep_get_freqs(unsigned int processor, unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed, unsigned int *low_speed,
unsigned int *high_speed, unsigned int *high_speed,
unsigned int *transition_latency,
void (*set_state) (unsigned int state)) void (*set_state) (unsigned int state))
{ {
unsigned int prev_speed; unsigned int prev_speed;
unsigned int ret = 0; unsigned int ret = 0;
unsigned long flags; unsigned long flags;
struct timeval tv1, tv2;
if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
return -EINVAL; return -EINVAL;
@ -337,7 +339,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
return -EIO; return -EIO;
dprintk("previous speed is %u\n", prev_speed); dprintk("previous speed is %u\n", prev_speed);
local_irq_save(flags); local_irq_save(flags);
/* switch to low state */ /* switch to low state */
@ -350,8 +352,17 @@ unsigned int speedstep_get_freqs(unsigned int processor,
dprintk("low speed is %u\n", *low_speed); dprintk("low speed is %u\n", *low_speed);
/* start latency measurement */
if (transition_latency)
do_gettimeofday(&tv1);
/* switch to high state */ /* switch to high state */
set_state(SPEEDSTEP_HIGH); set_state(SPEEDSTEP_HIGH);
/* end latency measurement */
if (transition_latency)
do_gettimeofday(&tv2);
*high_speed = speedstep_get_processor_frequency(processor); *high_speed = speedstep_get_processor_frequency(processor);
if (!*high_speed) { if (!*high_speed) {
ret = -EIO; ret = -EIO;
@ -369,6 +380,25 @@ unsigned int speedstep_get_freqs(unsigned int processor,
if (*high_speed != prev_speed) if (*high_speed != prev_speed)
set_state(SPEEDSTEP_LOW); set_state(SPEEDSTEP_LOW);
if (transition_latency) {
*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
tv2.tv_usec - tv1.tv_usec;
dprintk("transition latency is %u uSec\n", *transition_latency);
/* convert uSec to nSec and add 20% for safety reasons */
*transition_latency *= 1200;
/* check if the latency measurement is too high or too low
* and set it to a safe value (500uSec) in that case
*/
if (*transition_latency > 10000000 || *transition_latency < 50000) {
printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
"range (%u nSec), falling back to a safe one of %u nSec.\n",
*transition_latency, 500000);
*transition_latency = 500000;
}
}
out: out:
local_irq_restore(flags); local_irq_restore(flags);
return (ret); return (ret);

View File

@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
extern unsigned int speedstep_get_freqs(unsigned int processor, extern unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed, unsigned int *low_speed,
unsigned int *high_speed, unsigned int *high_speed,
unsigned int *transition_latency,
void (*set_state) (unsigned int state)); void (*set_state) (unsigned int state));

View File

@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
result = speedstep_get_freqs(speedstep_processor, result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency, &speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency, &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
NULL,
&speedstep_set_state); &speedstep_set_state);
if (result) { if (result) {

View File

@ -3,6 +3,7 @@
#include <linux/string.h> #include <linux/string.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/cpufreq.h>
/* /*
* Get CPU information for use by the procfs. * Get CPU information for use by the procfs.
@ -86,8 +87,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n"); seq_printf(m, "stepping\t: unknown\n");
if ( cpu_has(c, X86_FEATURE_TSC) ) { if ( cpu_has(c, X86_FEATURE_TSC) ) {
unsigned int freq = cpufreq_quick_get(n);
if (!freq)
freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n", seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
cpu_khz / 1000, (cpu_khz % 1000)); freq / 1000, (freq % 1000));
} }
/* Cache size */ /* Cache size */

View File

@ -452,7 +452,7 @@ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
#endif #endif
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow) DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds) DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip) DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun) DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS) DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)

View File

@ -43,6 +43,7 @@
#include <linux/initrd.h> #include <linux/initrd.h>
#include <linux/platform.h> #include <linux/platform.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/cpufreq.h>
#include <asm/ia32.h> #include <asm/ia32.h>
#include <asm/machvec.h> #include <asm/machvec.h>
@ -517,6 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v)
char family[32], features[128], *cp, sep; char family[32], features[128], *cp, sep;
struct cpuinfo_ia64 *c = v; struct cpuinfo_ia64 *c = v;
unsigned long mask; unsigned long mask;
unsigned int proc_freq;
int i; int i;
mask = c->features; mask = c->features;
@ -549,6 +551,10 @@ show_cpuinfo (struct seq_file *m, void *v)
sprintf(cp, " 0x%lx", mask); sprintf(cp, " 0x%lx", mask);
} }
proc_freq = cpufreq_quick_get(cpunum);
if (!proc_freq)
proc_freq = c->proc_freq / 1000;
seq_printf(m, seq_printf(m,
"processor : %d\n" "processor : %d\n"
"vendor : %s\n" "vendor : %s\n"
@ -565,7 +571,7 @@ show_cpuinfo (struct seq_file *m, void *v)
"BogoMIPS : %lu.%02lu\n", "BogoMIPS : %lu.%02lu\n",
cpunum, c->vendor, family, c->model, c->revision, c->archrev, cpunum, c->vendor, family, c->model, c->revision, c->archrev,
features, c->ppn, c->number, features, c->ppn, c->number,
c->proc_freq / 1000000, c->proc_freq % 1000000, proc_freq / 1000, proc_freq % 1000,
c->itc_freq / 1000000, c->itc_freq % 1000000, c->itc_freq / 1000000, c->itc_freq % 1000000,
lpj*HZ/500000, (lpj*HZ/5000) % 100); lpj*HZ/500000, (lpj*HZ/5000) % 100);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP

View File

@ -65,7 +65,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
} }
static int tiocx_hotplug(struct device *dev, char **envp, int num_envp, static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
return -ENODEV; return -ENODEV;
@ -79,7 +79,7 @@ static void tiocx_bus_release(struct device *dev)
struct bus_type tiocx_bus_type = { struct bus_type tiocx_bus_type = {
.name = "tiocx", .name = "tiocx",
.match = tiocx_match, .match = tiocx_match,
.hotplug = tiocx_hotplug, .uevent = tiocx_uevent,
}; };
/** /**

View File

@ -420,7 +420,7 @@ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
goto out; goto out;
pos = merge_64(a4, a5); pos = merge_64(a4, a5);
ret = rw_verify_area(READ, file, &pos, count); ret = rw_verify_area(READ, file, &pos, count);
if (ret) if (ret < 0)
goto out; goto out;
ret = -EINVAL; ret = -EINVAL;
if (!file->f_op || !(read = file->f_op->read)) if (!file->f_op || !(read = file->f_op->read))
@ -455,7 +455,7 @@ asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf,
goto out; goto out;
pos = merge_64(a4, a5); pos = merge_64(a4, a5);
ret = rw_verify_area(WRITE, file, &pos, count); ret = rw_verify_area(WRITE, file, &pos, count);
if (ret) if (ret < 0)
goto out; goto out;
ret = -EINVAL; ret = -EINVAL;
if (!file->f_op || !(write = file->f_op->write)) if (!file->f_op || !(write = file->f_op->write))

View File

@ -293,6 +293,6 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
struct bus_type vio_bus_type = { struct bus_type vio_bus_type = {
.name = "vio", .name = "vio",
.hotplug = vio_hotplug, .uevent = vio_hotplug,
.match = vio_bus_match, .match = vio_bus_match,
}; };

3
arch/x86_64/boot/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
bootsect
bzImage
setup

1
arch/x86_64/boot/tools/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

1
arch/x86_64/ia32/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
vsyscall*.so

View File

@ -42,6 +42,7 @@
#include <linux/edd.h> #include <linux/edd.h>
#include <linux/mmzone.h> #include <linux/mmzone.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/cpufreq.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -1256,8 +1257,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n"); seq_printf(m, "stepping\t: unknown\n");
if (cpu_has(c,X86_FEATURE_TSC)) { if (cpu_has(c,X86_FEATURE_TSC)) {
unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
if (!freq)
freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n", seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
cpu_khz / 1000, (cpu_khz % 1000)); freq / 1000, (freq % 1000));
} }
/* Cache size */ /* Cache size */

View File

@ -358,7 +358,7 @@ static struct sysfs_ops disk_sysfs_ops = {
static ssize_t disk_uevent_store(struct gendisk * disk, static ssize_t disk_uevent_store(struct gendisk * disk,
const char *buf, size_t count) const char *buf, size_t count)
{ {
kobject_hotplug(&disk->kobj, KOBJ_ADD); kobject_uevent(&disk->kobj, KOBJ_ADD);
return count; return count;
} }
static ssize_t disk_dev_read(struct gendisk * disk, char *page) static ssize_t disk_dev_read(struct gendisk * disk, char *page)
@ -455,14 +455,14 @@ static struct kobj_type ktype_block = {
extern struct kobj_type ktype_part; extern struct kobj_type ktype_part;
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj) static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
{ {
struct kobj_type *ktype = get_ktype(kobj); struct kobj_type *ktype = get_ktype(kobj);
return ((ktype == &ktype_block) || (ktype == &ktype_part)); return ((ktype == &ktype_block) || (ktype == &ktype_part));
} }
static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp, static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size) int num_envp, char *buffer, int buffer_size)
{ {
struct kobj_type *ktype = get_ktype(kobj); struct kobj_type *ktype = get_ktype(kobj);
@ -474,40 +474,40 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
if (ktype == &ktype_block) { if (ktype == &ktype_block) {
disk = container_of(kobj, struct gendisk, kobj); disk = container_of(kobj, struct gendisk, kobj);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "MINOR=%u", disk->first_minor); &length, "MINOR=%u", disk->first_minor);
} else if (ktype == &ktype_part) { } else if (ktype == &ktype_part) {
disk = container_of(kobj->parent, struct gendisk, kobj); disk = container_of(kobj->parent, struct gendisk, kobj);
part = container_of(kobj, struct hd_struct, kobj); part = container_of(kobj, struct hd_struct, kobj);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "MINOR=%u", &length, "MINOR=%u",
disk->first_minor + part->partno); disk->first_minor + part->partno);
} else } else
return 0; return 0;
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length, add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MAJOR=%u", disk->major); "MAJOR=%u", disk->major);
/* add physical device, backing this device */ /* add physical device, backing this device */
physdev = disk->driverfs_dev; physdev = disk->driverfs_dev;
if (physdev) { if (physdev) {
char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL); char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path); &length, "PHYSDEVPATH=%s", path);
kfree(path); kfree(path);
if (physdev->bus) if (physdev->bus)
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVBUS=%s", "PHYSDEVBUS=%s",
physdev->bus->name); physdev->bus->name);
if (physdev->driver) if (physdev->driver)
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", "PHYSDEVDRIVER=%s",
physdev->driver->name); physdev->driver->name);
} }
/* terminate, set to next free slot, shrink available space */ /* terminate, set to next free slot, shrink available space */
@ -520,13 +520,13 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
return 0; return 0;
} }
static struct kset_hotplug_ops block_hotplug_ops = { static struct kset_uevent_ops block_uevent_ops = {
.filter = block_hotplug_filter, .filter = block_uevent_filter,
.hotplug = block_hotplug, .uevent = block_uevent,
}; };
/* declare block_subsys. */ /* declare block_subsys. */
static decl_subsys(block, &ktype_block, &block_hotplug_ops); static decl_subsys(block, &ktype_block, &block_uevent_ops);
/* /*

View File

@ -239,7 +239,7 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
q->backing_dev_info.state = 0; q->backing_dev_info.state = 0;
q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY; q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
blk_queue_max_sectors(q, MAX_SECTORS); blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
blk_queue_hardsect_size(q, 512); blk_queue_hardsect_size(q, 512);
blk_queue_dma_alignment(q, 511); blk_queue_dma_alignment(q, 511);
blk_queue_congestion_threshold(q); blk_queue_congestion_threshold(q);
@ -555,7 +555,12 @@ void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors)
printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors); printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);
} }
q->max_sectors = q->max_hw_sectors = max_sectors; if (BLK_DEF_MAX_SECTORS > max_sectors)
q->max_hw_sectors = q->max_sectors = max_sectors;
else {
q->max_sectors = BLK_DEF_MAX_SECTORS;
q->max_hw_sectors = max_sectors;
}
} }
EXPORT_SYMBOL(blk_queue_max_sectors); EXPORT_SYMBOL(blk_queue_max_sectors);
@ -657,8 +662,8 @@ EXPORT_SYMBOL(blk_queue_hardsect_size);
void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b) void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
{ {
/* zero is "infinity" */ /* zero is "infinity" */
t->max_sectors = t->max_hw_sectors = t->max_sectors = min_not_zero(t->max_sectors,b->max_sectors);
min_not_zero(t->max_sectors,b->max_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors,b->max_hw_sectors);
t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments); t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments); t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
@ -1293,9 +1298,15 @@ static inline int ll_new_hw_segment(request_queue_t *q,
static int ll_back_merge_fn(request_queue_t *q, struct request *req, static int ll_back_merge_fn(request_queue_t *q, struct request *req,
struct bio *bio) struct bio *bio)
{ {
unsigned short max_sectors;
int len; int len;
if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) { if (unlikely(blk_pc_request(req)))
max_sectors = q->max_hw_sectors;
else
max_sectors = q->max_sectors;
if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
req->flags |= REQ_NOMERGE; req->flags |= REQ_NOMERGE;
if (req == q->last_merge) if (req == q->last_merge)
q->last_merge = NULL; q->last_merge = NULL;
@ -1325,9 +1336,16 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req,
static int ll_front_merge_fn(request_queue_t *q, struct request *req, static int ll_front_merge_fn(request_queue_t *q, struct request *req,
struct bio *bio) struct bio *bio)
{ {
unsigned short max_sectors;
int len; int len;
if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) { if (unlikely(blk_pc_request(req)))
max_sectors = q->max_hw_sectors;
else
max_sectors = q->max_sectors;
if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
req->flags |= REQ_NOMERGE; req->flags |= REQ_NOMERGE;
if (req == q->last_merge) if (req == q->last_merge)
q->last_merge = NULL; q->last_merge = NULL;
@ -2144,7 +2162,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
struct bio *bio; struct bio *bio;
int reading; int reading;
if (len > (q->max_sectors << 9)) if (len > (q->max_hw_sectors << 9))
return -EINVAL; return -EINVAL;
if (!len || !ubuf) if (!len || !ubuf)
return -EINVAL; return -EINVAL;
@ -2259,7 +2277,7 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
{ {
struct bio *bio; struct bio *bio;
if (len > (q->max_sectors << 9)) if (len > (q->max_hw_sectors << 9))
return -EINVAL; return -EINVAL;
if (!len || !kbuf) if (!len || !kbuf)
return -EINVAL; return -EINVAL;
@ -2306,6 +2324,8 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
generic_unplug_device(q); generic_unplug_device(q);
} }
EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
/** /**
* blk_execute_rq - insert a request into queue for execution * blk_execute_rq - insert a request into queue for execution
* @q: queue to insert the request in * @q: queue to insert the request in
@ -2444,7 +2464,7 @@ void disk_round_stats(struct gendisk *disk)
/* /*
* queue lock must be held * queue lock must be held
*/ */
static void __blk_put_request(request_queue_t *q, struct request *req) void __blk_put_request(request_queue_t *q, struct request *req)
{ {
struct request_list *rl = req->rl; struct request_list *rl = req->rl;
@ -2473,6 +2493,8 @@ static void __blk_put_request(request_queue_t *q, struct request *req)
} }
} }
EXPORT_SYMBOL_GPL(__blk_put_request);
void blk_put_request(struct request *req) void blk_put_request(struct request *req)
{ {
unsigned long flags; unsigned long flags;

View File

@ -233,7 +233,7 @@ static int sg_io(struct file *file, request_queue_t *q,
if (verify_command(file, cmd)) if (verify_command(file, cmd))
return -EPERM; return -EPERM;
if (hdr->dxfer_len > (q->max_sectors << 9)) if (hdr->dxfer_len > (q->max_hw_sectors << 9))
return -EIO; return -EIO;
if (hdr->dxfer_len) if (hdr->dxfer_len)

View File

@ -172,21 +172,21 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (ACPI_FAILURE(status) || !device) { if (ACPI_FAILURE(status) || !device) {
result = container_device_add(&device, handle); result = container_device_add(&device, handle);
if (!result) if (!result)
kobject_hotplug(&device->kobj, kobject_uevent(&device->kobj,
KOBJ_ONLINE); KOBJ_ONLINE);
else else
printk("Failed to add container\n"); printk("Failed to add container\n");
} }
} else { } else {
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
/* device exist and this is a remove request */ /* device exist and this is a remove request */
kobject_hotplug(&device->kobj, KOBJ_OFFLINE); kobject_uevent(&device->kobj, KOBJ_OFFLINE);
} }
} }
break; break;
case ACPI_NOTIFY_EJECT_REQUEST: case ACPI_NOTIFY_EJECT_REQUEST:
if (!acpi_bus_get_device(handle, &device) && device) { if (!acpi_bus_get_device(handle, &device) && device) {
kobject_hotplug(&device->kobj, KOBJ_OFFLINE); kobject_uevent(&device->kobj, KOBJ_OFFLINE);
} }
break; break;
default: default:

View File

@ -748,7 +748,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
if ((pr->id >= 0) && (pr->id < NR_CPUS)) { if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE); kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
} }
return_VALUE(0); return_VALUE(0);
} }
@ -788,13 +788,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
} }
if (pr->id >= 0 && (pr->id < NR_CPUS)) { if (pr->id >= 0 && (pr->id < NR_CPUS)) {
kobject_hotplug(&device->kobj, KOBJ_OFFLINE); kobject_uevent(&device->kobj, KOBJ_OFFLINE);
break; break;
} }
result = acpi_processor_start(device); result = acpi_processor_start(device);
if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) { if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
kobject_hotplug(&device->kobj, KOBJ_ONLINE); kobject_uevent(&device->kobj, KOBJ_ONLINE);
} else { } else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Device [%s] failed to start\n", "Device [%s] failed to start\n",
@ -818,7 +818,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
} }
if ((pr->id < NR_CPUS) && (cpu_present(pr->id))) if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
kobject_hotplug(&device->kobj, KOBJ_OFFLINE); kobject_uevent(&device->kobj, KOBJ_OFFLINE);
break; break;
default: default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,

View File

@ -78,7 +78,7 @@ static struct kobj_type ktype_acpi_ns = {
.release = acpi_device_release, .release = acpi_device_release,
}; };
static int namespace_hotplug(struct kset *kset, struct kobject *kobj, static int namespace_uevent(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer, char **envp, int num_envp, char *buffer,
int buffer_size) int buffer_size)
{ {
@ -89,8 +89,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
if (!dev->driver) if (!dev->driver)
return 0; return 0;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"PHYSDEVDRIVER=%s", dev->driver->name)) "PHYSDEVDRIVER=%s", dev->driver->name))
return -ENOMEM; return -ENOMEM;
envp[i] = NULL; envp[i] = NULL;
@ -98,8 +98,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
return 0; return 0;
} }
static struct kset_hotplug_ops namespace_hotplug_ops = { static struct kset_uevent_ops namespace_uevent_ops = {
.hotplug = &namespace_hotplug, .uevent = &namespace_uevent,
}; };
static struct kset acpi_namespace_kset = { static struct kset acpi_namespace_kset = {
@ -108,7 +108,7 @@ static struct kset acpi_namespace_kset = {
}, },
.subsys = &acpi_subsys, .subsys = &acpi_subsys,
.ktype = &ktype_acpi_ns, .ktype = &ktype_acpi_ns,
.hotplug_ops = &namespace_hotplug_ops, .uevent_ops = &namespace_uevent_ops,
}; };
static void acpi_device_register(struct acpi_device *device, static void acpi_device_register(struct acpi_device *device,
@ -347,7 +347,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
} }
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
ACPI hotplug sysfs device file support ACPI sysfs device file support
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
static ssize_t acpi_eject_store(struct acpi_device *device, static ssize_t acpi_eject_store(struct acpi_device *device,
const char *buf, size_t count); const char *buf, size_t count);

View File

@ -19,11 +19,11 @@ config PREVENT_FIRMWARE_BUILD
If unsure say Y here. If unsure say Y here.
config FW_LOADER config FW_LOADER
tristate "Hotplug firmware loading support" tristate "Userspace firmware loading support"
select HOTPLUG select HOTPLUG
---help--- ---help---
This option is provided for the case where no in-kernel-tree modules This option is provided for the case where no in-kernel-tree modules
require hotplug firmware loading support, but a module built outside require userspace firmware loading support, but a module built outside
the kernel tree does. the kernel tree does.
config DEBUG_DRIVER config DEBUG_DRIVER

View File

@ -152,7 +152,11 @@ static ssize_t driver_unbind(struct device_driver *drv,
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (dev && dev->driver == drv) { if (dev && dev->driver == drv) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
device_release_driver(dev); device_release_driver(dev);
if (dev->parent)
up(&dev->parent->sem);
err = count; err = count;
} }
put_device(dev); put_device(dev);
@ -175,9 +179,13 @@ static ssize_t driver_bind(struct device_driver *drv,
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (dev && dev->driver == NULL) { if (dev && dev->driver == NULL) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem); down(&dev->sem);
err = driver_probe_device(drv, dev); err = driver_probe_device(drv, dev);
up(&dev->sem); up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
} }
put_device(dev); put_device(dev);
put_bus(bus); put_bus(bus);
@ -420,6 +428,26 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr
} }
} }
#ifdef CONFIG_HOTPLUG
/*
* Thanks to drivers making their tables __devinit, we can't allow manual
* bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
*/
static void add_bind_files(struct device_driver *drv)
{
driver_create_file(drv, &driver_attr_unbind);
driver_create_file(drv, &driver_attr_bind);
}
static void remove_bind_files(struct device_driver *drv)
{
driver_remove_file(drv, &driver_attr_bind);
driver_remove_file(drv, &driver_attr_unbind);
}
#else
static inline void add_bind_files(struct device_driver *drv) {}
static inline void remove_bind_files(struct device_driver *drv) {}
#endif
/** /**
* bus_add_driver - Add a driver to the bus. * bus_add_driver - Add a driver to the bus.
@ -449,8 +477,7 @@ int bus_add_driver(struct device_driver * drv)
module_add_driver(drv->owner, drv); module_add_driver(drv->owner, drv);
driver_add_attrs(bus, drv); driver_add_attrs(bus, drv);
driver_create_file(drv, &driver_attr_unbind); add_bind_files(drv);
driver_create_file(drv, &driver_attr_bind);
} }
return error; return error;
} }
@ -468,8 +495,7 @@ int bus_add_driver(struct device_driver * drv)
void bus_remove_driver(struct device_driver * drv) void bus_remove_driver(struct device_driver * drv)
{ {
if (drv->bus) { if (drv->bus) {
driver_remove_file(drv, &driver_attr_bind); remove_bind_files(drv);
driver_remove_file(drv, &driver_attr_unbind);
driver_remove_attrs(drv->bus, drv); driver_remove_attrs(drv->bus, drv);
klist_remove(&drv->knode_bus); klist_remove(&drv->knode_bus);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
@ -484,8 +510,13 @@ void bus_remove_driver(struct device_driver * drv)
/* Helper for bus_rescan_devices's iter */ /* Helper for bus_rescan_devices's iter */
static int bus_rescan_devices_helper(struct device *dev, void *data) static int bus_rescan_devices_helper(struct device *dev, void *data)
{ {
if (!dev->driver) if (!dev->driver) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
device_attach(dev); device_attach(dev);
if (dev->parent)
up(&dev->parent->sem);
}
return 0; return 0;
} }

View File

@ -178,7 +178,7 @@ static void class_device_create_release(struct class_device *class_dev)
} }
/* needed to allow these devices to have parent class devices */ /* needed to allow these devices to have parent class devices */
static int class_device_create_hotplug(struct class_device *class_dev, static int class_device_create_uevent(struct class_device *class_dev,
char **envp, int num_envp, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
@ -331,7 +331,7 @@ static struct kobj_type ktype_class_device = {
.release = class_dev_release, .release = class_dev_release,
}; };
static int class_hotplug_filter(struct kset *kset, struct kobject *kobj) static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
{ {
struct kobj_type *ktype = get_ktype(kobj); struct kobj_type *ktype = get_ktype(kobj);
@ -343,14 +343,14 @@ static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
return 0; return 0;
} }
static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj) static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
{ {
struct class_device *class_dev = to_class_dev(kobj); struct class_device *class_dev = to_class_dev(kobj);
return class_dev->class->name; return class_dev->class->name;
} }
static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp, static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size) int num_envp, char *buffer, int buffer_size)
{ {
struct class_device *class_dev = to_class_dev(kobj); struct class_device *class_dev = to_class_dev(kobj);
@ -365,29 +365,29 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
struct device *dev = class_dev->dev; struct device *dev = class_dev->dev;
char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path); &length, "PHYSDEVPATH=%s", path);
kfree(path); kfree(path);
if (dev->bus) if (dev->bus)
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVBUS=%s", dev->bus->name); "PHYSDEVBUS=%s", dev->bus->name);
if (dev->driver) if (dev->driver)
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name); "PHYSDEVDRIVER=%s", dev->driver->name);
} }
if (MAJOR(class_dev->devt)) { if (MAJOR(class_dev->devt)) {
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"MAJOR=%u", MAJOR(class_dev->devt)); "MAJOR=%u", MAJOR(class_dev->devt));
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"MINOR=%u", MINOR(class_dev->devt)); "MINOR=%u", MINOR(class_dev->devt));
} }
/* terminate, set to next free slot, shrink available space */ /* terminate, set to next free slot, shrink available space */
@ -397,30 +397,30 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length]; buffer = &buffer[length];
buffer_size -= length; buffer_size -= length;
if (class_dev->hotplug) { if (class_dev->uevent) {
/* have the class device specific function add its stuff */ /* have the class device specific function add its stuff */
retval = class_dev->hotplug(class_dev, envp, num_envp, retval = class_dev->uevent(class_dev, envp, num_envp,
buffer, buffer_size); buffer, buffer_size);
if (retval) if (retval)
pr_debug("class_dev->hotplug() returned %d\n", retval); pr_debug("class_dev->uevent() returned %d\n", retval);
} else if (class_dev->class->hotplug) { } else if (class_dev->class->uevent) {
/* have the class specific function add its stuff */ /* have the class specific function add its stuff */
retval = class_dev->class->hotplug(class_dev, envp, num_envp, retval = class_dev->class->uevent(class_dev, envp, num_envp,
buffer, buffer_size); buffer, buffer_size);
if (retval) if (retval)
pr_debug("class->hotplug() returned %d\n", retval); pr_debug("class->uevent() returned %d\n", retval);
} }
return retval; return retval;
} }
static struct kset_hotplug_ops class_hotplug_ops = { static struct kset_uevent_ops class_uevent_ops = {
.filter = class_hotplug_filter, .filter = class_uevent_filter,
.name = class_hotplug_name, .name = class_uevent_name,
.hotplug = class_hotplug, .uevent = class_uevent,
}; };
static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops); static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);
static int class_device_add_attrs(struct class_device * cd) static int class_device_add_attrs(struct class_device * cd)
@ -464,7 +464,7 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
static ssize_t store_uevent(struct class_device *class_dev, static ssize_t store_uevent(struct class_device *class_dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
kobject_hotplug(&class_dev->kobj, KOBJ_ADD); kobject_uevent(&class_dev->kobj, KOBJ_ADD);
return count; return count;
} }
@ -559,7 +559,7 @@ int class_device_add(struct class_device *class_dev)
class_name); class_name);
} }
kobject_hotplug(&class_dev->kobj, KOBJ_ADD); kobject_uevent(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */ /* notify any interfaces this device is now here */
if (parent_class) { if (parent_class) {
@ -632,7 +632,7 @@ struct class_device *class_device_create(struct class *cls,
class_dev->class = cls; class_dev->class = cls;
class_dev->parent = parent; class_dev->parent = parent;
class_dev->release = class_device_create_release; class_dev->release = class_device_create_release;
class_dev->hotplug = class_device_create_hotplug; class_dev->uevent = class_device_create_uevent;
va_start(args, fmt); va_start(args, fmt);
vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@ -674,7 +674,7 @@ void class_device_del(struct class_device *class_dev)
class_device_remove_file(class_dev, class_dev->devt_attr); class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev); class_device_remove_attrs(class_dev);
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj); kobject_del(&class_dev->kobj);
class_device_put(parent_device); class_device_put(parent_device);

View File

@ -90,7 +90,7 @@ static struct kobj_type ktype_device = {
}; };
static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj) static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
{ {
struct kobj_type *ktype = get_ktype(kobj); struct kobj_type *ktype = get_ktype(kobj);
@ -102,14 +102,14 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
return 0; return 0;
} }
static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj) static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
{ {
struct device *dev = to_dev(kobj); struct device *dev = to_dev(kobj);
return dev->bus->name; return dev->bus->name;
} }
static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp, static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size) int num_envp, char *buffer, int buffer_size)
{ {
struct device *dev = to_dev(kobj); struct device *dev = to_dev(kobj);
@ -119,15 +119,15 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
/* add bus name of physical device */ /* add bus name of physical device */
if (dev->bus) if (dev->bus)
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVBUS=%s", dev->bus->name); "PHYSDEVBUS=%s", dev->bus->name);
/* add driver name of physical device */ /* add driver name of physical device */
if (dev->driver) if (dev->driver)
add_hotplug_env_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name); "PHYSDEVDRIVER=%s", dev->driver->name);
/* terminate, set to next free slot, shrink available space */ /* terminate, set to next free slot, shrink available space */
envp[i] = NULL; envp[i] = NULL;
@ -136,11 +136,11 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length]; buffer = &buffer[length];
buffer_size -= length; buffer_size -= length;
if (dev->bus && dev->bus->hotplug) { if (dev->bus && dev->bus->uevent) {
/* have the bus specific function add its stuff */ /* have the bus specific function add its stuff */
retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size); retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
if (retval) { if (retval) {
pr_debug ("%s - hotplug() returned %d\n", pr_debug ("%s - uevent() returned %d\n",
__FUNCTION__, retval); __FUNCTION__, retval);
} }
} }
@ -148,16 +148,16 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
return retval; return retval;
} }
static struct kset_hotplug_ops device_hotplug_ops = { static struct kset_uevent_ops device_uevent_ops = {
.filter = dev_hotplug_filter, .filter = dev_uevent_filter,
.name = dev_hotplug_name, .name = dev_uevent_name,
.hotplug = dev_hotplug, .uevent = dev_uevent,
}; };
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
kobject_hotplug(&dev->kobj, KOBJ_ADD); kobject_uevent(&dev->kobj, KOBJ_ADD);
return count; return count;
} }
@ -165,7 +165,7 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
* device_subsys - structure to be registered with kobject core. * device_subsys - structure to be registered with kobject core.
*/ */
decl_subsys(devices, &ktype_device, &device_hotplug_ops); decl_subsys(devices, &ktype_device, &device_uevent_ops);
/** /**
@ -274,7 +274,7 @@ int device_add(struct device *dev)
dev->uevent_attr.store = store_uevent; dev->uevent_attr.store = store_uevent;
device_create_file(dev, &dev->uevent_attr); device_create_file(dev, &dev->uevent_attr);
kobject_hotplug(&dev->kobj, KOBJ_ADD); kobject_uevent(&dev->kobj, KOBJ_ADD);
if ((error = device_pm_add(dev))) if ((error = device_pm_add(dev)))
goto PMError; goto PMError;
if ((error = bus_add_device(dev))) if ((error = bus_add_device(dev)))
@ -291,7 +291,7 @@ int device_add(struct device *dev)
BusError: BusError:
device_pm_remove(dev); device_pm_remove(dev);
PMError: PMError:
kobject_hotplug(&dev->kobj, KOBJ_REMOVE); kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj); kobject_del(&dev->kobj);
Error: Error:
if (parent) if (parent)
@ -374,7 +374,7 @@ void device_del(struct device * dev)
platform_notify_remove(dev); platform_notify_remove(dev);
bus_remove_device(dev); bus_remove_device(dev);
device_pm_remove(dev); device_pm_remove(dev);
kobject_hotplug(&dev->kobj, KOBJ_REMOVE); kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj); kobject_del(&dev->kobj);
if (parent) if (parent)
put_device(parent); put_device(parent);

View File

@ -41,14 +41,14 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
case '0': case '0':
ret = cpu_down(cpu->sysdev.id); ret = cpu_down(cpu->sysdev.id);
if (!ret) if (!ret)
kobject_hotplug(&dev->kobj, KOBJ_OFFLINE); kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
break; break;
case '1': case '1':
ret = smp_prepare_cpu(cpu->sysdev.id); ret = smp_prepare_cpu(cpu->sysdev.id);
if (!ret) if (!ret)
ret = cpu_up(cpu->sysdev.id); ret = cpu_up(cpu->sysdev.id);
if (!ret) if (!ret)
kobject_hotplug(&dev->kobj, KOBJ_ONLINE); kobject_uevent(&dev->kobj, KOBJ_ONLINE);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;

View File

@ -65,7 +65,8 @@ void device_bind_driver(struct device * dev)
* This function returns 1 if a match is found, an error if one * This function returns 1 if a match is found, an error if one
* occurs (that is not -ENODEV or -ENXIO), and 0 otherwise. * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
* *
* This function must be called with @dev->sem held. * This function must be called with @dev->sem held. When called
* for a USB interface, @dev->parent->sem must be held as well.
*/ */
int driver_probe_device(struct device_driver * drv, struct device * dev) int driver_probe_device(struct device_driver * drv, struct device * dev)
{ {
@ -123,6 +124,8 @@ static int __device_attach(struct device_driver * drv, void * data)
* *
* Returns 1 if the device was bound to a driver; * Returns 1 if the device was bound to a driver;
* 0 if no matching device was found; error code otherwise. * 0 if no matching device was found; error code otherwise.
*
* When called for a USB interface, @dev->parent->sem must be held.
*/ */
int device_attach(struct device * dev) int device_attach(struct device * dev)
{ {
@ -152,10 +155,14 @@ static int __driver_attach(struct device * dev, void * data)
* is an error. * is an error.
*/ */
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem); down(&dev->sem);
if (!dev->driver) if (!dev->driver)
driver_probe_device(drv, dev); driver_probe_device(drv, dev);
up(&dev->sem); up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0; return 0;
} }
@ -181,6 +188,8 @@ void driver_attach(struct device_driver * drv)
* Manually detach device from driver. * Manually detach device from driver.
* *
* __device_release_driver() must be called with @dev->sem held. * __device_release_driver() must be called with @dev->sem held.
* When called for a USB interface, @dev->parent->sem must be held
* as well.
*/ */
static void __device_release_driver(struct device * dev) static void __device_release_driver(struct device * dev)
@ -233,10 +242,14 @@ void driver_detach(struct device_driver * drv)
get_device(dev); get_device(dev);
spin_unlock(&drv->klist_devices.k_lock); spin_unlock(&drv->klist_devices.k_lock);
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem); down(&dev->sem);
if (dev->driver == drv) if (dev->driver == drv)
__device_release_driver(dev); __device_release_driver(dev);
up(&dev->sem); up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
put_device(dev); put_device(dev);
} }
} }

View File

@ -85,17 +85,17 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
static void fw_class_dev_release(struct class_device *class_dev); static void fw_class_dev_release(struct class_device *class_dev);
int firmware_class_hotplug(struct class_device *dev, char **envp, int firmware_class_uevent(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size); int num_envp, char *buffer, int buffer_size);
static struct class firmware_class = { static struct class firmware_class = {
.name = "firmware", .name = "firmware",
.hotplug = firmware_class_hotplug, .uevent = firmware_class_uevent,
.release = fw_class_dev_release, .release = fw_class_dev_release,
}; };
int int
firmware_class_hotplug(struct class_device *class_dev, char **envp, firmware_class_uevent(struct class_device *class_dev, char **envp,
int num_envp, char *buffer, int buffer_size) int num_envp, char *buffer, int buffer_size)
{ {
struct firmware_priv *fw_priv = class_get_devdata(class_dev); struct firmware_priv *fw_priv = class_get_devdata(class_dev);
@ -104,13 +104,12 @@ firmware_class_hotplug(struct class_device *class_dev, char **envp,
if (!test_bit(FW_STATUS_READY, &fw_priv->status)) if (!test_bit(FW_STATUS_READY, &fw_priv->status))
return -ENODEV; return -ENODEV;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"FIRMWARE=%s", fw_priv->fw_id)) "FIRMWARE=%s", fw_priv->fw_id))
return -ENOMEM; return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"TIMEOUT=%i", loading_timeout)) "TIMEOUT=%i", loading_timeout))
return -ENOMEM; return -ENOMEM;
envp[i] = NULL; envp[i] = NULL;
return 0; return 0;
@ -352,7 +351,7 @@ error_kfree:
static int static int
fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
const char *fw_name, struct device *device, int hotplug) const char *fw_name, struct device *device, int uevent)
{ {
struct class_device *class_dev; struct class_device *class_dev;
struct firmware_priv *fw_priv; struct firmware_priv *fw_priv;
@ -384,7 +383,7 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
goto error_unreg; goto error_unreg;
} }
if (hotplug) if (uevent)
set_bit(FW_STATUS_READY, &fw_priv->status); set_bit(FW_STATUS_READY, &fw_priv->status);
else else
set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
@ -399,7 +398,7 @@ out:
static int static int
_request_firmware(const struct firmware **firmware_p, const char *name, _request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device, int hotplug) struct device *device, int uevent)
{ {
struct class_device *class_dev; struct class_device *class_dev;
struct firmware_priv *fw_priv; struct firmware_priv *fw_priv;
@ -418,19 +417,19 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
} }
retval = fw_setup_class_device(firmware, &class_dev, name, device, retval = fw_setup_class_device(firmware, &class_dev, name, device,
hotplug); uevent);
if (retval) if (retval)
goto error_kfree_fw; goto error_kfree_fw;
fw_priv = class_get_devdata(class_dev); fw_priv = class_get_devdata(class_dev);
if (hotplug) { if (uevent) {
if (loading_timeout > 0) { if (loading_timeout > 0) {
fw_priv->timeout.expires = jiffies + loading_timeout * HZ; fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
add_timer(&fw_priv->timeout); add_timer(&fw_priv->timeout);
} }
kobject_hotplug(&class_dev->kobj, KOBJ_ADD); kobject_uevent(&class_dev->kobj, KOBJ_ADD);
wait_for_completion(&fw_priv->completion); wait_for_completion(&fw_priv->completion);
set_bit(FW_STATUS_DONE, &fw_priv->status); set_bit(FW_STATUS_DONE, &fw_priv->status);
del_timer_sync(&fw_priv->timeout); del_timer_sync(&fw_priv->timeout);
@ -456,7 +455,7 @@ out:
} }
/** /**
* request_firmware: - request firmware to hotplug and wait for it * request_firmware: - send firmware request and wait for it
* @firmware_p: pointer to firmware image * @firmware_p: pointer to firmware image
* @name: name of firmware file * @name: name of firmware file
* @device: device for which firmware is being loaded * @device: device for which firmware is being loaded
@ -466,7 +465,7 @@ out:
* *
* Should be called from user context where sleeping is allowed. * Should be called from user context where sleeping is allowed.
* *
* @name will be used as $FIRMWARE in the hotplug environment and * @name will be used as $FIRMWARE in the uevent environment and
* should be distinctive enough not to be confused with any other * should be distinctive enough not to be confused with any other
* firmware image for this or any other device. * firmware image for this or any other device.
**/ **/
@ -474,8 +473,8 @@ int
request_firmware(const struct firmware **firmware_p, const char *name, request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device) struct device *device)
{ {
int hotplug = 1; int uevent = 1;
return _request_firmware(firmware_p, name, device, hotplug); return _request_firmware(firmware_p, name, device, uevent);
} }
/** /**
@ -518,7 +517,7 @@ struct firmware_work {
struct device *device; struct device *device;
void *context; void *context;
void (*cont)(const struct firmware *fw, void *context); void (*cont)(const struct firmware *fw, void *context);
int hotplug; int uevent;
}; };
static int static int
@ -533,7 +532,7 @@ request_firmware_work_func(void *arg)
} }
daemonize("%s/%s", "firmware", fw_work->name); daemonize("%s/%s", "firmware", fw_work->name);
ret = _request_firmware(&fw, fw_work->name, fw_work->device, ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->hotplug); fw_work->uevent);
if (ret < 0) if (ret < 0)
fw_work->cont(NULL, fw_work->context); fw_work->cont(NULL, fw_work->context);
else { else {
@ -548,7 +547,7 @@ request_firmware_work_func(void *arg)
/** /**
* request_firmware_nowait: asynchronous version of request_firmware * request_firmware_nowait: asynchronous version of request_firmware
* @module: module requesting the firmware * @module: module requesting the firmware
* @hotplug: invokes hotplug event to copy the firmware image if this flag * @uevent: sends uevent to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually. * is non-zero else the firmware copy must be done manually.
* @name: name of firmware file * @name: name of firmware file
* @device: device for which firmware is being loaded * @device: device for which firmware is being loaded
@ -562,7 +561,7 @@ request_firmware_work_func(void *arg)
**/ **/
int int
request_firmware_nowait( request_firmware_nowait(
struct module *module, int hotplug, struct module *module, int uevent,
const char *name, struct device *device, void *context, const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context)) void (*cont)(const struct firmware *fw, void *context))
{ {
@ -583,7 +582,7 @@ request_firmware_nowait(
.device = device, .device = device,
.context = context, .context = context,
.cont = cont, .cont = cont,
.hotplug = hotplug, .uevent = uevent,
}; };
ret = kernel_thread(request_firmware_work_func, fw_work, ret = kernel_thread(request_firmware_work_func, fw_work,

View File

@ -29,12 +29,12 @@ static struct sysdev_class memory_sysdev_class = {
set_kset_name(MEMORY_CLASS_NAME), set_kset_name(MEMORY_CLASS_NAME),
}; };
static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj) static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
{ {
return MEMORY_CLASS_NAME; return MEMORY_CLASS_NAME;
} }
static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp, static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size) int num_envp, char *buffer, int buffer_size)
{ {
int retval = 0; int retval = 0;
@ -42,9 +42,9 @@ static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
return retval; return retval;
} }
static struct kset_hotplug_ops memory_hotplug_ops = { static struct kset_uevent_ops memory_uevent_ops = {
.name = memory_hotplug_name, .name = memory_uevent_name,
.hotplug = memory_hotplug, .uevent = memory_uevent,
}; };
static struct notifier_block *memory_chain; static struct notifier_block *memory_chain;
@ -431,7 +431,7 @@ int __init memory_dev_init(void)
unsigned int i; unsigned int i;
int ret; int ret;
memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
ret = sysdev_class_register(&memory_sysdev_class); ret = sysdev_class_register(&memory_sysdev_class);
/* /*

View File

@ -25,6 +25,7 @@
struct device platform_bus = { struct device platform_bus = {
.bus_id = "platform", .bus_id = "platform",
}; };
EXPORT_SYMBOL_GPL(platform_bus);
/** /**
* platform_get_resource - get a resource for a device * platform_get_resource - get a resource for a device
@ -49,6 +50,7 @@ platform_get_resource(struct platform_device *dev, unsigned int type,
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(platform_get_resource);
/** /**
* platform_get_irq - get an IRQ for a device * platform_get_irq - get an IRQ for a device
@ -61,6 +63,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
return r ? r->start : 0; return r ? r->start : 0;
} }
EXPORT_SYMBOL_GPL(platform_get_irq);
/** /**
* platform_get_resource_byname - get a resource for a device by name * platform_get_resource_byname - get a resource for a device by name
@ -84,6 +87,7 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type,
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(platform_get_resource_byname);
/** /**
* platform_get_irq - get an IRQ for a device * platform_get_irq - get an IRQ for a device
@ -96,6 +100,7 @@ int platform_get_irq_byname(struct platform_device *dev, char *name)
return r ? r->start : 0; return r ? r->start : 0;
} }
EXPORT_SYMBOL_GPL(platform_get_irq_byname);
/** /**
* platform_add_devices - add a numbers of platform devices * platform_add_devices - add a numbers of platform devices
@ -117,6 +122,7 @@ int platform_add_devices(struct platform_device **devs, int num)
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(platform_add_devices);
struct platform_object { struct platform_object {
struct platform_device pdev; struct platform_device pdev;
@ -168,7 +174,7 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
pa->pdev.dev.release = platform_device_release; pa->pdev.dev.release = platform_device_release;
} }
return pa ? &pa->pdev : NULL; return pa ? &pa->pdev : NULL;
} }
EXPORT_SYMBOL_GPL(platform_device_alloc); EXPORT_SYMBOL_GPL(platform_device_alloc);
@ -257,7 +263,7 @@ int platform_device_add(struct platform_device *pdev)
p = &ioport_resource; p = &ioport_resource;
} }
if (p && request_resource(p, r)) { if (p && insert_resource(p, r)) {
printk(KERN_ERR printk(KERN_ERR
"%s: failed to claim resource %d\n", "%s: failed to claim resource %d\n",
pdev->dev.bus_id, i); pdev->dev.bus_id, i);
@ -282,24 +288,13 @@ int platform_device_add(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_add); EXPORT_SYMBOL_GPL(platform_device_add);
/** /**
* platform_device_register - add a platform-level device * platform_device_del - remove a platform-level device
* @pdev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
/**
* platform_device_unregister - remove a platform-level device
* @pdev: platform device we're removing * @pdev: platform device we're removing
* *
* Note that this function will also release all memory- and port-based * Note that this function will also release all memory- and port-based
* resources owned by the device (@dev->resource). * resources owned by the device (@dev->resource).
*/ */
void platform_device_unregister(struct platform_device * pdev) void platform_device_del(struct platform_device *pdev)
{ {
int i; int i;
@ -310,9 +305,37 @@ void platform_device_unregister(struct platform_device * pdev)
release_resource(r); release_resource(r);
} }
device_unregister(&pdev->dev); device_del(&pdev->dev);
} }
} }
EXPORT_SYMBOL_GPL(platform_device_del);
/**
* platform_device_register - add a platform-level device
* @pdev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_register);
/**
* platform_device_unregister - unregister a platform-level device
* @pdev: platform device we're unregistering
*
* Unregistration is done in 2 steps. Fisrt we release all resources
* and remove it from the sybsystem, then we drop reference count by
* calling platform_device_put().
*/
void platform_device_unregister(struct platform_device * pdev)
{
platform_device_del(pdev);
platform_device_put(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_unregister);
/** /**
* platform_device_register_simple * platform_device_register_simple
@ -355,6 +378,7 @@ error:
platform_device_put(pdev); platform_device_put(pdev);
return ERR_PTR(retval); return ERR_PTR(retval);
} }
EXPORT_SYMBOL_GPL(platform_device_register_simple);
static int platform_drv_probe(struct device *_dev) static int platform_drv_probe(struct device *_dev)
{ {
@ -476,6 +500,7 @@ struct bus_type platform_bus_type = {
.suspend = platform_suspend, .suspend = platform_suspend,
.resume = platform_resume, .resume = platform_resume,
}; };
EXPORT_SYMBOL_GPL(platform_bus_type);
int __init platform_bus_init(void) int __init platform_bus_init(void)
{ {
@ -504,14 +529,3 @@ u64 dma_get_required_mask(struct device *dev)
} }
EXPORT_SYMBOL_GPL(dma_get_required_mask); EXPORT_SYMBOL_GPL(dma_get_required_mask);
#endif #endif
EXPORT_SYMBOL_GPL(platform_bus);
EXPORT_SYMBOL_GPL(platform_bus_type);
EXPORT_SYMBOL_GPL(platform_add_devices);
EXPORT_SYMBOL_GPL(platform_device_register);
EXPORT_SYMBOL_GPL(platform_device_register_simple);
EXPORT_SYMBOL_GPL(platform_device_unregister);
EXPORT_SYMBOL_GPL(platform_get_irq);
EXPORT_SYMBOL_GPL(platform_get_resource);
EXPORT_SYMBOL_GPL(platform_get_irq_byname);
EXPORT_SYMBOL_GPL(platform_get_resource_byname);

View File

@ -64,6 +64,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
} }
#if 0
/** /**
* dpm_set_power_state - Update power_state field. * dpm_set_power_state - Update power_state field.
* @dev: Device. * @dev: Device.
@ -80,3 +81,4 @@ void dpm_set_power_state(struct device * dev, pm_message_t state)
dev->power.power_state = state; dev->power.power_state = state;
up(&dpm_sem); up(&dpm_sem);
} }
#endif /* 0 */

View File

@ -358,7 +358,8 @@ config BLK_DEV_UB
This driver supports certain USB attached storage devices This driver supports certain USB attached storage devices
such as flash keys. such as flash keys.
Warning: Enabling this cripples the usb-storage driver. If you enable this driver, it is recommended to avoid conflicts
with usb-storage by enabling USB_LIBUSUAL.
If unsure, say N. If unsure, say N.

View File

@ -9,7 +9,6 @@
* *
* TODO (sorted by decreasing priority) * TODO (sorted by decreasing priority)
* -- Kill first_open (Al Viro fixed the block layer now) * -- Kill first_open (Al Viro fixed the block layer now)
* -- Do resets with usb_device_reset (needs a thread context, use khubd)
* -- set readonly flag for CDs, set removable flag for CF readers * -- set readonly flag for CDs, set removable flag for CF readers
* -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
* -- special case some senses, e.g. 3a/0 -> no media present, reduce retries * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
@ -29,6 +28,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb_usual.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#include <linux/timer.h> #include <linux/timer.h>
@ -106,16 +106,6 @@
* +--------+ * +--------+
*/ */
/*
* Definitions which have to be scattered once we understand the layout better.
*/
/* Transport (despite PR in the name) */
#define US_PR_BULK 0x50 /* bulk only */
/* Protocol */
#define US_SC_SCSI 0x06 /* Transparent */
/* /*
* This many LUNs per USB device. * This many LUNs per USB device.
* Every one of them takes a host, see UB_MAX_HOSTS. * Every one of them takes a host, see UB_MAX_HOSTS.
@ -125,7 +115,7 @@
/* /*
*/ */
#define UB_MINORS_PER_MAJOR 8 #define UB_PARTS_PER_LUN 8
#define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */
@ -245,6 +235,13 @@ struct ub_scsi_cmd {
void *back; void *back;
}; };
struct ub_request {
struct request *rq;
unsigned int current_try;
unsigned int nsg; /* sgv[nsg] */
struct scatterlist sgv[UB_MAX_REQ_SG];
};
/* /*
*/ */
struct ub_capacity { struct ub_capacity {
@ -340,6 +337,8 @@ struct ub_lun {
int readonly; int readonly;
int first_open; /* Kludge. See ub_bd_open. */ int first_open; /* Kludge. See ub_bd_open. */
struct ub_request urq;
/* Use Ingo's mempool if or when we have more than one command. */ /* Use Ingo's mempool if or when we have more than one command. */
/* /*
* Currently we never need more than one command for the whole device. * Currently we never need more than one command for the whole device.
@ -360,6 +359,7 @@ struct ub_dev {
atomic_t poison; /* The USB device is disconnected */ atomic_t poison; /* The USB device is disconnected */
int openc; /* protected by ub_lock! */ int openc; /* protected by ub_lock! */
/* kref is too implicit for our taste */ /* kref is too implicit for our taste */
int reset; /* Reset is running */
unsigned int tagcnt; unsigned int tagcnt;
char name[12]; char name[12];
struct usb_device *dev; struct usb_device *dev;
@ -387,6 +387,9 @@ struct ub_dev {
struct bulk_cs_wrap work_bcs; struct bulk_cs_wrap work_bcs;
struct usb_ctrlrequest work_cr; struct usb_ctrlrequest work_cr;
struct work_struct reset_work;
wait_queue_head_t reset_wait;
int sg_stat[6]; int sg_stat[6];
struct ub_scsi_trace tr; struct ub_scsi_trace tr;
}; };
@ -395,12 +398,14 @@ struct ub_dev {
*/ */
static void ub_cleanup(struct ub_dev *sc); static void ub_cleanup(struct ub_dev *sc);
static int ub_request_fn_1(struct ub_lun *lun, struct request *rq); static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct request *rq); struct ub_scsi_cmd *cmd, struct ub_request *urq);
static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct request *rq); struct ub_scsi_cmd *cmd, struct ub_request *urq);
static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_end_rq(struct request *rq, int uptodate); static void ub_end_rq(struct request *rq, int uptodate);
static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
struct ub_request *urq, struct ub_scsi_cmd *cmd);
static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
static void ub_scsi_action(unsigned long _dev); static void ub_scsi_action(unsigned long _dev);
@ -415,6 +420,8 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
int stalled_pipe); int stalled_pipe);
static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
static void ub_reset_enter(struct ub_dev *sc);
static void ub_reset_task(void *arg);
static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
struct ub_capacity *ret); struct ub_capacity *ret);
@ -422,13 +429,18 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
/* /*
*/ */
#ifdef CONFIG_USB_LIBUSUAL
#define ub_usb_ids storage_usb_ids
#else
static struct usb_device_id ub_usb_ids[] = { static struct usb_device_id ub_usb_ids[] = {
// { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
{ } { }
}; };
MODULE_DEVICE_TABLE(usb, ub_usb_ids); MODULE_DEVICE_TABLE(usb, ub_usb_ids);
#endif /* CONFIG_USB_LIBUSUAL */
/* /*
* Find me a way to identify "next free minor" for add_disk(), * Find me a way to identify "next free minor" for add_disk(),
@ -521,6 +533,9 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr,
cnt = 0; cnt = 0;
spin_lock_irqsave(&sc->lock, flags); spin_lock_irqsave(&sc->lock, flags);
cnt += sprintf(page + cnt,
"poison %d reset %d\n",
atomic_read(&sc->poison), sc->reset);
cnt += sprintf(page + cnt, cnt += sprintf(page + cnt,
"qlen %d qmax %d\n", "qlen %d qmax %d\n",
sc->cmd_queue.qlen, sc->cmd_queue.qmax); sc->cmd_queue.qlen, sc->cmd_queue.qmax);
@ -770,7 +785,8 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
{ {
struct ub_dev *sc = lun->udev; struct ub_dev *sc = lun->udev;
struct ub_scsi_cmd *cmd; struct ub_scsi_cmd *cmd;
int rc; struct ub_request *urq;
int n_elem;
if (atomic_read(&sc->poison) || lun->changed) { if (atomic_read(&sc->poison) || lun->changed) {
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
@ -778,66 +794,71 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
return 0; return 0;
} }
if (lun->urq.rq != NULL)
return -1;
if ((cmd = ub_get_cmd(lun)) == NULL) if ((cmd = ub_get_cmd(lun)) == NULL)
return -1; return -1;
memset(cmd, 0, sizeof(struct ub_scsi_cmd)); memset(cmd, 0, sizeof(struct ub_scsi_cmd));
blkdev_dequeue_request(rq); blkdev_dequeue_request(rq);
if (blk_pc_request(rq)) {
rc = ub_cmd_build_packet(sc, lun, cmd, rq);
} else {
rc = ub_cmd_build_block(sc, lun, cmd, rq);
}
if (rc != 0) {
ub_put_cmd(lun, cmd);
ub_end_rq(rq, 0);
return 0;
}
cmd->state = UB_CMDST_INIT;
cmd->lun = lun;
cmd->done = ub_rw_cmd_done;
cmd->back = rq;
cmd->tag = sc->tagcnt++; urq = &lun->urq;
if (ub_submit_scsi(sc, cmd) != 0) { memset(urq, 0, sizeof(struct ub_request));
ub_put_cmd(lun, cmd); urq->rq = rq;
ub_end_rq(rq, 0);
return 0;
}
return 0;
}
static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct request *rq)
{
int ub_dir;
int n_elem;
unsigned int block, nblks;
if (rq_data_dir(rq) == WRITE)
ub_dir = UB_DIR_WRITE;
else
ub_dir = UB_DIR_READ;
cmd->dir = ub_dir;
/* /*
* get scatterlist from block layer * get scatterlist from block layer
*/ */
n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
if (n_elem <= 0) { if (n_elem < 0) {
printk(KERN_INFO "%s: failed request map (%d)\n", printk(KERN_INFO "%s: failed request map (%d)\n",
sc->name, n_elem); /* P3 */ lun->name, n_elem); /* P3 */
return -1; /* request with no s/g entries? */ goto drop;
} }
if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
printk(KERN_WARNING "%s: request with %d segments\n", printk(KERN_WARNING "%s: request with %d segments\n",
sc->name, n_elem); lun->name, n_elem);
return -1; goto drop;
} }
cmd->nsg = n_elem; urq->nsg = n_elem;
sc->sg_stat[n_elem < 5 ? n_elem : 5]++; sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
if (blk_pc_request(rq)) {
ub_cmd_build_packet(sc, lun, cmd, urq);
} else {
ub_cmd_build_block(sc, lun, cmd, urq);
}
cmd->state = UB_CMDST_INIT;
cmd->lun = lun;
cmd->done = ub_rw_cmd_done;
cmd->back = urq;
cmd->tag = sc->tagcnt++;
if (ub_submit_scsi(sc, cmd) != 0)
goto drop;
return 0;
drop:
ub_put_cmd(lun, cmd);
ub_end_rq(rq, 0);
return 0;
}
static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct ub_request *urq)
{
struct request *rq = urq->rq;
unsigned int block, nblks;
if (rq_data_dir(rq) == WRITE)
cmd->dir = UB_DIR_WRITE;
else
cmd->dir = UB_DIR_READ;
cmd->nsg = urq->nsg;
memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
/* /*
* build the command * build the command
* *
@ -847,7 +868,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
block = rq->sector >> lun->capacity.bshift; block = rq->sector >> lun->capacity.bshift;
nblks = rq->nr_sectors >> lun->capacity.bshift; nblks = rq->nr_sectors >> lun->capacity.bshift;
cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10;
/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
cmd->cdb[2] = block >> 24; cmd->cdb[2] = block >> 24;
cmd->cdb[3] = block >> 16; cmd->cdb[3] = block >> 16;
@ -858,14 +879,12 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
cmd->cdb_len = 10; cmd->cdb_len = 10;
cmd->len = rq->nr_sectors * 512; cmd->len = rq->nr_sectors * 512;
return 0;
} }
static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
struct ub_scsi_cmd *cmd, struct request *rq) struct ub_scsi_cmd *cmd, struct ub_request *urq)
{ {
int n_elem; struct request *rq = urq->rq;
if (rq->data_len == 0) { if (rq->data_len == 0) {
cmd->dir = UB_DIR_NONE; cmd->dir = UB_DIR_NONE;
@ -874,40 +893,26 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
cmd->dir = UB_DIR_WRITE; cmd->dir = UB_DIR_WRITE;
else else
cmd->dir = UB_DIR_READ; cmd->dir = UB_DIR_READ;
} }
/* cmd->nsg = urq->nsg;
* get scatterlist from block layer memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
*/
n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
if (n_elem < 0) {
printk(KERN_INFO "%s: failed request map (%d)\n",
sc->name, n_elem); /* P3 */
return -1;
}
if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
printk(KERN_WARNING "%s: request with %d segments\n",
sc->name, n_elem);
return -1;
}
cmd->nsg = n_elem;
sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
cmd->cdb_len = rq->cmd_len; cmd->cdb_len = rq->cmd_len;
cmd->len = rq->data_len; cmd->len = rq->data_len;
return 0;
} }
static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{ {
struct request *rq = cmd->back;
struct ub_lun *lun = cmd->lun; struct ub_lun *lun = cmd->lun;
struct ub_request *urq = cmd->back;
struct request *rq;
int uptodate; int uptodate;
rq = urq->rq;
if (cmd->error == 0) { if (cmd->error == 0) {
uptodate = 1; uptodate = 1;
@ -928,9 +933,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
rq->errors = SAM_STAT_CHECK_CONDITION; rq->errors = SAM_STAT_CHECK_CONDITION;
else else
rq->errors = DID_ERROR << 16; rq->errors = DID_ERROR << 16;
} else {
if (cmd->error == -EIO) {
if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
return;
}
} }
} }
urq->rq = NULL;
ub_put_cmd(lun, cmd); ub_put_cmd(lun, cmd);
ub_end_rq(rq, uptodate); ub_end_rq(rq, uptodate);
blk_start_queue(lun->disk->queue); blk_start_queue(lun->disk->queue);
@ -938,13 +950,45 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
static void ub_end_rq(struct request *rq, int uptodate) static void ub_end_rq(struct request *rq, int uptodate)
{ {
int rc; end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
// assert(rc == 0);
end_that_request_last(rq); end_that_request_last(rq);
} }
static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
struct ub_request *urq, struct ub_scsi_cmd *cmd)
{
if (atomic_read(&sc->poison))
return -ENXIO;
ub_reset_enter(sc);
if (urq->current_try >= 3)
return -EIO;
urq->current_try++;
/* P3 */ printk("%s: dir %c len/act %d/%d "
"[sense %x %02x %02x] retry %d\n",
sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len,
cmd->key, cmd->asc, cmd->ascq, urq->current_try);
memset(cmd, 0, sizeof(struct ub_scsi_cmd));
ub_cmd_build_block(sc, lun, cmd, urq);
cmd->state = UB_CMDST_INIT;
cmd->lun = lun;
cmd->done = ub_rw_cmd_done;
cmd->back = urq;
cmd->tag = sc->tagcnt++;
#if 0 /* Wasteful */
return ub_submit_scsi(sc, cmd);
#else
ub_cmdq_add(sc, cmd);
return 0;
#endif
}
/* /*
* Submit a regular SCSI operation (not an auto-sense). * Submit a regular SCSI operation (not an auto-sense).
* *
@ -1075,7 +1119,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc)
struct ub_scsi_cmd *cmd; struct ub_scsi_cmd *cmd;
int rc; int rc;
while ((cmd = ub_cmdq_peek(sc)) != NULL) { while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) {
if (cmd->state == UB_CMDST_DONE) { if (cmd->state == UB_CMDST_DONE) {
ub_cmdq_pop(sc); ub_cmdq_pop(sc);
(*cmd->done)(sc, cmd); (*cmd->done)(sc, cmd);
@ -1098,11 +1142,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
{ {
struct urb *urb = &sc->work_urb; struct urb *urb = &sc->work_urb;
struct bulk_cs_wrap *bcs; struct bulk_cs_wrap *bcs;
int len;
int rc; int rc;
if (atomic_read(&sc->poison)) { if (atomic_read(&sc->poison)) {
/* A little too simplistic, I feel... */ ub_state_done(sc, cmd, -ENODEV);
goto Bad_End; return;
} }
if (cmd->state == UB_CMDST_CLEAR) { if (cmd->state == UB_CMDST_CLEAR) {
@ -1110,7 +1155,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
/* /*
* STALL while clearning STALL. * STALL while clearning STALL.
* The control pipe clears itself - nothing to do. * The control pipe clears itself - nothing to do.
* XXX Might try to reset the device here and retry.
*/ */
printk(KERN_NOTICE "%s: stall on control pipe\n", printk(KERN_NOTICE "%s: stall on control pipe\n",
sc->name); sc->name);
@ -1129,11 +1173,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
} else if (cmd->state == UB_CMDST_CLR2STS) { } else if (cmd->state == UB_CMDST_CLR2STS) {
if (urb->status == -EPIPE) { if (urb->status == -EPIPE) {
/*
* STALL while clearning STALL.
* The control pipe clears itself - nothing to do.
* XXX Might try to reset the device here and retry.
*/
printk(KERN_NOTICE "%s: stall on control pipe\n", printk(KERN_NOTICE "%s: stall on control pipe\n",
sc->name); sc->name);
goto Bad_End; goto Bad_End;
@ -1151,11 +1190,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
} else if (cmd->state == UB_CMDST_CLRRS) { } else if (cmd->state == UB_CMDST_CLRRS) {
if (urb->status == -EPIPE) { if (urb->status == -EPIPE) {
/*
* STALL while clearning STALL.
* The control pipe clears itself - nothing to do.
* XXX Might try to reset the device here and retry.
*/
printk(KERN_NOTICE "%s: stall on control pipe\n", printk(KERN_NOTICE "%s: stall on control pipe\n",
sc->name); sc->name);
goto Bad_End; goto Bad_End;
@ -1172,7 +1206,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_state_stat_counted(sc, cmd); ub_state_stat_counted(sc, cmd);
} else if (cmd->state == UB_CMDST_CMD) { } else if (cmd->state == UB_CMDST_CMD) {
if (urb->status == -EPIPE) { switch (urb->status) {
case 0:
break;
case -EOVERFLOW:
goto Bad_End;
case -EPIPE:
rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
if (rc != 0) { if (rc != 0) {
printk(KERN_NOTICE "%s: " printk(KERN_NOTICE "%s: "
@ -1182,17 +1221,20 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
* This is typically ENOMEM or some other such shit. * This is typically ENOMEM or some other such shit.
* Retrying is pointless. Just do Bad End on it... * Retrying is pointless. Just do Bad End on it...
*/ */
goto Bad_End; ub_state_done(sc, cmd, rc);
return;
} }
cmd->state = UB_CMDST_CLEAR; cmd->state = UB_CMDST_CLEAR;
ub_cmdtr_state(sc, cmd); ub_cmdtr_state(sc, cmd);
return; return;
} case -ESHUTDOWN: /* unplug */
if (urb->status != 0) { case -EILSEQ: /* unplug timeout on uhci */
ub_state_done(sc, cmd, -ENODEV);
return;
default:
goto Bad_End; goto Bad_End;
} }
if (urb->actual_length != US_BULK_CB_WRAP_LEN) { if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
/* XXX Must do reset here to unconfuse the device */
goto Bad_End; goto Bad_End;
} }
@ -1211,11 +1253,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
printk(KERN_NOTICE "%s: " printk(KERN_NOTICE "%s: "
"unable to submit clear (%d)\n", "unable to submit clear (%d)\n",
sc->name, rc); sc->name, rc);
/* ub_state_done(sc, cmd, rc);
* This is typically ENOMEM or some other such shit. return;
* Retrying is pointless. Just do Bad End on it...
*/
goto Bad_End;
} }
cmd->state = UB_CMDST_CLR2STS; cmd->state = UB_CMDST_CLR2STS;
ub_cmdtr_state(sc, cmd); ub_cmdtr_state(sc, cmd);
@ -1224,14 +1263,50 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
if (urb->status == -EOVERFLOW) { if (urb->status == -EOVERFLOW) {
/* /*
* A babble? Failure, but we must transfer CSW now. * A babble? Failure, but we must transfer CSW now.
* XXX This is going to end in perpetual babble. Reset.
*/ */
cmd->error = -EOVERFLOW; /* A cheap trick... */ cmd->error = -EOVERFLOW; /* A cheap trick... */
ub_state_stat(sc, cmd); ub_state_stat(sc, cmd);
return; return;
} }
if (urb->status != 0)
goto Bad_End; if (cmd->dir == UB_DIR_WRITE) {
/*
* Do not continue writes in case of a failure.
* Doing so would cause sectors to be mixed up,
* which is worse than sectors lost.
*
* We must try to read the CSW, or many devices
* get confused.
*/
len = urb->actual_length;
if (urb->status != 0 ||
len != cmd->sgv[cmd->current_sg].length) {
cmd->act_len += len;
ub_cmdtr_act_len(sc, cmd);
cmd->error = -EIO;
ub_state_stat(sc, cmd);
return;
}
} else {
/*
* If an error occurs on read, we record it, and
* continue to fetch data in order to avoid bubble.
*
* As a small shortcut, we stop if we detect that
* a CSW mixed into data.
*/
if (urb->status != 0)
cmd->error = -EIO;
len = urb->actual_length;
if (urb->status != 0 ||
len != cmd->sgv[cmd->current_sg].length) {
if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN)
goto Bad_End;
}
}
cmd->act_len += urb->actual_length; cmd->act_len += urb->actual_length;
ub_cmdtr_act_len(sc, cmd); ub_cmdtr_act_len(sc, cmd);
@ -1249,11 +1324,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
printk(KERN_NOTICE "%s: " printk(KERN_NOTICE "%s: "
"unable to submit clear (%d)\n", "unable to submit clear (%d)\n",
sc->name, rc); sc->name, rc);
/* ub_state_done(sc, cmd, rc);
* This is typically ENOMEM or some other such shit. return;
* Retrying is pointless. Just do Bad End on it...
*/
goto Bad_End;
} }
/* /*
@ -1266,14 +1338,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_cmdtr_state(sc, cmd); ub_cmdtr_state(sc, cmd);
return; return;
} }
if (urb->status == -EOVERFLOW) {
/* /* Catch everything, including -EOVERFLOW and other nasties. */
* XXX We are screwed here. Retrying is pointless,
* because the pipelined data will not get in until
* we read with a big enough buffer. We must reset XXX.
*/
goto Bad_End;
}
if (urb->status != 0) if (urb->status != 0)
goto Bad_End; goto Bad_End;
@ -1319,15 +1385,15 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
return; return;
} }
rc = le32_to_cpu(bcs->Residue); len = le32_to_cpu(bcs->Residue);
if (rc != cmd->len - cmd->act_len) { if (len != cmd->len - cmd->act_len) {
/* /*
* It is all right to transfer less, the caller has * It is all right to transfer less, the caller has
* to check. But it's not all right if the device * to check. But it's not all right if the device
* counts disagree with our counts. * counts disagree with our counts.
*/ */
/* P3 */ printk("%s: resid %d len %d act %d\n", /* P3 */ printk("%s: resid %d len %d act %d\n",
sc->name, rc, cmd->len, cmd->act_len); sc->name, len, cmd->len, cmd->act_len);
goto Bad_End; goto Bad_End;
} }
@ -1338,13 +1404,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
ub_state_sense(sc, cmd); ub_state_sense(sc, cmd);
return; return;
case US_BULK_STAT_PHASE: case US_BULK_STAT_PHASE:
/* XXX We must reset the transport here */
/* P3 */ printk("%s: status PHASE\n", sc->name); /* P3 */ printk("%s: status PHASE\n", sc->name);
goto Bad_End; goto Bad_End;
default: default:
printk(KERN_INFO "%s: unknown CSW status 0x%x\n", printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
sc->name, bcs->Status); sc->name, bcs->Status);
goto Bad_End; ub_state_done(sc, cmd, -EINVAL);
return;
} }
/* Not zeroing error to preserve a babble indicator */ /* Not zeroing error to preserve a babble indicator */
@ -1364,7 +1430,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
printk(KERN_WARNING "%s: " printk(KERN_WARNING "%s: "
"wrong command state %d\n", "wrong command state %d\n",
sc->name, cmd->state); sc->name, cmd->state);
goto Bad_End; ub_state_done(sc, cmd, -EINVAL);
return;
} }
return; return;
@ -1611,6 +1678,93 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd)
ub_scsi_urb_compl(sc, cmd); ub_scsi_urb_compl(sc, cmd);
} }
/*
* Reset management
*/
static void ub_reset_enter(struct ub_dev *sc)
{
if (sc->reset) {
/* This happens often on multi-LUN devices. */
return;
}
sc->reset = 1;
#if 0 /* Not needed because the disconnect waits for us. */
unsigned long flags;
spin_lock_irqsave(&ub_lock, flags);
sc->openc++;
spin_unlock_irqrestore(&ub_lock, flags);
#endif
#if 0 /* We let them stop themselves. */
struct list_head *p;
struct ub_lun *lun;
list_for_each(p, &sc->luns) {
lun = list_entry(p, struct ub_lun, link);
blk_stop_queue(lun->disk->queue);
}
#endif
schedule_work(&sc->reset_work);
}
static void ub_reset_task(void *arg)
{
struct ub_dev *sc = arg;
unsigned long flags;
struct list_head *p;
struct ub_lun *lun;
int lkr, rc;
if (!sc->reset) {
printk(KERN_WARNING "%s: Running reset unrequested\n",
sc->name);
return;
}
if (atomic_read(&sc->poison)) {
printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
sc->name); /* P3 This floods. Remove soon. XXX */
} else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
sc->name); /* P3 This floods. Remove soon. XXX */
} else {
if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) {
printk(KERN_NOTICE
"%s: usb_lock_device_for_reset failed (%d)\n",
sc->name, lkr);
} else {
rc = usb_reset_device(sc->dev);
if (rc < 0) {
printk(KERN_NOTICE "%s: "
"usb_lock_device_for_reset failed (%d)\n",
sc->name, rc);
}
if (lkr)
usb_unlock_device(sc->dev);
}
}
/*
* In theory, no commands can be running while reset is active,
* so nobody can ask for another reset, and so we do not need any
* queues of resets or anything. We do need a spinlock though,
* to interact with block layer.
*/
spin_lock_irqsave(&sc->lock, flags);
sc->reset = 0;
tasklet_schedule(&sc->tasklet);
list_for_each(p, &sc->luns) {
lun = list_entry(p, struct ub_lun, link);
blk_start_queue(lun->disk->queue);
}
wake_up(&sc->reset_wait);
spin_unlock_irqrestore(&sc->lock, flags);
}
/* /*
* This is called from a process context. * This is called from a process context.
*/ */
@ -2146,7 +2300,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
if (ep_in == NULL || ep_out == NULL) { if (ep_in == NULL || ep_out == NULL) {
printk(KERN_NOTICE "%s: failed endpoint check\n", printk(KERN_NOTICE "%s: failed endpoint check\n",
sc->name); sc->name);
return -EIO; return -ENODEV;
} }
/* Calculate and store the pipe values */ /* Calculate and store the pipe values */
@ -2172,6 +2326,9 @@ static int ub_probe(struct usb_interface *intf,
int rc; int rc;
int i; int i;
if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
return -ENXIO;
rc = -ENOMEM; rc = -ENOMEM;
if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
goto err_core; goto err_core;
@ -2181,6 +2338,8 @@ static int ub_probe(struct usb_interface *intf,
usb_init_urb(&sc->work_urb); usb_init_urb(&sc->work_urb);
tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
atomic_set(&sc->poison, 0); atomic_set(&sc->poison, 0);
INIT_WORK(&sc->reset_work, ub_reset_task, sc);
init_waitqueue_head(&sc->reset_wait);
init_timer(&sc->work_timer); init_timer(&sc->work_timer);
sc->work_timer.data = (unsigned long) sc; sc->work_timer.data = (unsigned long) sc;
@ -2201,7 +2360,8 @@ static int ub_probe(struct usb_interface *intf,
/* XXX Verify that we can handle the device (from descriptors) */ /* XXX Verify that we can handle the device (from descriptors) */
ub_get_pipes(sc, sc->dev, intf); if (ub_get_pipes(sc, sc->dev, intf) != 0)
goto err_dev_desc;
if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0) if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
goto err_diag; goto err_diag;
@ -2272,6 +2432,7 @@ static int ub_probe(struct usb_interface *intf,
/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
err_diag: err_diag:
err_dev_desc:
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
// usb_put_intf(sc->intf); // usb_put_intf(sc->intf);
usb_put_dev(sc->dev); usb_put_dev(sc->dev);
@ -2309,14 +2470,14 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
ub_revalidate(sc, lun); ub_revalidate(sc, lun);
rc = -ENOMEM; rc = -ENOMEM;
if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
goto err_diskalloc; goto err_diskalloc;
lun->disk = disk; lun->disk = disk;
sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
disk->major = UB_MAJOR; disk->major = UB_MAJOR;
disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; disk->first_minor = lun->id * UB_PARTS_PER_LUN;
disk->fops = &ub_bd_fops; disk->fops = &ub_bd_fops;
disk->private_data = lun; disk->private_data = lun;
disk->driverfs_dev = &sc->intf->dev; disk->driverfs_dev = &sc->intf->dev;
@ -2379,6 +2540,11 @@ static void ub_disconnect(struct usb_interface *intf)
*/ */
atomic_set(&sc->poison, 1); atomic_set(&sc->poison, 1);
/*
* Wait for reset to end, if any.
*/
wait_event(sc->reset_wait, !sc->reset);
/* /*
* Blow away queued commands. * Blow away queued commands.
* *
@ -2392,7 +2558,7 @@ static void ub_disconnect(struct usb_interface *intf)
{ {
struct ub_scsi_cmd *cmd; struct ub_scsi_cmd *cmd;
int cnt = 0; int cnt = 0;
while ((cmd = ub_cmdq_pop(sc)) != NULL) { while ((cmd = ub_cmdq_peek(sc)) != NULL) {
cmd->error = -ENOTCONN; cmd->error = -ENOTCONN;
cmd->state = UB_CMDST_DONE; cmd->state = UB_CMDST_DONE;
ub_cmdtr_state(sc, cmd); ub_cmdtr_state(sc, cmd);
@ -2461,7 +2627,6 @@ static void ub_disconnect(struct usb_interface *intf)
} }
static struct usb_driver ub_driver = { static struct usb_driver ub_driver = {
.owner = THIS_MODULE,
.name = "ub", .name = "ub",
.probe = ub_probe, .probe = ub_probe,
.disconnect = ub_disconnect, .disconnect = ub_disconnect,
@ -2479,6 +2644,7 @@ static int __init ub_init(void)
if ((rc = usb_register(&ub_driver)) != 0) if ((rc = usb_register(&ub_driver)) != 0)
goto err_register; goto err_register;
usb_usual_set_present(USB_US_TYPE_UB);
return 0; return 0;
err_register: err_register:
@ -2494,6 +2660,7 @@ static void __exit ub_exit(void)
devfs_remove(DEVFS_NAME); devfs_remove(DEVFS_NAME);
unregister_blkdev(UB_MAJOR, DRV_NAME); unregister_blkdev(UB_MAJOR, DRV_NAME);
usb_usual_clear_present(USB_US_TYPE_UB);
} }
module_init(ub_init); module_init(ub_init);

View File

@ -275,7 +275,6 @@ static void bcm203x_disconnect(struct usb_interface *intf)
} }
static struct usb_driver bcm203x_driver = { static struct usb_driver bcm203x_driver = {
.owner = THIS_MODULE,
.name = "bcm203x", .name = "bcm203x",
.probe = bcm203x_probe, .probe = bcm203x_probe,
.disconnect = bcm203x_disconnect, .disconnect = bcm203x_disconnect,

View File

@ -768,7 +768,6 @@ static void bfusb_disconnect(struct usb_interface *intf)
} }
static struct usb_driver bfusb_driver = { static struct usb_driver bfusb_driver = {
.owner = THIS_MODULE,
.name = "bfusb", .name = "bfusb",
.probe = bfusb_probe, .probe = bfusb_probe,
.disconnect = bfusb_disconnect, .disconnect = bfusb_disconnect,

View File

@ -619,7 +619,6 @@ static void bpa10x_disconnect(struct usb_interface *intf)
} }
static struct usb_driver bpa10x_driver = { static struct usb_driver bpa10x_driver = {
.owner = THIS_MODULE,
.name = "bpa10x", .name = "bpa10x",
.probe = bpa10x_probe, .probe = bpa10x_probe,
.disconnect = bpa10x_disconnect, .disconnect = bpa10x_disconnect,

View File

@ -1044,7 +1044,6 @@ static void hci_usb_disconnect(struct usb_interface *intf)
} }
static struct usb_driver hci_usb_driver = { static struct usb_driver hci_usb_driver = {
.owner = THIS_MODULE,
.name = "hci_usb", .name = "hci_usb",
.probe = hci_usb_probe, .probe = hci_usb_probe,
.disconnect = hci_usb_disconnect, .disconnect = hci_usb_disconnect,

View File

@ -1,3 +1,3 @@
consolemap_deftbl.c consolemap_deftbl.c
defkeymap.c defkeymap.c
qtronixmap.c

View File

@ -358,7 +358,7 @@ typedef struct _failStat
#define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo #define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo
#define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error #define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error
#pragma pack(4) // Reset padding to command-line default #pragma pack() // Reset padding to command-line default
#endif // I2PACK_H #endif // I2PACK_H

View File

@ -562,7 +562,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
} /* end of n_hdlc_tty_receive() */ } /* end of n_hdlc_tty_receive() */
/** /**
* n_hdlc_tty_read - Called to retreive one frame of data (if available) * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
* @tty - pointer to tty instance data * @tty - pointer to tty instance data
* @file - pointer to open file object * @file - pointer to open file object
* @buf - pointer to returned data buffer * @buf - pointer to returned data buffer

View File

@ -1554,10 +1554,8 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
EXPORT_SYMBOL(secure_tcp_sequence_number); EXPORT_SYMBOL(secure_tcp_sequence_number);
/* Generate secure starting point for ephemeral IPV4 transport port search */
u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
/* Generate secure starting point for ephemeral TCP port search */
u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
{ {
struct keydata *keyptr = get_keyptr(); struct keydata *keyptr = get_keyptr();
u32 hash[4]; u32 hash[4];
@ -1575,7 +1573,7 @@ u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
} }
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport) u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
{ {
struct keydata *keyptr = get_keyptr(); struct keydata *keyptr = get_keyptr();
u32 hash[12]; u32 hash[12];
@ -1586,7 +1584,7 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp
return twothirdsMD4Transform(daddr, hash); return twothirdsMD4Transform(daddr, hash);
} }
EXPORT_SYMBOL(secure_tcpv6_port_ephemeral); EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
#endif #endif
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)

View File

@ -186,8 +186,8 @@ static int __init ixp4xx_wdt_init(void)
unsigned long processor_id; unsigned long processor_id;
asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
if (!(processor_id & 0xf)) { if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
printk("IXP4XXX Watchdog: Rev. A0 CPU detected - " printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - "
"watchdog disabled\n"); "watchdog disabled\n");
return -ENODEV; return -ENODEV;

View File

@ -151,7 +151,6 @@ static void usb_pcwd_disconnect (struct usb_interface *interface);
/* usb specific object needed to register this driver with the usb subsystem */ /* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver usb_pcwd_driver = { static struct usb_driver usb_pcwd_driver = {
.owner = THIS_MODULE,
.name = DRIVER_NAME, .name = DRIVER_NAME,
.probe = usb_pcwd_probe, .probe = usb_pcwd_probe,
.disconnect = usb_pcwd_disconnect, .disconnect = usb_pcwd_disconnect,

View File

@ -822,6 +822,30 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne
} }
/**
* cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
* @cpu: CPU number
*
* This is the last known freq, without actually getting it from the driver.
* Return value will be same as what is shown in scaling_cur_freq in sysfs.
*/
unsigned int cpufreq_quick_get(unsigned int cpu)
{
struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
unsigned int ret = 0;
if (policy) {
down(&policy->lock);
ret = policy->cur;
up(&policy->lock);
cpufreq_cpu_put(policy);
}
return (ret);
}
EXPORT_SYMBOL(cpufreq_quick_get);
/** /**
* cpufreq_get - get the current CPU frequency (in kHz) * cpufreq_get - get the current CPU frequency (in kHz)
* @cpu: CPU number * @cpu: CPU number

View File

@ -93,7 +93,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
{ {
return kstat_cpu(cpu).cpustat.idle + return kstat_cpu(cpu).cpustat.idle +
kstat_cpu(cpu).cpustat.iowait + kstat_cpu(cpu).cpustat.iowait +
( !dbs_tuners_ins.ignore_nice ? ( dbs_tuners_ins.ignore_nice ?
kstat_cpu(cpu).cpustat.nice : kstat_cpu(cpu).cpustat.nice :
0); 0);
} }
@ -127,7 +127,7 @@ show_one(sampling_rate, sampling_rate);
show_one(sampling_down_factor, sampling_down_factor); show_one(sampling_down_factor, sampling_down_factor);
show_one(up_threshold, up_threshold); show_one(up_threshold, up_threshold);
show_one(down_threshold, down_threshold); show_one(down_threshold, down_threshold);
show_one(ignore_nice, ignore_nice); show_one(ignore_nice_load, ignore_nice);
show_one(freq_step, freq_step); show_one(freq_step, freq_step);
static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
@ -207,7 +207,7 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
return count; return count;
} }
static ssize_t store_ignore_nice(struct cpufreq_policy *policy, static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
const char *buf, size_t count) const char *buf, size_t count)
{ {
unsigned int input; unsigned int input;
@ -272,7 +272,7 @@ define_one_rw(sampling_rate);
define_one_rw(sampling_down_factor); define_one_rw(sampling_down_factor);
define_one_rw(up_threshold); define_one_rw(up_threshold);
define_one_rw(down_threshold); define_one_rw(down_threshold);
define_one_rw(ignore_nice); define_one_rw(ignore_nice_load);
define_one_rw(freq_step); define_one_rw(freq_step);
static struct attribute * dbs_attributes[] = { static struct attribute * dbs_attributes[] = {
@ -282,7 +282,7 @@ static struct attribute * dbs_attributes[] = {
&sampling_down_factor.attr, &sampling_down_factor.attr,
&up_threshold.attr, &up_threshold.attr,
&down_threshold.attr, &down_threshold.attr,
&ignore_nice.attr, &ignore_nice_load.attr,
&freq_step.attr, &freq_step.attr,
NULL NULL
}; };

View File

@ -89,7 +89,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
{ {
return kstat_cpu(cpu).cpustat.idle + return kstat_cpu(cpu).cpustat.idle +
kstat_cpu(cpu).cpustat.iowait + kstat_cpu(cpu).cpustat.iowait +
( !dbs_tuners_ins.ignore_nice ? ( dbs_tuners_ins.ignore_nice ?
kstat_cpu(cpu).cpustat.nice : kstat_cpu(cpu).cpustat.nice :
0); 0);
} }
@ -122,7 +122,7 @@ static ssize_t show_##file_name \
show_one(sampling_rate, sampling_rate); show_one(sampling_rate, sampling_rate);
show_one(sampling_down_factor, sampling_down_factor); show_one(sampling_down_factor, sampling_down_factor);
show_one(up_threshold, up_threshold); show_one(up_threshold, up_threshold);
show_one(ignore_nice, ignore_nice); show_one(ignore_nice_load, ignore_nice);
static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
const char *buf, size_t count) const char *buf, size_t count)
@ -182,7 +182,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
return count; return count;
} }
static ssize_t store_ignore_nice(struct cpufreq_policy *policy, static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
const char *buf, size_t count) const char *buf, size_t count)
{ {
unsigned int input; unsigned int input;
@ -223,7 +223,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
define_one_rw(sampling_rate); define_one_rw(sampling_rate);
define_one_rw(sampling_down_factor); define_one_rw(sampling_down_factor);
define_one_rw(up_threshold); define_one_rw(up_threshold);
define_one_rw(ignore_nice); define_one_rw(ignore_nice_load);
static struct attribute * dbs_attributes[] = { static struct attribute * dbs_attributes[] = {
&sampling_rate_max.attr, &sampling_rate_max.attr,
@ -231,7 +231,7 @@ static struct attribute * dbs_attributes[] = {
&sampling_rate.attr, &sampling_rate.attr,
&sampling_down_factor.attr, &sampling_down_factor.attr,
&up_threshold.attr, &up_threshold.attr,
&ignore_nice.attr, &ignore_nice_load.attr,
NULL NULL
}; };

View File

@ -3509,6 +3509,7 @@ static int __init ide_cdrom_init(void)
return driver_register(&ide_cdrom_driver.gen_driver); return driver_register(&ide_cdrom_driver.gen_driver);
} }
MODULE_ALIAS("ide:*m-cdrom*");
module_init(ide_cdrom_init); module_init(ide_cdrom_init);
module_exit(ide_cdrom_exit); module_exit(ide_cdrom_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -1271,6 +1271,7 @@ static int __init idedisk_init(void)
return driver_register(&idedisk_driver.gen_driver); return driver_register(&idedisk_driver.gen_driver);
} }
MODULE_ALIAS("ide:*m-disk*");
module_init(idedisk_init); module_init(idedisk_init);
module_exit(idedisk_exit); module_exit(idedisk_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -2197,6 +2197,7 @@ static int __init idefloppy_init(void)
return driver_register(&idefloppy_driver.gen_driver); return driver_register(&idefloppy_driver.gen_driver);
} }
MODULE_ALIAS("ide:*m-floppy*");
module_init(idefloppy_init); module_init(idefloppy_init);
module_exit(idefloppy_exit); module_exit(idefloppy_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -4947,6 +4947,7 @@ out:
return error; return error;
} }
MODULE_ALIAS("ide:*m-tape*");
module_init(idetape_init); module_init(idetape_init);
module_exit(idetape_exit); module_exit(idetape_exit);
MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);

View File

@ -1904,9 +1904,69 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
return 1; return 1;
} }
static char *media_string(ide_drive_t *drive)
{
switch (drive->media) {
case ide_disk:
return "disk";
case ide_cdrom:
return "cdrom";
case ide_tape:
return "tape";
case ide_floppy:
return "floppy";
default:
return "UNKNOWN";
}
}
static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", media_string(drive));
}
static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", drive->name);
}
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "ide:m-%s\n", media_string(drive));
}
static struct device_attribute ide_dev_attrs[] = {
__ATTR_RO(media),
__ATTR_RO(drivename),
__ATTR_RO(modalias),
__ATTR_NULL
};
static int ide_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
ide_drive_t *drive = to_ide_device(dev);
int i = 0;
int length = 0;
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MEDIA=%s", media_string(drive));
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"DRIVENAME=%s", drive->name);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MODALIAS=ide:m-%s", media_string(drive));
envp[i] = NULL;
return 0;
}
struct bus_type ide_bus_type = { struct bus_type ide_bus_type = {
.name = "ide", .name = "ide",
.match = ide_bus_match, .match = ide_bus_match,
.uevent = ide_uevent,
.dev_attrs = ide_dev_attrs,
.suspend = generic_ide_suspend, .suspend = generic_ide_suspend,
.resume = generic_ide_resume, .resume = generic_ide_resume,
}; };

1
drivers/ieee1394/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
oui.c

View File

@ -121,8 +121,8 @@ struct host_info {
}; };
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp, static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size); char *buffer, int buffer_size);
static void nodemgr_resume_ne(struct node_entry *ne); static void nodemgr_resume_ne(struct node_entry *ne);
static void nodemgr_remove_ne(struct node_entry *ne); static void nodemgr_remove_ne(struct node_entry *ne);
static struct node_entry *find_entry_by_guid(u64 guid); static struct node_entry *find_entry_by_guid(u64 guid);
@ -162,7 +162,7 @@ static void ud_cls_release(struct class_device *class_dev)
static struct class nodemgr_ud_class = { static struct class nodemgr_ud_class = {
.name = "ieee1394", .name = "ieee1394",
.release = ud_cls_release, .release = ud_cls_release,
.hotplug = nodemgr_hotplug, .uevent = nodemgr_uevent,
}; };
static struct hpsb_highlevel nodemgr_highlevel; static struct hpsb_highlevel nodemgr_highlevel;
@ -963,7 +963,7 @@ static struct unit_directory *nodemgr_process_unit_directory
if (ud_child == NULL) if (ud_child == NULL)
break; break;
/* inherit unspecified values so hotplug picks it up */ /* inherit unspecified values, the driver core picks it up */
if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
!(ud_child->flags & UNIT_DIRECTORY_MODEL_ID)) !(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
{ {
@ -1059,8 +1059,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp, static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
struct unit_directory *ud; struct unit_directory *ud;
int i = 0; int i = 0;
@ -1109,8 +1109,8 @@ do { \
#else #else
static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp, static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
return -ENODEV; return -ENODEV;
} }
@ -1630,8 +1630,8 @@ static int nodemgr_host_thread(void *__hi)
/* Scan our nodes to get the bus options and create node /* Scan our nodes to get the bus options and create node
* entries. This does not do the sysfs stuff, since that * entries. This does not do the sysfs stuff, since that
* would trigger hotplug callbacks and such, which is a * would trigger uevents and such, which is a bad idea at
* bad idea at this point. */ * this point. */
nodemgr_node_scan(hi, generation); nodemgr_node_scan(hi, generation);
/* This actually does the full probe, with sysfs /* This actually does the full probe, with sysfs

View File

@ -434,24 +434,24 @@ static void ib_device_release(struct class_device *cdev)
kfree(dev); kfree(dev);
} }
static int ib_device_hotplug(struct class_device *cdev, char **envp, static int ib_device_uevent(struct class_device *cdev, char **envp,
int num_envp, char *buf, int size) int num_envp, char *buf, int size)
{ {
struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
int i = 0, len = 0; int i = 0, len = 0;
if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len, if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
"NAME=%s", dev->name)) "NAME=%s", dev->name))
return -ENOMEM; return -ENOMEM;
/* /*
* It might be nice to pass the node GUID to hotplug, but * It might be nice to pass the node GUID with the event, but
* right now the only way to get it is to query the device * right now the only way to get it is to query the device
* provider, and this can crash during device removal because * provider, and this can crash during device removal because
* we are will be running after driver removal has started. * we are will be running after driver removal has started.
* We could add a node_guid field to struct ib_device, or we * We could add a node_guid field to struct ib_device, or we
* could just let the hotplug script read the node GUID from * could just let userspace read the node GUID from sysfs when
* sysfs when devices are added. * devices are added.
*/ */
envp[i] = NULL; envp[i] = NULL;
@ -653,7 +653,7 @@ static struct class_device_attribute *ib_class_attributes[] = {
static struct class ib_class = { static struct class ib_class = {
.name = "infiniband", .name = "infiniband",
.release = ib_device_release, .release = ib_device_release,
.hotplug = ib_device_hotplug, .uevent = ib_device_uevent,
}; };
int ib_device_register_sysfs(struct ib_device *device) int ib_device_register_sysfs(struct ib_device *device)

View File

@ -47,6 +47,8 @@
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/in.h> #include <linux/in.h>
#include <net/dst.h>
MODULE_AUTHOR("Roland Dreier"); MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");

View File

@ -43,6 +43,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <net/dst.h>
#include "ipoib.h" #include "ipoib.h"
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG

View File

@ -18,7 +18,6 @@
#include <linux/random.h> #include <linux/random.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/kobject_uevent.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/device.h> #include <linux/device.h>
@ -529,10 +528,49 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
INPUT_DEV_STRING_ATTR_SHOW(phys); INPUT_DEV_STRING_ATTR_SHOW(phys);
INPUT_DEV_STRING_ATTR_SHOW(uniq); INPUT_DEV_STRING_ATTR_SHOW(uniq);
static int print_modalias_bits(char *buf, char prefix, unsigned long *arr,
unsigned int min, unsigned int max)
{
int len, i;
len = sprintf(buf, "%c", prefix);
for (i = min; i < max; i++)
if (arr[LONG(i)] & BIT(i))
len += sprintf(buf+len, "%X,", i);
return len;
}
static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
{
struct input_dev *id = to_input_dev(dev);
ssize_t len = 0;
len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-",
id->id.bustype,
id->id.vendor,
id->id.product,
id->id.version);
len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX);
len += print_modalias_bits(buf+len, 'k', id->keybit,
KEY_MIN_INTERESTING, KEY_MAX);
len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX);
len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX);
len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX);
len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX);
len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX);
len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX);
len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX);
len += sprintf(buf+len, "\n");
return len;
}
static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
static struct attribute *input_dev_attrs[] = { static struct attribute *input_dev_attrs[] = {
&class_device_attr_name.attr, &class_device_attr_name.attr,
&class_device_attr_phys.attr, &class_device_attr_phys.attr,
&class_device_attr_uniq.attr, &class_device_attr_uniq.attr,
&class_device_attr_modalias.attr,
NULL NULL
}; };
@ -611,10 +649,10 @@ static void input_dev_release(struct class_device *class_dev)
} }
/* /*
* Input hotplugging interface - loading event handlers based on * Input uevent interface - loading event handlers based on
* device bitfields. * device bitfields.
*/ */
static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index, static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len, char *buffer, int buffer_size, int *cur_len,
const char *name, unsigned long *bitmap, int max) const char *name, unsigned long *bitmap, int max)
{ {
@ -639,7 +677,7 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
do { \ do { \
int err = add_hotplug_env_var(envp, num_envp, &i, \ int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \ buffer, buffer_size, &len, \
fmt, val); \ fmt, val); \
if (err) \ if (err) \
@ -648,15 +686,15 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
do { \ do { \
int err = input_add_hotplug_bm_var(envp, num_envp, &i, \ int err = input_add_uevent_bm_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \ buffer, buffer_size, &len, \
name, bm, max); \ name, bm, max); \
if (err) \ if (err) \
return err; \ return err; \
} while (0) } while (0)
static int input_dev_hotplug(struct class_device *cdev, char **envp, static int input_dev_uevent(struct class_device *cdev, char **envp,
int num_envp, char *buffer, int buffer_size) int num_envp, char *buffer, int buffer_size)
{ {
struct input_dev *dev = to_input_dev(cdev); struct input_dev *dev = to_input_dev(cdev);
int i = 0; int i = 0;
@ -698,7 +736,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
struct class input_class = { struct class input_class = {
.name = "input", .name = "input",
.release = input_dev_release, .release = input_dev_release,
.hotplug = input_dev_hotplug, .uevent = input_dev_uevent,
}; };
struct input_dev *input_allocate_device(void) struct input_dev *input_allocate_device(void)

View File

@ -235,7 +235,6 @@ static struct usb_device_id iforce_usb_ids [] = {
MODULE_DEVICE_TABLE (usb, iforce_usb_ids); MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
struct usb_driver iforce_usb_driver = { struct usb_driver iforce_usb_driver = {
.owner = THIS_MODULE,
.name = "iforce", .name = "iforce",
.probe = iforce_usb_probe, .probe = iforce_usb_probe,
.disconnect = iforce_usb_disconnect, .disconnect = iforce_usb_disconnect,

View File

@ -800,16 +800,16 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \ #define SERIO_ADD_UEVENT_VAR(fmt, val...) \
do { \ do { \
int err = add_hotplug_env_var(envp, num_envp, &i, \ int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \ buffer, buffer_size, &len, \
fmt, val); \ fmt, val); \
if (err) \ if (err) \
return err; \ return err; \
} while (0) } while (0)
static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{ {
struct serio *serio; struct serio *serio;
int i = 0; int i = 0;
@ -820,21 +820,21 @@ static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *bu
serio = to_serio_port(dev); serio = to_serio_port(dev);
SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type); SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto); SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id); SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra); SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
envp[i] = NULL; envp[i] = NULL;
return 0; return 0;
} }
#undef SERIO_ADD_HOTPLUG_VAR #undef SERIO_ADD_UEVENT_VAR
#else #else
static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{ {
return -ENODEV; return -ENODEV;
} }
@ -908,7 +908,7 @@ static int __init serio_init(void)
serio_bus.dev_attrs = serio_device_attrs; serio_bus.dev_attrs = serio_device_attrs;
serio_bus.drv_attrs = serio_driver_attrs; serio_bus.drv_attrs = serio_driver_attrs;
serio_bus.match = serio_bus_match; serio_bus.match = serio_bus_match;
serio_bus.hotplug = serio_hotplug; serio_bus.uevent = serio_uevent;
serio_bus.resume = serio_resume; serio_bus.resume = serio_resume;
bus_register(&serio_bus); bus_register(&serio_bus);

View File

@ -1715,7 +1715,6 @@ hfc_usb_disconnect(struct usb_interface
/* our driver information structure */ /* our driver information structure */
/************************************/ /************************************/
static struct usb_driver hfc_drv = { static struct usb_driver hfc_drv = {
.owner = THIS_MODULE,
.name = "hfc_usb", .name = "hfc_usb",
.id_table = hfcusb_idtab, .id_table = hfcusb_idtab,
.probe = hfc_usb_probe, .probe = hfc_usb_probe,

View File

@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = {
MODULE_DEVICE_TABLE (usb, st5481_ids); MODULE_DEVICE_TABLE (usb, st5481_ids);
static struct usb_driver st5481_usb_driver = { static struct usb_driver st5481_usb_driver = {
.owner = THIS_MODULE,
.name = "st5481_usb", .name = "st5481_usb",
.probe = probe_st5481, .probe = probe_st5481,
.disconnect = disconnect_st5481, .disconnect = disconnect_st5481,

View File

@ -128,7 +128,7 @@ static int macio_device_resume(struct device * dev)
return 0; return 0;
} }
static int macio_hotplug (struct device *dev, char **envp, int num_envp, static int macio_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size) char *buffer, int buffer_size)
{ {
struct macio_dev * macio_dev; struct macio_dev * macio_dev;
@ -203,7 +203,7 @@ extern struct device_attribute macio_dev_attrs[];
struct bus_type macio_bus_type = { struct bus_type macio_bus_type = {
.name = "macio", .name = "macio",
.match = macio_bus_match, .match = macio_bus_match,
.hotplug = macio_hotplug, .uevent = macio_uevent,
.suspend = macio_device_suspend, .suspend = macio_device_suspend,
.resume = macio_device_resume, .resume = macio_device_resume,
.dev_attrs = macio_dev_attrs, .dev_attrs = macio_dev_attrs,

4
drivers/md/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
mktables
raid6altivec*.c
raid6int*.c
raid6tables.c

View File

@ -638,7 +638,7 @@ int dm_split_args(int *argc, char ***argvp, char *input)
static void check_for_valid_limits(struct io_restrictions *rs) static void check_for_valid_limits(struct io_restrictions *rs)
{ {
if (!rs->max_sectors) if (!rs->max_sectors)
rs->max_sectors = MAX_SECTORS; rs->max_sectors = SAFE_MAX_SECTORS;
if (!rs->max_phys_segments) if (!rs->max_phys_segments)
rs->max_phys_segments = MAX_PHYS_SEGMENTS; rs->max_phys_segments = MAX_PHYS_SEGMENTS;
if (!rs->max_hw_segments) if (!rs->max_hw_segments)

View File

@ -544,7 +544,6 @@ static struct usb_device_id flexcop_usb_table [] = {
/* usb specific object needed to register this driver with the usb subsystem */ /* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver flexcop_usb_driver = { static struct usb_driver flexcop_usb_driver = {
.owner = THIS_MODULE,
.name = "b2c2_flexcop_usb", .name = "b2c2_flexcop_usb",
.probe = flexcop_usb_probe, .probe = flexcop_usb_probe,
.disconnect = flexcop_usb_disconnect, .disconnect = flexcop_usb_disconnect,

View File

@ -986,7 +986,6 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = {
MODULE_DEVICE_TABLE(usb, cinergyt2_table); MODULE_DEVICE_TABLE(usb, cinergyt2_table);
static struct usb_driver cinergyt2_driver = { static struct usb_driver cinergyt2_driver = {
.owner = THIS_MODULE,
.name = "cinergyT2", .name = "cinergyT2",
.probe = cinergyt2_probe, .probe = cinergyt2_probe,
.disconnect = cinergyt2_disconnect, .disconnect = cinergyt2_disconnect,

View File

@ -144,7 +144,6 @@ static struct dvb_usb_properties a800_properties = {
}; };
static struct usb_driver a800_driver = { static struct usb_driver a800_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_a800", .name = "dvb_usb_a800",
.probe = a800_probe, .probe = a800_probe,
.disconnect = dvb_usb_device_exit, .disconnect = dvb_usb_device_exit,

View File

@ -241,7 +241,6 @@ static struct dvb_usb_properties cxusb_properties = {
}; };
static struct usb_driver cxusb_driver = { static struct usb_driver cxusb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_cxusb", .name = "dvb_usb_cxusb",
.probe = cxusb_probe, .probe = cxusb_probe,
.disconnect = dvb_usb_device_exit, .disconnect = dvb_usb_device_exit,

View File

@ -373,7 +373,6 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
}; };
static struct usb_driver dibusb_driver = { static struct usb_driver dibusb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_dibusb_mb", .name = "dvb_usb_dibusb_mb",
.probe = dibusb_probe, .probe = dibusb_probe,
.disconnect = dvb_usb_device_exit, .disconnect = dvb_usb_device_exit,

View File

@ -82,7 +82,6 @@ static struct dvb_usb_properties dibusb_mc_properties = {
}; };
static struct usb_driver dibusb_mc_driver = { static struct usb_driver dibusb_mc_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_dibusb_mc", .name = "dvb_usb_dibusb_mc",
.probe = dibusb_mc_probe, .probe = dibusb_mc_probe,
.disconnect = dvb_usb_device_exit, .disconnect = dvb_usb_device_exit,

View File

@ -233,7 +233,6 @@ static struct dvb_usb_properties digitv_properties = {
}; };
static struct usb_driver digitv_driver = { static struct usb_driver digitv_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_digitv", .name = "dvb_usb_digitv",
.probe = digitv_probe, .probe = digitv_probe,
.disconnect = dvb_usb_device_exit, .disconnect = dvb_usb_device_exit,

View File

@ -198,7 +198,6 @@ static struct dvb_usb_properties wt220u_properties = {
/* usb specific object needed to register this driver with the usb subsystem */ /* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver dtt200u_usb_driver = { static struct usb_driver dtt200u_usb_driver = {
.owner = THIS_MODULE,
.name = "dvb_usb_dtt200u", .name = "dvb_usb_dtt200u",
.probe = dtt200u_usb_probe, .probe = dtt200u_usb_probe,
.disconnect = dvb_usb_device_exit, .disconnect = dvb_usb_device_exit,

Some files were not shown because too many files have changed in this diff Show More