Auto-update from upstream
This commit is contained in:
commit
5c3eee7912
|
@ -23,6 +23,7 @@ Module.symvers
|
|||
# Generated include files
|
||||
#
|
||||
include/asm
|
||||
include/asm-*/asm-offsets.h
|
||||
include/config
|
||||
include/linux/autoconf.h
|
||||
include/linux/compile.h
|
||||
|
|
1
CREDITS
1
CREDITS
|
@ -1883,6 +1883,7 @@ N: Jaya Kumar
|
|||
E: jayalk@intworks.biz
|
||||
W: http://www.intworks.biz
|
||||
D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
|
||||
D: pirq addr, CS5535 alsa audio driver
|
||||
S: Gurgaon, India
|
||||
S: Kuala Lumpur, Malaysia
|
||||
|
||||
|
|
|
@ -253,6 +253,7 @@
|
|||
!Edrivers/usb/core/urb.c
|
||||
!Edrivers/usb/core/message.c
|
||||
!Edrivers/usb/core/file.c
|
||||
!Edrivers/usb/core/driver.c
|
||||
!Edrivers/usb/core/usb.c
|
||||
!Edrivers/usb/core/hub.c
|
||||
</chapter>
|
||||
|
|
|
@ -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.
|
||||
|
||||
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:
|
||||
Spelling fixes in documentation
|
||||
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)
|
||||
Any fix by the author/maintainer of the file. (ie. patch monkey
|
||||
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/>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this
|
|||
document:
|
||||
Christoph Hellwig <hch@infradead.org>
|
||||
Arjan van de Ven <arjanv@redhat.com>
|
||||
Randy Dunlap <rddunlap@osdl.org>
|
||||
Randy Dunlap <rdunlap@xenotime.net>
|
||||
Andre Hedrick <andre@linux-ide.org>
|
||||
|
||||
The following people helped with fixes/contributions to the bio patches
|
||||
|
|
|
@ -27,6 +27,7 @@ Contents:
|
|||
2.2 Powersave
|
||||
2.3 Userspace
|
||||
2.4 Ondemand
|
||||
2.5 Conservative
|
||||
|
||||
3. The Governor Interface in the CPUfreq Core
|
||||
|
||||
|
@ -110,9 +111,64 @@ directory.
|
|||
|
||||
The CPUfreq govenor "ondemand" sets the CPU depending on the
|
||||
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
|
||||
=============================================
|
||||
|
|
|
@ -18,8 +18,6 @@ devfs/
|
|||
- directory containing devfs documentation.
|
||||
ext2.txt
|
||||
- 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
|
||||
- info and mount options for the OS/2 HPFS.
|
||||
isofs.txt
|
||||
|
|
|
@ -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
|
||||
filesystem implementation.
|
||||
|
||||
Usually, a filesystem uses generic one of the generic get_sb()
|
||||
implementations and provides a fill_super() method instead. The
|
||||
generic methods are:
|
||||
Usually, a filesystem uses one of the generic get_sb() implementations
|
||||
and provides a fill_super() method instead. The generic methods are:
|
||||
|
||||
get_sb_bdev: mount a filesystem residing on a block device
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ included in the kernel tree.
|
|||
What is covered within this file is mainly information to authors
|
||||
of modules. The author of an external modules should supply
|
||||
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".
|
||||
|
||||
|
||||
|
@ -69,7 +69,7 @@ when building an external module.
|
|||
|
||||
--- 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`
|
||||
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
|
||||
Install the external module(s).
|
||||
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
|
||||
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
|
||||
help will list the available target when building external
|
||||
|
@ -99,7 +99,7 @@ when building an external module.
|
|||
|
||||
--- 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
|
||||
Used to specify where to find the kernel source.
|
||||
|
@ -206,11 +206,11 @@ following files:
|
|||
|
||||
KERNELDIR := /lib/modules/`uname -r`/build
|
||||
all::
|
||||
$(MAKE) -C $KERNELDIR M=`pwd` $@
|
||||
$(MAKE) -C $(KERNELDIR) M=`pwd` $@
|
||||
|
||||
# Module specific targets
|
||||
genbin:
|
||||
echo "X" > 8123_bini.o_shipped
|
||||
echo "X" > 8123_bin.o_shipped
|
||||
|
||||
endif
|
||||
|
||||
|
@ -341,13 +341,13 @@ directory and therefore needs to deal with this in their kbuild file.
|
|||
EXTRA_CFLAGS := -Iinclude
|
||||
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.
|
||||
This is a kbuild limitation and no space must be present.
|
||||
Note that in the assignment there is no space between -I and the path.
|
||||
This is a kbuild limitation: there must be no space present.
|
||||
|
||||
|
||||
=== 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
|
||||
|
||||
|
@ -365,7 +365,7 @@ External modules are installed in the directory:
|
|||
=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
|
||||
|
||||
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
|
||||
the kernel as well as when installing external modules.
|
||||
|
||||
|
@ -384,7 +384,7 @@ External modules are installed in the directory:
|
|||
|
||||
=== 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
|
||||
versioning creates a CRC value of the full prototype for an exported symbol and
|
||||
|
|
|
@ -633,6 +633,14 @@ running once the system is up.
|
|||
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
|
||||
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]
|
||||
|
||||
io7= [HW] IO7 for Marvel based alpha systems
|
||||
|
|
|
@ -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.
|
|
@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER
|
|||
for the hash secret) for IP fragments.
|
||||
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_threshold - INTEGER
|
||||
|
|
|
@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
|
|||
At this time, a generic EEH recovery mechanism has been implemented,
|
||||
so that individual device drivers do not need to be modified to support
|
||||
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
|
||||
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().
|
||||
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,
|
||||
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"
|
||||
for ethernet cards, and so on. This handler then sleeps for 5 seconds,
|
||||
hoping to give the user-space scripts enough time to complete.
|
||||
|
@ -264,23 +264,24 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
|
|||
calls
|
||||
kobject_del() { //in /libs/kobject.c
|
||||
calls
|
||||
kobject_hotplug() { // in /libs/kobject.c
|
||||
kobject_uevent() { // in /libs/kobject.c
|
||||
calls
|
||||
kset_hotplug() { // in /lib/kobject.c
|
||||
kset_uevent() { // in /lib/kobject.c
|
||||
calls
|
||||
kset->hotplug_ops->hotplug() which is really just
|
||||
kset->uevent_ops->uevent() // which is really just
|
||||
a call to
|
||||
dev_hotplug() { // in /drivers/base/core.c
|
||||
dev_uevent() { // in /drivers/base/core.c
|
||||
calls
|
||||
dev->bus->hotplug() which is really just a call to
|
||||
pci_hotplug () { // in drivers/pci/hotplug.c
|
||||
dev->bus->uevent() which is really just a call to
|
||||
pci_uevent () { // in drivers/pci/hotplug.c
|
||||
which prints device name, etc....
|
||||
}
|
||||
}
|
||||
then kset_hotplug() calls
|
||||
call_usermodehelper () with
|
||||
argv[0]=hotplug_path[] which is "/sbin/hotplug"
|
||||
--> event to userspace,
|
||||
then kobject_uevent() sends a netlink uevent to userspace
|
||||
--> userspace uevent
|
||||
(during early boot, nobody listens to netlink events and
|
||||
kobject_uevent() executes uevent_helper[], which runs the
|
||||
event process /sbin/hotplug)
|
||||
}
|
||||
}
|
||||
kobject_del() then calls sysfs_remove_dir(), which would
|
||||
|
|
|
@ -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>
|
||||
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)
|
||||
|
|
|
@ -150,7 +150,8 @@ scsi devices of which only the first 2 respond:
|
|||
LLD mid level LLD
|
||||
===-------------------=========--------------------===------
|
||||
scsi_host_alloc() -->
|
||||
scsi_add_host() --------+
|
||||
scsi_add_host() ---->
|
||||
scsi_scan_host() -------+
|
||||
|
|
||||
slave_alloc()
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
@ -372,7 +373,7 @@ names all start with "scsi_".
|
|||
Summary:
|
||||
scsi_activate_tcq - turn on tag command queueing
|
||||
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_assign_lock - replace default host_lock with given lock
|
||||
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_host - detach and remove all SCSI devices owned by host
|
||||
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_unblock_requests - allow further commands to be queued to given host
|
||||
scsi_unregister - [calls scsi_host_put()]
|
||||
|
@ -425,10 +427,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
|
|||
* Might block: yes
|
||||
*
|
||||
* 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
|
||||
* device (lu) after scsi_add_host() has completed. If successful
|
||||
* this call we lead to slave_alloc() and slave_configure() callbacks
|
||||
* device (lu) after scsi_scan_host() has completed. If successful
|
||||
* this call can lead to slave_alloc() and slave_configure() callbacks
|
||||
* into the LLD.
|
||||
*
|
||||
* 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
|
||||
* @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
|
||||
*
|
||||
* 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
|
||||
**/
|
||||
|
@ -559,7 +565,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
|
|||
* area for the LLD's exclusive use.
|
||||
* Both associated refcounting objects have their refcount set to 1.
|
||||
* 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 .
|
||||
**/
|
||||
|
@ -698,6 +704,19 @@ int scsi_remove_host(struct Scsi_Host *shost)
|
|||
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
|
||||
* 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>
|
||||
Doug Ledford <dledford at redhat dot com>
|
||||
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>
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
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 negative, interpret as a bitmask of permissible
|
||||
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)
|
||||
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
|
||||
-----------------
|
||||
|
@ -145,9 +145,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
irq - IRQ # for AD1848 chip
|
||||
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.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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
|
||||
See the description of intel8x0 module for details.
|
||||
|
||||
This module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
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)
|
||||
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
|
||||
------------------
|
||||
|
@ -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.
|
||||
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
|
||||
-----------------
|
||||
|
@ -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
|
||||
choose the correct one via spdif_aclink module option.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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
|
||||
slot is excluded.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-au8810, snd-au8820, snd-au8830
|
||||
-----------------------------------------
|
||||
|
||||
|
@ -263,7 +273,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
dma1 - 1st 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
|
||||
------------------
|
||||
|
@ -272,7 +284,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
|
||||
joystick - Enable joystick (default off)
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
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)
|
||||
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
|
||||
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 supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
|
||||
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)
|
||||
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
|
||||
-----------------
|
||||
|
@ -321,7 +335,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
(default = 1)
|
||||
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
|
||||
-----------------
|
||||
|
@ -335,7 +351,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
dma1 - first 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.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
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.
|
||||
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
|
||||
from PCI sub vendor/device ids. If they don't work, give the options
|
||||
above explicitly.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-cs5535audio
|
||||
----------------------
|
||||
|
||||
Module for multifunction CS5535 companion PCI device
|
||||
|
||||
This module supports multiple cards.
|
||||
|
||||
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)
|
||||
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.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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
|
||||
requires a sound card (like RealPlayer).
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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.
|
||||
enable_ir - enable IR
|
||||
|
||||
Module supports up to 8 cards and autoprobe.
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
Input & Output configurations [extin/extout]
|
||||
* 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 all ins and outs [0x3fff/0x7fff]
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-emu10k1x
|
||||
-------------------
|
||||
|
||||
Module for Creative Emu10k1X (SB Live Dell OEM version)
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
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)
|
||||
|
||||
Module supports up to 8 cards and autoprobe.
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
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),
|
||||
0 = disable (default), 1 = auto-detect
|
||||
|
||||
Module supports up to 8 cards and autoprobe.
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
Module snd-es968
|
||||
----------------
|
||||
|
@ -506,7 +535,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
irq - IRQ # 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
|
||||
-----------------
|
||||
|
@ -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)
|
||||
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
|
||||
-----------------
|
||||
|
@ -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)
|
||||
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
|
||||
|
||||
Module supports up to 8 cards ISA PnP and autoprobe (without MPU-401 port
|
||||
if native ISA PnP routines are not used).
|
||||
This module supports multiple cards, ISA PnP and autoprobe (without MPU-401
|
||||
port if native ISA PnP routines are not used).
|
||||
When dma2 is equal with dma1, the driver works as half-duplex.
|
||||
|
||||
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 supports up to 8 cards and autoprobe.
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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))
|
||||
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.
|
||||
|
||||
|
@ -577,7 +610,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
- High 16-bits are video (radio) device number + 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
|
||||
---------------------
|
||||
|
@ -592,7 +627,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
voices - GF1 voices limit (14-32)
|
||||
pcm_voices - reserved PCM voices
|
||||
|
||||
Module supports up to 8 cards and autoprobe.
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
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)
|
||||
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
|
||||
-----------------
|
||||
|
@ -626,7 +661,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
voices - GF1 voices limit (14-32)
|
||||
pcm_voices - reserved PCM voices
|
||||
|
||||
Module supports up to 8 cards and autoprobe.
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
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
|
||||
position buffer.)
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-hdsp
|
||||
---------------
|
||||
|
||||
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
|
||||
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)
|
||||
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
|
||||
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,
|
||||
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
|
||||
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
|
||||
slot is excluded.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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);
|
||||
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
|
||||
------------------------
|
||||
|
@ -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);
|
||||
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 for Korg 1212 IO PCI card
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
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
|
||||
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.
|
||||
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 supports multiple cards.
|
||||
This module supports multiple cards.
|
||||
Note: One miXart8 board will be represented as 4 alsa cards.
|
||||
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)
|
||||
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
|
||||
----------------
|
||||
|
@ -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
|
||||
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!!!
|
||||
|
||||
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.
|
||||
|
||||
Module snd-pcxhr
|
||||
----------------
|
||||
|
||||
Module for Digigram PCXHR boards
|
||||
|
||||
This module supports multiple cards.
|
||||
|
||||
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.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-rme32
|
||||
----------------
|
||||
|
||||
Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32,
|
||||
Prodif96 and Prodif Gold) sound cards.
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
Module snd-rme96
|
||||
----------------
|
||||
|
||||
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
|
||||
------------------
|
||||
|
@ -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).
|
||||
(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
|
||||
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 has no enable and index options.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-sb8
|
||||
--------------
|
||||
|
||||
|
@ -1135,7 +1185,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
irq - IRQ # for SB DSP chip (5,7,9,10)
|
||||
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
|
||||
-----------------------------
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
16-bit DMA channel.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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)
|
||||
dma1 - DMA #
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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)
|
||||
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
|
||||
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 supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
Module snd-sun-cs4231 (on sparc only)
|
||||
-------------------------------------
|
||||
|
||||
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 for DBRI sound chips found on Sparcs.
|
||||
|
||||
Module supports up to 8 cards.
|
||||
This module supports multiple cards.
|
||||
|
||||
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.
|
||||
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
|
||||
---------------------
|
||||
|
@ -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.
|
||||
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
|
||||
------------------------
|
||||
|
@ -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,
|
||||
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.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
|
@ -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)
|
||||
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 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
|
||||
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
|
||||
additionally. The mpu_port option is for VIA686 chips only.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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
|
||||
slot is excluded.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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
|
||||
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
|
||||
----------------
|
||||
|
@ -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)
|
||||
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
|
||||
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
|
||||
/proc/asound/cardX/vx-status proc file.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
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)
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
ALSA 1.0.10.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-ymfpci
|
||||
-----------------
|
||||
|
||||
|
@ -1447,7 +1511,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
1 (auto-detect)
|
||||
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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
|
||||
AC97 Quirk Option
|
||||
=================
|
||||
|
@ -1474,7 +1540,7 @@ the proper value with this option.
|
|||
|
||||
The following strings are accepted:
|
||||
- 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
|
||||
- swap_hp Swap headphone and master controls
|
||||
- swap_surround Swap master and surround controls
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -138,6 +138,22 @@ card*/codec97#0/ac97#?-?+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
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
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);
|
||||
|
||||
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 {
|
||||
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,
|
||||
snd_pcm_substream_t *substream);
|
||||
struct snd_pcm_substream *substream);
|
||||
int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
|
||||
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,
|
||||
snd_pcm_substream_t *substream);
|
||||
struct snd_pcm_substream *substream);
|
||||
};
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
Note that this will call control->put callback of these entries. So,
|
||||
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.
|
||||
|
||||
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:
|
||||
snd_hda_input_mux_info() and snd_hda_input_mux_put(). See
|
||||
|
|
|
@ -202,17 +202,13 @@ you must call __handle_sysrq_nolock instead.
|
|||
|
||||
* 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
|
||||
responding as soon as possible.
|
||||
-Crutcher
|
||||
|
||||
* Credits
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Written by Mydraal <myrdraal@deathsdoor.com>
|
||||
Written by Mydraal <vulpyne@vulpyne.net>
|
||||
Updated by Adam Sulmicki <adam@cfar.umd.edu>
|
||||
Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
|
||||
Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>
|
||||
|
|
23
MAINTAINERS
23
MAINTAINERS
|
@ -650,6 +650,11 @@ L: linux-crypto@vger.kernel.org
|
|||
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
|
||||
S: Maintained
|
||||
|
||||
CS5535 Audio ALSA driver
|
||||
P: Jaya Kumar
|
||||
M: jayakumar.alsa@gmail.com
|
||||
S: Maintained
|
||||
|
||||
CYBERPRO FB DRIVER
|
||||
P: Russell King
|
||||
M: rmk@arm.linux.org.uk
|
||||
|
@ -1465,7 +1470,6 @@ P: Several
|
|||
L: kernel-janitors@osdl.org
|
||||
W: http://www.kerneljanitors.org/
|
||||
W: http://sf.net/projects/kernel-janitor/
|
||||
W: http://developer.osdl.org/rddunlap/kj-patches/
|
||||
S: Maintained
|
||||
|
||||
KERNEL NFSD
|
||||
|
@ -1476,17 +1480,11 @@ W: http://nfs.sourceforge.net/
|
|||
W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
|
||||
S: Maintained
|
||||
|
||||
KERNEL EVENT LAYER (KOBJECT_UEVENT)
|
||||
P: Robert Love
|
||||
M: rml@novell.com
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
KEXEC
|
||||
P: Eric Biederman
|
||||
P: Randy Dunlap
|
||||
M: ebiederm@xmission.com
|
||||
M: rddunlap@osdl.org
|
||||
M: rdunlap@xenotime.net
|
||||
W: http://www.xmission.com/~ebiederm/files/kexec/
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: fastboot@osdl.org
|
||||
|
@ -2587,7 +2585,6 @@ S: Maintained
|
|||
UDF FILESYSTEM
|
||||
P: Ben Fennema
|
||||
M: bfennema@falcon.csc.calpoly.edu
|
||||
L: linux_udf@hpesjro.fc.hp.com
|
||||
W: http://linux-udf.sourceforge.net
|
||||
S: Maintained
|
||||
|
||||
|
@ -2640,6 +2637,12 @@ L: linux-usb-users@lists.sourceforge.net
|
|||
L: linux-usb-devel@lists.sourceforge.net
|
||||
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
|
||||
P: Oliver Neukum
|
||||
M: oliver@neukum.name
|
||||
|
@ -2651,7 +2654,7 @@ USB MASS STORAGE DRIVER
|
|||
P: Matthew Dharm
|
||||
M: mdharm-usb@one-eyed-alien.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
|
||||
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
|
||||
|
||||
|
|
26
Makefile
26
Makefile
|
@ -286,10 +286,6 @@ export quiet Q KBUILD_VERBOSE
|
|||
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 ;)
|
||||
|
||||
# For backward compatibility
|
||||
check_gcc = $(warning check_gcc is deprecated - use cc-option) \
|
||||
$(call cc-option, $(1),$(2))
|
||||
|
||||
# cc-option-yn
|
||||
# Usage: flag := $(call cc-option-yn, -march=winchip-c6)
|
||||
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
|
||||
# oldconfig if changes are detected.
|
||||
-include .config.cmd
|
||||
-include .kconfig.d
|
||||
|
||||
include .config
|
||||
|
||||
# If .config needs to be updated, it will be done via the dependency
|
||||
# that autoconf has on .config.
|
||||
# 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
|
||||
# with it and forgot to run make oldconfig
|
||||
include/linux/autoconf.h: .config
|
||||
# with it and forgot to run make oldconfig.
|
||||
# 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)$(MAKE) -f $(srctree)/Makefile silentoldconfig
|
||||
else
|
||||
|
@ -1066,7 +1064,7 @@ help:
|
|||
@echo ' all - Build all targets marked with [*]'
|
||||
@echo '* vmlinux - Build the bare kernel'
|
||||
@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/file.[ois] - Build specified target only'
|
||||
@echo ' dir/file.ko - Build module including final link'
|
||||
|
@ -1240,7 +1238,10 @@ cscope: FORCE
|
|||
quiet_cmd_TAGS = MAKE $@
|
||||
define cmd_TAGS
|
||||
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 && \
|
||||
echo "-I __initdata,__exitdata,__acquires,__releases \
|
||||
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
|
||||
--extra=+f --c-kinds=+px"`; \
|
||||
$(all-sources) | xargs etags $$ETAGSF -a
|
||||
endef
|
||||
|
||||
|
@ -1251,7 +1252,10 @@ TAGS: FORCE
|
|||
quiet_cmd_tags = MAKE $@
|
||||
define cmd_tags
|
||||
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 && \
|
||||
echo "-I __initdata,__exitdata,__acquires,__releases \
|
||||
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
|
||||
--extra=+f --c-kinds=+px"`; \
|
||||
$(all-sources) | xargs ctags $$CTAGSF -a
|
||||
endef
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
|
|||
}
|
||||
|
||||
#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);
|
||||
|
||||
|
@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
|
|||
return 0;
|
||||
}
|
||||
#else
|
||||
#define amba_hotplug NULL
|
||||
#define amba_uevent NULL
|
||||
#endif
|
||||
|
||||
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 = {
|
||||
.name = "amba",
|
||||
.match = amba_match,
|
||||
.hotplug = amba_hotplug,
|
||||
.uevent = amba_uevent,
|
||||
.suspend = amba_suspend,
|
||||
.resume = amba_resume,
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <asm/arch/pxafb.h>
|
||||
#include <asm/arch/mmc.h>
|
||||
#include <asm/arch/irda.h>
|
||||
#include <asm/arch/ohci.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
|
@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = {
|
|||
&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)
|
||||
{
|
||||
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_ficp_info(&mainstone_ficp_platform_data);
|
||||
pxa_set_ohci_info(&mainstone_ohci_platform_data);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <asm/hardware.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/arch/ohci.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
|
@ -194,6 +195,11 @@ static struct platform_device ohci_device = {
|
|||
.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 = {
|
||||
&ohci_device,
|
||||
};
|
||||
|
|
|
@ -46,10 +46,9 @@ typedef struct task_struct* PTASK;
|
|||
|
||||
#ifdef MODULE
|
||||
void fp_send_sig(unsigned long sig, PTASK p, int priv);
|
||||
#if LINUX_VERSION_CODE > 0x20115
|
||||
|
||||
MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
|
||||
MODULE_DESCRIPTION("NWFPE floating point emulator");
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define fp_send_sig send_sig
|
||||
|
|
|
@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb)
|
|||
*/
|
||||
static int nforce2_set_fsb(unsigned int fsb)
|
||||
{
|
||||
u32 pll, temp = 0;
|
||||
u32 temp = 0;
|
||||
unsigned int tfsb;
|
||||
int diff;
|
||||
int pll = 0;
|
||||
|
||||
if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
|
||||
printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#define PFX "powernow-k8: "
|
||||
#define BFX PFX "BIOS error: "
|
||||
#define VERSION "version 1.50.4"
|
||||
#define VERSION "version 1.60.0"
|
||||
#include "powernow-k8.h"
|
||||
|
||||
/* serialize freq changes */
|
||||
|
@ -336,7 +336,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
|
|||
/* Phase 2 - core frequency transition */
|
||||
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)) {
|
||||
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;
|
||||
|
||||
while (vcofiddiff > 2) {
|
||||
(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
|
||||
|
||||
if (reqfid > data->currfid) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
|
@ -371,7 +373,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (write_new_fid(data, data->currfid - 2))
|
||||
if (write_new_fid(data, data->currfid - fid_interval))
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -464,7 +466,7 @@ static int check_supported_cpu(unsigned int cpu)
|
|||
set_cpus_allowed(current, cpumask_of_cpu(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;
|
||||
}
|
||||
|
||||
|
@ -474,7 +476,7 @@ static int check_supported_cpu(unsigned int cpu)
|
|||
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
|
||||
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
|
||||
((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);
|
||||
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);
|
||||
return -ENODEV;
|
||||
}
|
||||
if ((pst[j].fid > MAX_FID)
|
||||
|| (pst[j].fid & 1)
|
||||
|| (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
|
||||
if (pst[j].fid > MAX_FID) {
|
||||
printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
|
||||
/* 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;
|
||||
}
|
||||
if (pst[j].fid < lastfid)
|
||||
lastfid = pst[j].fid;
|
||||
}
|
||||
if (lastfid & 1) {
|
||||
printk(KERN_ERR PFX "lastfid invalid\n");
|
||||
printk(KERN_ERR BFX "lastfid invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -631,7 +635,7 @@ static int find_psb_table(struct powernow_k8_data *data)
|
|||
|
||||
dprintk("table vers: 0x%x\n", psb->tableversion);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -689,7 +693,7 @@ static int find_psb_table(struct powernow_k8_data *data)
|
|||
* BIOS and Kernel Developer's Guide, which is available on
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
@ -912,7 +916,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
|
|||
set_cpus_allowed(current, cpumask_of_cpu(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;
|
||||
}
|
||||
|
||||
|
@ -982,6 +986,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
|
|||
cpumask_t oldmask = CPU_MASK_ALL;
|
||||
int rc, i;
|
||||
|
||||
if (!cpu_online(pol->cpu))
|
||||
return -ENODEV;
|
||||
|
||||
if (!check_supported_cpu(pol->cpu))
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1162,10 +1169,9 @@ static void __exit powernowk8_exit(void)
|
|||
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_LICENSE("GPL");
|
||||
|
||||
late_initcall(powernowk8_init);
|
||||
module_exit(powernowk8_exit);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ struct powernow_k8_data {
|
|||
#define CPUID_XFAM 0x0ff00000 /* extended family */
|
||||
#define CPUID_XFAM_K8 0
|
||||
#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_GET_MAX_CAPABILITIES 0x80000000
|
||||
#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
|
||||
|
@ -86,13 +86,14 @@ struct powernow_k8_data {
|
|||
* low fid table
|
||||
* - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
|
||||
* 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
|
||||
* (only applies to MP systems obviously)
|
||||
*/
|
||||
|
||||
/* 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 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 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 VID_OFF 0x3f
|
||||
|
|
|
@ -40,6 +40,7 @@ static struct pci_dev *speedstep_chipset_dev;
|
|||
*/
|
||||
static unsigned int speedstep_processor = 0;
|
||||
|
||||
static u32 pmbase;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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)
|
||||
{
|
||||
u32 pmbase;
|
||||
u8 pm2_blk;
|
||||
u8 value;
|
||||
unsigned long flags;
|
||||
|
||||
if (!speedstep_chipset_dev || (state > 0x1))
|
||||
if (state > 0x1)
|
||||
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 */
|
||||
local_irq_save(flags);
|
||||
|
||||
|
@ -315,10 +329,11 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
|
|||
cpus_allowed = current->cpus_allowed;
|
||||
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,
|
||||
&speedstep_freqs[SPEEDSTEP_LOW].frequency,
|
||||
&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
|
||||
&policy->cpuinfo.transition_latency,
|
||||
&speedstep_set_state);
|
||||
set_cpus_allowed(current, cpus_allowed);
|
||||
if (result)
|
||||
|
@ -335,7 +350,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
|
|||
|
||||
/* cpuinfo and default policy values */
|
||||
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
|
||||
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
|
||||
policy->cur = speed;
|
||||
|
||||
result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
|
||||
|
@ -400,6 +414,9 @@ static int __init speedstep_init(void)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (speedstep_find_register())
|
||||
return -ENODEV;
|
||||
|
||||
return cpufreq_register_driver(&speedstep_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -320,11 +320,13 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor);
|
|||
unsigned int speedstep_get_freqs(unsigned int processor,
|
||||
unsigned int *low_speed,
|
||||
unsigned int *high_speed,
|
||||
unsigned int *transition_latency,
|
||||
void (*set_state) (unsigned int state))
|
||||
{
|
||||
unsigned int prev_speed;
|
||||
unsigned int ret = 0;
|
||||
unsigned long flags;
|
||||
struct timeval tv1, tv2;
|
||||
|
||||
if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
|
||||
return -EINVAL;
|
||||
|
@ -350,8 +352,17 @@ unsigned int speedstep_get_freqs(unsigned int processor,
|
|||
|
||||
dprintk("low speed is %u\n", *low_speed);
|
||||
|
||||
/* start latency measurement */
|
||||
if (transition_latency)
|
||||
do_gettimeofday(&tv1);
|
||||
|
||||
/* switch to high state */
|
||||
set_state(SPEEDSTEP_HIGH);
|
||||
|
||||
/* end latency measurement */
|
||||
if (transition_latency)
|
||||
do_gettimeofday(&tv2);
|
||||
|
||||
*high_speed = speedstep_get_processor_frequency(processor);
|
||||
if (!*high_speed) {
|
||||
ret = -EIO;
|
||||
|
@ -369,6 +380,25 @@ unsigned int speedstep_get_freqs(unsigned int processor,
|
|||
if (*high_speed != prev_speed)
|
||||
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:
|
||||
local_irq_restore(flags);
|
||||
return (ret);
|
||||
|
|
|
@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
|
|||
extern unsigned int speedstep_get_freqs(unsigned int processor,
|
||||
unsigned int *low_speed,
|
||||
unsigned int *high_speed,
|
||||
unsigned int *transition_latency,
|
||||
void (*set_state) (unsigned int state));
|
||||
|
|
|
@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
|
|||
result = speedstep_get_freqs(speedstep_processor,
|
||||
&speedstep_freqs[SPEEDSTEP_LOW].frequency,
|
||||
&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
|
||||
NULL,
|
||||
&speedstep_set_state);
|
||||
|
||||
if (result) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
/*
|
||||
* 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");
|
||||
|
||||
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",
|
||||
cpu_khz / 1000, (cpu_khz % 1000));
|
||||
freq / 1000, (freq % 1000));
|
||||
}
|
||||
|
||||
/* Cache size */
|
||||
|
|
|
@ -452,7 +452,7 @@ DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
|
|||
#endif
|
||||
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
|
||||
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(10, SIGSEGV, "invalid TSS", invalid_TSS)
|
||||
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <linux/initrd.h>
|
||||
#include <linux/platform.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
#include <asm/ia32.h>
|
||||
#include <asm/machvec.h>
|
||||
|
@ -517,6 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v)
|
|||
char family[32], features[128], *cp, sep;
|
||||
struct cpuinfo_ia64 *c = v;
|
||||
unsigned long mask;
|
||||
unsigned int proc_freq;
|
||||
int i;
|
||||
|
||||
mask = c->features;
|
||||
|
@ -549,6 +551,10 @@ show_cpuinfo (struct seq_file *m, void *v)
|
|||
sprintf(cp, " 0x%lx", mask);
|
||||
}
|
||||
|
||||
proc_freq = cpufreq_quick_get(cpunum);
|
||||
if (!proc_freq)
|
||||
proc_freq = c->proc_freq / 1000;
|
||||
|
||||
seq_printf(m,
|
||||
"processor : %d\n"
|
||||
"vendor : %s\n"
|
||||
|
@ -565,7 +571,7 @@ show_cpuinfo (struct seq_file *m, void *v)
|
|||
"BogoMIPS : %lu.%02lu\n",
|
||||
cpunum, c->vendor, family, c->model, c->revision, c->archrev,
|
||||
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,
|
||||
lpj*HZ/500000, (lpj*HZ/5000) % 100);
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
return -ENODEV;
|
||||
|
@ -79,7 +79,7 @@ static void tiocx_bus_release(struct device *dev)
|
|||
struct bus_type tiocx_bus_type = {
|
||||
.name = "tiocx",
|
||||
.match = tiocx_match,
|
||||
.hotplug = tiocx_hotplug,
|
||||
.uevent = tiocx_uevent,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -420,7 +420,7 @@ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf,
|
|||
goto out;
|
||||
pos = merge_64(a4, a5);
|
||||
ret = rw_verify_area(READ, file, &pos, count);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = -EINVAL;
|
||||
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;
|
||||
pos = merge_64(a4, a5);
|
||||
ret = rw_verify_area(WRITE, file, &pos, count);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = -EINVAL;
|
||||
if (!file->f_op || !(write = file->f_op->write))
|
||||
|
|
|
@ -293,6 +293,6 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
|
|||
|
||||
struct bus_type vio_bus_type = {
|
||||
.name = "vio",
|
||||
.hotplug = vio_hotplug,
|
||||
.uevent = vio_hotplug,
|
||||
.match = vio_bus_match,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
bootsect
|
||||
bzImage
|
||||
setup
|
|
@ -0,0 +1 @@
|
|||
build
|
|
@ -0,0 +1 @@
|
|||
vsyscall*.so
|
|
@ -42,6 +42,7 @@
|
|||
#include <linux/edd.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
#include <asm/mtrr.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");
|
||||
|
||||
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",
|
||||
cpu_khz / 1000, (cpu_khz % 1000));
|
||||
freq / 1000, (freq % 1000));
|
||||
}
|
||||
|
||||
/* Cache size */
|
||||
|
|
|
@ -358,7 +358,7 @@ static struct sysfs_ops disk_sysfs_ops = {
|
|||
static ssize_t disk_uevent_store(struct gendisk * disk,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
kobject_hotplug(&disk->kobj, KOBJ_ADD);
|
||||
kobject_uevent(&disk->kobj, KOBJ_ADD);
|
||||
return count;
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
struct kobj_type *ktype = get_ktype(kobj);
|
||||
|
@ -474,18 +474,18 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
|
||||
if (ktype == &ktype_block) {
|
||||
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);
|
||||
} else if (ktype == &ktype_part) {
|
||||
disk = container_of(kobj->parent, struct gendisk, 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",
|
||||
disk->first_minor + part->partno);
|
||||
} else
|
||||
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);
|
||||
|
||||
/* add physical device, backing this device */
|
||||
|
@ -493,18 +493,18 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
if (physdev) {
|
||||
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);
|
||||
kfree(path);
|
||||
|
||||
if (physdev->bus)
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s",
|
||||
physdev->bus->name);
|
||||
|
||||
if (physdev->driver)
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s",
|
||||
physdev->driver->name);
|
||||
|
@ -520,13 +520,13 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct kset_hotplug_ops block_hotplug_ops = {
|
||||
.filter = block_hotplug_filter,
|
||||
.hotplug = block_hotplug,
|
||||
static struct kset_uevent_ops block_uevent_ops = {
|
||||
.filter = block_uevent_filter,
|
||||
.uevent = block_uevent,
|
||||
};
|
||||
|
||||
/* declare block_subsys. */
|
||||
static decl_subsys(block, &ktype_block, &block_hotplug_ops);
|
||||
static decl_subsys(block, &ktype_block, &block_uevent_ops);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -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.state = 0;
|
||||
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_dma_alignment(q, 511);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -657,8 +662,8 @@ EXPORT_SYMBOL(blk_queue_hardsect_size);
|
|||
void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
|
||||
{
|
||||
/* zero is "infinity" */
|
||||
t->max_sectors = t->max_hw_sectors =
|
||||
min_not_zero(t->max_sectors,b->max_sectors);
|
||||
t->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_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,
|
||||
struct bio *bio)
|
||||
{
|
||||
unsigned short max_sectors;
|
||||
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;
|
||||
if (req == q->last_merge)
|
||||
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,
|
||||
struct bio *bio)
|
||||
{
|
||||
unsigned short max_sectors;
|
||||
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;
|
||||
if (req == q->last_merge)
|
||||
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;
|
||||
int reading;
|
||||
|
||||
if (len > (q->max_sectors << 9))
|
||||
if (len > (q->max_hw_sectors << 9))
|
||||
return -EINVAL;
|
||||
if (!len || !ubuf)
|
||||
return -EINVAL;
|
||||
|
@ -2259,7 +2277,7 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
|
|||
{
|
||||
struct bio *bio;
|
||||
|
||||
if (len > (q->max_sectors << 9))
|
||||
if (len > (q->max_hw_sectors << 9))
|
||||
return -EINVAL;
|
||||
if (!len || !kbuf)
|
||||
return -EINVAL;
|
||||
|
@ -2306,6 +2324,8 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
|
|||
generic_unplug_device(q);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
|
||||
|
||||
/**
|
||||
* blk_execute_rq - insert a request into queue for execution
|
||||
* @q: queue to insert the request in
|
||||
|
@ -2444,7 +2464,7 @@ void disk_round_stats(struct gendisk *disk)
|
|||
/*
|
||||
* 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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
|
|
@ -233,7 +233,7 @@ static int sg_io(struct file *file, request_queue_t *q,
|
|||
if (verify_command(file, cmd))
|
||||
return -EPERM;
|
||||
|
||||
if (hdr->dxfer_len > (q->max_sectors << 9))
|
||||
if (hdr->dxfer_len > (q->max_hw_sectors << 9))
|
||||
return -EIO;
|
||||
|
||||
if (hdr->dxfer_len)
|
||||
|
|
|
@ -172,7 +172,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
|
|||
if (ACPI_FAILURE(status) || !device) {
|
||||
result = container_device_add(&device, handle);
|
||||
if (!result)
|
||||
kobject_hotplug(&device->kobj,
|
||||
kobject_uevent(&device->kobj,
|
||||
KOBJ_ONLINE);
|
||||
else
|
||||
printk("Failed to add container\n");
|
||||
|
@ -180,13 +180,13 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
|
|||
} else {
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
/* device exist and this is a remove request */
|
||||
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
|
||||
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACPI_NOTIFY_EJECT_REQUEST:
|
||||
if (!acpi_bus_get_device(handle, &device) && device) {
|
||||
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
|
||||
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -748,7 +748,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
|
|||
return_VALUE(-ENODEV);
|
||||
|
||||
if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
|
||||
kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
|
||||
kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
|
||||
}
|
||||
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)) {
|
||||
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
|
||||
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
|
||||
break;
|
||||
}
|
||||
|
||||
result = acpi_processor_start(device);
|
||||
if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
|
||||
kobject_hotplug(&device->kobj, KOBJ_ONLINE);
|
||||
kobject_uevent(&device->kobj, KOBJ_ONLINE);
|
||||
} else {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
|
||||
"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)))
|
||||
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
|
||||
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
|
||||
break;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
|
|
|
@ -78,7 +78,7 @@ static struct kobj_type ktype_acpi_ns = {
|
|||
.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,
|
||||
int buffer_size)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
|
|||
if (!dev->driver)
|
||||
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))
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -98,8 +98,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct kset_hotplug_ops namespace_hotplug_ops = {
|
||||
.hotplug = &namespace_hotplug,
|
||||
static struct kset_uevent_ops namespace_uevent_ops = {
|
||||
.uevent = &namespace_uevent,
|
||||
};
|
||||
|
||||
static struct kset acpi_namespace_kset = {
|
||||
|
@ -108,7 +108,7 @@ static struct kset acpi_namespace_kset = {
|
|||
},
|
||||
.subsys = &acpi_subsys,
|
||||
.ktype = &ktype_acpi_ns,
|
||||
.hotplug_ops = &namespace_hotplug_ops,
|
||||
.uevent_ops = &namespace_uevent_ops,
|
||||
};
|
||||
|
||||
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,
|
||||
const char *buf, size_t count);
|
||||
|
|
|
@ -19,11 +19,11 @@ config PREVENT_FIRMWARE_BUILD
|
|||
If unsure say Y here.
|
||||
|
||||
config FW_LOADER
|
||||
tristate "Hotplug firmware loading support"
|
||||
tristate "Userspace firmware loading support"
|
||||
select HOTPLUG
|
||||
---help---
|
||||
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.
|
||||
|
||||
config DEBUG_DRIVER
|
||||
|
|
|
@ -152,7 +152,11 @@ static ssize_t driver_unbind(struct device_driver *drv,
|
|||
|
||||
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
|
||||
if (dev && dev->driver == drv) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
device_release_driver(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
err = count;
|
||||
}
|
||||
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);
|
||||
if (dev && dev->driver == NULL) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
down(&dev->sem);
|
||||
err = driver_probe_device(drv, dev);
|
||||
up(&dev->sem);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
}
|
||||
put_device(dev);
|
||||
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.
|
||||
|
@ -449,8 +477,7 @@ int bus_add_driver(struct device_driver * drv)
|
|||
module_add_driver(drv->owner, drv);
|
||||
|
||||
driver_add_attrs(bus, drv);
|
||||
driver_create_file(drv, &driver_attr_unbind);
|
||||
driver_create_file(drv, &driver_attr_bind);
|
||||
add_bind_files(drv);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
@ -468,8 +495,7 @@ int bus_add_driver(struct device_driver * drv)
|
|||
void bus_remove_driver(struct device_driver * drv)
|
||||
{
|
||||
if (drv->bus) {
|
||||
driver_remove_file(drv, &driver_attr_bind);
|
||||
driver_remove_file(drv, &driver_attr_unbind);
|
||||
remove_bind_files(drv);
|
||||
driver_remove_attrs(drv->bus, drv);
|
||||
klist_remove(&drv->knode_bus);
|
||||
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 */
|
||||
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);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
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 *buffer, int buffer_size)
|
||||
{
|
||||
|
@ -331,7 +331,7 @@ static struct kobj_type ktype_class_device = {
|
|||
.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);
|
||||
|
||||
|
@ -343,14 +343,14 @@ static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
|
|||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
struct class_device *class_dev = to_class_dev(kobj);
|
||||
|
@ -365,27 +365,27 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
struct device *dev = class_dev->dev;
|
||||
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);
|
||||
kfree(path);
|
||||
|
||||
if (dev->bus)
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", dev->bus->name);
|
||||
|
||||
if (dev->driver)
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
}
|
||||
|
||||
if (MAJOR(class_dev->devt)) {
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"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,
|
||||
"MINOR=%u", MINOR(class_dev->devt));
|
||||
}
|
||||
|
@ -397,30 +397,30 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
buffer = &buffer[length];
|
||||
buffer_size -= length;
|
||||
|
||||
if (class_dev->hotplug) {
|
||||
if (class_dev->uevent) {
|
||||
/* 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);
|
||||
if (retval)
|
||||
pr_debug("class_dev->hotplug() returned %d\n", retval);
|
||||
} else if (class_dev->class->hotplug) {
|
||||
pr_debug("class_dev->uevent() returned %d\n", retval);
|
||||
} else if (class_dev->class->uevent) {
|
||||
/* 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);
|
||||
if (retval)
|
||||
pr_debug("class->hotplug() returned %d\n", retval);
|
||||
pr_debug("class->uevent() returned %d\n", retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct kset_hotplug_ops class_hotplug_ops = {
|
||||
.filter = class_hotplug_filter,
|
||||
.name = class_hotplug_name,
|
||||
.hotplug = class_hotplug,
|
||||
static struct kset_uevent_ops class_uevent_ops = {
|
||||
.filter = class_uevent_filter,
|
||||
.name = class_uevent_name,
|
||||
.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)
|
||||
|
@ -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,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
|
||||
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -559,7 +559,7 @@ int class_device_add(struct class_device *class_dev)
|
|||
class_name);
|
||||
}
|
||||
|
||||
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
|
||||
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
|
||||
|
||||
/* notify any interfaces this device is now here */
|
||||
if (parent_class) {
|
||||
|
@ -632,7 +632,7 @@ struct class_device *class_device_create(struct class *cls,
|
|||
class_dev->class = cls;
|
||||
class_dev->parent = parent;
|
||||
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);
|
||||
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_attrs(class_dev);
|
||||
|
||||
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
|
||||
kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
|
||||
kobject_del(&class_dev->kobj);
|
||||
|
||||
class_device_put(parent_device);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -102,14 +102,14 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
|
|||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
struct device *dev = to_dev(kobj);
|
||||
|
@ -119,13 +119,13 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
|
||||
/* add bus name of physical device */
|
||||
if (dev->bus)
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", dev->bus->name);
|
||||
|
||||
/* add driver name of physical device */
|
||||
if (dev->driver)
|
||||
add_hotplug_env_var(envp, num_envp, &i,
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
|
||||
|
@ -136,11 +136,11 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
buffer = &buffer[length];
|
||||
buffer_size -= length;
|
||||
|
||||
if (dev->bus && dev->bus->hotplug) {
|
||||
if (dev->bus && dev->bus->uevent) {
|
||||
/* 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) {
|
||||
pr_debug ("%s - hotplug() returned %d\n",
|
||||
pr_debug ("%s - uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
}
|
||||
|
@ -148,16 +148,16 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
return retval;
|
||||
}
|
||||
|
||||
static struct kset_hotplug_ops device_hotplug_ops = {
|
||||
.filter = dev_hotplug_filter,
|
||||
.name = dev_hotplug_name,
|
||||
.hotplug = dev_hotplug,
|
||||
static struct kset_uevent_ops device_uevent_ops = {
|
||||
.filter = dev_uevent_filter,
|
||||
.name = dev_uevent_name,
|
||||
.uevent = dev_uevent,
|
||||
};
|
||||
|
||||
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
kobject_hotplug(&dev->kobj, KOBJ_ADD);
|
||||
kobject_uevent(&dev->kobj, KOBJ_ADD);
|
||||
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.
|
||||
*/
|
||||
|
||||
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;
|
||||
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)))
|
||||
goto PMError;
|
||||
if ((error = bus_add_device(dev)))
|
||||
|
@ -291,7 +291,7 @@ int device_add(struct device *dev)
|
|||
BusError:
|
||||
device_pm_remove(dev);
|
||||
PMError:
|
||||
kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
|
||||
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
|
||||
kobject_del(&dev->kobj);
|
||||
Error:
|
||||
if (parent)
|
||||
|
@ -374,7 +374,7 @@ void device_del(struct device * dev)
|
|||
platform_notify_remove(dev);
|
||||
bus_remove_device(dev);
|
||||
device_pm_remove(dev);
|
||||
kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
|
||||
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
|
||||
kobject_del(&dev->kobj);
|
||||
if (parent)
|
||||
put_device(parent);
|
||||
|
|
|
@ -41,14 +41,14 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
|
|||
case '0':
|
||||
ret = cpu_down(cpu->sysdev.id);
|
||||
if (!ret)
|
||||
kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
|
||||
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
|
||||
break;
|
||||
case '1':
|
||||
ret = smp_prepare_cpu(cpu->sysdev.id);
|
||||
if (!ret)
|
||||
ret = cpu_up(cpu->sysdev.id);
|
||||
if (!ret)
|
||||
kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
|
||||
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
|
|
@ -65,7 +65,8 @@ void device_bind_driver(struct device * dev)
|
|||
* This function returns 1 if a match is found, an error if one
|
||||
* 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)
|
||||
{
|
||||
|
@ -123,6 +124,8 @@ static int __device_attach(struct device_driver * drv, void * data)
|
|||
*
|
||||
* Returns 1 if the device was bound to a driver;
|
||||
* 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)
|
||||
{
|
||||
|
@ -152,10 +155,14 @@ static int __driver_attach(struct device * dev, void * data)
|
|||
* is an error.
|
||||
*/
|
||||
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
down(&dev->sem);
|
||||
if (!dev->driver)
|
||||
driver_probe_device(drv, dev);
|
||||
up(&dev->sem);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -181,6 +188,8 @@ void driver_attach(struct device_driver * drv)
|
|||
* Manually detach device from driver.
|
||||
*
|
||||
* __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)
|
||||
|
@ -233,10 +242,14 @@ void driver_detach(struct device_driver * drv)
|
|||
get_device(dev);
|
||||
spin_unlock(&drv->klist_devices.k_lock);
|
||||
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
down(&dev->sem);
|
||||
if (dev->driver == drv)
|
||||
__device_release_driver(dev);
|
||||
up(&dev->sem);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
put_device(dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 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);
|
||||
|
||||
static struct class firmware_class = {
|
||||
.name = "firmware",
|
||||
.hotplug = firmware_class_hotplug,
|
||||
.uevent = firmware_class_uevent,
|
||||
.release = fw_class_dev_release,
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
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))
|
||||
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))
|
||||
return -ENOMEM;
|
||||
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
|
@ -352,7 +351,7 @@ error_kfree:
|
|||
|
||||
static int
|
||||
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 firmware_priv *fw_priv;
|
||||
|
@ -384,7 +383,7 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
|
|||
goto error_unreg;
|
||||
}
|
||||
|
||||
if (hotplug)
|
||||
if (uevent)
|
||||
set_bit(FW_STATUS_READY, &fw_priv->status);
|
||||
else
|
||||
set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
|
||||
|
@ -399,7 +398,7 @@ out:
|
|||
|
||||
static int
|
||||
_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 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,
|
||||
hotplug);
|
||||
uevent);
|
||||
if (retval)
|
||||
goto error_kfree_fw;
|
||||
|
||||
fw_priv = class_get_devdata(class_dev);
|
||||
|
||||
if (hotplug) {
|
||||
if (uevent) {
|
||||
if (loading_timeout > 0) {
|
||||
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
|
||||
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);
|
||||
set_bit(FW_STATUS_DONE, &fw_priv->status);
|
||||
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
|
||||
* @name: name of firmware file
|
||||
* @device: device for which firmware is being loaded
|
||||
|
@ -466,7 +465,7 @@ out:
|
|||
*
|
||||
* 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
|
||||
* firmware image for this or any other device.
|
||||
**/
|
||||
|
@ -474,8 +473,8 @@ int
|
|||
request_firmware(const struct firmware **firmware_p, const char *name,
|
||||
struct device *device)
|
||||
{
|
||||
int hotplug = 1;
|
||||
return _request_firmware(firmware_p, name, device, hotplug);
|
||||
int uevent = 1;
|
||||
return _request_firmware(firmware_p, name, device, uevent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -518,7 +517,7 @@ struct firmware_work {
|
|||
struct device *device;
|
||||
void *context;
|
||||
void (*cont)(const struct firmware *fw, void *context);
|
||||
int hotplug;
|
||||
int uevent;
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -533,7 +532,7 @@ request_firmware_work_func(void *arg)
|
|||
}
|
||||
daemonize("%s/%s", "firmware", fw_work->name);
|
||||
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
|
||||
fw_work->hotplug);
|
||||
fw_work->uevent);
|
||||
if (ret < 0)
|
||||
fw_work->cont(NULL, fw_work->context);
|
||||
else {
|
||||
|
@ -548,7 +547,7 @@ request_firmware_work_func(void *arg)
|
|||
/**
|
||||
* request_firmware_nowait: asynchronous version of request_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.
|
||||
* @name: name of firmware file
|
||||
* @device: device for which firmware is being loaded
|
||||
|
@ -562,7 +561,7 @@ request_firmware_work_func(void *arg)
|
|||
**/
|
||||
int
|
||||
request_firmware_nowait(
|
||||
struct module *module, int hotplug,
|
||||
struct module *module, int uevent,
|
||||
const char *name, struct device *device, void *context,
|
||||
void (*cont)(const struct firmware *fw, void *context))
|
||||
{
|
||||
|
@ -583,7 +582,7 @@ request_firmware_nowait(
|
|||
.device = device,
|
||||
.context = context,
|
||||
.cont = cont,
|
||||
.hotplug = hotplug,
|
||||
.uevent = uevent,
|
||||
};
|
||||
|
||||
ret = kernel_thread(request_firmware_work_func, fw_work,
|
||||
|
|
|
@ -29,12 +29,12 @@ static struct sysdev_class memory_sysdev_class = {
|
|||
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;
|
||||
}
|
||||
|
||||
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 retval = 0;
|
||||
|
@ -42,9 +42,9 @@ static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
return retval;
|
||||
}
|
||||
|
||||
static struct kset_hotplug_ops memory_hotplug_ops = {
|
||||
.name = memory_hotplug_name,
|
||||
.hotplug = memory_hotplug,
|
||||
static struct kset_uevent_ops memory_uevent_ops = {
|
||||
.name = memory_uevent_name,
|
||||
.uevent = memory_uevent,
|
||||
};
|
||||
|
||||
static struct notifier_block *memory_chain;
|
||||
|
@ -431,7 +431,7 @@ int __init memory_dev_init(void)
|
|||
unsigned int i;
|
||||
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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
struct device platform_bus = {
|
||||
.bus_id = "platform",
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(platform_bus);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_get_resource);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_get_irq);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_get_resource_byname);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_get_irq_byname);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_add_devices);
|
||||
|
||||
struct platform_object {
|
||||
struct platform_device pdev;
|
||||
|
@ -257,7 +263,7 @@ int platform_device_add(struct platform_device *pdev)
|
|||
p = &ioport_resource;
|
||||
}
|
||||
|
||||
if (p && request_resource(p, r)) {
|
||||
if (p && insert_resource(p, r)) {
|
||||
printk(KERN_ERR
|
||||
"%s: failed to claim resource %d\n",
|
||||
pdev->dev.bus_id, i);
|
||||
|
@ -282,24 +288,13 @@ int platform_device_add(struct platform_device *pdev)
|
|||
EXPORT_SYMBOL_GPL(platform_device_add);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* platform_device_unregister - remove a platform-level device
|
||||
* platform_device_del - remove a platform-level device
|
||||
* @pdev: platform device we're removing
|
||||
*
|
||||
* Note that this function will also release all memory- and port-based
|
||||
* 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;
|
||||
|
||||
|
@ -310,9 +305,37 @@ void platform_device_unregister(struct platform_device * pdev)
|
|||
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
|
||||
|
@ -355,6 +378,7 @@ error:
|
|||
platform_device_put(pdev);
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_device_register_simple);
|
||||
|
||||
static int platform_drv_probe(struct device *_dev)
|
||||
{
|
||||
|
@ -476,6 +500,7 @@ struct bus_type platform_bus_type = {
|
|||
.suspend = platform_suspend,
|
||||
.resume = platform_resume,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(platform_bus_type);
|
||||
|
||||
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);
|
||||
#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);
|
||||
|
|
|
@ -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.
|
||||
* @dev: Device.
|
||||
|
@ -80,3 +81,4 @@ void dpm_set_power_state(struct device * dev, pm_message_t state)
|
|||
dev->power.power_state = state;
|
||||
up(&dpm_sem);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
|
|
@ -358,7 +358,8 @@ config BLK_DEV_UB
|
|||
This driver supports certain USB attached storage devices
|
||||
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.
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
*
|
||||
* TODO (sorted by decreasing priority)
|
||||
* -- 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
|
||||
* -- 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
|
||||
|
@ -29,6 +28,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_usual.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/devfs_fs_kernel.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.
|
||||
* 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 */
|
||||
|
||||
|
@ -245,6 +235,13 @@ struct ub_scsi_cmd {
|
|||
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 {
|
||||
|
@ -340,6 +337,8 @@ struct ub_lun {
|
|||
int readonly;
|
||||
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. */
|
||||
/*
|
||||
* 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 */
|
||||
int openc; /* protected by ub_lock! */
|
||||
/* kref is too implicit for our taste */
|
||||
int reset; /* Reset is running */
|
||||
unsigned int tagcnt;
|
||||
char name[12];
|
||||
struct usb_device *dev;
|
||||
|
@ -387,6 +387,9 @@ struct ub_dev {
|
|||
struct bulk_cs_wrap work_bcs;
|
||||
struct usb_ctrlrequest work_cr;
|
||||
|
||||
struct work_struct reset_work;
|
||||
wait_queue_head_t reset_wait;
|
||||
|
||||
int sg_stat[6];
|
||||
struct ub_scsi_trace tr;
|
||||
};
|
||||
|
@ -395,12 +398,14 @@ struct ub_dev {
|
|||
*/
|
||||
static void ub_cleanup(struct ub_dev *sc);
|
||||
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,
|
||||
struct ub_scsi_cmd *cmd, struct request *rq);
|
||||
static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
|
||||
struct ub_scsi_cmd *cmd, struct request *rq);
|
||||
static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
|
||||
struct ub_scsi_cmd *cmd, struct ub_request *urq);
|
||||
static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
|
||||
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_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 void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
|
||||
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,
|
||||
int stalled_pipe);
|
||||
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_read_cap(struct ub_dev *sc, struct ub_lun *lun,
|
||||
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[] = {
|
||||
// { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, ub_usb_ids);
|
||||
#endif /* CONFIG_USB_LIBUSUAL */
|
||||
|
||||
/*
|
||||
* 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;
|
||||
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,
|
||||
"qlen %d qmax %d\n",
|
||||
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_scsi_cmd *cmd;
|
||||
int rc;
|
||||
struct ub_request *urq;
|
||||
int n_elem;
|
||||
|
||||
if (atomic_read(&sc->poison) || lun->changed) {
|
||||
blkdev_dequeue_request(rq);
|
||||
|
@ -778,66 +794,71 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (lun->urq.rq != NULL)
|
||||
return -1;
|
||||
if ((cmd = ub_get_cmd(lun)) == NULL)
|
||||
return -1;
|
||||
memset(cmd, 0, sizeof(struct ub_scsi_cmd));
|
||||
|
||||
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++;
|
||||
if (ub_submit_scsi(sc, cmd) != 0) {
|
||||
ub_put_cmd(lun, cmd);
|
||||
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;
|
||||
urq = &lun->urq;
|
||||
memset(urq, 0, sizeof(struct ub_request));
|
||||
urq->rq = rq;
|
||||
|
||||
/*
|
||||
* get scatterlist from block layer
|
||||
*/
|
||||
n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
|
||||
if (n_elem <= 0) {
|
||||
n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
|
||||
if (n_elem < 0) {
|
||||
printk(KERN_INFO "%s: failed request map (%d)\n",
|
||||
sc->name, n_elem); /* P3 */
|
||||
return -1; /* request with no s/g entries? */
|
||||
lun->name, n_elem); /* P3 */
|
||||
goto drop;
|
||||
}
|
||||
if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */
|
||||
printk(KERN_WARNING "%s: request with %d segments\n",
|
||||
sc->name, n_elem);
|
||||
return -1;
|
||||
lun->name, n_elem);
|
||||
goto drop;
|
||||
}
|
||||
cmd->nsg = n_elem;
|
||||
urq->nsg = n_elem;
|
||||
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
|
||||
*
|
||||
|
@ -847,7 +868,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
|
|||
block = rq->sector >> 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 */
|
||||
cmd->cdb[2] = block >> 24;
|
||||
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->len = rq->nr_sectors * 512;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
|
||||
struct ub_scsi_cmd *cmd, struct request *rq)
|
||||
static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
|
||||
struct ub_scsi_cmd *cmd, struct ub_request *urq)
|
||||
{
|
||||
int n_elem;
|
||||
struct request *rq = urq->rq;
|
||||
|
||||
if (rq->data_len == 0) {
|
||||
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;
|
||||
else
|
||||
cmd->dir = UB_DIR_READ;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* get scatterlist from block layer
|
||||
*/
|
||||
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]++;
|
||||
cmd->nsg = urq->nsg;
|
||||
memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
|
||||
|
||||
memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
|
||||
cmd->cdb_len = rq->cmd_len;
|
||||
|
||||
cmd->len = rq->data_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_request *urq = cmd->back;
|
||||
struct request *rq;
|
||||
int uptodate;
|
||||
|
||||
rq = urq->rq;
|
||||
|
||||
if (cmd->error == 0) {
|
||||
uptodate = 1;
|
||||
|
||||
|
@ -928,8 +933,15 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
rq->errors = SAM_STAT_CHECK_CONDITION;
|
||||
else
|
||||
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_end_rq(rq, uptodate);
|
||||
|
@ -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)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
|
||||
// assert(rc == 0);
|
||||
end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
|
||||
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).
|
||||
*
|
||||
|
@ -1075,7 +1119,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc)
|
|||
struct ub_scsi_cmd *cmd;
|
||||
int rc;
|
||||
|
||||
while ((cmd = ub_cmdq_peek(sc)) != NULL) {
|
||||
while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) {
|
||||
if (cmd->state == UB_CMDST_DONE) {
|
||||
ub_cmdq_pop(sc);
|
||||
(*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 bulk_cs_wrap *bcs;
|
||||
int len;
|
||||
int rc;
|
||||
|
||||
if (atomic_read(&sc->poison)) {
|
||||
/* A little too simplistic, I feel... */
|
||||
goto Bad_End;
|
||||
ub_state_done(sc, cmd, -ENODEV);
|
||||
return;
|
||||
}
|
||||
|
||||
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.
|
||||
* 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",
|
||||
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) {
|
||||
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",
|
||||
sc->name);
|
||||
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) {
|
||||
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",
|
||||
sc->name);
|
||||
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);
|
||||
|
||||
} 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);
|
||||
if (rc != 0) {
|
||||
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.
|
||||
* Retrying is pointless. Just do Bad End on it...
|
||||
*/
|
||||
goto Bad_End;
|
||||
ub_state_done(sc, cmd, rc);
|
||||
return;
|
||||
}
|
||||
cmd->state = UB_CMDST_CLEAR;
|
||||
ub_cmdtr_state(sc, cmd);
|
||||
return;
|
||||
}
|
||||
if (urb->status != 0) {
|
||||
case -ESHUTDOWN: /* unplug */
|
||||
case -EILSEQ: /* unplug timeout on uhci */
|
||||
ub_state_done(sc, cmd, -ENODEV);
|
||||
return;
|
||||
default:
|
||||
goto Bad_End;
|
||||
}
|
||||
if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
|
||||
/* XXX Must do reset here to unconfuse the device */
|
||||
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: "
|
||||
"unable to submit clear (%d)\n",
|
||||
sc->name, rc);
|
||||
/*
|
||||
* This is typically ENOMEM or some other such shit.
|
||||
* Retrying is pointless. Just do Bad End on it...
|
||||
*/
|
||||
goto Bad_End;
|
||||
ub_state_done(sc, cmd, rc);
|
||||
return;
|
||||
}
|
||||
cmd->state = UB_CMDST_CLR2STS;
|
||||
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) {
|
||||
/*
|
||||
* 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... */
|
||||
ub_state_stat(sc, cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
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: "
|
||||
"unable to submit clear (%d)\n",
|
||||
sc->name, rc);
|
||||
/*
|
||||
* This is typically ENOMEM or some other such shit.
|
||||
* Retrying is pointless. Just do Bad End on it...
|
||||
*/
|
||||
goto Bad_End;
|
||||
ub_state_done(sc, cmd, rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1266,14 +1338,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
ub_cmdtr_state(sc, cmd);
|
||||
return;
|
||||
}
|
||||
if (urb->status == -EOVERFLOW) {
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* Catch everything, including -EOVERFLOW and other nasties. */
|
||||
if (urb->status != 0)
|
||||
goto Bad_End;
|
||||
|
||||
|
@ -1319,15 +1385,15 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
rc = le32_to_cpu(bcs->Residue);
|
||||
if (rc != cmd->len - cmd->act_len) {
|
||||
len = le32_to_cpu(bcs->Residue);
|
||||
if (len != cmd->len - cmd->act_len) {
|
||||
/*
|
||||
* It is all right to transfer less, the caller has
|
||||
* to check. But it's not all right if the device
|
||||
* counts disagree with our counts.
|
||||
*/
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -1338,13 +1404,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
|
|||
ub_state_sense(sc, cmd);
|
||||
return;
|
||||
case US_BULK_STAT_PHASE:
|
||||
/* XXX We must reset the transport here */
|
||||
/* P3 */ printk("%s: status PHASE\n", sc->name);
|
||||
goto Bad_End;
|
||||
default:
|
||||
printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
|
||||
sc->name, bcs->Status);
|
||||
goto Bad_End;
|
||||
ub_state_done(sc, cmd, -EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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: "
|
||||
"wrong command state %d\n",
|
||||
sc->name, cmd->state);
|
||||
goto Bad_End;
|
||||
ub_state_done(sc, cmd, -EINVAL);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
@ -2146,7 +2300,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
|
|||
if (ep_in == NULL || ep_out == NULL) {
|
||||
printk(KERN_NOTICE "%s: failed endpoint check\n",
|
||||
sc->name);
|
||||
return -EIO;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Calculate and store the pipe values */
|
||||
|
@ -2172,6 +2326,9 @@ static int ub_probe(struct usb_interface *intf,
|
|||
int rc;
|
||||
int i;
|
||||
|
||||
if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
|
||||
return -ENXIO;
|
||||
|
||||
rc = -ENOMEM;
|
||||
if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
|
||||
goto err_core;
|
||||
|
@ -2181,6 +2338,8 @@ static int ub_probe(struct usb_interface *intf,
|
|||
usb_init_urb(&sc->work_urb);
|
||||
tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
|
||||
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);
|
||||
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) */
|
||||
|
||||
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)
|
||||
goto err_diag;
|
||||
|
@ -2272,6 +2432,7 @@ static int ub_probe(struct usb_interface *intf,
|
|||
|
||||
/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
|
||||
err_diag:
|
||||
err_dev_desc:
|
||||
usb_set_intfdata(intf, NULL);
|
||||
// usb_put_intf(sc->intf);
|
||||
usb_put_dev(sc->dev);
|
||||
|
@ -2309,14 +2470,14 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum)
|
|||
ub_revalidate(sc, lun);
|
||||
|
||||
rc = -ENOMEM;
|
||||
if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
|
||||
if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
|
||||
goto err_diskalloc;
|
||||
|
||||
lun->disk = disk;
|
||||
sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
|
||||
sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
|
||||
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->private_data = lun;
|
||||
disk->driverfs_dev = &sc->intf->dev;
|
||||
|
@ -2379,6 +2540,11 @@ static void ub_disconnect(struct usb_interface *intf)
|
|||
*/
|
||||
atomic_set(&sc->poison, 1);
|
||||
|
||||
/*
|
||||
* Wait for reset to end, if any.
|
||||
*/
|
||||
wait_event(sc->reset_wait, !sc->reset);
|
||||
|
||||
/*
|
||||
* Blow away queued commands.
|
||||
*
|
||||
|
@ -2392,7 +2558,7 @@ static void ub_disconnect(struct usb_interface *intf)
|
|||
{
|
||||
struct ub_scsi_cmd *cmd;
|
||||
int cnt = 0;
|
||||
while ((cmd = ub_cmdq_pop(sc)) != NULL) {
|
||||
while ((cmd = ub_cmdq_peek(sc)) != NULL) {
|
||||
cmd->error = -ENOTCONN;
|
||||
cmd->state = UB_CMDST_DONE;
|
||||
ub_cmdtr_state(sc, cmd);
|
||||
|
@ -2461,7 +2627,6 @@ static void ub_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
|
||||
static struct usb_driver ub_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ub",
|
||||
.probe = ub_probe,
|
||||
.disconnect = ub_disconnect,
|
||||
|
@ -2479,6 +2644,7 @@ static int __init ub_init(void)
|
|||
if ((rc = usb_register(&ub_driver)) != 0)
|
||||
goto err_register;
|
||||
|
||||
usb_usual_set_present(USB_US_TYPE_UB);
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
|
@ -2494,6 +2660,7 @@ static void __exit ub_exit(void)
|
|||
|
||||
devfs_remove(DEVFS_NAME);
|
||||
unregister_blkdev(UB_MAJOR, DRV_NAME);
|
||||
usb_usual_clear_present(USB_US_TYPE_UB);
|
||||
}
|
||||
|
||||
module_init(ub_init);
|
||||
|
|
|
@ -275,7 +275,6 @@ static void bcm203x_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
|
||||
static struct usb_driver bcm203x_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bcm203x",
|
||||
.probe = bcm203x_probe,
|
||||
.disconnect = bcm203x_disconnect,
|
||||
|
|
|
@ -768,7 +768,6 @@ static void bfusb_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
|
||||
static struct usb_driver bfusb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bfusb",
|
||||
.probe = bfusb_probe,
|
||||
.disconnect = bfusb_disconnect,
|
||||
|
|
|
@ -619,7 +619,6 @@ static void bpa10x_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
|
||||
static struct usb_driver bpa10x_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "bpa10x",
|
||||
.probe = bpa10x_probe,
|
||||
.disconnect = bpa10x_disconnect,
|
||||
|
|
|
@ -1044,7 +1044,6 @@ static void hci_usb_disconnect(struct usb_interface *intf)
|
|||
}
|
||||
|
||||
static struct usb_driver hci_usb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "hci_usb",
|
||||
.probe = hci_usb_probe,
|
||||
.disconnect = hci_usb_disconnect,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
consolemap_deftbl.c
|
||||
defkeymap.c
|
||||
|
||||
qtronixmap.c
|
||||
|
|
|
@ -358,7 +358,7 @@ typedef struct _failStat
|
|||
#define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo
|
||||
#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
|
||||
|
||||
|
|
|
@ -562,7 +562,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
|
|||
} /* 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
|
||||
* @file - pointer to open file object
|
||||
* @buf - pointer to returned data buffer
|
||||
|
|
|
@ -1554,10 +1554,8 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
|
|||
|
||||
EXPORT_SYMBOL(secure_tcp_sequence_number);
|
||||
|
||||
|
||||
|
||||
/* Generate secure starting point for ephemeral TCP port search */
|
||||
u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
|
||||
/* Generate secure starting point for ephemeral IPV4 transport port search */
|
||||
u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
|
||||
{
|
||||
struct keydata *keyptr = get_keyptr();
|
||||
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)
|
||||
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();
|
||||
u32 hash[12];
|
||||
|
@ -1586,7 +1584,7 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp
|
|||
|
||||
return twothirdsMD4Transform(daddr, hash);
|
||||
}
|
||||
EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
|
||||
EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
|
||||
|
|
|
@ -186,8 +186,8 @@ static int __init ixp4xx_wdt_init(void)
|
|||
unsigned long processor_id;
|
||||
|
||||
asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
|
||||
if (!(processor_id & 0xf)) {
|
||||
printk("IXP4XXX Watchdog: Rev. A0 CPU detected - "
|
||||
if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
|
||||
printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - "
|
||||
"watchdog disabled\n");
|
||||
|
||||
return -ENODEV;
|
||||
|
|
|
@ -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 */
|
||||
static struct usb_driver usb_pcwd_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRIVER_NAME,
|
||||
.probe = usb_pcwd_probe,
|
||||
.disconnect = usb_pcwd_disconnect,
|
||||
|
|
|
@ -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)
|
||||
* @cpu: CPU number
|
||||
|
|
|
@ -93,7 +93,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
|
|||
{
|
||||
return kstat_cpu(cpu).cpustat.idle +
|
||||
kstat_cpu(cpu).cpustat.iowait +
|
||||
( !dbs_tuners_ins.ignore_nice ?
|
||||
( dbs_tuners_ins.ignore_nice ?
|
||||
kstat_cpu(cpu).cpustat.nice :
|
||||
0);
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ show_one(sampling_rate, sampling_rate);
|
|||
show_one(sampling_down_factor, sampling_down_factor);
|
||||
show_one(up_threshold, up_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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned int input;
|
||||
|
@ -272,7 +272,7 @@ define_one_rw(sampling_rate);
|
|||
define_one_rw(sampling_down_factor);
|
||||
define_one_rw(up_threshold);
|
||||
define_one_rw(down_threshold);
|
||||
define_one_rw(ignore_nice);
|
||||
define_one_rw(ignore_nice_load);
|
||||
define_one_rw(freq_step);
|
||||
|
||||
static struct attribute * dbs_attributes[] = {
|
||||
|
@ -282,7 +282,7 @@ static struct attribute * dbs_attributes[] = {
|
|||
&sampling_down_factor.attr,
|
||||
&up_threshold.attr,
|
||||
&down_threshold.attr,
|
||||
&ignore_nice.attr,
|
||||
&ignore_nice_load.attr,
|
||||
&freq_step.attr,
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -89,7 +89,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu)
|
|||
{
|
||||
return kstat_cpu(cpu).cpustat.idle +
|
||||
kstat_cpu(cpu).cpustat.iowait +
|
||||
( !dbs_tuners_ins.ignore_nice ?
|
||||
( dbs_tuners_ins.ignore_nice ?
|
||||
kstat_cpu(cpu).cpustat.nice :
|
||||
0);
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ static ssize_t show_##file_name \
|
|||
show_one(sampling_rate, sampling_rate);
|
||||
show_one(sampling_down_factor, sampling_down_factor);
|
||||
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,
|
||||
const char *buf, size_t count)
|
||||
|
@ -182,7 +182,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
|
|||
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)
|
||||
{
|
||||
unsigned int input;
|
||||
|
@ -223,7 +223,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
|
|||
define_one_rw(sampling_rate);
|
||||
define_one_rw(sampling_down_factor);
|
||||
define_one_rw(up_threshold);
|
||||
define_one_rw(ignore_nice);
|
||||
define_one_rw(ignore_nice_load);
|
||||
|
||||
static struct attribute * dbs_attributes[] = {
|
||||
&sampling_rate_max.attr,
|
||||
|
@ -231,7 +231,7 @@ static struct attribute * dbs_attributes[] = {
|
|||
&sampling_rate.attr,
|
||||
&sampling_down_factor.attr,
|
||||
&up_threshold.attr,
|
||||
&ignore_nice.attr,
|
||||
&ignore_nice_load.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -3509,6 +3509,7 @@ static int __init ide_cdrom_init(void)
|
|||
return driver_register(&ide_cdrom_driver.gen_driver);
|
||||
}
|
||||
|
||||
MODULE_ALIAS("ide:*m-cdrom*");
|
||||
module_init(ide_cdrom_init);
|
||||
module_exit(ide_cdrom_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -1271,6 +1271,7 @@ static int __init idedisk_init(void)
|
|||
return driver_register(&idedisk_driver.gen_driver);
|
||||
}
|
||||
|
||||
MODULE_ALIAS("ide:*m-disk*");
|
||||
module_init(idedisk_init);
|
||||
module_exit(idedisk_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -2197,6 +2197,7 @@ static int __init idefloppy_init(void)
|
|||
return driver_register(&idefloppy_driver.gen_driver);
|
||||
}
|
||||
|
||||
MODULE_ALIAS("ide:*m-floppy*");
|
||||
module_init(idefloppy_init);
|
||||
module_exit(idefloppy_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -4947,6 +4947,7 @@ out:
|
|||
return error;
|
||||
}
|
||||
|
||||
MODULE_ALIAS("ide:*m-tape*");
|
||||
module_init(idetape_init);
|
||||
module_exit(idetape_exit);
|
||||
MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
|
||||
|
|
|
@ -1904,9 +1904,69 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
|
|||
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 = {
|
||||
.name = "ide",
|
||||
.match = ide_bus_match,
|
||||
.uevent = ide_uevent,
|
||||
.dev_attrs = ide_dev_attrs,
|
||||
.suspend = generic_ide_suspend,
|
||||
.resume = generic_ide_resume,
|
||||
};
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
oui.c
|
|
@ -121,7 +121,7 @@ struct host_info {
|
|||
};
|
||||
|
||||
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);
|
||||
static void nodemgr_resume_ne(struct node_entry *ne);
|
||||
static void nodemgr_remove_ne(struct node_entry *ne);
|
||||
|
@ -162,7 +162,7 @@ static void ud_cls_release(struct class_device *class_dev)
|
|||
static struct class nodemgr_ud_class = {
|
||||
.name = "ieee1394",
|
||||
.release = ud_cls_release,
|
||||
.hotplug = nodemgr_hotplug,
|
||||
.uevent = nodemgr_uevent,
|
||||
};
|
||||
|
||||
static struct hpsb_highlevel nodemgr_highlevel;
|
||||
|
@ -966,7 +966,7 @@ static struct unit_directory *nodemgr_process_unit_directory
|
|||
if (ud_child == NULL)
|
||||
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) &&
|
||||
!(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
|
||||
{
|
||||
|
@ -1062,7 +1062,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
|
|||
|
||||
#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)
|
||||
{
|
||||
struct unit_directory *ud;
|
||||
|
@ -1112,7 +1112,7 @@ do { \
|
|||
|
||||
#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)
|
||||
{
|
||||
return -ENODEV;
|
||||
|
@ -1618,8 +1618,8 @@ static int nodemgr_host_thread(void *__hi)
|
|||
|
||||
/* Scan our nodes to get the bus options and create node
|
||||
* entries. This does not do the sysfs stuff, since that
|
||||
* would trigger hotplug callbacks and such, which is a
|
||||
* bad idea at this point. */
|
||||
* would trigger uevents and such, which is a bad idea at
|
||||
* this point. */
|
||||
nodemgr_node_scan(hi, generation);
|
||||
|
||||
/* This actually does the full probe, with sysfs
|
||||
|
|
|
@ -434,24 +434,24 @@ static void ib_device_release(struct class_device *cdev)
|
|||
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)
|
||||
{
|
||||
struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
|
||||
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))
|
||||
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
|
||||
* provider, and this can crash during device removal because
|
||||
* we are will be running after driver removal has started.
|
||||
* We could add a node_guid field to struct ib_device, or we
|
||||
* could just let the hotplug script read the node GUID from
|
||||
* sysfs when devices are added.
|
||||
* could just let userspace read the node GUID from sysfs when
|
||||
* devices are added.
|
||||
*/
|
||||
|
||||
envp[i] = NULL;
|
||||
|
@ -653,7 +653,7 @@ static struct class_device_attribute *ib_class_attributes[] = {
|
|||
static struct class ib_class = {
|
||||
.name = "infiniband",
|
||||
.release = ib_device_release,
|
||||
.hotplug = ib_device_hotplug,
|
||||
.uevent = ib_device_uevent,
|
||||
};
|
||||
|
||||
int ib_device_register_sysfs(struct ib_device *device)
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include <linux/ip.h>
|
||||
#include <linux/in.h>
|
||||
|
||||
#include <net/dst.h>
|
||||
|
||||
MODULE_AUTHOR("Roland Dreier");
|
||||
MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include <net/dst.h>
|
||||
|
||||
#include "ipoib.h"
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <linux/random.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/kobject_uevent.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/poll.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(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[] = {
|
||||
&class_device_attr_name.attr,
|
||||
&class_device_attr_phys.attr,
|
||||
&class_device_attr_uniq.attr,
|
||||
&class_device_attr_modalias.attr,
|
||||
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.
|
||||
*/
|
||||
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,
|
||||
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...) \
|
||||
do { \
|
||||
int err = add_hotplug_env_var(envp, num_envp, &i, \
|
||||
int err = add_uevent_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
fmt, val); \
|
||||
if (err) \
|
||||
|
@ -648,14 +686,14 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
|
|||
|
||||
#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
|
||||
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, \
|
||||
name, bm, max); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} 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)
|
||||
{
|
||||
struct input_dev *dev = to_input_dev(cdev);
|
||||
|
@ -698,7 +736,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
|
|||
struct class input_class = {
|
||||
.name = "input",
|
||||
.release = input_dev_release,
|
||||
.hotplug = input_dev_hotplug,
|
||||
.uevent = input_dev_uevent,
|
||||
};
|
||||
|
||||
struct input_dev *input_allocate_device(void)
|
||||
|
|
|
@ -235,7 +235,6 @@ static struct usb_device_id iforce_usb_ids [] = {
|
|||
MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
|
||||
|
||||
struct usb_driver iforce_usb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "iforce",
|
||||
.probe = iforce_usb_probe,
|
||||
.disconnect = iforce_usb_disconnect,
|
||||
|
|
|
@ -800,16 +800,16 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
|
|||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
|
||||
#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \
|
||||
#define SERIO_ADD_UEVENT_VAR(fmt, val...) \
|
||||
do { \
|
||||
int err = add_hotplug_env_var(envp, num_envp, &i, \
|
||||
int err = add_uevent_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
fmt, val); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} 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;
|
||||
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_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type);
|
||||
SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto);
|
||||
SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id);
|
||||
SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra);
|
||||
SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
|
||||
SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
|
||||
SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
|
||||
SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
|
||||
SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
|
||||
SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
|
||||
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
|
||||
envp[i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#undef SERIO_ADD_HOTPLUG_VAR
|
||||
#undef SERIO_ADD_UEVENT_VAR
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -908,7 +908,7 @@ static int __init serio_init(void)
|
|||
serio_bus.dev_attrs = serio_device_attrs;
|
||||
serio_bus.drv_attrs = serio_driver_attrs;
|
||||
serio_bus.match = serio_bus_match;
|
||||
serio_bus.hotplug = serio_hotplug;
|
||||
serio_bus.uevent = serio_uevent;
|
||||
serio_bus.resume = serio_resume;
|
||||
bus_register(&serio_bus);
|
||||
|
||||
|
|
|
@ -1715,7 +1715,6 @@ hfc_usb_disconnect(struct usb_interface
|
|||
/* our driver information structure */
|
||||
/************************************/
|
||||
static struct usb_driver hfc_drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "hfc_usb",
|
||||
.id_table = hfcusb_idtab,
|
||||
.probe = hfc_usb_probe,
|
||||
|
|
|
@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = {
|
|||
MODULE_DEVICE_TABLE (usb, st5481_ids);
|
||||
|
||||
static struct usb_driver st5481_usb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "st5481_usb",
|
||||
.probe = probe_st5481,
|
||||
.disconnect = disconnect_st5481,
|
||||
|
|
|
@ -128,7 +128,7 @@ static int macio_device_resume(struct device * dev)
|
|||
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)
|
||||
{
|
||||
struct macio_dev * macio_dev;
|
||||
|
@ -203,7 +203,7 @@ extern struct device_attribute macio_dev_attrs[];
|
|||
struct bus_type macio_bus_type = {
|
||||
.name = "macio",
|
||||
.match = macio_bus_match,
|
||||
.hotplug = macio_hotplug,
|
||||
.uevent = macio_uevent,
|
||||
.suspend = macio_device_suspend,
|
||||
.resume = macio_device_resume,
|
||||
.dev_attrs = macio_dev_attrs,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
mktables
|
||||
raid6altivec*.c
|
||||
raid6int*.c
|
||||
raid6tables.c
|
|
@ -638,7 +638,7 @@ int dm_split_args(int *argc, char ***argvp, char *input)
|
|||
static void check_for_valid_limits(struct io_restrictions *rs)
|
||||
{
|
||||
if (!rs->max_sectors)
|
||||
rs->max_sectors = MAX_SECTORS;
|
||||
rs->max_sectors = SAFE_MAX_SECTORS;
|
||||
if (!rs->max_phys_segments)
|
||||
rs->max_phys_segments = MAX_PHYS_SEGMENTS;
|
||||
if (!rs->max_hw_segments)
|
||||
|
|
|
@ -544,7 +544,6 @@ static struct usb_device_id flexcop_usb_table [] = {
|
|||
|
||||
/* usb specific object needed to register this driver with the usb subsystem */
|
||||
static struct usb_driver flexcop_usb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "b2c2_flexcop_usb",
|
||||
.probe = flexcop_usb_probe,
|
||||
.disconnect = flexcop_usb_disconnect,
|
||||
|
|
|
@ -986,7 +986,6 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = {
|
|||
MODULE_DEVICE_TABLE(usb, cinergyt2_table);
|
||||
|
||||
static struct usb_driver cinergyt2_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "cinergyT2",
|
||||
.probe = cinergyt2_probe,
|
||||
.disconnect = cinergyt2_disconnect,
|
||||
|
|
|
@ -144,7 +144,6 @@ static struct dvb_usb_properties a800_properties = {
|
|||
};
|
||||
|
||||
static struct usb_driver a800_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dvb_usb_a800",
|
||||
.probe = a800_probe,
|
||||
.disconnect = dvb_usb_device_exit,
|
||||
|
|
|
@ -241,7 +241,6 @@ static struct dvb_usb_properties cxusb_properties = {
|
|||
};
|
||||
|
||||
static struct usb_driver cxusb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dvb_usb_cxusb",
|
||||
.probe = cxusb_probe,
|
||||
.disconnect = dvb_usb_device_exit,
|
||||
|
|
|
@ -373,7 +373,6 @@ static struct dvb_usb_properties artec_t1_usb2_properties = {
|
|||
};
|
||||
|
||||
static struct usb_driver dibusb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dvb_usb_dibusb_mb",
|
||||
.probe = dibusb_probe,
|
||||
.disconnect = dvb_usb_device_exit,
|
||||
|
|
|
@ -82,7 +82,6 @@ static struct dvb_usb_properties dibusb_mc_properties = {
|
|||
};
|
||||
|
||||
static struct usb_driver dibusb_mc_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dvb_usb_dibusb_mc",
|
||||
.probe = dibusb_mc_probe,
|
||||
.disconnect = dvb_usb_device_exit,
|
||||
|
|
|
@ -233,7 +233,6 @@ static struct dvb_usb_properties digitv_properties = {
|
|||
};
|
||||
|
||||
static struct usb_driver digitv_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dvb_usb_digitv",
|
||||
.probe = digitv_probe,
|
||||
.disconnect = dvb_usb_device_exit,
|
||||
|
|
|
@ -198,7 +198,6 @@ static struct dvb_usb_properties wt220u_properties = {
|
|||
|
||||
/* usb specific object needed to register this driver with the usb subsystem */
|
||||
static struct usb_driver dtt200u_usb_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "dvb_usb_dtt200u",
|
||||
.probe = dtt200u_usb_probe,
|
||||
.disconnect = dvb_usb_device_exit,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue