mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 15:11:50 +00:00
Merge branch 'master'
This commit is contained in:
commit
f01c184569
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@
|
||||
#
|
||||
# Top-level generic files
|
||||
#
|
||||
tags
|
||||
vmlinux*
|
||||
System.map
|
||||
Module.symvers
|
||||
|
@ -1,3 +1,56 @@
|
||||
Table of contents
|
||||
=================
|
||||
|
||||
Last updated: 20 December 2005
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
- Introduction
|
||||
- Devices not appearing
|
||||
- Finding patch that caused a bug
|
||||
-- Finding using git-bisect
|
||||
-- Finding it the old way
|
||||
- Fixing the bug
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Always try the latest kernel from kernel.org and build from source. If you are
|
||||
not confident in doing that please report the bug to your distribution vendor
|
||||
instead of to a kernel developer.
|
||||
|
||||
Finding bugs is not always easy. Have a go though. If you can't find it don't
|
||||
give up. Report as much as you have found to the relevant maintainer. See
|
||||
MAINTAINERS for who that is for the subsystem you have worked on.
|
||||
|
||||
Before you submit a bug report read REPORTING-BUGS.
|
||||
|
||||
Devices not appearing
|
||||
=====================
|
||||
|
||||
Often this is caused by udev. Check that first before blaming it on the
|
||||
kernel.
|
||||
|
||||
Finding patch that caused a bug
|
||||
===============================
|
||||
|
||||
|
||||
|
||||
Finding using git-bisect
|
||||
------------------------
|
||||
|
||||
Using the provided tools with git makes finding bugs easy provided the bug is
|
||||
reproducible.
|
||||
|
||||
Steps to do it:
|
||||
- start using git for the kernel source
|
||||
- read the man page for git-bisect
|
||||
- have fun
|
||||
|
||||
Finding it the old way
|
||||
----------------------
|
||||
|
||||
[Sat Mar 2 10:32:33 PST 1996 KERNEL_BUG-HOWTO lm@sgi.com (Larry McVoy)]
|
||||
|
||||
This is how to track down a bug if you know nothing about kernel hacking.
|
||||
@ -90,3 +143,63 @@ it does work and it lets non-hackers help fix bugs. And it is cool
|
||||
because Linux snapshots will let you do this - something that you can't
|
||||
do with vendor supplied releases.
|
||||
|
||||
Fixing the bug
|
||||
==============
|
||||
|
||||
Nobody is going to tell you how to fix bugs. Seriously. You need to work it
|
||||
out. But below are some hints on how to use the tools.
|
||||
|
||||
To debug a kernel, use objdump and look for the hex offset from the crash
|
||||
output to find the valid line of code/assembler. Without debug symbols, you
|
||||
will see the assembler code for the routine shown, but if your kernel has
|
||||
debug symbols the C code will also be available. (Debug symbols can be enabled
|
||||
in the kernel hacking menu of the menu configuration.) For example:
|
||||
|
||||
objdump -r -S -l --disassemble net/dccp/ipv4.o
|
||||
|
||||
NB.: you need to be at the top level of the kernel tree for this to pick up
|
||||
your C files.
|
||||
|
||||
If you don't have access to the code you can also debug on some crash dumps
|
||||
e.g. crash dump output as shown by Dave Miller.
|
||||
|
||||
> EIP is at ip_queue_xmit+0x14/0x4c0
|
||||
> ...
|
||||
> Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00
|
||||
> 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08
|
||||
> <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85
|
||||
>
|
||||
> Put the bytes into a "foo.s" file like this:
|
||||
>
|
||||
> .text
|
||||
> .globl foo
|
||||
> foo:
|
||||
> .byte .... /* bytes from Code: part of OOPS dump */
|
||||
>
|
||||
> Compile it with "gcc -c -o foo.o foo.s" then look at the output of
|
||||
> "objdump --disassemble foo.o".
|
||||
>
|
||||
> Output:
|
||||
>
|
||||
> ip_queue_xmit:
|
||||
> push %ebp
|
||||
> push %edi
|
||||
> push %esi
|
||||
> push %ebx
|
||||
> sub $0xbc, %esp
|
||||
> mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb)
|
||||
> mov 0x8(%ebp), %ebx ! %ebx = skb->sk
|
||||
> mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt
|
||||
|
||||
Another very useful option of the Kernel Hacking section in menuconfig is
|
||||
Debug memory allocations. This will help you see whether data has been
|
||||
initialised and not set before use etc. To see the values that get assigned
|
||||
with this look at mm/slab.c and search for POISON_INUSE. When using this an
|
||||
Oops will often show the poisoned data instead of zero which is the default.
|
||||
|
||||
Once you have worked out a fix please submit it upstream. After all open
|
||||
source is about sharing what you do and don't you want to be recognised for
|
||||
your genius?
|
||||
|
||||
Please do read Documentation/SubmittingPatches though to help your code get
|
||||
accepted.
|
||||
|
@ -246,7 +246,7 @@ sub vp7041 {
|
||||
}
|
||||
|
||||
sub dibusb {
|
||||
my $url = "http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw";
|
||||
my $url = "http://www.linuxtv.org/downloads/firmware/dvb-usb-dibusb-5.0.0.11.fw";
|
||||
my $outfile = "dvb-dibusb-5.0.0.11.fw";
|
||||
my $hash = "fa490295a527360ca16dcdf3224ca243";
|
||||
|
||||
|
@ -9,9 +9,9 @@ when using discs encoded using Microsoft's Joliet extensions.
|
||||
iocharset=name Character set to use for converting from Unicode to
|
||||
ASCII. Joliet filenames are stored in Unicode format, but
|
||||
Unix for the most part doesn't know how to deal with Unicode.
|
||||
There is also an option of doing UTF8 translations with the
|
||||
There is also an option of doing UTF-8 translations with the
|
||||
utf8 option.
|
||||
utf8 Encode Unicode names in UTF8 format. Default is no.
|
||||
utf8 Encode Unicode names in UTF-8 format. Default is no.
|
||||
|
||||
Mount options unique to the isofs filesystem.
|
||||
block=512 Set the block size for the disk to 512 bytes
|
||||
|
@ -6,7 +6,7 @@ The following mount options are supported:
|
||||
|
||||
iocharset=name Character set to use for converting from Unicode to
|
||||
ASCII. The default is to do no conversion. Use
|
||||
iocharset=utf8 for UTF8 translations. This requires
|
||||
iocharset=utf8 for UTF-8 translations. This requires
|
||||
CONFIG_NLS_UTF8 to be set in the kernel .config file.
|
||||
iocharset=none specifies the default behavior explicitly.
|
||||
|
||||
|
@ -28,16 +28,16 @@ iocharset=name -- Character set to use for converting between the
|
||||
know how to deal with Unicode.
|
||||
By default, FAT_DEFAULT_IOCHARSET setting is used.
|
||||
|
||||
There is also an option of doing UTF8 translations
|
||||
There is also an option of doing UTF-8 translations
|
||||
with the utf8 option.
|
||||
|
||||
NOTE: "iocharset=utf8" is not recommended. If unsure,
|
||||
you should consider the following option instead.
|
||||
|
||||
utf8=<bool> -- UTF8 is the filesystem safe version of Unicode that
|
||||
utf8=<bool> -- UTF-8 is the filesystem safe version of Unicode that
|
||||
is used by the console. It can be be enabled for the
|
||||
filesystem with this option. If 'uni_xlate' gets set,
|
||||
UTF8 gets disabled.
|
||||
UTF-8 gets disabled.
|
||||
|
||||
uni_xlate=<bool> -- Translate unhandled Unicode characters to special
|
||||
escaped sequences. This would let you backup and
|
||||
|
@ -513,6 +513,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-ens1371
|
||||
------------------
|
||||
|
||||
@ -526,6 +528,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-es968
|
||||
----------------
|
||||
|
||||
@ -671,6 +675,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
model - force the model name
|
||||
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
|
||||
single_cmd - Use single immediate commands to communicate with
|
||||
codecs (for debugging only)
|
||||
|
||||
This module supports one card and autoprobe.
|
||||
|
||||
@ -694,13 +700,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
asus 3-jack
|
||||
uniwill 3-jack
|
||||
F1734 2-jack
|
||||
lg LG laptop (m1 express dual)
|
||||
test for testing/debugging purpose, almost all controls can be
|
||||
adjusted. Appearing only when compiled with
|
||||
$CONFIG_SND_DEBUG=y
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC260
|
||||
hp HP machines
|
||||
fujitsu Fujitsu S7020
|
||||
acer Acer TravelMate
|
||||
basic fixed pin assignment (old default model)
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC262
|
||||
fujitsu Fujitsu Laptop
|
||||
basic fixed pin assignment w/o SPDIF
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC882/883/885
|
||||
3stack-dig 3-jack with SPDIF I/O
|
||||
6stck-dig 6-jack digital with SPDIF I/O
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC861
|
||||
3stack 3-jack
|
||||
3stack-dig 3-jack with SPDIF I/O
|
||||
6stack-dig 6-jack with SPDIF I/O
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
CMI9880
|
||||
minimal 3-jack in back
|
||||
@ -710,6 +737,28 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
allout 5-jack in back, 2-jack in front, SPDIF out
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
AD1981
|
||||
basic 3-jack (default)
|
||||
hp HP nx6320
|
||||
|
||||
AD1986A
|
||||
6stack 6-jack, separate surrounds (default)
|
||||
3stack 3-stack, shared surrounds
|
||||
laptop 2-channel only (FSC V2060, Samsung M50)
|
||||
laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J)
|
||||
|
||||
AD1988
|
||||
6stack 6-jack
|
||||
6stack-dig ditto with SPDIF
|
||||
3stack 3-jack
|
||||
3stack-dig ditto with SPDIF
|
||||
laptop 3-jack with hp-jack automute
|
||||
laptop-dig ditto with SPDIF
|
||||
auto auto-confgi reading BIOS (default)
|
||||
|
||||
STAC7661(?)
|
||||
vaio Setup for VAIO FE550G/SZ110
|
||||
|
||||
If the default configuration doesn't work and one of the above
|
||||
matches with your device, report it together with the PCI
|
||||
subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
|
||||
@ -723,6 +772,17 @@ 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.)
|
||||
|
||||
NB: If you get many "azx_get_response timeout" messages at
|
||||
loading, it's likely a problem of interrupts (e.g. ACPI irq
|
||||
routing). Try to boot with options like "pci=noacpi". Also, you
|
||||
can try "single_cmd=1" module option. This will switch the
|
||||
communication method between HDA controller and codecs to the
|
||||
single immediate commands instead of CORB/RIRB. Basically, the
|
||||
single command mode is provided only for BIOS, and you won't get
|
||||
unsolicited events, too. But, at least, this works independently
|
||||
from the irq. Remember this is a last resort, and should be
|
||||
avoided as much as possible...
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-hdsp
|
||||
@ -802,6 +862,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
------------------
|
||||
|
||||
Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards.
|
||||
* MidiMan M Audio Revolution 5.1
|
||||
* MidiMan M Audio Revolution 7.1
|
||||
* AMP Ltd AUDIO2000
|
||||
* TerraTec Aureon 5.1 Sky
|
||||
@ -810,6 +871,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
* TerraTec Phase 22
|
||||
* TerraTec Phase 28
|
||||
* AudioTrak Prodigy 7.1
|
||||
* AudioTrak Prodigy 7.1LT
|
||||
* AudioTrak Prodigy 192
|
||||
* Pontis MS300
|
||||
* Albatron K8X800 Pro II
|
||||
@ -820,9 +882,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
* Shuttle SN25P
|
||||
|
||||
model - Use the given board model, one of the following:
|
||||
revo71, amp2000, prodigy71, prodigy192, aureon51,
|
||||
aureon71, universe, k8x800, phase22, phase28, ms300,
|
||||
av710
|
||||
revo51, revo71, amp2000, prodigy71, prodigy71lt,
|
||||
prodigy192, aureon51, aureon71, universe,
|
||||
k8x800, phase22, phase28, ms300, av710
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
@ -1353,6 +1415,9 @@ 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)
|
||||
device_setup - Device specific magic number (optional)
|
||||
- Influence depends on the device
|
||||
- Default: 0x0000
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
|
333
Documentation/sound/alsa/Audiophile-Usb.txt
Normal file
333
Documentation/sound/alsa/Audiophile-Usb.txt
Normal file
@ -0,0 +1,333 @@
|
||||
Guide to using M-Audio Audiophile USB with ALSA and Jack v1.2
|
||||
========================================================
|
||||
|
||||
Thibault Le Meur <Thibault.LeMeur@supelec.fr>
|
||||
|
||||
This document is a guide to using the M-Audio Audiophile USB (tm) device with
|
||||
ALSA and JACK.
|
||||
|
||||
1 - Audiophile USB Specs and correct usage
|
||||
==========================================
|
||||
This part is a reminder of important facts about the functions and limitations
|
||||
of the device.
|
||||
|
||||
The device has 4 audio interfaces, and 2 MIDI ports:
|
||||
* Analog Stereo Input (Ai)
|
||||
- This port supports 2 pairs of line-level audio inputs (1/4" TS and RCA)
|
||||
- When the 1/4" TS (jack) connectors are connected, the RCA connectors
|
||||
are disabled
|
||||
* Analog Stereo Output (Ao)
|
||||
* Digital Stereo Input (Di)
|
||||
* Digital Stereo Output (Do)
|
||||
* Midi In (Mi)
|
||||
* Midi Out (Mo)
|
||||
|
||||
The internal DAC/ADC has the following caracteristics:
|
||||
* sample depth of 16 or 24 bits
|
||||
* sample rate from 8kHz to 96kHz
|
||||
* Two ports can't use different sample depths at the same time.Moreover, the
|
||||
Audiophile USB documentation gives the following Warning: "Please exit any
|
||||
audio application running before switching between bit depths"
|
||||
|
||||
Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
|
||||
activated at the same time depending on the audio mode selected:
|
||||
* 16-bit/48kHz ==> 4 channels in/ 4 channels out
|
||||
- Ai+Ao+Di+Do
|
||||
* 24-bit/48kHz ==> 4 channels in/2 channels out,
|
||||
or 2 channels in/4 channels out
|
||||
- Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do
|
||||
* 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only)
|
||||
- Ai or Ao or Di or Do
|
||||
|
||||
Important facts about the Digital interface:
|
||||
--------------------------------------------
|
||||
* The Do port additionnaly supports surround-encoded AC-3 and DTS passthrough,
|
||||
though I haven't tested it under linux
|
||||
- Note that in this setup only the Do interface can be enabled
|
||||
* Apart from recording an audio digital stream, enabling the Di port is a way
|
||||
to synchronize the device to an external sample clock
|
||||
- As a consequence, the Di port must be enable only if an active Digital
|
||||
source is connected
|
||||
- Enabling Di when no digital source is connected can result in a
|
||||
synchronization error (for instance sound played at an odd sample rate)
|
||||
|
||||
|
||||
2 - Audiophile USB support in ALSA
|
||||
==================================
|
||||
|
||||
2.1 - MIDI ports
|
||||
----------------
|
||||
The Audiophile USB MIDI ports will be automatically supported once the
|
||||
following modules have been loaded:
|
||||
* snd-usb-audio
|
||||
* snd-seq
|
||||
* snd-seq-midi
|
||||
|
||||
No additionnal setting is required.
|
||||
|
||||
2.2 - Audio ports
|
||||
-----------------
|
||||
|
||||
Audio functions of the Audiophile USB device are handled by the snd-usb-audio
|
||||
module. This module can work in a default mode (without any device-specific
|
||||
parameter), or in an advanced mode with the device-specific parameter called
|
||||
"device_setup".
|
||||
|
||||
2.2.1 - Default Alsa driver mode
|
||||
|
||||
The default behaviour of the snd-usb-audio driver is to parse the device
|
||||
capabilities at startup and enable all functions inside the device (including
|
||||
all ports at any sample rates and any sample depths supported). This approach
|
||||
has the advantage to let the driver easily switch from sample rates/depths
|
||||
automatically according to the need of the application claiming the device.
|
||||
|
||||
In this case the Audiophile ports are mapped to alsa pcm devices in the
|
||||
following way (I suppose the device's index is 1):
|
||||
* hw:1,0 is Ao in playback and Di in capture
|
||||
* hw:1,1 is Do in playback and Ai in capture
|
||||
* hw:1,2 is Do in AC3/DTS passthrough mode
|
||||
|
||||
You must note as well that the device uses Big Endian byte encoding so that
|
||||
supported audio format are S16_BE for 16-bit depth modes and S24_3BE for
|
||||
24-bits depth mode. One exception is the hw:1,2 port which is Little Endian
|
||||
compliant and thus uses S16_LE.
|
||||
|
||||
Examples:
|
||||
* playing a S24_3BE encoded raw file to the Ao port
|
||||
% aplay -D hw:1,0 -c2 -t raw -r48000 -fS24_3BE test.raw
|
||||
* recording a S24_3BE encoded raw file from the Ai port
|
||||
% arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw
|
||||
* playing a S16_BE encoded raw file to the Do port
|
||||
% aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw
|
||||
|
||||
If you're happy with the default Alsa driver setup and don't experience any
|
||||
issue with this mode, then you can skip the following chapter.
|
||||
|
||||
2.2.2 - Advanced module setup
|
||||
|
||||
Due to the hardware constraints described above, the device initialization made
|
||||
by the Alsa driver in default mode may result in a corrupted state of the
|
||||
device. For instance, a particularly annoying issue is that the sound captured
|
||||
from the Ai port sounds distorted (as if boosted with an excessive high volume
|
||||
gain).
|
||||
|
||||
For people having this problem, the snd-usb-audio module has a new module
|
||||
parameter called "device_setup".
|
||||
|
||||
2.2.2.1 - Initializing the working mode of the Audiohile USB
|
||||
|
||||
As far as the Audiohile USB device is concerned, this value let the user
|
||||
specify:
|
||||
* the sample depth
|
||||
* the sample rate
|
||||
* whether the Di port is used or not
|
||||
|
||||
Here is a list of supported device_setup values for this device:
|
||||
* device_setup=0x00 (or omitted)
|
||||
- Alsa driver default mode
|
||||
- maintains backward compatibility with setups that do not use this
|
||||
parameter by not introducing any change
|
||||
- results sometimes in corrupted sound as decribed earlier
|
||||
* device_setup=0x01
|
||||
- 16bits 48kHz mode with Di disabled
|
||||
- Ai,Ao,Do can be used at the same time
|
||||
- hw:1,0 is not available in capture mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x11
|
||||
- 16bits 48kHz mode with Di enabled
|
||||
- Ai,Ao,Di,Do can be used at the same time
|
||||
- hw:1,0 is available in capture mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x09
|
||||
- 24bits 48kHz mode with Di disabled
|
||||
- Ai,Ao,Do can be used at the same time
|
||||
- hw:1,0 is not available in capture mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x19
|
||||
- 24bits 48kHz mode with Di enabled
|
||||
- 3 ports from {Ai,Ao,Di,Do} can be used at the same time
|
||||
- hw:1,0 is available in capture mode and an active digital source must be
|
||||
connected to Di
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x0D or 0x10
|
||||
- 24bits 96kHz mode
|
||||
- Di is enabled by default for this mode but does not need to be connected
|
||||
to an active source
|
||||
- Only 1 port from {Ai,Ao,Di,Do} can be used at the same time
|
||||
- hw:1,0 is available in captured mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x03
|
||||
- 16bits 48kHz mode with only the Do port enabled
|
||||
- AC3 with DTS passthru (not tested)
|
||||
- Caution with this setup the Do port is mapped to the pcm device hw:1,0
|
||||
|
||||
2.2.2.2 - Setting and switching configurations with the device_setup parameter
|
||||
|
||||
The parameter can be given:
|
||||
* By manually probing the device (as root):
|
||||
# modprobe -r snd-usb-audio
|
||||
# modprobe snd-usb-audio index=1 device_setup=0x09
|
||||
* Or while configuring the modules options in your modules configuration file
|
||||
- For Fedora distributions, edit the /etc/modprobe.conf file:
|
||||
alias snd-card-1 snd-usb-audio
|
||||
options snd-usb-audio index=1 device_setup=0x09
|
||||
|
||||
IMPORTANT NOTE WHEN SWITCHING CONFIGURATION:
|
||||
-------------------------------------------
|
||||
* You may need to _first_ intialize the module with the correct device_setup
|
||||
parameter and _only_after_ turn on the Audiophile USB device
|
||||
* This is especially true when switching the sample depth:
|
||||
- first trun off the device
|
||||
- de-register the snd-usb-audio module
|
||||
- change the device_setup parameter (by either manually reprobing the module
|
||||
or changing modprobe.conf)
|
||||
- turn on the device
|
||||
|
||||
2.2.2.3 - Audiophile USB's device_setup structure
|
||||
|
||||
If you want to understand the device_setup magic numbers for the Audiophile
|
||||
USB, you need some very basic understanding of binary computation. However,
|
||||
this is not required to use the parameter and you may skip thi section.
|
||||
|
||||
The device_setup is one byte long and its structure is the following:
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| b7| b6| b5| b4| b3| b2| b1| b0|
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| 0 | 0 | 0 | Di|24B|96K|DTS|SET|
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
Where:
|
||||
* b0 is the "SET" bit
|
||||
- it MUST be set if device_setup is initialized
|
||||
* b1 is the "DTS" bit
|
||||
- it is set only for Digital output with DTS/AC3
|
||||
- this setup is not tested
|
||||
* b2 is the Rate selection flag
|
||||
- When set to "1" the rate range is 48.1-96kHz
|
||||
- Otherwise the sample rate range is 8-48kHz
|
||||
* b3 is the bit depth selection flag
|
||||
- When set to "1" samples are 24bits long
|
||||
- Otherwise they are 16bits long
|
||||
- Note that b2 implies b3 as the 96kHz mode is only supported for 24 bits
|
||||
samples
|
||||
* b4 is the Digital input flag
|
||||
- When set to "1" the device assumes that an active digital source is
|
||||
connected
|
||||
- You shouldn't enable Di if no source is seen on the port (this leads to
|
||||
synchronization issues)
|
||||
- b4 is implied by b2 (since only one port is enabled at a time no synch
|
||||
error can occur)
|
||||
* b5 to b7 are reserved for future uses, and must be set to "0"
|
||||
- might become Ao, Do, Ai, for b7, b6, b4 respectively
|
||||
|
||||
Caution:
|
||||
* there is no check on the value you will give to device_setup
|
||||
- for instance choosing 0x05 (16bits 96kHz) will fail back to 0x09 since
|
||||
b2 implies b3. But _there_will_be_no_warning_ in /var/log/messages
|
||||
* Hardware constraints due to the USB bus limitation aren't checked
|
||||
- choosing b2 will prepare all interfaces for 24bits/96kHz but you'll
|
||||
only be able to use one at the same time
|
||||
|
||||
2.2.3 - USB implementation details for this device
|
||||
|
||||
You may safely skip this section if you're not interrested in driver
|
||||
development.
|
||||
|
||||
This section describes some internals aspect of the device and summarize the
|
||||
data I got by usb-snooping the windows and linux drivers.
|
||||
|
||||
The M-Audio Audiophile USB has 7 USB Interfaces:
|
||||
a "USB interface":
|
||||
* USB Interface nb.0
|
||||
* USB Interface nb.1
|
||||
- Audio Control function
|
||||
* USB Interface nb.2
|
||||
- Analog Output
|
||||
* USB Interface nb.3
|
||||
- Digital Output
|
||||
* USB Interface nb.4
|
||||
- Analog Input
|
||||
* USB Interface nb.5
|
||||
- Digital Input
|
||||
* USB Interface nb.6
|
||||
- MIDI interface compliant with the MIDIMAN quirk
|
||||
|
||||
Each interface has 5 altsettings (AltSet 1,2,3,4,5) except:
|
||||
* Interface 3 (Digital Out) has an extra Alset nb.6
|
||||
* Interface 5 (Digital In) does not have Alset nb.3 and 5
|
||||
|
||||
Here is a short description of the AltSettings capabilities:
|
||||
* AltSettings 1 corresponds to
|
||||
- 24-bit depth, 48.1-96kHz sample mode
|
||||
- Adaptive playback (Ao and Do), Synch capture (Ai), or Asynch capture (Di)
|
||||
* AltSettings 2 corresponds to
|
||||
- 24-bit depth, 8-48kHz sample mode
|
||||
- Asynch capture and playback (Ao,Ai,Do,Di)
|
||||
* AltSettings 3 corresponds to
|
||||
- 24-bit depth, 8-48kHz sample mode
|
||||
- Synch capture (Ai) and Adaptive playback (Ao,Do)
|
||||
* AltSettings 4 corresponds to
|
||||
- 16-bit depth, 8-48kHz sample mode
|
||||
- Asynch capture and playback (Ao,Ai,Do,Di)
|
||||
* AltSettings 5 corresponds to
|
||||
- 16-bit depth, 8-48kHz sample mode
|
||||
- Synch capture (Ai) and Adaptive playback (Ao,Do)
|
||||
* AltSettings 6 corresponds to
|
||||
- 16-bit depth, 8-48kHz sample mode
|
||||
- Synch playback (Do), audio format type III IEC1937_AC-3
|
||||
|
||||
In order to ensure a correct intialization of the device, the driver
|
||||
_must_know_ how the device will be used:
|
||||
* if DTS is choosen, only Interface 2 with AltSet nb.6 must be
|
||||
registered
|
||||
* if 96KHz only AltSets nb.1 of each interface must be selected
|
||||
* if samples are using 24bits/48KHz then AltSet 2 must me used if
|
||||
Digital input is connected, and only AltSet nb.3 if Digital input
|
||||
is not connected
|
||||
* if samples are using 16bits/48KHz then AltSet 4 must me used if
|
||||
Digital input is connected, and only AltSet nb.5 if Digital input
|
||||
is not connected
|
||||
|
||||
When device_setup is given as a parameter to the snd-usb-audio module, the
|
||||
parse_audio_enpoint function uses a quirk called
|
||||
"audiophile_skip_setting_quirk" in order to prevent AltSettings not
|
||||
corresponding to device_setup from being registered in the driver.
|
||||
|
||||
3 - Audiophile USB and Jack support
|
||||
===================================
|
||||
|
||||
This section deals with support of the Audiophile USB device in Jack.
|
||||
The main issue regarding this support is that the device is Big Endian
|
||||
compliant.
|
||||
|
||||
3.1 - Using the plug alsa plugin
|
||||
--------------------------------
|
||||
|
||||
Jack doesn't directly support big endian devices. Thus, one way to have support
|
||||
for this device with Alsa is to use the Alsa "plug" converter.
|
||||
|
||||
For instance here is one way to run Jack with 2 playback channels on Ao and 2
|
||||
capture channels from Ai:
|
||||
% jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1
|
||||
|
||||
|
||||
However you may see the following warning message:
|
||||
"You appear to be using the ALSA software "plug" layer, probably a result of
|
||||
using the "default" ALSA device. This is less efficient than it could be.
|
||||
Consider using a hardware device instead rather than using the plug layer."
|
||||
|
||||
|
||||
3.2 - Patching alsa to use direct pcm device
|
||||
-------------------------------------------
|
||||
A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
|
||||
However it has not been included in the CVS tree.
|
||||
|
||||
You can find it at the following URL:
|
||||
http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687&
|
||||
atid=425939
|
||||
|
||||
After having applied the patch you can run jackd with the following command
|
||||
line:
|
||||
% jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
|
||||
|
@ -1834,7 +1834,7 @@
|
||||
mychip_set_sample_format(chip, runtime->format);
|
||||
mychip_set_sample_rate(chip, runtime->rate);
|
||||
mychip_set_channels(chip, runtime->channels);
|
||||
mychip_set_dma_setup(chip, runtime->dma_area,
|
||||
mychip_set_dma_setup(chip, runtime->dma_addr,
|
||||
chip->buffer_size,
|
||||
chip->period_size);
|
||||
return 0;
|
||||
@ -3388,7 +3388,7 @@ struct _snd_pcm_runtime {
|
||||
.name = "PCM Playback Switch",
|
||||
.index = 0,
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
.private_values = 0xffff,
|
||||
.private_value = 0xffff,
|
||||
.info = my_control_info,
|
||||
.get = my_control_get,
|
||||
.put = my_control_put
|
||||
@ -3449,7 +3449,7 @@ struct _snd_pcm_runtime {
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <structfield>private_values</structfield> field contains
|
||||
The <structfield>private_value</structfield> field contains
|
||||
an arbitrary long integer value for this record. When using
|
||||
generic <structfield>info</structfield>,
|
||||
<structfield>get</structfield> and
|
||||
|
@ -9,7 +9,7 @@ removed soon. So for any new code dynamic initialization should be used:
|
||||
static int __init xxx_init(void)
|
||||
{
|
||||
spin_lock_init(&xxx_lock);
|
||||
rw_lock_init(&xxx_rw_lock);
|
||||
rwlock_init(&xxx_rw_lock);
|
||||
...
|
||||
}
|
||||
|
||||
|
@ -2145,7 +2145,7 @@ S: Maintained
|
||||
|
||||
QLOGIC QLA2XXX FC-SCSI DRIVER
|
||||
P: Andrew Vasquez
|
||||
M: andrew.vasquez@qlogic.com
|
||||
M: linux-driver@qlogic.com
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
|
@ -357,7 +357,7 @@ free_reserved_mem(void *start, void *end)
|
||||
void *__start = start;
|
||||
for (; __start < end; __start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(__start));
|
||||
set_page_count(virt_to_page(__start), 1);
|
||||
init_page_count(virt_to_page(__start));
|
||||
free_page((long)__start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -157,14 +157,14 @@ static struct platform_device smc91x_device = {
|
||||
.resource = smc91x_resources,
|
||||
};
|
||||
|
||||
static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv)
|
||||
static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv)
|
||||
static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
|
||||
|
@ -223,6 +223,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
pte = consistent_pte[idx] + off;
|
||||
c->vm_pages = page;
|
||||
|
||||
split_page(page, order);
|
||||
|
||||
/*
|
||||
* Set the "dma handle"
|
||||
*/
|
||||
@ -231,7 +233,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
do {
|
||||
BUG_ON(!pte_none(*pte));
|
||||
|
||||
set_page_count(page, 1);
|
||||
/*
|
||||
* x86 does not mark the pages reserved...
|
||||
*/
|
||||
@ -250,7 +251,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||
* Free the otherwise unused pages.
|
||||
*/
|
||||
while (page < end) {
|
||||
set_page_count(page, 1);
|
||||
__free_page(page);
|
||||
page++;
|
||||
}
|
||||
|
@ -531,7 +531,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
|
||||
for (; addr < end; addr += PAGE_SIZE) {
|
||||
struct page *page = virt_to_page(addr);
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ static inline void free_area(unsigned long addr, unsigned long end, char *s)
|
||||
for (; addr < end; addr += PAGE_SIZE) {
|
||||
struct page *page = virt_to_page(addr);
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ EXPORT_SYMBOL(__ioremap);
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
EXPORT_SYMBOL(strchr);
|
||||
|
@ -115,9 +115,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
|
||||
*/
|
||||
if (order > 0) {
|
||||
struct page *rpage = virt_to_page(page);
|
||||
|
||||
for (i = 1; i < (1 << order); i++)
|
||||
set_page_count(rpage + i, 1);
|
||||
split_page(rpage, order);
|
||||
}
|
||||
|
||||
err = 0;
|
||||
|
@ -169,7 +169,7 @@ void __init mem_init(void)
|
||||
struct page *page = &mem_map[pfn];
|
||||
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -210,7 +210,7 @@ void __init free_initmem(void)
|
||||
/* next to check that the page we free is not a partial page */
|
||||
for (addr = start; addr < end; addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -230,7 +230,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
|
||||
int pages = 0;
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
pages++;
|
||||
|
@ -25,6 +25,7 @@ extern char h8300_debug_device[];
|
||||
/* platform dependent support */
|
||||
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
EXPORT_SYMBOL(strchr);
|
||||
|
@ -196,7 +196,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
int pages = 0;
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
pages++;
|
||||
@ -219,7 +219,7 @@ free_initmem()
|
||||
/* next to check that the page we free is not a partial page */
|
||||
for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ static void efi_call_phys_epilog(void)
|
||||
unsigned long cr4;
|
||||
struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
|
||||
|
||||
cpu_gdt_descr->address = __va(cpu_gdt_descr->address);
|
||||
cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
|
||||
load_gdt(cpu_gdt_descr);
|
||||
|
||||
cr4 = read_cr4();
|
||||
|
@ -504,27 +504,23 @@ void unlock_ipi_call_lock(void)
|
||||
spin_unlock_irq(&call_lock);
|
||||
}
|
||||
|
||||
static struct call_data_struct * call_data;
|
||||
static struct call_data_struct *call_data;
|
||||
|
||||
/*
|
||||
* this function sends a 'generic call function' IPI to all other CPUs
|
||||
* in the system.
|
||||
*/
|
||||
|
||||
int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
|
||||
int wait)
|
||||
/*
|
||||
* [SUMMARY] Run a function on all other CPUs.
|
||||
* <func> The function to run. This must be fast and non-blocking.
|
||||
* <info> An arbitrary pointer to pass to the function.
|
||||
* <nonatomic> currently unused.
|
||||
* <wait> If true, wait (atomically) until function has completed on other CPUs.
|
||||
* [RETURNS] 0 on success, else a negative status code. Does not return until
|
||||
/**
|
||||
* smp_call_function(): Run a function on all other CPUs.
|
||||
* @func: The function to run. This must be fast and non-blocking.
|
||||
* @info: An arbitrary pointer to pass to the function.
|
||||
* @nonatomic: currently unused.
|
||||
* @wait: If true, wait (atomically) until function has completed on other CPUs.
|
||||
*
|
||||
* Returns 0 on success, else a negative status code. Does not return until
|
||||
* remote CPUs are nearly ready to execute <<func>> or are or have executed.
|
||||
*
|
||||
* You must not call this function with disabled interrupts or from a
|
||||
* hardware interrupt handler or from a bottom half handler.
|
||||
*/
|
||||
int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
|
||||
int wait)
|
||||
{
|
||||
struct call_data_struct data;
|
||||
int cpus;
|
||||
|
@ -40,14 +40,13 @@ asmlinkage int sys_pipe(unsigned long __user * fildes)
|
||||
return error;
|
||||
}
|
||||
|
||||
/* common code for old and new mmaps */
|
||||
static inline long do_mmap2(
|
||||
unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
{
|
||||
int error = -EBADF;
|
||||
struct file * file = NULL;
|
||||
struct file *file = NULL;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
|
||||
if (!(flags & MAP_ANONYMOUS)) {
|
||||
@ -56,9 +55,9 @@ static inline long do_mmap2(
|
||||
goto out;
|
||||
}
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
down_write(&mm->mmap_sem);
|
||||
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
up_write(&mm->mmap_sem);
|
||||
|
||||
if (file)
|
||||
fput(file);
|
||||
@ -66,13 +65,6 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
||||
unsigned long prot, unsigned long flags,
|
||||
unsigned long fd, unsigned long pgoff)
|
||||
{
|
||||
return do_mmap2(addr, len, prot, flags, fd, pgoff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the select(nd, in, out, ex, tv) and mmap() system
|
||||
* calls. Linux/i386 didn't use to be able to handle more than
|
||||
@ -101,7 +93,8 @@ asmlinkage int old_mmap(struct mmap_arg_struct __user *arg)
|
||||
if (a.offset & ~PAGE_MASK)
|
||||
goto out;
|
||||
|
||||
err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
|
||||
err = sys_mmap2(a.addr, a.len, a.prot, a.flags,
|
||||
a.fd, a.offset >> PAGE_SHIFT);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
|
||||
*
|
||||
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
|
||||
*/
|
||||
static unsigned long cyc2ns_scale;
|
||||
static unsigned long cyc2ns_scale __read_mostly;
|
||||
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
||||
|
||||
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
|
||||
|
@ -74,7 +74,7 @@ late_initcall(start_lost_tick_compensation);
|
||||
*
|
||||
* -johnstul@us.ibm.com "math is hard, lets go shopping!"
|
||||
*/
|
||||
static unsigned long cyc2ns_scale;
|
||||
static unsigned long cyc2ns_scale __read_mostly;
|
||||
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
||||
|
||||
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
|
||||
|
@ -48,18 +48,6 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
|
||||
return (pte_t *) pmd;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* This is just for testing */
|
||||
struct page *
|
||||
follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
|
||||
|
@ -270,7 +270,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
|
||||
|
||||
static void __meminit free_new_highpage(struct page *page)
|
||||
{
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalhigh_pages++;
|
||||
}
|
||||
@ -727,7 +727,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
memset((void *)addr, 0xcc, PAGE_SIZE);
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
@ -766,7 +766,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -51,6 +51,13 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
|
||||
if (!base)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* page_private is used to track the number of entries in
|
||||
* the page table page that have non standard attributes.
|
||||
*/
|
||||
SetPagePrivate(base);
|
||||
page_private(base) = 0;
|
||||
|
||||
address = __pa(address);
|
||||
addr = address & LARGE_PAGE_MASK;
|
||||
pbase = (pte_t *)page_address(base);
|
||||
@ -143,11 +150,12 @@ __change_page_attr(struct page *page, pgprot_t prot)
|
||||
return -ENOMEM;
|
||||
set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
|
||||
kpte_page = split;
|
||||
}
|
||||
get_page(kpte_page);
|
||||
}
|
||||
page_private(kpte_page)++;
|
||||
} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
|
||||
set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
|
||||
__put_page(kpte_page);
|
||||
BUG_ON(page_private(kpte_page) == 0);
|
||||
page_private(kpte_page)--;
|
||||
} else
|
||||
BUG();
|
||||
|
||||
@ -157,10 +165,8 @@ __change_page_attr(struct page *page, pgprot_t prot)
|
||||
* replace it with a largepage.
|
||||
*/
|
||||
if (!PageReserved(kpte_page)) {
|
||||
/* memleak and potential failed 2M page regeneration */
|
||||
BUG_ON(!page_count(kpte_page));
|
||||
|
||||
if (cpu_has_pse && (page_count(kpte_page) == 1)) {
|
||||
if (cpu_has_pse && (page_private(kpte_page) == 0)) {
|
||||
ClearPagePrivate(kpte_page);
|
||||
list_add(&kpte_page->lru, &df_list);
|
||||
revert_page(kpte_page, address);
|
||||
}
|
||||
|
@ -68,9 +68,10 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr)
|
||||
#define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; }
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
* Don't actually need to do any preparation, but need to make sure
|
||||
* the address is in the right region.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
int prepare_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
|
@ -197,7 +197,7 @@ free_initmem (void)
|
||||
eaddr = (unsigned long) ia64_imva(__init_end);
|
||||
while (addr < eaddr) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
++totalram_pages;
|
||||
addr += PAGE_SIZE;
|
||||
@ -252,7 +252,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
|
||||
continue;
|
||||
page = virt_to_page(start);
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
free_page(start);
|
||||
++totalram_pages;
|
||||
}
|
||||
@ -640,7 +640,7 @@ mem_init (void)
|
||||
void online_page(struct page *page)
|
||||
{
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
@ -226,7 +226,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -244,7 +244,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
unsigned long p;
|
||||
for (p = start; p < end; p += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(p));
|
||||
set_page_count(virt_to_page(p), 1);
|
||||
init_page_count(virt_to_page(p));
|
||||
free_page(p);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
int pages = 0;
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
pages++;
|
||||
|
@ -54,7 +54,7 @@ void __init init_pointer_table(unsigned long ptable)
|
||||
|
||||
/* unreserve the page so it's possible to free that page */
|
||||
PD_PAGE(dp)->flags &= ~(1 << PG_reserved);
|
||||
set_page_count(PD_PAGE(dp), 1);
|
||||
init_page_count(PD_PAGE(dp));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)&__init_begin;
|
||||
for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) {
|
||||
virt_to_page(addr)->flags &= ~(1 << PG_reserved);
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ EXPORT_SYMBOL(__ioremap);
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
EXPORT_SYMBOL(dump_fpu);
|
||||
EXPORT_SYMBOL(strnlen);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(strrchr);
|
||||
EXPORT_SYMBOL(strstr);
|
||||
EXPORT_SYMBOL(strchr);
|
||||
|
@ -195,7 +195,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
int pages = 0;
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
pages++;
|
||||
@ -218,7 +218,7 @@ free_initmem()
|
||||
/* next to check that the page we free is not a partial page */
|
||||
for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ unsigned long __init prom_free_prom_memory(void)
|
||||
while (addr < boot_mem_map.map[i].addr
|
||||
+ boot_mem_map.map[i].size) {
|
||||
ClearPageReserved(virt_to_page(__va(addr)));
|
||||
set_page_count(virt_to_page(__va(addr)), 1);
|
||||
init_page_count(virt_to_page(__va(addr)));
|
||||
free_page((unsigned long)__va(addr));
|
||||
addr += PAGE_SIZE;
|
||||
freed += PAGE_SIZE;
|
||||
|
@ -118,7 +118,7 @@ unsigned long __init prom_free_prom_memory(void)
|
||||
addr = PAGE_SIZE;
|
||||
while (addr < end) {
|
||||
ClearPageReserved(virt_to_page(__va(addr)));
|
||||
set_page_count(virt_to_page(__va(addr)), 1);
|
||||
init_page_count(virt_to_page(__va(addr)));
|
||||
free_page((unsigned long)__va(addr));
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ unsigned long __init prom_free_prom_memory(void)
|
||||
while (addr < boot_mem_map.map[i].addr
|
||||
+ boot_mem_map.map[i].size) {
|
||||
ClearPageReserved(virt_to_page(__va(addr)));
|
||||
set_page_count(virt_to_page(__va(addr)), 1);
|
||||
init_page_count(virt_to_page(__va(addr)));
|
||||
free_page((unsigned long)__va(addr));
|
||||
addr += PAGE_SIZE;
|
||||
freed += PAGE_SIZE;
|
||||
|
@ -117,7 +117,7 @@ unsigned long __init prom_free_prom_memory(void)
|
||||
while (addr < boot_mem_map.map[i].addr
|
||||
+ boot_mem_map.map[i].size) {
|
||||
ClearPageReserved(virt_to_page(__va(addr)));
|
||||
set_page_count(virt_to_page(__va(addr)), 1);
|
||||
init_page_count(virt_to_page(__va(addr)));
|
||||
free_page((unsigned long)__va(addr));
|
||||
addr += PAGE_SIZE;
|
||||
freed += PAGE_SIZE;
|
||||
|
@ -54,7 +54,8 @@ unsigned long empty_zero_page, zero_page_mask;
|
||||
*/
|
||||
unsigned long setup_zero_pages(void)
|
||||
{
|
||||
unsigned long order, size;
|
||||
unsigned int order;
|
||||
unsigned long size;
|
||||
struct page *page;
|
||||
|
||||
if (cpu_has_vce)
|
||||
@ -67,9 +68,9 @@ unsigned long setup_zero_pages(void)
|
||||
panic("Oh boy, that early out of memory?");
|
||||
|
||||
page = virt_to_page(empty_zero_page);
|
||||
split_page(page, order);
|
||||
while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) {
|
||||
SetPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
page++;
|
||||
}
|
||||
|
||||
@ -244,7 +245,7 @@ void __init mem_init(void)
|
||||
#ifdef CONFIG_LIMITED_DMA
|
||||
set_page_address(page, lowmem_page_address(page));
|
||||
#endif
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalhigh_pages++;
|
||||
}
|
||||
@ -291,7 +292,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -314,7 +315,7 @@ void free_initmem(void)
|
||||
page = addr;
|
||||
#endif
|
||||
ClearPageReserved(virt_to_page(page));
|
||||
set_page_count(virt_to_page(page), 1);
|
||||
init_page_count(virt_to_page(page));
|
||||
free_page(page);
|
||||
totalram_pages++;
|
||||
freed += PAGE_SIZE;
|
||||
|
@ -559,7 +559,7 @@ void __init mem_init(void)
|
||||
/* if (!page_is_ram(pgnr)) continue; */
|
||||
/* commented out until page_is_ram works */
|
||||
ClearPageReserved(p);
|
||||
set_page_count(p, 1);
|
||||
init_page_count(p);
|
||||
__free_page(p);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
num_physpages++;
|
||||
totalram_pages++;
|
||||
@ -1018,7 +1018,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
num_physpages++;
|
||||
totalram_pages++;
|
||||
|
@ -133,21 +133,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
return __pte(old);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (! (within_hugepage_low_range(addr, len)
|
||||
|| within_hugepage_high_range(addr, len)) )
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct slb_flush_info {
|
||||
struct mm_struct *mm;
|
||||
u16 newareas;
|
||||
|
@ -216,7 +216,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
|
||||
|
||||
while (start < end) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
cnt++;
|
||||
start += PAGE_SIZE;
|
||||
@ -248,7 +248,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ void free_initmem(void)
|
||||
for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
|
||||
memset((void *)addr, 0xcc, PAGE_SIZE);
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -155,7 +155,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ EXPORT_SYMBOL(phys_mem_access_prot);
|
||||
void online_page(struct page *page)
|
||||
{
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 0);
|
||||
free_cold_page(page);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
}
|
||||
@ -376,7 +376,7 @@ void __init mem_init(void)
|
||||
struct page *page = pfn_to_page(pfn);
|
||||
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalhigh_pages++;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ static void __init cell_spuprop_present(struct device_node *spe,
|
||||
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
|
||||
struct page *page = pfn_to_page(pfn);
|
||||
set_page_links(page, ZONE_DMA, node_id, pfn);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
reset_page_mapcount(page);
|
||||
SetPageReserved(page);
|
||||
INIT_LIST_HEAD(&page->lru);
|
||||
|
@ -223,6 +223,8 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
pte_t *pte = consistent_pte + CONSISTENT_OFFSET(vaddr);
|
||||
struct page *end = page + (1 << order);
|
||||
|
||||
split_page(page, order);
|
||||
|
||||
/*
|
||||
* Set the "dma handle"
|
||||
*/
|
||||
@ -231,7 +233,6 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
do {
|
||||
BUG_ON(!pte_none(*pte));
|
||||
|
||||
set_page_count(page, 1);
|
||||
SetPageReserved(page);
|
||||
set_pte_at(&init_mm, vaddr,
|
||||
pte, mk_pte(page, pgprot_noncached(PAGE_KERNEL)));
|
||||
@ -244,7 +245,6 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
|
||||
* Free the otherwise unused pages.
|
||||
*/
|
||||
while (page < end) {
|
||||
set_page_count(page, 1);
|
||||
__free_page(page);
|
||||
page++;
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ static void free_sec(unsigned long start, unsigned long end, const char *name)
|
||||
|
||||
while (start < end) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
cnt++;
|
||||
start += PAGE_SIZE;
|
||||
@ -172,7 +172,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -441,7 +441,7 @@ void __init mem_init(void)
|
||||
struct page *page = mem_map + pfn;
|
||||
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalhigh_pages++;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -307,7 +307,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
|
||||
page = alloc_pages(gfp, order);
|
||||
if (!page)
|
||||
return NULL;
|
||||
split_page(page, order);
|
||||
|
||||
ret = page_address(page);
|
||||
*handle = virt_to_phys(ret);
|
||||
@ -37,8 +38,6 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
|
||||
end = page + (1 << order);
|
||||
|
||||
while (++page < end) {
|
||||
set_page_count(page, 1);
|
||||
|
||||
/* Free any unused pages */
|
||||
if (page >= free) {
|
||||
__free_page(page);
|
||||
|
@ -84,18 +84,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct page *follow_huge_addr(struct mm_struct *mm,
|
||||
unsigned long address, int write)
|
||||
{
|
||||
|
@ -273,7 +273,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -286,7 +286,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
unsigned long p;
|
||||
for (p = start; p < end; p += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(p));
|
||||
set_page_count(virt_to_page(p), 1);
|
||||
init_page_count(virt_to_page(p));
|
||||
free_page(p);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -84,18 +84,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct page *follow_huge_addr(struct mm_struct *mm,
|
||||
unsigned long address, int write)
|
||||
{
|
||||
|
@ -173,7 +173,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@ -186,7 +186,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
unsigned long p;
|
||||
for (p = start; p < end; p += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(p));
|
||||
set_page_count(virt_to_page(p), 1);
|
||||
init_page_count(virt_to_page(p));
|
||||
free_page(p);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -266,19 +266,19 @@ void __init smp4d_boot_cpus(void)
|
||||
|
||||
/* Free unneeded trap tables */
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu1));
|
||||
set_page_count(virt_to_page(trapbase_cpu1), 1);
|
||||
init_page_count(virt_to_page(trapbase_cpu1));
|
||||
free_page((unsigned long)trapbase_cpu1);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu2));
|
||||
set_page_count(virt_to_page(trapbase_cpu2), 1);
|
||||
init_page_count(virt_to_page(trapbase_cpu2));
|
||||
free_page((unsigned long)trapbase_cpu2);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu3));
|
||||
set_page_count(virt_to_page(trapbase_cpu3), 1);
|
||||
init_page_count(virt_to_page(trapbase_cpu3));
|
||||
free_page((unsigned long)trapbase_cpu3);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
@ -233,21 +233,21 @@ void __init smp4m_boot_cpus(void)
|
||||
/* Free unneeded trap tables */
|
||||
if (!cpu_isset(i, cpu_present_map)) {
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu1));
|
||||
set_page_count(virt_to_page(trapbase_cpu1), 1);
|
||||
init_page_count(virt_to_page(trapbase_cpu1));
|
||||
free_page((unsigned long)trapbase_cpu1);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
}
|
||||
if (!cpu_isset(2, cpu_present_map)) {
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu2));
|
||||
set_page_count(virt_to_page(trapbase_cpu2), 1);
|
||||
init_page_count(virt_to_page(trapbase_cpu2));
|
||||
free_page((unsigned long)trapbase_cpu2);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
}
|
||||
if (!cpu_isset(3, cpu_present_map)) {
|
||||
ClearPageReserved(virt_to_page(trapbase_cpu3));
|
||||
set_page_count(virt_to_page(trapbase_cpu3), 1);
|
||||
init_page_count(virt_to_page(trapbase_cpu3));
|
||||
free_page((unsigned long)trapbase_cpu3);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
|
@ -76,7 +76,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
|
||||
vma->vm_pgoff = (offset >> PAGE_SHIFT) |
|
||||
((unsigned long)space << 28UL);
|
||||
|
||||
prot = __pgprot(pg_iobits);
|
||||
offset -= from;
|
||||
dir = pgd_offset(mm, from);
|
||||
flush_cache_range(vma, beg, end);
|
||||
|
@ -383,7 +383,7 @@ void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
|
||||
struct page *page = pfn_to_page(tmp);
|
||||
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalhigh_pages++;
|
||||
}
|
||||
@ -480,7 +480,7 @@ void free_initmem (void)
|
||||
p = virt_to_page(addr);
|
||||
|
||||
ClearPageReserved(p);
|
||||
set_page_count(p, 1);
|
||||
init_page_count(p);
|
||||
__free_page(p);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
@ -497,7 +497,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
struct page *p = virt_to_page(start);
|
||||
|
||||
ClearPageReserved(p);
|
||||
set_page_count(p, 1);
|
||||
init_page_count(p);
|
||||
__free_page(p);
|
||||
num_physpages++;
|
||||
}
|
||||
|
@ -22,8 +22,6 @@ struct ctx_list *ctx_list_pool;
|
||||
struct ctx_list ctx_free;
|
||||
struct ctx_list ctx_used;
|
||||
|
||||
unsigned int pg_iobits;
|
||||
|
||||
extern void ld_mmu_sun4c(void);
|
||||
extern void ld_mmu_srmmu(void);
|
||||
|
||||
|
@ -2130,6 +2130,13 @@ static unsigned long srmmu_pte_to_pgoff(pte_t pte)
|
||||
return pte_val(pte) >> SRMMU_PTE_FILE_SHIFT;
|
||||
}
|
||||
|
||||
static pgprot_t srmmu_pgprot_noncached(pgprot_t prot)
|
||||
{
|
||||
prot &= ~__pgprot(SRMMU_CACHE);
|
||||
|
||||
return prot;
|
||||
}
|
||||
|
||||
/* Load up routines and constants for sun4m and sun4d mmu */
|
||||
void __init ld_mmu_srmmu(void)
|
||||
{
|
||||
@ -2150,9 +2157,9 @@ void __init ld_mmu_srmmu(void)
|
||||
BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
|
||||
BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
|
||||
page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
|
||||
pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF;
|
||||
|
||||
/* Functions */
|
||||
BTFIXUPSET_CALL(pgprot_noncached, srmmu_pgprot_noncached, BTFIXUPCALL_NORM);
|
||||
#ifndef CONFIG_SMP
|
||||
BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2);
|
||||
#endif
|
||||
|
@ -1589,7 +1589,10 @@ static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
|
||||
|
||||
static inline void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr)
|
||||
{
|
||||
unsigned long page_entry;
|
||||
unsigned long page_entry, pg_iobits;
|
||||
|
||||
pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE |
|
||||
_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE;
|
||||
|
||||
page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK);
|
||||
page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT));
|
||||
@ -2134,6 +2137,13 @@ void __init sun4c_paging_init(void)
|
||||
printk("SUN4C: %d mmu entries for the kernel\n", cnt);
|
||||
}
|
||||
|
||||
static pgprot_t sun4c_pgprot_noncached(pgprot_t prot)
|
||||
{
|
||||
prot |= __pgprot(_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE);
|
||||
|
||||
return prot;
|
||||
}
|
||||
|
||||
/* Load up routines and constants for sun4c mmu */
|
||||
void __init ld_mmu_sun4c(void)
|
||||
{
|
||||
@ -2156,10 +2166,9 @@ void __init ld_mmu_sun4c(void)
|
||||
BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY));
|
||||
BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL));
|
||||
page_kernel = pgprot_val(SUN4C_PAGE_KERNEL);
|
||||
pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE |
|
||||
_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE;
|
||||
|
||||
/* Functions */
|
||||
BTFIXUPSET_CALL(pgprot_noncached, sun4c_pgprot_noncached, BTFIXUPCALL_NORM);
|
||||
BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM);
|
||||
BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM);
|
||||
|
||||
|
@ -175,11 +175,11 @@ config HUGETLB_PAGE_SIZE_4MB
|
||||
bool "4MB"
|
||||
|
||||
config HUGETLB_PAGE_SIZE_512K
|
||||
depends on !SPARC64_PAGE_SIZE_4MB
|
||||
depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB
|
||||
bool "512K"
|
||||
|
||||
config HUGETLB_PAGE_SIZE_64K
|
||||
depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB
|
||||
depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64K
|
||||
bool "64K"
|
||||
|
||||
endchoice
|
||||
|
@ -656,6 +656,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
__pci_mmap_set_flags(dev, vma, mmap_state);
|
||||
__pci_mmap_set_pgprot(dev, vma, mmap_state);
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
ret = io_remap_pfn_range(vma, vma->vm_start,
|
||||
vma->vm_pgoff,
|
||||
vma->vm_end - vma->vm_start,
|
||||
@ -663,7 +664,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
vma->vm_flags |= VM_IO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -29,15 +29,15 @@
|
||||
*
|
||||
* index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
|
||||
* tsb_base = tsb_reg & ~0x7UL;
|
||||
* tsb_index = ((vaddr >> PAGE_SHIFT) & tsb_mask);
|
||||
* tsb_index = ((vaddr >> HASH_SHIFT) & tsb_mask);
|
||||
* tsb_ptr = tsb_base + (tsb_index * 16);
|
||||
*/
|
||||
#define COMPUTE_TSB_PTR(TSB_PTR, VADDR, TMP1, TMP2) \
|
||||
#define COMPUTE_TSB_PTR(TSB_PTR, VADDR, HASH_SHIFT, TMP1, TMP2) \
|
||||
and TSB_PTR, 0x7, TMP1; \
|
||||
mov 512, TMP2; \
|
||||
andn TSB_PTR, 0x7, TSB_PTR; \
|
||||
sllx TMP2, TMP1, TMP2; \
|
||||
srlx VADDR, PAGE_SHIFT, TMP1; \
|
||||
srlx VADDR, HASH_SHIFT, TMP1; \
|
||||
sub TMP2, 1, TMP2; \
|
||||
and TMP1, TMP2, TMP1; \
|
||||
sllx TMP1, 4, TMP1; \
|
||||
@ -53,7 +53,7 @@ sun4v_itlb_miss:
|
||||
|
||||
LOAD_ITLB_INFO(%g2, %g4, %g5)
|
||||
COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_itlb_4v)
|
||||
COMPUTE_TSB_PTR(%g1, %g4, %g3, %g7)
|
||||
COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
|
||||
|
||||
/* Load TSB tag/pte into %g2/%g3 and compare the tag. */
|
||||
ldda [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
|
||||
@ -99,7 +99,7 @@ sun4v_dtlb_miss:
|
||||
|
||||
LOAD_DTLB_INFO(%g2, %g4, %g5)
|
||||
COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_dtlb_4v)
|
||||
COMPUTE_TSB_PTR(%g1, %g4, %g3, %g7)
|
||||
COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
|
||||
|
||||
/* Load TSB tag/pte into %g2/%g3 and compare the tag. */
|
||||
ldda [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
|
||||
@ -171,21 +171,26 @@ sun4v_dtsb_miss:
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
/* Create TSB pointer into %g1. This is something like:
|
||||
*
|
||||
* index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
|
||||
* tsb_base = tsb_reg & ~0x7UL;
|
||||
* tsb_index = ((vaddr >> PAGE_SHIFT) & tsb_mask);
|
||||
* tsb_ptr = tsb_base + (tsb_index * 16);
|
||||
*/
|
||||
sun4v_tsb_miss_common:
|
||||
COMPUTE_TSB_PTR(%g1, %g4, %g5, %g7)
|
||||
COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g5, %g7)
|
||||
|
||||
/* Branch directly to page table lookup. We have SCRATCHPAD_MMU_MISS
|
||||
* still in %g2, so it's quite trivial to get at the PGD PHYS value
|
||||
* so we can preload it into %g7.
|
||||
*/
|
||||
sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
mov SCRATCHPAD_UTSBREG2, %g5
|
||||
ldxa [%g5] ASI_SCRATCHPAD, %g5
|
||||
cmp %g5, -1
|
||||
be,pt %xcc, 80f
|
||||
nop
|
||||
COMPUTE_TSB_PTR(%g5, %g4, HPAGE_SHIFT, %g2, %g7)
|
||||
|
||||
/* That clobbered %g2, reload it. */
|
||||
ldxa [%g0] ASI_SCRATCHPAD, %g2
|
||||
sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
|
||||
|
||||
80: stx %g5, [%g2 + TRAP_PER_CPU_TSB_HUGE_TEMP]
|
||||
#endif
|
||||
|
||||
ba,pt %xcc, tsb_miss_page_table_walk_sun4v_fastpath
|
||||
ldx [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7
|
||||
|
||||
|
@ -2482,6 +2482,7 @@ void init_cur_cpu_trap(struct thread_info *t)
|
||||
|
||||
extern void thread_info_offsets_are_bolixed_dave(void);
|
||||
extern void trap_per_cpu_offsets_are_bolixed_dave(void);
|
||||
extern void tsb_config_offsets_are_bolixed_dave(void);
|
||||
|
||||
/* Only invoked on boot processor. */
|
||||
void __init trap_init(void)
|
||||
@ -2535,9 +2536,27 @@ void __init trap_init(void)
|
||||
(TRAP_PER_CPU_CPU_MONDO_BLOCK_PA !=
|
||||
offsetof(struct trap_per_cpu, cpu_mondo_block_pa)) ||
|
||||
(TRAP_PER_CPU_CPU_LIST_PA !=
|
||||
offsetof(struct trap_per_cpu, cpu_list_pa)))
|
||||
offsetof(struct trap_per_cpu, cpu_list_pa)) ||
|
||||
(TRAP_PER_CPU_TSB_HUGE !=
|
||||
offsetof(struct trap_per_cpu, tsb_huge)) ||
|
||||
(TRAP_PER_CPU_TSB_HUGE_TEMP !=
|
||||
offsetof(struct trap_per_cpu, tsb_huge_temp)))
|
||||
trap_per_cpu_offsets_are_bolixed_dave();
|
||||
|
||||
if ((TSB_CONFIG_TSB !=
|
||||
offsetof(struct tsb_config, tsb)) ||
|
||||
(TSB_CONFIG_RSS_LIMIT !=
|
||||
offsetof(struct tsb_config, tsb_rss_limit)) ||
|
||||
(TSB_CONFIG_NENTRIES !=
|
||||
offsetof(struct tsb_config, tsb_nentries)) ||
|
||||
(TSB_CONFIG_REG_VAL !=
|
||||
offsetof(struct tsb_config, tsb_reg_val)) ||
|
||||
(TSB_CONFIG_MAP_VADDR !=
|
||||
offsetof(struct tsb_config, tsb_map_vaddr)) ||
|
||||
(TSB_CONFIG_MAP_PTE !=
|
||||
offsetof(struct tsb_config, tsb_map_pte)))
|
||||
tsb_config_offsets_are_bolixed_dave();
|
||||
|
||||
/* Attach to the address space of init_task. On SMP we
|
||||
* do this in smp.c:smp_callin for other cpus.
|
||||
*/
|
||||
|
@ -3,8 +3,13 @@
|
||||
* Copyright (C) 2006 David S. Miller <davem@davemloft.net>
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
#include <asm/tsb.h>
|
||||
#include <asm/hypervisor.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/cpudata.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
.text
|
||||
.align 32
|
||||
@ -34,34 +39,124 @@ tsb_miss_itlb:
|
||||
ldxa [%g4] ASI_IMMU, %g4
|
||||
|
||||
/* At this point we have:
|
||||
* %g1 -- TSB entry address
|
||||
* %g1 -- PAGE_SIZE TSB entry address
|
||||
* %g3 -- FAULT_CODE_{D,I}TLB
|
||||
* %g4 -- missing virtual address
|
||||
* %g6 -- TAG TARGET (vaddr >> 22)
|
||||
*/
|
||||
tsb_miss_page_table_walk:
|
||||
TRAP_LOAD_PGD_PHYS(%g7, %g5)
|
||||
TRAP_LOAD_TRAP_BLOCK(%g7, %g5)
|
||||
|
||||
/* And now we have the PGD base physical address in %g7. */
|
||||
tsb_miss_page_table_walk_sun4v_fastpath:
|
||||
USER_PGTABLE_WALK_TL1(%g4, %g7, %g5, %g2, tsb_do_fault)
|
||||
/* Before committing to a full page table walk,
|
||||
* check the huge page TSB.
|
||||
*/
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
|
||||
661: ldx [%g7 + TRAP_PER_CPU_TSB_HUGE], %g5
|
||||
nop
|
||||
.section .sun4v_2insn_patch, "ax"
|
||||
.word 661b
|
||||
mov SCRATCHPAD_UTSBREG2, %g5
|
||||
ldxa [%g5] ASI_SCRATCHPAD, %g5
|
||||
.previous
|
||||
|
||||
cmp %g5, -1
|
||||
be,pt %xcc, 80f
|
||||
nop
|
||||
|
||||
/* We need an aligned pair of registers containing 2 values
|
||||
* which can be easily rematerialized. %g6 and %g7 foot the
|
||||
* bill just nicely. We'll save %g6 away into %g2 for the
|
||||
* huge page TSB TAG comparison.
|
||||
*
|
||||
* Perform a huge page TSB lookup.
|
||||
*/
|
||||
mov %g6, %g2
|
||||
and %g5, 0x7, %g6
|
||||
mov 512, %g7
|
||||
andn %g5, 0x7, %g5
|
||||
sllx %g7, %g6, %g7
|
||||
srlx %g4, HPAGE_SHIFT, %g6
|
||||
sub %g7, 1, %g7
|
||||
and %g6, %g7, %g6
|
||||
sllx %g6, 4, %g6
|
||||
add %g5, %g6, %g5
|
||||
|
||||
TSB_LOAD_QUAD(%g5, %g6)
|
||||
cmp %g6, %g2
|
||||
be,a,pt %xcc, tsb_tlb_reload
|
||||
mov %g7, %g5
|
||||
|
||||
/* No match, remember the huge page TSB entry address,
|
||||
* and restore %g6 and %g7.
|
||||
*/
|
||||
TRAP_LOAD_TRAP_BLOCK(%g7, %g6)
|
||||
srlx %g4, 22, %g6
|
||||
80: stx %g5, [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP]
|
||||
|
||||
#endif
|
||||
|
||||
ldx [%g7 + TRAP_PER_CPU_PGD_PADDR], %g7
|
||||
|
||||
/* At this point we have:
|
||||
* %g1 -- TSB entry address
|
||||
* %g3 -- FAULT_CODE_{D,I}TLB
|
||||
* %g5 -- physical address of PTE in Linux page tables
|
||||
* %g4 -- missing virtual address
|
||||
* %g6 -- TAG TARGET (vaddr >> 22)
|
||||
* %g7 -- page table physical address
|
||||
*
|
||||
* We know that both the base PAGE_SIZE TSB and the HPAGE_SIZE
|
||||
* TSB both lack a matching entry.
|
||||
*/
|
||||
tsb_miss_page_table_walk_sun4v_fastpath:
|
||||
USER_PGTABLE_WALK_TL1(%g4, %g7, %g5, %g2, tsb_do_fault)
|
||||
|
||||
/* Load and check PTE. */
|
||||
ldxa [%g5] ASI_PHYS_USE_EC, %g5
|
||||
brgez,pn %g5, tsb_do_fault
|
||||
nop
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
661: sethi %uhi(_PAGE_SZALL_4U), %g7
|
||||
sllx %g7, 32, %g7
|
||||
.section .sun4v_2insn_patch, "ax"
|
||||
.word 661b
|
||||
mov _PAGE_SZALL_4V, %g7
|
||||
nop
|
||||
.previous
|
||||
|
||||
and %g5, %g7, %g2
|
||||
|
||||
661: sethi %uhi(_PAGE_SZHUGE_4U), %g7
|
||||
sllx %g7, 32, %g7
|
||||
.section .sun4v_2insn_patch, "ax"
|
||||
.word 661b
|
||||
mov _PAGE_SZHUGE_4V, %g7
|
||||
nop
|
||||
.previous
|
||||
|
||||
cmp %g2, %g7
|
||||
bne,pt %xcc, 60f
|
||||
nop
|
||||
|
||||
/* It is a huge page, use huge page TSB entry address we
|
||||
* calculated above.
|
||||
*/
|
||||
TRAP_LOAD_TRAP_BLOCK(%g7, %g2)
|
||||
ldx [%g7 + TRAP_PER_CPU_TSB_HUGE_TEMP], %g2
|
||||
cmp %g2, -1
|
||||
movne %xcc, %g2, %g1
|
||||
60:
|
||||
#endif
|
||||
|
||||
/* At this point we have:
|
||||
* %g1 -- TSB entry address
|
||||
* %g3 -- FAULT_CODE_{D,I}TLB
|
||||
* %g5 -- valid PTE
|
||||
* %g6 -- TAG TARGET (vaddr >> 22)
|
||||
*/
|
||||
tsb_reload:
|
||||
TSB_LOCK_TAG(%g1, %g2, %g7)
|
||||
|
||||
/* Load and check PTE. */
|
||||
ldxa [%g5] ASI_PHYS_USE_EC, %g5
|
||||
mov 1, %g7
|
||||
sllx %g7, TSB_TAG_INVALID_BIT, %g7
|
||||
brgez,a,pn %g5, tsb_do_fault
|
||||
TSB_STORE(%g1, %g7)
|
||||
|
||||
TSB_WRITE(%g1, %g5, %g6)
|
||||
|
||||
/* Finally, load TLB and return from trap. */
|
||||
@ -240,10 +335,9 @@ tsb_flush:
|
||||
* schedule() time.
|
||||
*
|
||||
* %o0: page table physical address
|
||||
* %o1: TSB register value
|
||||
* %o2: TSB virtual address
|
||||
* %o3: TSB mapping locked PTE
|
||||
* %o4: Hypervisor TSB descriptor physical address
|
||||
* %o1: TSB base config pointer
|
||||
* %o2: TSB huge config pointer, or NULL if none
|
||||
* %o3: Hypervisor TSB descriptor physical address
|
||||
*
|
||||
* We have to run this whole thing with interrupts
|
||||
* disabled so that the current cpu doesn't change
|
||||
@ -253,63 +347,79 @@ tsb_flush:
|
||||
.globl __tsb_context_switch
|
||||
.type __tsb_context_switch,#function
|
||||
__tsb_context_switch:
|
||||
rdpr %pstate, %o5
|
||||
wrpr %o5, PSTATE_IE, %pstate
|
||||
rdpr %pstate, %g1
|
||||
wrpr %g1, PSTATE_IE, %pstate
|
||||
|
||||
TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
|
||||
|
||||
ldub [%g6 + TI_CPU], %g1
|
||||
sethi %hi(trap_block), %g2
|
||||
sllx %g1, TRAP_BLOCK_SZ_SHIFT, %g1
|
||||
or %g2, %lo(trap_block), %g2
|
||||
add %g2, %g1, %g2
|
||||
stx %o0, [%g2 + TRAP_PER_CPU_PGD_PADDR]
|
||||
|
||||
sethi %hi(tlb_type), %g1
|
||||
lduw [%g1 + %lo(tlb_type)], %g1
|
||||
cmp %g1, 3
|
||||
bne,pt %icc, 1f
|
||||
ldx [%o1 + TSB_CONFIG_REG_VAL], %o0
|
||||
brz,pt %o2, 1f
|
||||
mov -1, %g3
|
||||
|
||||
ldx [%o2 + TSB_CONFIG_REG_VAL], %g3
|
||||
|
||||
1: stx %g3, [%g2 + TRAP_PER_CPU_TSB_HUGE]
|
||||
|
||||
sethi %hi(tlb_type), %g2
|
||||
lduw [%g2 + %lo(tlb_type)], %g2
|
||||
cmp %g2, 3
|
||||
bne,pt %icc, 50f
|
||||
nop
|
||||
|
||||
/* Hypervisor TSB switch. */
|
||||
mov SCRATCHPAD_UTSBREG1, %g1
|
||||
stxa %o1, [%g1] ASI_SCRATCHPAD
|
||||
mov -1, %g2
|
||||
mov SCRATCHPAD_UTSBREG2, %g1
|
||||
stxa %g2, [%g1] ASI_SCRATCHPAD
|
||||
mov SCRATCHPAD_UTSBREG1, %o5
|
||||
stxa %o0, [%o5] ASI_SCRATCHPAD
|
||||
mov SCRATCHPAD_UTSBREG2, %o5
|
||||
stxa %g3, [%o5] ASI_SCRATCHPAD
|
||||
|
||||
/* Save away %o5's %pstate, we have to use %o5 for
|
||||
* the hypervisor call.
|
||||
*/
|
||||
mov %o5, %g1
|
||||
mov 2, %o0
|
||||
cmp %g3, -1
|
||||
move %xcc, 1, %o0
|
||||
|
||||
mov HV_FAST_MMU_TSB_CTXNON0, %o5
|
||||
mov 1, %o0
|
||||
mov %o4, %o1
|
||||
mov %o3, %o1
|
||||
ta HV_FAST_TRAP
|
||||
|
||||
/* Finish up and restore %o5. */
|
||||
/* Finish up. */
|
||||
ba,pt %xcc, 9f
|
||||
mov %g1, %o5
|
||||
|
||||
/* SUN4U TSB switch. */
|
||||
1: mov TSB_REG, %g1
|
||||
stxa %o1, [%g1] ASI_DMMU
|
||||
membar #Sync
|
||||
stxa %o1, [%g1] ASI_IMMU
|
||||
membar #Sync
|
||||
|
||||
2: brz %o2, 9f
|
||||
nop
|
||||
|
||||
/* SUN4U TSB switch. */
|
||||
50: mov TSB_REG, %o5
|
||||
stxa %o0, [%o5] ASI_DMMU
|
||||
membar #Sync
|
||||
stxa %o0, [%o5] ASI_IMMU
|
||||
membar #Sync
|
||||
|
||||
2: ldx [%o1 + TSB_CONFIG_MAP_VADDR], %o4
|
||||
brz %o4, 9f
|
||||
ldx [%o1 + TSB_CONFIG_MAP_PTE], %o5
|
||||
|
||||
sethi %hi(sparc64_highest_unlocked_tlb_ent), %g2
|
||||
mov TLB_TAG_ACCESS, %g1
|
||||
mov TLB_TAG_ACCESS, %g3
|
||||
lduw [%g2 + %lo(sparc64_highest_unlocked_tlb_ent)], %g2
|
||||
stxa %o2, [%g1] ASI_DMMU
|
||||
stxa %o4, [%g3] ASI_DMMU
|
||||
membar #Sync
|
||||
sllx %g2, 3, %g2
|
||||
stxa %o3, [%g2] ASI_DTLB_DATA_ACCESS
|
||||
stxa %o5, [%g2] ASI_DTLB_DATA_ACCESS
|
||||
membar #Sync
|
||||
|
||||
brz,pt %o2, 9f
|
||||
nop
|
||||
|
||||
ldx [%o2 + TSB_CONFIG_MAP_VADDR], %o4
|
||||
ldx [%o2 + TSB_CONFIG_MAP_PTE], %o5
|
||||
mov TLB_TAG_ACCESS, %g3
|
||||
stxa %o4, [%g3] ASI_DMMU
|
||||
membar #Sync
|
||||
sub %g2, (1 << 3), %g2
|
||||
stxa %o5, [%g2] ASI_DTLB_DATA_ACCESS
|
||||
membar #Sync
|
||||
|
||||
9:
|
||||
wrpr %o5, %pstate
|
||||
wrpr %g1, %pstate
|
||||
|
||||
retl
|
||||
nop
|
||||
|
@ -410,9 +410,18 @@ good_area:
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
mm_rss = get_mm_rss(mm);
|
||||
if (unlikely(mm_rss >= mm->context.tsb_rss_limit))
|
||||
tsb_grow(mm, mm_rss);
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
mm_rss -= (mm->context.huge_pte_count * (HPAGE_SIZE / PAGE_SIZE));
|
||||
#endif
|
||||
if (unlikely(mm_rss >=
|
||||
mm->context.tsb_block[MM_TSB_BASE].tsb_rss_limit))
|
||||
tsb_grow(mm, MM_TSB_BASE, mm_rss);
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
mm_rss = mm->context.huge_pte_count;
|
||||
if (unlikely(mm_rss >=
|
||||
mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit))
|
||||
tsb_grow(mm, MM_TSB_HUGE, mm_rss);
|
||||
#endif
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -140,7 +140,6 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
|
||||
vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
|
||||
vma->vm_pgoff = phys_base >> PAGE_SHIFT;
|
||||
|
||||
prot = __pgprot(pg_iobits);
|
||||
offset -= from;
|
||||
dir = pgd_offset(mm, from);
|
||||
flush_cache_range(vma, beg, end);
|
||||
|
@ -199,13 +199,11 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
|
||||
pte_t *pte = NULL;
|
||||
|
||||
pgd = pgd_offset(mm, addr);
|
||||
if (pgd) {
|
||||
pud = pud_offset(pgd, addr);
|
||||
if (pud) {
|
||||
pmd = pmd_alloc(mm, pud, addr);
|
||||
if (pmd)
|
||||
pte = pte_alloc_map(mm, pmd, addr);
|
||||
}
|
||||
pud = pud_alloc(mm, pgd, addr);
|
||||
if (pud) {
|
||||
pmd = pmd_alloc(mm, pud, addr);
|
||||
if (pmd)
|
||||
pte = pte_alloc_map(mm, pmd, addr);
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
@ -231,13 +229,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
|
||||
return pte;
|
||||
}
|
||||
|
||||
#define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
|
||||
|
||||
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t entry)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pte_present(*ptep) && pte_present(entry))
|
||||
mm->context.huge_pte_count++;
|
||||
|
||||
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
|
||||
set_pte_at(mm, addr, ptep, entry);
|
||||
ptep++;
|
||||
@ -253,6 +252,8 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
int i;
|
||||
|
||||
entry = *ptep;
|
||||
if (pte_present(entry))
|
||||
mm->context.huge_pte_count--;
|
||||
|
||||
for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
|
||||
pte_clear(mm, addr, ptep);
|
||||
@ -263,18 +264,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks for proper alignment of input addr and len parameters.
|
||||
*/
|
||||
int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
|
||||
{
|
||||
if (len & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
if (addr & ~HPAGE_MASK)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct page *follow_huge_addr(struct mm_struct *mm,
|
||||
unsigned long address, int write)
|
||||
{
|
||||
@ -302,6 +291,15 @@ static void context_reload(void *__data)
|
||||
|
||||
void hugetlb_prefault_arch_hook(struct mm_struct *mm)
|
||||
{
|
||||
struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE];
|
||||
|
||||
if (likely(tp->tsb != NULL))
|
||||
return;
|
||||
|
||||
tsb_grow(mm, MM_TSB_HUGE, 0);
|
||||
tsb_context_switch(mm);
|
||||
smp_tsb_sync(mm);
|
||||
|
||||
/* On UltraSPARC-III+ and later, configure the second half of
|
||||
* the Data-TLB for huge pages.
|
||||
*/
|
||||
|
@ -283,6 +283,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
|
||||
struct mm_struct *mm;
|
||||
struct tsb *tsb;
|
||||
unsigned long tag, flags;
|
||||
unsigned long tsb_index, tsb_hash_shift;
|
||||
|
||||
if (tlb_type != hypervisor) {
|
||||
unsigned long pfn = pte_pfn(pte);
|
||||
@ -312,10 +313,26 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
|
||||
|
||||
mm = vma->vm_mm;
|
||||
|
||||
tsb_index = MM_TSB_BASE;
|
||||
tsb_hash_shift = PAGE_SHIFT;
|
||||
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
|
||||
tsb = &mm->context.tsb[(address >> PAGE_SHIFT) &
|
||||
(mm->context.tsb_nentries - 1UL)];
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) {
|
||||
if ((tlb_type == hypervisor &&
|
||||
(pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
|
||||
(tlb_type != hypervisor &&
|
||||
(pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) {
|
||||
tsb_index = MM_TSB_HUGE;
|
||||
tsb_hash_shift = HPAGE_SHIFT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tsb = mm->context.tsb_block[tsb_index].tsb;
|
||||
tsb += ((address >> tsb_hash_shift) &
|
||||
(mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
|
||||
tag = (address >> 22UL);
|
||||
tsb_insert(tsb, tag, pte_val(pte));
|
||||
|
||||
@ -1461,7 +1478,7 @@ void free_initmem(void)
|
||||
p = virt_to_page(page);
|
||||
|
||||
ClearPageReserved(p);
|
||||
set_page_count(p, 1);
|
||||
init_page_count(p);
|
||||
__free_page(p);
|
||||
num_physpages++;
|
||||
totalram_pages++;
|
||||
@ -1477,7 +1494,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
struct page *p = virt_to_page(start);
|
||||
|
||||
ClearPageReserved(p);
|
||||
set_page_count(p, 1);
|
||||
init_page_count(p);
|
||||
__free_page(p);
|
||||
num_physpages++;
|
||||
totalram_pages++;
|
||||
|
@ -15,9 +15,9 @@
|
||||
|
||||
extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
|
||||
|
||||
static inline unsigned long tsb_hash(unsigned long vaddr, unsigned long nentries)
|
||||
static inline unsigned long tsb_hash(unsigned long vaddr, unsigned long hash_shift, unsigned long nentries)
|
||||
{
|
||||
vaddr >>= PAGE_SHIFT;
|
||||
vaddr >>= hash_shift;
|
||||
return vaddr & (nentries - 1);
|
||||
}
|
||||
|
||||
@ -36,7 +36,8 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end)
|
||||
unsigned long v;
|
||||
|
||||
for (v = start; v < end; v += PAGE_SIZE) {
|
||||
unsigned long hash = tsb_hash(v, KERNEL_TSB_NENTRIES);
|
||||
unsigned long hash = tsb_hash(v, PAGE_SHIFT,
|
||||
KERNEL_TSB_NENTRIES);
|
||||
struct tsb *ent = &swapper_tsb[hash];
|
||||
|
||||
if (tag_compare(ent->tag, v)) {
|
||||
@ -46,49 +47,91 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end)
|
||||
}
|
||||
}
|
||||
|
||||
void flush_tsb_user(struct mmu_gather *mp)
|
||||
static void __flush_tsb_one(struct mmu_gather *mp, unsigned long hash_shift, unsigned long tsb, unsigned long nentries)
|
||||
{
|
||||
struct mm_struct *mm = mp->mm;
|
||||
unsigned long nentries, base, flags;
|
||||
struct tsb *tsb;
|
||||
int i;
|
||||
unsigned long i;
|
||||
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
|
||||
tsb = mm->context.tsb;
|
||||
nentries = mm->context.tsb_nentries;
|
||||
|
||||
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
|
||||
base = __pa(tsb);
|
||||
else
|
||||
base = (unsigned long) tsb;
|
||||
|
||||
for (i = 0; i < mp->tlb_nr; i++) {
|
||||
unsigned long v = mp->vaddrs[i];
|
||||
unsigned long tag, ent, hash;
|
||||
|
||||
v &= ~0x1UL;
|
||||
|
||||
hash = tsb_hash(v, nentries);
|
||||
ent = base + (hash * sizeof(struct tsb));
|
||||
hash = tsb_hash(v, hash_shift, nentries);
|
||||
ent = tsb + (hash * sizeof(struct tsb));
|
||||
tag = (v >> 22UL);
|
||||
|
||||
tsb_flush(ent, tag);
|
||||
}
|
||||
}
|
||||
|
||||
void flush_tsb_user(struct mmu_gather *mp)
|
||||
{
|
||||
struct mm_struct *mm = mp->mm;
|
||||
unsigned long nentries, base, flags;
|
||||
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
|
||||
base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
|
||||
nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
|
||||
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
|
||||
base = __pa(base);
|
||||
__flush_tsb_one(mp, PAGE_SHIFT, base, nentries);
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
|
||||
base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
|
||||
nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
|
||||
if (tlb_type == cheetah_plus || tlb_type == hypervisor)
|
||||
base = __pa(base);
|
||||
__flush_tsb_one(mp, HPAGE_SHIFT, base, nentries);
|
||||
}
|
||||
#endif
|
||||
spin_unlock_irqrestore(&mm->context.lock, flags);
|
||||
}
|
||||
|
||||
static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_bytes)
|
||||
#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
|
||||
#define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K
|
||||
#define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
|
||||
#define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_64K
|
||||
#define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_64K
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB)
|
||||
#define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_512K
|
||||
#define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_512K
|
||||
#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB)
|
||||
#define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_4MB
|
||||
#define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_4MB
|
||||
#else
|
||||
#error Broken base page size setting...
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
|
||||
#define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_64K
|
||||
#define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_64K
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
|
||||
#define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_512K
|
||||
#define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_512K
|
||||
#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
|
||||
#define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_4MB
|
||||
#define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_4MB
|
||||
#else
|
||||
#error Broken huge page size setting...
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsigned long tsb_bytes)
|
||||
{
|
||||
unsigned long tsb_reg, base, tsb_paddr;
|
||||
unsigned long page_sz, tte;
|
||||
|
||||
mm->context.tsb_nentries = tsb_bytes / sizeof(struct tsb);
|
||||
mm->context.tsb_block[tsb_idx].tsb_nentries =
|
||||
tsb_bytes / sizeof(struct tsb);
|
||||
|
||||
base = TSBMAP_BASE;
|
||||
tte = pgprot_val(PAGE_KERNEL_LOCKED);
|
||||
tsb_paddr = __pa(mm->context.tsb);
|
||||
tsb_paddr = __pa(mm->context.tsb_block[tsb_idx].tsb);
|
||||
BUG_ON(tsb_paddr & (tsb_bytes - 1UL));
|
||||
|
||||
/* Use the smallest page size that can map the whole TSB
|
||||
@ -147,61 +190,49 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_bytes)
|
||||
/* Physical mapping, no locked TLB entry for TSB. */
|
||||
tsb_reg |= tsb_paddr;
|
||||
|
||||
mm->context.tsb_reg_val = tsb_reg;
|
||||
mm->context.tsb_map_vaddr = 0;
|
||||
mm->context.tsb_map_pte = 0;
|
||||
mm->context.tsb_block[tsb_idx].tsb_reg_val = tsb_reg;
|
||||
mm->context.tsb_block[tsb_idx].tsb_map_vaddr = 0;
|
||||
mm->context.tsb_block[tsb_idx].tsb_map_pte = 0;
|
||||
} else {
|
||||
tsb_reg |= base;
|
||||
tsb_reg |= (tsb_paddr & (page_sz - 1UL));
|
||||
tte |= (tsb_paddr & ~(page_sz - 1UL));
|
||||
|
||||
mm->context.tsb_reg_val = tsb_reg;
|
||||
mm->context.tsb_map_vaddr = base;
|
||||
mm->context.tsb_map_pte = tte;
|
||||
mm->context.tsb_block[tsb_idx].tsb_reg_val = tsb_reg;
|
||||
mm->context.tsb_block[tsb_idx].tsb_map_vaddr = base;
|
||||
mm->context.tsb_block[tsb_idx].tsb_map_pte = tte;
|
||||
}
|
||||
|
||||
/* Setup the Hypervisor TSB descriptor. */
|
||||
if (tlb_type == hypervisor) {
|
||||
struct hv_tsb_descr *hp = &mm->context.tsb_descr;
|
||||
struct hv_tsb_descr *hp = &mm->context.tsb_descr[tsb_idx];
|
||||
|
||||
switch (PAGE_SIZE) {
|
||||
case 8192:
|
||||
switch (tsb_idx) {
|
||||
case MM_TSB_BASE:
|
||||
hp->pgsz_idx = HV_PGSZ_IDX_BASE;
|
||||
break;
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
case MM_TSB_HUGE:
|
||||
hp->pgsz_idx = HV_PGSZ_IDX_HUGE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
hp->pgsz_idx = HV_PGSZ_IDX_8K;
|
||||
break;
|
||||
|
||||
case 64 * 1024:
|
||||
hp->pgsz_idx = HV_PGSZ_IDX_64K;
|
||||
break;
|
||||
|
||||
case 512 * 1024:
|
||||
hp->pgsz_idx = HV_PGSZ_IDX_512K;
|
||||
break;
|
||||
|
||||
case 4 * 1024 * 1024:
|
||||
hp->pgsz_idx = HV_PGSZ_IDX_4MB;
|
||||
break;
|
||||
BUG();
|
||||
};
|
||||
hp->assoc = 1;
|
||||
hp->num_ttes = tsb_bytes / 16;
|
||||
hp->ctx_idx = 0;
|
||||
switch (PAGE_SIZE) {
|
||||
case 8192:
|
||||
switch (tsb_idx) {
|
||||
case MM_TSB_BASE:
|
||||
hp->pgsz_mask = HV_PGSZ_MASK_BASE;
|
||||
break;
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
case MM_TSB_HUGE:
|
||||
hp->pgsz_mask = HV_PGSZ_MASK_HUGE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
hp->pgsz_mask = HV_PGSZ_MASK_8K;
|
||||
break;
|
||||
|
||||
case 64 * 1024:
|
||||
hp->pgsz_mask = HV_PGSZ_MASK_64K;
|
||||
break;
|
||||
|
||||
case 512 * 1024:
|
||||
hp->pgsz_mask = HV_PGSZ_MASK_512K;
|
||||
break;
|
||||
|
||||
case 4 * 1024 * 1024:
|
||||
hp->pgsz_mask = HV_PGSZ_MASK_4MB;
|
||||
break;
|
||||
BUG();
|
||||
};
|
||||
hp->tsb_base = tsb_paddr;
|
||||
hp->resv = 0;
|
||||
@ -241,11 +272,11 @@ void __init tsb_cache_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* When the RSS of an address space exceeds mm->context.tsb_rss_limit,
|
||||
* do_sparc64_fault() invokes this routine to try and grow the TSB.
|
||||
/* When the RSS of an address space exceeds tsb_rss_limit for a TSB,
|
||||
* do_sparc64_fault() invokes this routine to try and grow it.
|
||||
*
|
||||
* When we reach the maximum TSB size supported, we stick ~0UL into
|
||||
* mm->context.tsb_rss_limit so the grow checks in update_mmu_cache()
|
||||
* tsb_rss_limit for that TSB so the grow checks in do_sparc64_fault()
|
||||
* will not trigger any longer.
|
||||
*
|
||||
* The TSB can be anywhere from 8K to 1MB in size, in increasing powers
|
||||
@ -257,7 +288,7 @@ void __init tsb_cache_init(void)
|
||||
* the number of entries that the current TSB can hold at once. Currently,
|
||||
* we trigger when the RSS hits 3/4 of the TSB capacity.
|
||||
*/
|
||||
void tsb_grow(struct mm_struct *mm, unsigned long rss)
|
||||
void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss)
|
||||
{
|
||||
unsigned long max_tsb_size = 1 * 1024 * 1024;
|
||||
unsigned long new_size, old_size, flags;
|
||||
@ -297,7 +328,8 @@ retry_tsb_alloc:
|
||||
* down to a 0-order allocation and force no TSB
|
||||
* growing for this address space.
|
||||
*/
|
||||
if (mm->context.tsb == NULL && new_cache_index > 0) {
|
||||
if (mm->context.tsb_block[tsb_index].tsb == NULL &&
|
||||
new_cache_index > 0) {
|
||||
new_cache_index = 0;
|
||||
new_size = 8192;
|
||||
new_rss_limit = ~0UL;
|
||||
@ -307,8 +339,8 @@ retry_tsb_alloc:
|
||||
/* If we failed on a TSB grow, we are under serious
|
||||
* memory pressure so don't try to grow any more.
|
||||
*/
|
||||
if (mm->context.tsb != NULL)
|
||||
mm->context.tsb_rss_limit = ~0UL;
|
||||
if (mm->context.tsb_block[tsb_index].tsb != NULL)
|
||||
mm->context.tsb_block[tsb_index].tsb_rss_limit = ~0UL;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -339,23 +371,26 @@ retry_tsb_alloc:
|
||||
*/
|
||||
spin_lock_irqsave(&mm->context.lock, flags);
|
||||
|
||||
old_tsb = mm->context.tsb;
|
||||
old_cache_index = (mm->context.tsb_reg_val & 0x7UL);
|
||||
old_size = mm->context.tsb_nentries * sizeof(struct tsb);
|
||||
old_tsb = mm->context.tsb_block[tsb_index].tsb;
|
||||
old_cache_index =
|
||||
(mm->context.tsb_block[tsb_index].tsb_reg_val & 0x7UL);
|
||||
old_size = (mm->context.tsb_block[tsb_index].tsb_nentries *
|
||||
sizeof(struct tsb));
|
||||
|
||||
|
||||
/* Handle multiple threads trying to grow the TSB at the same time.
|
||||
* One will get in here first, and bump the size and the RSS limit.
|
||||
* The others will get in here next and hit this check.
|
||||
*/
|
||||
if (unlikely(old_tsb && (rss < mm->context.tsb_rss_limit))) {
|
||||
if (unlikely(old_tsb &&
|
||||
(rss < mm->context.tsb_block[tsb_index].tsb_rss_limit))) {
|
||||
spin_unlock_irqrestore(&mm->context.lock, flags);
|
||||
|
||||
kmem_cache_free(tsb_caches[new_cache_index], new_tsb);
|
||||
return;
|
||||
}
|
||||
|
||||
mm->context.tsb_rss_limit = new_rss_limit;
|
||||
mm->context.tsb_block[tsb_index].tsb_rss_limit = new_rss_limit;
|
||||
|
||||
if (old_tsb) {
|
||||
extern void copy_tsb(unsigned long old_tsb_base,
|
||||
@ -372,8 +407,8 @@ retry_tsb_alloc:
|
||||
copy_tsb(old_tsb_base, old_size, new_tsb_base, new_size);
|
||||
}
|
||||
|
||||
mm->context.tsb = new_tsb;
|
||||
setup_tsb_params(mm, new_size);
|
||||
mm->context.tsb_block[tsb_index].tsb = new_tsb;
|
||||
setup_tsb_params(mm, tsb_index, new_size);
|
||||
|
||||
spin_unlock_irqrestore(&mm->context.lock, flags);
|
||||
|
||||
@ -394,40 +429,65 @@ retry_tsb_alloc:
|
||||
|
||||
int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
||||
{
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
unsigned long huge_pte_count;
|
||||
#endif
|
||||
unsigned int i;
|
||||
|
||||
spin_lock_init(&mm->context.lock);
|
||||
|
||||
mm->context.sparc64_ctx_val = 0UL;
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
/* We reset it to zero because the fork() page copying
|
||||
* will re-increment the counters as the parent PTEs are
|
||||
* copied into the child address space.
|
||||
*/
|
||||
huge_pte_count = mm->context.huge_pte_count;
|
||||
mm->context.huge_pte_count = 0;
|
||||
#endif
|
||||
|
||||
/* copy_mm() copies over the parent's mm_struct before calling
|
||||
* us, so we need to zero out the TSB pointer or else tsb_grow()
|
||||
* will be confused and think there is an older TSB to free up.
|
||||
*/
|
||||
mm->context.tsb = NULL;
|
||||
for (i = 0; i < MM_NUM_TSBS; i++)
|
||||
mm->context.tsb_block[i].tsb = NULL;
|
||||
|
||||
/* If this is fork, inherit the parent's TSB size. We would
|
||||
* grow it to that size on the first page fault anyways.
|
||||
*/
|
||||
tsb_grow(mm, get_mm_rss(mm));
|
||||
tsb_grow(mm, MM_TSB_BASE, get_mm_rss(mm));
|
||||
|
||||
if (unlikely(!mm->context.tsb))
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
if (unlikely(huge_pte_count))
|
||||
tsb_grow(mm, MM_TSB_HUGE, huge_pte_count);
|
||||
#endif
|
||||
|
||||
if (unlikely(!mm->context.tsb_block[MM_TSB_BASE].tsb))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tsb_destroy_one(struct tsb_config *tp)
|
||||
{
|
||||
unsigned long cache_index;
|
||||
|
||||
if (!tp->tsb)
|
||||
return;
|
||||
cache_index = tp->tsb_reg_val & 0x7UL;
|
||||
kmem_cache_free(tsb_caches[cache_index], tp->tsb);
|
||||
tp->tsb = NULL;
|
||||
tp->tsb_reg_val = 0UL;
|
||||
}
|
||||
|
||||
void destroy_context(struct mm_struct *mm)
|
||||
{
|
||||
unsigned long flags, cache_index;
|
||||
unsigned long flags, i;
|
||||
|
||||
cache_index = (mm->context.tsb_reg_val & 0x7UL);
|
||||
kmem_cache_free(tsb_caches[cache_index], mm->context.tsb);
|
||||
|
||||
/* We can remove these later, but for now it's useful
|
||||
* to catch any bogus post-destroy_context() references
|
||||
* to the TSB.
|
||||
*/
|
||||
mm->context.tsb = NULL;
|
||||
mm->context.tsb_reg_val = 0UL;
|
||||
for (i = 0; i < MM_NUM_TSBS; i++)
|
||||
tsb_destroy_one(&mm->context.tsb_block[i]);
|
||||
|
||||
spin_lock_irqsave(&ctx_alloc_lock, flags);
|
||||
|
||||
|
@ -57,7 +57,7 @@ static void setup_highmem(unsigned long highmem_start,
|
||||
for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
|
||||
page = &mem_map[highmem_pfn + i];
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
}
|
||||
}
|
||||
@ -296,7 +296,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
(end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
|
||||
|
||||
for(i = 0; i < total_pages; i++){
|
||||
p = &map[i];
|
||||
set_page_count(p, 0);
|
||||
memset(p, 0, sizeof(struct page));
|
||||
SetPageReserved(p);
|
||||
INIT_LIST_HEAD(&p->lru);
|
||||
}
|
||||
|
@ -477,7 +477,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static unsigned int cyc2ns_scale;
|
||||
static unsigned int cyc2ns_scale __read_mostly;
|
||||
#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
|
||||
|
||||
static inline void set_cyc2ns_scale(unsigned long cpu_khz)
|
||||
|
@ -124,6 +124,7 @@ extern void * __memcpy(void *,const void *,__kernel_size_t);
|
||||
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(strlen);
|
||||
EXPORT_SYMBOL(strpbrk);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(__memcpy);
|
||||
|
@ -486,7 +486,7 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size)
|
||||
void online_page(struct page *page)
|
||||
{
|
||||
ClearPageReserved(page);
|
||||
set_page_count(page, 1);
|
||||
init_page_count(page);
|
||||
__free_page(page);
|
||||
totalram_pages++;
|
||||
num_physpages++;
|
||||
@ -592,7 +592,7 @@ void free_initmem(void)
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
init_page_count(virt_to_page(addr));
|
||||
memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE);
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
@ -632,7 +632,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -45,6 +45,13 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
|
||||
pte_t *pbase;
|
||||
if (!base)
|
||||
return NULL;
|
||||
/*
|
||||
* page_private is used to track the number of entries in
|
||||
* the page table page have non standard attributes.
|
||||
*/
|
||||
SetPagePrivate(base);
|
||||
page_private(base) = 0;
|
||||
|
||||
address = __pa(address);
|
||||
addr = address & LARGE_PAGE_MASK;
|
||||
pbase = (pte_t *)page_address(base);
|
||||
@ -77,26 +84,12 @@ static inline void flush_map(unsigned long address)
|
||||
on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
|
||||
}
|
||||
|
||||
struct deferred_page {
|
||||
struct deferred_page *next;
|
||||
struct page *fpage;
|
||||
unsigned long address;
|
||||
};
|
||||
static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
|
||||
static struct page *deferred_pages; /* protected by init_mm.mmap_sem */
|
||||
|
||||
static inline void save_page(unsigned long address, struct page *fpage)
|
||||
static inline void save_page(struct page *fpage)
|
||||
{
|
||||
struct deferred_page *df;
|
||||
df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL);
|
||||
if (!df) {
|
||||
flush_map(address);
|
||||
__free_page(fpage);
|
||||
} else {
|
||||
df->next = df_list;
|
||||
df->fpage = fpage;
|
||||
df->address = address;
|
||||
df_list = df;
|
||||
}
|
||||
fpage->lru.next = (struct list_head *)deferred_pages;
|
||||
deferred_pages = fpage;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -138,8 +131,8 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
|
||||
set_pte(kpte, pfn_pte(pfn, prot));
|
||||
} else {
|
||||
/*
|
||||
* split_large_page will take the reference for this change_page_attr
|
||||
* on the split page.
|
||||
* split_large_page will take the reference for this
|
||||
* change_page_attr on the split page.
|
||||
*/
|
||||
|
||||
struct page *split;
|
||||
@ -151,23 +144,20 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
|
||||
set_pte(kpte,mk_pte(split, ref_prot2));
|
||||
kpte_page = split;
|
||||
}
|
||||
get_page(kpte_page);
|
||||
page_private(kpte_page)++;
|
||||
} else if ((kpte_flags & _PAGE_PSE) == 0) {
|
||||
set_pte(kpte, pfn_pte(pfn, ref_prot));
|
||||
__put_page(kpte_page);
|
||||
BUG_ON(page_private(kpte_page) == 0);
|
||||
page_private(kpte_page)--;
|
||||
} else
|
||||
BUG();
|
||||
|
||||
/* on x86-64 the direct mapping set at boot is not using 4k pages */
|
||||
BUG_ON(PageReserved(kpte_page));
|
||||
|
||||
switch (page_count(kpte_page)) {
|
||||
case 1:
|
||||
save_page(address, kpte_page);
|
||||
if (page_private(kpte_page) == 0) {
|
||||
save_page(kpte_page);
|
||||
revert_page(address, ref_prot);
|
||||
break;
|
||||
case 0:
|
||||
BUG(); /* memleak and failed 2M page regeneration */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -220,17 +210,18 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot)
|
||||
|
||||
void global_flush_tlb(void)
|
||||
{
|
||||
struct deferred_page *df, *next_df;
|
||||
struct page *dpage;
|
||||
|
||||
down_read(&init_mm.mmap_sem);
|
||||
df = xchg(&df_list, NULL);
|
||||
dpage = xchg(&deferred_pages, NULL);
|
||||
up_read(&init_mm.mmap_sem);
|
||||
flush_map((df && !df->next) ? df->address : 0);
|
||||
for (; df; df = next_df) {
|
||||
next_df = df->next;
|
||||
if (df->fpage)
|
||||
__free_page(df->fpage);
|
||||
kfree(df);
|
||||
|
||||
flush_map((dpage && !dpage->lru.next) ? (unsigned long)page_address(dpage) : 0);
|
||||
while (dpage) {
|
||||
struct page *tmp = dpage;
|
||||
dpage = (struct page *)dpage->lru.next;
|
||||
ClearPagePrivate(tmp);
|
||||
__free_page(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ free_reserved_mem(void *start, void *end)
|
||||
{
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
set_page_count(virt_to_page(start), 1);
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page((unsigned long)start);
|
||||
totalram_pages++;
|
||||
}
|
||||
|
@ -14,25 +14,21 @@
|
||||
|
||||
pte_t* pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
pte_t *pte, p;
|
||||
pte_t *pte = NULL, *p;
|
||||
int color = ADDR_COLOR(address);
|
||||
int i;
|
||||
|
||||
p = (pte_t*) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, COLOR_ORDER);
|
||||
|
||||
if (likely(p)) {
|
||||
struct page *page;
|
||||
|
||||
for (i = 0; i < COLOR_SIZE; i++, p++) {
|
||||
page = virt_to_page(pte);
|
||||
|
||||
set_page_count(page, 1);
|
||||
ClearPageCompound(page);
|
||||
split_page(virt_to_page(p), COLOR_ORDER);
|
||||
|
||||
for (i = 0; i < COLOR_SIZE; i++) {
|
||||
if (ADDR_COLOR(p) == color)
|
||||
pte = p;
|
||||
else
|
||||
free_page(p);
|
||||
p += PTRS_PER_PTE;
|
||||
}
|
||||
clear_page(pte);
|
||||
}
|
||||
@ -49,20 +45,20 @@ int flush;
|
||||
|
||||
struct page* pte_alloc_one(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
struct page *page, p;
|
||||
struct page *page = NULL, *p;
|
||||
int color = ADDR_COLOR(address);
|
||||
|
||||
p = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
|
||||
|
||||
if (likely(p)) {
|
||||
for (i = 0; i < PAGE_ORDER; i++) {
|
||||
set_page_count(p, 1);
|
||||
ClearPageCompound(p);
|
||||
split_page(p, COLOR_ORDER);
|
||||
|
||||
if (PADDR_COLOR(page_address(pg)) == color)
|
||||
for (i = 0; i < PAGE_ORDER; i++) {
|
||||
if (PADDR_COLOR(page_address(p)) == color)
|
||||
page = p;
|
||||
else
|
||||
free_page(p);
|
||||
__free_page(p);
|
||||
p++;
|
||||
}
|
||||
clear_highpage(page);
|
||||
}
|
||||
|
@ -536,6 +536,28 @@ void bus_rescan_devices(struct bus_type * bus)
|
||||
bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* device_reprobe - remove driver for a device and probe for a new driver
|
||||
* @dev: the device to reprobe
|
||||
*
|
||||
* This function detaches the attached driver (if any) for the given
|
||||
* device and restarts the driver probing process. It is intended
|
||||
* to use if probing criteria changed during a devices lifetime and
|
||||
* driver attachment should change accordingly.
|
||||
*/
|
||||
void device_reprobe(struct device *dev)
|
||||
{
|
||||
if (dev->driver) {
|
||||
if (dev->parent) /* Needed for USB */
|
||||
down(&dev->parent->sem);
|
||||
device_release_driver(dev);
|
||||
if (dev->parent)
|
||||
up(&dev->parent->sem);
|
||||
}
|
||||
|
||||
bus_rescan_devices_helper(dev, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_reprobe);
|
||||
|
||||
struct bus_type * get_bus(struct bus_type * bus)
|
||||
{
|
||||
|
@ -326,7 +326,7 @@ 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
|
||||
* Unregistration is done in 2 steps. First we release all resources
|
||||
* and remove it from the subsystem, then we drop reference count by
|
||||
* calling platform_device_put().
|
||||
*/
|
||||
|
@ -2137,7 +2137,7 @@ static void start_io( ctlr_info_t *h)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the frist entry from the Request Q */
|
||||
/* Get the first entry from the Request Q */
|
||||
removeQ(&(h->reqQ), c);
|
||||
h->Qdepth--;
|
||||
|
||||
@ -3251,8 +3251,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
||||
|
||||
clean4:
|
||||
#ifdef CONFIG_CISS_SCSI_TAPE
|
||||
if(hba[i]->scsi_rejects.complete)
|
||||
kfree(hba[i]->scsi_rejects.complete);
|
||||
kfree(hba[i]->scsi_rejects.complete);
|
||||
#endif
|
||||
kfree(hba[i]->cmd_pool_bits);
|
||||
if(hba[i]->cmd_pool)
|
||||
|
@ -619,6 +619,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
#endif
|
||||
offset = dev->driver->get_reg_ofs(dev);
|
||||
#ifdef __sparc__
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
|
||||
(map->offset + offset) >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
|
@ -283,7 +283,7 @@ static void tb0219_pci_irq_init(void)
|
||||
vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW);
|
||||
}
|
||||
|
||||
static int tb0219_probe(struct platform_device *dev)
|
||||
static int __devinit tb0219_probe(struct platform_device *dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@ -319,7 +319,7 @@ static int tb0219_probe(struct platform_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tb0219_remove(struct platform_device *dev)
|
||||
static int __devexit tb0219_remove(struct platform_device *dev)
|
||||
{
|
||||
_machine_restart = old_machine_restart;
|
||||
|
||||
@ -335,19 +335,26 @@ static struct platform_device *tb0219_platform_device;
|
||||
|
||||
static struct platform_driver tb0219_device_driver = {
|
||||
.probe = tb0219_probe,
|
||||
.remove = tb0219_remove,
|
||||
.remove = __devexit_p(tb0219_remove),
|
||||
.driver = {
|
||||
.name = "TB0219",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit tanbac_tb0219_init(void)
|
||||
static int __init tanbac_tb0219_init(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
tb0219_platform_device = platform_device_register_simple("TB0219", -1, NULL, 0);
|
||||
if (IS_ERR(tb0219_platform_device))
|
||||
return PTR_ERR(tb0219_platform_device);
|
||||
tb0219_platform_device = platform_device_alloc("TB0219", -1);
|
||||
if (!tb0219_platform_device)
|
||||
return -ENOMEM;
|
||||
|
||||
retval = platform_device_add(tb0219_platform_device);
|
||||
if (retval < 0) {
|
||||
platform_device_put(tb0219_platform_device);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = platform_driver_register(&tb0219_device_driver);
|
||||
if (retval < 0)
|
||||
@ -356,10 +363,9 @@ static int __devinit tanbac_tb0219_init(void)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void __devexit tanbac_tb0219_exit(void)
|
||||
static void __exit tanbac_tb0219_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tb0219_device_driver);
|
||||
|
||||
platform_device_unregister(tb0219_platform_device);
|
||||
}
|
||||
|
||||
|
@ -613,7 +613,7 @@ static struct file_operations gpio_fops = {
|
||||
.release = gpio_release,
|
||||
};
|
||||
|
||||
static int giu_probe(struct platform_device *dev)
|
||||
static int __devinit giu_probe(struct platform_device *dev)
|
||||
{
|
||||
unsigned long start, size, flags = 0;
|
||||
unsigned int nr_pins = 0;
|
||||
@ -697,7 +697,7 @@ static int giu_probe(struct platform_device *dev)
|
||||
return cascade_irq(GIUINT_IRQ, giu_get_irq);
|
||||
}
|
||||
|
||||
static int giu_remove(struct platform_device *dev)
|
||||
static int __devexit giu_remove(struct platform_device *dev)
|
||||
{
|
||||
iounmap(giu_base);
|
||||
|
||||
@ -712,9 +712,10 @@ static struct platform_device *giu_platform_device;
|
||||
|
||||
static struct platform_driver giu_device_driver = {
|
||||
.probe = giu_probe,
|
||||
.remove = giu_remove,
|
||||
.remove = __devexit_p(giu_remove),
|
||||
.driver = {
|
||||
.name = "GIU",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
@ -722,9 +723,15 @@ static int __init vr41xx_giu_init(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
giu_platform_device = platform_device_register_simple("GIU", -1, NULL, 0);
|
||||
if (IS_ERR(giu_platform_device))
|
||||
return PTR_ERR(giu_platform_device);
|
||||
giu_platform_device = platform_device_alloc("GIU", -1);
|
||||
if (!giu_platform_device)
|
||||
return -ENOMEM;
|
||||
|
||||
retval = platform_device_add(giu_platform_device);
|
||||
if (retval < 0) {
|
||||
platform_device_put(giu_platform_device);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = platform_driver_register(&giu_device_driver);
|
||||
if (retval < 0)
|
||||
|
@ -558,7 +558,7 @@ static struct miscdevice rtc_miscdevice = {
|
||||
.fops = &rtc_fops,
|
||||
};
|
||||
|
||||
static int rtc_probe(struct platform_device *pdev)
|
||||
static int __devinit rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int irq;
|
||||
int retval;
|
||||
@ -631,7 +631,7 @@ static int rtc_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtc_remove(struct platform_device *dev)
|
||||
static int __devexit rtc_remove(struct platform_device *dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@ -653,13 +653,14 @@ static struct platform_device *rtc_platform_device;
|
||||
|
||||
static struct platform_driver rtc_device_driver = {
|
||||
.probe = rtc_probe,
|
||||
.remove = rtc_remove,
|
||||
.remove = __devexit_p(rtc_remove),
|
||||
.driver = {
|
||||
.name = rtc_name,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit vr41xx_rtc_init(void)
|
||||
static int __init vr41xx_rtc_init(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
@ -684,10 +685,20 @@ static int __devinit vr41xx_rtc_init(void)
|
||||
break;
|
||||
}
|
||||
|
||||
rtc_platform_device = platform_device_register_simple("RTC", -1,
|
||||
rtc_resource, ARRAY_SIZE(rtc_resource));
|
||||
if (IS_ERR(rtc_platform_device))
|
||||
return PTR_ERR(rtc_platform_device);
|
||||
rtc_platform_device = platform_device_alloc("RTC", -1);
|
||||
if (!rtc_platform_device)
|
||||
return -ENOMEM;
|
||||
|
||||
retval = platform_device_add_resources(rtc_platform_device,
|
||||
rtc_resource, ARRAY_SIZE(rtc_resource));
|
||||
|
||||
if (retval == 0)
|
||||
retval = platform_device_add(rtc_platform_device);
|
||||
|
||||
if (retval < 0) {
|
||||
platform_device_put(rtc_platform_device);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = platform_driver_register(&rtc_device_driver);
|
||||
if (retval < 0)
|
||||
@ -696,10 +707,9 @@ static int __devinit vr41xx_rtc_init(void)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void __devexit vr41xx_rtc_exit(void)
|
||||
static void __exit vr41xx_rtc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rtc_device_driver);
|
||||
|
||||
platform_device_unregister(rtc_platform_device);
|
||||
}
|
||||
|
||||
|
@ -228,15 +228,25 @@ static int __init mv64x60_wdt_init(void)
|
||||
|
||||
printk(KERN_INFO "MV64x60 watchdog driver\n");
|
||||
|
||||
mv64x60_wdt_dev = platform_device_register_simple(MV64x60_WDT_NAME,
|
||||
-1, NULL, 0);
|
||||
if (IS_ERR(mv64x60_wdt_dev)) {
|
||||
ret = PTR_ERR(mv64x60_wdt_dev);
|
||||
mv64x60_wdt_dev = platform_device_alloc(MV64x60_WDT_NAME, -1);
|
||||
if (!mv64x60_wdt_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = platform_device_add(mv64x60_wdt_dev);
|
||||
if (ret) {
|
||||
platform_device_put(mv64x60_wdt_dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&mv64x60_wdt_driver);
|
||||
out:
|
||||
if (ret) {
|
||||
platform_device_unregister(mv64x60_wdt_dev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -530,30 +530,27 @@ static DCDBAS_DEV_ATTR_RW(host_control_action);
|
||||
static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
|
||||
static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);
|
||||
|
||||
static struct device_attribute *dcdbas_dev_attrs[] = {
|
||||
&dev_attr_smi_data_buf_size,
|
||||
&dev_attr_smi_data_buf_phys_addr,
|
||||
&dev_attr_smi_request,
|
||||
&dev_attr_host_control_action,
|
||||
&dev_attr_host_control_smi_type,
|
||||
&dev_attr_host_control_on_shutdown,
|
||||
static struct attribute *dcdbas_dev_attrs[] = {
|
||||
&dev_attr_smi_data_buf_size.attr,
|
||||
&dev_attr_smi_data_buf_phys_addr.attr,
|
||||
&dev_attr_smi_request.attr,
|
||||
&dev_attr_host_control_action.attr,
|
||||
&dev_attr_host_control_smi_type.attr,
|
||||
&dev_attr_host_control_on_shutdown.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* dcdbas_init: initialize driver
|
||||
*/
|
||||
static int __init dcdbas_init(void)
|
||||
static struct attribute_group dcdbas_attr_group = {
|
||||
.attrs = dcdbas_dev_attrs,
|
||||
};
|
||||
|
||||
static int __devinit dcdbas_probe(struct platform_device *dev)
|
||||
{
|
||||
int i;
|
||||
int i, error;
|
||||
|
||||
host_control_action = HC_ACTION_NONE;
|
||||
host_control_smi_type = HC_SMITYPE_NONE;
|
||||
|
||||
dcdbas_pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
|
||||
if (IS_ERR(dcdbas_pdev))
|
||||
return PTR_ERR(dcdbas_pdev);
|
||||
|
||||
/*
|
||||
* BIOS SMI calls require buffer addresses be in 32-bit address space.
|
||||
* This is done by setting the DMA mask below.
|
||||
@ -561,21 +558,81 @@ static int __init dcdbas_init(void)
|
||||
dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
|
||||
dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;
|
||||
|
||||
error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
for (i = 0; dcdbas_bin_attrs[i]; i++) {
|
||||
error = sysfs_create_bin_file(&dev->dev.kobj,
|
||||
dcdbas_bin_attrs[i]);
|
||||
if (error) {
|
||||
while (--i >= 0)
|
||||
sysfs_remove_bin_file(&dev->dev.kobj,
|
||||
dcdbas_bin_attrs[i]);
|
||||
sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
register_reboot_notifier(&dcdbas_reboot_nb);
|
||||
|
||||
for (i = 0; dcdbas_bin_attrs[i]; i++)
|
||||
sysfs_create_bin_file(&dcdbas_pdev->dev.kobj,
|
||||
dcdbas_bin_attrs[i]);
|
||||
|
||||
for (i = 0; dcdbas_dev_attrs[i]; i++)
|
||||
device_create_file(&dcdbas_pdev->dev, dcdbas_dev_attrs[i]);
|
||||
|
||||
dev_info(&dcdbas_pdev->dev, "%s (version %s)\n",
|
||||
dev_info(&dev->dev, "%s (version %s)\n",
|
||||
DRIVER_DESCRIPTION, DRIVER_VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devexit dcdbas_remove(struct platform_device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
unregister_reboot_notifier(&dcdbas_reboot_nb);
|
||||
for (i = 0; dcdbas_bin_attrs[i]; i++)
|
||||
sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]);
|
||||
sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver dcdbas_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = dcdbas_probe,
|
||||
.remove = __devexit_p(dcdbas_remove),
|
||||
};
|
||||
|
||||
/**
|
||||
* dcdbas_init: initialize driver
|
||||
*/
|
||||
static int __init dcdbas_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = platform_driver_register(&dcdbas_driver);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
dcdbas_pdev = platform_device_alloc(DRIVER_NAME, -1);
|
||||
if (!dcdbas_pdev) {
|
||||
error = -ENOMEM;
|
||||
goto err_unregister_driver;
|
||||
}
|
||||
|
||||
error = platform_device_add(dcdbas_pdev);
|
||||
if (error)
|
||||
goto err_free_device;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_device:
|
||||
platform_device_put(dcdbas_pdev);
|
||||
err_unregister_driver:
|
||||
platform_driver_unregister(&dcdbas_driver);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* dcdbas_exit: perform driver cleanup
|
||||
*/
|
||||
@ -588,6 +645,15 @@ static void __exit dcdbas_exit(void)
|
||||
unregister_reboot_notifier(&dcdbas_reboot_nb);
|
||||
smi_data_buf_free();
|
||||
platform_device_unregister(dcdbas_pdev);
|
||||
platform_driver_unregister(&dcdbas_driver);
|
||||
|
||||
/*
|
||||
* We have to free the buffer here instead of dcdbas_remove
|
||||
* because only in module exit function we can be sure that
|
||||
* all sysfs attributes belonging to this module have been
|
||||
* released.
|
||||
*/
|
||||
smi_data_buf_free();
|
||||
}
|
||||
|
||||
module_init(dcdbas_init);
|
||||
|
@ -533,30 +533,35 @@ static void __clone_and_map(struct clone_info *ci)
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Create two copy bios to deal with io that has
|
||||
* been split across a target.
|
||||
* Handle a bvec that must be split between two or more targets.
|
||||
*/
|
||||
struct bio_vec *bv = bio->bi_io_vec + ci->idx;
|
||||
sector_t remaining = to_sector(bv->bv_len);
|
||||
unsigned int offset = 0;
|
||||
|
||||
clone = split_bvec(bio, ci->sector, ci->idx,
|
||||
bv->bv_offset, max);
|
||||
__map_bio(ti, clone, tio);
|
||||
do {
|
||||
if (offset) {
|
||||
ti = dm_table_find_target(ci->map, ci->sector);
|
||||
max = max_io_len(ci->md, ci->sector, ti);
|
||||
|
||||
ci->sector += max;
|
||||
ci->sector_count -= max;
|
||||
ti = dm_table_find_target(ci->map, ci->sector);
|
||||
tio = alloc_tio(ci->md);
|
||||
tio->io = ci->io;
|
||||
tio->ti = ti;
|
||||
memset(&tio->info, 0, sizeof(tio->info));
|
||||
}
|
||||
|
||||
len = to_sector(bv->bv_len) - max;
|
||||
clone = split_bvec(bio, ci->sector, ci->idx,
|
||||
bv->bv_offset + to_bytes(max), len);
|
||||
tio = alloc_tio(ci->md);
|
||||
tio->io = ci->io;
|
||||
tio->ti = ti;
|
||||
memset(&tio->info, 0, sizeof(tio->info));
|
||||
__map_bio(ti, clone, tio);
|
||||
len = min(remaining, max);
|
||||
|
||||
clone = split_bvec(bio, ci->sector, ci->idx,
|
||||
bv->bv_offset + offset, len);
|
||||
|
||||
__map_bio(ti, clone, tio);
|
||||
|
||||
ci->sector += len;
|
||||
ci->sector_count -= len;
|
||||
offset += to_bytes(len);
|
||||
} while (remaining -= len);
|
||||
|
||||
ci->sector += len;
|
||||
ci->sector_count -= len;
|
||||
ci->idx++;
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ struct cx88_audio_dev {
|
||||
/* audio controls */
|
||||
int irq;
|
||||
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
|
||||
spinlock_t reg_lock;
|
||||
|
||||
@ -82,7 +82,7 @@ struct cx88_audio_dev {
|
||||
struct cx88_buffer *buf;
|
||||
|
||||
long opened;
|
||||
snd_pcm_substream_t *substream;
|
||||
struct snd_pcm_substream *substream;
|
||||
|
||||
};
|
||||
typedef struct cx88_audio_dev snd_cx88_card_t;
|
||||
@ -96,7 +96,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
|
||||
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
||||
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
||||
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
|
||||
static snd_card_t *snd_cx88_cards[SNDRV_CARDS];
|
||||
static struct snd_card *snd_cx88_cards[SNDRV_CARDS];
|
||||
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
|
||||
@ -320,7 +320,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
|
||||
/*
|
||||
* Digital hardware definition
|
||||
*/
|
||||
static snd_pcm_hardware_t snd_cx88_digital_hw = {
|
||||
static struct snd_pcm_hardware snd_cx88_digital_hw = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -342,16 +342,16 @@ static snd_pcm_hardware_t snd_cx88_digital_hw = {
|
||||
/*
|
||||
* audio pcm capture runtime free
|
||||
*/
|
||||
static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime)
|
||||
static void snd_card_cx88_runtime_free(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
}
|
||||
/*
|
||||
* audio pcm capture open callback
|
||||
*/
|
||||
static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
|
||||
static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int err;
|
||||
|
||||
if (test_and_set_bit(0, &chip->opened))
|
||||
@ -380,7 +380,7 @@ _error:
|
||||
/*
|
||||
* audio close callback
|
||||
*/
|
||||
static int snd_cx88_close(snd_pcm_substream_t *substream)
|
||||
static int snd_cx88_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
|
||||
@ -393,8 +393,8 @@ static int snd_cx88_close(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* hw_params callback
|
||||
*/
|
||||
static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
|
||||
snd_pcm_hw_params_t * hw_params)
|
||||
static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
|
||||
struct snd_pcm_hw_params * hw_params)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
struct cx88_buffer *buf;
|
||||
@ -453,7 +453,7 @@ static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
|
||||
/*
|
||||
* hw free callback
|
||||
*/
|
||||
static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
|
||||
static int snd_cx88_hw_free(struct snd_pcm_substream * substream)
|
||||
{
|
||||
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
@ -469,7 +469,7 @@ static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
|
||||
/*
|
||||
* prepare callback
|
||||
*/
|
||||
static int snd_cx88_prepare(snd_pcm_substream_t *substream)
|
||||
static int snd_cx88_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -478,7 +478,7 @@ static int snd_cx88_prepare(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* trigger callback
|
||||
*/
|
||||
static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
|
||||
static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
int err;
|
||||
@ -505,10 +505,10 @@ static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
|
||||
/*
|
||||
* pointer callback
|
||||
*/
|
||||
static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
|
||||
static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
if (chip->read_count) {
|
||||
chip->read_count -= snd_pcm_lib_period_bytes(substream);
|
||||
@ -525,7 +525,7 @@ static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* operators
|
||||
*/
|
||||
static snd_pcm_ops_t snd_cx88_pcm_ops = {
|
||||
static struct snd_pcm_ops snd_cx88_pcm_ops = {
|
||||
.open = snd_cx88_pcm_open,
|
||||
.close = snd_cx88_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@ -542,7 +542,7 @@ static snd_pcm_ops_t snd_cx88_pcm_ops = {
|
||||
static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
|
||||
{
|
||||
int err;
|
||||
snd_pcm_t *pcm;
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
|
||||
if (err < 0)
|
||||
@ -557,7 +557,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
|
||||
/****************************************************************************
|
||||
CONTROL INTERFACE
|
||||
****************************************************************************/
|
||||
static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
|
||||
static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *info)
|
||||
{
|
||||
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
info->count = 1;
|
||||
@ -568,7 +569,8 @@ static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_i
|
||||
}
|
||||
|
||||
/* OK - TODO: test it */
|
||||
static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
|
||||
static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *value)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
struct cx88_core *core=chip->core;
|
||||
@ -579,7 +581,8 @@ static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
|
||||
}
|
||||
|
||||
/* OK - TODO: test it */
|
||||
static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
|
||||
static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *value)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
struct cx88_core *core=chip->core;
|
||||
@ -595,7 +598,7 @@ static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
|
||||
return v != old_control;
|
||||
}
|
||||
|
||||
static snd_kcontrol_new_t snd_cx88_capture_volume = {
|
||||
static struct snd_kcontrol_new snd_cx88_capture_volume = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Capture Volume",
|
||||
.info = snd_cx88_capture_volume_info,
|
||||
@ -641,7 +644,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip)
|
||||
/*
|
||||
* Component Destructor
|
||||
*/
|
||||
static void snd_cx88_dev_free(snd_card_t * card)
|
||||
static void snd_cx88_dev_free(struct snd_card * card)
|
||||
{
|
||||
snd_cx88_card_t *chip = card->private_data;
|
||||
|
||||
@ -654,8 +657,9 @@ static void snd_cx88_dev_free(snd_card_t * card)
|
||||
*/
|
||||
|
||||
static int devno;
|
||||
static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
|
||||
snd_cx88_card_t **rchip)
|
||||
static int __devinit snd_cx88_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
snd_cx88_card_t **rchip)
|
||||
{
|
||||
snd_cx88_card_t *chip;
|
||||
struct cx88_core *core;
|
||||
@ -726,7 +730,7 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
|
||||
static int __devinit cx88_audio_initdev(struct pci_dev *pci,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
snd_cx88_card_t *chip;
|
||||
int err;
|
||||
|
||||
|
@ -71,7 +71,7 @@ MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");
|
||||
*/
|
||||
|
||||
typedef struct snd_card_saa7134 {
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
spinlock_t mixer_lock;
|
||||
int mixer_volume[MIXER_ADDR_LAST+1][2];
|
||||
int capture_source[MIXER_ADDR_LAST+1][2];
|
||||
@ -95,10 +95,10 @@ typedef struct snd_card_saa7134_pcm {
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
snd_pcm_substream_t *substream;
|
||||
struct snd_pcm_substream *substream;
|
||||
} snd_card_saa7134_pcm_t;
|
||||
|
||||
static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
|
||||
static struct snd_card *snd_saa7134_cards[SNDRV_CARDS];
|
||||
|
||||
|
||||
/*
|
||||
@ -251,10 +251,10 @@ out:
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
|
||||
static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream,
|
||||
int cmd)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
|
||||
struct saa7134_dev *dev=pcm->dev;
|
||||
int err = 0;
|
||||
@ -332,9 +332,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int bswap, sign;
|
||||
u32 fmt, control;
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
@ -421,9 +421,10 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
|
||||
*
|
||||
*/
|
||||
|
||||
static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
|
||||
static snd_pcm_uframes_t
|
||||
snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
|
||||
struct saa7134_dev *dev=pcm->dev;
|
||||
|
||||
@ -441,7 +442,7 @@ static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t *
|
||||
* ALSA hardware capabilities definition
|
||||
*/
|
||||
|
||||
static snd_pcm_hardware_t snd_card_saa7134_capture =
|
||||
static struct snd_pcm_hardware snd_card_saa7134_capture =
|
||||
{
|
||||
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -464,7 +465,7 @@ static snd_pcm_hardware_t snd_card_saa7134_capture =
|
||||
.periods_max = 1024,
|
||||
};
|
||||
|
||||
static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
|
||||
static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
|
||||
|
||||
@ -481,8 +482,8 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
|
||||
snd_pcm_hw_params_t * hw_params)
|
||||
static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
|
||||
struct snd_pcm_hw_params * hw_params)
|
||||
{
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
struct saa7134_dev *dev;
|
||||
@ -561,7 +562,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
struct saa7134_dev *dev;
|
||||
@ -587,7 +588,7 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -602,9 +603,9 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_card_saa7134_pcm_t *pcm;
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
struct saa7134_dev *dev = saa7134->dev;
|
||||
@ -640,7 +641,7 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
|
||||
* ALSA capture callbacks definition
|
||||
*/
|
||||
|
||||
static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
|
||||
static struct snd_pcm_ops snd_card_saa7134_capture_ops = {
|
||||
.open = snd_card_saa7134_capture_open,
|
||||
.close = snd_card_saa7134_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@ -661,7 +662,7 @@ static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
|
||||
|
||||
static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
|
||||
@ -679,7 +680,8 @@ static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
|
||||
.get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
|
||||
.private_value = addr }
|
||||
|
||||
static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
|
||||
static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_info * uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 2;
|
||||
@ -688,7 +690,8 @@ static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int addr = kcontrol->private_value;
|
||||
@ -698,7 +701,8 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int change, addr = kcontrol->private_value;
|
||||
@ -729,7 +733,8 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
.get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
|
||||
.private_value = addr }
|
||||
|
||||
static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
|
||||
static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_info * uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 2;
|
||||
@ -738,7 +743,8 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int addr = kcontrol->private_value;
|
||||
@ -751,7 +757,8 @@ static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int change, addr = kcontrol->private_value;
|
||||
@ -828,7 +835,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
return change;
|
||||
}
|
||||
|
||||
static snd_kcontrol_new_t snd_saa7134_controls[] = {
|
||||
static struct snd_kcontrol_new snd_saa7134_controls[] = {
|
||||
SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
|
||||
@ -847,7 +854,7 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
|
||||
|
||||
static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
|
||||
{
|
||||
snd_card_t *card = chip->card;
|
||||
struct snd_card *card = chip->card;
|
||||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
@ -861,7 +868,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_saa7134_free(snd_card_t * card)
|
||||
static void snd_saa7134_free(struct snd_card * card)
|
||||
{
|
||||
snd_card_saa7134_t *chip = card->private_data;
|
||||
|
||||
@ -888,7 +895,7 @@ static void snd_saa7134_free(snd_card_t * card)
|
||||
static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
|
||||
{
|
||||
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
snd_card_saa7134_t *chip;
|
||||
int err;
|
||||
|
||||
|
@ -397,7 +397,7 @@ struct saa7134_dmasound {
|
||||
unsigned int read_offset;
|
||||
unsigned int read_count;
|
||||
void * priv_data;
|
||||
snd_pcm_substream_t *substream;
|
||||
struct snd_pcm_substream *substream;
|
||||
};
|
||||
|
||||
/* IR input */
|
||||
|
@ -9,6 +9,7 @@ config FUSION_SPI
|
||||
tristate "Fusion MPT ScsiHost drivers for SPI"
|
||||
depends on PCI && SCSI
|
||||
select FUSION
|
||||
select SCSI_SPI_ATTRS
|
||||
---help---
|
||||
SCSI HOST support for a parallel SCSI host adapters.
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_SG
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_VERBOSE_EVENTS
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
|
||||
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
|
||||
|
@ -3,38 +3,11 @@
|
||||
* *
|
||||
* Copyright 2003 LSI Logic Corporation. All rights reserved. *
|
||||
* *
|
||||
* This file is confidential and a trade secret of LSI Logic. The *
|
||||
* receipt of or possession of this file does not convey any rights to *
|
||||
* reproduce or disclose its contents or to manufacture, use, or sell *
|
||||
* anything it may describe, in whole, or in part, without the specific *
|
||||
* written consent of LSI Logic Corporation. *
|
||||
* Description *
|
||||
* ------------ *
|
||||
* This include file contains SAS firmware interface IOC Log Info codes *
|
||||
* *
|
||||
***************************************************************************
|
||||
*
|
||||
* Name: iopiIocLogInfo.h
|
||||
* Title: SAS Firmware IOP Interface IOC Log Info Definitions
|
||||
* Programmer: Guy Kendall
|
||||
* Creation Date: September 24, 2003
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
*
|
||||
* Last Updated
|
||||
* -------------
|
||||
* Version %version: 22 %
|
||||
* Date Updated %date_modified: %
|
||||
* Programmer %created_by: nperucca %
|
||||
*
|
||||
* Date Who Description
|
||||
* -------- --- -------------------------------------------------------
|
||||
* 09/24/03 GWK Initial version
|
||||
*
|
||||
*
|
||||
* Description
|
||||
* ------------
|
||||
* This include file contains SAS firmware interface IOC Log Info codes
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*-------------------------------------------------------------------------*
|
||||
*/
|
||||
|
||||
#ifndef IOPI_IOCLOGINFO_H_INCLUDED
|
||||
@ -57,6 +30,8 @@
|
||||
#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)
|
||||
#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)
|
||||
|
||||
#define IOC_LOGINFO_ORIGINATOR_MASK (0x0F000000)
|
||||
|
||||
/****************************************************************************/
|
||||
/* LOGINFO_CODE defines */
|
||||
/****************************************************************************/
|
||||
@ -78,11 +53,27 @@
|
||||
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
|
||||
#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
|
||||
|
||||
#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
|
||||
#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */
|
||||
|
||||
#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001)
|
||||
#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002)
|
||||
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003)
|
||||
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
|
||||
#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
|
||||
|
||||
/****************************************************************************/
|
||||
/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
|
||||
/****************************************************************************/
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
|
||||
#define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B)
|
||||
#define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C)
|
||||
#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
|
||||
#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
|
||||
#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
|
||||
@ -97,6 +88,7 @@
|
||||
#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
|
||||
#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
|
||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
|
||||
#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */
|
||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
|
||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
|
||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
|
||||
@ -105,11 +97,23 @@
|
||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
|
||||
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
|
||||
#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
|
||||
#define PL_LOGINFO_CODE_RESET (0x00110000)
|
||||
#define PL_LOGINFO_CODE_ABORT (0x00120000)
|
||||
#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */
|
||||
#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */
|
||||
#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
|
||||
#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
|
||||
#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
|
||||
#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B)
|
||||
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */
|
||||
|
||||
#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120)
|
||||
#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */
|
||||
#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */
|
||||
|
||||
|
||||
#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
|
||||
#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
|
||||
#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
|
||||
@ -123,26 +127,39 @@
|
||||
#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
|
||||
#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
|
||||
#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
|
||||
#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
|
||||
#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
|
||||
#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
|
||||
|
||||
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */
|
||||
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */
|
||||
|
||||
#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
|
||||
#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
|
||||
#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
|
||||
#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
|
||||
#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */
|
||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */
|
||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */
|
||||
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */
|
||||
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/
|
||||
#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */
|
||||
#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */
|
||||
#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */
|
||||
#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */
|
||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */
|
||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */
|
||||
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */
|
||||
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/
|
||||
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -180,6 +180,7 @@ static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
|
||||
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
|
||||
static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
|
||||
|
||||
/* module entry point */
|
||||
static int __init fusion_init (void);
|
||||
@ -428,7 +429,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||
results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
|
||||
if (results != evHandlers) {
|
||||
/* CHECKME! Any special handling needed here? */
|
||||
devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
|
||||
devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
|
||||
ioc->name, evHandlers, results));
|
||||
}
|
||||
|
||||
@ -438,10 +439,10 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
|
||||
*/
|
||||
if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
|
||||
freereq = 0;
|
||||
devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
|
||||
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
|
||||
ioc->name, pEvReply));
|
||||
} else {
|
||||
devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
|
||||
devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
|
||||
ioc->name, pEvReply));
|
||||
}
|
||||
|
||||
@ -1120,65 +1121,6 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
|
||||
{
|
||||
int loop_count = 30 * 4; /* Wait 30 seconds */
|
||||
int status = -1; /* -1 means failed to get board READY */
|
||||
|
||||
do {
|
||||
spin_lock(&ioc->initializing_hba_lock);
|
||||
if (ioc->initializing_hba_lock_flag == 0) {
|
||||
ioc->initializing_hba_lock_flag=1;
|
||||
spin_unlock(&ioc->initializing_hba_lock);
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
spin_unlock(&ioc->initializing_hba_lock);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(HZ/4);
|
||||
} while (--loop_count);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
|
||||
* @ioc: Pointer to MPT adapter structure
|
||||
* @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
|
||||
*
|
||||
* This routine performs all the steps necessary to bring the IOC
|
||||
* to a OPERATIONAL state.
|
||||
*
|
||||
* Special Note: This function was added with spin lock's so as to allow
|
||||
* the dv(domain validation) work thread to succeed on the other channel
|
||||
* that maybe occuring at the same time when this function is called.
|
||||
* Without this lock, the dv would fail when message frames were
|
||||
* requested during hba bringup on the alternate ioc.
|
||||
*/
|
||||
static int
|
||||
mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
|
||||
{
|
||||
int r;
|
||||
|
||||
if(ioc->alt_ioc) {
|
||||
if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
|
||||
return r;
|
||||
}
|
||||
|
||||
r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
|
||||
CAN_SLEEP);
|
||||
|
||||
if(ioc->alt_ioc) {
|
||||
spin_lock(&ioc->alt_ioc->initializing_hba_lock);
|
||||
ioc->alt_ioc->initializing_hba_lock_flag=0;
|
||||
spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mpt_attach - Install a PCI intelligent MPT adapter.
|
||||
@ -1482,7 +1424,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
*/
|
||||
mpt_detect_bound_ports(ioc, pdev);
|
||||
|
||||
if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){
|
||||
if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
|
||||
CAN_SLEEP)) != 0){
|
||||
printk(KERN_WARNING MYNAM
|
||||
": WARNING - %s did not initialize properly! (%d)\n",
|
||||
ioc->name, r);
|
||||
@ -1629,7 +1572,6 @@ mpt_resume(struct pci_dev *pdev)
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
u32 device_state = pdev->current_state;
|
||||
int recovery_state;
|
||||
int ii;
|
||||
|
||||
printk(MYIOC_s_INFO_FMT
|
||||
"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
|
||||
@ -1643,14 +1585,6 @@ mpt_resume(struct pci_dev *pdev)
|
||||
CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
|
||||
ioc->active = 1;
|
||||
|
||||
/* F/W not running */
|
||||
if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
|
||||
/* enable domain validation flags */
|
||||
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
|
||||
ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
|
||||
}
|
||||
}
|
||||
|
||||
printk(MYIOC_s_INFO_FMT
|
||||
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
|
||||
ioc->name,
|
||||
@ -4938,7 +4872,7 @@ done_and_free:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
|
||||
{
|
||||
IOCPage3_t *pIoc3;
|
||||
@ -5146,13 +5080,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
|
||||
|
||||
evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
|
||||
if (evnp == NULL) {
|
||||
devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
|
||||
devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
|
||||
ioc->name));
|
||||
return 0;
|
||||
}
|
||||
memset(evnp, 0, sizeof(*evnp));
|
||||
|
||||
devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
|
||||
devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
|
||||
|
||||
evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
|
||||
evnp->ChainOffset = 0;
|
||||
@ -5907,24 +5841,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
|
||||
break;
|
||||
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
||||
{
|
||||
char buf[50];
|
||||
u8 id = (u8)(evData0);
|
||||
u8 ReasonCode = (u8)(evData0 >> 16);
|
||||
switch (ReasonCode) {
|
||||
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
|
||||
ds = "SAS Device Status Change: Added";
|
||||
sprintf(buf,"SAS Device Status Change: Added: id=%d", id);
|
||||
break;
|
||||
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
|
||||
ds = "SAS Device Status Change: Deleted";
|
||||
sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id);
|
||||
break;
|
||||
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
|
||||
ds = "SAS Device Status Change: SMART Data";
|
||||
sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id);
|
||||
break;
|
||||
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
|
||||
ds = "SAS Device Status Change: No Persistancy Added";
|
||||
sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id);
|
||||
break;
|
||||
default:
|
||||
ds = "SAS Device Status Change: Unknown";
|
||||
sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id);
|
||||
break;
|
||||
}
|
||||
ds = buf;
|
||||
break;
|
||||
}
|
||||
case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
|
||||
@ -5940,11 +5877,97 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
|
||||
ds = "Persistent Table Full";
|
||||
break;
|
||||
case MPI_EVENT_SAS_PHY_LINK_STATUS:
|
||||
ds = "SAS PHY Link Status";
|
||||
{
|
||||
char buf[50];
|
||||
u8 LinkRates = (u8)(evData0 >> 8);
|
||||
u8 PhyNumber = (u8)(evData0);
|
||||
LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
|
||||
MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
|
||||
switch (LinkRates) {
|
||||
case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||
" Rate Unknown",PhyNumber);
|
||||
break;
|
||||
case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||
" Phy Disabled",PhyNumber);
|
||||
break;
|
||||
case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||
" Failed Speed Nego",PhyNumber);
|
||||
break;
|
||||
case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||
" Sata OOB Completed",PhyNumber);
|
||||
break;
|
||||
case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||
" Rate 1.5 Gbps",PhyNumber);
|
||||
break;
|
||||
case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d:"
|
||||
" Rate 3.0 Gpbs",PhyNumber);
|
||||
break;
|
||||
default:
|
||||
sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber);
|
||||
break;
|
||||
}
|
||||
ds = buf;
|
||||
break;
|
||||
}
|
||||
case MPI_EVENT_SAS_DISCOVERY_ERROR:
|
||||
ds = "SAS Discovery Error";
|
||||
break;
|
||||
case MPI_EVENT_IR_RESYNC_UPDATE:
|
||||
{
|
||||
u8 resync_complete = (u8)(evData0 >> 16);
|
||||
char buf[40];
|
||||
sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete);
|
||||
ds = buf;
|
||||
break;
|
||||
}
|
||||
case MPI_EVENT_IR2:
|
||||
{
|
||||
u8 ReasonCode = (u8)(evData0 >> 16);
|
||||
switch (ReasonCode) {
|
||||
case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
|
||||
ds = "IR2: LD State Changed";
|
||||
break;
|
||||
case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
|
||||
ds = "IR2: PD State Changed";
|
||||
break;
|
||||
case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
|
||||
ds = "IR2: Bad Block Table Full";
|
||||
break;
|
||||
case MPI_EVENT_IR2_RC_PD_INSERTED:
|
||||
ds = "IR2: PD Inserted";
|
||||
break;
|
||||
case MPI_EVENT_IR2_RC_PD_REMOVED:
|
||||
ds = "IR2: PD Removed";
|
||||
break;
|
||||
case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
|
||||
ds = "IR2: Foreign CFG Detected";
|
||||
break;
|
||||
case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
|
||||
ds = "IR2: Rebuild Medium Error";
|
||||
break;
|
||||
default:
|
||||
ds = "IR2";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPI_EVENT_SAS_DISCOVERY:
|
||||
{
|
||||
if (evData0)
|
||||
ds = "SAS Discovery: Start";
|
||||
else
|
||||
ds = "SAS Discovery: Stop";
|
||||
break;
|
||||
}
|
||||
case MPI_EVENT_LOG_ENTRY_ADDED:
|
||||
ds = "SAS Log Entry Added";
|
||||
break;
|
||||
|
||||
/*
|
||||
* MPT base "custom" events may be added here...
|
||||
@ -5989,12 +6012,12 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
|
||||
}
|
||||
|
||||
EventDescriptionStr(event, evData0, evStr);
|
||||
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
|
||||
devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
|
||||
ioc->name,
|
||||
evStr,
|
||||
event));
|
||||
event,
|
||||
evStr));
|
||||
|
||||
#if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
|
||||
#if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
|
||||
printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
|
||||
for (ii = 0; ii < evDataLen; ii++)
|
||||
printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
|
||||
@ -6053,7 +6076,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
|
||||
*/
|
||||
for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
|
||||
if (MptEvHandlers[ii]) {
|
||||
devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
|
||||
devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
|
||||
ioc->name, ii));
|
||||
r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
|
||||
handlers++;
|
||||
@ -6065,10 +6088,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
|
||||
* If needed, send (a single) EventAck.
|
||||
*/
|
||||
if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
|
||||
devtprintk((MYIOC_s_WARN_FMT
|
||||
devtverboseprintk((MYIOC_s_WARN_FMT
|
||||
"EventAck required\n",ioc->name));
|
||||
if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
|
||||
devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
|
||||
devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
|
||||
ioc->name, ii));
|
||||
}
|
||||
}
|
||||
@ -6205,8 +6228,8 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
|
||||
"Abort", /* 12h */
|
||||
"IO Not Yet Executed", /* 13h */
|
||||
"IO Executed", /* 14h */
|
||||
NULL, /* 15h */
|
||||
NULL, /* 16h */
|
||||
"Persistant Reservation Out Not Affiliation Owner", /* 15h */
|
||||
"Open Transmit DMA Abort", /* 16h */
|
||||
NULL, /* 17h */
|
||||
NULL, /* 18h */
|
||||
NULL, /* 19h */
|
||||
@ -6431,11 +6454,9 @@ EXPORT_SYMBOL(mpt_stm_index);
|
||||
EXPORT_SYMBOL(mpt_HardResetHandler);
|
||||
EXPORT_SYMBOL(mpt_config);
|
||||
EXPORT_SYMBOL(mpt_findImVolumes);
|
||||
EXPORT_SYMBOL(mpt_read_ioc_pg_3);
|
||||
EXPORT_SYMBOL(mpt_alloc_fw_memory);
|
||||
EXPORT_SYMBOL(mpt_free_fw_memory);
|
||||
EXPORT_SYMBOL(mptbase_sas_persist_operation);
|
||||
EXPORT_SYMBOL(mpt_alt_ioc_wait);
|
||||
EXPORT_SYMBOL(mptbase_GetFcPortPage0);
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user