@@ -1041,10 +1030,6 @@ running once the system is up.
irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned
automatically to PCI devices. You can make the kernel
exclude IRQs of your ISA cards this way.
- pirqaddr=0xAAAAA [IA-32] Specify the physical address
- of the PIRQ table (normally generated
- by the BIOS) if it is outside the
- F0000h-100000h range.
lastbus=N [IA-32] Scan all buses till bus #N. Can be useful
if the kernel is unable to find your secondary buses
and you want to tell it explicitly which ones they are.
diff --git a/trunk/Documentation/pcmcia/devicetable.txt b/trunk/Documentation/pcmcia/devicetable.txt
index 3351c0355143..045511acafc9 100644
--- a/trunk/Documentation/pcmcia/devicetable.txt
+++ b/trunk/Documentation/pcmcia/devicetable.txt
@@ -19,8 +19,9 @@ PCMCIA_DEVICE_PROD_ID1("some_string", 0x(hash_of_some_string)),
If the hash is incorrect, the kernel will inform you about this in "dmesg"
upon module initialization, and tell you of the correct hash.
-You can determine the hash of the product ID strings by catting the file
-"modalias" in the sysfs directory of the PCMCIA device. It generates a string
+You can determine the hash of the product ID strings by running
+"pcmcia-modalias %n.%m" [%n being replaced with the socket number and %m being
+replaced with the device function] from pcmciautils. It generates a string
in the following form:
pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000
diff --git a/trunk/Documentation/serial/driver b/trunk/Documentation/serial/driver
index ac7eabbf662a..e9c0178cd202 100644
--- a/trunk/Documentation/serial/driver
+++ b/trunk/Documentation/serial/driver
@@ -107,8 +107,8 @@ hardware.
indicate that the signal is permanently active. If RI is
not available, the signal should not be indicated as active.
- Locking: port->lock taken.
- Interrupts: locally disabled.
+ Locking: none.
+ Interrupts: caller dependent.
This call must not sleep
stop_tx(port,tty_stop)
diff --git a/trunk/Documentation/video4linux/API.html b/trunk/Documentation/video4linux/API.html
index 441407b12a9f..4b3d8f640a4a 100644
--- a/trunk/Documentation/video4linux/API.html
+++ b/trunk/Documentation/video4linux/API.html
@@ -1,16 +1,399 @@
-V4L API
-Video For Linux APIs
-
+
+Video4Linux Kernel API Reference v0.1:19990430
+
+
+
+
+
+Devices
+Video4Linux provides the following sets of device files. These live on the
+character device formerly known as "/dev/bttv". /dev/bttv should be a
+symlink to /dev/video0 for most people.
+
+
+Device Name | Minor Range | Function |
+
---|
/dev/video | 0-63 | Video Capture Interface |
+
/dev/radio | 64-127 | AM/FM Radio Devices |
+
/dev/vtx | 192-223 | Teletext Interface Chips |
+
/dev/vbi | 224-239 | Raw VBI Data (Intercast/teletext) |
+
+
+Video4Linux programs open and scan the devices to find what they are looking
+for. Capability queries define what each interface supports. The
+described API is only defined for video capture cards. The relevant subset
+applies to radio cards. Teletext interfaces talk the existing VTX API.
+
+
Capability Query Ioctl
+The VIDIOCGCAP ioctl call is used to obtain the capability
+information for a video device. The struct video_capability object
+passed to the ioctl is completed and returned. It contains the following
+information
+
+
+name[32] | Canonical name for this interface |
+
type | Type of interface |
+
channels | Number of radio/tv channels if appropriate |
+
audios | Number of audio devices if appropriate |
+
maxwidth | Maximum capture width in pixels |
+
maxheight | Maximum capture height in pixels |
+
minwidth | Minimum capture width in pixels |
+
minheight | Minimum capture height in pixels |
+
+
+The type field lists the capability flags for the device. These are
+as follows
+
+
+Name | Description |
+
---|
VID_TYPE_CAPTURE | Can capture to memory |
+
VID_TYPE_TUNER | Has a tuner of some form |
+
VID_TYPE_TELETEXT | Has teletext capability |
+
VID_TYPE_OVERLAY | Can overlay its image onto the frame buffer |
+
VID_TYPE_CHROMAKEY | Overlay is Chromakeyed |
+
VID_TYPE_CLIPPING | Overlay clipping is supported |
+
VID_TYPE_FRAMERAM | Overlay overwrites frame buffer memory |
+
VID_TYPE_SCALES | The hardware supports image scaling |
+
VID_TYPE_MONOCHROME | Image capture is grey scale only |
+
VID_TYPE_SUBCAPTURE | Capture can be of only part of the image |
+
+
+The minimum and maximum sizes listed for a capture device do not imply all
+that all height/width ratios or sizes within the range are possible. A
+request to set a size will be honoured by the largest available capture
+size whose capture is no large than the requested rectangle in either
+direction. For example the quickcam has 3 fixed settings.
+
+
Frame Buffer
+Capture cards that drop data directly onto the frame buffer must be told the
+base address of the frame buffer, its size and organisation. This is a
+privileged ioctl and one that eventually X itself should set.
+
+The VIDIOCSFBUF ioctl sets the frame buffer parameters for a capture
+card. If the card does not do direct writes to the frame buffer then this
+ioctl will be unsupported. The VIDIOCGFBUF ioctl returns the
+currently used parameters. The structure used in both cases is a
+struct video_buffer.
+
+
+void *base | Base physical address of the buffer |
+
int height | Height of the frame buffer |
+
int width | Width of the frame buffer |
+
int depth | Depth of the frame buffer |
+
int bytesperline | Number of bytes of memory between the start of two adjacent lines |
+
+
+Note that these values reflect the physical layout of the frame buffer.
+The visible area may be smaller. In fact under XFree86 this is commonly the
+case. XFree86 DGA can provide the parameters required to set up this ioctl.
+Setting the base address to NULL indicates there is no physical frame buffer
+access.
+
+
Capture Windows
+The capture area is described by a struct video_window. This defines
+a capture area and the clipping information if relevant. The
+VIDIOCGWIN ioctl recovers the current settings and the
+VIDIOCSWIN sets new values. A successful call to VIDIOCSWIN
+indicates that a suitable set of parameters have been chosen. They do not
+indicate that exactly what was requested was granted. The program should
+call VIDIOCGWIN to check if the nearest match was suitable. The
+struct video_window contains the following fields.
+
+
+x | The X co-ordinate specified in X windows format. |
+
y | The Y co-ordinate specified in X windows format. |
+
width | The width of the image capture. |
+
height | The height of the image capture. |
+
chromakey | A host order RGB32 value for the chroma key. |
+
flags | Additional capture flags. |
+
clips | A list of clipping rectangles. (Set only) |
+
clipcount | The number of clipping rectangles. (Set only) |
+
+
+Clipping rectangles are passed as an array. Each clip consists of the following
+fields available to the user.
+
+
+x | X co-ordinate of rectangle to skip |
+
y | Y co-ordinate of rectangle to skip |
+
width | Width of rectangle to skip |
+
height | Height of rectangle to skip |
+
+
+Merely setting the window does not enable capturing. Overlay capturing
+(i.e. PCI-PCI transfer to the frame buffer of the video card)
+is activated by passing the VIDIOCCAPTURE ioctl a value of 1, and
+disabled by passing it a value of 0.
+
+Some capture devices can capture a subfield of the image they actually see.
+This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
+The video_capture describes the time and special subfields to capture.
+The video_capture structure contains the following fields.
+
+
+x | X co-ordinate of source rectangle to grab |
+
y | Y co-ordinate of source rectangle to grab |
+
width | Width of source rectangle to grab |
+
height | Height of source rectangle to grab |
+
decimation | Decimation to apply |
+
flags | Flag settings for grabbing |
+
+The available flags are
+
+
+Name | Description |
+
---|
VIDEO_CAPTURE_ODD | Capture only odd frames |
+
VIDEO_CAPTURE_EVEN | Capture only even frames |
+
+
+
Video Sources
+Each video4linux video or audio device captures from one or more
+source channels. Each channel can be queries with the
+VDIOCGCHAN ioctl call. Before invoking this function the caller
+must set the channel field to the channel that is being queried. On return
+the struct video_channel is filled in with information about the
+nature of the channel itself.
+
+The VIDIOCSCHAN ioctl takes an integer argument and switches the
+capture to this input. It is not defined whether parameters such as colour
+settings or tuning are maintained across a channel switch. The caller should
+maintain settings as desired for each channel. (This is reasonable as
+different video inputs may have different properties).
+
+The struct video_channel consists of the following
+
+
+channel | The channel number |
+
name | The input name - preferably reflecting the label
+on the card input itself |
+
tuners | Number of tuners for this input |
+
flags | Properties the tuner has |
+
type | Input type (if known) |
+
norm | The norm for this channel |
+
+
+The flags defined are
+
+
+VIDEO_VC_TUNER | Channel has tuners. |
+
VIDEO_VC_AUDIO | Channel has audio. |
+
VIDEO_VC_NORM | Channel has norm setting. |
+
+
+The types defined are
+
+
+VIDEO_TYPE_TV | The input is a TV input. |
+
VIDEO_TYPE_CAMERA | The input is a camera. |
+
+
+
Image Properties
+The image properties of the picture can be queried with the VIDIOCGPICT
+ioctl which fills in a struct video_picture. The VIDIOCSPICT
+ioctl allows values to be changed. All values except for the palette type
+are scaled between 0-65535.
+
+The struct video_picture consists of the following fields
+
+
+brightness | Picture brightness |
+
hue | Picture hue (colour only) |
+
colour | Picture colour (colour only) |
+
contrast | Picture contrast |
+
whiteness | The whiteness (greyscale only) |
+
depth | The capture depth (may need to match the frame buffer depth) |
+
palette | Reports the palette that should be used for this image |
+
+
+The following palettes are defined
+
+
+VIDEO_PALETTE_GREY | Linear intensity grey scale (255 is brightest). |
+
VIDEO_PALETTE_HI240 | The BT848 8bit colour cube. |
+
VIDEO_PALETTE_RGB565 | RGB565 packed into 16 bit words. |
+
VIDEO_PALETTE_RGB555 | RGV555 packed into 16 bit words, top bit undefined. |
+
VIDEO_PALETTE_RGB24 | RGB888 packed into 24bit words. |
+
VIDEO_PALETTE_RGB32 | RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined. |
+
VIDEO_PALETTE_YUV422 | Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V |
+
VIDEO_PALETTE_YUYV | Describe me |
+
VIDEO_PALETTE_UYVY | Describe me |
+
VIDEO_PALETTE_YUV420 | YUV420 capture |
+
VIDEO_PALETTE_YUV411 | YUV411 capture |
+
VIDEO_PALETTE_RAW | RAW capture (BT848) |
+
VIDEO_PALETTE_YUV422P | YUV 4:2:2 Planar |
+
VIDEO_PALETTE_YUV411P | YUV 4:1:1 Planar |
+
+
+
Tuning
+Each video input channel can have one or more tuners associated with it. Many
+devices will not have tuners. TV cards and radio cards will have one or more
+tuners attached.
+
+Tuners are described by a struct video_tuner which can be obtained by
+the VIDIOCGTUNER ioctl. Fill in the tuner number in the structure
+then pass the structure to the ioctl to have the data filled in. The
+tuner can be switched using VIDIOCSTUNER which takes an integer argument
+giving the tuner to use. A struct tuner has the following fields
+
+
+tuner | Number of the tuner |
+
name | Canonical name for this tuner (eg FM/AM/TV) |
+
rangelow | Lowest tunable frequency |
+
rangehigh | Highest tunable frequency |
+
flags | Flags describing the tuner |
+
mode | The video signal mode if relevant |
+
signal | Signal strength if known - between 0-65535 |
+
+
+The following flags exist
+
+
+VIDEO_TUNER_PAL | PAL tuning is supported |
+
VIDEO_TUNER_NTSC | NTSC tuning is supported |
+
VIDEO_TUNER_SECAM | SECAM tuning is supported |
+
VIDEO_TUNER_LOW | Frequency is in a lower range |
+
VIDEO_TUNER_NORM | The norm for this tuner is settable |
+
VIDEO_TUNER_STEREO_ON | The tuner is seeing stereo audio |
+
VIDEO_TUNER_RDS_ON | The tuner is seeing a RDS datastream |
+
VIDEO_TUNER_MBS_ON | The tuner is seeing a MBS datastream |
+
+
+The following modes are defined
+
+
+VIDEO_MODE_PAL | The tuner is in PAL mode |
+
VIDEO_MODE_NTSC | The tuner is in NTSC mode |
+
VIDEO_MODE_SECAM | The tuner is in SECAM mode |
+
VIDEO_MODE_AUTO | The tuner auto switches, or mode does not apply |
+
+
+Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the
+VIDEO_TUNER_LOW flag is set they are in 1/16th KHz. The current
+frequency is obtained as an unsigned long via the VIDIOCGFREQ ioctl and
+set by the VIDIOCSFREQ ioctl.
+
+
Audio
+TV and Radio devices have one or more audio inputs that may be selected.
+The audio properties are queried by passing a struct video_audio to VIDIOCGAUDIO ioctl. The
+VIDIOCSAUDIO ioctl sets audio properties.
+
+The structure contains the following fields
+
+
+audio | The channel number |
+
volume | The volume level |
+
bass | The bass level |
+
treble | The treble level |
+
flags | Flags describing the audio channel |
+
name | Canonical name for the audio input |
+
mode | The mode the audio input is in |
+
balance | The left/right balance |
+
step | Actual step used by the hardware |
+
+
+The following flags are defined
+
+
+VIDEO_AUDIO_MUTE | The audio is muted |
+
VIDEO_AUDIO_MUTABLE | Audio muting is supported |
+
VIDEO_AUDIO_VOLUME | The volume is controllable |
+
VIDEO_AUDIO_BASS | The bass is controllable |
+
VIDEO_AUDIO_TREBLE | The treble is controllable |
+
VIDEO_AUDIO_BALANCE | The balance is controllable |
+
+
+The following decoding modes are defined
+
+
+VIDEO_SOUND_MONO | Mono signal |
+
VIDEO_SOUND_STEREO | Stereo signal (NICAM for TV) |
+
VIDEO_SOUND_LANG1 | European TV alternate language 1 |
+
VIDEO_SOUND_LANG2 | European TV alternate language 2 |
+
+
+
Reading Images
+Each call to the read syscall returns the next available image
+from the device. It is up to the caller to set format and size (using
+the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable
+size buffer and length to the function. Not all devices will support
+read operations.
+
+A second way to handle image capture is via the mmap interface if supported.
+To use the mmap interface a user first sets the desired image size and depth
+properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
+of buffer to mmap and the offset within the buffer for each frame. The
+number of frames supported is device dependent and may only be one.
+
+The video_mbuf structure contains the following fields
+
+
+size | The number of bytes to map |
+
frames | The number of frames |
+
offsets | The offset of each frame |
+
+
+Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the
+capture to a frame using the format and image size specified in the
+video_mmap (which should match or be below the initial query size).
+When the VIDIOCMCAPTURE ioctl returns the frame is not
+captured yet, the driver just instructed the hardware to start the
+capture. The application has to use the VIDIOCSYNC ioctl to wait
+until the capture of a frame is finished. VIDIOCSYNC takes the frame
+number you want to wait for as argument.
+
+It is allowed to call VIDIOCMCAPTURE multiple times (with different
+frame numbers in video_mmap->frame of course) and thus have multiple
+outstanding capture requests. A simple way do to double-buffering
+using this feature looks like this:
+
+/* setup everything */
+VIDIOCMCAPTURE(0)
+while (whatever) {
+ VIDIOCMCAPTURE(1)
+ VIDIOCSYNC(0)
+ /* process frame 0 while the hardware captures frame 1 */
+ VIDIOCMCAPTURE(0)
+ VIDIOCSYNC(1)
+ /* process frame 1 while the hardware captures frame 0 */
+}
+
+Note that you are not limited to only two frames. The API
+allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of
+frames the driver granted. Thus it is possible to build deeper queues
+to avoid loosing frames on load peaks.
+
+While capturing to memory the driver will make a "best effort" attempt
+to capture to screen as well if requested. This normally means all
+frames that "miss" memory mapped capture will go to the display.
+
+A final ioctl exists to allow a device to obtain related devices if a
+driver has multiple components (for example video0 may not be associated
+with vbi0 which would cause an intercast display program to make a bad
+mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated
+devices if any exist. The video_unit structure has the following fields.
+
+
+video | Video capture device |
+
vbi | VBI capture device |
+
radio | Radio device |
+
audio | Audio mixer |
+
teletext | Teletext device |
+
+
+
RDS Datastreams
+For radio devices that support it, it is possible to receive Radio Data
+System (RDS) data by means of a read() on the device. The data is packed in
+groups of three, as follows:
+
+First Octet | Least Significant Byte of RDS Block |
+Second Octet | Most Significant Byte of RDS Block
+ |
Third Octet | Bit 7: | Error bit. Indicates that
+an uncorrectable error occurred during reception of this block. |
+ | Bit 6: | Corrected bit. Indicates that
+an error was corrected for this data block. |
+ | Bits 5-3: | Received Offset. Indicates the
+offset received by the sync system. |
+ | Bits 2-0: | Offset Name. Indicates the
+offset applied to this data. |
+
+
+
diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88
index 4377aa11f567..216f705495cc 100644
--- a/trunk/Documentation/video4linux/CARDLIST.cx88
+++ b/trunk/Documentation/video4linux/CARDLIST.cx88
@@ -13,17 +13,17 @@ card=11 - Prolink PlayTV PVR
card=12 - ASUS PVR-416
card=13 - MSI TV-@nywhere
card=14 - KWorld/VStream XPert DVB-T
-card=15 - DViCO FusionHDTV DVB-T1
+card=15 - DVICO FusionHDTV DVB-T1
card=16 - KWorld LTV883RF
-card=17 - DViCO FusionHDTV 3 Gold-Q
+card=17 - DViCO - FusionHDTV 3 Gold
card=18 - Hauppauge Nova-T DVB-T
card=19 - Conexant DVB-T reference design
card=20 - Provideo PV259
-card=21 - DViCO FusionHDTV DVB-T Plus
+card=21 - DVICO FusionHDTV DVB-T Plus
card=22 - digitalnow DNTV Live! DVB-T
card=23 - pcHDTV HD3000 HDTV
card=24 - Hauppauge WinTV 28xxx (Roslyn) models
card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
card=26 - IODATA GV/BCTV7E
card=27 - PixelView PlayTV Ultra Pro (Stereo)
-card=28 - DViCO FusionHDTV 3 Gold-T
+card=28 - DViCO - FusionHDTV 3 Gold-T
diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134
index 735e8ba02d9f..d5ed95d28500 100644
--- a/trunk/Documentation/video4linux/CARDLIST.saa7134
+++ b/trunk/Documentation/video4linux/CARDLIST.saa7134
@@ -54,9 +54,3 @@
55 -> LifeView FlyDVB-T DUO [5168:0306]
56 -> Avermedia AVerTV 307 [1461:a70a]
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
- 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370]
- 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
- 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus
- 61 -> Philips TOUGH DVB-T reference design
- 62 -> Compro VideoMate TV Gold+II
- 63 -> Kworld Xpert TV PVR7134
diff --git a/trunk/Documentation/video4linux/CARDLIST.tuner b/trunk/Documentation/video4linux/CARDLIST.tuner
index e78020f68b2e..aeb8df8ce890 100644
--- a/trunk/Documentation/video4linux/CARDLIST.tuner
+++ b/trunk/Documentation/video4linux/CARDLIST.tuner
@@ -59,6 +59,3 @@ tuner=57 - Philips FQ1236A MK4
tuner=58 - Ymec TVision TVF-8531MF
tuner=59 - Ymec TVision TVF-5533MF
tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
-tuner=61 - Tena TNF9533-D/IF
-tuner=62 - Philips TEA5767HN FM Radio
-tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
diff --git a/trunk/Documentation/video4linux/README.saa7134 b/trunk/Documentation/video4linux/README.saa7134
index 1f788e498eff..1a446c65365e 100644
--- a/trunk/Documentation/video4linux/README.saa7134
+++ b/trunk/Documentation/video4linux/README.saa7134
@@ -57,15 +57,6 @@ Cards can use either of these two crystals (xtal):
- 24.576MHz -> .audio_clock=0x200000
(xtal * .audio_clock = 51539600)
-Some details about 30/34/35:
-
- - saa7130 - low-price chip, doesn't have mute, that is why all those
- cards should have .mute field defined in their tuner structure.
-
- - saa7134 - usual chip
-
- - saa7133/35 - saa7135 is probably a marketing decision, since all those
- chips identifies itself as 33 on pci.
Credits
=======
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 19a9a1c53037..4db63de9652a 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -512,11 +512,11 @@ W: http://linuxppc64.org
S: Supported
BTTV VIDEO4LINUX DRIVER
-P: Mauro Carvalho Chehab
-M: mchehab@brturbo.com.br
+P: Gerd Knorr
+M: kraxel@bytesex.org
L: video4linux-list@redhat.com
-W: http://linuxtv.org
-S: Maintained
+W: http://bytesex.org/bttv/
+S: Orphan
BUSLOGIC SCSI DRIVER
P: Leonard N. Zubkoff
@@ -2625,11 +2625,10 @@ W: http://rio500.sourceforge.net
S: Maintained
VIDEO FOR LINUX
-P: Mauro Carvalho Chehab
-M: mchehab@brturbo.com.br
+P: Gerd Knorr
+M: kraxel@bytesex.org
L: video4linux-list@redhat.com
-W: http://linuxtv.org
-S: Maintained
+S: Orphan
W1 DALLAS'S 1-WIRE BUS
P: Evgeniy Polyakov
diff --git a/trunk/Makefile b/trunk/Makefile
index 77aab7bdde01..1fdace757e15 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 13
-EXTRAVERSION =-rc1
+SUBLEVEL = 12
+EXTRAVERSION =
NAME=Woozy Numbat
# *DOCUMENTATION*
diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig
index 620f2ca94ed2..c8d94dcd8ef7 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -361,11 +361,6 @@ config NO_IDLE_HZ
Alternatively, if you want dynamic tick automatically enabled
during boot, pass "dyntick=enable" via the kernel command string.
- Please note that dynamic tick may affect the accuracy of
- timekeeping on some platforms depending on the implementation.
- Currently at least OMAP platform is known to have accurate
- timekeeping with dynamic tick.
-
config ARCH_DISCONTIGMEM_ENABLE
bool
default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
diff --git a/trunk/arch/arm/kernel/armksyms.c b/trunk/arch/arm/kernel/armksyms.c
index b713c44c6fb4..4c38bd8bc298 100644
--- a/trunk/arch/arm/kernel/armksyms.c
+++ b/trunk/arch/arm/kernel/armksyms.c
@@ -30,6 +30,9 @@ extern void __lshrdi3(void);
extern void __modsi3(void);
extern void __muldi3(void);
extern void __ucmpdi2(void);
+extern void __udivdi3(void);
+extern void __umoddi3(void);
+extern void __udivmoddi4(void);
extern void __udivsi3(void);
extern void __umodsi3(void);
extern void __do_div64(void);
@@ -131,6 +134,9 @@ EXPORT_SYMBOL(__lshrdi3);
EXPORT_SYMBOL(__modsi3);
EXPORT_SYMBOL(__muldi3);
EXPORT_SYMBOL(__ucmpdi2);
+EXPORT_SYMBOL(__udivdi3);
+EXPORT_SYMBOL(__umoddi3);
+EXPORT_SYMBOL(__udivmoddi4);
EXPORT_SYMBOL(__udivsi3);
EXPORT_SYMBOL(__umodsi3);
EXPORT_SYMBOL(__do_div64);
diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c
index 35b7273cfdb4..8cf733daa800 100644
--- a/trunk/arch/arm/kernel/setup.c
+++ b/trunk/arch/arm/kernel/setup.c
@@ -359,8 +359,7 @@ void cpu_init(void)
"I" (offsetof(struct stack, abt[0])),
"I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
"I" (offsetof(struct stack, und[0])),
- "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
- : "r14");
+ "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE));
}
static struct machine_desc * __init setup_machine(unsigned int nr)
diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c
index a931409c8fe4..34892758f098 100644
--- a/trunk/arch/arm/kernel/smp.c
+++ b/trunk/arch/arm/kernel/smp.c
@@ -502,126 +502,3 @@ int __init setup_profiling_timer(unsigned int multiplier)
{
return -EINVAL;
}
-
-static int
-on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait,
- cpumask_t mask)
-{
- int ret = 0;
-
- preempt_disable();
-
- ret = smp_call_function_on_cpu(func, info, retry, wait, mask);
- if (cpu_isset(smp_processor_id(), mask))
- func(info);
-
- preempt_enable();
-
- return ret;
-}
-
-/**********************************************************************/
-
-/*
- * TLB operations
- */
-struct tlb_args {
- struct vm_area_struct *ta_vma;
- unsigned long ta_start;
- unsigned long ta_end;
-};
-
-static inline void ipi_flush_tlb_all(void *ignored)
-{
- local_flush_tlb_all();
-}
-
-static inline void ipi_flush_tlb_mm(void *arg)
-{
- struct mm_struct *mm = (struct mm_struct *)arg;
-
- local_flush_tlb_mm(mm);
-}
-
-static inline void ipi_flush_tlb_page(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_page(ta->ta_vma, ta->ta_start);
-}
-
-static inline void ipi_flush_tlb_kernel_page(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_kernel_page(ta->ta_start);
-}
-
-static inline void ipi_flush_tlb_range(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
-}
-
-static inline void ipi_flush_tlb_kernel_range(void *arg)
-{
- struct tlb_args *ta = (struct tlb_args *)arg;
-
- local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
-}
-
-void flush_tlb_all(void)
-{
- on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
- cpumask_t mask = mm->cpu_vm_mask;
-
- on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask);
-}
-
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
-{
- cpumask_t mask = vma->vm_mm->cpu_vm_mask;
- struct tlb_args ta;
-
- ta.ta_vma = vma;
- ta.ta_start = uaddr;
-
- on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask);
-}
-
-void flush_tlb_kernel_page(unsigned long kaddr)
-{
- struct tlb_args ta;
-
- ta.ta_start = kaddr;
-
- on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1);
-}
-
-void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- cpumask_t mask = vma->vm_mm->cpu_vm_mask;
- struct tlb_args ta;
-
- ta.ta_vma = vma;
- ta.ta_start = start;
- ta.ta_end = end;
-
- on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask);
-}
-
-void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- struct tlb_args ta;
-
- ta.ta_start = start;
- ta.ta_end = end;
-
- on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1);
-}
diff --git a/trunk/arch/arm/lib/Makefile b/trunk/arch/arm/lib/Makefile
index 8725d63e4219..c0e65833ffc4 100644
--- a/trunk/arch/arm/lib/Makefile
+++ b/trunk/arch/arm/lib/Makefile
@@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
strnlen_user.o strchr.o strrchr.o testchangebit.o \
testclearbit.o testsetbit.o uaccess.o getuser.o \
putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
- ucmpdi2.o lib1funcs.o div64.o \
+ ucmpdi2.o udivdi3.o lib1funcs.o div64.o \
io-readsb.o io-writesb.o io-readsl.o io-writesl.o
ifeq ($(CONFIG_CPU_32v3),y)
diff --git a/trunk/arch/arm/lib/longlong.h b/trunk/arch/arm/lib/longlong.h
new file mode 100644
index 000000000000..90ae647e4d76
--- /dev/null
+++ b/trunk/arch/arm/lib/longlong.h
@@ -0,0 +1,183 @@
+/* longlong.h -- based on code from gcc-2.95.3
+
+ definitions for mixed size 32/64 bit arithmetic.
+ Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
+
+ This definition file is free software; you can redistribute it
+ and/or modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2, or (at your option) any later version.
+
+ This definition file is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
+
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((u32) (t) % __ll_B)
+#define __ll_highpart(t) ((u32) (t) / __ll_B)
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
+ multiplies two u32 integers MULTIPLER and MULTIPLICAND,
+ and generates a two-part u32 product in HIGH_PROD and
+ LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two u32 integers A and B,
+ and returns a u64 product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a two-word unsigned integer, composed by the
+ integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
+ places the quotient in QUOTIENT and the remainder in REMAINDER.
+ HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
+ If, in addition, the most significant bit of DENOMINATOR must be 1,
+ then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The
+ quotient is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from
+ the msb to the first non-zero bit. This is the number of steps X
+ needs to be shifted left to set the msb. Undefined for X == 0.
+
+ 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two two-word unsigned integers,
+ composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
+ LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
+ LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
+ lost.
+
+ 7) sub_ddmmss(high_difference, low_difference, high_minuend,
+ low_minuend, high_subtrahend, low_subtrahend) subtracts two
+ two-word unsigned integers, composed by HIGH_MINUEND_1 and
+ LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
+ respectively. The result is placed in HIGH_DIFFERENCE and
+ LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used. */
+
+#if defined (__arm__)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5 \n\
+ adc %0, %2, %3" \
+ : "=r" ((u32) (sh)), \
+ "=&r" ((u32) (sl)) \
+ : "%r" ((u32) (ah)), \
+ "rI" ((u32) (bh)), \
+ "%r" ((u32) (al)), \
+ "rI" ((u32) (bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5 \n\
+ sbc %0, %2, %3" \
+ : "=r" ((u32) (sh)), \
+ "=&r" ((u32) (sl)) \
+ : "r" ((u32) (ah)), \
+ "rI" ((u32) (bh)), \
+ "r" ((u32) (al)), \
+ "rI" ((u32) (bl)))
+#define umul_ppmm(xh, xl, a, b) \
+{register u32 __t0, __t1, __t2; \
+ __asm__ ("%@ Inlined umul_ppmm \n\
+ mov %2, %5, lsr #16 \n\
+ mov %0, %6, lsr #16 \n\
+ bic %3, %5, %2, lsl #16 \n\
+ bic %4, %6, %0, lsl #16 \n\
+ mul %1, %3, %4 \n\
+ mul %4, %2, %4 \n\
+ mul %3, %0, %3 \n\
+ mul %0, %2, %0 \n\
+ adds %3, %4, %3 \n\
+ addcs %0, %0, #65536 \n\
+ adds %1, %1, %3, lsl #16 \n\
+ adc %0, %0, %3, lsr #16" \
+ : "=&r" ((u32) (xh)), \
+ "=r" ((u32) (xl)), \
+ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
+ : "r" ((u32) (a)), \
+ "r" ((u32) (b)));}
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#define __umulsidi3(u, v) \
+ ({DIunion __w; \
+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
+ __w.ll; })
+
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ u32 __d1, __d0, __q1, __q0; \
+ u32 __r1, __r0, __m; \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (u32) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (u32) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (u32) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+
+#define count_leading_zeros(count, x) \
+ do { \
+ u32 __xr = (x); \
+ u32 __a; \
+ \
+ if (SI_TYPE_SIZE <= 32) \
+ { \
+ __a = __xr < ((u32)1<<2*__BITS4) \
+ ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \
+ : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
+ } \
+ else \
+ { \
+ for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
+ } while (0)
diff --git a/trunk/arch/arm/lib/udivdi3.c b/trunk/arch/arm/lib/udivdi3.c
new file mode 100644
index 000000000000..e343be4c6642
--- /dev/null
+++ b/trunk/arch/arm/lib/udivdi3.c
@@ -0,0 +1,222 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+#include "longlong.h"
+
+static const u8 __clz_tab[] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+};
+
+u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
+{
+ DIunion ww;
+ DIunion nn, dd;
+ DIunion rr;
+ u32 d0, d1, n0, n1, n2;
+ u32 q0, q1;
+ u32 b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+ if (d1 == 0) {
+ if (d0 > n1) {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros(bm, d0);
+
+ if (bm != 0) {
+ /* Normalize, i.e. make the most significant bit of the
+ denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ } else {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros(bm, d0);
+
+ if (bm == 0) {
+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ leading quotient digit q1 = 1).
+
+ This special case is necessary, not an optimization.
+ (Shifts counts of SI_TYPE_SIZE are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ } else {
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd(q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd(q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0) {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ } else {
+ if (d1 > n1) {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ /* 0q = NN / dd */
+
+ count_leading_zeros(bm, d1);
+ if (bm == 0) {
+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ quotient digit q0 = 0 or 1).
+
+ This special case is necessary, not an optimization. */
+
+ /* The condition on the next line takes advantage of that
+ n1 >= d1 (true due to program flow). */
+ if (n1 > d1 || n0 >= d0) {
+ q0 = 1;
+ sub_ddmmss(n1, n0, n1, n0, d1, d0);
+ } else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ u32 m1, m0;
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd(q0, n1, n2, n1, d1);
+ umul_ppmm(m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0)) {
+ q0--;
+ sub_ddmmss(m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0) {
+ sub_ddmmss(n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);
+ rr.s.high = n1 >> bm;
+ *rp = rr.ll;
+ }
+ }
+ }
+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
+}
+
+u64 __udivdi3(u64 n, u64 d)
+{
+ return __udivmoddi4(n, d, (u64 *) 0);
+}
+
+u64 __umoddi3(u64 u, u64 v)
+{
+ u64 w;
+
+ (void)__udivmoddi4(u, v, &w);
+
+ return w;
+}
diff --git a/trunk/arch/arm/mach-integrator/core.c b/trunk/arch/arm/mach-integrator/core.c
index dacbf504dae2..9222e57bd872 100644
--- a/trunk/arch/arm/mach-integrator/core.c
+++ b/trunk/arch/arm/mach-integrator/core.c
@@ -20,7 +20,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -157,6 +156,16 @@ EXPORT_SYMBOL(cm_control);
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
+/*
+ * What does it look like?
+ */
+typedef struct TimerStruct {
+ unsigned long TimerLoad;
+ unsigned long TimerValue;
+ unsigned long TimerControl;
+ unsigned long TimerClear;
+} TimerStruct_t;
+
static unsigned long timer_reload;
/*
@@ -165,6 +174,7 @@ static unsigned long timer_reload;
*/
unsigned long integrator_gettimeoffset(void)
{
+ volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
unsigned long ticks1, ticks2, status;
/*
@@ -173,11 +183,11 @@ unsigned long integrator_gettimeoffset(void)
* an interrupt. We get around this by ensuring that the
* counter has not reloaded between our two reads.
*/
- ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
+ ticks2 = timer1->TimerValue & 0xffff;
do {
ticks1 = ticks2;
status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
- ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
+ ticks2 = timer1->TimerValue & 0xffff;
} while (ticks2 > ticks1);
/*
@@ -203,12 +213,14 @@ unsigned long integrator_gettimeoffset(void)
static irqreturn_t
integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
+
write_seqlock(&xtime_lock);
/*
* clear the interrupt
*/
- writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
+ timer1->TimerClear = 1;
/*
* the clock tick routines are only processed on the
@@ -244,29 +256,32 @@ static struct irqaction integrator_timer_irq = {
*/
void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
{
- unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
+ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
+ volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
+ volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
+ unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */
timer_reload = reload;
timer_ctrl |= ctrl;
if (timer_reload > 0x100000) {
timer_reload >>= 8;
- timer_ctrl |= TIMER_CTRL_DIV256;
+ timer_ctrl |= 0x08; /* /256 */
} else if (timer_reload > 0x010000) {
timer_reload >>= 4;
- timer_ctrl |= TIMER_CTRL_DIV16;
+ timer_ctrl |= 0x04; /* /16 */
}
/*
* Initialise to a known state (all timers off)
*/
- writel(0, TIMER0_VA_BASE + TIMER_CTRL);
- writel(0, TIMER1_VA_BASE + TIMER_CTRL);
- writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+ timer0->TimerControl = 0;
+ timer1->TimerControl = 0;
+ timer2->TimerControl = 0;
- writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
- writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
- writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
+ timer1->TimerLoad = timer_reload;
+ timer1->TimerValue = timer_reload;
+ timer1->TimerControl = timer_ctrl;
/*
* Make irqs happen for the system timer
diff --git a/trunk/arch/arm/mach-omap/pm.c b/trunk/arch/arm/mach-omap/pm.c
index 6b03ccdc1e92..00fac155df2a 100644
--- a/trunk/arch/arm/mach-omap/pm.c
+++ b/trunk/arch/arm/mach-omap/pm.c
@@ -41,9 +41,7 @@
#include
#include
-#include
#include
-
#include
#include
#include
@@ -82,13 +80,13 @@ void omap_pm_idle(void)
return;
}
mask32 = omap_readl(ARM_SYSST);
+ local_fiq_enable();
+ local_irq_enable();
- /*
- * Since an interrupt may set up a timer, we don't want to
- * reprogram the hardware timer with interrupts enabled.
- * Re-enable interrupts only after returning from idle.
- */
- timer_dyn_reprogram();
+#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ)
+ /* Override timer to use VST for the next cycle */
+ omap_32k_timer_next_vst_interrupt();
+#endif
if ((mask32 & DSP_IDLE) == 0) {
__asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
@@ -104,8 +102,6 @@ void omap_pm_idle(void)
func_ptr();
}
- local_fiq_enable();
- local_irq_enable();
}
/*
diff --git a/trunk/arch/arm/mach-omap/time.c b/trunk/arch/arm/mach-omap/time.c
index dd34e9f4c413..589e8b2740dd 100644
--- a/trunk/arch/arm/mach-omap/time.c
+++ b/trunk/arch/arm/mach-omap/time.c
@@ -4,7 +4,7 @@
* OMAP Timers
*
* Copyright (C) 2004 Nokia Corporation
- * Partial timer rewrite and additional dynamic tick timer support by
+ * Partial timer rewrite and additional VST timer support by
* Tony Lindgen and
* Tuukka Tikkanen
*
@@ -261,6 +261,7 @@ unsigned long long sched_clock(void)
* so with HZ = 100, TVR = 327.68.
*/
#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
+#define MAX_SKIP_JIFFIES 25
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
@@ -346,42 +347,6 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
return IRQ_HANDLED;
}
-#ifdef CONFIG_NO_IDLE_HZ
-/*
- * Programs the next timer interrupt needed. Called when dynamic tick is
- * enabled, and to reprogram the ticks to skip from pm_idle. Note that
- * we can keep the timer continuous, and don't need to set it to run in
- * one-shot mode. This is because the timer will get reprogrammed again
- * after next interrupt.
- */
-void omap_32k_timer_reprogram(unsigned long next_tick)
-{
- omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
-}
-
-static struct irqaction omap_32k_timer_irq;
-extern struct timer_update_handler timer_update;
-
-static int omap_32k_timer_enable_dyn_tick(void)
-{
- /* No need to reprogram timer, just use the next interrupt */
- return 0;
-}
-
-static int omap_32k_timer_disable_dyn_tick(void)
-{
- omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
- return 0;
-}
-
-static struct dyn_tick_timer omap_dyn_tick_timer = {
- .enable = omap_32k_timer_enable_dyn_tick,
- .disable = omap_32k_timer_disable_dyn_tick,
- .reprogram = omap_32k_timer_reprogram,
- .handler = omap_32k_timer_interrupt,
-};
-#endif /* CONFIG_NO_IDLE_HZ */
-
static struct irqaction omap_32k_timer_irq = {
.name = "32KHz timer",
.flags = SA_INTERRUPT | SA_TIMER,
@@ -390,11 +355,6 @@ static struct irqaction omap_32k_timer_irq = {
static __init void omap_init_32k_timer(void)
{
-
-#ifdef CONFIG_NO_IDLE_HZ
- omap_timer.dyn_tick = &omap_dyn_tick_timer;
-#endif
-
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
omap_timer.offset = omap_32k_timer_gettimeoffset;
omap_32k_last_tick = omap_32k_sync_timer_read();
diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig
index d4d03d0daaec..534df0c6c770 100644
--- a/trunk/arch/arm/mach-s3c2410/Kconfig
+++ b/trunk/arch/arm/mach-s3c2410/Kconfig
@@ -154,11 +154,6 @@ config S3C2410_PM_CHECK_CHUNKSIZE
the CRC data block will take more memory, but wil identify any
faults with better precision.
-config PM_SIMTEC
- bool
- depends on PM && (ARCH_BAST || MACH_VR1000)
- default y
-
config S3C2410_LOWLEVEL_UART_PORT
int "S3C2410 UART to use for low-level messages"
default 0
diff --git a/trunk/arch/arm/mach-s3c2410/Makefile b/trunk/arch/arm/mach-s3c2410/Makefile
index f99b689e4392..7c379aad5d62 100644
--- a/trunk/arch/arm/mach-s3c2410/Makefile
+++ b/trunk/arch/arm/mach-s3c2410/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
# Power Management support
obj-$(CONFIG_PM) += pm.o sleep.o
-obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
# S3C2440 support
diff --git a/trunk/arch/arm/mach-s3c2410/devs.c b/trunk/arch/arm/mach-s3c2410/devs.c
index 4664bd11adc1..64792f678668 100644
--- a/trunk/arch/arm/mach-s3c2410/devs.c
+++ b/trunk/arch/arm/mach-s3c2410/devs.c
@@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = {
.num_resources = ARRAY_SIZE(s3c_lcd_resource),
.resource = s3c_lcd_resource,
.dev = {
- .dma_mask = &s3c_device_lcd_dmamask,
- .coherent_dma_mask = 0xffffffffUL
+ .dma_mask = &s3c_device_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
}
};
diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c
index cf9f46d88061..b668c48f4399 100644
--- a/trunk/arch/arm/mach-s3c2410/irq.c
+++ b/trunk/arch/arm/mach-s3c2410/irq.c
@@ -40,11 +40,8 @@
* 04-Nov-2004 Ben Dooks
* Fix standard IRQ wake for EINT0..4 and RTC
*
- * 22-Feb-2005 Ben Dooks
+ * 22-Feb-2004 Ben Dooks
* Fixed edge-triggering on ADC IRQ
- *
- * 28-Jun-2005 Ben Dooks
- * Mark IRQ_LCD valid
*/
#include
@@ -369,6 +366,7 @@ static struct irqchip s3c_irq_eint0t4 = {
#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
+#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
static inline void
s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
@@ -718,6 +716,7 @@ void __init s3c24xx_init_irq(void)
case IRQ_UART0:
case IRQ_UART1:
case IRQ_UART2:
+ case IRQ_LCD:
case IRQ_ADCPARENT:
set_irq_chip(irqno, &s3c_irq_level_chip);
set_irq_handler(irqno, do_level_IRQ);
diff --git a/trunk/arch/arm/mach-s3c2410/mach-bast.c b/trunk/arch/arm/mach-s3c2410/mach-bast.c
index 549bcb1f32c0..f3e970039b65 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-bast.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-bast.c
@@ -27,7 +27,6 @@
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
* 14-Mar-2006 BJD Updated for __iomem changes
* 22-Jun-2006 BJD Added DM9000 platform information
- * 28-Jun-2006 BJD Moved pm functionality out to common code
*/
#include
@@ -68,6 +67,7 @@
#include "devs.h"
#include "cpu.h"
#include "usb-simtec.h"
+#include "pm.h"
#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
@@ -405,13 +405,44 @@ void __init bast_map_io(void)
usb_simtec_init();
}
+void __init bast_init_irq(void)
+{
+ s3c24xx_init_irq();
+}
+
+#ifdef CONFIG_PM
+
+/* bast_init_machine
+ *
+ * enable the power management functions for the EB2410ITX
+*/
+
+static __init void bast_init_machine(void)
+{
+ unsigned long gstatus4;
+
+ printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n");
+
+ gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
+ gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
+ gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
+
+ __raw_writel(gstatus4, S3C2410_GSTATUS4);
+
+ s3c2410_pm_init();
+}
+
+#else
+#define bast_init_machine NULL
+#endif
+
MACHINE_START(BAST, "Simtec-BAST")
MAINTAINER("Ben Dooks ")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-
- .map_io = bast_map_io,
- .init_irq = s3c24xx_init_irq,
+ MAPIO(bast_map_io)
+ INITIRQ(bast_init_irq)
+ .init_machine = bast_init_machine,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c
index 1db2855e3e56..76be074944a0 100644
--- a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -371,12 +371,16 @@ void __init vr1000_map_io(void)
usb_simtec_init();
}
+void __init vr1000_init_irq(void)
+{
+ s3c24xx_init_irq();
+}
MACHINE_START(VR1000, "Thorcom-VR1000")
MAINTAINER("Ben Dooks ")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
- .map_io = vr1000_map_io,
- .init_irq = s3c24xx_init_irq,
+ MAPIO(vr1000_map_io)
+ INITIRQ(vr1000_init_irq)
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/trunk/arch/arm/mach-s3c2410/pm-simtec.c b/trunk/arch/arm/mach-s3c2410/pm-simtec.c
deleted file mode 100644
index 2cb798832223..000000000000
--- a/trunk/arch/arm/mach-s3c2410/pm-simtec.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/pm-simtec.c
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks
- *
- * http://armlinux.simtec.co.uk/
- *
- * Power Management helpers for Simtec S3C24XX implementations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-
-#include "pm.h"
-
-#define COPYRIGHT ", (c) 2005 Simtec Electronics"
-
-/* pm_simtec_init
- *
- * enable the power management functions
-*/
-
-static __init int pm_simtec_init(void)
-{
- unsigned long gstatus4;
-
- /* check which machine we are running on */
-
- if (!machine_is_bast() && !machine_is_vr1000())
- return 0;
-
- printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
-
- gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
- gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
- gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
-
- __raw_writel(gstatus4, S3C2410_GSTATUS4);
-
- return s3c2410_pm_init();
-}
-
-arch_initcall(pm_simtec_init);
diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c
index f01c0f8a2bb3..9d1f2253e987 100644
--- a/trunk/arch/arm/mach-versatile/core.c
+++ b/trunk/arch/arm/mach-versatile/core.c
@@ -33,7 +33,6 @@
#include
#include
#include
-#include
#include
#include
@@ -789,25 +788,38 @@ void __init versatile_init(void)
*/
#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
+#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */
+#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */
#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
#elif TIMER_INTERVAL >= 0x10000
#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
-#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
+#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */
#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
#else
#define TIMER_RELOAD (TIMER_INTERVAL)
-#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
+#define TIMER_CTRL 0x80 /* Enable */
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
+#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
+
+/*
+ * What does it look like?
+ */
+typedef struct TimerStruct {
+ unsigned long TimerLoad;
+ unsigned long TimerValue;
+ unsigned long TimerControl;
+ unsigned long TimerClear;
+} TimerStruct_t;
+
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long versatile_gettimeoffset(void)
{
+ volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
unsigned long ticks1, ticks2, status;
/*
@@ -816,11 +828,11 @@ static unsigned long versatile_gettimeoffset(void)
* an interrupt. We get around this by ensuring that the
* counter has not reloaded between our two reads.
*/
- ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
+ ticks2 = timer0->TimerValue & 0xffff;
do {
ticks1 = ticks2;
status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
- ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
+ ticks2 = timer0->TimerValue & 0xffff;
} while (ticks2 > ticks1);
/*
@@ -847,10 +859,12 @@ static unsigned long versatile_gettimeoffset(void)
*/
static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
+
write_seqlock(&xtime_lock);
// ...clear the interrupt
- writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
+ timer0->TimerClear = 1;
timer_tick(regs);
@@ -870,32 +884,31 @@ static struct irqaction versatile_timer_irq = {
*/
static void __init versatile_timer_init(void)
{
- u32 val;
+ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
+ volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
+ volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
+ volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
/*
* set clock frequency:
* VERSATILE_REFCLK is 32KHz
* VERSATILE_TIMCLK is 1MHz
*/
- val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE));
- writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
- (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
- (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
- (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
- IO_ADDRESS(VERSATILE_SCTL_BASE));
+ *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |=
+ ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
/*
* Initialise to a known state (all timers off)
*/
- writel(0, TIMER0_VA_BASE + TIMER_CTRL);
- writel(0, TIMER1_VA_BASE + TIMER_CTRL);
- writel(0, TIMER2_VA_BASE + TIMER_CTRL);
- writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-
- writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
- writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
- writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
- TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
+ timer0->TimerControl = 0;
+ timer1->TimerControl = 0;
+ timer2->TimerControl = 0;
+ timer3->TimerControl = 0;
+
+ timer0->TimerLoad = TIMER_RELOAD;
+ timer0->TimerValue = TIMER_RELOAD;
+ timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */
/*
* Make irqs happen for the system timer
diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c
index edffa47a4b2a..6dcb23d64bf5 100644
--- a/trunk/arch/arm/mm/init.c
+++ b/trunk/arch/arm/mm/init.c
@@ -437,7 +437,7 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
memtable_init(mi);
if (mdesc->map_io)
mdesc->map_io();
- local_flush_tlb_all();
+ flush_tlb_all();
/*
* initialise the zones within each node
diff --git a/trunk/arch/arm/mm/mm-armv.c b/trunk/arch/arm/mm/mm-armv.c
index c3bd503b43a2..052ab443ec4e 100644
--- a/trunk/arch/arm/mm/mm-armv.c
+++ b/trunk/arch/arm/mm/mm-armv.c
@@ -682,7 +682,7 @@ void __init memtable_init(struct meminfo *mi)
}
flush_cache_all();
- local_flush_tlb_all();
+ flush_tlb_all();
top_pmd = pmd_off_k(0xffff0000);
}
diff --git a/trunk/arch/arm/oprofile/Makefile b/trunk/arch/arm/oprofile/Makefile
index 8ffb523e6c77..ba1a6e9f2b28 100644
--- a/trunk/arch/arm/oprofile/Makefile
+++ b/trunk/arch/arm/oprofile/Makefile
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o \
timer_int.o )
-oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
+oprofile-y := $(DRIVER_OBJS) init.o
oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o
diff --git a/trunk/arch/arm/oprofile/backtrace.c b/trunk/arch/arm/oprofile/backtrace.c
deleted file mode 100644
index ec58d3e2eb8b..000000000000
--- a/trunk/arch/arm/oprofile/backtrace.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Arm specific backtracing code for oprofile
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie
- *
- * Based on i386 oprofile backtrace code by John Levon, David Smith
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-
-
-/*
- * The registers we're interested in are at the end of the variable
- * length saved register structure. The fp points at the end of this
- * structure so the address of this struct is:
- * (struct frame_tail *)(xxx->fp)-1
- */
-struct frame_tail {
- struct frame_tail *fp;
- unsigned long sp;
- unsigned long lr;
-} __attribute__((packed));
-
-
-#ifdef CONFIG_FRAME_POINTER
-static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
-{
- oprofile_add_trace(tail->lr);
-
- /* frame pointers should strictly progress back up the stack
- * (towards higher addresses) */
- if (tail >= tail->fp)
- return NULL;
-
- return tail->fp-1;
-}
-#endif
-
-static struct frame_tail* user_backtrace(struct frame_tail *tail)
-{
- struct frame_tail buftail;
-
- /* hardware pte might not be valid due to dirty/accessed bit emulation
- * so we use copy_from_user and benefit from exception fixups */
- if (copy_from_user(&buftail, tail, sizeof(struct frame_tail)))
- return NULL;
-
- oprofile_add_trace(buftail.lr);
-
- /* frame pointers should strictly progress back up the stack
- * (towards higher addresses) */
- if (tail >= buftail.fp)
- return NULL;
-
- return buftail.fp-1;
-}
-
-/* Compare two addresses and see if they're on the same page */
-#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \
- == ((((unsigned long) y) + offset) >> PAGE_SHIFT))
-
-/* check that the page(s) containing the frame tail are present */
-static int pages_present(struct frame_tail *tail)
-{
- struct mm_struct * mm = current->mm;
-
- if (!check_user_page_readable(mm, (unsigned long)tail))
- return 0;
-
- if (CMP_ADDR_EQUAL(tail, tail, 8))
- return 1;
-
- if (!check_user_page_readable(mm, ((unsigned long)tail) + 8))
- return 0;
-
- return 1;
-}
-
-/*
- * | | /\ Higher addresses
- * | |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * . .
- * | stack |
- * --------------- saved regs->ARM_fp value if valid (frame_tail address)
- * . .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
- * | |
- * . .
- * | |
- * --------------- %esp
- * | |
- * | | \/ Lower addresses
- *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
- */
-static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
-{
- unsigned long tailaddr = (unsigned long)tail;
- unsigned long stack = (unsigned long)regs;
- unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
- return (tailaddr > stack) && (tailaddr < stack_base);
-}
-
-void arm_backtrace(struct pt_regs const *regs, unsigned int depth)
-{
- struct frame_tail *tail;
- unsigned long last_address = 0;
-
- tail = ((struct frame_tail *) regs->ARM_fp) - 1;
-
- if (!user_mode(regs)) {
-
-#ifdef CONFIG_FRAME_POINTER
- while (depth-- && tail && valid_kernel_stack(tail, regs)) {
- tail = kernel_backtrace(tail);
- }
-#endif
- return;
- }
-
- while (depth-- && tail && !((unsigned long) tail & 3)) {
- if ((!CMP_ADDR_EQUAL(last_address, tail, 0)
- || !CMP_ADDR_EQUAL(last_address, tail, 8))
- && !pages_present(tail))
- return;
- last_address = (unsigned long) tail;
- tail = user_backtrace(tail);
- }
-}
-
diff --git a/trunk/arch/arm/oprofile/init.c b/trunk/arch/arm/oprofile/init.c
index d315a3a86c86..cce3d3015eb7 100644
--- a/trunk/arch/arm/oprofile/init.c
+++ b/trunk/arch/arm/oprofile/init.c
@@ -20,8 +20,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
ret = pmu_init(ops, &op_xscale_spec);
#endif
- ops->backtrace = arm_backtrace;
-
return ret;
}
diff --git a/trunk/arch/arm/oprofile/op_arm_model.h b/trunk/arch/arm/oprofile/op_arm_model.h
index 2148d07484b7..2d4caf4781ad 100644
--- a/trunk/arch/arm/oprofile/op_arm_model.h
+++ b/trunk/arch/arm/oprofile/op_arm_model.h
@@ -24,8 +24,6 @@ struct op_arm_model_spec {
extern struct op_arm_model_spec op_xscale_spec;
#endif
-extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
-
extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
extern void pmu_exit(void);
#endif /* OP_ARM_MODEL_H */
diff --git a/trunk/arch/arm/vfp/vfp.h b/trunk/arch/arm/vfp/vfp.h
index 4b97950984e9..55a02bc994a3 100644
--- a/trunk/arch/arm/vfp/vfp.h
+++ b/trunk/arch/arm/vfp/vfp.h
@@ -117,13 +117,7 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
if (nh >= m)
return ~0ULL;
mh = m >> 32;
- if (mh << 32 <= nh) {
- z = 0xffffffff00000000ULL;
- } else {
- z = nh;
- do_div(z, mh);
- z <<= 32;
- }
+ z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32;
mul64to128(&termh, &terml, m, z);
sub128(&remh, &reml, nh, nl, termh, terml);
ml = m << 32;
@@ -132,12 +126,7 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
add128(&remh, &reml, remh, reml, mh, ml);
}
remh = (remh << 32) | (reml >> 32);
- if (mh << 32 <= remh) {
- z |= 0xffffffff;
- } else {
- do_div(remh, mh);
- z |= remh;
- }
+ z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh;
return z;
}
diff --git a/trunk/arch/arm/vfp/vfpdouble.c b/trunk/arch/arm/vfp/vfpdouble.c
index b801cd66b6ea..fa3053e84db5 100644
--- a/trunk/arch/arm/vfp/vfpdouble.c
+++ b/trunk/arch/arm/vfp/vfpdouble.c
@@ -32,8 +32,6 @@
*/
#include
#include
-
-#include
#include
#include
diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c
index 22f3da4e0829..3aeedd2afc70 100644
--- a/trunk/arch/arm/vfp/vfpmodule.c
+++ b/trunk/arch/arm/vfp/vfpmodule.c
@@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
current->thread.error_code = 0;
current->thread.trap_no = 6;
- send_sig_info(SIGFPE, &info, current);
+ force_sig_info(SIGFPE, &info, current);
}
static void vfp_panic(char *reason)
diff --git a/trunk/arch/arm/vfp/vfpsingle.c b/trunk/arch/arm/vfp/vfpsingle.c
index 14dd696ddeb1..6849fe35cb2e 100644
--- a/trunk/arch/arm/vfp/vfpsingle.c
+++ b/trunk/arch/arm/vfp/vfpsingle.c
@@ -32,8 +32,6 @@
*/
#include
#include
-
-#include
#include
#include
@@ -305,11 +303,7 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
if (z <= a)
return (s32)a >> 1;
}
- {
- u64 v = (u64)a << 31;
- do_div(v, z);
- return v + (z >> 1);
- }
+ return (u32)(((u64)a << 31) / z) + (z >> 1);
}
static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
@@ -1113,11 +1107,7 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
vsn.significand >>= 1;
vsd.exponent++;
}
- {
- u64 significand = (u64)vsn.significand << 32;
- do_div(significand, vsm.significand);
- vsd.significand = significand;
- }
+ vsd.significand = ((u64)vsn.significand << 32) / vsm.significand;
if ((vsd.significand & 0x3f) == 0)
vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
diff --git a/trunk/arch/i386/boot/tools/build.c b/trunk/arch/i386/boot/tools/build.c
index 6835f6d47c31..4a17956512e1 100644
--- a/trunk/arch/i386/boot/tools/build.c
+++ b/trunk/arch/i386/boot/tools/build.c
@@ -70,8 +70,7 @@ void usage(void)
int main(int argc, char ** argv)
{
- unsigned int i, sz, setup_sectors;
- int c;
+ unsigned int i, c, sz, setup_sectors;
u32 sys_size;
byte major_root, minor_root;
struct stat sb;
diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c
index b7808a89d945..9f63ae0f404b 100644
--- a/trunk/arch/i386/kernel/acpi/boot.c
+++ b/trunk/arch/i386/kernel/acpi/boot.c
@@ -159,15 +159,9 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
#endif
#ifdef CONFIG_PCI_MMCONFIG
-/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
-struct acpi_table_mcfg_config *pci_mmcfg_config;
-int pci_mmcfg_config_num;
-
-int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
+static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
{
struct acpi_table_mcfg *mcfg;
- unsigned long i;
- int config_size;
if (!phys_addr || !size)
return -EINVAL;
@@ -178,38 +172,18 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
return -ENODEV;
}
- /* how many config structures do we have */
- pci_mmcfg_config_num = 0;
- i = size - sizeof(struct acpi_table_mcfg);
- while (i >= sizeof(struct acpi_table_mcfg_config)) {
- ++pci_mmcfg_config_num;
- i -= sizeof(struct acpi_table_mcfg_config);
- };
- if (pci_mmcfg_config_num == 0) {
- printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
+ if (mcfg->base_reserved) {
+ printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
return -ENODEV;
}
- config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
- pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
- if (!pci_mmcfg_config) {
- printk(KERN_WARNING PREFIX
- "No memory for MCFG config tables\n");
- return -ENOMEM;
- }
-
- memcpy(pci_mmcfg_config, &mcfg->config, config_size);
- for (i = 0; i < pci_mmcfg_config_num; ++i) {
- if (mcfg->config[i].base_reserved) {
- printk(KERN_ERR PREFIX
- "MMCONFIG not in low 4GB of memory\n");
- return -ENODEV;
- }
- }
+ pci_mmcfg_base_addr = mcfg->base_address;
return 0;
}
-#endif /* CONFIG_PCI_MMCONFIG */
+#else
+#define acpi_parse_mcfg NULL
+#endif /* !CONFIG_PCI_MMCONFIG */
#ifdef CONFIG_X86_LOCAL_APIC
static int __init
@@ -533,22 +507,6 @@ acpi_unmap_lsapic(int cpu)
EXPORT_SYMBOL(acpi_unmap_lsapic);
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
-int
-acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
-{
- /* TBD */
- return -EINVAL;
-}
-EXPORT_SYMBOL(acpi_register_ioapic);
-
-int
-acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
-{
- /* TBD */
- return -EINVAL;
-}
-EXPORT_SYMBOL(acpi_unregister_ioapic);
-
static unsigned long __init
acpi_scan_rsdp (
unsigned long start,
@@ -1165,6 +1123,7 @@ int __init acpi_boot_init(void)
acpi_process_madt();
acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+ acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
return 0;
}
diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c
index bd1dbf3bd223..93df90bbb87e 100644
--- a/trunk/arch/i386/kernel/apic.c
+++ b/trunk/arch/i386/kernel/apic.c
@@ -35,7 +35,6 @@
#include
#include
#include
-#include
#include
@@ -880,6 +879,7 @@ void __init init_apic_mappings(void)
*/
static unsigned int __devinit get_8254_timer_count(void)
{
+ extern spinlock_t i8253_lock;
unsigned long flags;
unsigned int count;
diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c
index 064211d5f41b..d48ce9290963 100644
--- a/trunk/arch/i386/kernel/apm.c
+++ b/trunk/arch/i386/kernel/apm.c
@@ -228,10 +228,10 @@
#include
#include
#include
-#include
#include "io_ports.h"
+extern spinlock_t i8253_lock;
extern unsigned long get_cmos_time(void);
extern void machine_real_restart(unsigned char *, int);
@@ -1168,7 +1168,8 @@ static void get_time_diff(void)
static void reinit_timer(void)
{
#ifdef INIT_TIMER_AFTER_SUSPEND
- unsigned long flags;
+ unsigned long flags;
+ extern spinlock_t i8253_lock;
spin_lock_irqsave(&i8253_lock, flags);
/* set the clock to 100 Hz */
diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c
index 6578f40bd501..35eb8e29c485 100644
--- a/trunk/arch/i386/kernel/io_apic.c
+++ b/trunk/arch/i386/kernel/io_apic.c
@@ -37,7 +37,6 @@
#include
#include
#include
-#include
#include
@@ -1567,6 +1566,7 @@ void print_all_local_APICs (void)
void /*__init*/ print_PIC(void)
{
+ extern spinlock_t i8259A_lock;
unsigned int v;
unsigned long flags;
diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c
index 2854c357377f..e68d9fdb0759 100644
--- a/trunk/arch/i386/kernel/time.c
+++ b/trunk/arch/i386/kernel/time.c
@@ -68,8 +68,7 @@
#include "io_ports.h"
-#include
-
+extern spinlock_t i8259A_lock;
int pit_latch_buggy; /* extern */
#include "do_timer.h"
@@ -86,8 +85,6 @@ extern unsigned long wall_jiffies;
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
-#include
-
DEFINE_SPINLOCK(i8253_lock);
EXPORT_SYMBOL(i8253_lock);
diff --git a/trunk/arch/i386/kernel/timers/timer_cyclone.c b/trunk/arch/i386/kernel/timers/timer_cyclone.c
index 13892a65c941..f6f1206a11bb 100644
--- a/trunk/arch/i386/kernel/timers/timer_cyclone.c
+++ b/trunk/arch/i386/kernel/timers/timer_cyclone.c
@@ -17,10 +17,10 @@
#include
#include
#include
-#include
-
#include "io_ports.h"
+extern spinlock_t i8253_lock;
+
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
diff --git a/trunk/arch/i386/kernel/timers/timer_pit.c b/trunk/arch/i386/kernel/timers/timer_pit.c
index 06de036a820c..967d5453cd0e 100644
--- a/trunk/arch/i386/kernel/timers/timer_pit.c
+++ b/trunk/arch/i386/kernel/timers/timer_pit.c
@@ -15,8 +15,9 @@
#include
#include
#include
-#include
+extern spinlock_t i8259A_lock;
+extern spinlock_t i8253_lock;
#include "do_timer.h"
#include "io_ports.h"
@@ -165,6 +166,7 @@ struct init_timer_opts __initdata timer_pit_init = {
void setup_pit_timer(void)
{
+ extern spinlock_t i8253_lock;
unsigned long flags;
spin_lock_irqsave(&i8253_lock, flags);
diff --git a/trunk/arch/i386/kernel/timers/timer_tsc.c b/trunk/arch/i386/kernel/timers/timer_tsc.c
index 8f4e4d5bc560..f46e625bab67 100644
--- a/trunk/arch/i386/kernel/timers/timer_tsc.c
+++ b/trunk/arch/i386/kernel/timers/timer_tsc.c
@@ -24,7 +24,6 @@
#include "mach_timer.h"
#include
-#include
#ifdef CONFIG_HPET_TIMER
static unsigned long hpet_usec_quotient;
@@ -36,6 +35,8 @@ static inline void cpufreq_delayed_get(void);
int tsc_disable __devinitdata = 0;
+extern spinlock_t i8253_lock;
+
static int use_tsc;
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
diff --git a/trunk/arch/i386/mach-voyager/voyager_basic.c b/trunk/arch/i386/mach-voyager/voyager_basic.c
index 3e439ce5e1b2..602aea240e9b 100644
--- a/trunk/arch/i386/mach-voyager/voyager_basic.c
+++ b/trunk/arch/i386/mach-voyager/voyager_basic.c
@@ -30,7 +30,6 @@
#include
#include
#include
-#include
/*
* Power off function, if any
@@ -183,6 +182,7 @@ voyager_timer_interrupt(struct pt_regs *regs)
* and swiftly introduce it to something sharp and
* pointy. */
__u16 val;
+ extern spinlock_t i8253_lock;
spin_lock(&i8253_lock);
diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c
index 87325263cd4f..720975e1af50 100644
--- a/trunk/arch/i386/pci/common.c
+++ b/trunk/arch/i386/pci/common.c
@@ -25,8 +25,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
int pci_routeirq;
int pcibios_last_bus = -1;
-unsigned long pirq_table_addr;
-struct pci_bus *pci_root_bus;
+struct pci_bus *pci_root_bus = NULL;
struct pci_raw_ops *raw_pci_ops;
static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -134,7 +133,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
- return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
+ return pci_scan_bus(busnum, &pci_root_ops, NULL);
}
extern u8 pci_cache_line_size;
@@ -189,9 +188,6 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "biosirq")) {
pci_probe |= PCI_BIOS_IRQ_SCAN;
return NULL;
- } else if (!strncmp(str, "pirqaddr=", 9)) {
- pirq_table_addr = simple_strtoul(str+9, NULL, 0);
- return NULL;
}
#endif
#ifdef CONFIG_PCI_DIRECT
diff --git a/trunk/arch/i386/pci/irq.c b/trunk/arch/i386/pci/irq.c
index 78ca1ecbb907..83458f81e661 100644
--- a/trunk/arch/i386/pci/irq.c
+++ b/trunk/arch/i386/pci/irq.c
@@ -57,35 +57,6 @@ struct irq_router_handler {
int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
-/*
- * Check passed address for the PCI IRQ Routing Table signature
- * and perform checksum verification.
- */
-
-static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
-{
- struct irq_routing_table *rt;
- int i;
- u8 sum;
-
- rt = (struct irq_routing_table *) addr;
- if (rt->signature != PIRQ_SIGNATURE ||
- rt->version != PIRQ_VERSION ||
- rt->size % 16 ||
- rt->size < sizeof(struct irq_routing_table))
- return NULL;
- sum = 0;
- for (i=0; i < rt->size; i++)
- sum += addr[i];
- if (!sum) {
- DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
- return rt;
- }
- return NULL;
-}
-
-
-
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
@@ -94,17 +65,23 @@ static struct irq_routing_table * __init pirq_find_routing_table(void)
{
u8 *addr;
struct irq_routing_table *rt;
+ int i;
+ u8 sum;
- if (pirq_table_addr) {
- rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
- if (rt)
- return rt;
- printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
- }
for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
- rt = pirq_check_routing_table(addr);
- if (rt)
+ rt = (struct irq_routing_table *) addr;
+ if (rt->signature != PIRQ_SIGNATURE ||
+ rt->version != PIRQ_VERSION ||
+ rt->size % 16 ||
+ rt->size < sizeof(struct irq_routing_table))
+ continue;
+ sum = 0;
+ for(i=0; isize; i++)
+ sum += addr[i];
+ if (!sum) {
+ DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
return rt;
+ }
}
return NULL;
}
diff --git a/trunk/arch/i386/pci/legacy.c b/trunk/arch/i386/pci/legacy.c
index 149a9588c256..1492e3753869 100644
--- a/trunk/arch/i386/pci/legacy.c
+++ b/trunk/arch/i386/pci/legacy.c
@@ -45,8 +45,6 @@ static int __init pci_legacy_init(void)
printk("PCI: Probing PCI hardware\n");
pci_root_bus = pcibios_scan_root(0);
- if (pci_root_bus)
- pci_bus_add_devices(pci_root_bus);
pcibios_fixup_peer_bridges();
diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c
index 60f0e7a1162a..021a50aa51f4 100644
--- a/trunk/arch/i386/pci/mmconfig.c
+++ b/trunk/arch/i386/pci/mmconfig.c
@@ -11,9 +11,11 @@
#include
#include
-#include
#include "pci.h"
+/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
+u32 pci_mmcfg_base_addr;
+
#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
/* The base address of the last MMCONFIG device accessed */
@@ -22,31 +24,10 @@ static u32 mmcfg_last_accessed_device;
/*
* Functions for accessing PCI configuration space with MMCONFIG accesses
*/
-static u32 get_base_addr(unsigned int seg, int bus)
-{
- int cfg_num = -1;
- struct acpi_table_mcfg_config *cfg;
-
- while (1) {
- ++cfg_num;
- if (cfg_num >= pci_mmcfg_config_num) {
- /* something bad is going on, no cfg table is found. */
- /* so we fall back to the old way we used to do this */
- /* and just rely on the first entry to be correct. */
- return pci_mmcfg_config[0].base_address;
- }
- cfg = &pci_mmcfg_config[cfg_num];
- if (cfg->pci_segment_group_number != seg)
- continue;
- if ((cfg->start_bus_number <= bus) &&
- (cfg->end_bus_number >= bus))
- return cfg->base_address;
- }
-}
-static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
+static inline void pci_exp_set_dev_base(int bus, int devfn)
{
- u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
+ u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12);
if (dev_base != mmcfg_last_accessed_device) {
mmcfg_last_accessed_device = dev_base;
set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -63,7 +44,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
spin_lock_irqsave(&pci_config_lock, flags);
- pci_exp_set_dev_base(seg, bus, devfn);
+ pci_exp_set_dev_base(bus, devfn);
switch (len) {
case 1:
@@ -92,7 +73,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
spin_lock_irqsave(&pci_config_lock, flags);
- pci_exp_set_dev_base(seg, bus, devfn);
+ pci_exp_set_dev_base(bus, devfn);
switch (len) {
case 1:
@@ -120,11 +101,7 @@ static int __init pci_mmcfg_init(void)
{
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
goto out;
-
- acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
- if ((pci_mmcfg_config_num == 0) ||
- (pci_mmcfg_config == NULL) ||
- (pci_mmcfg_config[0].base_address == 0))
+ if (!pci_mmcfg_base_addr)
goto out;
/* Kludge for now. Don't use mmconfig on AMD systems because
diff --git a/trunk/arch/i386/pci/numa.c b/trunk/arch/i386/pci/numa.c
index adbe17a38f6f..9e3695461899 100644
--- a/trunk/arch/i386/pci/numa.c
+++ b/trunk/arch/i386/pci/numa.c
@@ -115,8 +115,6 @@ static int __init pci_numa_init(void)
return 0;
pci_root_bus = pcibios_scan_root(0);
- if (pci_root_bus)
- pci_bus_add_devices(pci_root_bus);
if (num_online_nodes() > 1)
for_each_online_node(quad) {
if (quad == 0)
diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h
index a80f0f55ff51..a8fc80ca69f3 100644
--- a/trunk/arch/i386/pci/pci.h
+++ b/trunk/arch/i386/pci/pci.h
@@ -27,7 +27,6 @@
#define PCI_ASSIGN_ALL_BUSSES 0x4000
extern unsigned int pci_probe;
-extern unsigned long pirq_table_addr;
/* pci-i386.c */
diff --git a/trunk/arch/ia64/configs/sn2_defconfig b/trunk/arch/ia64/configs/sn2_defconfig
index c05613980300..487d2e36b0a6 100644
--- a/trunk/arch/ia64/configs/sn2_defconfig
+++ b/trunk/arch/ia64/configs/sn2_defconfig
@@ -99,7 +99,7 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y
# Firmware Drivers
#
CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
+# CONFIG_EFI_PCDP is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -650,7 +650,7 @@ CONFIG_MMTIMER=y
#
# Console display driver support
#
-CONFIG_VGA_CONSOLE=y
+# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
#
diff --git a/trunk/arch/ia64/configs/tiger_defconfig b/trunk/arch/ia64/configs/tiger_defconfig
index 73454eee26f1..47f45341ac62 100644
--- a/trunk/arch/ia64/configs/tiger_defconfig
+++ b/trunk/arch/ia64/configs/tiger_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc1-20050629
-# Wed Jun 29 15:28:12 2005
+# Linux kernel version: 2.6.12-20050621
+# Tue Jun 21 14:03:24 2005
#
#
@@ -80,29 +80,18 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
CONFIG_IA64_L1_CACHE_SHIFT=7
# CONFIG_NUMA is not set
CONFIG_VIRTUAL_MEM_MAP=y
CONFIG_HOLES_IN_ZONE=y
CONFIG_IA64_CYCLONE=y
CONFIG_IOSAPIC=y
-# CONFIG_IA64_SGI_SN_XP is not set
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=4
CONFIG_HOTPLUG_CPU=y
# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
@@ -268,7 +257,6 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -407,7 +395,6 @@ CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
@@ -420,8 +407,6 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_TUNNEL is not set
CONFIG_IP_TCPDIAG=y
# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
@@ -613,7 +598,9 @@ CONFIG_GAMEPORT=m
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461X is not set
#
# Character devices
@@ -642,6 +629,7 @@ CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -755,7 +743,6 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -792,11 +779,9 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -853,7 +838,7 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_TEST is not set
#
-# USB DSL modem support
+# USB ATM/DSL drivers
#
#
@@ -871,10 +856,6 @@ CONFIG_USB_HIDINPUT=y
#
# CONFIG_INFINIBAND is not set
-#
-# SN Devices
-#
-
#
# File systems
#
@@ -882,7 +863,6 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -942,6 +922,7 @@ CONFIG_NTFS_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
CONFIG_TMPFS_XATTR=y
@@ -972,18 +953,15 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1091,7 +1069,6 @@ CONFIG_LOG_BUF_SHIFT=20
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
-# CONFIG_KPROBES is not set
CONFIG_IA64_GRANULE_16MB=y
# CONFIG_IA64_GRANULE_64MB is not set
# CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1113,7 +1090,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MD5=m
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
diff --git a/trunk/arch/ia64/configs/zx1_defconfig b/trunk/arch/ia64/configs/zx1_defconfig
index b7755e4436d2..21d6f9bab5e9 100644
--- a/trunk/arch/ia64/configs/zx1_defconfig
+++ b/trunk/arch/ia64/configs/zx1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc1-20050629
-# Wed Jun 29 15:31:11 2005
+# Linux kernel version: 2.6.10
+# Wed Dec 29 09:05:48 2004
#
#
@@ -12,7 +12,6 @@ CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -25,26 +24,23 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=17
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
-# CONFIG_CPUSETS is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -63,15 +59,12 @@ CONFIG_IA64=y
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_IA64_GENERIC is not set
# CONFIG_IA64_DIG is not set
CONFIG_IA64_HP_ZX1=y
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
# CONFIG_IA64_SGI_SN2 is not set
# CONFIG_IA64_HP_SIM is not set
# CONFIG_ITANIUM is not set
@@ -80,36 +73,22 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
CONFIG_IA64_L1_CACHE_SHIFT=7
# CONFIG_NUMA is not set
CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
# CONFIG_IA64_CYCLONE is not set
CONFIG_IOSAPIC=y
-# CONFIG_IA64_SGI_SN_XP is not set
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=16
# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
-CONFIG_ACPI_DEALLOCATE_IRQ=y
#
# Firmware Drivers
@@ -141,7 +120,6 @@ CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
-# CONFIG_ACPI_CONTAINER is not set
#
# Bus options (PCI, PCMCIA)
@@ -151,7 +129,6 @@ CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y
-# CONFIG_PCI_DEBUG is not set
#
# PCI Hotplug Support
@@ -161,6 +138,7 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set
#
@@ -168,6 +146,10 @@ CONFIG_HOTPLUG_PCI_ACPI=y
#
# CONFIG_PCCARD is not set
+#
+# PC-card bridges
+#
+
#
# Device Drivers
#
@@ -202,7 +184,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
@@ -222,7 +203,6 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -266,7 +246,6 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -296,7 +275,6 @@ CONFIG_CHR_DEV_OSST=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
-# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -310,7 +288,6 @@ CONFIG_SCSI_LOGGING=y
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
#
# SCSI low-level drivers
@@ -326,10 +303,13 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -339,6 +319,8 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
CONFIG_SCSI_QLOGIC_1280=y
@@ -349,7 +331,7 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_QLA6322 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -362,9 +344,9 @@ CONFIG_SCSI_QLA2XXX=y
#
# Fusion MPT device support
#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
+CONFIG_FUSION=y
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_CTL is not set
#
# IEEE 1394 (FireWire) support
@@ -386,12 +368,12 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
@@ -404,8 +386,6 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_TUNNEL is not set
# CONFIG_IP_TCPDIAG is not set
# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -425,6 +405,8 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_ARPTABLES=y
# CONFIG_IP_NF_ARPFILTER is not set
# CONFIG_IP_NF_ARP_MANGLE is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -501,6 +483,7 @@ CONFIG_NET_PCI=y
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=y
+# CONFIG_E100_NAPI is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
@@ -522,11 +505,9 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
-# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
-# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
@@ -583,6 +564,18 @@ CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+
#
# Input Device Drivers
#
@@ -592,16 +585,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
#
# Character devices
#
@@ -620,6 +603,7 @@ CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -627,7 +611,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -661,12 +644,6 @@ CONFIG_DRM_RADEON=y
# CONFIG_DRM_SIS is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
#
# I2C support
@@ -691,7 +668,6 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -715,14 +691,10 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
@@ -733,29 +705,21 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
#
# Other I2C Chip support
#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -782,7 +746,6 @@ CONFIG_VIDEO_DEV=y
#
# Video Adapters
#
-# CONFIG_TUNER_MULTI_I2C is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_CPIA is not set
# CONFIG_VIDEO_SAA5246A is not set
@@ -815,11 +778,6 @@ CONFIG_VIDEO_DEV=y
# Graphics support
#
CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
-# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -827,7 +785,6 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -844,7 +801,6 @@ CONFIG_FB_RADEON_DEBUG=y
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_PM3 is not set
-# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -864,7 +820,6 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -914,8 +869,6 @@ CONFIG_SND_AC97_CODEC=y
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_CA0106 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
@@ -923,7 +876,6 @@ CONFIG_SND_AC97_CODEC=y
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_ALS4000 is not set
@@ -941,14 +893,13 @@ CONFIG_SND_FM801_TEA575X=y
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
-# CONFIG_SND_HDA_INTEL is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
#
# Open Sound System
@@ -958,8 +909,6 @@ CONFIG_SND_FM801_TEA575X=y
#
# USB support
#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -971,6 +920,8 @@ CONFIG_USB_BANDWIDTH=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
@@ -978,10 +929,7 @@ CONFIG_USB_BANDWIDTH=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
@@ -999,11 +947,12 @@ CONFIG_USB_UHCI_HCD=y
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_RW_DETECT is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -1017,11 +966,9 @@ CONFIG_USB_HIDINPUT=y
CONFIG_USB_HIDDEV=y
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -1031,6 +978,7 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
#
# USB Multimedia devices
@@ -1044,7 +992,6 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_SE401 is not set
# CONFIG_USB_SN9C102 is not set
# CONFIG_USB_STV680 is not set
-# CONFIG_USB_PWC is not set
#
# USB Network Adapters
@@ -1054,7 +1001,6 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
#
# USB port drivers
@@ -1070,6 +1016,7 @@ CONFIG_USB_MON=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -1078,11 +1025,9 @@ CONFIG_USB_MON=y
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_SISUSBVGA is not set
#
-# USB DSL modem support
+# USB ATM/DSL drivers
#
#
@@ -1095,15 +1040,6 @@ CONFIG_USB_MON=y
#
# CONFIG_MMC is not set
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# SN Devices
-#
-
#
# File systems
#
@@ -1111,7 +1047,6 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_POSIX_ACL is not set
# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -1121,10 +1056,6 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1158,6 +1089,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
CONFIG_TMPFS_XATTR=y
@@ -1188,18 +1120,15 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
@@ -1280,8 +1209,6 @@ CONFIG_NLS_UTF8=y
# CONFIG_CRC_CCITT is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
#
# Profiling support
@@ -1291,18 +1218,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
#
# Kernel hacking
#
-# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=17
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-CONFIG_KPROBES=y
CONFIG_IA64_GRANULE_16MB=y
# CONFIG_IA64_GRANULE_64MB is not set
CONFIG_IA64_PRINT_HAZARDS=y
@@ -1329,7 +1252,6 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/trunk/arch/ia64/hp/common/sba_iommu.c b/trunk/arch/ia64/hp/common/sba_iommu.c
index 11957598a8b9..b8db6e3e5e81 100644
--- a/trunk/arch/ia64/hp/common/sba_iommu.c
+++ b/trunk/arch/ia64/hp/common/sba_iommu.c
@@ -156,13 +156,10 @@
*/
#define DELAYED_RESOURCE_CNT 64
-#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec
-
#define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
#define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP)
#define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP)
-#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP)
#define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */
@@ -1729,7 +1726,6 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = {
{ ZX1_IOC_ID, "zx1", ioc_zx1_init },
{ ZX2_IOC_ID, "zx2", NULL },
{ SX1000_IOC_ID, "sx1000", NULL },
- { SX2000_IOC_ID, "sx2000", NULL },
};
static struct ioc * __init
diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c
index 7a8ae0f4b387..786e70718ce4 100644
--- a/trunk/arch/ia64/hp/sim/simserial.c
+++ b/trunk/arch/ia64/hp/sim/simserial.c
@@ -30,7 +30,6 @@
#include
#include
#include
-#include
#include
#include
@@ -150,17 +149,12 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
seen_esc = 2;
continue;
} else if ( seen_esc == 2 ) {
- if ( ch == 'P' ) /* F1 */
- show_state();
-#ifdef CONFIG_MAGIC_SYSRQ
- if ( ch == 'S' ) { /* F4 */
- do
- ch = ia64_ssc(0, 0, 0, 0,
- SSC_GETCHAR);
- while (!ch);
- handle_sysrq(ch, regs, NULL);
- }
+ if ( ch == 'P' ) show_state(); /* F1 key */
+#ifdef CONFIG_KDB
+ if ( ch == 'S' )
+ kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs);
#endif
+
seen_esc = 0;
continue;
}
diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c
index cda06f88c66e..72dfd9e7de0f 100644
--- a/trunk/arch/ia64/kernel/acpi.c
+++ b/trunk/arch/ia64/kernel/acpi.c
@@ -236,7 +236,9 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
if (BAD_MADT_ENTRY(iosapic, end))
return -EINVAL;
- return iosapic_init(iosapic->address, iosapic->global_irq_base);
+ iosapic_init(iosapic->address, iosapic->global_irq_base);
+
+ return 0;
}
@@ -770,7 +772,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
#ifdef CONFIG_ACPI_NUMA
-acpi_status __devinit
+acpi_status __init
acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
{
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -823,28 +825,4 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
return AE_OK;
}
#endif /* CONFIG_NUMA */
-
-int
-acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
-{
- int err;
-
- if ((err = iosapic_init(phys_addr, gsi_base)))
- return err;
-
-#if CONFIG_ACPI_NUMA
- acpi_map_iosapic(handle, 0, NULL, NULL);
-#endif /* CONFIG_ACPI_NUMA */
-
- return 0;
-}
-EXPORT_SYMBOL(acpi_register_ioapic);
-
-int
-acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
-{
- return iosapic_remove(gsi_base);
-}
-EXPORT_SYMBOL(acpi_unregister_ioapic);
-
#endif /* CONFIG_ACPI_BOOT */
diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S
index 69f88d561d62..785a51b0ad8e 100644
--- a/trunk/arch/ia64/kernel/entry.S
+++ b/trunk/arch/ia64/kernel/entry.S
@@ -470,6 +470,18 @@ ENTRY(load_switch_stack)
br.cond.sptk.many b7
END(load_switch_stack)
+GLOBAL_ENTRY(__ia64_syscall)
+ .regstk 6,0,0,0
+ mov r15=in5 // put syscall number in place
+ break __BREAK_SYSCALL
+ movl r2=errno
+ cmp.eq p6,p7=-1,r10
+ ;;
+(p6) st4 [r2]=r8
+(p6) mov r8=-1
+ br.ret.sptk.many rp
+END(__ia64_syscall)
+
GLOBAL_ENTRY(execve)
mov r15=__NR_execve // put syscall number in place
break __BREAK_SYSCALL
@@ -625,7 +637,7 @@ END(ia64_ret_from_syscall)
* r8-r11: restored (syscall return value(s))
* r12: restored (user-level stack pointer)
* r13: restored (user-level thread pointer)
- * r14: set to __kernel_syscall_via_epc
+ * r14: cleared
* r15: restored (syscall #)
* r16-r17: cleared
* r18: user-level b6
@@ -646,7 +658,7 @@ END(ia64_ret_from_syscall)
* pr: restored (user-level pr)
* b0: restored (user-level rp)
* b6: restored
- * b7: set to __kernel_syscall_via_epc
+ * b7: cleared
* ar.unat: restored (user-level ar.unat)
* ar.pfs: restored (user-level ar.pfs)
* ar.rsc: restored (user-level ar.rsc)
@@ -692,79 +704,72 @@ ENTRY(ia64_leave_syscall)
;;
(p6) ld4 r31=[r18] // load current_thread_info()->flags
ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs"
- nop.i 0
+ mov b7=r0 // clear b7
;;
- mov r16=ar.bsp // M2 get existing backing store pointer
+ ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage)
ld8 r18=[r2],PT(R9)-PT(B6) // load b6
(p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE?
;;
- ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage)
+ mov r16=ar.bsp // M2 get existing backing store pointer
(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending?
(p6) br.cond.spnt .work_pending_syscall
;;
// start restoring the state saved on the kernel stack (struct pt_regs):
ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
ld8 r11=[r3],PT(CR_IIP)-PT(R11)
-(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE!
+ mov f6=f0 // clear f6
;;
invala // M0|1 invalidate ALAT
- rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection
- cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs
+ rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection
+ mov f9=f0 // clear f9
- ld8 r29=[r2],16 // M0|1 load cr.ipsr
- ld8 r28=[r3],16 // M0|1 load cr.iip
- mov r22=r0 // A clear r22
+ ld8 r29=[r2],16 // load cr.ipsr
+ ld8 r28=[r3],16 // load cr.iip
+ mov f8=f0 // clear f8
;;
ld8 r30=[r2],16 // M0|1 load cr.ifs
ld8 r25=[r3],16 // M0|1 load ar.unat
-(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+ cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs
;;
ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
-(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
- nop 0
+(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
+ mov f10=f0 // clear f10
;;
- ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
- ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc
- mov f6=f0 // F clear f6
+ ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
+ ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc
+ mov f11=f0 // clear f11
;;
- ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage)
- ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates
- mov f7=f0 // F clear f7
+ ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage)
+ ld8 r31=[r3],PT(R1)-PT(PR) // load predicates
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
;;
- ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr
- ld8.fill r1=[r3],16 // M0|1 load r1
-(pUStk) mov r17=1 // A
+ ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr
+ ld8.fill r1=[r3],16 // load r1
+(pUStk) mov r17=1
;;
-(pUStk) st1 [r14]=r17 // M2|3
- ld8.fill r13=[r3],16 // M0|1
- mov f8=f0 // F clear f8
+ srlz.d // M0 ensure interruption collection is off
+ ld8.fill r13=[r3],16
+ mov f7=f0 // clear f7
;;
- ld8.fill r12=[r2] // M0|1 restore r12 (sp)
- ld8.fill r15=[r3] // M0|1 restore r15
- mov b6=r18 // I0 restore b6
+ ld8.fill r12=[r2] // restore r12 (sp)
+ mov.m ar.ssd=r0 // M2 clear ar.ssd
+ mov r22=r0 // clear r22
- addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
- mov f9=f0 // F clear f9
-(pKStk) br.cond.dpnt.many skip_rbs_switch // B
-
- srlz.d // M0 ensure interruption collection is off (for cover)
- shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
- cover // B add current frame into dirty partition & set cr.ifs
+ ld8.fill r15=[r3] // restore r15
+(pUStk) st1 [r14]=r17
+ addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
;;
-(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8
- mov r19=ar.bsp // M2 get new backing store pointer
- mov f10=f0 // F clear f10
-
- nop.m 0
- movl r14=__kernel_syscall_via_epc // X
+(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8
+ mov.m ar.csd=r0 // M2 clear ar.csd
+ mov b6=r18 // I0 restore b6
;;
- mov.m ar.csd=r0 // M2 clear ar.csd
- mov.m ar.ccv=r0 // M2 clear ar.ccv
- mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc)
+ mov r14=r0 // clear r14
+ shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
+(pKStk) br.cond.dpnt.many skip_rbs_switch
- mov.m ar.ssd=r0 // M2 clear ar.ssd
- mov f11=f0 // F clear f11
- br.cond.sptk.many rbs_switch // B
+ mov.m ar.ccv=r0 // clear ar.ccv
+(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
+ br.cond.sptk.many rbs_switch
END(ia64_leave_syscall)
#ifdef CONFIG_IA32_SUPPORT
@@ -880,7 +885,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
ldf.fill f7=[r2],PT(F11)-PT(F7)
ldf.fill f8=[r3],32
;;
- srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned)
+ srlz.i // ensure interruption collection is off
mov ar.ccv=r15
;;
ldf.fill f11=[r2]
@@ -940,10 +945,11 @@ GLOBAL_ENTRY(ia64_leave_kernel)
* NOTE: alloc, loadrs, and cover can't be predicated.
*/
(pNonSys) br.cond.dpnt dont_preserve_current_frame
+
+rbs_switch:
cover // add current frame into dirty partition and set cr.ifs
;;
mov r19=ar.bsp // get new backing store pointer
-rbs_switch:
sub r16=r16,r18 // krbs = old bsp - size of dirty partition
cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs
;;
@@ -1018,14 +1024,14 @@ rse_clear_invalid:
mov loc5=0
mov loc6=0
mov loc7=0
-(pRecurse) br.call.dptk.few b0=rse_clear_invalid
+(pRecurse) br.call.sptk.few b0=rse_clear_invalid
;;
mov loc8=0
mov loc9=0
cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret
mov loc10=0
mov loc11=0
-(pReturn) br.ret.dptk.many b0
+(pReturn) br.ret.sptk.many b0
#endif /* !CONFIG_ITANIUM */
# undef pRecurse
# undef pReturn
diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S
index 7d7684a369d3..962b6c4e32b5 100644
--- a/trunk/arch/ia64/kernel/fsys.S
+++ b/trunk/arch/ia64/kernel/fsys.S
@@ -531,114 +531,93 @@ GLOBAL_ENTRY(fsys_bubble_down)
.altrp b6
.body
/*
- * We get here for syscalls that don't have a lightweight
- * handler. For those, we need to bubble down into the kernel
- * and that requires setting up a minimal pt_regs structure,
- * and initializing the CPU state more or less as if an
- * interruption had occurred. To make syscall-restarts work,
- * we setup pt_regs such that cr_iip points to the second
- * instruction in syscall_via_break. Decrementing the IP
- * hence will restart the syscall via break and not
- * decrementing IP will return us to the caller, as usual.
- * Note that we preserve the value of psr.pp rather than
- * initializing it from dcr.pp. This makes it possible to
- * distinguish fsyscall execution from other privileged
- * execution.
+ * We get here for syscalls that don't have a lightweight handler. For those, we
+ * need to bubble down into the kernel and that requires setting up a minimal
+ * pt_regs structure, and initializing the CPU state more or less as if an
+ * interruption had occurred. To make syscall-restarts work, we setup pt_regs
+ * such that cr_iip points to the second instruction in syscall_via_break.
+ * Decrementing the IP hence will restart the syscall via break and not
+ * decrementing IP will return us to the caller, as usual. Note that we preserve
+ * the value of psr.pp rather than initializing it from dcr.pp. This makes it
+ * possible to distinguish fsyscall execution from other privileged execution.
*
* On entry:
- * - normal fsyscall handler register usage, except
- * that we also have:
+ * - normal fsyscall handler register usage, except that we also have:
* - r18: address of syscall entry point
* - r21: ar.fpsr
* - r26: ar.pfs
* - r27: ar.rsc
* - r29: psr
- *
- * We used to clear some PSR bits here but that requires slow
- * serialization. Fortuntely, that isn't really necessary.
- * The rationale is as follows: we used to clear bits
- * ~PSR_PRESERVED_BITS in PSR.L. Since
- * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we
- * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}.
- * However,
- *
- * PSR.BE : already is turned off in __kernel_syscall_via_epc()
- * PSR.AC : don't care (kernel normally turns PSR.AC on)
- * PSR.I : already turned off by the time fsys_bubble_down gets
- * invoked
- * PSR.DFL: always 0 (kernel never turns it on)
- * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
- * initiative
- * PSR.DI : always 0 (kernel never turns it on)
- * PSR.SI : always 0 (kernel never turns it on)
- * PSR.DB : don't care --- kernel never enables kernel-level
- * breakpoints
- * PSR.TB : must be 0 already; if it wasn't zero on entry to
- * __kernel_syscall_via_epc, the branch to fsys_bubble_down
- * will trigger a taken branch; the taken-trap-handler then
- * converts the syscall into a break-based system-call.
*/
+# define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \
+ | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \
+ | IA64_PSR_IC)
/*
- * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.
- * The rest we have to synthesize.
+ * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have
+ * to synthesize.
*/
-# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \
- | (0x1 << IA64_PSR_RI_BIT) \
+# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
| IA64_PSR_BN | IA64_PSR_I)
- invala // M0|1
- movl r14=ia64_ret_from_syscall // X
+ invala
+ movl r8=PSR_ONE_BITS
- nop.m 0
- movl r28=__kernel_syscall_via_break // X create cr.iip
- ;;
+ mov r25=ar.unat // save ar.unat (5 cyc)
+ movl r9=PSR_PRESERVED_BITS
- mov r2=r16 // A get task addr to addl-addressable register
- adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A
- mov r31=pr // I0 save pr (2 cyc)
+ mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0
+ movl r28=__kernel_syscall_via_break
;;
- st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
- addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS
- add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A
+ mov r23=ar.bspstore // save ar.bspstore (12 cyc)
+ mov r31=pr // save pr (2 cyc)
+ mov r20=r1 // save caller's gp in r20
;;
- ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags
- lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store
- nop.i 0
+ mov r2=r16 // copy current task addr to addl-addressable register
+ and r9=r9,r29
+ mov r19=b6 // save b6 (2 cyc)
;;
- mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0
- nop.m 0
- nop.i 0
+ mov psr.l=r9 // slam the door (17 cyc to srlz.i)
+ or r29=r8,r29 // construct cr.ipsr value to save
+ addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS
;;
- mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore
- mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!)
- nop.i 0
+ // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks
+ // we may be reading ar.itc after writing to psr.l. Avoid that message with
+ // this directive:
+ dv_serialize_data
+ mov.m r24=ar.rnat // read ar.rnat (5 cyc lat)
+ lfetch.fault.excl.nt1 [r22]
+ adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2
+
+ // ensure previous insn group is issued before we stall for srlz.i:
;;
- mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS
- movl r8=PSR_ONE_BITS // X
+ srlz.i // ensure new psr.l has been established
+ /////////////////////////////////////////////////////////////////////////////
+ ////////// from this point on, execution is not interruptible anymore
+ /////////////////////////////////////////////////////////////////////////////
+ addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack
+ cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1
;;
- mov r25=ar.unat // M2 (5 cyc) save ar.unat
- mov r19=b6 // I0 save b6 (2 cyc)
- mov r20=r1 // A save caller's gp in r20
+ st1 [r16]=r0 // clear current->thread.on_ustack flag
+ mov ar.bspstore=r22 // switch to kernel RBS
+ mov b6=r18 // copy syscall entry-point to b6 (7 cyc)
+ add r3=TI_FLAGS+IA64_TASK_SIZE,r2
;;
- or r29=r8,r29 // A construct cr.ipsr value to save
- mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc)
- addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack
-
- mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc)
- cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1
- br.call.sptk.many b7=ia64_syscall_setup // B
+ ld4 r3=[r3] // r2 = current_thread_info()->flags
+ mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc)
+ mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0
+ br.call.sptk.many b7=ia64_syscall_setup
+ ;;
+ ssm psr.i
+ movl r2=ia64_ret_from_syscall
;;
- mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
- mov rp=r14 // I0 set the real return addr
- and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A
+ mov rp=r2 // set the real return addr
+ and r3=_TIF_SYSCALL_TRACEAUDIT,r3
;;
- ssm psr.i // M2 we're on kernel stacks now, reenable irqs
- cmp.eq p8,p0=r3,r0 // A
-(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
+ cmp.eq p8,p0=r3,r0
- nop.m 0
-(p8) br.call.sptk.many b6=b6 // B (ignore return address)
- br.cond.spnt ia64_trace_syscall // B
+(p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8
+(p8) br.call.sptk.many b6=b6 // ignore this return addr
+ br.cond.sptk ia64_trace_syscall
END(fsys_bubble_down)
.rodata
diff --git a/trunk/arch/ia64/kernel/gate.S b/trunk/arch/ia64/kernel/gate.S
index 86948ce63e43..facf75acdc85 100644
--- a/trunk/arch/ia64/kernel/gate.S
+++ b/trunk/arch/ia64/kernel/gate.S
@@ -72,40 +72,38 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
* bundle get executed. The remaining code must be safe even if
* they do not get executed.
*/
- adds r17=-1024,r15 // A
- mov r10=0 // A default to successful syscall execution
- epc // B causes split-issue
+ adds r17=-1024,r15
+ mov r10=0 // default to successful syscall execution
+ epc
}
;;
- rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
- LOAD_FSYSCALL_TABLE(r14) // X
- ;;
- mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
- shladd r18=r17,3,r14 // A
- mov r19=NR_syscalls-1 // A
- ;;
- lfetch [r18] // M0|1
- mov r29=psr // M2 (12 cyc)
- // If r17 is a NaT, p6 will be zero
- cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
- ;;
- mov r21=ar.fpsr // M2 (12 cyc)
- tnat.nz p10,p9=r15 // I0
- mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
- ;;
- srlz.d // M0 (forces split-issue) ensure PSR.BE==0
-(p6) ld8 r18=[r18] // M0|1
- nop.i 0
- ;;
- nop.m 0
-(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
- nop.i 0
+ rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be"
+ LOAD_FSYSCALL_TABLE(r14)
+
+ mov r16=IA64_KR(CURRENT) // 12 cycle read latency
+ tnat.nz p10,p9=r15
+ mov r19=NR_syscalls-1
;;
-(p8) ssm psr.i
-(p6) mov b7=r18 // I0
-(p8) br.dptk.many b7 // B
+ shladd r18=r17,3,r14
+
+ srlz.d
+ cmp.ne p8,p0=r0,r0 // p8 <- FALSE
+ /* Note: if r17 is a NaT, p6 will be set to zero. */
+ cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)?
+ ;;
+(p6) ld8 r18=[r18]
+ mov r21=ar.fpsr
+ add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
+ ;;
+(p6) mov b7=r18
+(p6) tbit.z p8,p0=r18,0
+(p8) br.dptk.many b7
- mov r27=ar.rsc // M2 (12 cyc)
+(p6) rsm psr.i
+ mov r27=ar.rsc
+ mov r26=ar.pfs
+ ;;
+ mov r29=psr // read psr (12 cyc load latency)
/*
* brl.cond doesn't work as intended because the linker would convert this branch
* into a branch to a PLT. Perhaps there will be a way to avoid this with some
@@ -113,8 +111,6 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
* instead.
*/
#ifdef CONFIG_ITANIUM
-(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
- ;;
(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
;;
(p6) mov b7=r14
@@ -122,7 +118,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
#else
BRL_COND_FSYS_BUBBLE_DOWN(p6)
#endif
- ssm psr.i
+
mov r10=-1
(p10) mov r8=EINVAL
(p9) mov r8=ENOSYS
diff --git a/trunk/arch/ia64/kernel/ia64_ksyms.c b/trunk/arch/ia64/kernel/ia64_ksyms.c
index 01572814abe4..7bbf019c9867 100644
--- a/trunk/arch/ia64/kernel/ia64_ksyms.c
+++ b/trunk/arch/ia64/kernel/ia64_ksyms.c
@@ -58,6 +58,9 @@ EXPORT_SYMBOL(__strlen_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(__strnlen_user);
+#include
+EXPORT_SYMBOL(__ia64_syscall);
+
/* from arch/ia64/lib */
extern void __divsi3(void);
extern void __udivsi3(void);
diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c
index c170be095ccd..88b014381df5 100644
--- a/trunk/arch/ia64/kernel/iosapic.c
+++ b/trunk/arch/ia64/kernel/iosapic.c
@@ -129,13 +129,14 @@ static struct iosapic {
char __iomem *addr; /* base address of IOSAPIC */
unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
unsigned short num_rte; /* number of RTE in this IOSAPIC */
- int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
#ifdef CONFIG_NUMA
unsigned short node; /* numa node association via pxm */
#endif
} iosapic_lists[NR_IOSAPICS];
-static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
+static int num_iosapic;
+
+static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */
static int iosapic_kmalloc_ok;
static LIST_HEAD(free_rte_list);
@@ -148,7 +149,7 @@ find_iosapic (unsigned int gsi)
{
int i;
- for (i = 0; i < NR_IOSAPICS; i++) {
+ for (i = 0; i < num_iosapic; i++) {
if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
return i;
}
@@ -597,7 +598,6 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
rte->refcnt++;
list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
iosapic_intr_info[vector].count++;
- iosapic_lists[index].rtes_inuse++;
}
else if (vector_is_shared(vector)) {
struct iosapic_intr_info *info = &iosapic_intr_info[vector];
@@ -778,7 +778,7 @@ void
iosapic_unregister_intr (unsigned int gsi)
{
unsigned long flags;
- int irq, vector, index;
+ int irq, vector;
irq_desc_t *idesc;
u32 low32;
unsigned long trigger, polarity;
@@ -819,9 +819,6 @@ iosapic_unregister_intr (unsigned int gsi)
list_del(&rte->rte_list);
iosapic_intr_info[vector].count--;
iosapic_free_rte(rte);
- index = find_iosapic(gsi);
- iosapic_lists[index].rtes_inuse--;
- WARN_ON(iosapic_lists[index].rtes_inuse < 0);
trigger = iosapic_intr_info[vector].trigger;
polarity = iosapic_intr_info[vector].polarity;
@@ -955,86 +952,30 @@ iosapic_system_init (int system_pcat_compat)
}
}
-static inline int
-iosapic_alloc (void)
-{
- int index;
-
- for (index = 0; index < NR_IOSAPICS; index++)
- if (!iosapic_lists[index].addr)
- return index;
-
- printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
- return -1;
-}
-
-static inline void
-iosapic_free (int index)
-{
- memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
-}
-
-static inline int
-iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
-{
- int index;
- unsigned int gsi_end, base, end;
-
- /* check gsi range */
- gsi_end = gsi_base + ((ver >> 16) & 0xff);
- for (index = 0; index < NR_IOSAPICS; index++) {
- if (!iosapic_lists[index].addr)
- continue;
-
- base = iosapic_lists[index].gsi_base;
- end = base + iosapic_lists[index].num_rte - 1;
-
- if (gsi_base < base && gsi_end < base)
- continue;/* OK */
-
- if (gsi_base > end && gsi_end > end)
- continue; /* OK */
-
- return -EBUSY;
- }
- return 0;
-}
-
-int __devinit
+void __init
iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
{
- int num_rte, err, index;
+ int num_rte;
unsigned int isa_irq, ver;
char __iomem *addr;
- unsigned long flags;
-
- spin_lock_irqsave(&iosapic_lock, flags);
- {
- addr = ioremap(phys_addr, 0);
- ver = iosapic_version(addr);
- if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
- iounmap(addr);
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return err;
- }
+ addr = ioremap(phys_addr, 0);
+ ver = iosapic_version(addr);
- /*
- * The MAX_REDIR register holds the highest input pin
- * number (starting from 0).
- * We add 1 so that we can use it for number of pins (= RTEs)
- */
- num_rte = ((ver >> 16) & 0xff) + 1;
+ /*
+ * The MAX_REDIR register holds the highest input pin
+ * number (starting from 0).
+ * We add 1 so that we can use it for number of pins (= RTEs)
+ */
+ num_rte = ((ver >> 16) & 0xff) + 1;
- index = iosapic_alloc();
- iosapic_lists[index].addr = addr;
- iosapic_lists[index].gsi_base = gsi_base;
- iosapic_lists[index].num_rte = num_rte;
+ iosapic_lists[num_iosapic].addr = addr;
+ iosapic_lists[num_iosapic].gsi_base = gsi_base;
+ iosapic_lists[num_iosapic].num_rte = num_rte;
#ifdef CONFIG_NUMA
- iosapic_lists[index].node = MAX_NUMNODES;
+ iosapic_lists[num_iosapic].node = MAX_NUMNODES;
#endif
- }
- spin_unlock_irqrestore(&iosapic_lock, flags);
+ num_iosapic++;
if ((gsi_base == 0) && pcat_compat) {
/*
@@ -1045,43 +986,10 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
for (isa_irq = 0; isa_irq < 16; ++isa_irq)
iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
}
- return 0;
-}
-
-#ifdef CONFIG_HOTPLUG
-int
-iosapic_remove (unsigned int gsi_base)
-{
- int index, err = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&iosapic_lock, flags);
- {
- index = find_iosapic(gsi_base);
- if (index < 0) {
- printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
- __FUNCTION__, gsi_base);
- goto out;
- }
-
- if (iosapic_lists[index].rtes_inuse) {
- err = -EBUSY;
- printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
- __FUNCTION__, gsi_base);
- goto out;
- }
-
- iounmap(iosapic_lists[index].addr);
- iosapic_free(index);
- }
- out:
- spin_unlock_irqrestore(&iosapic_lock, flags);
- return err;
}
-#endif /* CONFIG_HOTPLUG */
#ifdef CONFIG_NUMA
-void __devinit
+void __init
map_iosapic_to_node(unsigned int gsi_base, int node)
{
int index;
diff --git a/trunk/arch/ia64/kernel/ivt.S b/trunk/arch/ia64/kernel/ivt.S
index 3bb3a13c4047..2bc085a73e30 100644
--- a/trunk/arch/ia64/kernel/ivt.S
+++ b/trunk/arch/ia64/kernel/ivt.S
@@ -1,7 +1,7 @@
/*
* arch/ia64/kernel/ivt.S
*
- * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
* Stephane Eranian
* David Mosberger
* Copyright (C) 2000, 2002-2003 Intel Co
@@ -692,118 +692,82 @@ ENTRY(break_fault)
* to prevent leaking bits from kernel to user level.
*/
DBG_FAULT(11)
- mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
- mov r29=cr.ipsr // M2 (12 cyc)
- mov r31=pr // I0 (2 cyc)
-
- mov r17=cr.iim // M2 (2 cyc)
- mov.m r27=ar.rsc // M2 (12 cyc)
- mov r18=__IA64_BREAK_SYSCALL // A
-
- mov.m ar.rsc=0 // M2
- mov.m r21=ar.fpsr // M2 (12 cyc)
- mov r19=b6 // I0 (2 cyc)
- ;;
- mov.m r23=ar.bspstore // M2 (12 cyc)
- mov.m r24=ar.rnat // M2 (5 cyc)
- mov.i r26=ar.pfs // I0 (2 cyc)
-
- invala // M0|1
- nop.m 0 // M
- mov r20=r1 // A save r1
-
- nop.m 0
- movl r30=sys_call_table // X
-
- mov r28=cr.iip // M2 (2 cyc)
- cmp.eq p0,p7=r18,r17 // I0 is this a system call?
-(p7) br.cond.spnt non_syscall // B no ->
- //
- // From this point on, we are definitely on the syscall-path
- // and we can use (non-banked) scratch registers.
- //
-///////////////////////////////////////////////////////////////////////
- mov r1=r16 // A move task-pointer to "addl"-addressable reg
- mov r2=r16 // A setup r2 for ia64_syscall_setup
- add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags
-
+ mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat.
+ mov r17=cr.iim
+ mov r18=__IA64_BREAK_SYSCALL
+ mov r21=ar.fpsr
+ mov r29=cr.ipsr
+ mov r19=b6
+ mov r25=ar.unat
+ mov r27=ar.rsc
+ mov r26=ar.pfs
+ mov r28=cr.iip
+ mov r31=pr // prepare to save predicates
+ mov r20=r1
+ ;;
adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
- adds r15=-1024,r15 // A subtract 1024 from syscall number
- mov r3=NR_syscalls - 1
+ cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so)
+(p7) br.cond.spnt non_syscall
;;
- ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag
- ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags
- extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr
-
- shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024)
- addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS
- cmp.leu p6,p7=r15,r3 // A syscall number in range?
+ ld1 r17=[r16] // load current->thread.on_ustack flag
+ st1 [r16]=r0 // clear current->thread.on_ustack flag
+ add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT
;;
+ invala
- lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS
-(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point
- tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT?
+ /* adjust return address so we skip over the break instruction: */
- mov.m ar.bspstore=r22 // M2 switch to kernel RBS
- cmp.eq p8,p9=2,r8 // A isr.ei==2?
+ extr.u r8=r29,41,2 // extract ei field from cr.ipsr
;;
-
-(p8) mov r8=0 // A clear ei to 0
-(p7) movl r30=sys_ni_syscall // X
-
-(p8) adds r28=16,r28 // A switch cr.iip to next bundle
-(p9) adds r8=1,r8 // A increment ei to next slot
- nop.i 0
+ cmp.eq p6,p7=2,r8 // isr.ei==2?
+ mov r2=r1 // setup r2 for ia64_syscall_setup
;;
-
- mov.m r25=ar.unat // M2 (5 cyc)
- dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr
- adds r15=1024,r15 // A restore original syscall number
- //
- // If any of the above loads miss in L1D, we'll stall here until
- // the data arrives.
- //
-///////////////////////////////////////////////////////////////////////
- st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
- mov b6=r30 // I0 setup syscall handler branch reg early
- cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already?
-
- and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit
- mov r18=ar.bsp // M2 (12 cyc)
-(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS
- ;;
-.back_from_break_fixup:
-(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack
- cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited?
- br.call.sptk.many b7=ia64_syscall_setup // B
-1:
- mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
- nop 0
- bsw.1 // B (6 cyc) regs are saved, switch to bank 1
+(p6) mov r8=0 // clear ei to 0
+(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped
+(p7) adds r8=1,r8 // increment ei to next slot
+ ;;
+ cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already?
+ dep r29=r8,r29,41,2 // insert new ei into cr.ipsr
;;
- ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection
- movl r3=ia64_ret_from_syscall // X
+ // switch from user to kernel RBS:
+ MINSTATE_START_SAVE_MIN_VIRT
+ br.call.sptk.many b7=ia64_syscall_setup
;;
+ MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1
+ ssm psr.ic | PSR_DEFAULT_BITS
+ ;;
+ srlz.i // guarantee that interruption collection is on
+ mov r3=NR_syscalls - 1
+ ;;
+(p15) ssm psr.i // restore psr.i
+ // p10==true means out registers are more than 8 or r15's Nat is true
+(p10) br.cond.spnt.many ia64_ret_from_syscall
+ ;;
+ movl r16=sys_call_table
- srlz.i // M0 ensure interruption collection is on
- mov rp=r3 // I0 set the real return addr
-(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
+ adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
+ movl r2=ia64_ret_from_syscall
+ ;;
+ shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024)
+ cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ?
+ mov rp=r2 // set the real return addr
+ ;;
+(p6) ld8 r20=[r20] // load address of syscall entry point
+(p7) movl r20=sys_ni_syscall
-(p15) ssm psr.i // M2 restore psr.i
-(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr)
- br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic
+ add r2=TI_FLAGS+IA64_TASK_SIZE,r13
+ ;;
+ ld4 r2=[r2] // r2 = current_thread_info()->flags
+ ;;
+ and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit
+ ;;
+ cmp.eq p8,p0=r2,r0
+ mov b6=r20
+ ;;
+(p8) br.call.sptk.many b6=b6 // ignore this return addr
+ br.cond.sptk ia64_trace_syscall
// NOT REACHED
-///////////////////////////////////////////////////////////////////////
- // On entry, we optimistically assumed that we're coming from user-space.
- // For the rare cases where a system-call is done from within the kernel,
- // we fix things up at this point:
-.break_fixup:
- add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure
- mov ar.rnat=r24 // M2 restore kernel's AR.RNAT
- ;;
- mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE
- br.cond.sptk .back_from_break_fixup
END(break_fault)
.org ia64_ivt+0x3000
@@ -878,6 +842,8 @@ END(interrupt)
* - r31: saved pr
* - b0: original contents (to be saved)
* On exit:
+ * - executing on bank 1 registers
+ * - psr.ic enabled, interrupts restored
* - p10: TRUE if syscall is invoked with more than 8 out
* registers or r15's Nat is true
* - r1: kernel's gp
@@ -885,11 +851,8 @@ END(interrupt)
* - r8: -EINVAL if p10 is true
* - r12: points to kernel stack
* - r13: points to current task
- * - r14: preserved (same as on entry)
- * - p13: preserved
* - p15: TRUE if interrupts need to be re-enabled
* - ar.fpsr: set to kernel settings
- * - b6: preserved (same as on entry)
*/
GLOBAL_ENTRY(ia64_syscall_setup)
#if PT(B6) != 0
@@ -957,10 +920,10 @@ GLOBAL_ENTRY(ia64_syscall_setup)
(p13) mov in5=-1
;;
st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
- tnat.nz p13,p0=in6
+ tnat.nz p14,p0=in6
cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
;;
- mov r8=1
+ stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
(p9) tnat.nz p10,p0=r15
adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch)
@@ -971,9 +934,9 @@ GLOBAL_ENTRY(ia64_syscall_setup)
mov r13=r2 // establish `current'
movl r1=__gp // establish kernel global pointer
;;
- st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
-(p13) mov in6=-1
+(p14) mov in6=-1
(p8) mov in7=-1
+ nop.i 0
cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
movl r17=FPSR_DEFAULT
@@ -1044,8 +1007,6 @@ END(dispatch_illegal_op_fault)
FAULT(17)
ENTRY(non_syscall)
- mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER
- ;;
SAVE_MIN_WITH_COVER
// There is no particular reason for this code to be here, other than that
@@ -1243,25 +1204,6 @@ END(disabled_fp_reg)
// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
ENTRY(nat_consumption)
DBG_FAULT(26)
-
- mov r16=cr.ipsr
- mov r17=cr.isr
- mov r31=pr // save PR
- ;;
- and r18=0xf,r17 // r18 = cr.ipsr.code{3:0}
- tbit.z p6,p0=r17,IA64_ISR_NA_BIT
- ;;
- cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
- dep r16=-1,r16,IA64_PSR_ED_BIT,1
-(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
- ;;
- mov cr.ipsr=r16 // set cr.ipsr.na
- mov pr=r31,-1
- ;;
- rfi
-
-1: mov pr=r31,-1
- ;;
FAULT(26)
END(nat_consumption)
diff --git a/trunk/arch/ia64/kernel/ptrace.c b/trunk/arch/ia64/kernel/ptrace.c
index bbb8bc7c0552..6d57aebad485 100644
--- a/trunk/arch/ia64/kernel/ptrace.c
+++ b/trunk/arch/ia64/kernel/ptrace.c
@@ -725,32 +725,12 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
break;
}
- /*
- * Note: at the time of this call, the target task is blocked
- * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL
- * (aka, "pLvSys") we redirect execution from
- * .work_pending_syscall_end to .work_processed_kernel.
- */
unw_get_pr(&prev_info, &pr);
- pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL));
+ pr &= ~(1UL << PRED_SYSCALL);
pr |= (1UL << PRED_NON_SYSCALL);
unw_set_pr(&prev_info, pr);
pt->cr_ifs = (1UL << 63) | cfm;
- /*
- * Clear the memory that is NOT written on syscall-entry to
- * ensure we do not leak kernel-state to user when execution
- * resumes.
- */
- pt->r2 = 0;
- pt->r3 = 0;
- pt->r14 = 0;
- memset(&pt->r16, 0, 16*8); /* clear r16-r31 */
- memset(&pt->f6, 0, 6*16); /* clear f6-f11 */
- pt->b7 = 0;
- pt->ar_ccv = 0;
- pt->ar_csd = 0;
- pt->ar_ssd = 0;
}
static int
diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c
index 2693e1522d7c..d14692e0920a 100644
--- a/trunk/arch/ia64/kernel/setup.c
+++ b/trunk/arch/ia64/kernel/setup.c
@@ -72,8 +72,6 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
unsigned long ia64_cycles_per_usec;
struct ia64_boot_param *ia64_boot_param;
struct screen_info screen_info;
-unsigned long vga_console_iobase;
-unsigned long vga_console_membase;
unsigned long ia64_max_cacheline_size;
unsigned long ia64_iobase; /* virtual address for I/O accesses */
@@ -275,25 +273,23 @@ io_port_init (void)
static inline int __init
early_console_setup (char *cmdline)
{
- int earlycons = 0;
-
#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
{
extern int sn_serial_console_early_setup(void);
if (!sn_serial_console_early_setup())
- earlycons++;
+ return 0;
}
#endif
#ifdef CONFIG_EFI_PCDP
if (!efi_setup_pcdp_console(cmdline))
- earlycons++;
+ return 0;
#endif
#ifdef CONFIG_SERIAL_8250_CONSOLE
if (!early_serial_console_init(cmdline))
- earlycons++;
+ return 0;
#endif
- return (earlycons) ? 0 : -1;
+ return -1;
}
static inline void
diff --git a/trunk/arch/ia64/kernel/smp.c b/trunk/arch/ia64/kernel/smp.c
index 0166a9847095..b49d4ddaab93 100644
--- a/trunk/arch/ia64/kernel/smp.c
+++ b/trunk/arch/ia64/kernel/smp.c
@@ -231,16 +231,13 @@ smp_flush_tlb_all (void)
void
smp_flush_tlb_mm (struct mm_struct *mm)
{
- preempt_disable();
/* this happens for the common case of a single-threaded fork(): */
if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
{
local_finish_flush_tlb_mm(mm);
- preempt_enable();
return;
}
- preempt_enable();
/*
* We could optimize this further by using mm->cpu_vm_mask to track which CPUs
* have been running in the address space. It's not clear that this is worth the
diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c
index 720a861f88be..e3fc4edea113 100644
--- a/trunk/arch/ia64/pci/pci.c
+++ b/trunk/arch/ia64/pci/pci.c
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
&info);
- pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
+ pbus = pci_scan_bus(bus, &pci_root_ops, controller);
if (pbus)
pcibios_setup_root_windows(pbus, controller);
@@ -373,25 +373,6 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
res->end = region->end + offset;
}
-static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
-{
- unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
- struct resource *devr = &dev->resource[idx];
-
- if (!dev->bus)
- return 0;
- for (i=0; ibus->resource[i];
-
- if (!busr || ((busr->flags ^ devr->flags) & type_mask))
- continue;
- if ((devr->start) && (devr->start >= busr->start) &&
- (devr->end <= busr->end))
- return 1;
- }
- return 0;
-}
-
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
{
struct pci_bus_region region;
@@ -405,8 +386,7 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
region.start = dev->resource[i].start;
region.end = dev->resource[i].end;
pcibios_bus_to_resource(dev, &dev->resource[i], ®ion);
- if ((is_valid_resource(dev, i)))
- pci_claim_resource(dev, i);
+ pci_claim_resource(dev, i);
}
}
@@ -418,10 +398,6 @@ pcibios_fixup_bus (struct pci_bus *b)
{
struct pci_dev *dev;
- if (b->self) {
- pci_read_bridge_bases(b);
- pcibios_fixup_device_resources(b->self);
- }
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
@@ -442,24 +418,18 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
u16 cmd, old_cmd;
int idx;
struct resource *r;
- unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
if (!dev)
return -EINVAL;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
- for (idx=0; idxresource[idx];
- if (!(r->flags & type_mask))
- continue;
- if ((idx == PCI_ROM_RESOURCE) &&
- (!(r->flags & IORESOURCE_ROM_ENABLE)))
- continue;
if (!r->start && r->end) {
printk(KERN_ERR
"PCI: Device %s not available because of resource collisions\n",
@@ -471,6 +441,8 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
+ if (dev->resource[PCI_ROM_RESOURCE].start)
+ cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
diff --git a/trunk/arch/ia64/sn/kernel/io_init.c b/trunk/arch/ia64/sn/kernel/io_init.c
index 783eb4323847..9e07f5463f21 100644
--- a/trunk/arch/ia64/sn/kernel/io_init.c
+++ b/trunk/arch/ia64/sn/kernel/io_init.c
@@ -384,7 +384,7 @@ static int __init sn_pci_init(void)
extern void register_sn_procfs(void);
#endif
- if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
+ if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR())
return 0;
/*
diff --git a/trunk/arch/ia64/sn/kernel/iomv.c b/trunk/arch/ia64/sn/kernel/iomv.c
index 7ce3cdad627b..fec6d8b8237b 100644
--- a/trunk/arch/ia64/sn/kernel/iomv.c
+++ b/trunk/arch/ia64/sn/kernel/iomv.c
@@ -9,16 +9,12 @@
#include
#include
#include
-#include
#include
#include
#include
#include
#include
-#define IS_LEGACY_VGA_IOPORT(p) \
- (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df))
-
/**
* sn_io_addr - convert an in/out port to an i/o address
* @port: port to convert
@@ -30,8 +26,6 @@
void *sn_io_addr(unsigned long port)
{
if (!IS_RUNNING_ON_SIMULATOR()) {
- if (IS_LEGACY_VGA_IOPORT(port))
- port += vga_console_iobase;
/* On sn2, legacy I/O ports don't point at anything */
if (port < (64 * 1024))
return NULL;
diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c
index 22e10d282c7f..44bfc7f318cb 100644
--- a/trunk/arch/ia64/sn/kernel/setup.c
+++ b/trunk/arch/ia64/sn/kernel/setup.c
@@ -36,7 +36,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -96,7 +95,6 @@ u8 sn_coherency_id;
EXPORT_SYMBOL(sn_coherency_id);
u8 sn_region_size;
EXPORT_SYMBOL(sn_region_size);
-int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
short physical_node_map[MAX_PHYSNODE_ID];
@@ -275,17 +273,14 @@ void __init sn_setup(char **cmdline_p)
ia64_sn_plat_set_error_handling_features();
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
/*
- * If there was a primary vga adapter identified through the
- * EFI PCDP table, make it the preferred console. Otherwise
- * zero out conswitchp.
+ * If the generic code has enabled vga console support - lets
+ * get rid of it again. This is a kludge for the fact that ACPI
+ * currtently has no way of informing us if legacy VGA is available
+ * or not.
*/
-
- if (vga_console_membase) {
- /* usable vga ... make tty0 the preferred default console */
- add_preferred_console("tty", 0, NULL);
- } else {
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
+ if (conswitchp == &vga_con) {
printk(KERN_DEBUG "SGI: Disabling VGA console\n");
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -355,7 +350,7 @@ void __init sn_setup(char **cmdline_p)
ia64_mark_idle = &snidle;
- /*
+ /*
* For the bootcpu, we do this here. All other cpus will make the
* call as part of cpu_init in slave cpu initialization.
*/
@@ -402,7 +397,7 @@ static void __init sn_init_pdas(char **cmdline_p)
nodepdaindr[cnode] =
alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
- memset(nodepdaindr[cnode]->phys_cpuid, -1,
+ memset(nodepdaindr[cnode]->phys_cpuid, -1,
sizeof(nodepdaindr[cnode]->phys_cpuid));
}
@@ -432,7 +427,7 @@ static void __init sn_init_pdas(char **cmdline_p)
}
/*
- * Initialize the per node hubdev. This includes IO Nodes and
+ * Initialize the per node hubdev. This includes IO Nodes and
* headless/memless nodes.
*/
for (cnode = 0; cnode < numionodes; cnode++) {
@@ -460,14 +455,6 @@ void __init sn_cpu_init(void)
int i;
static int wars_have_been_checked;
- if (smp_processor_id() == 0 && IS_MEDUSA()) {
- if (ia64_sn_is_fake_prom())
- sn_prom_type = 2;
- else
- sn_prom_type = 1;
- printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
- }
-
memset(pda, 0, sizeof(pda));
if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
&sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
@@ -533,7 +520,7 @@ void __init sn_cpu_init(void)
*/
{
u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
- u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
+ u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
u64 *pio;
pio = is_shub1() ? pio1 : pio2;
@@ -565,10 +552,6 @@ static void __init scan_for_ionodes(void)
int nasid = 0;
lboard_t *brd;
- /* fakeprom does not support klgraph */
- if (IS_RUNNING_ON_FAKE_PROM())
- return;
-
/* Setup ionodes with memory */
for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
char *klgraph_header;
@@ -580,6 +563,8 @@ static void __init scan_for_ionodes(void)
cnodeid = -1;
klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
if (!klgraph_header) {
+ if (IS_RUNNING_ON_SIMULATOR())
+ continue;
BUG(); /* All nodes must have klconfig tables! */
}
cnodeid = nasid_to_cnodeid(nasid);
@@ -645,8 +630,8 @@ int
nasid_slice_to_cpuid(int nasid, int slice)
{
long cpu;
-
- for (cpu=0; cpu < NR_CPUS; cpu++)
+
+ for (cpu=0; cpu < NR_CPUS; cpu++)
if (cpuid_to_nasid(cpu) == nasid &&
cpuid_to_slice(cpu) == slice)
return cpu;
diff --git a/trunk/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/trunk/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
index 96cb71d15682..7947312801ec 100644
--- a/trunk/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
+++ b/trunk/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
@@ -6,7 +6,6 @@
* Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
*/
-#include
#include
#define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c
index 8716f4d5314b..a087b274847e 100644
--- a/trunk/arch/ia64/sn/kernel/tiocx.c
+++ b/trunk/arch/ia64/sn/kernel/tiocx.c
@@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num,
cx_dev->dev.parent = NULL;
cx_dev->dev.bus = &tiocx_bus_type;
cx_dev->dev.release = tiocx_bus_release;
- snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d",
- cx_dev->cx_id.nasid);
+ snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x",
+ cx_dev->cx_id.nasid, cx_dev->cx_id.part_num);
device_register(&cx_dev->dev);
get_device(&cx_dev->dev);
@@ -236,6 +236,7 @@ int cx_device_unregister(struct cx_dev *cx_dev)
*/
static int cx_device_reload(struct cx_dev *cx_dev)
{
+ device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control);
cx_device_unregister(cx_dev);
return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
cx_dev->cx_id.mfg_num, cx_dev->hubdev);
@@ -382,7 +383,6 @@ static int is_fpga_brick(int nasid)
switch (tiocx_btchar_get(nasid)) {
case L1_BRICKTYPE_SA:
case L1_BRICKTYPE_ATHENA:
- case L1_BRICKTYPE_DAYTONA:
return 1;
}
return 0;
@@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *cx_dev)
uint64_t cx_id;
cx_id =
- *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
+ *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
WIDGET_ID);
part_num = XWIDGET_PART_NUM(cx_id);
mfg_num = XWIDGET_MFG_NUM(cx_id);
@@ -458,10 +458,6 @@ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *
switch (n) {
case 1:
- tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
- tiocx_reload(cx_dev);
- break;
- case 2:
tiocx_reload(cx_dev);
break;
case 3:
@@ -541,7 +537,7 @@ static void __exit tiocx_exit(void)
bus_unregister(&tiocx_bus_type);
}
-subsys_initcall(tiocx_init);
+module_init(tiocx_init);
module_exit(tiocx_exit);
/************************************************************************
diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c
index 05aa8c2fe9bb..8dae9eb45456 100644
--- a/trunk/arch/ia64/sn/pci/tioca_provider.c
+++ b/trunk/arch/ia64/sn/pci/tioca_provider.c
@@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
if (!ct_addr)
return 0;
- bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
+ bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff);
node_upper = ct_addr >> 48;
if (node_upper > 64) {
@@ -464,7 +464,7 @@ tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size)
* For mappings created using the direct modes (64 or 48) there are no
* resources to release.
*/
-static void
+void
tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
{
int i, entry;
@@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
* The mapping mode used is based on the devices dma_mask. As a last resort
* use the GART mapped mode.
*/
-static uint64_t
+uint64_t
tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
{
uint64_t mapaddr;
@@ -580,7 +580,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
* On successful setup, returns the kernel version of tioca_common back to
* the caller.
*/
-static void *
+void *
tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
{
struct tioca_common *tioca_common;
diff --git a/trunk/arch/parisc/configs/712_defconfig b/trunk/arch/parisc/configs/712_defconfig
index 6efaa9293eef..872085dea8a8 100644
--- a/trunk/arch/parisc/configs/712_defconfig
+++ b/trunk/arch/parisc/configs/712_defconfig
@@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=17
+CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/trunk/arch/parisc/configs/a500_defconfig b/trunk/arch/parisc/configs/a500_defconfig
index 30fc03ed0cfb..d28ebfa1070d 100644
--- a/trunk/arch/parisc/configs/a500_defconfig
+++ b/trunk/arch/parisc/configs/a500_defconfig
@@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
-CONFIG_SERIAL_8250_NR_UARTS=17
+CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/trunk/arch/parisc/configs/b180_defconfig b/trunk/arch/parisc/configs/b180_defconfig
index 46c9511f3229..1700d7aec686 100644
--- a/trunk/arch/parisc/configs/b180_defconfig
+++ b/trunk/arch/parisc/configs/b180_defconfig
@@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=13
+CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/trunk/arch/parisc/configs/c3000_defconfig b/trunk/arch/parisc/configs/c3000_defconfig
index 67aca6ccc9b0..b27980161c31 100644
--- a/trunk/arch/parisc/configs/c3000_defconfig
+++ b/trunk/arch/parisc/configs/c3000_defconfig
@@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=13
+CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/trunk/arch/parisc/defconfig b/trunk/arch/parisc/defconfig
index fdae21c503d7..ebd6301aa599 100644
--- a/trunk/arch/parisc/defconfig
+++ b/trunk/arch/parisc/defconfig
@@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=13
+CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/trunk/arch/ppc/kernel/pci.c b/trunk/arch/ppc/kernel/pci.c
index 70cfb6ffd877..6d7b92d72458 100644
--- a/trunk/arch/ppc/kernel/pci.c
+++ b/trunk/arch/ppc/kernel/pci.c
@@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
*offset += hose->pci_mem_offset;
res_bit = IORESOURCE_MEM;
} else {
- io_offset = hose->io_base_virt - ___IO_BASE;
+ io_offset = (unsigned long)hose->io_base_virt;
*offset += io_offset;
res_bit = IORESOURCE_IO;
}
@@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
/* found it! construct the final physical address */
if (mmap_state == pci_mmap_io)
- *offset += hose->io_base_phys - io_offset;
+ *offset += hose->io_base_phys - _IO_BASE;
return rp;
}
@@ -1739,23 +1739,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
return result;
}
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
- const struct resource *rsrc,
- u64 *start, u64 *end)
-{
- struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
- unsigned long offset = 0;
-
- if (hose == NULL)
- return;
-
- if (rsrc->flags & IORESOURCE_IO)
- offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
-
- *start = rsrc->start + offset;
- *end = rsrc->end + offset;
-}
-
void __init
pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
int flags, char *name)
diff --git a/trunk/arch/ppc/kernel/relocate_kernel.S b/trunk/arch/ppc/kernel/relocate_kernel.S
index 9b2ad48e988c..7ff69c4af920 100644
--- a/trunk/arch/ppc/kernel/relocate_kernel.S
+++ b/trunk/arch/ppc/kernel/relocate_kernel.S
@@ -34,9 +34,9 @@ relocate_new_kernel:
mr r8, r0
ori r8, r8, MSR_RI|MSR_ME
- mtspr SPRN_SRR1, r8
+ mtspr SRR1, r8
addi r8, r4, 1f - relocate_new_kernel
- mtspr SPRN_SRR0, r8
+ mtspr SRR0, r8
sync
rfi
diff --git a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c
index f761fdf160db..ddd2e9a5bb12 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -111,8 +111,8 @@ mpc8540ads_setup_arch(void)
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
- pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
if (pdata) {
+ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
pdata->board_flags = 0;
pdata->interruptPHY = MPC85xx_IRQ_EXT5;
pdata->phyid = 3;
diff --git a/trunk/arch/ppc64/kernel/irq.c b/trunk/arch/ppc64/kernel/irq.c
index ffe300611f00..3defc8c33adf 100644
--- a/trunk/arch/ppc64/kernel/irq.c
+++ b/trunk/arch/ppc64/kernel/irq.c
@@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
spin_lock(&desc->lock);
if (!noirqdebug)
- note_interrupt(irq, desc, action_ret, regs);
+ note_interrupt(irq, desc, action_ret);
if (likely(!(desc->status & IRQ_PENDING)))
break;
desc->status &= ~IRQ_PENDING;
diff --git a/trunk/arch/ppc64/kernel/nvram.c b/trunk/arch/ppc64/kernel/nvram.c
index 4e71781a4414..4fb1a9f5060d 100644
--- a/trunk/arch/ppc64/kernel/nvram.c
+++ b/trunk/arch/ppc64/kernel/nvram.c
@@ -338,9 +338,8 @@ static int nvram_remove_os_partition(void)
*/
static int nvram_create_os_partition(void)
{
- struct list_head * p;
- struct nvram_partition *part = NULL;
- struct nvram_partition *new_part = NULL;
+ struct nvram_partition *part;
+ struct nvram_partition *new_part;
struct nvram_partition *free_part = NULL;
int seq_init[2] = { 0, 0 };
loff_t tmp_index;
@@ -349,8 +348,7 @@ static int nvram_create_os_partition(void)
/* Find a free partition that will give us the maximum needed size
If can't find one that will give us the minimum size needed */
- list_for_each(p, &nvram_part->partition) {
- part = list_entry(p, struct nvram_partition, partition);
+ list_for_each_entry(part, &nvram_part->partition, partition) {
if (part->header.signature != NVRAM_SIG_FREE)
continue;
diff --git a/trunk/arch/ppc64/kernel/pci.c b/trunk/arch/ppc64/kernel/pci.c
index ae6f579d3fa0..580676f87d23 100644
--- a/trunk/arch/ppc64/kernel/pci.c
+++ b/trunk/arch/ppc64/kernel/pci.c
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
*offset += hose->pci_mem_offset;
res_bit = IORESOURCE_MEM;
} else {
- io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+ io_offset = (unsigned long)hose->io_base_virt;
*offset += io_offset;
res_bit = IORESOURCE_IO;
}
@@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
/* found it! construct the final physical address */
if (mmap_state == pci_mmap_io)
- *offset += hose->io_base_phys - io_offset;
+ *offset += hose->io_base_phys - io_offset;
return rp;
}
@@ -944,22 +944,4 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
}
EXPORT_SYMBOL(pci_read_irq_line);
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
- const struct resource *rsrc,
- u64 *start, u64 *end)
-{
- struct pci_controller *hose = pci_bus_to_host(dev->bus);
- unsigned long offset = 0;
-
- if (hose == NULL)
- return;
-
- if (rsrc->flags & IORESOURCE_IO)
- offset = pci_io_base - (unsigned long)hose->io_base_virt +
- hose->io_base_phys;
-
- *start = rsrc->start + offset;
- *end = rsrc->end + offset;
-}
-
#endif /* CONFIG_PPC_MULTIPLATFORM */
diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig
index 7a117ef473c5..262e13d086fe 100644
--- a/trunk/arch/sparc/Kconfig
+++ b/trunk/arch/sparc/Kconfig
@@ -270,10 +270,66 @@ endmenu
source "drivers/Kconfig"
+config PRINTER
+ tristate "Parallel printer support"
+ depends on PARPORT
+ ---help---
+ If you intend to attach a printer to the parallel port of your Linux
+ box (as opposed to using a serial printer; if the connector at the
+ printer has 9 or 25 holes ["female"], then it's serial), say Y.
+ Also read the Printing-HOWTO, available from
+ .
+
+ It is possible to share one parallel port among several devices
+ (e.g. printer and ZIP drive) and it is safe to compile the
+ corresponding drivers into the kernel. If you want to compile this
+ driver as a module however, choose M here and read
+ . The module will be called lp.
+
+ If you have several parallel ports, you can specify which ports to
+ use with the "lp" kernel command line option. (Try "man bootparam"
+ or see the documentation of your boot loader (silo) about how to pass
+ options to the kernel at boot time.) The syntax of the "lp" command
+ line option can be found in .
+
+ If you have more than 8 printers, you need to increase the LP_NO
+ macro in lp.c and the PARPORT_MAX macro in parport.h.
+
+source "mm/Kconfig"
+
+endmenu
+
+source "drivers/base/Kconfig"
+
+source "drivers/video/Kconfig"
+
+source "drivers/mtd/Kconfig"
+
+source "drivers/serial/Kconfig"
+
if !SUN4
source "drivers/sbus/char/Kconfig"
endif
+source "drivers/block/Kconfig"
+
+# Don't frighten a common SBus user
+if PCI
+
+source "drivers/ide/Kconfig"
+
+endif
+
+source "drivers/isdn/Kconfig"
+
+source "drivers/scsi/Kconfig"
+
+source "drivers/fc4/Kconfig"
+
+source "drivers/md/Kconfig"
+
+source "net/Kconfig"
+
# This one must be before the filesystem configs. -DaveM
menu "Unix98 PTY support"
diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c
index d206d7e49cf5..157190d986bb 100644
--- a/trunk/arch/x86_64/kernel/io_apic.c
+++ b/trunk/arch/x86_64/kernel/io_apic.c
@@ -1064,6 +1064,7 @@ void print_all_local_APICs (void)
void __apicdebuginit print_PIC(void)
{
+ extern spinlock_t i8259A_lock;
unsigned int v;
unsigned long flags;
diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c
index 657e88aa0902..b693c232fd07 100644
--- a/trunk/arch/x86_64/pci/mmconfig.c
+++ b/trunk/arch/x86_64/pci/mmconfig.c
@@ -7,50 +7,25 @@
#include
#include
-#include
#include "pci.h"
#define MMCONFIG_APER_SIZE (256*1024*1024)
+/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
+u32 pci_mmcfg_base_addr;
+
/* Static virtual mapping of the MMCONFIG aperture */
-struct mmcfg_virt {
- struct acpi_table_mcfg_config *cfg;
- char *virt;
-};
-static struct mmcfg_virt *pci_mmcfg_virt;
+char *pci_mmcfg_virt;
-static char *get_virt(unsigned int seg, int bus)
+static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)
{
- int cfg_num = -1;
- struct acpi_table_mcfg_config *cfg;
-
- while (1) {
- ++cfg_num;
- if (cfg_num >= pci_mmcfg_config_num) {
- /* something bad is going on, no cfg table is found. */
- /* so we fall back to the old way we used to do this */
- /* and just rely on the first entry to be correct. */
- return pci_mmcfg_virt[0].virt;
- }
- cfg = pci_mmcfg_virt[cfg_num].cfg;
- if (cfg->pci_segment_group_number != seg)
- continue;
- if ((cfg->start_bus_number <= bus) &&
- (cfg->end_bus_number >= bus))
- return pci_mmcfg_virt[cfg_num].virt;
- }
-}
-
-static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
-{
-
- return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
+ return pci_mmcfg_virt + ((bus << 20) | (devfn << 12));
}
static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 *value)
{
- char *addr = pci_dev_base(seg, bus, devfn);
+ char *addr = pci_dev_base(bus, devfn);
if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
return -EINVAL;
@@ -73,7 +48,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
unsigned int devfn, int reg, int len, u32 value)
{
- char *addr = pci_dev_base(seg, bus, devfn);
+ char *addr = pci_dev_base(bus,devfn);
if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
return -EINVAL;
@@ -100,15 +75,9 @@ static struct pci_raw_ops pci_mmcfg = {
static int __init pci_mmcfg_init(void)
{
- int i;
-
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return 0;
-
- acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
- if ((pci_mmcfg_config_num == 0) ||
- (pci_mmcfg_config == NULL) ||
- (pci_mmcfg_config[0].base_address == 0))
+ if (!pci_mmcfg_base_addr)
return 0;
/* Kludge for now. Don't use mmconfig on AMD systems because
@@ -119,22 +88,13 @@ static int __init pci_mmcfg_init(void)
return 0;
/* RED-PEN i386 doesn't do _nocache right now */
- pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
- if (pci_mmcfg_virt == NULL) {
- printk("PCI: Can not allocate memory for mmconfig structures\n");
+ pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE);
+ if (!pci_mmcfg_virt) {
+ printk("PCI: Cannot map mmconfig aperture\n");
return 0;
- }
- for (i = 0; i < pci_mmcfg_config_num; ++i) {
- pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
- pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
- if (!pci_mmcfg_virt[i].virt) {
- printk("PCI: Cannot map mmconfig aperture for segment %d\n",
- pci_mmcfg_config[i].pci_segment_group_number);
- return 0;
- }
- printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
- }
+ }
+ printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig
index c9b5d298e3c4..3e89767cea72 100644
--- a/trunk/arch/xtensa/Kconfig
+++ b/trunk/arch/xtensa/Kconfig
@@ -132,7 +132,7 @@ config XTENSA_CPU_CLOCK
config GENERIC_CALIBRATE_DELAY
bool "Auto calibration of the BogoMIPS value"
---help---
- The BogoMIPS value can easily be derived from the CPU frequency.
+ The BogoMIPS value can easily derived from the CPU frequency.
config CMDLINE_BOOL
bool "Default bootloader kernel arguments"
@@ -158,8 +158,6 @@ config XTENSA_ISS_NETWORK
depends on XTENSA_PLATFORM_ISS
default y
-source "mm/Kconfig"
-
endmenu
menu "Bus options"
diff --git a/trunk/arch/xtensa/Makefile b/trunk/arch/xtensa/Makefile
index 27847e4ffcbf..4fa27453b1f9 100644
--- a/trunk/arch/xtensa/Makefile
+++ b/trunk/arch/xtensa/Makefile
@@ -21,17 +21,23 @@ export CPU
# Platform configuration
+platform-y := common
platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
PLATFORM = $(platform-y)
export PLATFORM
-CPPFLAGS += $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/)
-CPPFLAGS += -Iinclude/asm
-CFLAGS += -pipe -mlongcalls
+#LDFLAGS_vmlinux := -T$(word 1,$(LINKSCRIPT))
+AFLAGS_vmlinux.lds.o := -Uxtensa
+CPPFLAGS += -Iarch/xtensa -Iinclude/asm -mlongcalls -g
+AFLAGS += -Iarch/xtensa -Iinclude/asm
+CPP = $(CC) -E $(CFLAGS)
-KBUILD_DEFCONFIG := iss_defconfig
+cflags-y += -Iarch/xtensa -pipe -mlongcalls
+
+
+KBUILD_DEFCONFIG := common_defconfig
# ramdisk/initrd support
# You need a compressed ramdisk image, named ramdisk.gz in
@@ -56,36 +62,30 @@ endif
LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
head-y := arch/xtensa/kernel/head.o
-core-y += arch/xtensa/kernel/ arch/xtensa/mm/
-ifneq ($(PLATFORM),)
-core-y += arch/xtensa/platform-$(PLATFORM)/
-endif
+core-y += arch/xtensa/kernel/ \
+ arch/xtensa/mm/ arch/xtensa/platform-$(PLATFORM)/
libs-y += arch/xtensa/lib/ $(LIBGCC)
-boot := arch/xtensa/boot
-
-archinc := include/asm-xtensa
+boot := arch/xtensa/boot
arch/xtensa/kernel/asm-offsets.s: \
- arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform
+ arch/xtensa/kernel/asm-offsets.c \
+ include/asm-xtensa/.platform
include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s
$(call filechk,gen-asm-offsets)
-prepare: $(archinc)/.platform $(archinc)/offsets.h
+prepare: include/asm-xtensa/.platform include/asm-xtensa/offsets.h
# Update machine cpu and platform symlinks if something which affects
# them changed.
-$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER
- @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)'
- $(Q)mkdir -p $(archinc)
- $(Q)mkdir -p $(archinc)/xtensa
- $(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config
- @echo ' SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)'
- $(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform
- @touch $@
-
+include/asm-xtensa/.platform: $(wildcard include/config/arch/*.h)
+ @echo ' Setting up cpu ($(CPU)) and platform ($(PLATFORM)) symlinks'
+ $(Q)rm -f include/asm-xtensa/platform
+ $(Q)rm -f include/asm-xtensa/xtensa/config
+ $(Q)(cd include/asm-xtensa/; ln -sf platform-$(PLATFORM) platform)
+ $(Q)(cd include/asm-xtensa/xtensa; ln -sf config-$(CPU) config)
all: zImage
@@ -94,9 +94,7 @@ bzImage : zImage
zImage zImage.initrd: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
-CLEAN_FILES += arch/xtensa/vmlinux.lds $(archinc)/offset.h \
- $(archinc)/platform $(archinc)/xtensa/config \
- $(archinc)/.platform
+CLEAN_FILES += arch/xtensa/vmlinux.lds include/asm-xtensa/offset.h
define archhelp
@echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)'
diff --git a/trunk/arch/xtensa/boot/Makefile b/trunk/arch/xtensa/boot/Makefile
index 820b31d10ae4..260f456ccf0b 100644
--- a/trunk/arch/xtensa/boot/Makefile
+++ b/trunk/arch/xtensa/boot/Makefile
@@ -11,19 +11,21 @@
CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include
HOSTFLAGS += -Iarch/$(ARCH)/boot/include
-BIG_ENDIAN := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
+BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
+
export CFLAGS
export AFLAGS
export BIG_ENDIAN
-subdir-y := lib
-
# Subdirs for the boot loader(s)
bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf
bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
+subdir-y := lib/
+
+subdir-y += boot-elf/ boot-redboot/
zImage zImage.initrd Image Image.initrd: $(bootdir-y)
@@ -31,3 +33,5 @@ $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
$(addprefix $(obj)/,$(host-progs))
$(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
+
+
diff --git a/trunk/arch/xtensa/boot/boot-elf/Makefile b/trunk/arch/xtensa/boot/boot-elf/Makefile
index 734db7f76583..f6ef6a369667 100644
--- a/trunk/arch/xtensa/boot/boot-elf/Makefile
+++ b/trunk/arch/xtensa/boot/boot-elf/Makefile
@@ -27,7 +27,7 @@ Image: vmlinux $(OBJS)
--set-section-flags image=contents,alloc,load,load,data \
$(OBJS) $@.tmp
$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
- -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
+ -T arch/$(ARCH)/boot/boot-elf/boot.ld \
-o arch/$(ARCH)/boot/$@.elf $@.tmp
rm -f $@.tmp vmlinux.tmp
@@ -41,7 +41,7 @@ Image.initrd: vmlinux $(OBJS)
--set-section-flags image=contents,alloc,load,load,data \
$(OBJS) $@.tmp
$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
- -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
+ -T arch/$(ARCH)/boot/boot-elf/boot.ld \
-o arch/$(ARCH)/boot/$@.elf $@.tmp
rm -f $@.tmp vmlinux.tmp
diff --git a/trunk/arch/xtensa/boot/boot-redboot/Makefile b/trunk/arch/xtensa/boot/boot-redboot/Makefile
index f53262c2e1f3..ca8a68bc8472 100644
--- a/trunk/arch/xtensa/boot/boot-redboot/Makefile
+++ b/trunk/arch/xtensa/boot/boot-redboot/Makefile
@@ -12,24 +12,24 @@ else
OBJCOPY_ARGS := -O elf32-xtensa-le
endif
-LD_ARGS = -T $(srctree)/$(obj)/boot.ld
+LD_ARGS = -T $(obj)/boot.ld
boot-y := bootstrap.o
OBJS := $(addprefix $(obj)/,$(boot-y))
-LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
+LIBS := arch/$(ARCH)/boot/lib/lib.a arch/$(ARCH)/lib/lib.a
LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
zImage: vmlinux $(OBJS) $(LIBS)
$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
- vmlinux vmlinux.tmp
+ $(TOPDIR)/vmlinux vmlinux.tmp
gzip -vf9 vmlinux.tmp
$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
--add-section image=vmlinux.tmp.gz \
--set-section-flags image=contents,alloc,load,load,data \
$(OBJS) $@.tmp
$(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
- $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot
- rm -f $@.tmp $@.elf vmlinux.tmp.gz
+ $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/images/$@.redboot
+# rm -f $@.tmp $@.elf vmlinux.tmp.gz
diff --git a/trunk/arch/xtensa/boot/include/zlib.h b/trunk/arch/xtensa/boot/include/zlib.h
new file mode 100644
index 000000000000..ea29b6237852
--- /dev/null
+++ b/trunk/arch/xtensa/boot/include/zlib.h
@@ -0,0 +1,433 @@
+/*
+ * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort
+ */
+/*
+ * This file is derived from zlib.h and zconf.h from the zlib-0.95
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.
+ */
+
+/*
+ * ==FILEVERSION 960122==
+ *
+ * This marker is used by the Linux installation script to determine
+ * whether an up-to-date version of this file is already installed.
+ */
+
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 0.95, Aug 16th, 1995.
+
+ Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ gzip@prep.ai.mit.edu madler@alumni.caltech.edu
+ */
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+/* #include "zconf.h" */ /* included directly here */
+
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
+
+/*
+ The library does not install any signal handler. It is recommended to
+ add at least a handler for SIGSEGV when decompressing; the library checks
+ the consistency of the input data whenever possible but may go nuts
+ for some forms of corrupted input.
+ */
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
+ * at addresses which are not a multiple of their size.
+ * Under DOS, -DFAR=far or -DFAR=__far may be needed.
+ */
+
+#ifndef STDC
+# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
+# define STDC
+# endif
+#endif
+
+#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
+# include
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ 1 << (windowBits+2) + 1 << (memLevel+9)
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+typedef unsigned char Byte; /* 8 bits */
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+typedef Byte FAR Bytef;
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+/* end of original zconf.h */
+
+#define ZLIB_VERSION "0.95P"
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms may be added later and will have the same
+ stream interface.
+
+ For compression the application must provide the output buffer and
+ may optionally provide the input buffer for optimization. For decompression,
+ the application must provide the input buffer and may optionally provide
+ the output buffer for optimization.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidp opaque; /* private data object passed to zalloc and zfree */
+
+ Byte data_type; /* best guess about the data type: ascii or binary */
+
+} z_stream;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_FULL_FLUSH 2
+#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
+#define Z_FINISH 4
+#define Z_PACKET_FLUSH 5
+/* See deflate() below for the usage of these constants */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+/* error codes for the compression/decompression functions */
+
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Used to set the data_type field */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+extern char *zlib_version;
+/* The application can compare zlib_version and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ */
+
+ /* basic functions */
+
+extern int inflateInit OF((z_stream *strm));
+/*
+ Initializes the internal stream state for decompression. The fields
+ zalloc and zfree must be initialized before by the caller. If zalloc and
+ zfree are set to Z_NULL, inflateInit updates them to use default allocation
+ functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory. msg is set to null if there is no error message.
+ inflateInit does not perform any decompression: this will be done by
+ inflate().
+*/
+
+
+extern int inflate OF((z_stream *strm, int flush));
+/*
+ Performs one or both of the following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() always provides as much output as possible
+ (until there is no more input data or no more space in the output buffer).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate().
+
+ If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
+ inflate flushes as much output as possible to the output buffer. The
+ flushing behavior of inflate is not specified for values of the flush
+ parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
+ current implementation actually flushes as much output as possible
+ anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
+ has been consumed, it is expecting to see the length field of a stored
+ block; if not, it returns Z_DATA_ERROR.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster routine
+ may be used for the single inflate() call.
+
+ inflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if the end of the
+ compressed data has been reached and all uncompressed output has been
+ produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
+ the stream structure was inconsistent (for example if next_in or next_out
+ was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
+ progress is possible or if there was not enough room in the output buffer
+ when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
+ call inflateSync to look for a good compression block. */
+
+
+extern int inflateEnd OF((z_stream *strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* advanced functions */
+
+extern int inflateInit2 OF((z_stream *strm,
+ int windowBits));
+/*
+ This is another version of inflateInit with more compression options. The
+ fields next_out, zalloc and zfree must be initialized before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library (the value 16 will be allowed soon). The
+ default value is 15 if inflateInit is used instead. If a compressed stream
+ with a larger window size is given as input, inflate() will return with
+ the error code Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ If next_out is not null, the library will use this buffer for the history
+ buffer; the buffer must either be large enough to hold the entire output
+ data, or have at least 1< $@
-
-$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
- $(call cmd,copy_zlib)
-
-clean-files := $(zlib)
+lib-y := zlib.o zmem.o
diff --git a/trunk/arch/xtensa/boot/lib/memcpy.S b/trunk/arch/xtensa/boot/lib/memcpy.S
new file mode 100644
index 000000000000..a029f5df2d5c
--- /dev/null
+++ b/trunk/arch/xtensa/boot/lib/memcpy.S
@@ -0,0 +1,36 @@
+/*
+ * arch/xtensa/lib/memcpy.S
+ *
+ * ANSI C standard library function memcpy
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+#define _ASMLANGUAGE
+#include
+
+.text
+.align 4
+.global bcopy
+.type bcopy,@function
+bcopy:
+ movi a14, xthal_bcopy // a14 safe to use regardless of whether caller
+ // used call4 or call8 (can't have used call12)
+ jx a14 // let the Core HAL do the work
+
+.text
+.align 4
+.global memcpy
+.type memcpy,@function
+memcpy:
+.global memmove
+.type memmove,@function
+memmove:
+ movi a14, xthal_memcpy // a14 safe to use regardless of whether caller
+ // used call4 or call8 (can't have used call12)
+ jx a14 // let the Core HAL do the work
+
diff --git a/trunk/arch/xtensa/boot/lib/zlib.c b/trunk/arch/xtensa/boot/lib/zlib.c
new file mode 100644
index 000000000000..e3859f631077
--- /dev/null
+++ b/trunk/arch/xtensa/boot/lib/zlib.c
@@ -0,0 +1,2150 @@
+/*
+ * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort
+ */
+/*
+ * This file is derived from various .h and .c files from the zlib-0.95
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets. See zlib.h for conditions of
+ * distribution and use.
+ *
+ * Changes that have been made include:
+ * - changed functions not used outside this file to "local"
+ * - added minCompression parameter to deflateInit2
+ * - added Z_PACKET_FLUSH (see zlib.h for details)
+ * - added inflateIncomp
+ *
+ */
+
+/*+++++*/
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
+
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#define FAR
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern char *z_errmsg[]; /* indexed by 1-zlib_error */
+
+#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
+/* To be used only when the state is known to be valid */
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+ /* common constants */
+
+#define DEFLATED 8
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+ /* functions */
+
+#include
+#define zmemcpy memcpy
+#define zmemzero(dest, len) memset(dest, 0, len)
+
+/* Diagnostic functions */
+#ifdef DEBUG_ZLIB
+# include
+# ifndef verbose
+# define verbose 0
+# endif
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
+
+/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
+/* void zcfree OF((voidpf opaque, voidpf ptr)); */
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr, size) \
+ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
+#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
+
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/*+++++*/
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+local inflate_blocks_statef * inflate_blocks_new OF((
+ z_stream *z,
+ check_func c, /* check function */
+ uInt w)); /* window size */
+
+local int inflate_blocks OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ int)); /* initial return code */
+
+local void inflate_blocks_reset OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ uLongf *)); /* check value on output */
+
+local int inflate_blocks_free OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ uLongf *)); /* check value on output */
+
+local int inflate_addhistory OF((
+ inflate_blocks_statef *,
+ z_stream *));
+
+local int inflate_packet_flush OF((
+ inflate_blocks_statef *));
+
+/*+++++*/
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+ union {
+ struct {
+ Byte Exop; /* number of extra bits or operation */
+ Byte Bits; /* number of bits in this code or subcode */
+ } what;
+ uInt Nalloc; /* number of these allocated here */
+ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
+ } word; /* 16-bit, 8 bytes for 32-bit machines) */
+ union {
+ uInt Base; /* literal, length base, or distance base */
+ inflate_huft *Next; /* pointer to next level of table */
+ } more;
+};
+
+#ifdef DEBUG_ZLIB
+ local uInt inflate_hufts;
+#endif
+
+local int inflate_trees_bits OF((
+ uIntf *, /* 19 code lengths */
+ uIntf *, /* bits tree desired/actual depth */
+ inflate_huft * FAR *, /* bits tree result */
+ z_stream *)); /* for zalloc, zfree functions */
+
+local int inflate_trees_dynamic OF((
+ uInt, /* number of literal/length codes */
+ uInt, /* number of distance codes */
+ uIntf *, /* that many (total) code lengths */
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *, /* distance tree result */
+ z_stream *)); /* for zalloc, zfree functions */
+
+local int inflate_trees_fixed OF((
+ uIntf *, /* literal desired/actual bit depth */
+ uIntf *, /* distance desired/actual bit depth */
+ inflate_huft * FAR *, /* literal/length tree result */
+ inflate_huft * FAR *)); /* distance tree result */
+
+local int inflate_trees_free OF((
+ inflate_huft *, /* tables to free */
+ z_stream *)); /* for zfree function */
+
+
+/*+++++*/
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+local inflate_codes_statef *inflate_codes_new OF((
+ uInt, uInt,
+ inflate_huft *, inflate_huft *,
+ z_stream *));
+
+local int inflate_codes OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ int));
+
+local void inflate_codes_free OF((
+ inflate_codes_statef *,
+ z_stream *));
+
+
+/*+++++*/
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* inflate private state */
+struct internal_state {
+
+ /* mode */
+ enum {
+ METHOD, /* waiting for method byte */
+ FLAG, /* waiting for flag byte */
+ BLOCKS, /* decompressing blocks */
+ CHECK4, /* four check bytes to go */
+ CHECK3, /* three check bytes to go */
+ CHECK2, /* two check bytes to go */
+ CHECK1, /* one check byte to go */
+ DONE, /* finished check, done */
+ BAD} /* got an error--stay here */
+ mode; /* current inflate mode */
+
+ /* mode dependent information */
+ union {
+ uInt method; /* if FLAGS, method byte */
+ struct {
+ uLong was; /* computed check value */
+ uLong need; /* stream check value */
+ } check; /* if CHECK, check values to compare */
+ uInt marker; /* if BAD, inflateSync's marker bytes count */
+ } sub; /* submode */
+
+ /* mode independent information */
+ int nowrap; /* flag for no wrapper */
+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
+ inflate_blocks_statef
+ *blocks; /* current inflate_blocks state */
+
+};
+
+
+int inflateReset(z)
+z_stream *z;
+{
+ uLong c;
+
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ z->total_in = z->total_out = 0;
+ z->msg = Z_NULL;
+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+ inflate_blocks_reset(z->state->blocks, z, &c);
+ Trace((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+
+int inflateEnd(z)
+z_stream *z;
+{
+ uLong c;
+
+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->blocks != Z_NULL)
+ inflate_blocks_free(z->state->blocks, z, &c);
+ ZFREE(z, z->state, sizeof(struct internal_state));
+ z->state = Z_NULL;
+ Trace((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+
+int inflateInit2(z, w)
+z_stream *z;
+int w;
+{
+ /* initialize state */
+ if (z == Z_NULL)
+ return Z_STREAM_ERROR;
+/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
+/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
+ if ((z->state = (struct internal_state FAR *)
+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+ return Z_MEM_ERROR;
+ z->state->blocks = Z_NULL;
+
+ /* handle undocumented nowrap option (no zlib header or check) */
+ z->state->nowrap = 0;
+ if (w < 0)
+ {
+ w = - w;
+ z->state->nowrap = 1;
+ }
+
+ /* set window size */
+ if (w < 8 || w > 15)
+ {
+ inflateEnd(z);
+ return Z_STREAM_ERROR;
+ }
+ z->state->wbits = (uInt)w;
+
+ /* create inflate_blocks state */
+ if ((z->state->blocks =
+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
+ == Z_NULL)
+ {
+ inflateEnd(z);
+ return Z_MEM_ERROR;
+ }
+ Trace((stderr, "inflate: allocated\n"));
+
+ /* reset state */
+ inflateReset(z);
+ return Z_OK;
+}
+
+
+int inflateInit(z)
+z_stream *z;
+{
+ return inflateInit2(z, DEF_WBITS);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int inflate(z, f)
+z_stream *z;
+int f;
+{
+ int r;
+ uInt b;
+
+ if (z == Z_NULL || z->next_in == Z_NULL)
+ return Z_STREAM_ERROR;
+ r = Z_BUF_ERROR;
+ while (1) switch (z->state->mode)
+ {
+ case METHOD:
+ NEEDBYTE
+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
+ {
+ z->state->mode = BAD;
+ z->msg = "unknown compression method";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+ {
+ z->state->mode = BAD;
+ z->msg = "invalid window size";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ z->state->mode = FLAG;
+ case FLAG:
+ NEEDBYTE
+ if ((b = NEXTBYTE) & 0x20)
+ {
+ z->state->mode = BAD;
+ z->msg = "invalid reserved bit";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ if (((z->state->sub.method << 8) + b) % 31)
+ {
+ z->state->mode = BAD;
+ z->msg = "incorrect header check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Trace((stderr, "inflate: zlib header ok\n"));
+ z->state->mode = BLOCKS;
+ case BLOCKS:
+ r = inflate_blocks(z->state->blocks, z, r);
+ if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
+ r = inflate_packet_flush(z->state->blocks);
+ if (r == Z_DATA_ERROR)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0; /* can try inflateSync */
+ break;
+ }
+ if (r != Z_STREAM_END)
+ return r;
+ r = Z_OK;
+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+ if (z->state->nowrap)
+ {
+ z->state->mode = DONE;
+ break;
+ }
+ z->state->mode = CHECK4;
+ case CHECK4:
+ NEEDBYTE
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+ z->state->mode = CHECK3;
+ case CHECK3:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+ z->state->mode = CHECK2;
+ case CHECK2:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+ z->state->mode = CHECK1;
+ case CHECK1:
+ NEEDBYTE
+ z->state->sub.check.need += (uLong)NEXTBYTE;
+
+ if (z->state->sub.check.was != z->state->sub.check.need)
+ {
+ z->state->mode = BAD;
+ z->msg = "incorrect data check";
+ z->state->sub.marker = 5; /* can't try inflateSync */
+ break;
+ }
+ Trace((stderr, "inflate: zlib check ok\n"));
+ z->state->mode = DONE;
+ case DONE:
+ return Z_STREAM_END;
+ case BAD:
+ return Z_DATA_ERROR;
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ empty:
+ if (f != Z_PACKET_FLUSH)
+ return r;
+ z->state->mode = BAD;
+ z->state->sub.marker = 0; /* can try inflateSync */
+ return Z_DATA_ERROR;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output. The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS). On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+
+int inflateIncomp(z)
+z_stream *z;
+{
+ if (z->state->mode != BLOCKS)
+ return Z_DATA_ERROR;
+ return inflate_addhistory(z->state->blocks, z);
+}
+
+
+int inflateSync(z)
+z_stream *z;
+{
+ uInt n; /* number of bytes to look at */
+ Bytef *p; /* pointer to bytes */
+ uInt m; /* number of marker bytes found in a row */
+ uLong r, w; /* temporaries to save total_in and total_out */
+
+ /* set up */
+ if (z == Z_NULL || z->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ if (z->state->mode != BAD)
+ {
+ z->state->mode = BAD;
+ z->state->sub.marker = 0;
+ }
+ if ((n = z->avail_in) == 0)
+ return Z_BUF_ERROR;
+ p = z->next_in;
+ m = z->state->sub.marker;
+
+ /* search */
+ while (n && m < 4)
+ {
+ if (*p == (Byte)(m < 2 ? 0 : 0xff))
+ m++;
+ else if (*p)
+ m = 0;
+ else
+ m = 4 - m;
+ p++, n--;
+ }
+
+ /* restore */
+ z->total_in += p - z->next_in;
+ z->next_in = p;
+ z->avail_in = n;
+ z->state->sub.marker = m;
+
+ /* return no joy or set up to restart on a new block */
+ if (m != 4)
+ return Z_DATA_ERROR;
+ r = z->total_in; w = z->total_out;
+ inflateReset(z);
+ z->total_in = r; z->total_out = w;
+ z->state->mode = BLOCKS;
+ return Z_OK;
+}
+
+#undef NEEDBYTE
+#undef NEXTBYTE
+
+/*+++++*/
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+ /* mode */
+ enum {
+ TYPE, /* get type bits (3, including end bit) */
+ LENS, /* get lengths for stored */
+ STORED, /* processing stored block */
+ TABLE, /* get table lengths */
+ BTREE, /* get bit lengths tree for a dynamic block */
+ DTREE, /* get length, distance trees for a dynamic block */
+ CODES, /* processing fixed or dynamic block */
+ DRY, /* output remaining window bytes */
+ DONEB, /* finished last block, done */
+ BADB} /* got a data error--stuck here */
+ mode; /* current inflate_block mode */
+
+ /* mode dependent information */
+ union {
+ uInt left; /* if STORED, bytes left to copy */
+ struct {
+ uInt table; /* table lengths (14 bits) */
+ uInt index; /* index into blens (or border) */
+ uIntf *blens; /* bit lengths of codes */
+ uInt bb; /* bit length tree depth */
+ inflate_huft *tb; /* bit length decoding tree */
+ int nblens; /* # elements allocated at blens */
+ } trees; /* if DTREE, decoding info for trees */
+ struct {
+ inflate_huft *tl, *td; /* trees to free */
+ inflate_codes_statef
+ *codes;
+ } decode; /* if CODES, current state */
+ } sub; /* submode */
+ uInt last; /* true if this block is the last block */
+
+ /* mode independent information */
+ uInt bitk; /* bits in bit buffer */
+ uLong bitb; /* bit buffer */
+ Bytef *window; /* sliding window */
+ Bytef *end; /* one byte after sliding window */
+ Bytef *read; /* window read pointer */
+ Bytef *write; /* window write pointer */
+ check_func checkfn; /* check function */
+ uLong check; /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/* update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/* get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);}
+/* output bytes */
+#define WAVAIL (qread?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/* load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/*
+ * The IBM 150 firmware munges the data right after _etext[]. This
+ * protects it. -- Cort
+ */
+local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
+/* And'ing with mask[n] masks the lower n bits */
+local uInt inflate_mask[] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+/* copy as much as possible from the sliding window to the output area */
+local int inflate_flush OF((
+ inflate_blocks_statef *,
+ z_stream *,
+ int));
+
+/*+++++*/
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+local int inflate_fast OF((
+ uInt,
+ uInt,
+ inflate_huft *,
+ inflate_huft *,
+ inflate_blocks_statef *,
+ z_stream *));
+
+
+/*+++++*/
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local uInt border[] = { /* Order of the bit length code lengths */
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+ Notes beyond the 1.93a appnote.txt:
+
+ 1. Distance pointers never point before the beginning of the output
+ stream.
+ 2. Distance pointers can point back across blocks, up to 32k away.
+ 3. There is an implied maximum of 7 bits for the bit length table and
+ 15 bits for the actual data.
+ 4. If only one code exists, then it is encoded using one bit. (Zero
+ would be more efficient, but perhaps a little confusing.) If two
+ codes exist, they are coded using one bit each (0 and 1).
+ 5. There is no way of sending zero distance codes--a dummy must be
+ sent if there are none. (History: a pre 2.0 version of PKZIP would
+ store blocks with no distance codes, but this was discovered to be
+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
+ zero distance codes, which is sent as one code of zero bits in
+ length.
+ 6. There are up to 286 literal/length codes. Code 256 represents the
+ end-of-block. Note however that the static length tree defines
+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
+ cannot be used though, since there is no length base or extra bits
+ defined for them. Similarily, there are up to 30 distance codes.
+ However, static trees define 32 codes (all 5 bits) to fill out the
+ Huffman codes, but the last two had better not show up in the data.
+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
+ The exception is that a single code would not be complete (see #4).
+ 8. The five bits following the block type is really the number of
+ literal codes sent minus 257.
+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+ (1+6+6). Therefore, to output three times the length, you output
+ three codes (1+1+1), whereas to output four times the same length,
+ you only need two codes (1+3). Hmm.
+ 10. In the tree reconstruction algorithm, Code = Code + Increment
+ only if BitLength(i) is not zero. (Pretty obvious.)
+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
+ 12. Note: length code 284 can represent 227-258, but length code 285
+ really is 258. The last length deserves its own, short code
+ since it gets used a lot in very redundant files. The length
+ 258 is special since 258 - 3 (the min match length) is 255.
+ 13. The literal/length and distance code bit lengths are read as a
+ single stream of lengths. It is possible (and advantageous) for
+ a repeat code (16, 17, or 18) to go across the boundary between
+ the two sets of lengths.
+ */
+
+
+local void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_stream *z;
+uLongf *c;
+{
+ if (s->checkfn != Z_NULL)
+ *c = s->check;
+ if (s->mode == BTREE || s->mode == DTREE)
+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+ if (s->mode == CODES)
+ {
+ inflate_codes_free(s->sub.decode.codes, z);
+ inflate_trees_free(s->sub.decode.td, z);
+ inflate_trees_free(s->sub.decode.tl, z);
+ }
+ s->mode = TYPE;
+ s->bitk = 0;
+ s->bitb = 0;
+ s->read = s->write = s->window;
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(0L, Z_NULL, 0);
+ Trace((stderr, "inflate: blocks reset\n"));
+}
+
+
+local inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_stream *z;
+check_func c;
+uInt w;
+{
+ inflate_blocks_statef *s;
+
+ if ((s = (inflate_blocks_statef *)ZALLOC
+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+ return s;
+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+ {
+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
+ return Z_NULL;
+ }
+ s->end = s->window + w;
+ s->checkfn = c;
+ s->mode = TYPE;
+ Trace((stderr, "inflate: blocks allocated\n"));
+ inflate_blocks_reset(s, z, &s->check);
+ return s;
+}
+
+
+local int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+ uInt t; /* temporary storage */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input based on current state */
+ while (1) switch (s->mode)
+ {
+ case TYPE:
+ NEEDBITS(3)
+ t = (uInt)b & 7;
+ s->last = t & 1;
+ switch (t >> 1)
+ {
+ case 0: /* stored */
+ Trace((stderr, "inflate: stored block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ t = k & 7; /* go to byte boundary */
+ DUMPBITS(t)
+ s->mode = LENS; /* get length of stored block */
+ break;
+ case 1: /* fixed */
+ Trace((stderr, "inflate: fixed codes block%s\n",
+ s->last ? " (last)" : ""));
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+
+ inflate_trees_fixed(&bl, &bd, &tl, &td);
+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+ if (s->sub.decode.codes == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ s->sub.decode.tl = Z_NULL; /* don't try to free these */
+ s->sub.decode.td = Z_NULL;
+ }
+ DUMPBITS(3)
+ s->mode = CODES;
+ break;
+ case 2: /* dynamic */
+ Trace((stderr, "inflate: dynamic codes block%s\n",
+ s->last ? " (last)" : ""));
+ DUMPBITS(3)
+ s->mode = TABLE;
+ break;
+ case 3: /* illegal */
+ DUMPBITS(3)
+ s->mode = BADB;
+ z->msg = "invalid block type";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ break;
+ case LENS:
+ NEEDBITS(32)
+ if (((~b) >> 16) != (b & 0xffff))
+ {
+ s->mode = BADB;
+ z->msg = "invalid stored block lengths";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ s->sub.left = (uInt)b & 0xffff;
+ b = k = 0; /* dump bits */
+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
+ s->mode = s->sub.left ? STORED : TYPE;
+ break;
+ case STORED:
+ if (n == 0)
+ LEAVE
+ NEEDOUT
+ t = s->sub.left;
+ if (t > n) t = n;
+ if (t > m) t = m;
+ zmemcpy(q, p, t);
+ p += t; n -= t;
+ q += t; m -= t;
+ if ((s->sub.left -= t) != 0)
+ break;
+ Tracev((stderr, "inflate: stored end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ s->mode = s->last ? DRY : TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14)
+ s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+ {
+ s->mode = BADB;
+ z->msg = "too many length or distance symbols";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+#endif
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ if (t < 19)
+ t = 19;
+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+ {
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ s->sub.trees.nblens = t;
+ DUMPBITS(14)
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ s->mode = BTREE;
+ case BTREE:
+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+ {
+ NEEDBITS(3)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+ DUMPBITS(3)
+ }
+ while (s->sub.trees.index < 19)
+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+ s->sub.trees.bb = 7;
+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+ &s->sub.trees.tb, z);
+ if (t != Z_OK)
+ {
+ r = t;
+ if (r == Z_DATA_ERROR)
+ s->mode = BADB;
+ LEAVE
+ }
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: bits tree ok\n"));
+ s->mode = DTREE;
+ case DTREE:
+ while (t = s->sub.trees.table,
+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+ {
+ inflate_huft *h;
+ uInt i, j, c;
+
+ t = s->sub.trees.bb;
+ NEEDBITS(t)
+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+ t = h->word.what.Bits;
+ c = h->more.Base;
+ if (c < 16)
+ {
+ DUMPBITS(t)
+ s->sub.trees.blens[s->sub.trees.index++] = c;
+ }
+ else /* c == 16..18 */
+ {
+ i = c == 18 ? 7 : c - 14;
+ j = c == 18 ? 11 : 3;
+ NEEDBITS(t + i)
+ DUMPBITS(t)
+ j += (uInt)b & inflate_mask[i];
+ DUMPBITS(i)
+ i = s->sub.trees.index;
+ t = s->sub.trees.table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+ (c == 16 && i < 1))
+ {
+ s->mode = BADB;
+ z->msg = "invalid bit length repeat";
+ r = Z_DATA_ERROR;
+ LEAVE
+ }
+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+ do {
+ s->sub.trees.blens[i++] = c;
+ } while (--j);
+ s->sub.trees.index = i;
+ }
+ }
+ inflate_trees_free(s->sub.trees.tb, z);
+ s->sub.trees.tb = Z_NULL;
+ {
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+ inflate_codes_statef *c;
+
+ bl = 9; /* must be <= 9 for lookahead assumptions */
+ bd = 6; /* must be <= 9 for lookahead assumptions */
+ t = s->sub.trees.table;
+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+ s->sub.trees.blens, &bl, &bd, &tl, &td, z);
+ if (t != Z_OK)
+ {
+ if (t == (uInt)Z_DATA_ERROR)
+ s->mode = BADB;
+ r = t;
+ LEAVE
+ }
+ Tracev((stderr, "inflate: trees ok\n"));
+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+ {
+ inflate_trees_free(td, z);
+ inflate_trees_free(tl, z);
+ r = Z_MEM_ERROR;
+ LEAVE
+ }
+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
+ s->sub.decode.codes = c;
+ s->sub.decode.tl = tl;
+ s->sub.decode.td = td;
+ }
+ s->mode = CODES;
+ case CODES:
+ UPDATE
+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+ return inflate_flush(s, z, r);
+ r = Z_OK;
+ inflate_codes_free(s->sub.decode.codes, z);
+ inflate_trees_free(s->sub.decode.td, z);
+ inflate_trees_free(s->sub.decode.tl, z);
+ LOAD
+ Tracev((stderr, "inflate: codes end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ if (!s->last)
+ {
+ s->mode = TYPE;
+ break;
+ }
+ if (k > 7) /* return unused byte, if any */
+ {
+ Assert(k < 16, "inflate_codes grabbed too many bytes")
+ k -= 8;
+ n++;
+ p--; /* can always return one */
+ }
+ s->mode = DRY;
+ case DRY:
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ s->mode = DONEB;
+ case DONEB:
+ r = Z_STREAM_END;
+ LEAVE
+ case BADB:
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+}
+
+
+local int inflate_blocks_free(s, z, c)
+inflate_blocks_statef *s;
+z_stream *z;
+uLongf *c;
+{
+ inflate_blocks_reset(s, z, c);
+ ZFREE(z, s->window, s->end - s->window);
+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
+ Trace((stderr, "inflate: blocks freed\n"));
+ return Z_OK;
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output. The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS). On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+local int inflate_addhistory(s, z)
+inflate_blocks_statef *s;
+z_stream *z;
+{
+ uLong b; /* bit buffer */ /* NOT USED HERE */
+ uInt k; /* bits in bit buffer */ /* NOT USED HERE */
+ uInt t; /* temporary storage */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ if (s->read != s->write)
+ return Z_STREAM_ERROR;
+ if (s->mode != TYPE)
+ return Z_DATA_ERROR;
+
+ /* we're ready to rock */
+ LOAD
+ /* while there is input ready, copy to output buffer, moving
+ * pointers as needed.
+ */
+ while (n) {
+ t = n; /* how many to do */
+ /* is there room until end of buffer? */
+ if (t > m) t = m;
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(s->check, q, t);
+ zmemcpy(q, p, t);
+ q += t;
+ p += t;
+ n -= t;
+ z->total_out += t;
+ s->read = q; /* drag read pointer forward */
+/* WRAP */ /* expand WRAP macro by hand to handle s->read */
+ if (q == s->end) {
+ s->read = q = s->window;
+ m = WAVAIL;
+ }
+ }
+ UPDATE
+ return Z_OK;
+}
+
+
+/*
+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
+ * a `stored' block type value but not the (zero) length bytes.
+ */
+local int inflate_packet_flush(s)
+ inflate_blocks_statef *s;
+{
+ if (s->mode != LENS)
+ return Z_DATA_ERROR;
+ s->mode = TYPE;
+ return Z_OK;
+}
+
+
+/*+++++*/
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+ uIntf *, /* code lengths in bits */
+ uInt, /* number of codes */
+ uInt, /* number of "simple" codes */
+ uIntf *, /* list of base values for non-simple codes */
+ uIntf *, /* list of extra bits for non-simple codes */
+ inflate_huft * FAR*,/* result: starting table */
+ uIntf *, /* maximum lookup bits (returns actual) */
+ z_stream *)); /* for zalloc function */
+
+local voidpf falloc OF((
+ voidpf, /* opaque pointer (not used) */
+ uInt, /* number of items */
+ uInt)); /* size of item */
+
+local void ffree OF((
+ voidpf q, /* opaque pointer (not used) */
+ voidpf p, /* what to free (not used) */
+ uInt n)); /* number of bytes (not used) */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ /* actually lengths - 2; also see note #13 above about 258 */
+local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
+local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577};
+local uInt cpdext[] = { /* Extra bits for distance codes */
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13};
+
+/*
+ Huffman code decoding is performed using a multi-level table lookup.
+ The fastest way to decode is to simply build a lookup table whose
+ size is determined by the longest code. However, the time it takes
+ to build this table can also be a factor if the data being decoded
+ is not very long. The most common codes are necessarily the
+ shortest codes, so those codes dominate the decoding time, and hence
+ the speed. The idea is you can have a shorter table that decodes the
+ shorter, more probable codes, and then point to subsidiary tables for
+ the longer codes. The time it costs to decode the longer codes is
+ then traded against the time it takes to make longer tables.
+
+ This results of this trade are in the variables lbits and dbits
+ below. lbits is the number of bits the first level table for literal/
+ length codes can decode in one step, and dbits is the same thing for
+ the distance codes. Subsequent tables are also less than or equal to
+ those sizes. These values may be adjusted either when all of the
+ codes are shorter than that, in which case the longest code length in
+ bits is used, or when the shortest code is *longer* than the requested
+ table size, in which case the length of the shortest code in bits is
+ used.
+
+ There are two different values for the two tables, since they code a
+ different number of possibilities each. The literal/length table
+ codes 286 possible values, or in a flat code, a little over eight
+ bits. The distance table codes 30 possible values, or a little less
+ than five bits, flat. The optimum values for speed end up being
+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+ The optimum values may differ though from machine to machine, and
+ possibly even between compilers. Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15 /* maximum bit length of any code */
+#define N_MAX 288 /* maximum number of codes in any set */
+
+#ifdef DEBUG_ZLIB
+ uInt inflate_hufts;
+#endif
+
+local int huft_build(b, n, s, d, e, t, m, zs)
+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
+uInt n; /* number of codes (assumed <= N_MAX) */
+uInt s; /* number of simple-valued codes (0..s-1) */
+uIntf *d; /* list of base values for non-simple codes */
+uIntf *e; /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t; /* result: starting table */
+uIntf *m; /* maximum lookup bits, returns actual */
+z_stream *zs; /* for zalloc function */
+/* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
+ if the given code set is incomplete (the tables are still built in this
+ case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
+ over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+ uInt a; /* counter for codes of length k */
+ uInt c[BMAX+1]; /* bit length count table */
+ uInt f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ register uInt i; /* counter, current code */
+ register uInt j; /* counter */
+ register int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ register uIntf *p; /* pointer into c[], b[], or v[] */
+ inflate_huft *q; /* points to current table */
+ struct inflate_huft_s r; /* table entry for structure assignment */
+ inflate_huft *u[BMAX]; /* table stack */
+ uInt v[N_MAX]; /* values in order of bit length */
+ register int w; /* bits before this table == (l * h) */
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
+ uIntf *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ uInt z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+ C4 /* clear c[]--assume BMAX+1 is 16 */
+ p = b; i = n;
+ do {
+ c[*p++]++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (inflate_huft *)Z_NULL;
+ *m = 0;
+ return Z_OK;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ l = *m;
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if ((uInt)l < j)
+ l = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if ((uInt)l > i)
+ l = i;
+ *m = l;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return Z_DATA_ERROR;
+ if ((y -= c[i]) < 0)
+ return Z_DATA_ERROR;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ p = b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = -l; /* bits decoded == (l * h) */
+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
+ q = (inflate_huft *)Z_NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > w + l)
+ {
+ h++;
+ w += l; /* previous table always l bits */
+
+ /* compute minimum size table less than or equal to l bits */
+ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ if (j < z)
+ while (++j < z) /* try smaller tables up to z bits */
+ {
+ if ((f <<= 1) <= *++xp)
+ break; /* enough codes to use up j bits */
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ z = 1 << j; /* table entries for j-bit table */
+
+ /* allocate and link in new table */
+ if ((q = (inflate_huft *)ZALLOC
+ (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
+ {
+ if (h)
+ inflate_trees_free(u[0], zs);
+ return Z_MEM_ERROR; /* not enough memory */
+ }
+ q->word.Nalloc = z + 1;
+#ifdef DEBUG_ZLIB
+ inflate_hufts += z + 1;
+#endif
+ *t = q + 1; /* link to list for huft_free() */
+ *(t = &(q->next)) = Z_NULL;
+ u[h] = ++q; /* table starts after link */
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.bits = (Byte)l; /* bits to dump before this table */
+ r.exop = (Byte)j; /* bits in this table */
+ r.next = q; /* pointer to this table */
+ j = i >> (w - l); /* (get around Turbo C bug) */
+ u[h-1][j] = r; /* connect to last table */
+ }
+ }
+
+ /* set up table entry in r */
+ r.bits = (Byte)(k - w);
+ if (p >= v + n)
+ r.exop = 128 + 64; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
+ r.base = *p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
+ r.base = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ while ((i & ((1 << w) - 1)) != x[h])
+ {
+ h--; /* don't need to update q */
+ w -= l;
+ }
+ }
+ }
+
+
+ /* Return Z_BUF_ERROR if we were given an incomplete table */
+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+local int inflate_trees_bits(c, bb, tb, z)
+uIntf *c; /* 19 code lengths */
+uIntf *bb; /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+z_stream *z; /* for zfree function */
+{
+ int r;
+
+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
+ if (r == Z_DATA_ERROR)
+ z->msg = "oversubscribed dynamic bit lengths tree";
+ else if (r == Z_BUF_ERROR)
+ {
+ inflate_trees_free(*tb, z);
+ z->msg = "incomplete dynamic bit lengths tree";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+}
+
+
+local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
+uInt nl; /* number of literal/length codes */
+uInt nd; /* number of distance codes */
+uIntf *c; /* that many (total) code lengths */
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+z_stream *z; /* for zfree function */
+{
+ int r;
+
+ /* build literal/length tree */
+ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = "oversubscribed literal/length tree";
+ else if (r == Z_BUF_ERROR)
+ {
+ inflate_trees_free(*tl, z);
+ z->msg = "incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ return r;
+ }
+
+ /* build distance tree */
+ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
+ {
+ if (r == Z_DATA_ERROR)
+ z->msg = "oversubscribed literal/length tree";
+ else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+ r = Z_OK;
+ }
+#else
+ inflate_trees_free(*td, z);
+ z->msg = "incomplete literal/length tree";
+ r = Z_DATA_ERROR;
+ }
+ inflate_trees_free(*tl, z);
+ return r;
+#endif
+ }
+
+ /* done */
+ return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+local int fixed_lock = 0;
+local int fixed_built = 0;
+#define FIXEDH 530 /* number of hufts used by fixed tables */
+local uInt fixed_left = FIXEDH;
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+
+
+local voidpf falloc(q, n, s)
+voidpf q; /* opaque pointer (not used) */
+uInt n; /* number of items */
+uInt s; /* size of item */
+{
+ Assert(s == sizeof(inflate_huft) && n <= fixed_left,
+ "inflate_trees falloc overflow");
+ if (q) s++; /* to make some compilers happy */
+ fixed_left -= n;
+ return (voidpf)(fixed_mem + fixed_left);
+}
+
+
+local void ffree(q, p, n)
+voidpf q;
+voidpf p;
+uInt n;
+{
+ Assert(0, "inflate_trees ffree called!");
+ if (q) q = p; /* to make some compilers happy */
+}
+
+
+local int inflate_trees_fixed(bl, bd, tl, td)
+uIntf *bl; /* literal desired/actual bit depth */
+uIntf *bd; /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+{
+ /* build fixed tables if not built already--lock out other instances */
+ while (++fixed_lock > 1)
+ fixed_lock--;
+ if (!fixed_built)
+ {
+ int k; /* temporary variable */
+ unsigned c[288]; /* length list for huft_build */
+ z_stream z; /* for falloc function */
+
+ /* set up fake z_stream for memory routines */
+ z.zalloc = falloc;
+ z.zfree = ffree;
+ z.opaque = Z_NULL;
+
+ /* literal table */
+ for (k = 0; k < 144; k++)
+ c[k] = 8;
+ for (; k < 256; k++)
+ c[k] = 9;
+ for (; k < 280; k++)
+ c[k] = 7;
+ for (; k < 288; k++)
+ c[k] = 8;
+ fixed_bl = 7;
+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
+
+ /* distance table */
+ for (k = 0; k < 30; k++)
+ c[k] = 5;
+ fixed_bd = 5;
+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
+
+ /* done */
+ fixed_built = 1;
+ }
+ fixed_lock--;
+ *bl = fixed_bl;
+ *bd = fixed_bd;
+ *tl = fixed_tl;
+ *td = fixed_td;
+ return Z_OK;
+}
+
+
+local int inflate_trees_free(t, z)
+inflate_huft *t; /* table to free */
+z_stream *z; /* for zfree function */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+ list of the tables it made, with the links in a dummy first entry of
+ each table. */
+{
+ register inflate_huft *p, *q;
+
+ /* Go through linked list, freeing from the malloced (t[-1]) address. */
+ p = t;
+ while (p != Z_NULL)
+ {
+ q = (--p)->next;
+ ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
+ p = q;
+ }
+ return Z_OK;
+}
+
+/*+++++*/
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+ /* mode */
+ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ START, /* x: set up for LEN */
+ LEN, /* i: get length/literal/eob next */
+ LENEXT, /* i: getting length extra (have base) */
+ DIST, /* i: get distance next */
+ DISTEXT, /* i: getting distance extra */
+ COPY, /* o: copying bytes in window, waiting for space */
+ LIT, /* o: got literal, waiting for output space */
+ WASH, /* o: got eob, possibly still output waiting */
+ END, /* x: got eob and all data flushed */
+ BADCODE} /* x: got error */
+ mode; /* current inflate_codes mode */
+
+ /* mode dependent information */
+ uInt len;
+ union {
+ struct {
+ inflate_huft *tree; /* pointer into tree */
+ uInt need; /* bits needed */
+ } code; /* if LEN or DIST, where in tree */
+ uInt lit; /* if LIT, literal */
+ struct {
+ uInt get; /* bits to get for extra */
+ uInt dist; /* distance back to copy from */
+ } copy; /* if EXT or COPY, where and how much */
+ } sub; /* submode */
+
+ /* mode independent information */
+ Byte lbits; /* ltree bits decoded per branch */
+ Byte dbits; /* dtree bits decoder per branch */
+ inflate_huft *ltree; /* literal/length/eob tree */
+ inflate_huft *dtree; /* distance tree */
+
+};
+
+
+local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+z_stream *z;
+{
+ inflate_codes_statef *c;
+
+ if ((c = (inflate_codes_statef *)
+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+ {
+ c->mode = START;
+ c->lbits = (Byte)bl;
+ c->dbits = (Byte)bd;
+ c->ltree = tl;
+ c->dtree = td;
+ Tracev((stderr, "inflate: codes new\n"));
+ }
+ return c;
+}
+
+
+local int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+ uInt j; /* temporary storage */
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ Bytef *f; /* pointer to copy strings from */
+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input and output based on current state */
+ while (1) switch (c->mode)
+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ case START: /* x: set up for LEN */
+#ifndef SLOW
+ if (m >= 258 && n >= 10)
+ {
+ UPDATE
+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+ LOAD
+ if (r != Z_OK)
+ {
+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+ break;
+ }
+ }
+#endif /* !SLOW */
+ c->sub.code.need = c->lbits;
+ c->sub.code.tree = c->ltree;
+ c->mode = LEN;
+ case LEN: /* i: get length/literal/eob next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e == 0) /* literal */
+ {
+ c->sub.lit = t->base;
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", t->base));
+ c->mode = LIT;
+ break;
+ }
+ if (e & 16) /* length */
+ {
+ c->sub.copy.get = e & 15;
+ c->len = t->base;
+ c->mode = LENEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t->next;
+ break;
+ }
+ if (e & 32) /* end of block */
+ {
+ Tracevv((stderr, "inflate: end of block\n"));
+ c->mode = WASH;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = "invalid literal/length code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case LENEXT: /* i: getting length extra (have base) */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->len += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ c->sub.code.need = c->dbits;
+ c->sub.code.tree = c->dtree;
+ Tracevv((stderr, "inflate: length %u\n", c->len));
+ c->mode = DIST;
+ case DIST: /* i: get distance next */
+ j = c->sub.code.need;
+ NEEDBITS(j)
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+ DUMPBITS(t->bits)
+ e = (uInt)(t->exop);
+ if (e & 16) /* distance */
+ {
+ c->sub.copy.get = e & 15;
+ c->sub.copy.dist = t->base;
+ c->mode = DISTEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = t->next;
+ break;
+ }
+ c->mode = BADCODE; /* invalid code */
+ z->msg = "invalid distance code";
+ r = Z_DATA_ERROR;
+ LEAVE
+ case DISTEXT: /* i: getting distance extra */
+ j = c->sub.copy.get;
+ NEEDBITS(j)
+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
+ DUMPBITS(j)
+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
+ c->mode = COPY;
+ case COPY: /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
+ s->end - (c->sub.copy.dist - (q - s->window)) :
+ q - c->sub.copy.dist;
+#else
+ f = q - c->sub.copy.dist;
+ if ((uInt)(q - s->window) < c->sub.copy.dist)
+ f = s->end - (c->sub.copy.dist - (q - s->window));
+#endif
+ while (c->len)
+ {
+ NEEDOUT
+ OUTBYTE(*f++)
+ if (f == s->end)
+ f = s->window;
+ c->len--;
+ }
+ c->mode = START;
+ break;
+ case LIT: /* o: got literal, waiting for output space */
+ NEEDOUT
+ OUTBYTE(c->sub.lit)
+ c->mode = START;
+ break;
+ case WASH: /* o: got eob, possibly more output */
+ FLUSH
+ if (s->read != s->write)
+ LEAVE
+ c->mode = END;
+ case END:
+ r = Z_STREAM_END;
+ LEAVE
+ case BADCODE: /* x: got error */
+ r = Z_DATA_ERROR;
+ LEAVE
+ default:
+ r = Z_STREAM_ERROR;
+ LEAVE
+ }
+}
+
+
+local void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_stream *z;
+{
+ ZFREE(z, c, sizeof(struct inflate_codes_state));
+ Tracev((stderr, "inflate: codes free\n"));
+}
+
+/*+++++*/
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* copy as much as possible from the sliding window to the output area */
+local int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_stream *z;
+int r;
+{
+ uInt n;
+ Bytef *p, *q;
+
+ /* local copies of source and destination pointers */
+ p = z->next_out;
+ q = s->read;
+
+ /* compute number of bytes to copy as far as end of window */
+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy as far as end of window */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+
+ /* see if more to copy at beginning of window */
+ if (q == s->end)
+ {
+ /* wrap pointers */
+ q = s->window;
+ if (s->write == s->end)
+ s->write = s->window;
+
+ /* compute bytes to copy */
+ n = (uInt)(s->write - q);
+ if (n > z->avail_out) n = z->avail_out;
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+ /* update counters */
+ z->avail_out -= n;
+ z->total_out += n;
+
+ /* update check information */
+ if (s->checkfn != Z_NULL)
+ s->check = (*s->checkfn)(s->check, q, n);
+
+ /* copy */
+ zmemcpy(p, q, n);
+ p += n;
+ q += n;
+ }
+
+ /* update pointers */
+ z->next_out = p;
+ s->read = q;
+
+ /* done */
+ return r;
+}
+
+
+/*+++++*/
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;}
+
+/* Called with number of bytes left to write in window at least 258
+ (the maximum string length) and number of input bytes available
+ at least ten. The ten bytes are six bytes for the longest length/
+ distance pair plus four bytes for overloading the bit buffer. */
+
+local int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+inflate_blocks_statef *s;
+z_stream *z;
+{
+ inflate_huft *t; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+ uInt ml; /* mask for literal/length tree */
+ uInt md; /* mask for distance tree */
+ uInt c; /* bytes to copy */
+ uInt d; /* distance back to copy from */
+ Bytef *r; /* copy source pointer */
+
+ /* load input, output, bit values */
+ LOAD
+
+ /* initialize masks */
+ ml = inflate_mask[bl];
+ md = inflate_mask[bd];
+
+ /* do until not enough input or output space for fast loop */
+ do { /* assume called with m >= 258 && n >= 10 */
+ /* get literal/length code */
+ GRABBITS(20) /* max bits for literal/length code */
+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ continue;
+ }
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits for length */
+ e &= 15;
+ c = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * length %u\n", c));
+
+ /* decode distance base of block to copy */
+ GRABBITS(15); /* max bits for distance code */
+ e = (t = td + ((uInt)b & md))->exop;
+ do {
+ DUMPBITS(t->bits)
+ if (e & 16)
+ {
+ /* get extra bits to add to distance base */
+ e &= 15;
+ GRABBITS(e) /* get extra bits (up to 13) */
+ d = t->base + ((uInt)b & inflate_mask[e]);
+ DUMPBITS(e)
+ Tracevv((stderr, "inflate: * distance %u\n", d));
+
+ /* do the copy */
+ m -= c;
+ if ((uInt)(q - s->window) >= d) /* offset before dest */
+ { /* just copy */
+ r = q - d;
+ *q++ = *r++; c--; /* minimum count is three, */
+ *q++ = *r++; c--; /* so unroll loop a little */
+ }
+ else /* else offset after destination */
+ {
+ e = d - (q - s->window); /* bytes from offset to end */
+ r = s->end - e; /* pointer to offset */
+ if (c > e) /* if source crosses, */
+ {
+ c -= e; /* copy to end of window */
+ do {
+ *q++ = *r++;
+ } while (--e);
+ r = s->window; /* copy rest from start of window */
+ }
+ }
+ do { /* copy all or what's left */
+ *q++ = *r++;
+ } while (--c);
+ break;
+ }
+ else if ((e & 64) == 0)
+ e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
+ else
+ {
+ z->msg = "invalid distance code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ break;
+ }
+ if ((e & 64) == 0)
+ {
+ if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
+ {
+ DUMPBITS(t->bits)
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+ "inflate: * literal '%c'\n" :
+ "inflate: * literal 0x%02x\n", t->base));
+ *q++ = (Byte)t->base;
+ m--;
+ break;
+ }
+ }
+ else if (e & 32)
+ {
+ Tracevv((stderr, "inflate: * end of block\n"));
+ UNGRAB
+ UPDATE
+ return Z_STREAM_END;
+ }
+ else
+ {
+ z->msg = "invalid literal/length code";
+ UNGRAB
+ UPDATE
+ return Z_DATA_ERROR;
+ }
+ } while (1);
+ } while (m >= 258 && n >= 10);
+
+ /* not enough input or output--restore pointers and return */
+ UNGRAB
+ UPDATE
+ return Z_OK;
+}
+
+
+/*+++++*/
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
+
+char *zlib_version = ZLIB_VERSION;
+
+char *z_errmsg[] = {
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+""};
+
+
+/*+++++*/
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf) {s1 += *buf++; s2 += s1;}
+#define DO2(buf) DO1(buf); DO1(buf);
+#define DO4(buf) DO2(buf); DO2(buf);
+#define DO8(buf) DO4(buf); DO4(buf);
+#define DO16(buf) DO8(buf); DO8(buf);
+
+/* ========================================================================= */
+uLong adler32(adler, buf, len)
+ uLong adler;
+ Bytef *buf;
+ uInt len;
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == Z_NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ k -= 16;
+ }
+ if (k != 0) do {
+ DO1(buf);
+ } while (--k);
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ return (s2 << 16) | s1;
+}
diff --git a/trunk/arch/xtensa/boot/lib/zmem.c b/trunk/arch/xtensa/boot/lib/zmem.c
index d9862aa8ca25..7848f126d67d 100644
--- a/trunk/arch/xtensa/boot/lib/zmem.c
+++ b/trunk/arch/xtensa/boot/lib/zmem.c
@@ -1,4 +1,4 @@
-#include
+#include "zlib.h"
/* bits taken from ppc */
@@ -9,10 +9,11 @@ void exit (void)
for (;;);
}
-void *zalloc(unsigned size)
+void *zalloc(void *x, unsigned items, unsigned size)
{
void *p = avail_ram;
+ size *= items;
size = (size + 7) & -8;
avail_ram += size;
if (avail_ram > end_avail) {
@@ -23,6 +24,11 @@ void *zalloc(unsigned size)
return p;
}
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
@@ -37,6 +43,7 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp)
int r, i, flags;
/* skip header */
+
i = 10;
flags = src[3];
if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
@@ -58,8 +65,9 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp)
exit();
}
- s.workspace = zalloc(zlib_inflate_workspacesize());
- r = zlib_inflateInit2(&s, -MAX_WBITS);
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
if (r != Z_OK) {
//puts("inflateInit2 returned "); puthex(r); puts("\n");
exit();
@@ -68,12 +76,12 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp)
s.avail_in = *lenp - i;
s.next_out = dst;
s.avail_out = dstlen;
- r = zlib_inflate(&s, Z_FINISH);
+ r = inflate(&s, Z_FINISH);
if (r != Z_OK && r != Z_STREAM_END) {
//puts("inflate returned "); puthex(r); puts("\n");
exit();
}
*lenp = s.next_out - (unsigned char *) dst;
- zlib_inflateEnd(&s);
+ inflateEnd(&s);
}
diff --git a/trunk/arch/xtensa/kernel/pci.c b/trunk/arch/xtensa/kernel/pci.c
index 09887c96e9a1..d29a81648637 100644
--- a/trunk/arch/xtensa/kernel/pci.c
+++ b/trunk/arch/xtensa/kernel/pci.c
@@ -57,6 +57,50 @@ struct pci_controller** pci_ctrl_tail = &pci_ctrl_head;
static int pci_bus_count;
+static void pcibios_fixup_resources(struct pci_dev* dev);
+
+#if 0 // FIXME
+struct pci_fixup pcibios_fixups[] = {
+ { DECLARE_PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources },
+ { 0 }
+};
+#endif
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
+{
+ u32 new, check, mask;
+ int reg;
+ struct pci_controller* pci_ctrl = dev->sysdata;
+
+ new = res->start;
+ if (pci_ctrl && res->flags & IORESOURCE_IO) {
+ new -= pci_ctrl->io_space.base;
+ }
+ new |= (res->flags & PCI_REGION_FLAG_MASK);
+ if (resource < 6) {
+ reg = PCI_BASE_ADDRESS_0 + 4*resource;
+ } else if (resource == PCI_ROM_RESOURCE) {
+ res->flags |= PCI_ROM_ADDRESS_ENABLE;
+ reg = dev->rom_base_reg;
+ } else {
+ /* Somebody might have asked allocation of a non-standard resource */
+ return;
+ }
+
+ pci_write_config_dword(dev, reg, new);
+ pci_read_config_dword(dev, reg, &check);
+ mask = (new & PCI_BASE_ADDRESS_SPACE_IO) ?
+ PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK;
+
+ if ((new ^ check) & mask) {
+ printk(KERN_ERR "PCI: Error while updating region "
+ "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+ new, check);
+ }
+}
+
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
@@ -81,7 +125,7 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size,
if (size > 0x100) {
printk(KERN_ERR "PCI: I/O Region %s/%d too large"
- " (%ld bytes)\n", pci_name(dev),
+ " (%ld bytes)\n", dev->slot_name,
dev->resource - res, size);
}
@@ -105,7 +149,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask)
r = &dev->resource[idx];
if (!r->start && r->end) {
printk (KERN_ERR "PCI: Device %s not available because "
- "of resource collisions\n", pci_name(dev));
+ "of resource collisions\n", dev->slot_name);
return -EINVAL;
}
if (r->flags & IORESOURCE_IO)
@@ -117,7 +161,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask)
cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n",
- pci_name(dev), old_cmd, cmd);
+ dev->slot_name, old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
return 0;
@@ -249,7 +293,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
r = &dev->resource[idx];
if (!r->start && r->end) {
printk(KERN_ERR "PCI: Device %s not available because "
- "of resource collisions\n", pci_name(dev));
+ "of resource collisions\n", dev->slot_name);
return -EINVAL;
}
if (r->flags & IORESOURCE_IO)
@@ -259,7 +303,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
}
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n",
- pci_name(dev), old_cmd, cmd);
+ dev->slot_name, old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
@@ -281,6 +325,47 @@ pci_controller_num(struct pci_dev *dev)
#endif /* CONFIG_PROC_FS */
+
+static void
+pcibios_fixup_resources(struct pci_dev *dev)
+{
+ struct pci_controller* pci_ctrl = (struct pci_controller *)dev->sysdata;
+ int i;
+ unsigned long offset;
+
+ if (!pci_ctrl) {
+ printk(KERN_ERR "No pci_ctrl for PCI dev %s!\n",dev->slot_name);
+ return;
+ }
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ struct resource *res = dev->resource + i;
+ if (!res->start || !res->flags)
+ continue;
+ if (res->end == 0xffffffff) {
+ DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
+ dev->slot_name, i, res->start, res->end);
+ res->end -= res->start;
+ res->start = 0;
+ continue;
+ }
+ offset = 0;
+ if (res->flags & IORESOURCE_IO)
+ offset = (unsigned long) pci_ctrl->io_space.base;
+ else if (res->flags & IORESOURCE_MEM)
+ offset = (unsigned long) pci_ctrl->mem_space.base;
+
+ if (offset != 0) {
+ res->start += offset;
+ res->end += offset;
+#ifdef DEBUG
+ printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n",
+ i, res->flags, dev->slot_name,
+ res->start - offset, res->start);
+#endif
+ }
+ }
+}
+
/*
* Platform support for /proc/bus/pci/X/Y mmap()s,
* modelled on the sparc64 implementation by Dave Miller.
diff --git a/trunk/arch/xtensa/kernel/ptrace.c b/trunk/arch/xtensa/kernel/ptrace.c
index 2659efdd4e99..9ef07a4dd2a2 100644
--- a/trunk/arch/xtensa/kernel/ptrace.c
+++ b/trunk/arch/xtensa/kernel/ptrace.c
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
#include
@@ -240,7 +239,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_CONT: /* restart after signal. */
{
ret = -EIO;
- if (!valid_signal(data))
+ if ((unsigned long) data > _NSIG)
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -270,7 +269,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP:
ret = -EIO;
- if (!valid_signal(data))
+ if ((unsigned long) data > _NSIG)
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->ptrace |= PT_SINGLESTEP;
diff --git a/trunk/drivers/acpi/container.c b/trunk/drivers/acpi/container.c
index 97013ddfa202..5a0adbf8bc04 100644
--- a/trunk/drivers/acpi/container.c
+++ b/trunk/drivers/acpi/container.c
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle)
return_VALUE(-ENODEV);
}
- result = acpi_bus_start(*device);
+ result = acpi_bus_scan(*device);
return_VALUE(result);
}
diff --git a/trunk/drivers/acpi/pci_bind.c b/trunk/drivers/acpi/pci_bind.c
index 5148f3c10b5c..5d19b39e9e2b 100644
--- a/trunk/drivers/acpi/pci_bind.c
+++ b/trunk/drivers/acpi/pci_bind.c
@@ -61,14 +61,15 @@ acpi_pci_data_handler (
/**
- * acpi_get_pci_id
+ * acpi_os_get_pci_id
* ------------------
* This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
* to resolve PCI information for ACPI-PCI devices defined in the namespace.
* This typically occurs when resolving PCI operation region information.
*/
+#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_get_pci_id (
+acpi_os_get_pci_id (
acpi_handle handle,
struct acpi_pci_id *id)
{
@@ -77,7 +78,7 @@ acpi_get_pci_id (
struct acpi_device *device = NULL;
struct acpi_pci_data *data = NULL;
- ACPI_FUNCTION_TRACE("acpi_get_pci_id");
+ ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
if (!id)
return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -91,7 +92,7 @@ acpi_get_pci_id (
}
status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
- if (ACPI_FAILURE(status) || !data) {
+ if (ACPI_FAILURE(status) || !data || !data->dev) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Invalid ACPI-PCI context for device %s\n",
acpi_device_bid(device)));
@@ -114,7 +115,7 @@ acpi_get_pci_id (
return_ACPI_STATUS(AE_OK);
}
-EXPORT_SYMBOL(acpi_get_pci_id);
+#endif /* ACPI_FUTURE_USAGE */
int
@@ -128,8 +129,6 @@ acpi_pci_bind (
char *pathname = NULL;
struct acpi_buffer buffer = {0, NULL};
acpi_handle handle = NULL;
- struct pci_dev *dev;
- struct pci_bus *bus;
ACPI_FUNCTION_TRACE("acpi_pci_bind");
@@ -194,20 +193,8 @@ acpi_pci_bind (
* Locate matching device in PCI namespace. If it doesn't exist
* this typically means that the device isn't currently inserted
* (e.g. docking station, port replicator, etc.).
- * We cannot simply search the global pci device list, since
- * PCI devices are added to the global pci list when the root
- * bridge start ops are run, which may not have happened yet.
*/
- bus = pci_find_bus(data->id.segment, data->id.bus);
- if (bus) {
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (dev->devfn == PCI_DEVFN(data->id.device,
- data->id.function)) {
- data->dev = dev;
- break;
- }
- }
- }
+ data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
if (!data->dev) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c
index 5d2f77fcd50c..7e6b8e3b2ed4 100644
--- a/trunk/drivers/acpi/pci_root.c
+++ b/trunk/drivers/acpi/pci_root.c
@@ -46,7 +46,6 @@ ACPI_MODULE_NAME ("pci_root")
static int acpi_pci_root_add (struct acpi_device *device);
static int acpi_pci_root_remove (struct acpi_device *device, int type);
-static int acpi_pci_root_start (struct acpi_device *device);
static struct acpi_driver acpi_pci_root_driver = {
.name = ACPI_PCI_ROOT_DRIVER_NAME,
@@ -55,7 +54,6 @@ static struct acpi_driver acpi_pci_root_driver = {
.ops = {
.add = acpi_pci_root_add,
.remove = acpi_pci_root_remove,
- .start = acpi_pci_root_start,
},
};
@@ -171,7 +169,6 @@ acpi_pci_root_add (
if (!root)
return_VALUE(-ENOMEM);
memset(root, 0, sizeof(struct acpi_pci_root));
- INIT_LIST_HEAD(&root->node);
root->handle = device->handle;
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
@@ -301,31 +298,12 @@ acpi_pci_root_add (
root->id.bus);
end:
- if (result) {
- if (!list_empty(&root->node))
- list_del(&root->node);
+ if (result)
kfree(root);
- }
return_VALUE(result);
}
-static int
-acpi_pci_root_start (
- struct acpi_device *device)
-{
- struct acpi_pci_root *root;
-
- ACPI_FUNCTION_TRACE("acpi_pci_root_start");
-
- list_for_each_entry(root, &acpi_pci_roots, node) {
- if (root->handle == device->handle) {
- pci_bus_add_devices(root->bus);
- return_VALUE(0);
- }
- }
- return_VALUE(-ENODEV);
-}
static int
acpi_pci_root_remove (
diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c
index 76156ac91bd3..f4778747e889 100644
--- a/trunk/drivers/acpi/processor_core.c
+++ b/trunk/drivers/acpi/processor_core.c
@@ -723,7 +723,7 @@ int acpi_processor_device_add(
return_VALUE(-ENODEV);
}
- acpi_bus_start(*device);
+ acpi_bus_scan(*device);
pr = acpi_driver_data(*device);
if (!pr)
diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c
index 337d49b5564b..e85885593280 100644
--- a/trunk/drivers/acpi/scan.c
+++ b/trunk/drivers/acpi/scan.c
@@ -553,29 +553,20 @@ acpi_bus_driver_init (
* upon possible configuration and currently allocated resources.
*/
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
- return_VALUE(0);
-}
-
-int
-acpi_start_single_object (
- struct acpi_device *device)
-{
- int result = 0;
- struct acpi_driver *driver;
-
- ACPI_FUNCTION_TRACE("acpi_start_single_object");
-
- if (!(driver = device->driver))
- return_VALUE(0);
-
if (driver->ops.start) {
result = driver->ops.start(device);
if (result && driver->ops.remove)
driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
+ return_VALUE(result);
}
- return_VALUE(result);
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+
+ if (driver->ops.scan) {
+ driver->ops.scan(device);
+ }
+
+ return_VALUE(0);
}
static int acpi_driver_attach(struct acpi_driver * drv)
@@ -595,7 +586,6 @@ static int acpi_driver_attach(struct acpi_driver * drv)
if (!acpi_bus_match(dev, drv)) {
if (!acpi_bus_driver_init(dev, drv)) {
- acpi_start_single_object(dev);
atomic_inc(&drv->references);
count++;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1019,8 +1009,8 @@ acpi_bus_remove (
}
-static int
-acpi_add_single_object (
+int
+acpi_bus_add (
struct acpi_device **child,
struct acpi_device *parent,
acpi_handle handle,
@@ -1029,7 +1019,7 @@ acpi_add_single_object (
int result = 0;
struct acpi_device *device = NULL;
- ACPI_FUNCTION_TRACE("acpi_add_single_object");
+ ACPI_FUNCTION_TRACE("acpi_bus_add");
if (!child)
return_VALUE(-EINVAL);
@@ -1150,7 +1140,7 @@ acpi_add_single_object (
*
* TBD: Assumes LDM provides driver hot-plug capability.
*/
- result = acpi_bus_find_driver(device);
+ acpi_bus_find_driver(device);
end:
if (!result)
@@ -1163,10 +1153,10 @@ acpi_add_single_object (
return_VALUE(result);
}
+EXPORT_SYMBOL(acpi_bus_add);
-static int acpi_bus_scan (struct acpi_device *start,
- struct acpi_bus_ops *ops)
+int acpi_bus_scan (struct acpi_device *start)
{
acpi_status status = AE_OK;
struct acpi_device *parent = NULL;
@@ -1239,20 +1229,9 @@ static int acpi_bus_scan (struct acpi_device *start,
continue;
}
- if (ops->acpi_op_add)
- status = acpi_add_single_object(&child, parent,
- chandle, type);
- else
- status = acpi_bus_get_device(chandle, &child);
-
- if (ACPI_FAILURE(status))
- continue;
-
- if (ops->acpi_op_start) {
- status = acpi_start_single_object(child);
- if (ACPI_FAILURE(status))
- continue;
- }
+ status = acpi_bus_add(&child, parent, chandle, type);
+ if (ACPI_FAILURE(status))
+ continue;
/*
* If the device is present, enabled, and functioning then
@@ -1278,50 +1257,8 @@ static int acpi_bus_scan (struct acpi_device *start,
return_VALUE(0);
}
+EXPORT_SYMBOL(acpi_bus_scan);
-int
-acpi_bus_add (
- struct acpi_device **child,
- struct acpi_device *parent,
- acpi_handle handle,
- int type)
-{
- int result;
- struct acpi_bus_ops ops;
-
- ACPI_FUNCTION_TRACE("acpi_bus_add");
-
- result = acpi_add_single_object(child, parent, handle, type);
- if (!result) {
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
- result = acpi_bus_scan(*child, &ops);
- }
- return_VALUE(result);
-}
-EXPORT_SYMBOL(acpi_bus_add);
-
-int
-acpi_bus_start (
- struct acpi_device *device)
-{
- int result;
- struct acpi_bus_ops ops;
-
- ACPI_FUNCTION_TRACE("acpi_bus_start");
-
- if (!device)
- return_VALUE(-EINVAL);
-
- result = acpi_start_single_object(device);
- if (!result) {
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_start = 1;
- result = acpi_bus_scan(device, &ops);
- }
- return_VALUE(result);
-}
-EXPORT_SYMBOL(acpi_bus_start);
static int
acpi_bus_trim(struct acpi_device *start,
@@ -1394,19 +1331,13 @@ acpi_bus_scan_fixed (
/*
* Enumerate all fixed-feature devices.
*/
- if (acpi_fadt.pwr_button == 0) {
- result = acpi_add_single_object(&device, acpi_root,
+ if (acpi_fadt.pwr_button == 0)
+ result = acpi_bus_add(&device, acpi_root,
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
- if (!result)
- result = acpi_start_single_object(device);
- }
- if (acpi_fadt.sleep_button == 0) {
- result = acpi_add_single_object(&device, acpi_root,
+ if (acpi_fadt.sleep_button == 0)
+ result = acpi_bus_add(&device, acpi_root,
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
- if (!result)
- result = acpi_start_single_object(device);
- }
return_VALUE(result);
}
@@ -1415,7 +1346,6 @@ acpi_bus_scan_fixed (
static int __init acpi_scan_init(void)
{
int result;
- struct acpi_bus_ops ops;
ACPI_FUNCTION_TRACE("acpi_scan_init");
@@ -1427,23 +1357,17 @@ static int __init acpi_scan_init(void)
/*
* Create the root device in the bus's device tree
*/
- result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
+ result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT,
ACPI_BUS_TYPE_SYSTEM);
if (result)
goto Done;
- result = acpi_start_single_object(acpi_root);
-
/*
* Enumerate devices in the ACPI namespace.
*/
result = acpi_bus_scan_fixed(acpi_root);
- if (!result) {
- memset(&ops, 0, sizeof(ops));
- ops.acpi_op_add = 1;
- ops.acpi_op_start = 1;
- result = acpi_bus_scan(acpi_root, &ops);
- }
+ if (!result)
+ result = acpi_bus_scan(acpi_root);
if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c
index 652281402c92..97fe13f7f07c 100644
--- a/trunk/drivers/base/firmware_class.c
+++ b/trunk/drivers/base/firmware_class.c
@@ -74,8 +74,6 @@ static ssize_t
firmware_timeout_store(struct class *class, const char *buf, size_t count)
{
loading_timeout = simple_strtol(buf, NULL, 10);
- if (loading_timeout < 0)
- loading_timeout = 0;
return count;
}
@@ -140,10 +138,6 @@ firmware_loading_store(struct class_device *class_dev,
switch (loading) {
case 1:
down(&fw_lock);
- if (!fw_priv->fw) {
- up(&fw_lock);
- break;
- }
vfree(fw_priv->fw->data);
fw_priv->fw->data = NULL;
fw_priv->fw->size = 0;
@@ -184,7 +178,7 @@ firmware_data_read(struct kobject *kobj,
down(&fw_lock);
fw = fw_priv->fw;
- if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+ if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
ret_count = -ENODEV;
goto out;
}
@@ -244,10 +238,9 @@ firmware_data_write(struct kobject *kobj,
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
-
down(&fw_lock);
fw = fw_priv->fw;
- if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+ if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
retval = -ENODEV;
goto out;
}
@@ -425,7 +418,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
fw_priv = class_get_devdata(class_dev);
- if (loading_timeout > 0) {
+ if (loading_timeout) {
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
add_timer(&fw_priv->timeout);
}
diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c
index 3e9fb6e4a52a..653512b77570 100644
--- a/trunk/drivers/block/cciss.c
+++ b/trunk/drivers/block/cciss.c
@@ -786,6 +786,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETLUNINFO: {
LogvolInfo_struct luninfo;
+ int i;
luninfo.LunID = drv->LunID;
luninfo.num_opens = drv->usage_count;
diff --git a/trunk/drivers/block/ll_rw_blk.c b/trunk/drivers/block/ll_rw_blk.c
index 692a5fced76e..234fdcfbdf01 100644
--- a/trunk/drivers/block/ll_rw_blk.c
+++ b/trunk/drivers/block/ll_rw_blk.c
@@ -1867,20 +1867,19 @@ static void freed_request(request_queue_t *q, int rw)
#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
/*
- * Get a free request, queue_lock must be held.
- * Returns NULL on failure, with queue_lock held.
- * Returns !NULL on success, with queue_lock *not held*.
+ * Get a free request, queue_lock must not be held
*/
static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
int gfp_mask)
{
struct request *rq = NULL;
struct request_list *rl = &q->rq;
- struct io_context *ioc = current_io_context(GFP_ATOMIC);
+ struct io_context *ioc = get_io_context(gfp_mask);
if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
goto out;
+ spin_lock_irq(q->queue_lock);
if (rl->count[rw]+1 >= q->nr_requests) {
/*
* The queue will fill after this allocation, so set it as
@@ -1908,18 +1907,11 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
* The queue is full and the allocating process is not a
* "batcher", and not exempted by the IO scheduler
*/
+ spin_unlock_irq(q->queue_lock);
goto out;
}
get_rq:
- /*
- * Only allow batching queuers to allocate up to 50% over the defined
- * limit of requests, otherwise we could have thousands of requests
- * allocated with any setting of ->nr_requests
- */
- if (rl->count[rw] >= (3 * q->nr_requests / 2))
- goto out;
-
rl->count[rw]++;
rl->starved[rw] = 0;
if (rl->count[rw] >= queue_congestion_on_threshold(q))
@@ -1949,6 +1941,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
if (unlikely(rl->count[rw] == 0))
rl->starved[rw] = 1;
+ spin_unlock_irq(q->queue_lock);
goto out;
}
@@ -1958,23 +1951,21 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
rq_init(q, rq);
rq->rl = rl;
out:
+ put_io_context(ioc);
return rq;
}
/*
* No available requests for this queue, unplug the device and wait for some
* requests to become available.
- *
- * Called with q->queue_lock held, and returns with it unlocked.
*/
static struct request *get_request_wait(request_queue_t *q, int rw,
struct bio *bio)
{
+ DEFINE_WAIT(wait);
struct request *rq;
- rq = get_request(q, rw, bio, GFP_NOIO);
- while (!rq) {
- DEFINE_WAIT(wait);
+ do {
struct request_list *rl = &q->rq;
prepare_to_wait_exclusive(&rl->wait[rw], &wait,
@@ -1985,8 +1976,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
if (!rq) {
struct io_context *ioc;
- __generic_unplug_device(q);
- spin_unlock_irq(q->queue_lock);
+ generic_unplug_device(q);
io_schedule();
/*
@@ -1995,13 +1985,12 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
* up to a big batch of them for a small period time.
* See ioc_batching, ioc_set_batching
*/
- ioc = current_io_context(GFP_NOIO);
+ ioc = get_io_context(GFP_NOIO);
ioc_set_batching(q, ioc);
-
- spin_lock_irq(q->queue_lock);
+ put_io_context(ioc);
}
finish_wait(&rl->wait[rw], &wait);
- }
+ } while (!rq);
return rq;
}
@@ -2012,18 +2001,14 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
BUG_ON(rw != READ && rw != WRITE);
- spin_lock_irq(q->queue_lock);
- if (gfp_mask & __GFP_WAIT) {
+ if (gfp_mask & __GFP_WAIT)
rq = get_request_wait(q, rw, NULL);
- } else {
+ else
rq = get_request(q, rw, NULL, gfp_mask);
- if (!rq)
- spin_unlock_irq(q->queue_lock);
- }
- /* q->queue_lock is unlocked at this point */
return rq;
}
+
EXPORT_SYMBOL(blk_get_request);
/**
@@ -2527,7 +2512,7 @@ EXPORT_SYMBOL(blk_attempt_remerge);
static int __make_request(request_queue_t *q, struct bio *bio)
{
- struct request *req;
+ struct request *req, *freereq = NULL;
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
unsigned short prio;
sector_t sector;
@@ -2555,9 +2540,14 @@ static int __make_request(request_queue_t *q, struct bio *bio)
goto end_io;
}
+again:
spin_lock_irq(q->queue_lock);
- if (unlikely(barrier) || elv_queue_empty(q))
+ if (elv_queue_empty(q)) {
+ blk_plug_device(q);
+ goto get_rq;
+ }
+ if (barrier)
goto get_rq;
el_ret = elv_merge(q, &req, bio);
@@ -2602,24 +2592,40 @@ static int __make_request(request_queue_t *q, struct bio *bio)
elv_merged_request(q, req);
goto out;
- /* ELV_NO_MERGE: elevator says don't/can't merge. */
+ /*
+ * elevator says don't/can't merge. get new request
+ */
+ case ELEVATOR_NO_MERGE:
+ break;
+
default:
- ;
+ printk("elevator returned crap (%d)\n", el_ret);
+ BUG();
}
-get_rq:
- /*
- * Grab a free request. This is might sleep but can not fail.
- * Returns with the queue unlocked.
- */
- req = get_request_wait(q, rw, bio);
-
/*
- * After dropping the lock and possibly sleeping here, our request
- * may now be mergeable after it had proven unmergeable (above).
- * We don't worry about that case for efficiency. It won't happen
- * often, and the elevators are able to handle it.
+ * Grab a free request from the freelist - if that is empty, check
+ * if we are doing read ahead and abort instead of blocking for
+ * a free slot.
*/
+get_rq:
+ if (freereq) {
+ req = freereq;
+ freereq = NULL;
+ } else {
+ spin_unlock_irq(q->queue_lock);
+ if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) {
+ /*
+ * READA bit set
+ */
+ err = -EWOULDBLOCK;
+ if (bio_rw_ahead(bio))
+ goto end_io;
+
+ freereq = get_request_wait(q, rw, bio);
+ }
+ goto again;
+ }
req->flags |= REQ_CMD;
@@ -2648,11 +2654,10 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req->rq_disk = bio->bi_bdev->bd_disk;
req->start_time = jiffies;
- spin_lock_irq(q->queue_lock);
- if (elv_queue_empty(q))
- blk_plug_device(q);
add_request(q, req);
out:
+ if (freereq)
+ __blk_put_request(q, freereq);
if (sync)
__generic_unplug_device(q);
@@ -3279,20 +3284,24 @@ void exit_io_context(void)
/*
* If the current task has no IO context then create one and initialise it.
- * Otherwise, return its existing IO context.
+ * If it does have a context, take a ref on it.
*
- * This returned IO context doesn't have a specifically elevated refcount,
- * but since the current task itself holds a reference, the context can be
- * used in general code, so long as it stays within `current` context.
+ * This is always called in the context of the task which submitted the I/O.
+ * But weird things happen, so we disable local interrupts to ensure exclusive
+ * access to *current.
*/
-struct io_context *current_io_context(int gfp_flags)
+struct io_context *get_io_context(int gfp_flags)
{
struct task_struct *tsk = current;
+ unsigned long flags;
struct io_context *ret;
+ local_irq_save(flags);
ret = tsk->io_context;
- if (likely(ret))
- return ret;
+ if (ret)
+ goto out;
+
+ local_irq_restore(flags);
ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
if (ret) {
@@ -3303,25 +3312,25 @@ struct io_context *current_io_context(int gfp_flags)
ret->nr_batch_requests = 0; /* because this is 0 */
ret->aic = NULL;
ret->cic = NULL;
- tsk->io_context = ret;
- }
- return ret;
-}
-EXPORT_SYMBOL(current_io_context);
+ local_irq_save(flags);
-/*
- * If the current task has no IO context then create one and initialise it.
- * If it does have a context, take a ref on it.
- *
- * This is always called in the context of the task which submitted the I/O.
- */
-struct io_context *get_io_context(int gfp_flags)
-{
- struct io_context *ret;
- ret = current_io_context(gfp_flags);
- if (likely(ret))
+ /*
+ * very unlikely, someone raced with us in setting up the task
+ * io context. free new context and just grab a reference.
+ */
+ if (!tsk->io_context)
+ tsk->io_context = ret;
+ else {
+ kmem_cache_free(iocontext_cachep, ret);
+ ret = tsk->io_context;
+ }
+
+out:
atomic_inc(&ret->refcount);
+ local_irq_restore(flags);
+ }
+
return ret;
}
EXPORT_SYMBOL(get_io_context);
diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c
index 59f589d733f9..1407945a5892 100644
--- a/trunk/drivers/char/agp/amd64-agp.c
+++ b/trunk/drivers/char/agp/amd64-agp.c
@@ -686,15 +686,6 @@ static struct pci_device_id agp_amd64_pci_table[] = {
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
- /* SIS 760 */
- {
- .class = (PCI_CLASS_BRIDGE_HOST << 8),
- .class_mask = ~0,
- .vendor = PCI_VENDOR_ID_SI,
- .device = PCI_DEVICE_ID_SI_760,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- },
{ }
};
diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c
index e16c13fe698d..1813d0d198f1 100644
--- a/trunk/drivers/char/ipmi/ipmi_msghandler.c
+++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c
@@ -1088,8 +1088,8 @@ static inline int i_ipmi_request(ipmi_user_t user,
long seqid;
int broadcast = 0;
- if (addr->channel >= IPMI_MAX_CHANNELS) {
- spin_lock_irqsave(&intf->counter_lock, flags);
+ if (addr->channel > IPMI_NUM_CHANNELS) {
+ spin_lock_irqsave(&intf->counter_lock, flags);
intf->sent_invalid_commands++;
spin_unlock_irqrestore(&intf->counter_lock, flags);
rv = -EINVAL;
diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c
index 95f7046ff059..7c24fbe831f8 100644
--- a/trunk/drivers/char/moxa.c
+++ b/trunk/drivers/char/moxa.c
@@ -451,7 +451,7 @@ static int __init moxa_init(void)
int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
i = 0;
while (i < n) {
- while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
+ while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
{
if (pci_enable_device(p))
continue;
diff --git a/trunk/drivers/char/rio/rio_linux.c b/trunk/drivers/char/rio/rio_linux.c
index d7d484024e2b..7db3370f4972 100644
--- a/trunk/drivers/char/rio/rio_linux.c
+++ b/trunk/drivers/char/rio/rio_linux.c
@@ -1095,7 +1095,7 @@ static int __init rio_init(void)
#ifdef CONFIG_PCI
/* First look for the JET devices: */
- while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
+ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
pdev))) {
if (pci_enable_device(pdev)) continue;
@@ -1169,7 +1169,7 @@ static int __init rio_init(void)
*/
/* Then look for the older RIO/PCI devices: */
- while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
+ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_RIO,
pdev))) {
if (pci_enable_device(pdev)) continue;
diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c
index d8f9e94ae475..ff4f09804865 100644
--- a/trunk/drivers/char/rtc.c
+++ b/trunk/drivers/char/rtc.c
@@ -78,7 +78,6 @@
#include
#include
#include
-#include
#include
#include
@@ -895,6 +894,7 @@ static int __init rtc_init(void)
struct proc_dir_entry *ent;
#if defined(__alpha__) || defined(__mips__)
unsigned int year, ctrl;
+ unsigned long uip_watchdog;
char *guess = NULL;
#endif
#ifdef __sparc__
@@ -1000,8 +1000,12 @@ static int __init rtc_init(void)
/* Each operating system on an Alpha uses its own epoch.
Let's try to guess which one we are using now. */
+ uip_watchdog = jiffies;
if (rtc_is_updating() != 0)
- msleep(20);
+ while (jiffies - uip_watchdog < 2*HZ/100) {
+ barrier();
+ cpu_relax();
+ }
spin_lock_irq(&rtc_lock);
year = CMOS_READ(RTC_YEAR);
@@ -1209,6 +1213,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
void rtc_get_rtc_time(struct rtc_time *rtc_tm)
{
+ unsigned long uip_watchdog = jiffies;
unsigned char ctrl;
#ifdef CONFIG_MACH_DECSTATION
unsigned int real_year;
@@ -1216,7 +1221,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
/*
* read RTC once any update in progress is done. The update
- * can take just over 2ms. We wait 20ms. There is no need to
+ * can take just over 2ms. We wait 10 to 20ms. There is no need to
* to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
* If you need to know *exactly* when a second has started, enable
* periodic update complete interrupts, (via ioctl) and then
@@ -1225,7 +1230,10 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
*/
if (rtc_is_updating() != 0)
- msleep(20);
+ while (jiffies - uip_watchdog < 2*HZ/100) {
+ barrier();
+ cpu_relax();
+ }
/*
* Only the values that we read from the RTC are set. We leave
diff --git a/trunk/drivers/char/tipar.c b/trunk/drivers/char/tipar.c
index ec78d2f161f7..659335d80ee7 100644
--- a/trunk/drivers/char/tipar.c
+++ b/trunk/drivers/char/tipar.c
@@ -396,7 +396,7 @@ static struct file_operations tipar_fops = {
static int __init
tipar_setup(char *str)
{
- int ints[3];
+ int ints[2];
str = get_options(str, ARRAY_SIZE(ints), ints);
diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c
index 049d128ae7f0..854475c54f0e 100644
--- a/trunk/drivers/char/tpm/tpm.c
+++ b/trunk/drivers/char/tpm/tpm.c
@@ -464,7 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
pci_set_drvdata(pci_dev, NULL);
misc_deregister(&chip->vendor->miscdev);
- kfree(chip->vendor->miscdev.name);
+ kfree(&chip->vendor->miscdev.name);
sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c
index f19cf9d7792d..58597993954f 100644
--- a/trunk/drivers/char/tty_ioctl.c
+++ b/trunk/drivers/char/tty_ioctl.c
@@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
ld = tty_ldisc_ref(tty);
switch (arg) {
case TCIFLUSH:
- if (ld && ld->flush_buffer)
+ if (ld->flush_buffer)
ld->flush_buffer(tty);
break;
case TCIOFLUSH:
- if (ld && ld->flush_buffer)
+ if (ld->flush_buffer)
ld->flush_buffer(tty);
/* fall through */
case TCOFLUSH:
diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c
index 1d44f69e1fda..8971484b956b 100644
--- a/trunk/drivers/char/vt_ioctl.c
+++ b/trunk/drivers/char/vt_ioctl.c
@@ -25,7 +25,6 @@
#include
#include
#include
-#include
#include
#include
@@ -387,7 +386,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (!perm)
return -EPERM;
if (arg)
- arg = CLOCK_TICK_RATE / arg;
+ arg = 1193182 / arg;
kd_mksound(arg, 0);
return 0;
@@ -404,7 +403,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (arg & 0xffff) : 0;
if (count)
- count = CLOCK_TICK_RATE / count;
+ count = 1193182 / count;
kd_mksound(count, ticks);
return 0;
}
diff --git a/trunk/drivers/char/watchdog/ixp2000_wdt.c b/trunk/drivers/char/watchdog/ixp2000_wdt.c
index 4b039516cc86..4e98c215e5b1 100644
--- a/trunk/drivers/char/watchdog/ixp2000_wdt.c
+++ b/trunk/drivers/char/watchdog/ixp2000_wdt.c
@@ -162,7 +162,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
wdt_disable();
} else {
- printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
+ printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
"timer will not stop\n");
}
diff --git a/trunk/drivers/char/watchdog/ixp4xx_wdt.c b/trunk/drivers/char/watchdog/ixp4xx_wdt.c
index 83df369113a4..82396e06c8a8 100644
--- a/trunk/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/trunk/drivers/char/watchdog/ixp4xx_wdt.c
@@ -156,7 +156,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file)
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
wdt_disable();
} else {
- printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
+ printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
"timer will not stop\n");
}
diff --git a/trunk/drivers/firmware/pcdp.c b/trunk/drivers/firmware/pcdp.c
index 53c95c0bbf46..839b44a7e08b 100644
--- a/trunk/drivers/firmware/pcdp.c
+++ b/trunk/drivers/firmware/pcdp.c
@@ -16,7 +16,6 @@
#include
#include
#include
-#include
#include "pcdp.h"
static int __init
@@ -41,27 +40,10 @@ setup_serial_console(struct pcdp_uart *uart)
}
static int __init
-setup_vga_console(struct pcdp_device *dev)
+setup_vga_console(struct pcdp_vga *vga)
{
#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
- u8 *if_ptr;
-
- if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
- if (if_ptr[0] == PCDP_IF_PCI) {
- struct pcdp_if_pci if_pci;
-
- /* struct copy since ifptr might not be correctly aligned */
-
- memcpy(&if_pci, if_ptr, sizeof(if_pci));
-
- if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
- vga_console_iobase = if_pci.ioport_tra;
-
- if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
- vga_console_membase = if_pci.mmio_tra;
- }
-
- if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
+ if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) {
printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
return -ENODEV;
}
@@ -113,7 +95,7 @@ efi_setup_pcdp_console(char *cmdline)
dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
if (dev->flags & PCDP_PRIMARY_CONSOLE) {
if (dev->type == PCDP_CONSOLE_VGA) {
- return setup_vga_console(dev);
+ return setup_vga_console((struct pcdp_vga *) dev);
}
}
}
diff --git a/trunk/drivers/firmware/pcdp.h b/trunk/drivers/firmware/pcdp.h
index e72cc47de33b..1dc7c88b7b4d 100644
--- a/trunk/drivers/firmware/pcdp.h
+++ b/trunk/drivers/firmware/pcdp.h
@@ -52,34 +52,11 @@ struct pcdp_uart {
u32 clock_rate;
u8 pci_prog_intfc;
u8 flags;
-} __attribute__((packed));
-
-#define PCDP_IF_PCI 1
-
-/* pcdp_if_pci.trans */
-#define PCDP_PCI_TRANS_IOPORT 0x02
-#define PCDP_PCI_TRANS_MMIO 0x01
-
-struct pcdp_if_pci {
- u8 interconnect;
- u8 reserved;
- u16 length;
- u8 segment;
- u8 bus;
- u8 dev;
- u8 fun;
- u16 dev_id;
- u16 vendor_id;
- u32 acpi_interrupt;
- u64 mmio_tra;
- u64 ioport_tra;
- u8 flags;
- u8 trans;
-} __attribute__((packed));
+};
struct pcdp_vga {
u8 count; /* address space descriptors */
-} __attribute__((packed));
+};
/* pcdp_device.flags */
#define PCDP_PRIMARY_CONSOLE 1
@@ -89,9 +66,7 @@ struct pcdp_device {
u8 flags;
u16 length;
u16 efi_index;
- /* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */
- /* next data is device specific type (currently only pcdp_vga) */
-} __attribute__((packed));
+};
struct pcdp {
u8 signature[4];
@@ -106,4 +81,4 @@ struct pcdp {
u32 num_uarts;
struct pcdp_uart uart[0]; /* actual size is num_uarts */
/* remainder of table is pcdp_device structures */
-} __attribute__((packed));
+};
diff --git a/trunk/drivers/i2c/chips/atxp1.c b/trunk/drivers/i2c/chips/atxp1.c
index 0bcf82b4c07b..5c6597aa2c7f 100644
--- a/trunk/drivers/i2c/chips/atxp1.c
+++ b/trunk/drivers/i2c/chips/atxp1.c
@@ -144,7 +144,7 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att
if (vid == cvid)
return count;
- dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid);
+ dev_info(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid);
/* Write every 25 mV step to increase stability */
if (cvid > vid) {
diff --git a/trunk/drivers/ide/legacy/hd.c b/trunk/drivers/ide/legacy/hd.c
index 242029c9c0ca..e884cd4b22fd 100644
--- a/trunk/drivers/ide/legacy/hd.c
+++ b/trunk/drivers/ide/legacy/hd.c
@@ -156,13 +156,11 @@ else \
#if (HD_DELAY > 0)
-
-#include
-
unsigned long last_req;
unsigned long read_timer(void)
{
+ extern spinlock_t i8253_lock;
unsigned long t, flags;
int i;
diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c
index ab09cf4093e3..3e72c9b1461e 100644
--- a/trunk/drivers/input/gameport/gameport.c
+++ b/trunk/drivers/input/gameport/gameport.c
@@ -60,13 +60,12 @@ static void gameport_disconnect_port(struct gameport *gameport);
#if defined(__i386__)
-#include
-
#define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0))
#define GET_TIME(x) do { x = get_time_pit(); } while (0)
static unsigned int get_time_pit(void)
{
+ extern spinlock_t i8253_lock;
unsigned long flags;
unsigned int count;
diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c
index c3a5739030c3..504b7d550567 100644
--- a/trunk/drivers/input/joystick/analog.c
+++ b/trunk/drivers/input/joystick/analog.c
@@ -140,14 +140,12 @@ struct analog_port {
*/
#ifdef __i386__
-
-#include
-
#define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0)
#define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0)))
#define TIME_NAME (cpu_has_tsc?"TSC":"PIT")
static unsigned int get_time_pit(void)
{
+ extern spinlock_t i8253_lock;
unsigned long flags;
unsigned int count;
diff --git a/trunk/drivers/isdn/hardware/eicon/dadapter.c b/trunk/drivers/isdn/hardware/eicon/dadapter.c
index 89497890158d..6e548a222ef1 100644
--- a/trunk/drivers/isdn/hardware/eicon/dadapter.c
+++ b/trunk/drivers/isdn/hardware/eicon/dadapter.c
@@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\
Array to held adapter information
-------------------------------------------------------------------------- */
static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS];
-static dword Adapters = 0; /* Number of adapters */
+dword Adapters = 0; /* Number of adapters */
/* --------------------------------------------------------------------------
Shadow IDI_DIMAINT
and 'shadow' debug stuff
diff --git a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c
index 7333377ab31d..6e7e060716b7 100644
--- a/trunk/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/trunk/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a)
/* function to read critical counter registers that */
/* may be udpated by the chip during read */
/******************************************************/
-static u_char
+static volatile u_char
Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
{
u_char ref8;
@@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
return in8;
}
-static int
+static volatile int
Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
{
int ref16;
@@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
/******************************************/
/* disable memory mapped ports / io ports */
/******************************************/
-static void
+void
release_pci_ports(hfc4s8s_hw * hw)
{
pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
@@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw)
/*****************************************/
/* enable memory mapped ports / io ports */
/*****************************************/
-static void
+void
enable_pci_ports(hfc4s8s_hw * hw)
{
#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
diff --git a/trunk/drivers/isdn/hysdn/hycapi.c b/trunk/drivers/isdn/hysdn/hycapi.c
index 1fd3d4e5f284..8ee25b2ccce1 100644
--- a/trunk/drivers/isdn/hysdn/hycapi.c
+++ b/trunk/drivers/isdn/hysdn/hycapi.c
@@ -42,8 +42,6 @@ typedef struct _hycapi_appl {
static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
-static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
-
static inline int _hycapi_appCheck(int app_id, int ctrl_no)
{
if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
@@ -59,7 +57,7 @@ static inline int _hycapi_appCheck(int app_id, int ctrl_no)
Kernel-Capi callback reset_ctr
******************************/
-static void
+void
hycapi_reset_ctr(struct capi_ctr *ctrl)
{
hycapictrl_info *cinfo = ctrl->driverdata;
@@ -75,7 +73,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
Kernel-Capi callback remove_ctr
******************************/
-static void
+void
hycapi_remove_ctr(struct capi_ctr *ctrl)
{
int i;
@@ -217,7 +215,7 @@ Error-checking is done for CAPI-compliance.
The application is recorded in the internal list.
*************************************************************/
-static void
+void
hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
capi_register_params *rp)
{
@@ -293,7 +291,7 @@ Release the application from the internal list an remove it's
registration at controller-level
******************************************************************/
-static void
+void
hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
{
int chk;
@@ -366,7 +364,7 @@ firmware-releases that do not check the MsgLen-Indication!
***************************************************************/
-static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
+u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
{
__u16 appl_id;
int _len, _len2;
@@ -439,8 +437,8 @@ Informations provided in the /proc/capi-entries.
*********************************************************************/
-static int hycapi_read_proc(char *page, char **start, off_t off,
- int count, int *eof, struct capi_ctr *ctrl)
+int hycapi_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, struct capi_ctr *ctrl)
{
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
hysdn_card *card = cinfo->card;
@@ -487,7 +485,7 @@ on capi-interface registration.
**************************************************************/
-static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
+int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
{
#ifdef HYCAPI_PRINTFNAMES
printk(KERN_NOTICE "hycapi_load_firmware\n");
@@ -496,7 +494,7 @@ static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
}
-static char *hycapi_procinfo(struct capi_ctr *ctrl)
+char *hycapi_procinfo(struct capi_ctr *ctrl)
{
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
#ifdef HYCAPI_PRINTFNAMES
diff --git a/trunk/drivers/isdn/hysdn/hysdn_boot.c b/trunk/drivers/isdn/hysdn/hysdn_boot.c
index 7bfba196f315..6c04281e57b8 100644
--- a/trunk/drivers/isdn/hysdn/hysdn_boot.c
+++ b/trunk/drivers/isdn/hysdn/hysdn_boot.c
@@ -53,7 +53,7 @@ struct boot_data {
/* to be called at start of POF file reading, */
/* before starting any decryption on any POF record. */
/*****************************************************/
-static void
+void
StartDecryption(struct boot_data *boot)
{
boot->Cryptor = CRYPT_STARTTERM;
@@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot)
/* to HI and LO boot loader and (all) seq tags, because */
/* global Cryptor is started for whole POF. */
/***************************************************************/
-static void
+void
DecryptBuf(struct boot_data *boot, int cnt)
{
uchar *bufp = boot->buf.BootBuf;
diff --git a/trunk/drivers/isdn/hysdn/hysdn_defs.h b/trunk/drivers/isdn/hysdn/hysdn_defs.h
index 432f6f99089e..4cee26e558ee 100644
--- a/trunk/drivers/isdn/hysdn/hysdn_defs.h
+++ b/trunk/drivers/isdn/hysdn/hysdn_defs.h
@@ -227,6 +227,7 @@ typedef struct hycapictrl_info hycapictrl_info;
/*****************/
/* exported vars */
/*****************/
+extern int cardmax; /* number of found cards */
extern hysdn_card *card_root; /* pointer to first card */
@@ -243,6 +244,7 @@ extern void hysdn_procconf_release(void); /* deinit proc config filesys */
/* hysdn_proclog.c */
extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */
extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */
+extern void put_log_buffer(hysdn_card *, char *); /* output log data */
extern void hysdn_addlog(hysdn_card *, char *,...); /* output data to log */
extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */
@@ -276,6 +278,16 @@ extern unsigned int hycapi_enable;
extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */
extern int hycapi_capi_release(hysdn_card *); /* delete the device */
extern int hycapi_capi_stop(hysdn_card *card); /* suspend */
+extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *);
+extern void hycapi_reset_ctr(struct capi_ctr *);
+extern void hycapi_remove_ctr(struct capi_ctr *);
+extern void hycapi_register_appl(struct capi_ctr *, __u16 appl,
+ capi_register_params *);
+extern void hycapi_release_appl(struct capi_ctr *, __u16 appl);
+extern u16 hycapi_send_message(struct capi_ctr *, struct sk_buff *skb);
+extern char *hycapi_procinfo(struct capi_ctr *);
+extern int hycapi_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, struct capi_ctr *card);
extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len);
extern void hycapi_tx_capiack(hysdn_card * card);
extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
diff --git a/trunk/drivers/isdn/hysdn/hysdn_init.c b/trunk/drivers/isdn/hysdn/hysdn_init.c
index 12c8137b5161..5cac2bf5f4b0 100644
--- a/trunk/drivers/isdn/hysdn/hysdn_init.c
+++ b/trunk/drivers/isdn/hysdn/hysdn_init.c
@@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius");
MODULE_LICENSE("GPL");
static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
-static int cardmax; /* number of found cards */
+int cardmax; /* number of found cards */
hysdn_card *card_root = NULL; /* pointer to first card */
/**********************************************/
diff --git a/trunk/drivers/isdn/hysdn/hysdn_proclog.c b/trunk/drivers/isdn/hysdn/hysdn_proclog.c
index 4d57011c5737..8ef2b7c952a6 100644
--- a/trunk/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/trunk/drivers/isdn/hysdn/hysdn_proclog.c
@@ -22,8 +22,6 @@
/* the proc subdir for the interface is defined in the procconf module */
extern struct proc_dir_entry *hysdn_proc_entry;
-static void put_log_buffer(hysdn_card * card, char *cp);
-
/*************************************************/
/* structure keeping ascii log for device output */
/*************************************************/
@@ -95,7 +93,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...)
/* opened for read got the contents. */
/* Flushes buffers not longer in use. */
/********************************************/
-static void
+void
put_log_buffer(hysdn_card * card, char *cp)
{
struct log_data *ib;
diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c
index 4a0c57db2b67..3802f7a17f16 100644
--- a/trunk/drivers/md/md.c
+++ b/trunk/drivers/md/md.c
@@ -338,7 +338,6 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error)
if (atomic_dec_and_test(&rdev->mddev->pending_writes))
wake_up(&rdev->mddev->sb_wait);
- bio_put(bio);
return 0;
}
diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile
index 810e7aac0a53..2dc906fdfa55 100644
--- a/trunk/drivers/media/video/Makefile
+++ b/trunk/drivers/media/video/Makefile
@@ -7,7 +7,8 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
zr36067-objs := zoran_procfs.o zoran_device.o \
zoran_driver.o zoran_card.o
-tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
+tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o
+
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
diff --git a/trunk/drivers/media/video/bttv-driver.c b/trunk/drivers/media/video/bttv-driver.c
index 7d62b394c509..290289a99757 100644
--- a/trunk/drivers/media/video/bttv-driver.c
+++ b/trunk/drivers/media/video/bttv-driver.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $
+ $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $
bttv - Bt848 frame grabber driver
@@ -76,9 +76,6 @@ static unsigned int whitecrush_upper = 0xCF;
static unsigned int whitecrush_lower = 0x7F;
static unsigned int vcr_hack = 0;
static unsigned int irq_iswitch = 0;
-static unsigned int uv_ratio = 50;
-static unsigned int full_luma_range = 0;
-static unsigned int coring = 0;
/* API features (turn on/off stuff for testing) */
static unsigned int v4l2 = 1;
@@ -109,9 +106,6 @@ module_param(adc_crush, int, 0444);
module_param(whitecrush_upper, int, 0444);
module_param(whitecrush_lower, int, 0444);
module_param(vcr_hack, int, 0444);
-module_param(uv_ratio, int, 0444);
-module_param(full_luma_range, int, 0444);
-module_param(coring, int, 0444);
module_param_array(radio, int, NULL, 0444);
@@ -130,9 +124,6 @@ MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is
MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
-MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
-MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
-MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
@@ -493,10 +484,7 @@ static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
-#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8)
-#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9)
-#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10)
-#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11)
+#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8)
static const struct v4l2_queryctrl no_ctl = {
.name = "42",
@@ -630,32 +618,8 @@ static const struct v4l2_queryctrl bttv_ctls[] = {
.step = 1,
.default_value = 0x7F,
.type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_UV_RATIO,
- .name = "uv ratio",
- .minimum = 0,
- .maximum = 100,
- .step = 1,
- .default_value = 50,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
- .name = "full luma range",
- .minimum = 0,
- .maximum = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_PRIVATE_CORING,
- .name = "coring",
- .minimum = 0,
- .maximum = 3,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
}
-
-
};
static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
@@ -869,8 +833,8 @@ static void bt848_sat(struct bttv *btv, int color)
btv->saturation = color;
/* 0-511 for the color */
- val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
- val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
+ val_u = color >> 7;
+ val_v = ((color>>7)*180L)/254;
hibits = (val_u >> 7) & 2;
hibits |= (val_v >> 8) & 1;
btwrite(val_u & 0xff, BT848_SAT_U_LO);
@@ -1187,15 +1151,6 @@ static int get_control(struct bttv *btv, struct v4l2_control *c)
case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
c->value = btv->opt_whitecrush_lower;
break;
- case V4L2_CID_PRIVATE_UV_RATIO:
- c->value = btv->opt_uv_ratio;
- break;
- case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
- c->value = btv->opt_full_luma_range;
- break;
- case V4L2_CID_PRIVATE_CORING:
- c->value = btv->opt_coring;
- break;
default:
return -EINVAL;
}
@@ -1292,18 +1247,6 @@ static int set_control(struct bttv *btv, struct v4l2_control *c)
btv->opt_whitecrush_lower = c->value;
btwrite(c->value, BT848_WC_DOWN);
break;
- case V4L2_CID_PRIVATE_UV_RATIO:
- btv->opt_uv_ratio = c->value;
- bt848_sat(btv, btv->saturation);
- break;
- case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
- btv->opt_full_luma_range = c->value;
- btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
- break;
- case V4L2_CID_PRIVATE_CORING:
- btv->opt_coring = c->value;
- btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
- break;
default:
return -EINVAL;
}
@@ -3174,6 +3117,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
memset(v,0,sizeof(*v));
strcpy(v->name, "Radio");
+ /* japan: 76.0 MHz - 89.9 MHz
+ western europe: 87.5 MHz - 108.0 MHz
+ russia: 65.0 MHz - 108.0 MHz */
+ v->rangelow=(int)(65*16);
+ v->rangehigh=(int)(108*16);
bttv_call_i2c_clients(btv,cmd,v);
return 0;
}
@@ -3928,9 +3876,6 @@ static int __devinit bttv_probe(struct pci_dev *dev,
btv->opt_vcr_hack = vcr_hack;
btv->opt_whitecrush_upper = whitecrush_upper;
btv->opt_whitecrush_lower = whitecrush_lower;
- btv->opt_uv_ratio = uv_ratio;
- btv->opt_full_luma_range = full_luma_range;
- btv->opt_coring = coring;
/* fill struct bttv with some useful defaults */
btv->init.btv = btv;
diff --git a/trunk/drivers/media/video/bttvp.h b/trunk/drivers/media/video/bttvp.h
index f3293e4a15ad..7b6f1e856028 100644
--- a/trunk/drivers/media/video/bttvp.h
+++ b/trunk/drivers/media/video/bttvp.h
@@ -1,5 +1,5 @@
/*
- $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $
+ $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
bttv - Bt848 frame grabber driver
@@ -326,9 +326,6 @@ struct bttv {
int opt_vcr_hack;
int opt_whitecrush_upper;
int opt_whitecrush_lower;
- int opt_uv_ratio;
- int opt_full_luma_range;
- int opt_coring;
/* radio data/state */
int has_radio;
diff --git a/trunk/drivers/media/video/mt20xx.c b/trunk/drivers/media/video/mt20xx.c
index 9c005cb128d7..95ad17b7f38e 100644
--- a/trunk/drivers/media/video/mt20xx.c
+++ b/trunk/drivers/media/video/mt20xx.c
@@ -1,5 +1,5 @@
/*
- * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
+ * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
*
* i2c tv tuner chip device driver
* controls microtune tuners, mt2032 + mt2050 at the moment.
@@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
int if2 = t->radio_if2;
// per Manual for FM tuning: first if center freq. 1085 MHz
- mt2032_set_if_freq(c, freq * 1000 / 16,
- 1085*1000*1000,if2,if2,if2);
+ mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
+ 1085*1000*1000,if2,if2,if2);
}
// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
diff --git a/trunk/drivers/media/video/tda8290.c b/trunk/drivers/media/video/tda8290.c
index f59d4601cc63..b27cc348d95c 100644
--- a/trunk/drivers/media/video/tda8290.c
+++ b/trunk/drivers/media/video/tda8290.c
@@ -1,5 +1,5 @@
/*
- * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $
+ * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
*
* i2c tv tuner chip device driver
* controls the philips tda8290+75 tuner chip combo.
@@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_entry* table, __u16 freq)
static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 };
static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 };
static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00,
- 0xfC, 0x04, 0xA3, 0x3F,
+ 0x7C, 0x04, 0xA3, 0x3F,
0x2A, 0x04, 0xFF, 0x00,
0x00, 0x40 };
static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
@@ -138,24 +138,16 @@ static int tda8290_tune(struct i2c_client *c)
static void set_frequency(struct tuner *t, u16 ifc)
{
- u32 freq;
- u32 N;
+ u32 N = (((t->freq<<3)+ifc)&0x3fffc);
- if (t->mode == V4L2_TUNER_RADIO)
- freq = t->freq / 1000;
- else
- freq = t->freq;
-
- N = (((freq<<3)+ifc)&0x3fffc);
-
- N = N >> get_freq_entry(div_table, freq);
+ N = N >> get_freq_entry(div_table, t->freq);
t->i2c_set_freq[0] = 0;
t->i2c_set_freq[1] = (unsigned char)(N>>8);
t->i2c_set_freq[2] = (unsigned char) N;
t->i2c_set_freq[3] = 0x40;
t->i2c_set_freq[4] = 0x52;
- t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
- t->i2c_set_freq[6] = get_freq_entry(agc_table, freq);
+ t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
+ t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq);
t->i2c_set_freq[7] = 0x8f;
}
diff --git a/trunk/drivers/media/video/tda9887.c b/trunk/drivers/media/video/tda9887.c
index ee35562f4d1a..39773633cc3c 100644
--- a/trunk/drivers/media/video/tda9887.c
+++ b/trunk/drivers/media/video/tda9887.c
@@ -368,7 +368,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
if (t->radio_mode == V4L2_TUNER_MODE_MONO)
norm = &radio_mono;
else
- norm = &radio_stereo;
+ norm = &radio_stereo;
} else {
for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
if (tvnorms[i].std & t->std) {
@@ -566,6 +566,7 @@ static int tda9887_configure(struct tda9887 *t)
if (UNSET != t->pinnacle_id) {
tda9887_set_pinnacle(t,buf);
}
+
tda9887_set_config(t,buf);
tda9887_set_insmod(t,buf);
@@ -614,8 +615,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
t->pinnacle_id = UNSET;
t->radio_mode = V4L2_TUNER_MODE_STEREO;
- i2c_set_clientdata(&t->client, t);
- i2c_attach_client(&t->client);
+ i2c_set_clientdata(&t->client, t);
+ i2c_attach_client(&t->client);
return 0;
}
diff --git a/trunk/drivers/media/video/tea5767.c b/trunk/drivers/media/video/tea5767.c
deleted file mode 100644
index a29f08f81f63..000000000000
--- a/trunk/drivers/media/video/tea5767.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
- * I2C address is allways 0xC0.
- *
- * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $
- *
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
- * This code is placed under the terms of the GNU General Public License
- *
- * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
- * from their contributions on DScaler.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-/* Declared at tuner-core.c */
-extern unsigned int tuner_debug;
-
-#define PREFIX "TEA5767 "
-
-/*****************************************************************************/
-
-/******************************
- * Write mode register values *
- ******************************/
-
-/* First register */
-#define TEA5767_MUTE 0x80 /* Mutes output */
-#define TEA5767_SEARCH 0x40 /* Activates station search */
-/* Bits 0-5 for divider MSB */
-
-/* Second register */
-/* Bits 0-7 for divider LSB */
-
-/* Third register */
-
-/* Station search from botton to up */
-#define TEA5767_SEARCH_UP 0x80
-
-/* Searches with ADC output = 10 */
-#define TEA5767_SRCH_HIGH_LVL 0x60
-
-/* Searches with ADC output = 10 */
-#define TEA5767_SRCH_MID_LVL 0x40
-
-/* Searches with ADC output = 5 */
-#define TEA5767_SRCH_LOW_LVL 0x20
-
-/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
-#define TEA5767_HIGH_LO_INJECT 0x10
-
-/* Disable stereo */
-#define TEA5767_MONO 0x08
-
-/* Disable right channel and turns to mono */
-#define TEA5767_MUTE_RIGHT 0x04
-
-/* Disable left channel and turns to mono */
-#define TEA5767_MUTE_LEFT 0x02
-
-#define TEA5767_PORT1_HIGH 0x01
-
-/* Forth register */
-#define TEA5767_PORT2_HIGH 0x80
-/* Chips stops working. Only I2C bus remains on */
-#define TEA5767_STDBY 0x40
-
-/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
-#define TEA5767_JAPAN_BAND 0x20
-
-/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
-#define TEA5767_XTAL_32768 0x10
-
-/* Cuts weak signals */
-#define TEA5767_SOFT_MUTE 0x08
-
-/* Activates high cut control */
-#define TEA5767_HIGH_CUT_CTRL 0x04
-
-/* Activates stereo noise control */
-#define TEA5767_ST_NOISE_CTL 0x02
-
-/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
-#define TEA5767_SRCH_IND 0x01
-
-/* Fiveth register */
-
-/* By activating, it will use Xtal at 13 MHz as reference for divider */
-#define TEA5767_PLLREF_ENABLE 0x80
-
-/* By activating, deemphasis=50, or else, deemphasis of 50us */
-#define TEA5767_DEEMPH_75 0X40
-
-/*****************************
- * Read mode register values *
- *****************************/
-
-/* First register */
-#define TEA5767_READY_FLAG_MASK 0x80
-#define TEA5767_BAND_LIMIT_MASK 0X40
-/* Bits 0-5 for divider MSB after search or preset */
-
-/* Second register */
-/* Bits 0-7 for divider LSB after search or preset */
-
-/* Third register */
-#define TEA5767_STEREO_MASK 0x80
-#define TEA5767_IF_CNTR_MASK 0x7f
-
-/* Four register */
-#define TEA5767_ADC_LEVEL_MASK 0xf0
-
-/* should be 0 */
-#define TEA5767_CHIP_ID_MASK 0x0f
-
-/* Fiveth register */
-/* Reserved for future extensions */
-#define TEA5767_RESERVED_MASK 0xff
-
-/*****************************************************************************/
-
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
-{
- struct tuner *t = i2c_get_clientdata(c);
-
- tuner_warn("This tuner doesn't support TV freq.\n");
-}
-
-static void tea5767_status_dump(unsigned char *buffer)
-{
- unsigned int div, frq;
-
- if (TEA5767_READY_FLAG_MASK & buffer[0])
- printk(PREFIX "Ready Flag ON\n");
- else
- printk(PREFIX "Ready Flag OFF\n");
-
- if (TEA5767_BAND_LIMIT_MASK & buffer[0])
- printk(PREFIX "Tuner at band limit\n");
- else
- printk(PREFIX "Tuner not at band limit\n");
-
- div=((buffer[0]&0x3f)<<8) | buffer[1];
-
- switch (TEA5767_HIGH_LO_32768) {
- case TEA5767_HIGH_LO_13MHz:
- frq = 1000*(div*50-700-225)/4; /* Freq in KHz */
- break;
- case TEA5767_LOW_LO_13MHz:
- frq = 1000*(div*50+700+225)/4; /* Freq in KHz */
- break;
- case TEA5767_LOW_LO_32768:
- frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */
- break;
- case TEA5767_HIGH_LO_32768:
- default:
- frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */
- break;
- }
- buffer[0] = (div>>8) & 0x3f;
- buffer[1] = div & 0xff;
-
- printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
- frq/1000,frq%1000,div);
-
- if (TEA5767_STEREO_MASK & buffer[2])
- printk(PREFIX "Stereo\n");
- else
- printk(PREFIX "Mono\n");
-
- printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK);
-
- printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4);
-
- printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK));
-
- printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK));
-}
-
-/* Freq should be specifyed at 62.5 Hz */
-static void set_radio_freq(struct i2c_client *c, unsigned int frq)
-{
- struct tuner *t = i2c_get_clientdata(c);
- unsigned char buffer[5];
- unsigned div;
- int rc;
-
- if ( tuner_debug )
- printk(PREFIX "radio freq counter %d\n",frq);
-
- /* Rounds freq to next decimal value - for 62.5 KHz step */
- /* frq = 20*(frq/16)+radio_frq[frq%16]; */
-
- buffer[2] = TEA5767_PORT1_HIGH;
- buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
- buffer[4]=0;
-
- if (t->audmode == V4L2_TUNER_MODE_MONO) {
- tuner_dbg("TEA5767 set to mono\n");
- buffer[2] |= TEA5767_MONO;
- } else
- tuner_dbg("TEA5767 set to stereo\n");
-
- switch (t->type) {
- case TEA5767_HIGH_LO_13MHz:
- tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
- buffer[2] |= TEA5767_HIGH_LO_INJECT;
- buffer[4] |= TEA5767_PLLREF_ENABLE;
- div = (frq*4/16+700+225+25)/50;
- break;
- case TEA5767_LOW_LO_13MHz:
- tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
-
- buffer[4] |= TEA5767_PLLREF_ENABLE;
- div = (frq*4/16-700-225+25)/50;
- break;
- case TEA5767_LOW_LO_32768:
- tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
- buffer[3] |= TEA5767_XTAL_32768;
- /* const 700=4000*175 Khz - to adjust freq to right value */
- div = (1000*(frq*4/16-700-225)+16384)>>15;
- break;
- case TEA5767_HIGH_LO_32768:
- default:
- tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
-
- buffer[2] |= TEA5767_HIGH_LO_INJECT;
- buffer[3] |= TEA5767_XTAL_32768;
- div = (1000*(frq*4/16+700+225)+16384)>>15;
- break;
- }
- buffer[0] = (div>>8) & 0x3f;
- buffer[1] = div & 0xff;
-
- if ( tuner_debug )
- tea5767_status_dump(buffer);
-
- if (5 != (rc = i2c_master_send(c,buffer,5)))
- tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc);
-}
-
-static int tea5767_signal(struct i2c_client *c)
-{
- unsigned char buffer[5];
- int rc;
- struct tuner *t = i2c_get_clientdata(c);
-
- memset(buffer,0,sizeof(buffer));
- if (5 != (rc = i2c_master_recv(c,buffer,5)))
- tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
-
- return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4));
-}
-
-static int tea5767_stereo(struct i2c_client *c)
-{
- unsigned char buffer[5];
- int rc;
- struct tuner *t = i2c_get_clientdata(c);
-
- memset(buffer,0,sizeof(buffer));
- if (5 != (rc = i2c_master_recv(c,buffer,5)))
- tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
-
- rc = buffer[2] & TEA5767_STEREO_MASK;
-
- if ( tuner_debug )
- tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
-
- return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0);
-}
-
-int tea_detection(struct i2c_client *c)
-{
- unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff };
- int rc;
- struct tuner *t = i2c_get_clientdata(c);
-
- if (5 != (rc = i2c_master_recv(c,buffer,5))) {
- tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc );
- return EINVAL;
- }
-
- /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */
- if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
- buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
- tuner_warn ( "All bytes are equal. It is not a TEA5767\n" );
- return EINVAL;
- }
-
- /* Status bytes:
- * Byte 4: bit 3:1 : CI (Chip Identification) == 0
- * bit 0 : internally set to 0
- * Byte 5: bit 7:0 : == 0
- */
-
- if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
- tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" );
- return EINVAL;
- }
- tuner_warn ( "TEA5767 detected.\n" );
- return 0;
-}
-
-int tea5767_tuner_init(struct i2c_client *c)
-{
- struct tuner *t = i2c_get_clientdata(c);
-
- if (tea_detection(c)==EINVAL) return EINVAL;
-
- tuner_info("type set to %d (%s)\n",
- t->type, TEA5767_TUNER_NAME);
- strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name));
-
- t->tv_freq = set_tv_freq;
- t->radio_freq = set_radio_freq;
- t->has_signal = tea5767_signal;
- t->is_stereo = tea5767_stereo;
-
- return (0);
-}
diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c
index 6f6bf4a633fc..eaabfc858703 100644
--- a/trunk/drivers/media/video/tuner-core.c
+++ b/trunk/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $
+ * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $
*
* i2c tv tuner chip device driver
* core core, i.e. kernel interfaces, registering and so on
@@ -26,6 +26,7 @@
/*
* comment line bellow to return to old behavor, where only one I2C device is supported
*/
+#define CONFIG_TUNER_MULTI_I2C /**/
#define UNSET (-1U)
@@ -57,7 +58,9 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
MODULE_LICENSE("GPL");
static int this_adap;
+#ifdef CONFIG_TUNER_MULTI_I2C
static unsigned short first_tuner, tv_tuner, radio_tuner;
+#endif
static struct i2c_driver driver;
static struct i2c_client client_template;
@@ -78,9 +81,26 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
return;
}
if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
+
+ if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
+ /* V4L2_TUNER_CAP_LOW frequency */
+
+ tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n");
+
+ t->tv_freq(c,freq>>10);
+
+ return;
+ } else {
+ /* FIXME: better do that chip-specific, but
+ right now we don't have that in the config
+ struct and this way is still better than no
+ check at all */
tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
+ return;
+ }
}
+ tuner_dbg("62.5 Khz freq step selected for TV.\n");
t->tv_freq(c,freq);
}
@@ -96,18 +116,31 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
tuner_info("no radio tuning for this one, sorry.\n");
return;
}
- if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) {
- if (tuner_debug)
- tuner_info("radio freq step 62.5Hz (%d.%06d)\n",
- freq/16000,freq%16000*1000/16);
- t->radio_freq(c,freq);
- } else {
- tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
- freq/16,freq%16*100/16,
- radio_range[0],radio_range[1]);
- }
+ if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
+ if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
+ /* V4L2_TUNER_CAP_LOW frequency */
+ if (t->type == TUNER_TEA5767) {
+ tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
+ t->radio_freq(c,freq>>10);
+ return;
+ }
+
+ tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n");
- return;
+ tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
+
+ t->radio_freq(c,freq>>10);
+ return;
+
+ } else {
+ tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
+ freq/16,freq%16*100/16,
+ radio_range[0],radio_range[1]);
+ return;
+ }
+ }
+ tuner_dbg("62.5 Khz freq step selected for Radio.\n");
+ t->radio_freq(c,freq);
}
static void set_freq(struct i2c_client *c, unsigned long freq)
@@ -133,8 +166,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
static void set_type(struct i2c_client *c, unsigned int type)
{
struct tuner *t = i2c_get_clientdata(c);
- unsigned char buffer[4];
+ tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
/* sanity check */
if (type == UNSET || type == TUNER_ABSENT)
return;
@@ -146,8 +179,8 @@ static void set_type(struct i2c_client *c, unsigned int type)
t->type = type;
return;
}
- if ((t->initialized) && (t->type == type))
- /* run only once except type change Hac 04/05*/
+ if (t->initialized)
+ /* run only once */
return;
t->initialized = 1;
@@ -160,42 +193,25 @@ static void set_type(struct i2c_client *c, unsigned int type)
case TUNER_PHILIPS_TDA8290:
tda8290_init(c);
break;
- case TUNER_TEA5767:
- if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT;
- break;
- case TUNER_PHILIPS_FMD1216ME_MK3:
- buffer[0] = 0x0b;
- buffer[1] = 0xdc;
- buffer[2] = 0x9c;
- buffer[3] = 0x60;
- i2c_master_send(c,buffer,4);
- mdelay(1);
- buffer[2] = 0x86;
- buffer[3] = 0x54;
- i2c_master_send(c,buffer,4);
- default_tuner_init(c);
- break;
default:
- /* TEA5767 autodetection code */
- if (tea5767_tuner_init(c)!=EINVAL) {
- t->type = TUNER_TEA5767;
- if (first_tuner == 0x60)
- first_tuner++;
- break;
- }
-
default_tuner_init(c);
break;
}
- tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
}
+#ifdef CONFIG_TUNER_MULTI_I2C
#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \
- return 0; } else if (tuner_debug) \
+ return 0; } else \
tuner_info ("Cmd %s accepted to "tun"\n",cmd);
#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
CHECK_ADDR(radio_tuner,cmd,"radio") } else \
{ CHECK_ADDR(tv_tuner,cmd,"TV"); }
+#else
+#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd);
+#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd);
+#endif
+
+#ifdef CONFIG_TUNER_MULTI_I2C
static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
{
@@ -226,6 +242,9 @@ static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
}
set_type(c,tun_addr->type);
}
+#else
+#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
+#endif
static char pal[] = "-";
module_param_string(pal, pal, sizeof(pal), 0644);
@@ -265,12 +284,17 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct tuner *t;
+#ifndef CONFIG_TUNER_MULTI_I2C
+ if (this_adap > 0)
+ return -1;
+#else
/* by default, first I2C card is both tv and radio tuner */
if (this_adap == 0) {
first_tuner = addr;
tv_tuner = addr;
radio_tuner = addr;
}
+#endif
this_adap++;
client_template.adapter = adap;
@@ -284,7 +308,6 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
i2c_set_clientdata(&t->i2c, t);
t->type = UNSET;
t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
- t->audmode = V4L2_TUNER_MODE_STEREO;
i2c_attach_client(&t->i2c);
tuner_info("chip found @ 0x%x (%s)\n",
@@ -302,9 +325,11 @@ static int tuner_probe(struct i2c_adapter *adap)
}
this_adap = 0;
+#ifdef CONFIG_TUNER_MULTI_I2C
first_tuner = 0;
tv_tuner = 0;
radio_tuner = 0;
+#endif
if (adap->class & I2C_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, tuner_attach);
@@ -367,7 +392,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
t->radio_if2 = 41300 * 1000;
break;
}
- break;
+ break;
+
/* --- v4l ioctls --- */
/* take care: bttv does userspace copying, we'll get a
kernel pointer here... */
@@ -414,18 +440,11 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
vt->signal = t->has_signal(client);
if (t->is_stereo) {
if (t->is_stereo(client))
- vt->flags |= VIDEO_TUNER_STEREO_ON;
+ vt-> flags |= VIDEO_TUNER_STEREO_ON;
else
- vt->flags &= ~VIDEO_TUNER_STEREO_ON;
+ vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON;
}
vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */
-
- vt->rangelow = radio_range[0] * 16000;
- vt->rangehigh = radio_range[1] * 16000;
-
- } else {
- vt->rangelow = tv_range[0] * 16;
- vt->rangehigh = tv_range[1] * 16;
}
return 0;
@@ -491,46 +510,20 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
tuner -> signal = t->has_signal(client);
if (t->is_stereo) {
if (t->is_stereo(client)) {
- tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+ tuner -> capability |= V4L2_TUNER_CAP_STEREO;
+ tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
} else {
- tuner -> rxsubchans = V4L2_TUNER_SUB_MONO;
+ tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO;
}
}
- tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- tuner->audmode = t->audmode;
-
- tuner->rangelow = radio_range[0] * 16000;
- tuner->rangehigh = radio_range[1] * 16000;
- } else {
- tuner->rangelow = tv_range[0] * 16;
- tuner->rangehigh = tv_range[1] * 16;
}
+ /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */
+ tuner->rangelow = tv_range[0] * 16;
+// tuner->rangehigh = tv_range[1] * 16;
+// tuner->rangelow = tv_range[0] * 16384;
+ tuner->rangehigh = tv_range[1] * 16384;
break;
}
- case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */
- {
- struct v4l2_tuner *tuner = arg;
-
- CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio");
- SWITCH_V4L2;
-
- /* To switch the audio mode, applications initialize the
- index and audmode fields and the reserved array and
- call the VIDIOC_S_TUNER ioctl. */
- /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO,
- V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2,
- V4L2_TUNER_MODE_SAP */
-
- if (tuner->audmode == V4L2_TUNER_MODE_MONO)
- t->audmode = V4L2_TUNER_MODE_MONO;
- else
- t->audmode = V4L2_TUNER_MODE_STEREO;
-
- set_radio_freq(client, t->freq);
- break;
- }
- case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */
- break;
default:
tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
/* nothing */
diff --git a/trunk/drivers/media/video/tuner-simple.c b/trunk/drivers/media/video/tuner-simple.c
index c39ed6226ee0..539f30557317 100644
--- a/trunk/drivers/media/video/tuner-simple.c
+++ b/trunk/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
/*
- * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $
+ * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $
*
* i2c tv tuner chip device driver
* controls all those simple 4-control-bytes style tuners.
@@ -207,27 +207,28 @@ static struct tunertype tuners[] = {
{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
- { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
- 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
- { "Philips FQ1236A MK4", Philips, NTSC,
- 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+ { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
+ 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
+ { "Philips FQ1236A MK4", Philips, NTSC,
+ 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
/* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
{ "Ymec TVision TVF-8531MF", Philips, NTSC,
16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
+
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
- /* Should work for TNF9533-D/IF, TNF9533-B/DF */
- { "Tena TNF9533-D/IF", Philips, PAL,
- 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
+ { "Tena TNF9533-D/IF", LGINNOTEK, PAL,
+ 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
- /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */
+ /*
+ * This entry is for TEA5767 FM radio only chip used on several boards
+ * w/TV tuner
+ */
{ TEA5767_TUNER_NAME, Philips, RADIO,
- -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
- { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
- 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
+ -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
};
unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -454,24 +455,24 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
int rc;
tun=&tuners[t->type];
- div = (freq / 1000) + (int)(16*10.7);
+ div = freq + (int)(16*10.7);
buffer[2] = tun->config;
switch (t->type) {
case TUNER_TENA_9533_DI:
case TUNER_YMEC_TVF_5533MF:
+
/*These values are empirically determinated */
- div = (freq * 122) / 16000 - 20;
+ div = (freq*122)/16 - 20;
buffer[2] = 0x88; /* could be also 0x80 */
buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
break;
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
- case TUNER_PHILIPS_FMD1216ME_MK3:
buffer[3] = 0x19;
break;
case TUNER_PHILIPS_FM1256_IH3:
- div = (20 * freq) / 16000 + 333 * 2;
+ div = (20 * freq)/16 + 333 * 2;
buffer[2] = 0x80;
buffer[3] = 0x19;
break;
@@ -504,7 +505,6 @@ int default_tuner_init(struct i2c_client *c)
t->radio_freq = default_set_radio_freq;
t->has_signal = tuner_signal;
t->is_stereo = tuner_stereo;
-
return 0;
}
diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c
index 353deb25e397..d8d65397e06e 100644
--- a/trunk/drivers/message/fusion/mptfc.c
+++ b/trunk/drivers/message/fusion/mptfc.c
@@ -364,7 +364,9 @@ static struct pci_driver mptfc_driver = {
.id_table = mptfc_pci_table,
.probe = mptfc_probe,
.remove = __devexit_p(mptscsih_remove),
- .shutdown = mptscsih_shutdown,
+ .driver = {
+ .shutdown = mptscsih_shutdown,
+ },
#ifdef CONFIG_PM
.suspend = mptscsih_suspend,
.resume = mptscsih_resume,
diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c
index 4f973a49be4c..a0078ae5b9b8 100644
--- a/trunk/drivers/message/fusion/mptscsih.c
+++ b/trunk/drivers/message/fusion/mptscsih.c
@@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
#endif
void mptscsih_remove(struct pci_dev *);
-void mptscsih_shutdown(struct pci_dev *);
+void mptscsih_shutdown(struct device *);
#ifdef CONFIG_PM
int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
int mptscsih_resume(struct pci_dev *pdev);
@@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev)
#endif
#endif
- mptscsih_shutdown(pdev);
+ mptscsih_shutdown(&pdev->dev);
sz1=0;
@@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev)
*
*/
void
-mptscsih_shutdown(struct pci_dev *pdev)
+mptscsih_shutdown(struct device * dev)
{
- MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
+ MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
struct Scsi_Host *host = ioc->sh;
MPT_SCSI_HOST *hd;
@@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct pci_dev *pdev)
int
mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
{
- mptscsih_shutdown(pdev);
+ mptscsih_shutdown(&pdev->dev);
return mpt_suspend(pdev,state);
}
diff --git a/trunk/drivers/message/fusion/mptscsih.h b/trunk/drivers/message/fusion/mptscsih.h
index 5ea89bf0df19..d73aec33e16a 100644
--- a/trunk/drivers/message/fusion/mptscsih.h
+++ b/trunk/drivers/message/fusion/mptscsih.h
@@ -82,7 +82,7 @@
#endif
extern void mptscsih_remove(struct pci_dev *);
-extern void mptscsih_shutdown(struct pci_dev *);
+extern void mptscsih_shutdown(struct device *);
#ifdef CONFIG_PM
extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
extern int mptscsih_resume(struct pci_dev *pdev);
diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c
index e0c0ee5bc966..5f9a61b85b3b 100644
--- a/trunk/drivers/message/fusion/mptspi.c
+++ b/trunk/drivers/message/fusion/mptspi.c
@@ -419,7 +419,9 @@ static struct pci_driver mptspi_driver = {
.id_table = mptspi_pci_table,
.probe = mptspi_probe,
.remove = __devexit_p(mptscsih_remove),
- .shutdown = mptscsih_shutdown,
+ .driver = {
+ .shutdown = mptscsih_shutdown,
+ },
#ifdef CONFIG_PM
.suspend = mptscsih_suspend,
.resume = mptscsih_resume,
diff --git a/trunk/drivers/net/3c515.c b/trunk/drivers/net/3c515.c
index 91d1c4c24d9b..d272ea36a578 100644
--- a/trunk/drivers/net/3c515.c
+++ b/trunk/drivers/net/3c515.c
@@ -822,7 +822,7 @@ static int corkscrew_open(struct net_device *dev)
break; /* Bad news! */
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
+ vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
}
vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */
outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
@@ -1406,7 +1406,7 @@ static int boomerang_rx(struct net_device *dev)
break; /* Bad news! */
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
+ vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
vp->rx_skbuff[entry] = skb;
}
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c
index 07746b95fd83..80ec9aa575bb 100644
--- a/trunk/drivers/net/3c59x.c
+++ b/trunk/drivers/net/3c59x.c
@@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev)
break; /* Bad news! */
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+ vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
}
if (i != RX_RING_SIZE) {
int j;
@@ -2632,7 +2632,7 @@ boomerang_rx(struct net_device *dev)
pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
/* 'skb_put()' points to the start of sk_buff data area. */
memcpy(skb_put(skb, pkt_len),
- vp->rx_skbuff[entry]->data,
+ vp->rx_skbuff[entry]->tail,
pkt_len);
pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
vp->rx_copy++;
@@ -2678,7 +2678,7 @@ boomerang_rx(struct net_device *dev)
}
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+ vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
vp->rx_skbuff[entry] = skb;
}
vp->rx_ring[entry].status = 0; /* Clear complete bit. */
diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c
index 7b293f01c9ed..e4b3c5c88542 100644
--- a/trunk/drivers/net/8139cp.c
+++ b/trunk/drivers/net/8139cp.c
@@ -596,7 +596,7 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
mapping =
cp->rx_skb[rx_tail].mapping =
- pci_map_single(cp->pdev, new_skb->data,
+ pci_map_single(cp->pdev, new_skb->tail,
buflen, PCI_DMA_FROMDEVICE);
cp->rx_skb[rx_tail].skb = new_skb;
@@ -1101,7 +1101,7 @@ static int cp_refill_rx (struct cp_private *cp)
skb_reserve(skb, RX_OFFSET);
cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
- skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
cp->rx_skb[i].skb = skb;
cp->rx_ring[i].opts2 = 0;
diff --git a/trunk/drivers/net/82596.c b/trunk/drivers/net/82596.c
index 13b745b39667..65f97b1dc581 100644
--- a/trunk/drivers/net/82596.c
+++ b/trunk/drivers/net/82596.c
@@ -546,11 +546,11 @@ static inline void init_rx_bufs(struct net_device *dev)
rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1));
rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
rbd->skb = skb;
- rbd->v_data = skb->data;
- rbd->b_data = WSWAPchar(virt_to_bus(skb->data));
+ rbd->v_data = skb->tail;
+ rbd->b_data = WSWAPchar(virt_to_bus(skb->tail));
rbd->size = PKT_BUF_SZ;
#ifdef __mc68000__
- cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ);
+ cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ);
#endif
}
lp->rbd_head = lp->rbds;
@@ -816,10 +816,10 @@ static inline int i596_rx(struct net_device *dev)
rx_in_place = 1;
rbd->skb = newskb;
newskb->dev = dev;
- rbd->v_data = newskb->data;
- rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
+ rbd->v_data = newskb->tail;
+ rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail));
#ifdef __mc68000__
- cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
+ cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ);
#endif
}
else
@@ -840,7 +840,7 @@ static inline int i596_rx(struct net_device *dev)
skb->protocol=eth_type_trans(skb,dev);
skb->len = pkt_len;
#ifdef __mc68000__
- cache_clear(virt_to_phys(rbd->skb->data),
+ cache_clear(virt_to_phys(rbd->skb->tail),
pkt_len);
#endif
netif_rx(skb);
diff --git a/trunk/drivers/net/amd8111e.c b/trunk/drivers/net/amd8111e.c
index 8618012df06a..b7dd7260cafb 100755
--- a/trunk/drivers/net/amd8111e.c
+++ b/trunk/drivers/net/amd8111e.c
@@ -87,7 +87,6 @@ Revision History:
#include
#include
#include
-#include
#include
#include
@@ -2007,11 +2006,12 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
}
/* Initialize DMA */
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
+ if(!pci_dma_supported(pdev, 0xffffffff)){
printk(KERN_ERR "amd8111e: DMA not supported,"
"exiting.\n");
- goto err_free_reg;
- }
+ goto err_free_reg;
+ } else
+ pdev->dma_mask = 0xffffffff;
reg_addr = pci_resource_start(pdev, 0);
reg_len = pci_resource_len(pdev, 0);
diff --git a/trunk/drivers/net/arm/etherh.c b/trunk/drivers/net/arm/etherh.c
index 942a2819576c..2e28c201dcc0 100644
--- a/trunk/drivers/net/arm/etherh.c
+++ b/trunk/drivers/net/arm/etherh.c
@@ -68,6 +68,7 @@ struct etherh_priv {
void __iomem *dma_base;
unsigned int id;
void __iomem *ctrl_port;
+ void __iomem *base;
unsigned char ctrl;
u32 supported;
};
@@ -177,7 +178,7 @@ etherh_setif(struct net_device *dev)
switch (etherh_priv(dev)->id) {
case PROD_I3_ETHERLAN600:
case PROD_I3_ETHERLAN600A:
- addr = (void *)dev->base_addr + EN0_RCNTHI;
+ addr = etherh_priv(dev)->base + EN0_RCNTHI;
switch (dev->if_port) {
case IF_PORT_10BASE2:
@@ -218,7 +219,7 @@ etherh_getifstat(struct net_device *dev)
switch (etherh_priv(dev)->id) {
case PROD_I3_ETHERLAN600:
case PROD_I3_ETHERLAN600A:
- addr = (void *)dev->base_addr + EN0_RCNTHI;
+ addr = etherh_priv(dev)->base + EN0_RCNTHI;
switch (dev->if_port) {
case IF_PORT_10BASE2:
stat = 1;
@@ -281,7 +282,7 @@ static void
etherh_reset(struct net_device *dev)
{
struct ei_device *ei_local = netdev_priv(dev);
- void __iomem *addr = (void *)dev->base_addr;
+ void __iomem *addr = etherh_priv(dev)->base;
writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);
@@ -327,7 +328,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
ei_local->dmaing = 1;
- addr = (void *)dev->base_addr;
+ addr = etherh_priv(dev)->base;
dma_base = etherh_priv(dev)->dma_base;
count = (count + 1) & ~1;
@@ -387,7 +388,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int
ei_local->dmaing = 1;
- addr = (void *)dev->base_addr;
+ addr = etherh_priv(dev)->base;
dma_base = etherh_priv(dev)->dma_base;
buf = skb->data;
@@ -427,7 +428,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p
ei_local->dmaing = 1;
- addr = (void *)dev->base_addr;
+ addr = etherh_priv(dev)->base;
dma_base = etherh_priv(dev)->dma_base;
writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
@@ -696,7 +697,8 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
eh->ctrl_port = eh->ioc_fast;
}
- dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
+ eh->base = eh->memc + data->ns8390_offset;
+ dev->base_addr = (unsigned long)eh->base;
eh->dma_base = eh->memc + data->dataport_offset;
eh->ctrl_port += data->ctrlport_offset;
diff --git a/trunk/drivers/net/at1700.c b/trunk/drivers/net/at1700.c
index e613cc289749..b8ab2b6355eb 100644
--- a/trunk/drivers/net/at1700.c
+++ b/trunk/drivers/net/at1700.c
@@ -34,6 +34,10 @@
only is it difficult to detect, it also moves around in I/O space in
response to inb()s from other device probes!
*/
+/*
+ 99/03/03 Allied Telesis RE1000 Plus support by T.Hagawa
+ 99/12/30 port to 2.3.35 by K.Takai
+*/
#include
#include
diff --git a/trunk/drivers/net/dl2k.c b/trunk/drivers/net/dl2k.c
index 430c628279b3..aa42b7a27735 100644
--- a/trunk/drivers/net/dl2k.c
+++ b/trunk/drivers/net/dl2k.c
@@ -547,7 +547,7 @@ rio_timer (unsigned long data)
skb_reserve (skb, 2);
np->rx_ring[entry].fraginfo =
cpu_to_le64 (pci_map_single
- (np->pdev, skb->data, np->rx_buf_sz,
+ (np->pdev, skb->tail, np->rx_buf_sz,
PCI_DMA_FROMDEVICE));
}
np->rx_ring[entry].fraginfo |=
@@ -618,7 +618,7 @@ alloc_list (struct net_device *dev)
/* Rubicon now supports 40 bits of addressing space. */
np->rx_ring[i].fraginfo =
cpu_to_le64 ( pci_map_single (
- np->pdev, skb->data, np->rx_buf_sz,
+ np->pdev, skb->tail, np->rx_buf_sz,
PCI_DMA_FROMDEVICE));
np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
}
@@ -906,7 +906,7 @@ receive_packet (struct net_device *dev)
/* 16 byte align the IP header */
skb_reserve (skb, 2);
eth_copy_and_sum (skb,
- np->rx_skbuff[entry]->data,
+ np->rx_skbuff[entry]->tail,
pkt_len, 0);
skb_put (skb, pkt_len);
pci_dma_sync_single_for_device(np->pdev,
@@ -950,7 +950,7 @@ receive_packet (struct net_device *dev)
skb_reserve (skb, 2);
np->rx_ring[entry].fraginfo =
cpu_to_le64 (pci_map_single
- (np->pdev, skb->data, np->rx_buf_sz,
+ (np->pdev, skb->tail, np->rx_buf_sz,
PCI_DMA_FROMDEVICE));
}
np->rx_ring[entry].fraginfo |=
diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c
index d0fa2448761d..1e56c8eea35f 100644
--- a/trunk/drivers/net/e100.c
+++ b/trunk/drivers/net/e100.c
@@ -2447,8 +2447,9 @@ static int e100_resume(struct pci_dev *pdev)
#endif
-static void e100_shutdown(struct pci_dev *pdev)
+static void e100_shutdown(struct device *dev)
{
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct nic *nic = netdev_priv(netdev);
@@ -2469,7 +2470,11 @@ static struct pci_driver e100_driver = {
.suspend = e100_suspend,
.resume = e100_resume,
#endif
- .shutdown = e100_shutdown,
+
+ .driver = {
+ .shutdown = e100_shutdown,
+ }
+
};
static int __init e100_init_module(void)
diff --git a/trunk/drivers/net/eepro100.c b/trunk/drivers/net/eepro100.c
index 1795425f512e..98b3a2fdce90 100644
--- a/trunk/drivers/net/eepro100.c
+++ b/trunk/drivers/net/eepro100.c
@@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev)
if (skb == NULL)
break; /* OK. Just initially short of Rx bufs. */
skb->dev = dev; /* Mark as being used by this device. */
- rxf = (struct RxFD *)skb->data;
+ rxf = (struct RxFD *)skb->tail;
sp->rx_ringp[i] = rxf;
sp->rx_ring_dma[i] =
pci_map_single(sp->pdev, rxf,
@@ -1661,7 +1661,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
sp->rx_ringp[entry] = NULL;
return NULL;
}
- rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data;
+ rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail;
sp->rx_ring_dma[entry] =
pci_map_single(sp->pdev, rxf,
PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
@@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev)
#if 1 || USE_IP_CSUM
/* Packet is in one chunk -- we can copy + cksum. */
- eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0);
+ eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
#else
- memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data,
+ memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail,
pkt_len);
#endif
pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
diff --git a/trunk/drivers/net/epic100.c b/trunk/drivers/net/epic100.c
index 87f522738bfc..81ebaedaa240 100644
--- a/trunk/drivers/net/epic100.c
+++ b/trunk/drivers/net/epic100.c
@@ -1003,7 +1003,7 @@ static void epic_init_ring(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev,
- skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn);
}
ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1274,7 +1274,7 @@ static int epic_rx(struct net_device *dev, int budget)
ep->rx_ring[entry].bufaddr,
ep->rx_buf_sz,
PCI_DMA_FROMDEVICE);
- eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0);
+ eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(ep->pci_dev,
ep->rx_ring[entry].bufaddr,
@@ -1308,7 +1308,7 @@ static int epic_rx(struct net_device *dev, int budget)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev,
- skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
work_done++;
}
ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn);
diff --git a/trunk/drivers/net/fealnx.c b/trunk/drivers/net/fealnx.c
index 55dbe9a3fd56..9e0303f6d73c 100644
--- a/trunk/drivers/net/fealnx.c
+++ b/trunk/drivers/net/fealnx.c
@@ -1107,7 +1107,7 @@ static void allocate_rx_buffers(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
np->lack_rxbuf->skbuff = skb;
- np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data,
+ np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail,
np->rx_buf_sz, PCI_DMA_FROMDEVICE);
np->lack_rxbuf->status = RXOWN;
++np->really_rx_count;
@@ -1300,7 +1300,7 @@ static void init_ring(struct net_device *dev)
++np->really_rx_count;
np->rx_ring[i].skbuff = skb;
skb->dev = dev; /* Mark as being used by this device. */
- np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data,
+ np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail,
np->rx_buf_sz, PCI_DMA_FROMDEVICE);
np->rx_ring[i].status = RXOWN;
np->rx_ring[i].control |= RXIC;
@@ -1737,11 +1737,11 @@ static int netdev_rx(struct net_device *dev)
#if ! defined(__alpha__)
eth_copy_and_sum(skb,
- np->cur_rx->skbuff->data, pkt_len, 0);
+ np->cur_rx->skbuff->tail, pkt_len, 0);
skb_put(skb, pkt_len);
#else
memcpy(skb_put(skb, pkt_len),
- np->cur_rx->skbuff->data, pkt_len);
+ np->cur_rx->skbuff->tail, pkt_len);
#endif
pci_dma_sync_single_for_device(np->pci_dev,
np->cur_rx->buffer,
diff --git a/trunk/drivers/net/hamachi.c b/trunk/drivers/net/hamachi.c
index d9df1d9a5739..3d96714ed3cf 100644
--- a/trunk/drivers/net/hamachi.c
+++ b/trunk/drivers/net/hamachi.c
@@ -1149,7 +1149,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
}
@@ -1210,7 +1210,7 @@ static void hamachi_init_ring(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
/* -2 because it doesn't REALLY have that first 2 bytes -KDU */
hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn |
DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
@@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device *dev)
desc->addr,
hmp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
- buf_addr = (u8 *) hmp->rx_skbuff[entry]->data;
+ buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail;
frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
if (hamachi_debug > 4)
printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n",
@@ -1678,7 +1678,7 @@ static int hamachi_rx(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
- skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz);
if (entry >= RX_RING_SIZE-1)
@@ -1772,9 +1772,9 @@ static int hamachi_close(struct net_device *dev)
readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ',
i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
if (hamachi_debug > 6) {
- if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) {
+ if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) {
u16 *addr = (u16 *)
- hmp->rx_skbuff[i]->data;
+ hmp->rx_skbuff[i]->tail;
int j;
for (j = 0; j < 0x50; j++)
diff --git a/trunk/drivers/net/lance.c b/trunk/drivers/net/lance.c
index b4929beb33b2..ca90f0d1e4b0 100644
--- a/trunk/drivers/net/lance.c
+++ b/trunk/drivers/net/lance.c
@@ -862,7 +862,7 @@ lance_init_ring(struct net_device *dev, int gfp)
lp->rx_skbuff[i] = skb;
if (skb) {
skb->dev = dev;
- rx_buff = skb->data;
+ rx_buff = skb->tail;
} else
rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
if (rx_buff == NULL)
diff --git a/trunk/drivers/net/lasi_82596.c b/trunk/drivers/net/lasi_82596.c
index 41bad07ac1ac..5e263fcba669 100644
--- a/trunk/drivers/net/lasi_82596.c
+++ b/trunk/drivers/net/lasi_82596.c
@@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct net_device *dev)
if (skb == NULL)
panic("%s: alloc_skb() failed", __FILE__);
skb_reserve(skb, 2);
- dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ,
+ dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
DMA_FROM_DEVICE);
skb->dev = dev;
rbd->v_next = rbd+1;
rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
rbd->skb = skb;
- rbd->v_data = skb->data;
+ rbd->v_data = skb->tail;
rbd->b_data = WSWAPchar(dma_addr);
rbd->size = PKT_BUF_SZ;
}
@@ -783,8 +783,8 @@ static inline int i596_rx(struct net_device *dev)
rx_in_place = 1;
rbd->skb = newskb;
newskb->dev = dev;
- dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
- rbd->v_data = newskb->data;
+ dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
+ rbd->v_data = newskb->tail;
rbd->b_data = WSWAPchar(dma_addr);
CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
}
diff --git a/trunk/drivers/net/natsemi.c b/trunk/drivers/net/natsemi.c
index 9d6d2548c2d3..babb59e146ea 100644
--- a/trunk/drivers/net/natsemi.c
+++ b/trunk/drivers/net/natsemi.c
@@ -1926,7 +1926,7 @@ static void refill_rx(struct net_device *dev)
break; /* Better luck next round. */
skb->dev = dev; /* Mark as being used by this device. */
np->rx_dma[entry] = pci_map_single(np->pci_dev,
- skb->data, buflen, PCI_DMA_FROMDEVICE);
+ skb->tail, buflen, PCI_DMA_FROMDEVICE);
np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
}
np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz);
@@ -2280,7 +2280,7 @@ static void netdev_rx(struct net_device *dev)
buflen,
PCI_DMA_FROMDEVICE);
eth_copy_and_sum(skb,
- np->rx_skbuff[entry]->data, pkt_len, 0);
+ np->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(np->pci_dev,
np->rx_dma[entry],
diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c
index e64df4d0800b..cc7965271778 100644
--- a/trunk/drivers/net/ns83820.c
+++ b/trunk/drivers/net/ns83820.c
@@ -574,7 +574,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
- buf = pci_map_single(dev->pci_dev, skb->data,
+ buf = pci_map_single(dev->pci_dev, skb->tail,
REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
/* update link of previous rx */
@@ -604,7 +604,7 @@ static inline int rx_refill(struct net_device *ndev, int gfp)
if (unlikely(!skb))
break;
- res = (long)skb->data & 0xf;
+ res = (long)skb->tail & 0xf;
res = 0x10 - res;
res &= 0xf;
skb_reserve(skb, res);
diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c
index 113b68099216..3213f3e50487 100644
--- a/trunk/drivers/net/pcnet32.c
+++ b/trunk/drivers/net/pcnet32.c
@@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev)
rmb();
if (lp->rx_dma_addr[i] == 0)
- lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data,
+ lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail,
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
@@ -1983,7 +1983,7 @@ pcnet32_rx(struct net_device *dev)
lp->rx_skbuff[entry] = newskb;
newskb->dev = dev;
lp->rx_dma_addr[entry] =
- pci_map_single(lp->pci_dev, newskb->data,
+ pci_map_single(lp->pci_dev, newskb->tail,
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
rx_in_place = 1;
@@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev)
PKT_BUF_SZ-2,
PCI_DMA_FROMDEVICE);
eth_copy_and_sum(skb,
- (unsigned char *)(lp->rx_skbuff[entry]->data),
+ (unsigned char *)(lp->rx_skbuff[entry]->tail),
pkt_len,0);
pci_dma_sync_single_for_device(lp->pci_dev,
lp->rx_dma_addr[entry],
diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c
index d5afe05cd826..ce449fe90e6d 100644
--- a/trunk/drivers/net/r8169.c
+++ b/trunk/drivers/net/r8169.c
@@ -1876,7 +1876,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
skb_reserve(skb, NET_IP_ALIGN);
*sk_buff = skb;
- mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
+ mapping = pci_map_single(pdev, skb->tail, rx_buf_sz,
PCI_DMA_FROMDEVICE);
rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
@@ -2336,7 +2336,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
if (skb) {
skb_reserve(skb, NET_IP_ALIGN);
- eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
+ eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
*sk_buff = skb;
rtl8169_mark_to_asic(desc, rx_buf_sz);
ret = 0;
diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c
index ea638b162d3f..bb639a8794d4 100644
--- a/trunk/drivers/net/s2io.c
+++ b/trunk/drivers/net/s2io.c
@@ -1699,9 +1699,11 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
#else
ba = &nic->ba[ring_no][block_no][off];
skb_reserve(skb, BUF0_LEN);
- tmp = ((unsigned long) skb->data & ALIGN_SIZE);
- if (tmp)
- skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
+ tmp = (unsigned long) skb->data;
+ tmp += ALIGN_SIZE;
+ tmp &= ~ALIGN_SIZE;
+ skb->data = (void *) tmp;
+ skb->tail = (void *) tmp;
memset(rxdp, 0, sizeof(RxD_t));
rxdp->Buffer2_ptr = pci_map_single
diff --git a/trunk/drivers/net/sb1250-mac.c b/trunk/drivers/net/sb1250-mac.c
index 7abd55a4fb21..fd2e7c374906 100644
--- a/trunk/drivers/net/sb1250-mac.c
+++ b/trunk/drivers/net/sb1250-mac.c
@@ -963,11 +963,11 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
/*
* Do not interrupt per DMA transfer.
*/
- dsc->dscr_a = virt_to_phys(sb_new->data) |
+ dsc->dscr_a = virt_to_phys(sb_new->tail) |
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
0;
#else
- dsc->dscr_a = virt_to_phys(sb_new->data) |
+ dsc->dscr_a = virt_to_phys(sb_new->tail) |
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
M_DMA_DSCRA_INTERRUPT;
#endif
diff --git a/trunk/drivers/net/sis900.c b/trunk/drivers/net/sis900.c
index 23b713c700b3..127324f014de 100644
--- a/trunk/drivers/net/sis900.c
+++ b/trunk/drivers/net/sis900.c
@@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
sis_priv->rx_skbuff[i] = skb;
sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
- skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
}
sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
@@ -1776,7 +1776,7 @@ static int sis900_rx(struct net_device *net_dev)
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
sis_priv->rx_ring[entry].bufptr =
- pci_map_single(sis_priv->pci_dev, skb->data,
+ pci_map_single(sis_priv->pci_dev, skb->tail,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
sis_priv->dirty_rx++;
}
@@ -1809,7 +1809,7 @@ static int sis900_rx(struct net_device *net_dev)
sis_priv->rx_skbuff[entry] = skb;
sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
sis_priv->rx_ring[entry].bufptr =
- pci_map_single(sis_priv->pci_dev, skb->data,
+ pci_map_single(sis_priv->pci_dev, skb->tail,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
}
}
diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c
index 3dbb1cb09ed8..30e8d589d167 100644
--- a/trunk/drivers/net/skge.c
+++ b/trunk/drivers/net/skge.c
@@ -7,7 +7,7 @@
* of the original driver such as link fail-over and link management because
* those should be done at higher levels.
*
- * Copyright (C) 2004, 2005 Stephen Hemminger
+ * Copyright (C) 2004, Stephen Hemminger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,20 +42,19 @@
#include "skge.h"
#define DRV_NAME "skge"
-#define DRV_VERSION "0.7"
+#define DRV_VERSION "0.6"
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
#define DEFAULT_RX_RING_SIZE 512
#define MAX_TX_RING_SIZE 1024
#define MAX_RX_RING_SIZE 4096
-#define RX_COPY_THRESHOLD 128
-#define RX_BUF_SIZE 1536
#define PHY_RETRIES 1000
#define ETH_JUMBO_MTU 9000
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define BLINK_HZ (HZ/4)
+#define LINK_POLL_HZ (HZ/10)
MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
MODULE_AUTHOR("Stephen Hemminger ");
@@ -71,17 +70,28 @@ module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
static const struct pci_device_id skge_id_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) },
- { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) },
- { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
- { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
- { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
- { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
- { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },
- { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) },
- { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) },
+ { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_SYSKONNECT, 0x9E00, /* SK-9Exx */
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_MARVELL, 0x4320, /* Gigabit Ethernet Controller */
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_MARVELL, 0x5005, /* Marvell (11ab), Belkin */
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064,
+ PCI_ANY_ID, PCI_ANY_ID },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, skge_id_table);
@@ -89,22 +99,19 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
static int skge_up(struct net_device *dev);
static int skge_down(struct net_device *dev);
static void skge_tx_clean(struct skge_port *skge);
-static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
-static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
static void genesis_get_stats(struct skge_port *skge, u64 *data);
static void yukon_get_stats(struct skge_port *skge, u64 *data);
static void yukon_init(struct skge_hw *hw, int port);
static void yukon_reset(struct skge_hw *hw, int port);
static void genesis_mac_init(struct skge_hw *hw, int port);
static void genesis_reset(struct skge_hw *hw, int port);
-static void genesis_link_up(struct skge_port *skge);
-/* Avoid conditionals by using array */
static const int txqaddr[] = { Q_XA1, Q_XA2 };
static const int rxqaddr[] = { Q_R1, Q_R2 };
static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
-static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 };
/* Don't need to look at whole 16K.
* last interesting register is descriptor poll timer.
@@ -147,7 +154,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
static int wol_supported(const struct skge_hw *hw)
{
return !((hw->chip_id == CHIP_ID_GENESIS ||
- (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)));
+ (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0)));
}
static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -163,7 +170,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
- if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+ if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
return -EOPNOTSUPP;
if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw))
@@ -183,36 +190,6 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
-/* Determine supported/adverised modes based on hardware.
- * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
- */
-static u32 skge_supported_modes(const struct skge_hw *hw)
-{
- u32 supported;
-
- if (iscopper(hw)) {
- supported = SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full
- | SUPPORTED_1000baseT_Half
- | SUPPORTED_1000baseT_Full
- | SUPPORTED_Autoneg| SUPPORTED_TP;
-
- if (hw->chip_id == CHIP_ID_GENESIS)
- supported &= ~(SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full);
-
- else if (hw->chip_id == CHIP_ID_YUKON)
- supported &= ~SUPPORTED_1000baseT_Half;
- } else
- supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
- | SUPPORTED_Autoneg;
-
- return supported;
-}
static int skge_get_settings(struct net_device *dev,
struct ethtool_cmd *ecmd)
@@ -221,13 +198,38 @@ static int skge_get_settings(struct net_device *dev,
struct skge_hw *hw = skge->hw;
ecmd->transceiver = XCVR_INTERNAL;
- ecmd->supported = skge_supported_modes(hw);
if (iscopper(hw)) {
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ ecmd->supported = SUPPORTED_1000baseT_Full
+ | SUPPORTED_1000baseT_Half
+ | SUPPORTED_Autoneg | SUPPORTED_TP;
+ else {
+ ecmd->supported = SUPPORTED_10baseT_Half
+ | SUPPORTED_10baseT_Full
+ | SUPPORTED_100baseT_Half
+ | SUPPORTED_100baseT_Full
+ | SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full
+ | SUPPORTED_Autoneg| SUPPORTED_TP;
+
+ if (hw->chip_id == CHIP_ID_YUKON)
+ ecmd->supported &= ~SUPPORTED_1000baseT_Half;
+
+ else if (hw->chip_id == CHIP_ID_YUKON_FE)
+ ecmd->supported &= ~(SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full);
+ }
+
ecmd->port = PORT_TP;
ecmd->phy_address = hw->phy_addr;
- } else
+ } else {
+ ecmd->supported = SUPPORTED_1000baseT_Full
+ | SUPPORTED_FIBRE
+ | SUPPORTED_Autoneg;
+
ecmd->port = PORT_FIBRE;
+ }
ecmd->advertising = skge->advertising;
ecmd->autoneg = skge->autoneg;
@@ -236,57 +238,65 @@ static int skge_get_settings(struct net_device *dev,
return 0;
}
+static u32 skge_modes(const struct skge_hw *hw)
+{
+ u32 modes = ADVERTISED_Autoneg
+ | ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half
+ | ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half
+ | ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half;
+
+ if (iscopper(hw)) {
+ modes |= ADVERTISED_TP;
+ switch(hw->chip_id) {
+ case CHIP_ID_GENESIS:
+ modes &= ~(ADVERTISED_100baseT_Full
+ | ADVERTISED_100baseT_Half
+ | ADVERTISED_10baseT_Full
+ | ADVERTISED_10baseT_Half);
+ break;
+
+ case CHIP_ID_YUKON:
+ modes &= ~ADVERTISED_1000baseT_Half;
+ break;
+
+ case CHIP_ID_YUKON_FE:
+ modes &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
+ break;
+ }
+ } else {
+ modes |= ADVERTISED_FIBRE;
+ modes &= ~ADVERTISED_1000baseT_Half;
+ }
+ return modes;
+}
+
static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct skge_port *skge = netdev_priv(dev);
const struct skge_hw *hw = skge->hw;
- u32 supported = skge_supported_modes(hw);
if (ecmd->autoneg == AUTONEG_ENABLE) {
- ecmd->advertising = supported;
- skge->duplex = -1;
- skge->speed = -1;
+ if (ecmd->advertising & skge_modes(hw))
+ return -EINVAL;
} else {
- u32 setting;
-
switch(ecmd->speed) {
case SPEED_1000:
- if (ecmd->duplex == DUPLEX_FULL)
- setting = SUPPORTED_1000baseT_Full;
- else if (ecmd->duplex == DUPLEX_HALF)
- setting = SUPPORTED_1000baseT_Half;
- else
+ if (hw->chip_id == CHIP_ID_YUKON_FE)
return -EINVAL;
break;
case SPEED_100:
- if (ecmd->duplex == DUPLEX_FULL)
- setting = SUPPORTED_100baseT_Full;
- else if (ecmd->duplex == DUPLEX_HALF)
- setting = SUPPORTED_100baseT_Half;
- else
- return -EINVAL;
- break;
-
case SPEED_10:
- if (ecmd->duplex == DUPLEX_FULL)
- setting = SUPPORTED_10baseT_Full;
- else if (ecmd->duplex == DUPLEX_HALF)
- setting = SUPPORTED_10baseT_Half;
- else
+ if (iscopper(hw) || hw->chip_id == CHIP_ID_GENESIS)
return -EINVAL;
break;
default:
return -EINVAL;
}
-
- if ((setting & supported) == 0)
- return -EINVAL;
-
- skge->speed = ecmd->speed;
- skge->duplex = ecmd->duplex;
}
skge->autoneg = ecmd->autoneg;
+ skge->speed = ecmd->speed;
+ skge->duplex = ecmd->duplex;
skge->advertising = ecmd->advertising;
if (netif_running(dev)) {
@@ -383,7 +393,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
int i;
- switch (stringset) {
+ switch(stringset) {
case ETH_SS_STATS:
for (i = 0; i < ARRAY_SIZE(skge_stats); i++)
memcpy(data + i * ETH_GSTRING_LEN,
@@ -501,6 +511,14 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data)
return 0;
}
+/* Only Yukon II supports TSO (not implemented yet) */
+static int skge_set_tso(struct net_device *dev, u32 data)
+{
+ if (data)
+ return -EOPNOTSUPP;
+ return 0;
+}
+
static void skge_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *ecmd)
{
@@ -522,9 +540,9 @@ static int skge_set_pauseparam(struct net_device *dev,
skge->autoneg = ecmd->autoneg;
if (ecmd->rx_pause && ecmd->tx_pause)
skge->flow_control = FLOW_MODE_SYMMETRIC;
- else if (ecmd->rx_pause && !ecmd->tx_pause)
+ else if(ecmd->rx_pause && !ecmd->tx_pause)
skge->flow_control = FLOW_MODE_REM_SEND;
- else if (!ecmd->rx_pause && ecmd->tx_pause)
+ else if(!ecmd->rx_pause && ecmd->tx_pause)
skge->flow_control = FLOW_MODE_LOC_SEND;
else
skge->flow_control = FLOW_MODE_NONE;
@@ -541,6 +559,8 @@ static inline u32 hwkhz(const struct skge_hw *hw)
{
if (hw->chip_id == CHIP_ID_GENESIS)
return 53215; /* or: 53.125 MHz */
+ else if (hw->chip_id == CHIP_ID_YUKON_EC)
+ return 125000; /* or: 125.000 MHz */
else
return 78215; /* or: 78.125 MHz */
}
@@ -623,18 +643,30 @@ static int skge_set_coalesce(struct net_device *dev,
static void skge_led_on(struct skge_hw *hw, int port)
{
if (hw->chip_id == CHIP_ID_GENESIS) {
- skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
+ skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON);
skge_write8(hw, B0_LED, LED_STAT_ON);
- skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
- skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
- skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
+ skge_write8(hw, SKGEMAC_REG(port, RX_LED_TST), LED_T_ON);
+ skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 100);
+ skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START);
- /* For Broadcom Phy only */
- xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
+ switch (hw->phy_type) {
+ case SK_PHY_BCOM:
+ skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL,
+ PHY_B_PEC_LED_ON);
+ break;
+ case SK_PHY_LONE:
+ skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG,
+ 0x0800);
+ break;
+ default:
+ skge_write8(hw, SKGEMAC_REG(port, TX_LED_TST), LED_T_ON);
+ skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 100);
+ skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START);
+ }
} else {
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
- gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+ skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+ skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER,
PHY_M_LED_MO_DUP(MO_LED_ON) |
PHY_M_LED_MO_10(MO_LED_ON) |
PHY_M_LED_MO_100(MO_LED_ON) |
@@ -646,17 +678,28 @@ static void skge_led_on(struct skge_hw *hw, int port)
static void skge_led_off(struct skge_hw *hw, int port)
{
if (hw->chip_id == CHIP_ID_GENESIS) {
- skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+ skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_OFF);
skge_write8(hw, B0_LED, LED_STAT_OFF);
- skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
- skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
+ skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 0);
+ skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_T_OFF);
- /* Broadcom only */
- xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
+ switch (hw->phy_type) {
+ case SK_PHY_BCOM:
+ skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL,
+ PHY_B_PEC_LED_OFF);
+ break;
+ case SK_PHY_LONE:
+ skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG,
+ PHY_L_LC_LEDT);
+ break;
+ default:
+ skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 0);
+ skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_T_OFF);
+ }
} else {
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
- gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+ skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+ skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER,
PHY_M_LED_MO_DUP(MO_LED_OFF) |
PHY_M_LED_MO_10(MO_LED_OFF) |
PHY_M_LED_MO_100(MO_LED_OFF) |
@@ -687,7 +730,7 @@ static int skge_phys_id(struct net_device *dev, u32 data)
{
struct skge_port *skge = netdev_priv(dev);
- if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
+ if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
/* start blinking */
@@ -720,6 +763,8 @@ static struct ethtool_ops skge_ethtool_ops = {
.set_pauseparam = skge_set_pauseparam,
.get_coalesce = skge_get_coalesce,
.set_coalesce = skge_set_coalesce,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = skge_set_tso,
.get_sg = ethtool_op_get_sg,
.set_sg = skge_set_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
@@ -748,7 +793,6 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) {
e->desc = d;
- e->skb = NULL;
if (i == ring->count - 1) {
e->next = ring->start;
d->next_offset = base;
@@ -762,23 +806,24 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
return 0;
}
-static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size)
+/* Setup buffer for receiving */
+static inline int skge_rx_alloc(struct skge_port *skge,
+ struct skge_element *e)
{
- struct sk_buff *skb = dev_alloc_skb(size);
+ unsigned long bufsize = skge->netdev->mtu + ETH_HLEN; /* VLAN? */
+ struct skge_rx_desc *rd = e->desc;
+ struct sk_buff *skb;
+ u64 map;
- if (likely(skb)) {
- skb->dev = dev;
- skb_reserve(skb, NET_IP_ALIGN);
+ skb = dev_alloc_skb(bufsize + NET_IP_ALIGN);
+ if (unlikely(!skb)) {
+ printk(KERN_DEBUG PFX "%s: out of memory for receive\n",
+ skge->netdev->name);
+ return -ENOMEM;
}
- return skb;
-}
-/* Allocate and setup a new buffer for receiving */
-static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
- struct sk_buff *skb, unsigned int bufsize)
-{
- struct skge_rx_desc *rd = e->desc;
- u64 map;
+ skb->dev = skge->netdev;
+ skb_reserve(skb, NET_IP_ALIGN);
map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
PCI_DMA_FROMDEVICE);
@@ -796,69 +841,55 @@ static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
pci_unmap_addr_set(e, mapaddr, map);
pci_unmap_len_set(e, maplen, bufsize);
+ return 0;
}
-/* Resume receiving using existing skb,
- * Note: DMA address is not changed by chip.
- * MTU not changed while receiver active.
- */
-static void skge_rx_reuse(struct skge_element *e, unsigned int size)
-{
- struct skge_rx_desc *rd = e->desc;
-
- rd->csum2 = 0;
- rd->csum2_start = ETH_HLEN;
-
- wmb();
-
- rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size;
-}
-
-
-/* Free all buffers in receive ring, assumes receiver stopped */
+/* Free all unused buffers in receive ring, assumes receiver stopped */
static void skge_rx_clean(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
struct skge_ring *ring = &skge->rx_ring;
struct skge_element *e;
- e = ring->start;
- do {
+ for (e = ring->to_clean; e != ring->to_use; e = e->next) {
struct skge_rx_desc *rd = e->desc;
rd->control = 0;
- if (e->skb) {
- pci_unmap_single(hw->pdev,
- pci_unmap_addr(e, mapaddr),
- pci_unmap_len(e, maplen),
- PCI_DMA_FROMDEVICE);
- dev_kfree_skb(e->skb);
- e->skb = NULL;
- }
- } while ((e = e->next) != ring->start);
-}
+ pci_unmap_single(hw->pdev,
+ pci_unmap_addr(e, mapaddr),
+ pci_unmap_len(e, maplen),
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(e->skb);
+ e->skb = NULL;
+ }
+ ring->to_clean = e;
+}
/* Allocate buffers for receive ring
- * For receive: to_clean is next received frame.
+ * For receive: to_use is refill location
+ * to_clean is next received frame.
+ *
+ * if (to_use == to_clean)
+ * then ring all frames in ring need buffers
+ * if (to_use->next == to_clean)
+ * then ring all frames in ring have buffers
*/
static int skge_rx_fill(struct skge_port *skge)
{
struct skge_ring *ring = &skge->rx_ring;
struct skge_element *e;
- unsigned int bufsize = skge->rx_buf_size;
-
- e = ring->start;
- do {
- struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize);
+ int ret = 0;
- if (!skb)
- return -ENOMEM;
+ for (e = ring->to_use; e->next != ring->to_clean; e = e->next) {
+ if (skge_rx_alloc(skge, e)) {
+ ret = 1;
+ break;
+ }
- skge_rx_setup(skge, e, skb, bufsize);
- } while ( (e = e->next) != ring->start);
+ }
+ ring->to_use = e;
- ring->to_clean = ring->start;
- return 0;
+ return ret;
}
static void skge_link_up(struct skge_port *skge)
@@ -888,50 +919,50 @@ static void skge_link_down(struct skge_port *skge)
printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
}
-static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
+static u16 skge_xm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
int i;
u16 v;
- xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
- v = xm_read16(hw, port, XM_PHY_DATA);
+ skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
+ v = skge_xm_read16(hw, port, XM_PHY_DATA);
+ if (hw->phy_type != SK_PHY_XMAC) {
+ for (i = 0; i < PHY_RETRIES; i++) {
+ udelay(1);
+ if (skge_xm_read16(hw, port, XM_MMU_CMD)
+ & XM_MMU_PHY_RDY)
+ goto ready;
+ }
- /* Need to wait for external PHY */
- for (i = 0; i < PHY_RETRIES; i++) {
- udelay(1);
- if (xm_read16(hw, port, XM_MMU_CMD)
- & XM_MMU_PHY_RDY)
- goto ready;
+ printk(KERN_WARNING PFX "%s: phy read timed out\n",
+ hw->dev[port]->name);
+ return 0;
+ ready:
+ v = skge_xm_read16(hw, port, XM_PHY_DATA);
}
- printk(KERN_WARNING PFX "%s: phy read timed out\n",
- hw->dev[port]->name);
- return 0;
- ready:
- v = xm_read16(hw, port, XM_PHY_DATA);
-
return v;
}
-static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
int i;
- xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
+ skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
for (i = 0; i < PHY_RETRIES; i++) {
- if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
+ if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
goto ready;
- udelay(1);
+ cpu_relax();
}
printk(KERN_WARNING PFX "%s: phy write failed to come ready\n",
hw->dev[port]->name);
ready:
- xm_write16(hw, port, XM_PHY_DATA, val);
+ skge_xm_write16(hw, port, XM_PHY_DATA, val);
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
- if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
+ if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
return;
}
printk(KERN_WARNING PFX "%s: phy write timed out\n",
@@ -968,112 +999,34 @@ static void genesis_init(struct skge_hw *hw)
static void genesis_reset(struct skge_hw *hw, int port)
{
- const u8 zero[8] = { 0 };
+ int i;
+ u64 zero = 0;
/* reset the statistics module */
- xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
- xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */
- xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */
- xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */
- xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */
+ skge_xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
+ skge_xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */
+ skge_xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */
+ skge_xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */
+ skge_xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */
- /* disable Broadcom PHY IRQ */
- xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
+ /* disable all PHY IRQs */
+ if (hw->phy_type == SK_PHY_BCOM)
+ skge_xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
- xm_outhash(hw, port, XM_HSM, zero);
+ skge_xm_outhash(hw, port, XM_HSM, (u8 *) &zero);
+ for (i = 0; i < 15; i++)
+ skge_xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero);
+ skge_xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero);
}
-/* Convert mode to MII values */
-static const u16 phy_pause_map[] = {
- [FLOW_MODE_NONE] = 0,
- [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM,
- [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
- [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
-};
-
-
-/* Check status of Broadcom phy link */
-static void bcom_check_link(struct skge_hw *hw, int port)
-{
- struct net_device *dev = hw->dev[port];
- struct skge_port *skge = netdev_priv(dev);
- u16 status;
-
- /* read twice because of latch */
- (void) xm_phy_read(hw, port, PHY_BCOM_STAT);
- status = xm_phy_read(hw, port, PHY_BCOM_STAT);
-
- pr_debug("bcom_check_link status=0x%x\n", status);
-
- if ((status & PHY_ST_LSYNC) == 0) {
- u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
- cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
- xm_write16(hw, port, XM_MMU_CMD, cmd);
- /* dummy read to ensure writing */
- (void) xm_read16(hw, port, XM_MMU_CMD);
-
- if (netif_carrier_ok(dev))
- skge_link_down(skge);
- } else {
- if (skge->autoneg == AUTONEG_ENABLE &&
- (status & PHY_ST_AN_OVER)) {
- u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
- u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
-
- if (lpa & PHY_B_AN_RF) {
- printk(KERN_NOTICE PFX "%s: remote fault\n",
- dev->name);
- return;
- }
-
- /* Check Duplex mismatch */
- switch(aux & PHY_B_AS_AN_RES_MSK) {
- case PHY_B_RES_1000FD:
- skge->duplex = DUPLEX_FULL;
- break;
- case PHY_B_RES_1000HD:
- skge->duplex = DUPLEX_HALF;
- break;
- default:
- printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
- dev->name);
- return;
- }
-
-
- /* We are using IEEE 802.3z/D5.0 Table 37-4 */
- switch (aux & PHY_B_AS_PAUSE_MSK) {
- case PHY_B_AS_PAUSE_MSK:
- skge->flow_control = FLOW_MODE_SYMMETRIC;
- break;
- case PHY_B_AS_PRR:
- skge->flow_control = FLOW_MODE_REM_SEND;
- break;
- case PHY_B_AS_PRT:
- skge->flow_control = FLOW_MODE_LOC_SEND;
- break;
- default:
- skge->flow_control = FLOW_MODE_NONE;
- }
-
- skge->speed = SPEED_1000;
- }
-
- if (!netif_carrier_ok(dev))
- genesis_link_up(skge);
- }
-}
-
-/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
- * Phy on for 100 or 10Mbit operation
- */
-static void bcom_phy_init(struct skge_port *skge, int jumbo)
+static void genesis_mac_init(struct skge_hw *hw, int port)
{
- struct skge_hw *hw = skge->hw;
- int port = skge->port;
+ struct skge_port *skge = netdev_priv(hw->dev[port]);
int i;
- u16 id1, r, ext, ctl;
+ u32 r;
+ u16 id1;
+ u16 ctrl1, ctrl2, ctrl3, ctrl4, ctrl5;
/* magic workaround patterns for Broadcom */
static const struct {
@@ -1089,120 +1042,16 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
};
- pr_debug("bcom_phy_init\n");
-
- /* read Id from external PHY (all have the same address) */
- id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
-
- /* Optimize MDIO transfer by suppressing preamble. */
- r = xm_read16(hw, port, XM_MMU_CMD);
- r |= XM_MMU_NO_PRE;
- xm_write16(hw, port, XM_MMU_CMD,r);
-
- switch(id1) {
- case PHY_BCOM_ID1_C0:
- /*
- * Workaround BCOM Errata for the C0 type.
- * Write magic patterns to reserved registers.
- */
- for (i = 0; i < ARRAY_SIZE(C0hack); i++)
- xm_phy_write(hw, port,
- C0hack[i].reg, C0hack[i].val);
-
- break;
- case PHY_BCOM_ID1_A1:
- /*
- * Workaround BCOM Errata for the A1 type.
- * Write magic patterns to reserved registers.
- */
- for (i = 0; i < ARRAY_SIZE(A1hack); i++)
- xm_phy_write(hw, port,
- A1hack[i].reg, A1hack[i].val);
- break;
- }
-
- /*
- * Workaround BCOM Errata (#10523) for all BCom PHYs.
- * Disable Power Management after reset.
- */
- r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
- r |= PHY_B_AC_DIS_PM;
- xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r);
-
- /* Dummy read */
- xm_read16(hw, port, XM_ISRC);
-
- ext = PHY_B_PEC_EN_LTR; /* enable tx led */
- ctl = PHY_CT_SP1000; /* always 1000mbit */
-
- if (skge->autoneg == AUTONEG_ENABLE) {
- /*
- * Workaround BCOM Errata #1 for the C5 type.
- * 1000Base-T Link Acquisition Failure in Slave Mode
- * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
- */
- u16 adv = PHY_B_1000C_RD;
- if (skge->advertising & ADVERTISED_1000baseT_Half)
- adv |= PHY_B_1000C_AHD;
- if (skge->advertising & ADVERTISED_1000baseT_Full)
- adv |= PHY_B_1000C_AFD;
- xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv);
-
- ctl |= PHY_CT_ANE | PHY_CT_RE_CFG;
- } else {
- if (skge->duplex == DUPLEX_FULL)
- ctl |= PHY_CT_DUP_MD;
- /* Force to slave */
- xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE);
- }
-
- /* Set autonegotiation pause parameters */
- xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV,
- phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
-
- /* Handle Jumbo frames */
- if (jumbo) {
- xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
- PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
-
- ext |= PHY_B_PEC_HIGH_LA;
-
- }
-
- xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
- xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
-
- /* Use link status change interrrupt */
- xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
-
- bcom_check_link(hw, port);
-}
-
-static void genesis_mac_init(struct skge_hw *hw, int port)
-{
- struct net_device *dev = hw->dev[port];
- struct skge_port *skge = netdev_priv(dev);
- int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
- int i;
- u32 r;
- const u8 zero[6] = { 0 };
-
- /* Clear MIB counters */
- xm_write16(hw, port, XM_STAT_CMD,
- XM_SC_CLR_RXC | XM_SC_CLR_TXC);
- /* Clear two times according to Errata #3 */
- xm_write16(hw, port, XM_STAT_CMD,
- XM_SC_CLR_RXC | XM_SC_CLR_TXC);
/* initialize Rx, Tx and Link LED */
- skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
- skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
+ skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON);
+ skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
- skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
- skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
+ skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START);
+ skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START);
/* Unreset the XMAC. */
- skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+ skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
/*
* Perform additional initialization for external PHYs,
@@ -1210,56 +1059,67 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* GMII mode.
*/
spin_lock_bh(&hw->phy_lock);
- /* Take external Phy out of reset */
- r = skge_read32(hw, B2_GP_IO);
- if (port == 0)
- r |= GP_DIR_0|GP_IO_0;
- else
- r |= GP_DIR_2|GP_IO_2;
-
- skge_write32(hw, B2_GP_IO, r);
- skge_read32(hw, B2_GP_IO);
- spin_unlock_bh(&hw->phy_lock);
-
- /* Enable GMII interfac */
- xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
-
- bcom_phy_init(skge, jumbo);
-
- /* Set Station Address */
- xm_outaddr(hw, port, XM_SA, dev->dev_addr);
-
- /* We don't use match addresses so clear */
- for (i = 1; i < 16; i++)
- xm_outaddr(hw, port, XM_EXM(i), zero);
-
- /* configure Rx High Water Mark (XM_RX_HI_WM) */
- xm_write16(hw, port, XM_RX_HI_WM, 1450);
-
- /* We don't need the FCS appended to the packet. */
- r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS;
- if (jumbo)
- r |= XM_RX_BIG_PK_OK;
+ if (hw->phy_type != SK_PHY_XMAC) {
+ /* Take PHY out of reset. */
+ r = skge_read32(hw, B2_GP_IO);
+ if (port == 0)
+ r |= GP_DIR_0|GP_IO_0;
+ else
+ r |= GP_DIR_2|GP_IO_2;
+
+ skge_write32(hw, B2_GP_IO, r);
+ skge_read32(hw, B2_GP_IO);
+
+ /* Enable GMII mode on the XMAC. */
+ skge_xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
+
+ id1 = skge_xm_phy_read(hw, port, PHY_XMAC_ID1);
+
+ /* Optimize MDIO transfer by suppressing preamble. */
+ skge_xm_write16(hw, port, XM_MMU_CMD,
+ skge_xm_read16(hw, port, XM_MMU_CMD)
+ | XM_MMU_NO_PRE);
+
+ if (id1 == PHY_BCOM_ID1_C0) {
+ /*
+ * Workaround BCOM Errata for the C0 type.
+ * Write magic patterns to reserved registers.
+ */
+ for (i = 0; i < ARRAY_SIZE(C0hack); i++)
+ skge_xm_phy_write(hw, port,
+ C0hack[i].reg, C0hack[i].val);
+
+ } else if (id1 == PHY_BCOM_ID1_A1) {
+ /*
+ * Workaround BCOM Errata for the A1 type.
+ * Write magic patterns to reserved registers.
+ */
+ for (i = 0; i < ARRAY_SIZE(A1hack); i++)
+ skge_xm_phy_write(hw, port,
+ A1hack[i].reg, A1hack[i].val);
+ }
- if (skge->duplex == DUPLEX_HALF) {
/*
- * If in manual half duplex mode the other side might be in
- * full duplex mode, so ignore if a carrier extension is not seen
- * on frames received
+ * Workaround BCOM Errata (#10523) for all BCom PHYs.
+ * Disable Power Management after reset.
*/
- r |= XM_RX_DIS_CEXT;
+ r = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
+ skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM);
}
- xm_write16(hw, port, XM_RX_CMD, r);
+ /* Dummy read */
+ skge_xm_read16(hw, port, XM_ISRC);
- /* We want short frames padded to 60 bytes. */
- xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);
+ r = skge_xm_read32(hw, port, XM_MODE);
+ skge_xm_write32(hw, port, XM_MODE, r|XM_MD_CSA);
- /*
- * Bump up the transmit threshold. This helps hold off transmit
- * underruns when we're blasting traffic from both ports at once.
- */
- xm_write16(hw, port, XM_TX_THR, 512);
+ /* We don't need the FCS appended to the packet. */
+ r = skge_xm_read16(hw, port, XM_RX_CMD);
+ skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS);
+
+ /* We want short frames padded to 60 bytes. */
+ r = skge_xm_read16(hw, port, XM_TX_CMD);
+ skge_xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD);
/*
* Enable the reception of all error frames. This is is
@@ -1275,22 +1135,19 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* case the XMAC will start transfering frames out of the
* RX FIFO as soon as the FIFO threshold is reached.
*/
- xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
+ r = skge_xm_read32(hw, port, XM_MODE);
+ skge_xm_write32(hw, port, XM_MODE,
+ XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT|
+ XM_MD_RX_ERR|XM_MD_RX_IRLE);
+ skge_xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr);
+ skge_xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr);
/*
- * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
- * - Enable all bits excepting 'Octets Rx OK Low CntOv'
- * and 'Octets Rx OK Hi Cnt Ov'.
- */
- xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK);
-
- /*
- * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
- * - Enable all bits excepting 'Octets Tx OK Low CntOv'
- * and 'Octets Tx OK Hi Cnt Ov'.
+ * Bump up the transmit threshold. This helps hold off transmit
+ * underruns when we're blasting traffic from both ports at once.
*/
- xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK);
+ skge_xm_write16(hw, port, XM_TX_THR, 512);
/* Configure MAC arbiter */
skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
@@ -1307,30 +1164,137 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write8(hw, B3_MA_RCINI_TX2, 0);
/* Configure Rx MAC FIFO */
- skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
- skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
- skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
+ skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
+ skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
+ skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
/* Configure Tx MAC FIFO */
- skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
- skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
- skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
+ skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
+ skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
+ skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
- if (jumbo) {
+ if (hw->dev[port]->mtu > ETH_DATA_LEN) {
/* Enable frame flushing if jumbo frames used */
- skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
+ skge_write16(hw, SKGEMAC_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
} else {
/* enable timeout timers if normal frames */
skge_write16(hw, B3_PA_CTRL,
- (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
+ port == 0 ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
}
+
+
+ r = skge_xm_read16(hw, port, XM_RX_CMD);
+ if (hw->dev[port]->mtu > ETH_DATA_LEN)
+ skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK);
+ else
+ skge_xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK));
+
+ switch (hw->phy_type) {
+ case SK_PHY_XMAC:
+ if (skge->autoneg == AUTONEG_ENABLE) {
+ ctrl1 = PHY_X_AN_FD | PHY_X_AN_HD;
+
+ switch (skge->flow_control) {
+ case FLOW_MODE_NONE:
+ ctrl1 |= PHY_X_P_NO_PAUSE;
+ break;
+ case FLOW_MODE_LOC_SEND:
+ ctrl1 |= PHY_X_P_ASYM_MD;
+ break;
+ case FLOW_MODE_SYMMETRIC:
+ ctrl1 |= PHY_X_P_SYM_MD;
+ break;
+ case FLOW_MODE_REM_SEND:
+ ctrl1 |= PHY_X_P_BOTH_MD;
+ break;
+ }
+
+ skge_xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1);
+ ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG;
+ } else {
+ ctrl2 = 0;
+ if (skge->duplex == DUPLEX_FULL)
+ ctrl2 |= PHY_CT_DUP_MD;
+ }
+
+ skge_xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2);
+ break;
+
+ case SK_PHY_BCOM:
+ ctrl1 = PHY_CT_SP1000;
+ ctrl2 = 0;
+ ctrl3 = PHY_SEL_TYPE;
+ ctrl4 = PHY_B_PEC_EN_LTR;
+ ctrl5 = PHY_B_AC_TX_TST;
+
+ if (skge->autoneg == AUTONEG_ENABLE) {
+ /*
+ * Workaround BCOM Errata #1 for the C5 type.
+ * 1000Base-T Link Acquisition Failure in Slave Mode
+ * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
+ */
+ ctrl2 |= PHY_B_1000C_RD;
+ if (skge->advertising & ADVERTISED_1000baseT_Half)
+ ctrl2 |= PHY_B_1000C_AHD;
+ if (skge->advertising & ADVERTISED_1000baseT_Full)
+ ctrl2 |= PHY_B_1000C_AFD;
+
+ /* Set Flow-control capabilities */
+ switch (skge->flow_control) {
+ case FLOW_MODE_NONE:
+ ctrl3 |= PHY_B_P_NO_PAUSE;
+ break;
+ case FLOW_MODE_LOC_SEND:
+ ctrl3 |= PHY_B_P_ASYM_MD;
+ break;
+ case FLOW_MODE_SYMMETRIC:
+ ctrl3 |= PHY_B_P_SYM_MD;
+ break;
+ case FLOW_MODE_REM_SEND:
+ ctrl3 |= PHY_B_P_BOTH_MD;
+ break;
+ }
+
+ /* Restart Auto-negotiation */
+ ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
+ } else {
+ if (skge->duplex == DUPLEX_FULL)
+ ctrl1 |= PHY_CT_DUP_MD;
+
+ ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */
+ }
+
+ skge_xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2);
+ skge_xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3);
+
+ if (skge->netdev->mtu > ETH_DATA_LEN) {
+ ctrl4 |= PHY_B_PEC_HIGH_LA;
+ ctrl5 |= PHY_B_AC_LONG_PACK;
+
+ skge_xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5);
+ }
+
+ skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4);
+ skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1);
+ break;
+ }
+ spin_unlock_bh(&hw->phy_lock);
+
+ /* Clear MIB counters */
+ skge_xm_write16(hw, port, XM_STAT_CMD,
+ XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+ /* Clear two times according to Errata #3 */
+ skge_xm_write16(hw, port, XM_STAT_CMD,
+ XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+
+ /* Start polling for link status */
+ mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
}
static void genesis_stop(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
int port = skge->port;
- u32 reg;
/* Clear Tx packet arbiter timeout IRQ */
skge_write16(hw, B3_PA_CTRL,
@@ -1340,30 +1304,33 @@ static void genesis_stop(struct skge_port *skge)
* If the transfer stucks at the MAC the STOP command will not
* terminate if we don't flush the XMAC's transmit FIFO !
*/
- xm_write32(hw, port, XM_MODE,
- xm_read32(hw, port, XM_MODE)|XM_MD_FTF);
+ skge_xm_write32(hw, port, XM_MODE,
+ skge_xm_read32(hw, port, XM_MODE)|XM_MD_FTF);
/* Reset the MAC */
- skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+ skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
/* For external PHYs there must be special handling */
- reg = skge_read32(hw, B2_GP_IO);
- if (port == 0) {
- reg |= GP_DIR_0;
- reg &= ~GP_IO_0;
- } else {
- reg |= GP_DIR_2;
- reg &= ~GP_IO_2;
+ if (hw->phy_type != SK_PHY_XMAC) {
+ u32 reg = skge_read32(hw, B2_GP_IO);
+
+ if (port == 0) {
+ reg |= GP_DIR_0;
+ reg &= ~GP_IO_0;
+ } else {
+ reg |= GP_DIR_2;
+ reg &= ~GP_IO_2;
+ }
+ skge_write32(hw, B2_GP_IO, reg);
+ skge_read32(hw, B2_GP_IO);
}
- skge_write32(hw, B2_GP_IO, reg);
- skge_read32(hw, B2_GP_IO);
- xm_write16(hw, port, XM_MMU_CMD,
- xm_read16(hw, port, XM_MMU_CMD)
+ skge_xm_write16(hw, port, XM_MMU_CMD,
+ skge_xm_read16(hw, port, XM_MMU_CMD)
& ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
- xm_read16(hw, port, XM_MMU_CMD);
+ skge_xm_read16(hw, port, XM_MMU_CMD);
}
@@ -1374,11 +1341,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
int i;
unsigned long timeout = jiffies + HZ;
- xm_write16(hw, port,
+ skge_xm_write16(hw, port,
XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
/* wait for update to complete */
- while (xm_read16(hw, port, XM_STAT_CMD)
+ while (skge_xm_read16(hw, port, XM_STAT_CMD)
& (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) {
if (time_after(jiffies, timeout))
break;
@@ -1386,60 +1353,68 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
}
/* special case for 64 bit octet counter */
- data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32
- | xm_read32(hw, port, XM_TXO_OK_LO);
- data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32
- | xm_read32(hw, port, XM_RXO_OK_LO);
+ data[0] = (u64) skge_xm_read32(hw, port, XM_TXO_OK_HI) << 32
+ | skge_xm_read32(hw, port, XM_TXO_OK_LO);
+ data[1] = (u64) skge_xm_read32(hw, port, XM_RXO_OK_HI) << 32
+ | skge_xm_read32(hw, port, XM_RXO_OK_LO);
for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
- data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset);
+ data[i] = skge_xm_read32(hw, port, skge_stats[i].xmac_offset);
}
static void genesis_mac_intr(struct skge_hw *hw, int port)
{
struct skge_port *skge = netdev_priv(hw->dev[port]);
- u16 status = xm_read16(hw, port, XM_ISRC);
-
- if (netif_msg_intr(skge))
- printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
- skge->netdev->name, status);
+ u16 status = skge_xm_read16(hw, port, XM_ISRC);
+
+ pr_debug("genesis_intr status %x\n", status);
+ if (hw->phy_type == SK_PHY_XMAC) {
+ /* LInk down, start polling for state change */
+ if (status & XM_IS_INP_ASS) {
+ skge_xm_write16(hw, port, XM_IMSK,
+ skge_xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS);
+ mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
+ }
+ else if (status & XM_IS_AND)
+ mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
+ }
if (status & XM_IS_TXF_UR) {
- xm_write32(hw, port, XM_MODE, XM_MD_FTF);
+ skge_xm_write32(hw, port, XM_MODE, XM_MD_FTF);
++skge->net_stats.tx_fifo_errors;
}
if (status & XM_IS_RXF_OV) {
- xm_write32(hw, port, XM_MODE, XM_MD_FRF);
+ skge_xm_write32(hw, port, XM_MODE, XM_MD_FRF);
++skge->net_stats.rx_fifo_errors;
}
}
-static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
{
int i;
- gma_write16(hw, port, GM_SMI_DATA, val);
- gma_write16(hw, port, GM_SMI_CTRL,
+ skge_gma_write16(hw, port, GM_SMI_DATA, val);
+ skge_gma_write16(hw, port, GM_SMI_CTRL,
GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
- if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+ if (!(skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
break;
}
}
-static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
+static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg)
{
int i;
- gma_write16(hw, port, GM_SMI_CTRL,
+ skge_gma_write16(hw, port, GM_SMI_CTRL,
GM_SMI_CT_PHY_AD(hw->phy_addr)
| GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
for (i = 0; i < PHY_RETRIES; i++) {
udelay(1);
- if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
+ if (skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
goto ready;
}
@@ -1447,7 +1422,24 @@ static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
hw->dev[port]->name);
return 0;
ready:
- return gma_read16(hw, port, GM_SMI_DATA);
+ return skge_gma_read16(hw, port, GM_SMI_DATA);
+}
+
+static void genesis_link_down(struct skge_port *skge)
+{
+ struct skge_hw *hw = skge->hw;
+ int port = skge->port;
+
+ pr_debug("genesis_link_down\n");
+
+ skge_xm_write16(hw, port, XM_MMU_CMD,
+ skge_xm_read16(hw, port, XM_MMU_CMD)
+ & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
+
+ /* dummy read to ensure writing */
+ (void) skge_xm_read16(hw, port, XM_MMU_CMD);
+
+ skge_link_down(skge);
}
static void genesis_link_up(struct skge_port *skge)
@@ -1458,7 +1450,7 @@ static void genesis_link_up(struct skge_port *skge)
u32 mode, msk;
pr_debug("genesis_link_up\n");
- cmd = xm_read16(hw, port, XM_MMU_CMD);
+ cmd = skge_xm_read16(hw, port, XM_MMU_CMD);
/*
* enabling pause frame reception is required for 1000BT
@@ -1466,15 +1458,14 @@ static void genesis_link_up(struct skge_port *skge)
*/
if (skge->flow_control == FLOW_MODE_NONE ||
skge->flow_control == FLOW_MODE_LOC_SEND)
- /* Disable Pause Frame Reception */
cmd |= XM_MMU_IGN_PF;
else
/* Enable Pause Frame Reception */
cmd &= ~XM_MMU_IGN_PF;
- xm_write16(hw, port, XM_MMU_CMD, cmd);
+ skge_xm_write16(hw, port, XM_MMU_CMD, cmd);
- mode = xm_read32(hw, port, XM_MODE);
+ mode = skge_xm_read32(hw, port, XM_MODE);
if (skge->flow_control == FLOW_MODE_SYMMETRIC ||
skge->flow_control == FLOW_MODE_LOC_SEND) {
/*
@@ -1488,10 +1479,10 @@ static void genesis_link_up(struct skge_port *skge)
/* XM_PAUSE_DA = '010000C28001' (default) */
/* XM_MAC_PTIME = 0xffff (maximum) */
/* remember this value is defined in big endian (!) */
- xm_write16(hw, port, XM_MAC_PTIME, 0xffff);
+ skge_xm_write16(hw, port, XM_MAC_PTIME, 0xffff);
mode |= XM_PAUSE_MODE;
- skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
+ skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
} else {
/*
* disable pause frame generation is required for 1000BT
@@ -1500,68 +1491,125 @@ static void genesis_link_up(struct skge_port *skge)
/* Disable Pause Mode in Mode Register */
mode &= ~XM_PAUSE_MODE;
- skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
+ skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
}
- xm_write32(hw, port, XM_MODE, mode);
+ skge_xm_write32(hw, port, XM_MODE, mode);
msk = XM_DEF_MSK;
- /* disable GP0 interrupt bit for external Phy */
- msk |= XM_IS_INP_ASS;
+ if (hw->phy_type != SK_PHY_XMAC)
+ msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */
- xm_write16(hw, port, XM_IMSK, msk);
- xm_read16(hw, port, XM_ISRC);
+ skge_xm_write16(hw, port, XM_IMSK, msk);
+ skge_xm_read16(hw, port, XM_ISRC);
/* get MMU Command Reg. */
- cmd = xm_read16(hw, port, XM_MMU_CMD);
- if (skge->duplex == DUPLEX_FULL)
+ cmd = skge_xm_read16(hw, port, XM_MMU_CMD);
+ if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
cmd |= XM_MMU_GMII_FD;
- /*
- * Workaround BCOM Errata (#10523) for all BCom Phys
- * Enable Power Management after link up
- */
- xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
- xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
- & ~PHY_B_AC_DIS_PM);
- xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+ if (hw->phy_type == SK_PHY_BCOM) {
+ /*
+ * Workaround BCOM Errata (#10523) for all BCom Phys
+ * Enable Power Management after link up
+ */
+ skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
+ skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
+ & ~PHY_B_AC_DIS_PM);
+ skge_xm_phy_write(hw, port, PHY_BCOM_INT_MASK,
+ PHY_B_DEF_MSK);
+ }
/* enable Rx/Tx */
- xm_write16(hw, port, XM_MMU_CMD,
+ skge_xm_write16(hw, port, XM_MMU_CMD,
cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
skge_link_up(skge);
}
-static inline void bcom_phy_intr(struct skge_port *skge)
+static void genesis_bcom_intr(struct skge_port *skge)
{
struct skge_hw *hw = skge->hw;
int port = skge->port;
- u16 isrc;
-
- isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
- if (netif_msg_intr(skge))
- printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n",
- skge->netdev->name, isrc);
+ u16 stat = skge_xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
- if (isrc & PHY_B_IS_PSE)
- printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n",
- hw->dev[port]->name);
+ pr_debug("genesis_bcom intr stat=%x\n", stat);
/* Workaround BCom Errata:
* enable and disable loopback mode if "NO HCD" occurs.
*/
- if (isrc & PHY_B_IS_NO_HDCL) {
- u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL);
- xm_phy_write(hw, port, PHY_BCOM_CTRL,
+ if (stat & PHY_B_IS_NO_HDCL) {
+ u16 ctrl = skge_xm_phy_read(hw, port, PHY_BCOM_CTRL);
+ skge_xm_phy_write(hw, port, PHY_BCOM_CTRL,
ctrl | PHY_CT_LOOP);
- xm_phy_write(hw, port, PHY_BCOM_CTRL,
+ skge_xm_phy_write(hw, port, PHY_BCOM_CTRL,
ctrl & ~PHY_CT_LOOP);
}
- if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
- bcom_check_link(hw, port);
+ stat = skge_xm_phy_read(hw, port, PHY_BCOM_STAT);
+ if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) {
+ u16 aux = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
+ if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev))
+ genesis_link_down(skge);
+
+ else if (stat & PHY_B_IS_LST_CHANGE) {
+ if (aux & PHY_B_AS_AN_C) {
+ switch (aux & PHY_B_AS_AN_RES_MSK) {
+ case PHY_B_RES_1000FD:
+ skge->duplex = DUPLEX_FULL;
+ break;
+ case PHY_B_RES_1000HD:
+ skge->duplex = DUPLEX_HALF;
+ break;
+ }
+
+ switch (aux & PHY_B_AS_PAUSE_MSK) {
+ case PHY_B_AS_PAUSE_MSK:
+ skge->flow_control = FLOW_MODE_SYMMETRIC;
+ break;
+ case PHY_B_AS_PRR:
+ skge->flow_control = FLOW_MODE_REM_SEND;
+ break;
+ case PHY_B_AS_PRT:
+ skge->flow_control = FLOW_MODE_LOC_SEND;
+ break;
+ default:
+ skge->flow_control = FLOW_MODE_NONE;
+ }
+ skge->speed = SPEED_1000;
+ }
+ genesis_link_up(skge);
+ }
+ else
+ mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
+ }
+}
+/* Perodic poll of phy status to check for link transistion */
+static void skge_link_timer(unsigned long __arg)
+{
+ struct skge_port *skge = (struct skge_port *) __arg;
+ struct skge_hw *hw = skge->hw;
+ int port = skge->port;
+
+ if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev))
+ return;
+
+ spin_lock_bh(&hw->phy_lock);
+ if (hw->phy_type == SK_PHY_BCOM)
+ genesis_bcom_intr(skge);
+ else {
+ int i;
+ for (i = 0; i < 3; i++)
+ if (skge_xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)
+ break;
+
+ if (i == 3)
+ mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
+ else
+ genesis_link_up(skge);
+ }
+ spin_unlock_bh(&hw->phy_lock);
}
/* Marvell Phy Initailization */
@@ -1573,27 +1621,31 @@ static void yukon_init(struct skge_hw *hw, int port)
pr_debug("yukon_init\n");
if (skge->autoneg == AUTONEG_ENABLE) {
- u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+ u16 ectrl = skge_gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
PHY_M_EC_MAC_S_MSK);
ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
- ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
+ /* on PHY 88E1111 there is a change for downshift control */
+ if (hw->chip_id == CHIP_ID_YUKON_EC)
+ ectrl |= PHY_M_EC_M_DSC_2(0) | PHY_M_EC_DOWN_S_ENA;
+ else
+ ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
- gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+ skge_gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
}
- ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+ ctrl = skge_gm_phy_read(hw, port, PHY_MARV_CTRL);
if (skge->autoneg == AUTONEG_DISABLE)
ctrl &= ~PHY_CT_ANE;
ctrl |= PHY_CT_RESET;
- gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+ skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
ctrl = 0;
ct1000 = 0;
- adv = PHY_AN_CSMA;
+ adv = PHY_SEL_TYPE;
if (skge->autoneg == AUTONEG_ENABLE) {
if (iscopper(hw)) {
@@ -1609,12 +1661,41 @@ static void yukon_init(struct skge_hw *hw, int port)
adv |= PHY_M_AN_10_FD;
if (skge->advertising & ADVERTISED_10baseT_Half)
adv |= PHY_M_AN_10_HD;
- } else /* special defines for FIBER (88E1011S only) */
- adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
- /* Set Flow-control capabilities */
- adv |= phy_pause_map[skge->flow_control];
+ /* Set Flow-control capabilities */
+ switch (skge->flow_control) {
+ case FLOW_MODE_NONE:
+ adv |= PHY_B_P_NO_PAUSE;
+ break;
+ case FLOW_MODE_LOC_SEND:
+ adv |= PHY_B_P_ASYM_MD;
+ break;
+ case FLOW_MODE_SYMMETRIC:
+ adv |= PHY_B_P_SYM_MD;
+ break;
+ case FLOW_MODE_REM_SEND:
+ adv |= PHY_B_P_BOTH_MD;
+ break;
+ }
+ } else { /* special defines for FIBER (88E1011S only) */
+ adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
+ /* Set Flow-control capabilities */
+ switch (skge->flow_control) {
+ case FLOW_MODE_NONE:
+ adv |= PHY_M_P_NO_PAUSE_X;
+ break;
+ case FLOW_MODE_LOC_SEND:
+ adv |= PHY_M_P_ASYM_MD_X;
+ break;
+ case FLOW_MODE_SYMMETRIC:
+ adv |= PHY_M_P_SYM_MD_X;
+ break;
+ case FLOW_MODE_REM_SEND:
+ adv |= PHY_M_P_BOTH_MD_X;
+ break;
+ }
+ }
/* Restart Auto-negotiation */
ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
} else {
@@ -1636,23 +1717,36 @@ static void yukon_init(struct skge_hw *hw, int port)
ctrl |= PHY_CT_RESET;
}
- gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+ if (hw->chip_id != CHIP_ID_YUKON_FE)
+ skge_gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
- gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
- gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+ skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+ skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
/* Setup Phy LED's */
ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
ledover = 0;
- ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+ if (hw->chip_id == CHIP_ID_YUKON_FE) {
+ /* on 88E3082 these bits are at 11..9 (shifted left) */
+ ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+
+ skge_gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR,
+ ((skge_gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR)
+
+ & ~PHY_M_FELP_LED1_MSK)
+ | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL)));
+ } else {
+ /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
+ ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
- /* turn off the Rx LED (LED_RX) */
- ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+ /* turn off the Rx LED (LED_RX) */
+ ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+ }
/* disable blink mode (LED_DUPLEX) on collisions */
ctrl |= PHY_M_LEDC_DP_CTRL;
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+ skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) {
/* turn on 100 Mbps LED (LED_LINK100) */
@@ -1660,25 +1754,25 @@ static void yukon_init(struct skge_hw *hw, int port)
}
if (ledover)
- gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+ skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
/* Enable phy interrupt on autonegotiation complete (or link up) */
if (skge->autoneg == AUTONEG_ENABLE)
- gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
+ skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
else
- gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+ skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
}
static void yukon_reset(struct skge_hw *hw, int port)
{
- gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
- gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */
- gma_write16(hw, port, GM_MC_ADDR_H2, 0);
- gma_write16(hw, port, GM_MC_ADDR_H3, 0);
- gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+ skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
+ skge_gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */
+ skge_gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+ skge_gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+ skge_gma_write16(hw, port, GM_MC_ADDR_H4, 0);
- gma_write16(hw, port, GM_RX_CTRL,
- gma_read16(hw, port, GM_RX_CTRL)
+ skge_gma_write16(hw, port, GM_RX_CTRL,
+ skge_gma_read16(hw, port, GM_RX_CTRL)
| GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
}
@@ -1691,17 +1785,17 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
/* WA code for COMA mode -- set PHY reset */
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev == CHIP_REV_YU_LITE_A3)
+ chip_rev(hw) == CHIP_REV_YU_LITE_A3)
skge_write32(hw, B2_GP_IO,
(skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
/* hard reset */
- skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
- skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+ skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), GPC_RST_SET);
+ skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_RST_SET);
/* WA code for COMA mode -- clear PHY reset */
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev == CHIP_REV_YU_LITE_A3)
+ chip_rev(hw) == CHIP_REV_YU_LITE_A3)
skge_write32(hw, B2_GP_IO,
(skge_read32(hw, B2_GP_IO) | GP_DIR_9)
& ~GP_IO_9);
@@ -1712,13 +1806,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB;
/* Clear GMC reset */
- skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
- skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
- skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+ skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
+ skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
+ skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
if (skge->autoneg == AUTONEG_DISABLE) {
reg = GM_GPCR_AU_ALL_DIS;
- gma_write16(hw, port, GM_GP_CTRL,
- gma_read16(hw, port, GM_GP_CTRL) | reg);
+ skge_gma_write16(hw, port, GM_GP_CTRL,
+ skge_gma_read16(hw, port, GM_GP_CTRL) | reg);
switch (skge->speed) {
case SPEED_1000:
@@ -1734,7 +1828,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
switch (skge->flow_control) {
case FLOW_MODE_NONE:
- skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+ skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
break;
case FLOW_MODE_LOC_SEND:
@@ -1742,7 +1836,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
}
- gma_write16(hw, port, GM_GP_CTRL, reg);
+ skge_gma_write16(hw, port, GM_GP_CTRL, reg);
skge_read16(hw, GMAC_IRQ_SRC);
spin_lock_bh(&hw->phy_lock);
@@ -1750,25 +1844,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
spin_unlock_bh(&hw->phy_lock);
/* MIB clear */
- reg = gma_read16(hw, port, GM_PHY_ADDR);
- gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+ reg = skge_gma_read16(hw, port, GM_PHY_ADDR);
+ skge_gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
for (i = 0; i < GM_MIB_CNT_SIZE; i++)
- gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
- gma_write16(hw, port, GM_PHY_ADDR, reg);
+ skge_gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
+ skge_gma_write16(hw, port, GM_PHY_ADDR, reg);
/* transmit control */
- gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+ skge_gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
/* receive control reg: unicast + multicast + no FCS */
- gma_write16(hw, port, GM_RX_CTRL,
+ skge_gma_write16(hw, port, GM_RX_CTRL,
GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
/* transmit flow control */
- gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+ skge_gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
/* transmit parameter */
- gma_write16(hw, port, GM_TX_PARAM,
+ skge_gma_write16(hw, port, GM_TX_PARAM,
TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
TX_IPG_JAM_DATA(TX_IPG_JAM_DEF));
@@ -1778,33 +1872,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
if (hw->dev[port]->mtu > 1500)
reg |= GM_SMOD_JUMBO_ENA;
- gma_write16(hw, port, GM_SERIAL_MODE, reg);
+ skge_gma_write16(hw, port, GM_SERIAL_MODE, reg);
/* physical address: used for pause frames */
- gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+ skge_gm_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
/* virtual address for data */
- gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+ skge_gm_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
/* enable interrupt mask for counter overflows */
- gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
- gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
- gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+ skge_gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+ skge_gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+ skge_gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
/* Initialize Mac Fifo */
/* Configure Rx MAC FIFO */
- skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
+ skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev == CHIP_REV_YU_LITE_A3)
+ chip_rev(hw) == CHIP_REV_YU_LITE_A3)
reg &= ~GMF_RX_F_FL_ON;
- skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
- skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
- skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+ skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+ skge_write16(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), reg);
+ skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
/* Configure Tx MAC FIFO */
- skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
- skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+ skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+ skge_write16(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
}
static void yukon_stop(struct skge_port *skge)
@@ -1813,19 +1907,19 @@ static void yukon_stop(struct skge_port *skge)
int port = skge->port;
if (hw->chip_id == CHIP_ID_YUKON_LITE &&
- hw->chip_rev == CHIP_REV_YU_LITE_A3) {
+ chip_rev(hw) == CHIP_REV_YU_LITE_A3) {
skge_write32(hw, B2_GP_IO,
skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
}
- gma_write16(hw, port, GM_GP_CTRL,
- gma_read16(hw, port, GM_GP_CTRL)
+ skge_gma_write16(hw, port, GM_GP_CTRL,
+ skge_gma_read16(hw, port, GM_GP_CTRL)
& ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA));
- gma_read16(hw, port, GM_GP_CTRL);
+ skge_gma_read16(hw, port, GM_GP_CTRL);
/* set GPHY Control reset */
- gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET);
- gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET);
+ skge_gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET);
+ skge_gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET);
}
static void yukon_get_stats(struct skge_port *skge, u64 *data)
@@ -1834,40 +1928,39 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data)
int port = skge->port;
int i;
- data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
- | gma_read32(hw, port, GM_TXO_OK_LO);
- data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
- | gma_read32(hw, port, GM_RXO_OK_LO);
+ data[0] = (u64) skge_gma_read32(hw, port, GM_TXO_OK_HI) << 32
+ | skge_gma_read32(hw, port, GM_TXO_OK_LO);
+ data[1] = (u64) skge_gma_read32(hw, port, GM_RXO_OK_HI) << 32
+ | skge_gma_read32(hw, port, GM_RXO_OK_LO);
for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
- data[i] = gma_read32(hw, port,
+ data[i] = skge_gma_read32(hw, port,
skge_stats[i].gma_offset);
}
static void yukon_mac_intr(struct skge_hw *hw, int port)
{
- struct net_device *dev = hw->dev[port];
- struct skge_port *skge = netdev_priv(dev);
- u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
-
- if (netif_msg_intr(skge))
- printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
- dev->name, status);
+ struct skge_port *skge = netdev_priv(hw->dev[port]);
+ u8 status = skge_read8(hw, SKGEMAC_REG(port, GMAC_IRQ_SRC));
+ pr_debug("yukon_intr status %x\n", status);
if (status & GM_IS_RX_FF_OR) {
++skge->net_stats.rx_fifo_errors;
- gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO);
+ skge_gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO);
}
if (status & GM_IS_TX_FF_UR) {
++skge->net_stats.tx_fifo_errors;
- gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU);
+ skge_gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU);
}
}
static u16 yukon_speed(const struct skge_hw *hw, u16 aux)
{
- switch (aux & PHY_M_PS_SPEED_MSK) {
+ if (hw->chip_id == CHIP_ID_YUKON_FE)
+ return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
+
+ switch(aux & PHY_M_PS_SPEED_MSK) {
case PHY_M_PS_SPEED_1000:
return SPEED_1000;
case PHY_M_PS_SPEED_100:
@@ -1888,15 +1981,15 @@ static void yukon_link_up(struct skge_port *skge)
/* Enable Transmit FIFO Underrun */
skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
- reg = gma_read16(hw, port, GM_GP_CTRL);
+ reg = skge_gma_read16(hw, port, GM_GP_CTRL);
if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
reg |= GM_GPCR_DUP_FULL;
/* enable Rx/Tx */
reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
- gma_write16(hw, port, GM_GP_CTRL, reg);
+ skge_gma_write16(hw, port, GM_GP_CTRL, reg);
- gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+ skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
skge_link_up(skge);
}
@@ -1906,15 +1999,16 @@ static void yukon_link_down(struct skge_port *skge)
int port = skge->port;
pr_debug("yukon_link_down\n");
- gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
- gm_phy_write(hw, port, GM_GP_CTRL,
- gm_phy_read(hw, port, GM_GP_CTRL)
+ skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+ skge_gm_phy_write(hw, port, GM_GP_CTRL,
+ skge_gm_phy_read(hw, port, GM_GP_CTRL)
& ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA));
- if (skge->flow_control == FLOW_MODE_REM_SEND) {
+ if (hw->chip_id != CHIP_ID_YUKON_FE &&
+ skge->flow_control == FLOW_MODE_REM_SEND) {
/* restore Asymmetric Pause bit */
- gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
- gm_phy_read(hw, port,
+ skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+ skge_gm_phy_read(hw, port,
PHY_MARV_AUNE_ADV)
| PHY_M_AN_ASP);
@@ -1933,21 +2027,20 @@ static void yukon_phy_intr(struct skge_port *skge)
const char *reason = NULL;
u16 istatus, phystat;
- istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
- phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
-
- if (netif_msg_intr(skge))
- printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n",
- skge->netdev->name, istatus, phystat);
+ istatus = skge_gm_phy_read(hw, port, PHY_MARV_INT_STAT);
+ phystat = skge_gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
+ pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat);
if (istatus & PHY_M_IS_AN_COMPL) {
- if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
+ if (skge_gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
& PHY_M_AN_RF) {
reason = "remote fault";
goto failed;
}
- if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
+ if (!(hw->chip_id == CHIP_ID_YUKON_FE || hw->chip_id == CHIP_ID_YUKON_EC)
+ && (skge_gm_phy_read(hw, port, PHY_MARV_1000T_STAT)
+ & PHY_B_1000S_MSF)) {
reason = "master/slave fault";
goto failed;
}
@@ -1961,6 +2054,10 @@ static void yukon_phy_intr(struct skge_port *skge)
? DUPLEX_FULL : DUPLEX_HALF;
skge->speed = yukon_speed(hw, phystat);
+ /* Tx & Rx Pause Enabled bits are at 9..8 */
+ if (hw->chip_id == CHIP_ID_YUKON_XL)
+ phystat >>= 6;
+
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
switch (phystat & PHY_M_PS_PAUSE_MSK) {
case PHY_M_PS_PAUSE_MSK:
@@ -1978,9 +2075,9 @@ static void yukon_phy_intr(struct skge_port *skge)
if (skge->flow_control == FLOW_MODE_NONE ||
(skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF))
- skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+ skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
else
- skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+ skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
yukon_link_up(skge);
return;
}
@@ -2064,12 +2161,6 @@ static int skge_up(struct net_device *dev)
if (netif_msg_ifup(skge))
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
- if (dev->mtu > RX_BUF_SIZE)
- skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN;
- else
- skge->rx_buf_size = RX_BUF_SIZE;
-
-
rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc);
tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc);
skge->mem_size = tx_size + rx_size;
@@ -2082,8 +2173,7 @@ static int skge_up(struct net_device *dev)
if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma)))
goto free_pci_mem;
- err = skge_rx_fill(skge);
- if (err)
+ if (skge_rx_fill(skge))
goto free_rx_ring;
if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size,
@@ -2092,10 +2182,6 @@ static int skge_up(struct net_device *dev)
skge->tx_avail = skge->tx_ring.count - 1;
- /* Enable IRQ from port */
- hw->intr_mask |= portirqmask[port];
- skge_write32(hw, B0_IMSK, hw->intr_mask);
-
/* Initialze MAC */
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_mac_init(hw, port);
@@ -2103,7 +2189,7 @@ static int skge_up(struct net_device *dev)
yukon_mac_init(hw, port);
/* Configure RAMbuffers */
- chunk = hw->ram_size / ((hw->ports + 1)*2);
+ chunk = hw->ram_size / (isdualport(hw) ? 4 : 2);
ram_addr = hw->ram_offset + 2 * chunk * port;
skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
@@ -2141,6 +2227,7 @@ static int skge_down(struct net_device *dev)
netif_stop_queue(dev);
del_timer_sync(&skge->led_blink);
+ del_timer_sync(&skge->link_check);
/* Stop transmitter */
skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
@@ -2153,12 +2240,12 @@ static int skge_down(struct net_device *dev)
yukon_stop(skge);
/* Disable Force Sync bit and Enable Alloc bit */
- skge_write8(hw, SK_REG(port, TXA_CTRL),
+ skge_write8(hw, SKGEMAC_REG(port, TXA_CTRL),
TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
/* Stop Interval Timer and Limit Counter of Tx Arbiter */
- skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
- skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+ skge_write32(hw, SKGEMAC_REG(port, TXA_ITI_INI), 0L);
+ skge_write32(hw, SKGEMAC_REG(port, TXA_LIM_INI), 0L);
/* Reset PCI FIFO */
skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET);
@@ -2173,13 +2260,13 @@ static int skge_down(struct net_device *dev)
skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
if (hw->chip_id == CHIP_ID_GENESIS) {
- skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
- skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
- skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP);
- skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP);
+ skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
+ skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
+ skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_STOP);
+ skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_STOP);
} else {
- skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
- skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+ skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+ skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
}
/* turn off led's */
@@ -2212,10 +2299,10 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
local_irq_save(flags);
if (!spin_trylock(&skge->tx_lock)) {
- /* Collision - tell upper layer to requeue */
- local_irq_restore(flags);
- return NETDEV_TX_LOCKED;
- }
+ /* Collision - tell upper layer to requeue */
+ local_irq_restore(flags);
+ return NETDEV_TX_LOCKED;
+ }
if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) {
netif_stop_queue(dev);
@@ -2246,7 +2333,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
* does. Looks like hardware is wrong?
*/
if (ip->protocol == IPPROTO_UDP
- && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
+ && chip_rev(hw) == 0 && hw->chip_id == CHIP_ID_YUKON)
control = BMU_TCP_CHECK;
else
control = BMU_UDP_CHECK;
@@ -2307,7 +2394,6 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e)
{
- /* This ring element can be skb or fragment */
if (e->skb) {
pci_unmap_single(hw->pdev,
pci_unmap_addr(e, mapaddr),
@@ -2352,17 +2438,16 @@ static void skge_tx_timeout(struct net_device *dev)
static int skge_change_mtu(struct net_device *dev, int new_mtu)
{
int err = 0;
- int running = netif_running(dev);
- if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+ if(new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
+ dev->mtu = new_mtu;
- if (running)
+ if (netif_running(dev)) {
skge_down(dev);
- dev->mtu = new_mtu;
- if (running)
skge_up(dev);
+ }
return err;
}
@@ -2377,9 +2462,7 @@ static void genesis_set_multicast(struct net_device *dev)
u32 mode;
u8 filter[8];
- pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
-
- mode = xm_read32(hw, port, XM_MODE);
+ mode = skge_xm_read32(hw, port, XM_MODE);
mode |= XM_MD_ENA_HASH;
if (dev->flags & IFF_PROMISC)
mode |= XM_MD_ENA_PROM;
@@ -2390,16 +2473,17 @@ static void genesis_set_multicast(struct net_device *dev)
memset(filter, 0xff, sizeof(filter));
else {
memset(filter, 0, sizeof(filter));
- for (i = 0; list && i < count; i++, list = list->next) {
- u32 crc, bit;
- crc = ether_crc_le(ETH_ALEN, list->dmi_addr);
- bit = ~crc & 0x3f;
+ for(i = 0; list && i < count; i++, list = list->next) {
+ u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN);
+ u8 bit = 63 - (crc & 63);
+
filter[bit/8] |= 1 << (bit%8);
}
}
- xm_write32(hw, port, XM_MODE, mode);
- xm_outhash(hw, port, XM_HSM, filter);
+ skge_xm_outhash(hw, port, XM_HSM, filter);
+
+ skge_xm_write32(hw, port, XM_MODE, mode);
}
static void yukon_set_multicast(struct net_device *dev)
@@ -2413,7 +2497,7 @@ static void yukon_set_multicast(struct net_device *dev)
memset(filter, 0, sizeof(filter));
- reg = gma_read16(hw, port, GM_RX_CTRL);
+ reg = skge_gma_read16(hw, port, GM_RX_CTRL);
reg |= GM_RXCR_UCF_ENA;
if (dev->flags & IFF_PROMISC) /* promiscious */
@@ -2426,23 +2510,23 @@ static void yukon_set_multicast(struct net_device *dev)
int i;
reg |= GM_RXCR_MCF_ENA;
- for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
+ for(i = 0; list && i < dev->mc_count; i++, list = list->next) {
u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
filter[bit/8] |= 1 << (bit%8);
}
}
- gma_write16(hw, port, GM_MC_ADDR_H1,
+ skge_gma_write16(hw, port, GM_MC_ADDR_H1,
(u16)filter[0] | ((u16)filter[1] << 8));
- gma_write16(hw, port, GM_MC_ADDR_H2,
+ skge_gma_write16(hw, port, GM_MC_ADDR_H2,
(u16)filter[2] | ((u16)filter[3] << 8));
- gma_write16(hw, port, GM_MC_ADDR_H3,
+ skge_gma_write16(hw, port, GM_MC_ADDR_H3,
(u16)filter[4] | ((u16)filter[5] << 8));
- gma_write16(hw, port, GM_MC_ADDR_H4,
+ skge_gma_write16(hw, port, GM_MC_ADDR_H4,
(u16)filter[6] | ((u16)filter[7] << 8));
- gma_write16(hw, port, GM_RX_CTRL, reg);
+ skge_gma_write16(hw, port, GM_RX_CTRL, reg);
}
static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
@@ -2461,76 +2545,28 @@ static void skge_rx_error(struct skge_port *skge, int slot,
printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n",
skge->netdev->name, slot, control, status);
- if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF))
+ if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
+ || (control & BMU_BBC) > skge->netdev->mtu + VLAN_ETH_HLEN)
skge->net_stats.rx_length_errors++;
- else if (skge->hw->chip_id == CHIP_ID_GENESIS) {
- if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
- skge->net_stats.rx_length_errors++;
- if (status & XMR_FS_FRA_ERR)
- skge->net_stats.rx_frame_errors++;
- if (status & XMR_FS_FCS_ERR)
- skge->net_stats.rx_crc_errors++;
- } else {
- if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
- skge->net_stats.rx_length_errors++;
- if (status & GMR_FS_FRAGMENT)
- skge->net_stats.rx_frame_errors++;
- if (status & GMR_FS_CRC_ERR)
- skge->net_stats.rx_crc_errors++;
- }
-}
-
-/* Get receive buffer from descriptor.
- * Handles copy of small buffers and reallocation failures
- */
-static inline struct sk_buff *skge_rx_get(struct skge_port *skge,
- struct skge_element *e,
- unsigned int len)
-{
- struct sk_buff *nskb, *skb;
-
- if (len < RX_COPY_THRESHOLD) {
- nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN);
- if (unlikely(!nskb))
- return NULL;
-
- pci_dma_sync_single_for_cpu(skge->hw->pdev,
- pci_unmap_addr(e, mapaddr),
- len, PCI_DMA_FROMDEVICE);
- memcpy(nskb->data, e->skb->data, len);
- pci_dma_sync_single_for_device(skge->hw->pdev,
- pci_unmap_addr(e, mapaddr),
- len, PCI_DMA_FROMDEVICE);
-
- if (skge->rx_csum) {
- struct skge_rx_desc *rd = e->desc;
- nskb->csum = le16_to_cpu(rd->csum2);
- nskb->ip_summed = CHECKSUM_HW;
- }
- skge_rx_reuse(e, skge->rx_buf_size);
- return nskb;
- } else {
- nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size);
- if (unlikely(!nskb))
- return NULL;
-
- pci_unmap_single(skge->hw->pdev,
- pci_unmap_addr(e, mapaddr),
- pci_unmap_len(e, maplen),
- PCI_DMA_FROMDEVICE);
- skb = e->skb;
- if (skge->rx_csum) {
- struct skge_rx_desc *rd = e->desc;
- skb->csum = le16_to_cpu(rd->csum2);
- skb->ip_summed = CHECKSUM_HW;
+ else {
+ if (skge->hw->chip_id == CHIP_ID_GENESIS) {
+ if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
+ skge->net_stats.rx_length_errors++;
+ if (status & XMR_FS_FRA_ERR)
+ skge->net_stats.rx_frame_errors++;
+ if (status & XMR_FS_FCS_ERR)
+ skge->net_stats.rx_crc_errors++;
+ } else {
+ if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
+ skge->net_stats.rx_length_errors++;
+ if (status & GMR_FS_FRAGMENT)
+ skge->net_stats.rx_frame_errors++;
+ if (status & GMR_FS_CRC_ERR)
+ skge->net_stats.rx_crc_errors++;
}
-
- skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
- return skb;
}
}
-
static int skge_poll(struct net_device *dev, int *budget)
{
struct skge_port *skge = netdev_priv(dev);
@@ -2539,12 +2575,13 @@ static int skge_poll(struct net_device *dev, int *budget)
struct skge_element *e;
unsigned int to_do = min(dev->quota, *budget);
unsigned int work_done = 0;
+ int done;
+ static const u32 irqmask[] = { IS_PORT_1, IS_PORT_2 };
- pr_debug("skge_poll\n");
-
- for (e = ring->to_clean; work_done < to_do; e = e->next) {
+ for (e = ring->to_clean; e != ring->to_use && work_done < to_do;
+ e = e->next) {
struct skge_rx_desc *rd = e->desc;
- struct sk_buff *skb;
+ struct sk_buff *skb = e->skb;
u32 control, len, status;
rmb();
@@ -2553,12 +2590,19 @@ static int skge_poll(struct net_device *dev, int *budget)
break;
len = control & BMU_BBC;
- status = rd->status;
+ e->skb = NULL;
+
+ pci_unmap_single(hw->pdev,
+ pci_unmap_addr(e, mapaddr),
+ pci_unmap_len(e, maplen),
+ PCI_DMA_FROMDEVICE);
- if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
- || bad_phy_status(hw, status))) {
+ status = rd->status;
+ if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
+ || len > dev->mtu + VLAN_ETH_HLEN
+ || bad_phy_status(hw, status)) {
skge_rx_error(skge, e - ring->start, control, status);
- skge_rx_reuse(e, skge->rx_buf_size);
+ dev_kfree_skb(skb);
continue;
}
@@ -2566,37 +2610,43 @@ static int skge_poll(struct net_device *dev, int *budget)
printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n",
dev->name, e - ring->start, rd->status, len);
- skb = skge_rx_get(skge, e, len);
- if (likely(skb)) {
- skb_put(skb, len);
- skb->protocol = eth_type_trans(skb, dev);
+ skb_put(skb, len);
+ skb->protocol = eth_type_trans(skb, dev);
- dev->last_rx = jiffies;
- netif_receive_skb(skb);
+ if (skge->rx_csum) {
+ skb->csum = le16_to_cpu(rd->csum2);
+ skb->ip_summed = CHECKSUM_HW;
+ }
- ++work_done;
- } else
- skge_rx_reuse(e, skge->rx_buf_size);
+ dev->last_rx = jiffies;
+ netif_receive_skb(skb);
+
+ ++work_done;
}
ring->to_clean = e;
+ *budget -= work_done;
+ dev->quota -= work_done;
+ done = work_done < to_do;
+
+ if (skge_rx_fill(skge))
+ done = 0;
+
/* restart receiver */
wmb();
skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR),
CSR_START | CSR_IRQ_CL_F);
- *budget -= work_done;
- dev->quota -= work_done;
-
- if (work_done >= to_do)
- return 1; /* not done */
+ if (done) {
+ local_irq_disable();
+ hw->intr_mask |= irqmask[skge->port];
+ /* Order is important since data can get interrupted */
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+ __netif_rx_complete(dev);
+ local_irq_enable();
+ }
- local_irq_disable();
- __netif_rx_complete(dev);
- hw->intr_mask |= portirqmask[skge->port];
- skge_write32(hw, B0_IMSK, hw->intr_mask);
- local_irq_enable();
- return 0;
+ return !done;
}
static inline void skge_tx_intr(struct net_device *dev)
@@ -2607,7 +2657,7 @@ static inline void skge_tx_intr(struct net_device *dev)
struct skge_element *e;
spin_lock(&skge->tx_lock);
- for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+ for(e = ring->to_clean; e != ring->to_use; e = e->next) {
struct skge_tx_desc *td = e->desc;
u32 control;
@@ -2640,12 +2690,12 @@ static void skge_mac_parity(struct skge_hw *hw, int port)
: (port == 0 ? "(port A)": "(port B"));
if (hw->chip_id == CHIP_ID_GENESIS)
- skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
+ skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1),
MFF_CLR_PERR);
else
/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
- skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T),
- (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
+ skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T),
+ (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0)
? GMF_CLI_TX_FC : GMF_CLI_TX_PE);
}
@@ -2653,16 +2703,16 @@ static void skge_pci_clear(struct skge_hw *hw)
{
u16 status;
- pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+ status = skge_read16(hw, SKGEPCI_REG(PCI_STATUS));
skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- pci_write_config_word(hw->pdev, PCI_STATUS,
- status | PCI_STATUS_ERROR_BITS);
+ skge_write16(hw, SKGEPCI_REG(PCI_STATUS),
+ status | PCI_STATUS_ERROR_BITS);
skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
static void skge_mac_intr(struct skge_hw *hw, int port)
{
- if (hw->chip_id == CHIP_ID_GENESIS)
+ if (hw->chip_id == CHIP_ID_GENESIS)
genesis_mac_intr(hw, port);
else
yukon_mac_intr(hw, port);
@@ -2676,9 +2726,9 @@ static void skge_error_irq(struct skge_hw *hw)
if (hw->chip_id == CHIP_ID_GENESIS) {
/* clear xmac errors */
if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
- skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+ skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
- skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
+ skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
} else {
/* Timestamp (unused) overflow */
if (hwstatus & IS_IRQ_TIST_OV)
@@ -2753,8 +2803,8 @@ static void skge_extirq(unsigned long data)
if (hw->chip_id != CHIP_ID_GENESIS)
yukon_phy_intr(skge);
- else
- bcom_phy_intr(skge);
+ else if (hw->phy_type == SK_PHY_BCOM)
+ genesis_bcom_intr(skge);
}
}
spin_unlock(&hw->phy_lock);
@@ -2774,14 +2824,19 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
status &= hw->intr_mask;
- if (status & IS_R1_F) {
+
+ if ((status & IS_R1_F) && netif_rx_schedule_prep(hw->dev[0])) {
+ status &= ~IS_R1_F;
hw->intr_mask &= ~IS_R1_F;
- netif_rx_schedule(hw->dev[0]);
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+ __netif_rx_schedule(hw->dev[0]);
}
- if (status & IS_R2_F) {
+ if ((status & IS_R2_F) && netif_rx_schedule_prep(hw->dev[1])) {
+ status &= ~IS_R2_F;
hw->intr_mask &= ~IS_R2_F;
- netif_rx_schedule(hw->dev[1]);
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+ __netif_rx_schedule(hw->dev[1]);
}
if (status & IS_XA1_F)
@@ -2790,27 +2845,9 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
if (status & IS_XA2_F)
skge_tx_intr(hw->dev[1]);
- if (status & IS_PA_TO_RX1) {
- struct skge_port *skge = netdev_priv(hw->dev[0]);
- ++skge->net_stats.rx_over_errors;
- skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1);
- }
-
- if (status & IS_PA_TO_RX2) {
- struct skge_port *skge = netdev_priv(hw->dev[1]);
- ++skge->net_stats.rx_over_errors;
- skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2);
- }
-
- if (status & IS_PA_TO_TX1)
- skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1);
-
- if (status & IS_PA_TO_TX2)
- skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2);
-
if (status & IS_MAC1)
skge_mac_intr(hw, 0);
-
+
if (status & IS_MAC2)
skge_mac_intr(hw, 1);
@@ -2822,7 +2859,8 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
tasklet_schedule(&hw->ext_tasklet);
}
- skge_write32(hw, B0_IMSK, hw->intr_mask);
+ if (status)
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
return IRQ_HANDLED;
}
@@ -2866,6 +2904,9 @@ static const struct {
{ CHIP_ID_YUKON, "Yukon" },
{ CHIP_ID_YUKON_LITE, "Yukon-Lite"},
{ CHIP_ID_YUKON_LP, "Yukon-LP"},
+ { CHIP_ID_YUKON_XL, "Yukon-2 XL"},
+ { CHIP_ID_YUKON_EC, "YUKON-2 EC"},
+ { CHIP_ID_YUKON_FE, "YUKON-2 FE"},
};
static const char *skge_board_name(const struct skge_hw *hw)
@@ -2889,8 +2930,8 @@ static const char *skge_board_name(const struct skge_hw *hw)
static int skge_reset(struct skge_hw *hw)
{
u16 ctst;
- u8 t8, mac_cfg;
- int i;
+ u8 t8;
+ int i, ports;
ctst = skge_read16(hw, B0_CTST);
@@ -2911,9 +2952,12 @@ static int skge_reset(struct skge_hw *hw)
hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
hw->pmd_type = skge_read8(hw, B2_PMD_TYP);
- switch (hw->chip_id) {
+ switch(hw->chip_id) {
case CHIP_ID_GENESIS:
switch (hw->phy_type) {
+ case SK_PHY_XMAC:
+ hw->phy_addr = PHY_ADDR_XMAC;
+ break;
case SK_PHY_BCOM:
hw->phy_addr = PHY_ADDR_BCOM;
break;
@@ -2942,9 +2986,8 @@ static int skge_reset(struct skge_hw *hw)
return -EOPNOTSUPP;
}
- mac_cfg = skge_read8(hw, B2_MAC_CFG);
- hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2;
- hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4;
+ hw->mac_cfg = skge_read8(hw, B2_MAC_CFG);
+ ports = isdualport(hw) ? 2 : 1;
/* read the adapters RAM size */
t8 = skge_read8(hw, B2_E_0);
@@ -2967,9 +3010,9 @@ static int skge_reset(struct skge_hw *hw)
/* switch power to VCC (WA for VAUX problem) */
skge_write8(hw, B0_POWER_CTRL,
PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
- for (i = 0; i < hw->ports; i++) {
- skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
- skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+ for (i = 0; i < ports; i++) {
+ skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+ skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
}
}
@@ -2979,8 +3022,8 @@ static int skge_reset(struct skge_hw *hw)
skge_write8(hw, B0_LED, LED_STAT_ON);
/* enable the Tx Arbiters */
- for (i = 0; i < hw->ports; i++)
- skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
+ for (i = 0; i < ports; i++)
+ skge_write8(hw, SKGEMAC_REG(i, TXA_CTRL), TXA_ENA_ARB);
/* Initialize ram interface */
skge_write16(hw, B3_RI_CTRL, RI_RST_CLR);
@@ -3007,14 +3050,16 @@ static int skge_reset(struct skge_hw *hw)
skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
skge_write32(hw, B2_IRQM_CTRL, TIM_START);
- hw->intr_mask = IS_HW_ERR | IS_EXT_REG;
+ hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1;
+ if (isdualport(hw))
+ hw->intr_mask |= IS_PORT_2;
skge_write32(hw, B0_IMSK, hw->intr_mask);
if (hw->chip_id != CHIP_ID_GENESIS)
skge_write8(hw, GMAC_IRQ_MSK, 0);
spin_lock_bh(&hw->phy_lock);
- for (i = 0; i < hw->ports; i++) {
+ for (i = 0; i < ports; i++) {
if (hw->chip_id == CHIP_ID_GENESIS)
genesis_reset(hw, i);
else
@@ -3026,8 +3071,7 @@ static int skge_reset(struct skge_hw *hw)
}
/* Initialize network device */
-static struct net_device *skge_devinit(struct skge_hw *hw, int port,
- int highmem)
+static struct net_device *skge_devinit(struct skge_hw *hw, int port)
{
struct skge_port *skge;
struct net_device *dev = alloc_etherdev(sizeof(*skge));
@@ -3060,8 +3104,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
#endif
dev->irq = hw->pdev->irq;
dev->features = NETIF_F_LLTX;
- if (highmem)
- dev->features |= NETIF_F_HIGHDMA;
skge = netdev_priv(dev);
skge->netdev = dev;
@@ -3075,7 +3117,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
skge->flow_control = FLOW_MODE_SYMMETRIC;
skge->duplex = -1;
skge->speed = -1;
- skge->advertising = skge_supported_modes(hw);
+ skge->advertising = skge_modes(hw);
hw->dev[port] = dev;
@@ -3083,6 +3125,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
spin_lock_init(&skge->tx_lock);
+ init_timer(&skge->link_check);
+ skge->link_check.function = skge_link_timer;
+ skge->link_check.data = (unsigned long) skge;
+
init_timer(&skge->led_blink);
skge->led_blink.function = skge_blink_timer;
skge->led_blink.data = (unsigned long) skge;
@@ -3186,11 +3232,14 @@ static int __devinit skge_probe(struct pci_dev *pdev,
printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n",
pci_resource_start(pdev, 0), pdev->irq,
- skge_board_name(hw), hw->chip_rev);
+ skge_board_name(hw), chip_rev(hw));
- if ((dev = skge_devinit(hw, 0, using_dac)) == NULL)
+ if ((dev = skge_devinit(hw, 0)) == NULL)
goto err_out_led_off;
+ if (using_dac)
+ dev->features |= NETIF_F_HIGHDMA;
+
if ((err = register_netdev(dev))) {
printk(KERN_ERR PFX "%s: cannot register net device\n",
pci_name(pdev));
@@ -3199,7 +3248,10 @@ static int __devinit skge_probe(struct pci_dev *pdev,
skge_show_addr(dev);
- if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) {
+ if (isdualport(hw) && (dev1 = skge_devinit(hw, 1))) {
+ if (using_dac)
+ dev1->features |= NETIF_F_HIGHDMA;
+
if (register_netdev(dev1) == 0)
skge_show_addr(dev1);
else {
@@ -3236,7 +3288,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
struct skge_hw *hw = pci_get_drvdata(pdev);
struct net_device *dev0, *dev1;
- if (!hw)
+ if(!hw)
return;
if ((dev1 = hw->dev[1]))
@@ -3264,7 +3316,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state)
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, wol = 0;
- for (i = 0; i < 2; i++) {
+ for(i = 0; i < 2; i++) {
struct net_device *dev = hw->dev[i];
if (dev) {
@@ -3297,11 +3349,11 @@ static int skge_resume(struct pci_dev *pdev)
skge_reset(hw);
- for (i = 0; i < 2; i++) {
+ for(i = 0; i < 2; i++) {
struct net_device *dev = hw->dev[i];
if (dev) {
netif_device_attach(dev);
- if (netif_running(dev))
+ if(netif_running(dev))
skge_up(dev);
}
}
diff --git a/trunk/drivers/net/skge.h b/trunk/drivers/net/skge.h
index 14d0cc01fb9a..36c62b68fab4 100644
--- a/trunk/drivers/net/skge.h
+++ b/trunk/drivers/net/skge.h
@@ -7,6 +7,31 @@
/* PCI config registers */
#define PCI_DEV_REG1 0x40
#define PCI_DEV_REG2 0x44
+#ifndef PCI_VPD
+#define PCI_VPD 0x50
+#endif
+
+/* PCI_OUR_REG_2 32 bit Our Register 2 */
+enum {
+ PCI_VPD_WR_THR = 0xff<<24, /* Bit 31..24: VPD Write Threshold */
+ PCI_DEV_SEL = 0x7f<<17, /* Bit 23..17: EEPROM Device Select */
+ PCI_VPD_ROM_SZ = 7 <<14, /* Bit 16..14: VPD ROM Size */
+ /* Bit 13..12: reserved */
+ PCI_EN_DUMMY_RD = 1<<3, /* Enable Dummy Read */
+ PCI_REV_DESC = 1<<2, /* Reverse Desc. Bytes */
+ PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */
+};
+
+/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
+enum {
+ PCI_VPD_FLAG = 1<<15, /* starts VPD rd/wr cycle */
+ PCI_VPD_ADR_MSK =0x7fffL, /* Bit 14.. 0: VPD Address Mask */
+ VPD_RES_ID = 0x82,
+ VPD_RES_READ = 0x90,
+ VPD_RES_WRITE = 0x81,
+ VPD_RES_END = 0x78,
+};
+
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -14,6 +39,7 @@
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
+
enum csr_regs {
B0_RAP = 0x0000,
B0_CTST = 0x0004,
@@ -203,11 +229,8 @@ enum {
IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */
IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */
- IS_TO_PORT1 = IS_PA_TO_RX1 | IS_PA_TO_TX1,
- IS_TO_PORT2 = IS_PA_TO_RX2 | IS_PA_TO_TX2,
-
- IS_PORT_1 = IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1,
- IS_PORT_2 = IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2,
+ IS_PORT_1 = IS_XA1_F| IS_R1_F| IS_MAC1,
+ IS_PORT_2 = IS_XA2_F| IS_R2_F| IS_MAC2,
};
@@ -265,6 +288,14 @@ enum {
CHIP_REV_YU_LITE_A3 = 7, /* Chip Rev. for YUKON-Lite A3 */
};
+/* B2_LD_TEST 8 bit EPROM loader test register */
+enum {
+ LD_T_ON = 1<<3, /* Loader Test mode on */
+ LD_T_OFF = 1<<2, /* Loader Test mode off */
+ LD_T_STEP = 1<<1, /* Decrement FPROM addr. Counter */
+ LD_START = 1<<0, /* Start loading FPROM */
+};
+
/* B2_TI_CTRL 8 bit Timer control */
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
enum {
@@ -282,6 +313,16 @@ enum {
TIM_T_STEP = 1<<0, /* Test step */
};
+/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
+/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
+/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
+enum {
+ DPT_MSK = 0x00ffffffL, /* Bit 23.. 0: Desc Poll Timer Bits */
+
+ DPT_START = 1<<1, /* Start Descriptor Poll Timer */
+ DPT_STOP = 1<<0, /* Stop Descriptor Poll Timer */
+};
+
/* B2_GP_IO 32 bit General Purpose I/O Register */
enum {
GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */
@@ -307,6 +348,30 @@ enum {
GP_IO_0 = 1<<0, /* IO_0 pin */
};
+/* Rx/Tx Path related Arbiter Test Registers */
+/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
+/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
+/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
+/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
+enum {
+ TX2_T_EV = 1<<15,/* TX2 Timeout/Recv Event occured */
+ TX2_T_ON = 1<<14,/* TX2 Timeout/Recv Timer Test On */
+ TX2_T_OFF = 1<<13,/* TX2 Timeout/Recv Timer Tst Off */
+ TX2_T_STEP = 1<<12,/* TX2 Timeout/Recv Timer Step */
+ TX1_T_EV = 1<<11,/* TX1 Timeout/Recv Event occured */
+ TX1_T_ON = 1<<10,/* TX1 Timeout/Recv Timer Test On */
+ TX1_T_OFF = 1<<9, /* TX1 Timeout/Recv Timer Tst Off */
+ TX1_T_STEP = 1<<8, /* TX1 Timeout/Recv Timer Step */
+ RX2_T_EV = 1<<7, /* RX2 Timeout/Recv Event occured */
+ RX2_T_ON = 1<<6, /* RX2 Timeout/Recv Timer Test On */
+ RX2_T_OFF = 1<<5, /* RX2 Timeout/Recv Timer Tst Off */
+ RX2_T_STEP = 1<<4, /* RX2 Timeout/Recv Timer Step */
+ RX1_T_EV = 1<<3, /* RX1 Timeout/Recv Event occured */
+ RX1_T_ON = 1<<2, /* RX1 Timeout/Recv Timer Test On */
+ RX1_T_OFF = 1<<1, /* RX1 Timeout/Recv Timer Tst Off */
+ RX1_T_STEP = 1<<0, /* RX1 Timeout/Recv Timer Step */
+};
+
/* Descriptor Bit Definition */
/* TxCtrl Transmit Buffer Control Field */
/* RxCtrl Receive Buffer Control Field */
@@ -363,6 +428,14 @@ enum {
RI_RST_SET = 1<<0, /* Set RAM Interface Reset */
};
+/* B3_RI_TEST 8 bit RAM Iface Test Register */
+enum {
+ RI_T_EV = 1<<3, /* Timeout Event occured */
+ RI_T_ON = 1<<2, /* Timeout Timer Test On */
+ RI_T_OFF = 1<<1, /* Timeout Timer Test Off */
+ RI_T_STEP = 1<<0, /* Timeout Timer Step */
+};
+
/* MAC Arbiter Registers */
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
enum {
@@ -379,6 +452,19 @@ enum {
#define SK_PKT_TO_MAX 0xffff /* Maximum value */
#define SK_RI_TO_53 36 /* RAM interface timeout */
+
+/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
+enum {
+ MA_ENA_REC_TX2 = 1<<7, /* Enable Recovery Timer TX2 */
+ MA_DIS_REC_TX2 = 1<<6, /* Disable Recovery Timer TX2 */
+ MA_ENA_REC_TX1 = 1<<5, /* Enable Recovery Timer TX1 */
+ MA_DIS_REC_TX1 = 1<<4, /* Disable Recovery Timer TX1 */
+ MA_ENA_REC_RX2 = 1<<3, /* Enable Recovery Timer RX2 */
+ MA_DIS_REC_RX2 = 1<<2, /* Disable Recovery Timer RX2 */
+ MA_ENA_REC_RX1 = 1<<1, /* Enable Recovery Timer RX1 */
+ MA_DIS_REC_RX1 = 1<<0, /* Disable Recovery Timer RX1 */
+};
+
/* Packet Arbiter Registers */
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
enum {
@@ -402,7 +488,7 @@ enum {
PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
-/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
@@ -425,7 +511,7 @@ enum {
/*
* Bank 4 - 5
*/
-/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
enum {
TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/
TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */
@@ -451,7 +537,7 @@ enum {
/* Queue Register Offsets, use Q_ADDR() to access */
enum {
- B8_Q_REGS = 0x0400, /* base of Queue registers */
+ B8_Q_REGS = 0x0400, /* base of Queue registers */
Q_D = 0x00, /* 8*32 bit Current Descriptor */
Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */
Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */
@@ -532,7 +618,8 @@ enum {
enum {
PHY_ADDR_XMAC = 0<<8,
PHY_ADDR_BCOM = 1<<8,
-
+ PHY_ADDR_LONE = 3<<8,
+ PHY_ADDR_NAT = 0<<8,
/* GPHY address (bits 15..11 of SMI control reg) */
PHY_ADDR_MARV = 0,
};
@@ -899,7 +986,7 @@ enum {
LINKLED_BLINK_OFF = 0x10,
LINKLED_BLINK_ON = 0x20,
};
-
+
/* GMAC and GPHY Control Registers (YUKON only) */
enum {
GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */
@@ -1064,6 +1151,54 @@ enum {
PHY_MARV_FE_SPEC_2 = 0x1c,/* 16 bit r/w Specific Control Reg. 2 */
};
+/* Level One-PHY Registers, indirect addressed over XMAC */
+enum {
+ PHY_LONE_CTRL = 0x00,/* 16 bit r/w PHY Control Register */
+ PHY_LONE_STAT = 0x01,/* 16 bit r/o PHY Status Register */
+ PHY_LONE_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */
+ PHY_LONE_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */
+ PHY_LONE_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
+ PHY_LONE_AUNE_LP = 0x05,/* 16 bit r/o Link Part Ability Reg */
+ PHY_LONE_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
+ PHY_LONE_NEPG = 0x07,/* 16 bit r/w Next Page Register */
+ PHY_LONE_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */
+ /* Level One-specific registers */
+ PHY_LONE_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */
+ PHY_LONE_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */
+ PHY_LONE_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Reg */
+ PHY_LONE_PORT_CFG = 0x10,/* 16 bit r/w Port Configuration Reg*/
+ PHY_LONE_Q_STAT = 0x11,/* 16 bit r/o Quick Status Reg */
+ PHY_LONE_INT_ENAB = 0x12,/* 16 bit r/w Interrupt Enable Reg */
+ PHY_LONE_INT_STAT = 0x13,/* 16 bit r/o Interrupt Status Reg */
+ PHY_LONE_LED_CFG = 0x14,/* 16 bit r/w LED Configuration Reg */
+ PHY_LONE_PORT_CTRL = 0x15,/* 16 bit r/w Port Control Reg */
+ PHY_LONE_CIM = 0x16,/* 16 bit r/o CIM Reg */
+};
+
+/* National-PHY Registers, indirect addressed over XMAC */
+enum {
+ PHY_NAT_CTRL = 0x00,/* 16 bit r/w PHY Control Register */
+ PHY_NAT_STAT = 0x01,/* 16 bit r/w PHY Status Register */
+ PHY_NAT_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */
+ PHY_NAT_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */
+ PHY_NAT_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */
+ PHY_NAT_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Ability Reg */
+ PHY_NAT_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */
+ PHY_NAT_NEPG = 0x07,/* 16 bit r/w Next Page Register */
+ PHY_NAT_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner Reg */
+ /* National-specific registers */
+ PHY_NAT_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */
+ PHY_NAT_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */
+ PHY_NAT_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Register */
+ PHY_NAT_EXT_CTRL1 = 0x10,/* 16 bit r/o Extended Control Reg1 */
+ PHY_NAT_Q_STAT1 = 0x11,/* 16 bit r/o Quick Status Reg1 */
+ PHY_NAT_10B_OP = 0x12,/* 16 bit r/o 10Base-T Operations Reg */
+ PHY_NAT_EXT_CTRL2 = 0x13,/* 16 bit r/o Extended Control Reg1 */
+ PHY_NAT_Q_STAT2 = 0x14,/* 16 bit r/o Quick Status Reg2 */
+
+ PHY_NAT_PHY_ADDR = 0x19,/* 16 bit r/o PHY Address Register */
+};
+
enum {
PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */
PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */
@@ -1118,29 +1253,8 @@ enum {
PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
};
-/* Advertisement register bits */
enum {
PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */
- PHY_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */
- PHY_AN_RF = 1<<13, /* Bit 13: Remote Fault Bits */
-
- PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11: Try for asymmetric */
- PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10: Try for pause */
- PHY_AN_100BASE4 = 1<<9, /* Bit 9: Try for 100mbps 4k packets */
- PHY_AN_100FULL = 1<<8, /* Bit 8: Try for 100mbps full-duplex */
- PHY_AN_100HALF = 1<<7, /* Bit 7: Try for 100mbps half-duplex */
- PHY_AN_10FULL = 1<<6, /* Bit 6: Try for 10mbps full-duplex */
- PHY_AN_10HALF = 1<<5, /* Bit 5: Try for 10mbps half-duplex */
- PHY_AN_CSMA = 1<<0, /* Bit 0: Only selector supported */
- PHY_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
- PHY_AN_FULL = PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
- PHY_AN_ALL = PHY_AN_10HALF | PHY_AN_10FULL |
- PHY_AN_100HALF | PHY_AN_100FULL,
-};
-
-/* Xmac Specific */
-enum {
- PHY_X_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */
PHY_X_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */
PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */
@@ -1149,6 +1263,82 @@ enum {
PHY_X_AN_FD = 1<<5, /* Bit 5: Full Duplex */
};
+enum {
+ PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */
+
+ PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
+ PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */
+ PHY_B_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
+};
+
+enum {
+ PHY_L_AN_RF = 1<<13, /* Bit 13: Remote Fault */
+ /* Bit 12: reserved */
+ PHY_L_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
+ PHY_L_AN_PC = 1<<10, /* Bit 10: Pause Capable */
+
+ PHY_L_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
+};
+
+/* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */
+/* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
+/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
+enum {
+ PHY_N_AN_RF = 1<<13, /* Bit 13: Remote Fault */
+
+ PHY_N_AN_100F = 1<<11, /* Bit 11: 100Base-T2 FD Support */
+ PHY_N_AN_100H = 1<<10, /* Bit 10: 100Base-T2 HD Support */
+
+ PHY_N_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/
+};
+
+/* field type definition for PHY_x_AN_SEL */
+enum {
+ PHY_SEL_TYPE = 1, /* 00001 = Ethernet */
+};
+
+enum {
+ PHY_ANE_LP_NP = 1<<3, /* Bit 3: Link Partner can Next Page */
+ PHY_ANE_LOC_NP = 1<<2, /* Bit 2: Local PHY can Next Page */
+ PHY_ANE_RX_PG = 1<<1, /* Bit 1: Page Received */
+};
+
+enum {
+ PHY_ANE_PAR_DF = 1<<4, /* Bit 4: Parallel Detection Fault */
+
+ PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */
+};
+
+enum {
+ PHY_NP_MORE = 1<<15, /* Bit 15: More, Next Pages to follow */
+ PHY_NP_ACK1 = 1<<14, /* Bit 14: (ro) Ack1, for receiving a message */
+ PHY_NP_MSG_VAL = 1<<13, /* Bit 13: Message Page valid */
+ PHY_NP_ACK2 = 1<<12, /* Bit 12: Ack2, comply with msg content */
+ PHY_NP_TOG = 1<<11, /* Bit 11: Toggle Bit, ensure sync */
+ PHY_NP_MSG = 0x07ff, /* Bit 10..0: Message from/to Link Partner */
+};
+
+enum {
+ PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */
+ PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */
+};
+
+enum {
+ PHY_X_RS_PAUSE = 3<<7,/* Bit 8..7: selected Pause Mode */
+ PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */
+ PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */
+ PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */
+ PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */
+};
+
+/** Remote Fault Bits (PHY_X_AN_RFB) encoding */
+enum {
+ X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */
+ X_RFB_LF = 1<<12, /* Bit 13..12 Link Failure */
+ X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */
+ X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */
+};
+
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
enum {
PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */
@@ -1228,16 +1418,6 @@ enum {
PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */
};
-/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
-/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
-enum {
- PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */
-
- PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */
- PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */
-};
-
-
/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
enum {
PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */
@@ -1298,9 +1478,7 @@ enum {
PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */
PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */
};
-#define PHY_B_DEF_MSK \
- (~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
- PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
+#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
enum {
@@ -1317,6 +1495,166 @@ enum {
PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */
};
+/*
+ * Level One-Specific
+ */
+/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
+enum {
+ PHY_L_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */
+ PHY_L_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */
+ PHY_L_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */
+ PHY_L_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */
+ PHY_L_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */
+ PHY_L_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */
+};
+
+/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
+enum {
+ PHY_L_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */
+ PHY_L_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */
+ PHY_L_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */
+ PHY_L_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status */
+ PHY_L_1000S_LP_FD = 1<<11, /* Bit 11: Link Partner can FD */
+ PHY_L_1000S_LP_HD = 1<<10, /* Bit 10: Link Partner can HD */
+
+ PHY_L_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */
+
+/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
+ PHY_L_ES_X_FD_CAP = 1<<15, /* Bit 15: 1000Base-X FD capable */
+ PHY_L_ES_X_HD_CAP = 1<<14, /* Bit 14: 1000Base-X HD capable */
+ PHY_L_ES_T_FD_CAP = 1<<13, /* Bit 13: 1000Base-T FD capable */
+ PHY_L_ES_T_HD_CAP = 1<<12, /* Bit 12: 1000Base-T HD capable */
+};
+
+/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
+enum {
+ PHY_L_PC_REP_MODE = 1<<15, /* Bit 15: Repeater Mode */
+
+ PHY_L_PC_TX_DIS = 1<<13, /* Bit 13: Tx output Disabled */
+ PHY_L_PC_BY_SCR = 1<<12, /* Bit 12: Bypass Scrambler */
+ PHY_L_PC_BY_45 = 1<<11, /* Bit 11: Bypass 4B5B-Decoder */
+ PHY_L_PC_JAB_DIS = 1<<10, /* Bit 10: Jabber Disabled */
+ PHY_L_PC_SQE = 1<<9, /* Bit 9: Enable Heartbeat */
+ PHY_L_PC_TP_LOOP = 1<<8, /* Bit 8: TP Loopback */
+ PHY_L_PC_SSS = 1<<7, /* Bit 7: Smart Speed Selection */
+ PHY_L_PC_FIFO_SIZE = 1<<6, /* Bit 6: FIFO Size */
+ PHY_L_PC_PRE_EN = 1<<5, /* Bit 5: Preamble Enable */
+ PHY_L_PC_CIM = 1<<4, /* Bit 4: Carrier Integrity Mon */
+ PHY_L_PC_10_SER = 1<<3, /* Bit 3: Use Serial Output */
+ PHY_L_PC_ANISOL = 1<<2, /* Bit 2: Unisolate Port */
+ PHY_L_PC_TEN_BIT = 1<<1, /* Bit 1: 10bit iface mode on */
+ PHY_L_PC_ALTCLOCK = 1<<0, /* Bit 0: (ro) ALTCLOCK Mode on */
+};
+
+/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
+enum {
+ PHY_L_QS_D_RATE = 3<<14,/* Bit 15..14: Data Rate */
+ PHY_L_QS_TX_STAT = 1<<13, /* Bit 13: Transmitting */
+ PHY_L_QS_RX_STAT = 1<<12, /* Bit 12: Receiving */
+ PHY_L_QS_COL_STAT = 1<<11, /* Bit 11: Collision */
+ PHY_L_QS_L_STAT = 1<<10, /* Bit 10: Link is up */
+ PHY_L_QS_DUP_MOD = 1<<9, /* Bit 9: Full/Half Duplex */
+ PHY_L_QS_AN = 1<<8, /* Bit 8: AutoNeg is On */
+ PHY_L_QS_AN_C = 1<<7, /* Bit 7: AN is Complete */
+ PHY_L_QS_LLE = 7<<4,/* Bit 6..4: Line Length Estim. */
+ PHY_L_QS_PAUSE = 1<<3, /* Bit 3: LP advertised Pause */
+ PHY_L_QS_AS_PAUSE = 1<<2, /* Bit 2: LP adv. asym. Pause */
+ PHY_L_QS_ISOLATE = 1<<1, /* Bit 1: CIM Isolated */
+ PHY_L_QS_EVENT = 1<<0, /* Bit 0: Event has occurred */
+};
+
+/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
+/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
+enum {
+ PHY_L_IS_AN_F = 1<<13, /* Bit 13: Auto-Negotiation fault */
+ PHY_L_IS_CROSS = 1<<11, /* Bit 11: Crossover used */
+ PHY_L_IS_POL = 1<<10, /* Bit 10: Polarity correct. used */
+ PHY_L_IS_SS = 1<<9, /* Bit 9: Smart Speed Downgrade */
+ PHY_L_IS_CFULL = 1<<8, /* Bit 8: Counter Full */
+ PHY_L_IS_AN_C = 1<<7, /* Bit 7: AutoNeg Complete */
+ PHY_L_IS_SPEED = 1<<6, /* Bit 6: Speed Changed */
+ PHY_L_IS_DUP = 1<<5, /* Bit 5: Duplex Changed */
+ PHY_L_IS_LS = 1<<4, /* Bit 4: Link Status Changed */
+ PHY_L_IS_ISOL = 1<<3, /* Bit 3: Isolate Occured */
+ PHY_L_IS_MDINT = 1<<2, /* Bit 2: (ro) STAT: MII Int Pending */
+ PHY_L_IS_INTEN = 1<<1, /* Bit 1: ENAB: Enable IRQs */
+ PHY_L_IS_FORCE = 1<<0, /* Bit 0: ENAB: Force Interrupt */
+};
+
+/* int. mask */
+#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
+
+/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
+enum {
+ PHY_L_LC_LEDC = 3<<14,/* Bit 15..14: Col/Blink/On/Off */
+ PHY_L_LC_LEDR = 3<<12,/* Bit 13..12: Rx/Blink/On/Off */
+ PHY_L_LC_LEDT = 3<<10,/* Bit 11..10: Tx/Blink/On/Off */
+ PHY_L_LC_LEDG = 3<<8,/* Bit 9..8: Giga/Blink/On/Off */
+ PHY_L_LC_LEDS = 3<<6,/* Bit 7..6: 10-100/Blink/On/Off */
+ PHY_L_LC_LEDL = 3<<4,/* Bit 5..4: Link/Blink/On/Off */
+ PHY_L_LC_LEDF = 3<<2,/* Bit 3..2: Duplex/Blink/On/Off */
+ PHY_L_LC_PSTRECH= 1<<1, /* Bit 1: Strech LED Pulses */
+ PHY_L_LC_FREQ = 1<<0, /* Bit 0: 30/100 ms */
+};
+
+/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
+enum {
+ PHY_L_PC_TX_TCLK = 1<<15, /* Bit 15: Enable TX_TCLK */
+ PHY_L_PC_ALT_NP = 1<<13, /* Bit 14: Alternate Next Page */
+ PHY_L_PC_GMII_ALT= 1<<12, /* Bit 13: Alternate GMII driver */
+ PHY_L_PC_TEN_CRS = 1<<10, /* Bit 10: Extend CRS*/
+};
+
+/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
+enum {
+ PHY_L_CIM_ISOL = 0xff<<8,/* Bit 15..8: Isolate Count */
+ PHY_L_CIM_FALSE_CAR = 0xff, /* Bit 7..0: False Carrier Count */
+};
+
+/*
+ * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
+ */
+enum {
+ PHY_L_P_NO_PAUSE= 0<<10,/* Bit 11..10: no Pause Mode */
+ PHY_L_P_SYM_MD = 1<<10, /* Bit 11..10: symmetric Pause Mode */
+ PHY_L_P_ASYM_MD = 2<<10,/* Bit 11..10: asymmetric Pause Mode */
+ PHY_L_P_BOTH_MD = 3<<10,/* Bit 11..10: both Pause Mode */
+};
+
+/*
+ * National-Specific
+ */
+/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
+enum {
+ PHY_N_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */
+ PHY_N_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */
+ PHY_N_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */
+ PHY_N_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */
+ PHY_N_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */
+ PHY_N_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */
+ PHY_N_1000C_APC = 1<<7, /* Bit 7: Asymmetric Pause Cap. */};
+
+
+/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
+enum {
+ PHY_N_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */
+ PHY_N_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */
+ PHY_N_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */
+ PHY_N_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status*/
+ PHY_N_1000S_LP_FD= 1<<11, /* Bit 11: Link Partner can FD */
+ PHY_N_1000S_LP_HD= 1<<10, /* Bit 10: Link Partner can HD */
+ PHY_N_1000C_LP_APC= 1<<9, /* Bit 9: LP Asym. Pause Cap. */
+ PHY_N_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */
+};
+
+/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
+enum {
+ PHY_N_ES_X_FD_CAP= 1<<15, /* Bit 15: 1000Base-X FD capable */
+ PHY_N_ES_X_HD_CAP= 1<<14, /* Bit 14: 1000Base-X HD capable */
+ PHY_N_ES_T_FD_CAP= 1<<13, /* Bit 13: 1000Base-T FD capable */
+ PHY_N_ES_T_HD_CAP= 1<<12, /* Bit 12: 1000Base-T HD capable */
+};
+
/** Marvell-Specific */
enum {
PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */
@@ -1380,7 +1718,7 @@ enum {
PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */
};
-#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
+#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
enum {
PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */
@@ -1767,7 +2105,7 @@ enum {
GM_GPSR_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */
GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */
};
-
+
/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
enum {
GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */
@@ -1789,7 +2127,7 @@ enum {
#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
-
+
/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
enum {
GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */
@@ -1800,7 +2138,7 @@ enum {
#define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK)
#define TX_COL_DEF 0x04
-
+
/* GM_RX_CTRL 16 bit r/w Receive Control Register */
enum {
GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */
@@ -1808,7 +2146,7 @@ enum {
GM_RXCR_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */
GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */
};
-
+
/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
enum {
GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */
@@ -1833,7 +2171,7 @@ enum {
GM_SMOD_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */
GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
};
-
+
#define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK)
#define DATA_BLIND_DEF 0x04
@@ -1848,7 +2186,7 @@ enum {
GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */
GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */
};
-
+
#define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK)
#define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK)
@@ -1857,7 +2195,7 @@ enum {
GM_PAR_MIB_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */
GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */
};
-
+
/* Receive Frame Status Encoding */
enum {
GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */
@@ -1879,12 +2217,12 @@ enum {
/*
* GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
*/
- GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR |
- GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+ GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR |
+ GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
GMR_FS_JABBER,
/* Rx GMAC FIFO Flush Mask (default) */
RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR |
- GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE |
+ GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE |
GMR_FS_JABBER,
};
@@ -2202,6 +2540,10 @@ enum {
};
+/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
+#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
+
+
/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
enum {
XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */
@@ -2320,8 +2662,8 @@ enum {
};
#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
-#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
- XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA)
+#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
+ XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
enum {
@@ -2451,20 +2793,28 @@ struct skge_hw {
u32 intr_mask;
struct net_device *dev[2];
+ u8 mac_cfg;
u8 chip_id;
- u8 chip_rev;
u8 phy_type;
u8 pmd_type;
u16 phy_addr;
- u8 ports;
u32 ram_size;
u32 ram_offset;
-
+
struct tasklet_struct ext_tasklet;
spinlock_t phy_lock;
};
+static inline int isdualport(const struct skge_hw *hw)
+{
+ return !(hw->mac_cfg & CFG_SNG_MAC);
+}
+
+static inline u8 chip_rev(const struct skge_hw *hw)
+{
+ return (hw->mac_cfg & CFG_CHIP_R_MSK) >> 4;
+}
static inline int iscopper(const struct skge_hw *hw)
{
@@ -2477,7 +2827,7 @@ enum {
FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */
FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */
};
-
+
struct skge_port {
u32 msg_enable;
struct skge_hw *hw;
@@ -2503,8 +2853,8 @@ struct skge_port {
void *mem; /* PCI memory for rings */
dma_addr_t dma;
unsigned long mem_size;
- unsigned int rx_buf_size;
+ struct timer_list link_check;
struct timer_list led_blink;
};
@@ -2513,6 +2863,7 @@ struct skge_port {
static inline u32 skge_read32(const struct skge_hw *hw, int reg)
{
return readl(hw->regs + reg);
+
}
static inline u16 skge_read16(const struct skge_hw *hw, int reg)
@@ -2541,87 +2892,114 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
}
/* MAC Related Registers inside the device. */
-#define SK_REG(port,reg) (((port)<<7)+(reg))
-#define SK_XMAC_REG(port, reg) \
+#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg))
+
+/* PCI config space can be accessed via memory mapped space */
+#define SKGEPCI_REG(reg) ((reg)+ 0x380)
+
+#define SKGEXM_REG(port, reg) \
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
-static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg)
+static inline u32 skge_xm_read32(const struct skge_hw *hw, int port, int reg)
+{
+ return skge_read32(hw, SKGEXM_REG(port,reg));
+}
+
+static inline u16 skge_xm_read16(const struct skge_hw *hw, int port, int reg)
{
- u32 v;
- v = skge_read16(hw, SK_XMAC_REG(port, reg));
- v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16;
- return v;
+ return skge_read16(hw, SKGEXM_REG(port,reg));
}
-static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg)
+static inline u8 skge_xm_read8(const struct skge_hw *hw, int port, int reg)
{
- return skge_read16(hw, SK_XMAC_REG(port,reg));
+ return skge_read8(hw, SKGEXM_REG(port,reg));
}
-static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
+static inline void skge_xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
{
- skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff);
- skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16);
+ skge_write32(hw, SKGEXM_REG(port,r), v);
}
-static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
+static inline void skge_xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
{
- skge_write16(hw, SK_XMAC_REG(port,r), v);
+ skge_write16(hw, SKGEXM_REG(port,r), v);
}
-static inline void xm_outhash(const struct skge_hw *hw, int port, int reg,
+static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 v)
+{
+ skge_write8(hw, SKGEXM_REG(port,r), v);
+}
+
+static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg,
const u8 *hash)
{
- xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8));
- xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8));
- xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8));
- xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8));
+ skge_xm_write16(hw, port, reg,
+ (u16)hash[0] | ((u16)hash[1] << 8));
+ skge_xm_write16(hw, port, reg+2,
+ (u16)hash[2] | ((u16)hash[3] << 8));
+ skge_xm_write16(hw, port, reg+4,
+ (u16)hash[4] | ((u16)hash[5] << 8));
+ skge_xm_write16(hw, port, reg+6,
+ (u16)hash[6] | ((u16)hash[7] << 8));
}
-static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg,
+static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg,
const u8 *addr)
{
- xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8));
- xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8));
- xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8));
+ skge_xm_write16(hw, port, reg,
+ (u16)addr[0] | ((u16)addr[1] << 8));
+ skge_xm_write16(hw, port, reg,
+ (u16)addr[2] | ((u16)addr[3] << 8));
+ skge_xm_write16(hw, port, reg,
+ (u16)addr[4] | ((u16)addr[5] << 8));
}
-#define SK_GMAC_REG(port,reg) \
- (BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
-static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg)
+#define SKGEGMA_REG(port,reg) \
+ ((reg) + BASE_GMAC_1 + \
+ (port) * (BASE_GMAC_2-BASE_GMAC_1))
+
+static inline u16 skge_gma_read16(const struct skge_hw *hw, int port, int reg)
{
- return skge_read16(hw, SK_GMAC_REG(port,reg));
+ return skge_read16(hw, SKGEGMA_REG(port,reg));
}
-static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg)
+static inline u32 skge_gma_read32(const struct skge_hw *hw, int port, int reg)
{
- return (u32) skge_read16(hw, SK_GMAC_REG(port,reg))
- | ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16);
+ return (u32) skge_read16(hw, SKGEGMA_REG(port,reg))
+ | ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16);
}
-static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
+static inline u8 skge_gma_read8(const struct skge_hw *hw, int port, int reg)
{
- skge_write16(hw, SK_GMAC_REG(port,r), v);
+ return skge_read8(hw, SKGEGMA_REG(port,reg));
}
-static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v)
+static inline void skge_gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
{
- skge_write16(hw, SK_GMAC_REG(port, r), (u16) v);
- skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16));
+ skge_write16(hw, SKGEGMA_REG(port,r), v);
}
-static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
+static inline void skge_gma_write32(const struct skge_hw *hw, int port, int r, u32 v)
{
- skge_write8(hw, SK_GMAC_REG(port,r), v);
+ skge_write16(hw, SKGEGMA_REG(port, r), (u16) v);
+ skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16));
}
-static inline void gma_set_addr(struct skge_hw *hw, int port, int reg,
- const u8 *addr)
+static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
{
- gma_write16(hw, port, reg, (u16) addr[0] | ((u16) addr[1] << 8));
- gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
- gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
+ skge_write8(hw, SKGEGMA_REG(port,r), v);
}
+static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg,
+ const u8 *addr)
+{
+ skge_gma_write16(hw, port, reg,
+ (u16) addr[0] | ((u16) addr[1] << 8));
+ skge_gma_write16(hw, port, reg+4,
+ (u16) addr[2] | ((u16) addr[3] << 8));
+ skge_gma_write16(hw, port, reg+8,
+ (u16) addr[4] | ((u16) addr[5] << 8));
+}
+
#endif
diff --git a/trunk/drivers/net/slip.c b/trunk/drivers/net/slip.c
index 404ea4297e32..16363b5c6f56 100644
--- a/trunk/drivers/net/slip.c
+++ b/trunk/drivers/net/slip.c
@@ -74,7 +74,6 @@
#include
#include
#include
-#include
#include
#include "slip.h"
#ifdef CONFIG_INET
diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c
index 1438fdd20826..cfb9d3cdb04a 100644
--- a/trunk/drivers/net/smc91x.c
+++ b/trunk/drivers/net/smc91x.c
@@ -1998,7 +1998,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr)
if (retval)
goto err_out;
- set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
+ set_irq_type(dev->irq, IRQT_RISING);
#ifdef SMC_USE_PXA_DMA
{
diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h
index 7089d86e857a..946528e6b742 100644
--- a/trunk/drivers/net/smc91x.h
+++ b/trunk/drivers/net/smc91x.h
@@ -182,16 +182,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
-#include
-#include
-
-#define SMC_IRQ_TRIGGER_TYPE (( \
- machine_is_omap_h2() \
- || machine_is_omap_h3() \
- || (machine_is_omap_innovator() && !cpu_is_omap150()) \
- ) ? IRQT_FALLING : IRQT_RISING)
-
-
#elif defined(CONFIG_SH_SH4202_MICRODEV)
#define SMC_CAN_USE_8BIT 0
@@ -310,9 +300,6 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l)
#endif
-#ifndef SMC_IRQ_TRIGGER_TYPE
-#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING
-#endif
#ifdef SMC_USE_PXA_DMA
/*
diff --git a/trunk/drivers/net/starfire.c b/trunk/drivers/net/starfire.c
index 88b89dc95c77..12e2b6826fa3 100644
--- a/trunk/drivers/net/starfire.c
+++ b/trunk/drivers/net/starfire.c
@@ -1286,7 +1286,7 @@ static void init_ring(struct net_device *dev)
np->rx_info[i].skb = skb;
if (skb == NULL)
break;
- np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
skb->dev = dev; /* Mark as being used by this device. */
/* Grrr, we cannot offset to correctly align the IP header. */
np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
@@ -1572,7 +1572,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
pci_dma_sync_single_for_cpu(np->pci_dev,
np->rx_info[entry].mapping,
pkt_len, PCI_DMA_FROMDEVICE);
- eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
+ eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
pci_dma_sync_single_for_device(np->pci_dev,
np->rx_info[entry].mapping,
pkt_len, PCI_DMA_FROMDEVICE);
@@ -1696,7 +1696,7 @@ static void refill_rx_ring(struct net_device *dev)
if (skb == NULL)
break; /* Better luck next round. */
np->rx_info[entry].mapping =
- pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
skb->dev = dev; /* Mark as being used by this device. */
np->rx_ring[entry].rxaddr =
cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
diff --git a/trunk/drivers/net/sundance.c b/trunk/drivers/net/sundance.c
index d500a5771dbc..08cb7177a175 100644
--- a/trunk/drivers/net/sundance.c
+++ b/trunk/drivers/net/sundance.c
@@ -1028,7 +1028,7 @@ static void init_ring(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
np->rx_ring[i].frag[0].addr = cpu_to_le32(
- pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz,
+ pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz,
PCI_DMA_FROMDEVICE));
np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
}
@@ -1341,7 +1341,7 @@ static void rx_poll(unsigned long data)
np->rx_buf_sz,
PCI_DMA_FROMDEVICE);
- eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
+ eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
pci_dma_sync_single_for_device(np->pci_dev,
desc->frag[0].addr,
np->rx_buf_sz,
@@ -1400,7 +1400,7 @@ static void refill_rx (struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
np->rx_ring[entry].frag[0].addr = cpu_to_le32(
- pci_map_single(np->pci_dev, skb->data,
+ pci_map_single(np->pci_dev, skb->tail,
np->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
/* Perhaps we need not reset this field. */
diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c
index fc353e348f9a..dd357dd8c370 100644
--- a/trunk/drivers/net/tulip/de2104x.c
+++ b/trunk/drivers/net/tulip/de2104x.c
@@ -446,13 +446,13 @@ static void de_rx (struct de_private *de)
mapping =
de->rx_skb[rx_tail].mapping =
- pci_map_single(de->pdev, copy_skb->data,
+ pci_map_single(de->pdev, copy_skb->tail,
buflen, PCI_DMA_FROMDEVICE);
de->rx_skb[rx_tail].skb = copy_skb;
} else {
pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE);
skb_reserve(copy_skb, RX_OFFSET);
- memcpy(skb_put(copy_skb, len), skb->data, len);
+ memcpy(skb_put(copy_skb, len), skb->tail, len);
pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE);
@@ -1269,7 +1269,7 @@ static int de_refill_rx (struct de_private *de)
skb->dev = de->dev;
de->rx_skb[i].mapping = pci_map_single(de->pdev,
- skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
de->rx_skb[i].skb = skb;
de->rx_ring[i].opts1 = cpu_to_le32(DescOwn);
diff --git a/trunk/drivers/net/tulip/dmfe.c b/trunk/drivers/net/tulip/dmfe.c
index 74e9075d9c48..7b899702ceb9 100644
--- a/trunk/drivers/net/tulip/dmfe.c
+++ b/trunk/drivers/net/tulip/dmfe.c
@@ -945,8 +945,8 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db)
/* Received Packet CRC check need or not */
if ( (db->dm910x_chk_mode & 1) &&
- (cal_CRC(skb->data, rxlen, 1) !=
- (*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */
+ (cal_CRC(skb->tail, rxlen, 1) !=
+ (*(u32 *) (skb->tail+rxlen) ))) { /* FIXME (?) */
/* Found a error received packet */
dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
db->dm910x_chk_mode = 3;
@@ -959,7 +959,7 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db)
/* size less than COPY_SIZE, allocate a rxlen SKB */
skb->dev = dev;
skb_reserve(skb, 2); /* 16byte align */
- memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->data, rxlen);
+ memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen);
dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
} else {
skb->dev = dev;
@@ -1252,7 +1252,7 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb)
if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) {
rxptr->rx_skb_ptr = skb;
- rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+ rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
wmb();
rxptr->rdes0 = cpu_to_le32(0x80000000);
db->rx_avail_cnt++;
@@ -1463,7 +1463,7 @@ static void allocate_rx_buffer(struct dmfe_board_info *db)
if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
break;
rxptr->rx_skb_ptr = skb; /* FIXME (?) */
- rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+ rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
wmb();
rxptr->rdes0 = cpu_to_le32(0x80000000);
rxptr = rxptr->next_rx_desc;
diff --git a/trunk/drivers/net/tulip/interrupt.c b/trunk/drivers/net/tulip/interrupt.c
index bb3558164a5b..afb5cda9d8e1 100644
--- a/trunk/drivers/net/tulip/interrupt.c
+++ b/trunk/drivers/net/tulip/interrupt.c
@@ -78,7 +78,7 @@ int tulip_refill_rx(struct net_device *dev)
if (skb == NULL)
break;
- mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
+ mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
tp->rx_buffers[entry].mapping = mapping;
@@ -199,12 +199,12 @@ int tulip_poll(struct net_device *dev, int *budget)
tp->rx_buffers[entry].mapping,
pkt_len, PCI_DMA_FROMDEVICE);
#if ! defined(__alpha__)
- eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
+ eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
pkt_len, 0);
skb_put(skb, pkt_len);
#else
memcpy(skb_put(skb, pkt_len),
- tp->rx_buffers[entry].skb->data,
+ tp->rx_buffers[entry].skb->tail,
pkt_len);
#endif
pci_dma_sync_single_for_device(tp->pdev,
@@ -423,12 +423,12 @@ static int tulip_rx(struct net_device *dev)
tp->rx_buffers[entry].mapping,
pkt_len, PCI_DMA_FROMDEVICE);
#if ! defined(__alpha__)
- eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
+ eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
pkt_len, 0);
skb_put(skb, pkt_len);
#else
memcpy(skb_put(skb, pkt_len),
- tp->rx_buffers[entry].skb->data,
+ tp->rx_buffers[entry].skb->tail,
pkt_len);
#endif
pci_dma_sync_single_for_device(tp->pdev,
diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c
index d45d8f56e5b4..08e0f80f89d5 100644
--- a/trunk/drivers/net/tulip/tulip_core.c
+++ b/trunk/drivers/net/tulip/tulip_core.c
@@ -625,7 +625,7 @@ static void tulip_init_ring(struct net_device *dev)
tp->rx_buffers[i].skb = skb;
if (skb == NULL)
break;
- mapping = pci_map_single(tp->pdev, skb->data,
+ mapping = pci_map_single(tp->pdev, skb->tail,
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
tp->rx_buffers[i].mapping = mapping;
skb->dev = dev; /* Mark as being used by this device. */
diff --git a/trunk/drivers/net/tulip/winbond-840.c b/trunk/drivers/net/tulip/winbond-840.c
index 5b1af3986abf..db4b32c2369a 100644
--- a/trunk/drivers/net/tulip/winbond-840.c
+++ b/trunk/drivers/net/tulip/winbond-840.c
@@ -849,7 +849,7 @@ static void init_rxtx_rings(struct net_device *dev)
if (skb == NULL)
break;
skb->dev = dev; /* Mark as being used by this device. */
- np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
+ np->rx_addr[i] = pci_map_single(np->pci_dev,skb->tail,
skb->len,PCI_DMA_FROMDEVICE);
np->rx_ring[i].buffer1 = np->rx_addr[i];
@@ -1269,7 +1269,7 @@ static int netdev_rx(struct net_device *dev)
pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
np->rx_skbuff[entry]->len,
PCI_DMA_FROMDEVICE);
- eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
+ eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
np->rx_skbuff[entry]->len,
@@ -1315,7 +1315,7 @@ static int netdev_rx(struct net_device *dev)
break; /* Better luck next round. */
skb->dev = dev; /* Mark as being used by this device. */
np->rx_addr[entry] = pci_map_single(np->pci_dev,
- skb->data,
+ skb->tail,
skb->len, PCI_DMA_FROMDEVICE);
np->rx_ring[entry].buffer1 = np->rx_addr[entry];
}
diff --git a/trunk/drivers/net/tulip/xircom_tulip_cb.c b/trunk/drivers/net/tulip/xircom_tulip_cb.c
index 887d7245fe7b..b8a9b395c5ea 100644
--- a/trunk/drivers/net/tulip/xircom_tulip_cb.c
+++ b/trunk/drivers/net/tulip/xircom_tulip_cb.c
@@ -899,7 +899,7 @@ static void xircom_init_ring(struct net_device *dev)
break;
skb->dev = dev; /* Mark as being used by this device. */
tp->rx_ring[i].status = Rx0DescOwned; /* Owned by Xircom chip */
- tp->rx_ring[i].buffer1 = virt_to_bus(skb->data);
+ tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail);
}
tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1291,7 +1291,7 @@ xircom_rx(struct net_device *dev)
if (skb == NULL)
break;
skb->dev = dev; /* Mark as being used by this device. */
- tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data);
+ tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail);
work_done++;
}
tp->rx_ring[entry].status = Rx0DescOwned;
diff --git a/trunk/drivers/net/typhoon.c b/trunk/drivers/net/typhoon.c
index 0b5ca2537963..8f3392989a06 100644
--- a/trunk/drivers/net/typhoon.c
+++ b/trunk/drivers/net/typhoon.c
@@ -1661,7 +1661,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
#endif
skb->dev = tp->dev;
- dma_addr = pci_map_single(tp->pdev, skb->data,
+ dma_addr = pci_map_single(tp->pdev, skb->tail,
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
/* Since no card does 64 bit DAC, the high bits will never
@@ -1721,7 +1721,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready,
pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
- eth_copy_and_sum(new_skb, skb->data, pkt_len, 0);
+ eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0);
pci_dma_sync_single_for_device(tp->pdev, dma_addr,
PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c
index fc7738ffbfff..be1c1047b9ba 100644
--- a/trunk/drivers/net/via-rhine.c
+++ b/trunk/drivers/net/via-rhine.c
@@ -507,7 +507,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static struct ethtool_ops netdev_ethtool_ops;
static int rhine_close(struct net_device *dev);
-static void rhine_shutdown (struct pci_dev *pdev);
+static void rhine_shutdown (struct device *gdev);
#define RHINE_WAIT_FOR(condition) do { \
int i=1024; \
@@ -990,7 +990,7 @@ static void alloc_rbufs(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
rp->rx_skbuff_dma[i] =
- pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
+ pci_map_single(rp->pdev, skb->tail, rp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]);
@@ -1518,7 +1518,7 @@ static void rhine_rx(struct net_device *dev)
PCI_DMA_FROMDEVICE);
eth_copy_and_sum(skb,
- rp->rx_skbuff[entry]->data,
+ rp->rx_skbuff[entry]->tail,
pkt_len, 0);
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(rp->pdev,
@@ -1561,7 +1561,7 @@ static void rhine_rx(struct net_device *dev)
break; /* Better luck next round. */
skb->dev = dev; /* Mark as being used by this device. */
rp->rx_skbuff_dma[entry] =
- pci_map_single(rp->pdev, skb->data,
+ pci_map_single(rp->pdev, skb->tail,
rp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]);
@@ -1895,8 +1895,9 @@ static void __devexit rhine_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static void rhine_shutdown (struct pci_dev *pdev)
+static void rhine_shutdown (struct device *gendev)
{
+ struct pci_dev *pdev = to_pci_dev(gendev);
struct net_device *dev = pci_get_drvdata(pdev);
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
@@ -1955,7 +1956,7 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev);
spin_lock_irqsave(&rp->lock, flags);
- rhine_shutdown(pdev);
+ rhine_shutdown(&pdev->dev);
spin_unlock_irqrestore(&rp->lock, flags);
free_irq(dev->irq, dev);
@@ -2009,7 +2010,9 @@ static struct pci_driver rhine_driver = {
.suspend = rhine_suspend,
.resume = rhine_resume,
#endif /* CONFIG_PM */
- .shutdown = rhine_shutdown,
+ .driver = {
+ .shutdown = rhine_shutdown,
+ }
};
diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c
index abc5cee6eedc..15e710283493 100644
--- a/trunk/drivers/net/via-velocity.c
+++ b/trunk/drivers/net/via-velocity.c
@@ -1335,7 +1335,7 @@ static inline int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
skb_reserve(new_skb, 2);
- memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
+ memcpy(new_skb->data, rx_skb[0]->tail, pkt_size);
*rx_skb = new_skb;
ret = 0;
}
@@ -1456,9 +1456,9 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
* Do the gymnastics to get the buffer head for data at
* 64byte alignment.
*/
- skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
+ skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63);
rd_info->skb->dev = vptr->dev;
- rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
/*
* Fill in the descriptor to match
diff --git a/trunk/drivers/net/wan/hdlc_cisco.c b/trunk/drivers/net/wan/hdlc_cisco.c
index 87496843681a..c1b6896d7007 100644
--- a/trunk/drivers/net/wan/hdlc_cisco.c
+++ b/trunk/drivers/net/wan/hdlc_cisco.c
@@ -72,7 +72,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
}
skb_reserve(skb, 4);
cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0);
- data = (cisco_packet*)skb->data;
+ data = (cisco_packet*)skb->tail;
data->type = htonl(type);
data->par1 = htonl(par1);
diff --git a/trunk/drivers/net/yellowfin.c b/trunk/drivers/net/yellowfin.c
index 1c2506535f7e..9da925430109 100644
--- a/trunk/drivers/net/yellowfin.c
+++ b/trunk/drivers/net/yellowfin.c
@@ -786,7 +786,7 @@ static void yellowfin_init_ring(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* 16 byte align the IP header. */
yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1111,7 +1111,7 @@ static int yellowfin_rx(struct net_device *dev)
pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr,
yp->rx_buf_sz, PCI_DMA_FROMDEVICE);
desc_status = le32_to_cpu(desc->result_status) >> 16;
- buf_addr = rx_skb->data;
+ buf_addr = rx_skb->tail;
data_size = (le32_to_cpu(desc->dbdma_cmd) -
le32_to_cpu(desc->result_status)) & 0xffff;
frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2])));
@@ -1185,7 +1185,7 @@ static int yellowfin_rx(struct net_device *dev)
break;
skb->dev = dev;
skb_reserve(skb, 2); /* 16 byte align the IP header */
- eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0);
+ eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0);
skb_put(skb, pkt_len);
pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
yp->rx_buf_sz,
@@ -1211,7 +1211,7 @@ static int yellowfin_rx(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
- skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+ skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
}
yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP);
yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */
diff --git a/trunk/drivers/parisc/dino.c b/trunk/drivers/parisc/dino.c
index 2f2dbef2c3b7..b0d2a73d1d47 100644
--- a/trunk/drivers/parisc/dino.c
+++ b/trunk/drivers/parisc/dino.c
@@ -993,7 +993,6 @@ dino_driver_callback(struct parisc_device *dev)
bus = pci_scan_bus_parented(&dev->dev, dino_current_bus,
&dino_cfg_ops, NULL);
if(bus) {
- pci_bus_add_devices(bus);
/* This code *depends* on scanning being single threaded
* if it isn't, this global bus number count will fail
*/
diff --git a/trunk/drivers/parisc/lba_pci.c b/trunk/drivers/parisc/lba_pci.c
index 7fdd80b7eb47..dc838804c0dd 100644
--- a/trunk/drivers/parisc/lba_pci.c
+++ b/trunk/drivers/parisc/lba_pci.c
@@ -1570,8 +1570,6 @@ lba_driver_probe(struct parisc_device *dev)
lba_bus = lba_dev->hba.hba_bus =
pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
cfg_ops, NULL);
- if (lba_bus)
- pci_bus_add_devices(lba_bus);
/* This is in lieu of calling pci_assign_unassigned_resources() */
if (is_pdc_pat()) {
diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c
index fedae89d8f7d..dbd33605cc10 100644
--- a/trunk/drivers/pci/bus.c
+++ b/trunk/drivers/pci/bus.c
@@ -121,13 +121,10 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
* If there is an unattached subordinate bus, attach
* it and then scan for unattached PCI devices.
*/
- if (dev->subordinate) {
- if (list_empty(&dev->subordinate->node)) {
- spin_lock(&pci_bus_lock);
- list_add_tail(&dev->subordinate->node,
- &dev->bus->children);
- spin_unlock(&pci_bus_lock);
- }
+ if (dev->subordinate && list_empty(&dev->subordinate->node)) {
+ spin_lock(&pci_bus_lock);
+ list_add_tail(&dev->subordinate->node, &dev->bus->children);
+ spin_unlock(&pci_bus_lock);
pci_bus_add_devices(dev->subordinate);
sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
diff --git a/trunk/drivers/pci/hotplug/Makefile b/trunk/drivers/pci/hotplug/Makefile
index 3e632ff8c717..93c120ddbd39 100644
--- a/trunk/drivers/pci/hotplug/Makefile
+++ b/trunk/drivers/pci/hotplug/Makefile
@@ -36,7 +36,9 @@ ibmphp-objs := ibmphp_core.o \
ibmphp_hpc.o
acpiphp-objs := acpiphp_core.o \
- acpiphp_glue.o
+ acpiphp_glue.o \
+ acpiphp_pci.o \
+ acpiphp_res.o
rpaphp-objs := rpaphp_core.o \
rpaphp_pci.o \
diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h
index 293603e1b7c3..d9499874c8a9 100644
--- a/trunk/drivers/pci/hotplug/acpiphp.h
+++ b/trunk/drivers/pci/hotplug/acpiphp.h
@@ -7,8 +7,6 @@
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002,2003 NEC Corporation
- * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
- * Copyright (C) 2003-2005 Hewlett Packard
*
* All rights reserved.
*
@@ -54,6 +52,7 @@
struct acpiphp_bridge;
struct acpiphp_slot;
+struct pci_resource;
/*
* struct slot - slot information for each *physical* slot
@@ -66,6 +65,15 @@ struct slot {
struct acpiphp_slot *acpi_slot;
};
+/*
+ * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
+ */
+struct pci_resource {
+ struct pci_resource * next;
+ u64 base;
+ u32 length;
+};
+
/**
* struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
* @cache_line_size in DWORD
@@ -93,6 +101,10 @@ struct acpiphp_bridge {
int type;
int nr_slots;
+ u8 seg;
+ u8 bus;
+ u8 sub;
+
u32 flags;
/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
@@ -105,6 +117,12 @@ struct acpiphp_bridge {
struct hpp_param hpp;
spinlock_t res_lock;
+
+ /* available resources on this bus */
+ struct pci_resource *mem_head;
+ struct pci_resource *p_mem_head;
+ struct pci_resource *io_head;
+ struct pci_resource *bus_head;
};
@@ -145,6 +163,12 @@ struct acpiphp_func {
u8 function; /* pci function# */
u32 flags; /* see below */
+
+ /* resources used for this function */
+ struct pci_resource *mem_head;
+ struct pci_resource *p_mem_head;
+ struct pci_resource *io_head;
+ struct pci_resource *bus_head;
};
/**
@@ -219,6 +243,25 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
+/* acpiphp_pci.c */
+extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
+extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
+extern int acpiphp_configure_function (struct acpiphp_func *func);
+extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
+extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
+extern int acpiphp_init_func_resource (struct acpiphp_func *func);
+
+/* acpiphp_res.c */
+extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
+extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
+extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
+extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
+extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
+extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
+extern void acpiphp_free_resource (struct pci_resource **res);
+extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
+extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
+
/* variables */
extern int acpiphp_debug;
diff --git a/trunk/drivers/pci/hotplug/acpiphp_core.c b/trunk/drivers/pci/hotplug/acpiphp_core.c
index 60c4c38047a3..4539e61a3dc1 100644
--- a/trunk/drivers/pci/hotplug/acpiphp_core.c
+++ b/trunk/drivers/pci/hotplug/acpiphp_core.c
@@ -7,8 +7,6 @@
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002,2003 NEC Corporation
- * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
- * Copyright (C) 2003-2005 Hewlett Packard
*
* All rights reserved.
*
@@ -55,8 +53,8 @@ int acpiphp_debug;
static int num_slots;
static struct acpiphp_attention_info *attention_info;
-#define DRIVER_VERSION "0.5"
-#define DRIVER_AUTHOR "Greg Kroah-Hartman , Takayoshi Kochi , Matthew Wilcox "
+#define DRIVER_VERSION "0.4"
+#define DRIVER_AUTHOR "Greg Kroah-Hartman , Takayoshi Kochi "
#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -283,7 +281,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
/**
* get_address - get pci address of a slot
* @hotplug_slot: slot to get status
- * @value: pointer to struct pci_busdev (seg, bus, dev)
+ * @busdev: pointer to struct pci_busdev (seg, bus, dev)
+ *
*/
static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
{
diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c
index 424e7de181ae..e7f41294f811 100644
--- a/trunk/drivers/pci/hotplug/acpiphp_glue.c
+++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c
@@ -4,10 +4,6 @@
* Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
* Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (C) 2002,2003 NEC Corporation
- * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
- * Copyright (C) 2003-2005 Hewlett Packard
- * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com)
- * Copyright (C) 2005 Intel Corporation
*
* All rights reserved.
*
@@ -30,16 +26,6 @@
*
*/
-/*
- * Lifetime rules for pci_dev:
- * - The one in acpiphp_func has its refcount elevated by pci_get_slot()
- * when the driver is loaded or when an insertion event occurs. It loses
- * a refcount when its ejected or the driver unloads.
- * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
- * when the bridge is scanned and it loses a refcount when the bridge
- * is removed.
- */
-
#include
#include
@@ -192,18 +178,21 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
bridge->nr_slots++;
- dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
- slot->sun, pci_domain_nr(bridge->pci_bus),
- bridge->pci_bus->number, slot->device);
+ dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
+ slot->bridge->bus, slot->device, slot->sun);
}
newfunc->slot = slot;
list_add_tail(&newfunc->sibling, &slot->funcs);
/* associate corresponding pci_dev */
- newfunc->pci_dev = pci_get_slot(bridge->pci_bus,
+ newfunc->pci_dev = pci_find_slot(bridge->bus,
PCI_DEVFN(device, function));
if (newfunc->pci_dev) {
+ if (acpiphp_init_func_resource(newfunc) < 0) {
+ kfree(newfunc);
+ return AE_ERROR;
+ }
slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
}
@@ -238,6 +227,62 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle)
}
+/* decode ACPI _CRS data and convert into our internal resource list
+ * TBD: _TRA, etc.
+ */
+static acpi_status
+decode_acpi_resource(struct acpi_resource *resource, void *context)
+{
+ struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
+ struct acpi_resource_address64 address;
+ struct pci_resource *res;
+
+ if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+ resource->id != ACPI_RSTYPE_ADDRESS32 &&
+ resource->id != ACPI_RSTYPE_ADDRESS64)
+ return AE_OK;
+
+ acpi_resource_to_address64(resource, &address);
+
+ if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
+ dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
+ (unsigned long long)address.min_address_range,
+ (unsigned long long)address.max_address_range);
+ res = acpiphp_make_resource(address.min_address_range,
+ address.address_length);
+ if (!res) {
+ err("out of memory\n");
+ return AE_OK;
+ }
+
+ switch (address.resource_type) {
+ case ACPI_MEMORY_RANGE:
+ if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
+ res->next = bridge->p_mem_head;
+ bridge->p_mem_head = res;
+ } else {
+ res->next = bridge->mem_head;
+ bridge->mem_head = res;
+ }
+ break;
+ case ACPI_IO_RANGE:
+ res->next = bridge->io_head;
+ bridge->io_head = res;
+ break;
+ case ACPI_BUS_NUMBER_RANGE:
+ res->next = bridge->bus_head;
+ bridge->bus_head = res;
+ break;
+ default:
+ /* invalid type */
+ kfree(res);
+ break;
+ }
+ }
+
+ return AE_OK;
+}
+
/* decode ACPI 2.0 _HPP hot plug parameters */
static void decode_hpp(struct acpiphp_bridge *bridge)
{
@@ -301,29 +346,34 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
/* decode ACPI 2.0 _HPP (hot plug parameters) */
decode_hpp(bridge);
+ /* subtract all resources already allocated */
+ acpiphp_detect_pci_resource(bridge);
+
/* register all slot objects under this bridge */
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
register_slot, bridge, NULL);
/* install notify handler */
- if (bridge->type != BRIDGE_TYPE_HOST) {
- status = acpi_install_notify_handler(bridge->handle,
+ status = acpi_install_notify_handler(bridge->handle,
ACPI_SYSTEM_NOTIFY,
handle_hotplug_event_bridge,
bridge);
- if (ACPI_FAILURE(status)) {
- err("failed to register interrupt notify handler\n");
- }
+ if (ACPI_FAILURE(status)) {
+ err("failed to register interrupt notify handler\n");
}
list_add(&bridge->list, &bridge_list);
+
+ dbg("Bridge resource:\n");
+ acpiphp_dump_resource(bridge);
}
/* allocate and initialize host bridge data structure */
-static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
+static void add_host_bridge(acpi_handle *handle, int seg, int bus)
{
+ acpi_status status;
struct acpiphp_bridge *bridge;
bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -334,19 +384,52 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
bridge->type = BRIDGE_TYPE_HOST;
bridge->handle = handle;
+ bridge->seg = seg;
+ bridge->bus = bus;
- bridge->pci_bus = pci_bus;
+ bridge->pci_bus = pci_find_bus(seg, bus);
spin_lock_init(&bridge->res_lock);
+ /* to be overridden when we decode _CRS */
+ bridge->sub = bridge->bus;
+
+ /* decode resources */
+
+ status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+ decode_acpi_resource, bridge);
+
+ if (ACPI_FAILURE(status)) {
+ err("failed to decode bridge resources\n");
+ kfree(bridge);
+ return;
+ }
+
+ acpiphp_resource_sort_and_combine(&bridge->io_head);
+ acpiphp_resource_sort_and_combine(&bridge->mem_head);
+ acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
+ acpiphp_resource_sort_and_combine(&bridge->bus_head);
+
+ dbg("ACPI _CRS resource:\n");
+ acpiphp_dump_resource(bridge);
+
+ if (bridge->bus_head) {
+ bridge->bus = bridge->bus_head->base;
+ bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
+ }
+
init_bridge_misc(bridge);
}
/* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
+static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)
{
struct acpiphp_bridge *bridge;
+ u8 tmp8;
+ u16 tmp16;
+ u64 base64, limit64;
+ u32 base, limit, base32u, limit32u;
bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
if (bridge == NULL) {
@@ -358,22 +441,133 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
bridge->type = BRIDGE_TYPE_P2P;
bridge->handle = handle;
+ bridge->seg = seg;
+
+ bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
+ if (!bridge->pci_dev) {
+ err("Can't get pci_dev\n");
+ kfree(bridge);
+ return;
+ }
- bridge->pci_dev = pci_dev_get(pci_dev);
- bridge->pci_bus = pci_dev->subordinate;
+ bridge->pci_bus = bridge->pci_dev->subordinate;
if (!bridge->pci_bus) {
err("This is not a PCI-to-PCI bridge!\n");
- goto err;
+ kfree(bridge);
+ return;
}
spin_lock_init(&bridge->res_lock);
+ bridge->bus = bridge->pci_bus->number;
+ bridge->sub = bridge->pci_bus->subordinate;
+
+ /*
+ * decode resources under this P2P bridge
+ */
+
+ /* I/O resources */
+ pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
+ base = tmp8;
+ pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
+ limit = tmp8;
+
+ switch (base & PCI_IO_RANGE_TYPE_MASK) {
+ case PCI_IO_RANGE_TYPE_16:
+ base = (base << 8) & 0xf000;
+ limit = ((limit << 8) & 0xf000) + 0xfff;
+ bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
+ if (!bridge->io_head) {
+ err("out of memory\n");
+ kfree(bridge);
+ return;
+ }
+ dbg("16bit I/O range: %04x-%04x\n",
+ (u32)bridge->io_head->base,
+ (u32)(bridge->io_head->base + bridge->io_head->length - 1));
+ break;
+ case PCI_IO_RANGE_TYPE_32:
+ pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
+ base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
+ pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
+ limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
+ bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
+ if (!bridge->io_head) {
+ err("out of memory\n");
+ kfree(bridge);
+ return;
+ }
+ dbg("32bit I/O range: %08x-%08x\n",
+ (u32)bridge->io_head->base,
+ (u32)(bridge->io_head->base + bridge->io_head->length - 1));
+ break;
+ case 0x0f:
+ dbg("I/O space unsupported\n");
+ break;
+ default:
+ warn("Unknown I/O range type\n");
+ }
+
+ /* Memory resources (mandatory for P2P bridge) */
+ pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
+ base = (tmp16 & 0xfff0) << 16;
+ pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
+ limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
+ bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
+ if (!bridge->mem_head) {
+ err("out of memory\n");
+ kfree(bridge);
+ return;
+ }
+ dbg("32bit Memory range: %08x-%08x\n",
+ (u32)bridge->mem_head->base,
+ (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
+
+ /* Prefetchable Memory resources (optional) */
+ pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
+ base = tmp16;
+ pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
+ limit = tmp16;
+
+ switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
+ case PCI_PREF_RANGE_TYPE_32:
+ base = (base & 0xfff0) << 16;
+ limit = ((limit & 0xfff0) << 16) | 0xfffff;
+ bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
+ if (!bridge->p_mem_head) {
+ err("out of memory\n");
+ kfree(bridge);
+ return;
+ }
+ dbg("32bit Prefetchable memory range: %08x-%08x\n",
+ (u32)bridge->p_mem_head->base,
+ (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
+ break;
+ case PCI_PREF_RANGE_TYPE_64:
+ pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
+ pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
+ base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
+ limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
+
+ bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
+ if (!bridge->p_mem_head) {
+ err("out of memory\n");
+ kfree(bridge);
+ return;
+ }
+ dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
+ (u32)(bridge->p_mem_head->base >> 32),
+ (u32)(bridge->p_mem_head->base & 0xffffffff),
+ (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
+ (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
+ break;
+ case 0x0f:
+ break;
+ default:
+ warn("Unknown prefetchale memory type\n");
+ }
+
init_bridge_misc(bridge);
- return;
- err:
- pci_dev_put(pci_dev);
- kfree(bridge);
- return;
}
@@ -383,10 +577,14 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
{
acpi_status status;
acpi_handle dummy_handle;
+ unsigned long *segbus = context;
unsigned long tmp;
- int device, function;
+ int seg, bus, device, function;
struct pci_dev *dev;
- struct pci_bus *pci_bus = context;
+
+ /* get PCI address */
+ seg = (*segbus >> 8) & 0xff;
+ bus = *segbus & 0xff;
status = acpi_get_handle(handle, "_ADR", &dummy_handle);
if (ACPI_FAILURE(status))
@@ -401,19 +599,20 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
device = (tmp >> 16) & 0xffff;
function = tmp & 0xffff;
- dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
+ dev = pci_find_slot(bus, PCI_DEVFN(device, function));
- if (!dev || !dev->subordinate)
- goto out;
+ if (!dev)
+ return AE_OK;
+
+ if (!dev->subordinate)
+ return AE_OK;
/* check if this bridge has ejectable slots */
if (detect_ejectable_slots(handle) > 0) {
dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
- add_p2p_bridge(handle, dev);
+ add_p2p_bridge(handle, seg, bus, device, function);
}
- out:
- pci_dev_put(dev);
return AE_OK;
}
@@ -425,7 +624,6 @@ static int add_bridge(acpi_handle handle)
unsigned long tmp;
int seg, bus;
acpi_handle dummy_handle;
- struct pci_bus *pci_bus;
/* if the bridge doesn't have _STA, we assume it is always there */
status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -455,22 +653,18 @@ static int add_bridge(acpi_handle handle)
bus = 0;
}
- pci_bus = pci_find_bus(seg, bus);
- if (!pci_bus) {
- err("Can't find bus %04x:%02x\n", seg, bus);
- return 0;
- }
-
/* check if this bridge has ejectable slots */
if (detect_ejectable_slots(handle) > 0) {
dbg("found PCI host-bus bridge with hot-pluggable slots\n");
- add_host_bridge(handle, pci_bus);
+ add_host_bridge(handle, seg, bus);
return 0;
}
+ tmp = seg << 8 | bus;
+
/* search P2P bridges under this host bridge */
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
- find_p2p_bridge, pci_bus, NULL);
+ find_p2p_bridge, &tmp, NULL);
if (ACPI_FAILURE(status))
warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
@@ -478,205 +672,12 @@ static int add_bridge(acpi_handle handle)
return 0;
}
-static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
-{
- struct list_head *head;
- list_for_each(head, &bridge_list) {
- struct acpiphp_bridge *bridge = list_entry(head,
- struct acpiphp_bridge, list);
- if (bridge->handle == handle)
- return bridge;
- }
-
- return NULL;
-}
-
-static void cleanup_bridge(struct acpiphp_bridge *bridge)
-{
- struct list_head *list, *tmp;
- struct acpiphp_slot *slot;
- acpi_status status;
- acpi_handle handle = bridge->handle;
-
- status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
- handle_hotplug_event_bridge);
- if (ACPI_FAILURE(status))
- err("failed to remove notify handler\n");
-
- slot = bridge->slots;
- while (slot) {
- struct acpiphp_slot *next = slot->next;
- list_for_each_safe (list, tmp, &slot->funcs) {
- struct acpiphp_func *func;
- func = list_entry(list, struct acpiphp_func, sibling);
- status = acpi_remove_notify_handler(func->handle,
- ACPI_SYSTEM_NOTIFY,
- handle_hotplug_event_func);
- if (ACPI_FAILURE(status))
- err("failed to remove notify handler\n");
- pci_dev_put(func->pci_dev);
- list_del(list);
- kfree(func);
- }
- kfree(slot);
- slot = next;
- }
-
- pci_dev_put(bridge->pci_dev);
- list_del(&bridge->list);
- kfree(bridge);
-}
-
-static acpi_status
-cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- struct acpiphp_bridge *bridge;
-
- if (!(bridge = acpiphp_handle_to_bridge(handle)))
- return AE_OK;
- cleanup_bridge(bridge);
- return AE_OK;
-}
static void remove_bridge(acpi_handle handle)
{
- struct acpiphp_bridge *bridge;
-
- bridge = acpiphp_handle_to_bridge(handle);
- if (bridge) {
- cleanup_bridge(bridge);
- } else {
- /* clean-up p2p bridges under this host bridge */
- acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
- (u32)1, cleanup_p2p_bridge, NULL, NULL);
- }
-}
-
-static struct pci_dev * get_apic_pci_info(acpi_handle handle)
-{
- struct acpi_pci_id id;
- struct pci_bus *bus;
- struct pci_dev *dev;
-
- if (ACPI_FAILURE(acpi_get_pci_id(handle, &id)))
- return NULL;
-
- bus = pci_find_bus(id.segment, id.bus);
- if (!bus)
- return NULL;
-
- dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function));
- if (!dev)
- return NULL;
-
- if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
- (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
- {
- pci_dev_put(dev);
- return NULL;
- }
-
- return dev;
-}
-
-static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
-{
- acpi_status status;
- int result = -1;
- unsigned long gsb;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *obj;
- void *table;
-
- status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
- if (ACPI_SUCCESS(status)) {
- *gsi_base = (u32)gsb;
- return 0;
- }
-
- status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
- if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
- return -1;
-
- obj = buffer.pointer;
- if (obj->type != ACPI_TYPE_BUFFER)
- goto out;
-
- table = obj->buffer.pointer;
- switch (((acpi_table_entry_header *)table)->type) {
- case ACPI_MADT_IOSAPIC:
- *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base;
- result = 0;
- break;
- case ACPI_MADT_IOAPIC:
- *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base;
- result = 0;
- break;
- default:
- break;
- }
- out:
- acpi_os_free(buffer.pointer);
- return result;
-}
-
-static acpi_status
-ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- acpi_status status;
- unsigned long sta;
- acpi_handle tmp;
- struct pci_dev *pdev;
- u32 gsi_base;
- u64 phys_addr;
-
- /* Evaluate _STA if present */
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
- if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
- return AE_CTRL_DEPTH;
-
- /* Scan only PCI bus scope */
- status = acpi_get_handle(handle, "_HID", &tmp);
- if (ACPI_SUCCESS(status))
- return AE_CTRL_DEPTH;
-
- if (get_gsi_base(handle, &gsi_base))
- return AE_OK;
-
- pdev = get_apic_pci_info(handle);
- if (!pdev)
- return AE_OK;
-
- if (pci_enable_device(pdev)) {
- pci_dev_put(pdev);
- return AE_OK;
- }
-
- pci_set_master(pdev);
-
- if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) {
- pci_disable_device(pdev);
- pci_dev_put(pdev);
- return AE_OK;
- }
-
- phys_addr = pci_resource_start(pdev, 0);
- if (acpi_register_ioapic(handle, phys_addr, gsi_base)) {
- pci_release_region(pdev, 0);
- pci_disable_device(pdev);
- pci_dev_put(pdev);
- return AE_OK;
- }
-
- return AE_OK;
+ /* No-op for now .. */
}
-static int acpiphp_configure_ioapics(acpi_handle handle)
-{
- acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
- ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
- return 0;
-}
static int power_on_slot(struct acpiphp_slot *slot)
{
@@ -718,6 +719,8 @@ static int power_off_slot(struct acpiphp_slot *slot)
acpi_status status;
struct acpiphp_func *func;
struct list_head *l;
+ struct acpi_object_list arg_list;
+ union acpi_object arg;
int retval = 0;
@@ -728,7 +731,7 @@ static int power_off_slot(struct acpiphp_slot *slot)
list_for_each (l, &slot->funcs) {
func = list_entry(l, struct acpiphp_func, sibling);
- if (func->flags & FUNC_HAS_PS3) {
+ if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
if (ACPI_FAILURE(status)) {
warn("%s: _PS3 failed\n", __FUNCTION__);
@@ -739,6 +742,27 @@ static int power_off_slot(struct acpiphp_slot *slot)
}
}
+ list_for_each (l, &slot->funcs) {
+ func = list_entry(l, struct acpiphp_func, sibling);
+
+ /* We don't want to call _EJ0 on non-existing functions. */
+ if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
+ /* _EJ0 method take one argument */
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = 1;
+
+ status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
+ if (ACPI_FAILURE(status)) {
+ warn("%s: _EJ0 failed\n", __FUNCTION__);
+ retval = -1;
+ goto err_exit;
+ } else
+ break;
+ }
+ }
+
/* TBD: evaluate _STA to check if the slot is disabled */
slot->flags &= (~SLOT_POWEREDON);
@@ -758,56 +782,70 @@ static int power_off_slot(struct acpiphp_slot *slot)
*/
static int enable_device(struct acpiphp_slot *slot)
{
+ u8 bus;
struct pci_dev *dev;
- struct pci_bus *bus = slot->bridge->pci_bus;
+ struct pci_bus *child;
struct list_head *l;
struct acpiphp_func *func;
int retval = 0;
- int num, max, pass;
+ int num;
if (slot->flags & SLOT_ENABLED)
goto err_exit;
/* sanity check: dev should be NULL when hot-plugged in */
- dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
+ dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
if (dev) {
/* This case shouldn't happen */
err("pci_dev structure already exists.\n");
- pci_dev_put(dev);
retval = -1;
goto err_exit;
}
- num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
- if (num == 0) {
+ /* allocate resources to device */
+ retval = acpiphp_configure_slot(slot);
+ if (retval)
+ goto err_exit;
+
+ /* returned `dev' is the *first function* only! */
+ num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
+ if (num)
+ pci_bus_add_devices(slot->bridge->pci_bus);
+ dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
+
+ if (!dev) {
err("No new device found\n");
retval = -1;
goto err_exit;
}
- max = bus->secondary;
- for (pass = 0; pass < 2; pass++) {
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (PCI_SLOT(dev->devfn) != slot->device)
- continue;
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
- dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
- max = pci_scan_bridge(bus, dev, max, pass);
- }
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
+ child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
+ pci_do_scan_bus(child);
}
- pci_bus_assign_resources(bus);
- pci_bus_add_devices(bus);
-
/* associate pci_dev to our representation */
list_for_each (l, &slot->funcs) {
func = list_entry(l, struct acpiphp_func, sibling);
- func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
+
+ func->pci_dev = pci_find_slot(slot->bridge->bus,
+ PCI_DEVFN(slot->device,
func->function));
+ if (!func->pci_dev)
+ continue;
+
+ /* configure device */
+ retval = acpiphp_configure_function(func);
+ if (retval)
+ goto err_exit;
}
slot->flags |= SLOT_ENABLED;
+ dbg("Available resources:\n");
+ acpiphp_dump_resource(slot->bridge);
+
err_exit:
return retval;
}
@@ -828,12 +866,9 @@ static int disable_device(struct acpiphp_slot *slot)
list_for_each (l, &slot->funcs) {
func = list_entry(l, struct acpiphp_func, sibling);
- if (!func->pci_dev)
- continue;
- pci_remove_bus_device(func->pci_dev);
- pci_dev_put(func->pci_dev);
- func->pci_dev = NULL;
+ if (func->pci_dev)
+ acpiphp_unconfigure_function(func);
}
slot->flags &= (~SLOT_ENABLED);
@@ -884,39 +919,6 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)
return (unsigned int)sta;
}
-/**
- * acpiphp_eject_slot - physically eject the slot
- */
-static int acpiphp_eject_slot(struct acpiphp_slot *slot)
-{
- acpi_status status;
- struct acpiphp_func *func;
- struct list_head *l;
- struct acpi_object_list arg_list;
- union acpi_object arg;
-
- list_for_each (l, &slot->funcs) {
- func = list_entry(l, struct acpiphp_func, sibling);
-
- /* We don't want to call _EJ0 on non-existing functions. */
- if ((func->flags & FUNC_HAS_EJ0)) {
- /* _EJ0 method take one argument */
- arg_list.count = 1;
- arg_list.pointer = &arg;
- arg.type = ACPI_TYPE_INTEGER;
- arg.integer.value = 1;
-
- status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
- if (ACPI_FAILURE(status)) {
- warn("%s: _EJ0 failed\n", __FUNCTION__);
- return -1;
- } else
- break;
- }
- }
- return 0;
-}
-
/**
* acpiphp_check_bridge - re-enumerate devices
*
@@ -940,8 +942,6 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
if (retval) {
err("Error occurred in disabling\n");
goto err_exit;
- } else {
- acpiphp_eject_slot(slot);
}
disabled++;
} else {
@@ -962,144 +962,6 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
return retval;
}
-static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
-{
- u16 pci_cmd, pci_bctl;
- struct pci_dev *cdev;
-
- /* Program hpp values for this device */
- if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
- (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
- (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
- return;
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
- bridge->hpp.cache_line_size);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER,
- bridge->hpp.latency_timer);
- pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
- if (bridge->hpp.enable_SERR)
- pci_cmd |= PCI_COMMAND_SERR;
- else
- pci_cmd &= ~PCI_COMMAND_SERR;
- if (bridge->hpp.enable_PERR)
- pci_cmd |= PCI_COMMAND_PARITY;
- else
- pci_cmd &= ~PCI_COMMAND_PARITY;
- pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
-
- /* Program bridge control value and child devices */
- if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
- pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
- bridge->hpp.latency_timer);
- pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
- if (bridge->hpp.enable_SERR)
- pci_bctl |= PCI_BRIDGE_CTL_SERR;
- else
- pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
- if (bridge->hpp.enable_PERR)
- pci_bctl |= PCI_BRIDGE_CTL_PARITY;
- else
- pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
- pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
- if (dev->subordinate) {
- list_for_each_entry(cdev, &dev->subordinate->devices,
- bus_list)
- program_hpp(cdev, bridge);
- }
- }
-}
-
-static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
-{
- struct acpiphp_bridge bridge;
- struct pci_dev *dev;
-
- memset(&bridge, 0, sizeof(bridge));
- bridge.handle = handle;
- decode_hpp(&bridge);
- list_for_each_entry(dev, &bus->devices, bus_list)
- program_hpp(dev, &bridge);
-
-}
-
-/*
- * Remove devices for which we could not assign resources, call
- * arch specific code to fix-up the bus
- */
-static void acpiphp_sanitize_bus(struct pci_bus *bus)
-{
- struct pci_dev *dev;
- int i;
- unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- for (i=0; iresource[i];
- if ((res->flags & type_mask) && !res->start &&
- res->end) {
- /* Could not assign a required resources
- * for this device, remove it */
- pci_remove_bus_device(dev);
- break;
- }
- }
- }
-}
-
-/* Program resources in newly inserted bridge */
-static int acpiphp_configure_bridge (acpi_handle handle)
-{
- struct acpi_pci_id pci_id;
- struct pci_bus *bus;
-
- if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {
- err("cannot get PCI domain and bus number for bridge\n");
- return -EINVAL;
- }
- bus = pci_find_bus(pci_id.segment, pci_id.bus);
- if (!bus) {
- err("cannot find bus %d:%d\n",
- pci_id.segment, pci_id.bus);
- return -EINVAL;
- }
-
- pci_bus_size_bridges(bus);
- pci_bus_assign_resources(bus);
- acpiphp_sanitize_bus(bus);
- acpiphp_set_hpp_values(handle, bus);
- pci_enable_bridges(bus);
- acpiphp_configure_ioapics(handle);
- return 0;
-}
-
-static void handle_bridge_insertion(acpi_handle handle, u32 type)
-{
- struct acpi_device *device, *pdevice;
- acpi_handle phandle;
-
- if ((type != ACPI_NOTIFY_BUS_CHECK) &&
- (type != ACPI_NOTIFY_DEVICE_CHECK)) {
- err("unexpected notification type %d\n", type);
- return;
- }
-
- acpi_get_parent(handle, &phandle);
- if (acpi_bus_get_device(phandle, &pdevice)) {
- dbg("no parent device, assuming NULL\n");
- pdevice = NULL;
- }
- if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
- err("cannot add bridge to acpi list\n");
- return;
- }
- if (!acpiphp_configure_bridge(handle) &&
- !acpi_bus_start(device))
- add_bridge(handle);
- else
- err("cannot configure and start bridge\n");
-
-}
-
/*
* ACPI event handlers
*/
@@ -1120,19 +982,8 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
- struct acpi_device *device;
- if (acpi_bus_get_device(handle, &device)) {
- /* This bridge must have just been physically inserted */
- handle_bridge_insertion(handle, type);
- return;
- }
-
- bridge = acpiphp_handle_to_bridge(handle);
- if (!bridge) {
- err("cannot get bridge info\n");
- return;
- }
+ bridge = (struct acpiphp_bridge *)context;
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
@@ -1180,6 +1031,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
}
}
+
/**
* handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
*
@@ -1222,8 +1074,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
case ACPI_NOTIFY_EJECT_REQUEST:
/* request device eject */
dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
- if (!(acpiphp_disable_slot(func->slot)))
- acpiphp_eject_slot(func->slot);
+ acpiphp_disable_slot(func->slot);
break;
default:
@@ -1232,47 +1083,6 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex
}
}
-static int is_root_bridge(acpi_handle handle)
-{
- acpi_status status;
- struct acpi_device_info *info;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- int i;
-
- status = acpi_get_object_info(handle, &buffer);
- if (ACPI_SUCCESS(status)) {
- info = buffer.pointer;
- if ((info->valid & ACPI_VALID_HID) &&
- !strcmp(PCI_ROOT_HID_STRING,
- info->hardware_id.value)) {
- acpi_os_free(buffer.pointer);
- return 1;
- }
- if (info->valid & ACPI_VALID_CID) {
- for (i=0; i < info->compatibility_id.count; i++) {
- if (!strcmp(PCI_ROOT_HID_STRING,
- info->compatibility_id.id[i].value)) {
- acpi_os_free(buffer.pointer);
- return 1;
- }
- }
- }
- }
- return 0;
-}
-
-static acpi_status
-find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- int *count = (int *)context;
-
- if (is_root_bridge(handle)) {
- acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
- handle_hotplug_event_bridge, NULL);
- (*count)++;
- }
- return AE_OK ;
-}
static struct acpi_pci_driver acpi_pci_hp_driver = {
.add = add_bridge,
@@ -1285,15 +1095,15 @@ static struct acpi_pci_driver acpi_pci_hp_driver = {
*/
int __init acpiphp_glue_init(void)
{
- int num = 0;
+ int num;
+
+ if (list_empty(&pci_root_buses))
+ return -1;
- acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
+ num = acpi_pci_register_driver(&acpi_pci_hp_driver);
if (num <= 0)
return -1;
- else
- acpi_pci_register_driver(&acpi_pci_hp_driver);
return 0;
}
@@ -1306,6 +1116,46 @@ int __init acpiphp_glue_init(void)
*/
void __exit acpiphp_glue_exit(void)
{
+ struct list_head *l1, *l2, *n1, *n2;
+ struct acpiphp_bridge *bridge;
+ struct acpiphp_slot *slot, *next;
+ struct acpiphp_func *func;
+ acpi_status status;
+
+ list_for_each_safe (l1, n1, &bridge_list) {
+ bridge = (struct acpiphp_bridge *)l1;
+ slot = bridge->slots;
+ while (slot) {
+ next = slot->next;
+ list_for_each_safe (l2, n2, &slot->funcs) {
+ func = list_entry(l2, struct acpiphp_func, sibling);
+ acpiphp_free_resource(&func->io_head);
+ acpiphp_free_resource(&func->mem_head);
+ acpiphp_free_resource(&func->p_mem_head);
+ acpiphp_free_resource(&func->bus_head);
+ status = acpi_remove_notify_handler(func->handle,
+ ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_func);
+ if (ACPI_FAILURE(status))
+ err("failed to remove notify handler\n");
+ kfree(func);
+ }
+ kfree(slot);
+ slot = next;
+ }
+ status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
+ handle_hotplug_event_bridge);
+ if (ACPI_FAILURE(status))
+ err("failed to remove notify handler\n");
+
+ acpiphp_free_resource(&bridge->io_head);
+ acpiphp_free_resource(&bridge->mem_head);
+ acpiphp_free_resource(&bridge->p_mem_head);
+ acpiphp_free_resource(&bridge->bus_head);
+
+ kfree(bridge);
+ }
+
acpi_pci_unregister_driver(&acpi_pci_hp_driver);
}
@@ -1323,14 +1173,11 @@ int __init acpiphp_get_num_slots(void)
list_for_each (node, &bridge_list) {
bridge = (struct acpiphp_bridge *)node;
- dbg("Bus %04x:%02x has %d slot%s\n",
- pci_domain_nr(bridge->pci_bus),
- bridge->pci_bus->number, bridge->nr_slots,
- bridge->nr_slots == 1 ? "" : "s");
+ dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
num_slots += bridge->nr_slots;
}
- dbg("Total %d slots\n", num_slots);
+ dbg("Total %dslots\n", num_slots);
return num_slots;
}
@@ -1407,6 +1254,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
return retval;
}
+
/**
* acpiphp_disable_slot - power off slot
*/
@@ -1426,6 +1274,13 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
if (retval)
goto err_exit;
+ acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
+ acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
+ acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
+ acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
+ dbg("Available resources:\n");
+ acpiphp_dump_resource(slot->bridge);
+
err_exit:
up(&slot->crit_sect);
return retval;
@@ -1438,7 +1293,11 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot)
*/
u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
{
- return (slot->flags & SLOT_POWEREDON);
+ unsigned int sta;
+
+ sta = get_slot_status(slot);
+
+ return (sta & ACPI_STA_ENABLED) ? 1 : 0;
}
@@ -1476,10 +1335,9 @@ u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot)
u32 acpiphp_get_address(struct acpiphp_slot *slot)
{
u32 address;
- struct pci_bus *pci_bus = slot->bridge->pci_bus;
- address = (pci_domain_nr(pci_bus) << 16) |
- (pci_bus->number << 8) |
+ address = ((slot->bridge->seg) << 16) |
+ ((slot->bridge->bus) << 8) |
slot->device;
return address;
diff --git a/trunk/drivers/pci/hotplug/acpiphp_pci.c b/trunk/drivers/pci/hotplug/acpiphp_pci.c
new file mode 100644
index 000000000000..54d97c9d1dff
--- /dev/null
+++ b/trunk/drivers/pci/hotplug/acpiphp_pci.c
@@ -0,0 +1,449 @@
+/*
+ * ACPI PCI HotPlug PCI configuration space management
+ *
+ * Copyright (C) 1995,2001 Compaq Computer Corporation
+ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2001,2002 IBM Corp.
+ * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (C) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to
+ *
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include "../pci.h"
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+#define MY_NAME "acpiphp_pci"
+
+
+/* allocate mem/pmem/io resource to a new function */
+static int init_config_space (struct acpiphp_func *func)
+{
+ u32 bar, len;
+ u32 address[] = {
+ PCI_BASE_ADDRESS_0,
+ PCI_BASE_ADDRESS_1,
+ PCI_BASE_ADDRESS_2,
+ PCI_BASE_ADDRESS_3,
+ PCI_BASE_ADDRESS_4,
+ PCI_BASE_ADDRESS_5,
+ 0
+ };
+ int count;
+ struct acpiphp_bridge *bridge;
+ struct pci_resource *res;
+ struct pci_bus *pbus;
+ int bus, device, function;
+ unsigned int devfn;
+ u16 tmp;
+
+ bridge = func->slot->bridge;
+ pbus = bridge->pci_bus;
+ bus = bridge->bus;
+ device = func->slot->device;
+ function = func->function;
+ devfn = PCI_DEVFN(device, function);
+
+ for (count = 0; address[count]; count++) { /* for 6 BARs */
+ pci_bus_write_config_dword(pbus, devfn,
+ address[count], 0xFFFFFFFF);
+ pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
+
+ if (!bar) /* This BAR is not implemented */
+ continue;
+
+ dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
+
+ if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
+ /* This is IO */
+
+ len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
+ len = len & ~(len - 1);
+
+ dbg("len in IO %x, BAR %d\n", len, count);
+
+ spin_lock(&bridge->res_lock);
+ res = acpiphp_get_io_resource(&bridge->io_head, len);
+ spin_unlock(&bridge->res_lock);
+
+ if (!res) {
+ err("cannot allocate requested io for %02x:%02x.%d len %x\n",
+ bus, device, function, len);
+ return -1;
+ }
+ pci_bus_write_config_dword(pbus, devfn,
+ address[count],
+ (u32)res->base);
+ res->next = func->io_head;
+ func->io_head = res;
+
+ } else {
+ /* This is Memory */
+ if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+ /* pfmem */
+
+ len = bar & 0xFFFFFFF0;
+ len = ~len + 1;
+
+ dbg("len in PFMEM %x, BAR %d\n", len, count);
+
+ spin_lock(&bridge->res_lock);
+ res = acpiphp_get_resource(&bridge->p_mem_head, len);
+ spin_unlock(&bridge->res_lock);
+
+ if (!res) {
+ err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
+ bus, device, function, len);
+ return -1;
+ }
+
+ pci_bus_write_config_dword(pbus, devfn,
+ address[count],
+ (u32)res->base);
+
+ if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
+ dbg("inside the pfmem 64 case, count %d\n", count);
+ count += 1;
+ pci_bus_write_config_dword(pbus, devfn,
+ address[count],
+ (u32)(res->base >> 32));
+ }
+
+ res->next = func->p_mem_head;
+ func->p_mem_head = res;
+
+ } else {
+ /* regular memory */
+
+ len = bar & 0xFFFFFFF0;
+ len = ~len + 1;
+
+ dbg("len in MEM %x, BAR %d\n", len, count);
+
+ spin_lock(&bridge->res_lock);
+ res = acpiphp_get_resource(&bridge->mem_head, len);
+ spin_unlock(&bridge->res_lock);
+
+ if (!res) {
+ err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
+ bus, device, function, len);
+ return -1;
+ }
+
+ pci_bus_write_config_dword(pbus, devfn,
+ address[count],
+ (u32)res->base);
+
+ if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ /* takes up another dword */
+ dbg("inside mem 64 case, reg. mem, count %d\n", count);
+ count += 1;
+ pci_bus_write_config_dword(pbus, devfn,
+ address[count],
+ (u32)(res->base >> 32));
+ }
+
+ res->next = func->mem_head;
+ func->mem_head = res;
+
+ }
+ }
+ }
+
+ /* disable expansion rom */
+ pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
+
+ /* set PCI parameters from _HPP */
+ pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
+ bridge->hpp.cache_line_size);
+ pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
+ bridge->hpp.latency_timer);
+
+ pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
+ if (bridge->hpp.enable_SERR)
+ tmp |= PCI_COMMAND_SERR;
+ if (bridge->hpp.enable_PERR)
+ tmp |= PCI_COMMAND_PARITY;
+ pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
+
+ return 0;
+}
+
+/* detect_used_resource - subtract resource under dev from bridge */
+static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
+{
+ int count;
+
+ dbg("Device %s\n", pci_name(dev));
+
+ for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
+ struct pci_resource *res;
+ struct pci_resource **head;
+ unsigned long base = dev->resource[count].start;
+ unsigned long len = dev->resource[count].end - base + 1;
+ unsigned long flags = dev->resource[count].flags;
+
+ if (!flags)
+ continue;
+
+ dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
+ base + len - 1, flags);
+
+ if (flags & IORESOURCE_IO) {
+ head = &bridge->io_head;
+ } else if (flags & IORESOURCE_PREFETCH) {
+ head = &bridge->p_mem_head;
+ } else {
+ head = &bridge->mem_head;
+ }
+
+ spin_lock(&bridge->res_lock);
+ res = acpiphp_get_resource_with_base(head, base, len);
+ spin_unlock(&bridge->res_lock);
+ if (res)
+ kfree(res);
+ }
+
+ return 0;
+}
+
+
+/**
+ * acpiphp_detect_pci_resource - detect resources under bridge
+ * @bridge: detect all resources already used under this bridge
+ *
+ * collect all resources already allocated for all devices under a bridge.
+ */
+int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
+{
+ struct list_head *l;
+ struct pci_dev *dev;
+
+ list_for_each (l, &bridge->pci_bus->devices) {
+ dev = pci_dev_b(l);
+ detect_used_resource(bridge, dev);
+ }
+
+ return 0;
+}
+
+
+/**
+ * acpiphp_init_slot_resource - gather resource usage information of a slot
+ * @slot: ACPI slot object to be checked, should have valid pci_dev member
+ *
+ * TBD: PCI-to-PCI bridge case
+ * use pci_dev->resource[]
+ */
+int acpiphp_init_func_resource (struct acpiphp_func *func)
+{
+ u64 base;
+ u32 bar, len;
+ u32 address[] = {
+ PCI_BASE_ADDRESS_0,
+ PCI_BASE_ADDRESS_1,
+ PCI_BASE_ADDRESS_2,
+ PCI_BASE_ADDRESS_3,
+ PCI_BASE_ADDRESS_4,
+ PCI_BASE_ADDRESS_5,
+ 0
+ };
+ int count;
+ struct pci_resource *res;
+ struct pci_dev *dev;
+
+ dev = func->pci_dev;
+ dbg("Hot-pluggable device %s\n", pci_name(dev));
+
+ for (count = 0; address[count]; count++) { /* for 6 BARs */
+ pci_read_config_dword(dev, address[count], &bar);
+
+ if (!bar) /* This BAR is not implemented */
+ continue;
+
+ pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
+ pci_read_config_dword(dev, address[count], &len);
+
+ if (len & PCI_BASE_ADDRESS_SPACE_IO) {
+ /* This is IO */
+ base = bar & 0xFFFFFFFC;
+ len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
+ len = len & ~(len - 1);
+
+ dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
+
+ res = acpiphp_make_resource(base, len);
+ if (!res)
+ goto no_memory;
+
+ res->next = func->io_head;
+ func->io_head = res;
+
+ } else {
+ /* This is Memory */
+ base = bar & 0xFFFFFFF0;
+ if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+ /* pfmem */
+
+ len &= 0xFFFFFFF0;
+ len = ~len + 1;
+
+ if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */
+ dbg("prefetch mem 64\n");
+ count += 1;
+ }
+ dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
+ res = acpiphp_make_resource(base, len);
+ if (!res)
+ goto no_memory;
+
+ res->next = func->p_mem_head;
+ func->p_mem_head = res;
+
+ } else {
+ /* regular memory */
+
+ len &= 0xFFFFFFF0;
+ len = ~len + 1;
+
+ if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ /* takes up another dword */
+ dbg("mem 64\n");
+ count += 1;
+ }
+ dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
+ res = acpiphp_make_resource(base, len);
+ if (!res)
+ goto no_memory;
+
+ res->next = func->mem_head;
+ func->mem_head = res;
+
+ }
+ }
+
+ pci_write_config_dword(dev, address[count], bar);
+ }
+#if 1
+ acpiphp_dump_func_resource(func);
+#endif
+
+ return 0;
+
+ no_memory:
+ err("out of memory\n");
+ acpiphp_free_resource(&func->io_head);
+ acpiphp_free_resource(&func->mem_head);
+ acpiphp_free_resource(&func->p_mem_head);
+
+ return -1;
+}
+
+
+/**
+ * acpiphp_configure_slot - allocate PCI resources
+ * @slot: slot to be configured
+ *
+ * initializes a PCI functions on a device inserted
+ * into the slot
+ *
+ */
+int acpiphp_configure_slot (struct acpiphp_slot *slot)
+{
+ struct acpiphp_func *func;
+ struct list_head *l;
+ u8 hdr;
+ u32 dvid;
+ int retval = 0;
+ int is_multi = 0;
+
+ pci_bus_read_config_byte(slot->bridge->pci_bus,
+ PCI_DEVFN(slot->device, 0),
+ PCI_HEADER_TYPE, &hdr);
+
+ if (hdr & 0x80)
+ is_multi = 1;
+
+ list_for_each (l, &slot->funcs) {
+ func = list_entry(l, struct acpiphp_func, sibling);
+ if (is_multi || func->function == 0) {
+ pci_bus_read_config_dword(slot->bridge->pci_bus,
+ PCI_DEVFN(slot->device,
+ func->function),
+ PCI_VENDOR_ID, &dvid);
+ if (dvid != 0xffffffff) {
+ retval = init_config_space(func);
+ if (retval)
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * acpiphp_configure_function - configure PCI function
+ * @func: function to be configured
+ *
+ * initializes a PCI functions on a device inserted
+ * into the slot
+ *
+ */
+int acpiphp_configure_function (struct acpiphp_func *func)
+{
+ /* all handled by the pci core now */
+ return 0;
+}
+
+/**
+ * acpiphp_unconfigure_function - unconfigure PCI function
+ * @func: function to be unconfigured
+ *
+ */
+void acpiphp_unconfigure_function (struct acpiphp_func *func)
+{
+ struct acpiphp_bridge *bridge;
+
+ /* if pci_dev is NULL, ignore it */
+ if (!func->pci_dev)
+ return;
+
+ pci_remove_bus_device(func->pci_dev);
+
+ /* free all resources */
+ bridge = func->slot->bridge;
+
+ spin_lock(&bridge->res_lock);
+ acpiphp_move_resource(&func->io_head, &bridge->io_head);
+ acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
+ acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
+ acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
+ spin_unlock(&bridge->res_lock);
+}
diff --git a/trunk/drivers/pci/hotplug/acpiphp_res.c b/trunk/drivers/pci/hotplug/acpiphp_res.c
new file mode 100644
index 000000000000..f54b1fa7b75a
--- /dev/null
+++ b/trunk/drivers/pci/hotplug/acpiphp_res.c
@@ -0,0 +1,700 @@
+/*
+ * ACPI PCI HotPlug Utility functions
+ *
+ * Copyright (C) 1995,2001 Compaq Computer Corporation
+ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2001 IBM Corp.
+ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
+ * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
+ * Copyright (C) 2002 NEC Corporation
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to ,
+ *
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include "pci_hotplug.h"
+#include "acpiphp.h"
+
+#define MY_NAME "acpiphp_res"
+
+
+/*
+ * sort_by_size - sort nodes by their length, smallest first
+ */
+static int sort_by_size(struct pci_resource **head)
+{
+ struct pci_resource *current_res;
+ struct pci_resource *next_res;
+ int out_of_order = 1;
+
+ if (!(*head))
+ return 1;
+
+ if (!((*head)->next))
+ return 0;
+
+ while (out_of_order) {
+ out_of_order = 0;
+
+ /* Special case for swapping list head */
+ if (((*head)->next) &&
+ ((*head)->length > (*head)->next->length)) {
+ out_of_order++;
+ current_res = *head;
+ *head = (*head)->next;
+ current_res->next = (*head)->next;
+ (*head)->next = current_res;
+ }
+
+ current_res = *head;
+
+ while (current_res->next && current_res->next->next) {
+ if (current_res->next->length > current_res->next->next->length) {
+ out_of_order++;
+ next_res = current_res->next;
+ current_res->next = current_res->next->next;
+ current_res = current_res->next;
+ next_res->next = current_res->next;
+ current_res->next = next_res;
+ } else
+ current_res = current_res->next;
+ }
+ } /* End of out_of_order loop */
+
+ return 0;
+}
+
+#if 0
+/*
+ * sort_by_max_size - sort nodes by their length, largest first
+ */
+static int sort_by_max_size(struct pci_resource **head)
+{
+ struct pci_resource *current_res;
+ struct pci_resource *next_res;
+ int out_of_order = 1;
+
+ if (!(*head))
+ return 1;
+
+ if (!((*head)->next))
+ return 0;
+
+ while (out_of_order) {
+ out_of_order = 0;
+
+ /* Special case for swapping list head */
+ if (((*head)->next) &&
+ ((*head)->length < (*head)->next->length)) {
+ out_of_order++;
+ current_res = *head;
+ *head = (*head)->next;
+ current_res->next = (*head)->next;
+ (*head)->next = current_res;
+ }
+
+ current_res = *head;
+
+ while (current_res->next && current_res->next->next) {
+ if (current_res->next->length < current_res->next->next->length) {
+ out_of_order++;
+ next_res = current_res->next;
+ current_res->next = current_res->next->next;
+ current_res = current_res->next;
+ next_res->next = current_res->next;
+ current_res->next = next_res;
+ } else
+ current_res = current_res->next;
+ }
+ } /* End of out_of_order loop */
+
+ return 0;
+}
+#endif
+
+/**
+ * get_io_resource - get resource for I/O ports
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length that is not in the
+ * ISA aliasing window. If it finds a node larger than "size"
+ * it will split it up.
+ *
+ * size must be a power of two.
+ *
+ * difference from get_resource is handling of ISA aliasing space.
+ *
+ */
+struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
+{
+ struct pci_resource *prevnode;
+ struct pci_resource *node;
+ struct pci_resource *split_node;
+ u64 temp_qword;
+
+ if (!(*head))
+ return NULL;
+
+ if (acpiphp_resource_sort_and_combine(head))
+ return NULL;
+
+ if (sort_by_size(head))
+ return NULL;
+
+ for (node = *head; node; node = node->next) {
+ if (node->length < size)
+ continue;
+
+ if (node->base & (size - 1)) {
+ /* this one isn't base aligned properly
+ so we'll make a new entry and split it up */
+ temp_qword = (node->base | (size-1)) + 1;
+
+ /* Short circuit if adjusted size is too small */
+ if ((node->length - (temp_qword - node->base)) < size)
+ continue;
+
+ split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
+
+ if (!split_node)
+ return NULL;
+
+ node->base = temp_qword;
+ node->length -= split_node->length;
+
+ /* Put it in the list */
+ split_node->next = node->next;
+ node->next = split_node;
+ } /* End of non-aligned base */
+
+ /* Don't need to check if too small since we already did */
+ if (node->length > size) {
+ /* this one is longer than we need
+ so we'll make a new entry and split it up */
+ split_node = acpiphp_make_resource(node->base + size, node->length - size);
+
+ if (!split_node)
+ return NULL;
+
+ node->length = size;
+
+ /* Put it in the list */
+ split_node->next = node->next;
+ node->next = split_node;
+ } /* End of too big on top end */
+
+ /* For IO make sure it's not in the ISA aliasing space */
+ if ((node->base & 0x300L) && !(node->base & 0xfffff000))
+ continue;
+
+ /* If we got here, then it is the right size
+ Now take it out of the list */
+ if (*head == node) {
+ *head = node->next;
+ } else {
+ prevnode = *head;
+ while (prevnode->next != node)
+ prevnode = prevnode->next;
+
+ prevnode->next = node->next;
+ }
+ node->next = NULL;
+ /* Stop looping */
+ break;
+ }
+
+ return node;
+}
+
+
+#if 0
+/**
+ * get_max_resource - get the largest resource
+ *
+ * Gets the largest node that is at least "size" big from the
+ * list pointed to by head. It aligns the node on top and bottom
+ * to "size" alignment before returning it.
+ */
+static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
+{
+ struct pci_resource *max;
+ struct pci_resource *temp;
+ struct pci_resource *split_node;
+ u64 temp_qword;
+
+ if (!(*head))
+ return NULL;
+
+ if (acpiphp_resource_sort_and_combine(head))
+ return NULL;
+
+ if (sort_by_max_size(head))
+ return NULL;
+
+ for (max = *head;max; max = max->next) {
+
+ /* If not big enough we could probably just bail,
+ instead we'll continue to the next. */
+ if (max->length < size)
+ continue;
+
+ if (max->base & (size - 1)) {
+ /* this one isn't base aligned properly
+ so we'll make a new entry and split it up */
+ temp_qword = (max->base | (size-1)) + 1;
+
+ /* Short circuit if adjusted size is too small */
+ if ((max->length - (temp_qword - max->base)) < size)
+ continue;
+
+ split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
+
+ if (!split_node)
+ return NULL;
+
+ max->base = temp_qword;
+ max->length -= split_node->length;
+
+ /* Put it next in the list */
+ split_node->next = max->next;
+ max->next = split_node;
+ }
+
+ if ((max->base + max->length) & (size - 1)) {
+ /* this one isn't end aligned properly at the top
+ so we'll make a new entry and split it up */
+ temp_qword = ((max->base + max->length) & ~(size - 1));
+
+ split_node = acpiphp_make_resource(temp_qword,
+ max->length + max->base - temp_qword);
+
+ if (!split_node)
+ return NULL;
+
+ max->length -= split_node->length;
+
+ /* Put it in the list */
+ split_node->next = max->next;
+ max->next = split_node;
+ }
+
+ /* Make sure it didn't shrink too much when we aligned it */
+ if (max->length < size)
+ continue;
+
+ /* Now take it out of the list */
+ temp = (struct pci_resource*) *head;
+ if (temp == max) {
+ *head = max->next;
+ } else {
+ while (temp && temp->next != max) {
+ temp = temp->next;
+ }
+
+ temp->next = max->next;
+ }
+
+ max->next = NULL;
+ return max;
+ }
+
+ /* If we get here, we couldn't find one */
+ return NULL;
+}
+#endif
+
+/**
+ * get_resource - get resource (mem, pfmem)
+ *
+ * this function sorts the resource list by size and then
+ * returns the first node of "size" length. If it finds a node
+ * larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ *
+ */
+struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
+{
+ struct pci_resource *prevnode;
+ struct pci_resource *node;
+ struct pci_resource *split_node;
+ u64 temp_qword;
+
+ if (!(*head))
+ return NULL;
+
+ if (acpiphp_resource_sort_and_combine(head))
+ return NULL;
+
+ if (sort_by_size(head))
+ return NULL;
+
+ for (node = *head; node; node = node->next) {
+ dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
+ __FUNCTION__, size, node, (u32)node->base, node->length);
+ if (node->length < size)
+ continue;
+
+ if (node->base & (size - 1)) {
+ dbg("%s: not aligned\n", __FUNCTION__);
+ /* this one isn't base aligned properly
+ so we'll make a new entry and split it up */
+ temp_qword = (node->base | (size-1)) + 1;
+
+ /* Short circuit if adjusted size is too small */
+ if ((node->length - (temp_qword - node->base)) < size)
+ continue;
+
+ split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
+
+ if (!split_node)
+ return NULL;
+
+ node->base = temp_qword;
+ node->length -= split_node->length;
+
+ /* Put it in the list */
+ split_node->next = node->next;
+ node->next = split_node;
+ } /* End of non-aligned base */
+
+ /* Don't need to check if too small since we already did */
+ if (node->length > size) {
+ dbg("%s: too big\n", __FUNCTION__);
+ /* this one is longer than we need
+ so we'll make a new entry and split it up */
+ split_node = acpiphp_make_resource(node->base + size, node->length - size);
+
+ if (!split_node)
+ return NULL;
+
+ node->length = size;
+
+ /* Put it in the list */
+ split_node->next = node->next;
+ node->next = split_node;
+ } /* End of too big on top end */
+
+ dbg("%s: got one!!!\n", __FUNCTION__);
+ /* If we got here, then it is the right size
+ Now take it out of the list */
+ if (*head == node) {
+ *head = node->next;
+ } else {
+ prevnode = *head;
+ while (prevnode->next != node)
+ prevnode = prevnode->next;
+
+ prevnode->next = node->next;
+ }
+ node->next = NULL;
+ /* Stop looping */
+ break;
+ }
+ return node;
+}
+
+/**
+ * get_resource_with_base - get resource with specific base address
+ *
+ * this function
+ * returns the first node of "size" length located at specified base address.
+ * If it finds a node larger than "size" it will split it up.
+ *
+ * size must be a power of two.
+ *
+ */
+struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
+{
+ struct pci_resource *prevnode;
+ struct pci_resource *node;
+ struct pci_resource *split_node;
+ u64 temp_qword;
+
+ if (!(*head))
+ return NULL;
+
+ if (acpiphp_resource_sort_and_combine(head))
+ return NULL;
+
+ for (node = *head; node; node = node->next) {
+ dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
+ (u32)base, size, node, (u32)node->base, node->length);
+ if (node->base > base)
+ continue;
+
+ if ((node->base + node->length) < (base + size))
+ continue;
+
+ if (node->base < base) {
+ dbg(": split 1\n");
+ /* this one isn't base aligned properly
+ so we'll make a new entry and split it up */
+ temp_qword = base;
+
+ /* Short circuit if adjusted size is too small */
+ if ((node->length - (temp_qword - node->base)) < size)
+ continue;
+
+ split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
+
+ if (!split_node)
+ return NULL;
+
+ node->base = temp_qword;
+ node->length -= split_node->length;
+
+ /* Put it in the list */
+ split_node->next = node->next;
+ node->next = split_node;
+ }
+
+ dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
+ (u32)base, size, node, (u32)node->base, node->length);
+
+ /* Don't need to check if too small since we already did */
+ if (node->length > size) {
+ dbg(": split 2\n");
+ /* this one is longer than we need
+ so we'll make a new entry and split it up */
+ split_node = acpiphp_make_resource(node->base + size, node->length - size);
+
+ if (!split_node)
+ return NULL;
+
+ node->length = size;
+
+ /* Put it in the list */
+ split_node->next = node->next;
+ node->next = split_node;
+ } /* End of too big on top end */
+
+ dbg(": got one!!!\n");
+ /* If we got here, then it is the right size
+ Now take it out of the list */
+ if (*head == node) {
+ *head = node->next;
+ } else {
+ prevnode = *head;
+ while (prevnode->next != node)
+ prevnode = prevnode->next;
+
+ prevnode->next = node->next;
+ }
+ node->next = NULL;
+ /* Stop looping */
+ break;
+ }
+ return node;
+}
+
+
+/**
+ * acpiphp_resource_sort_and_combine
+ *
+ * Sorts all of the nodes in the list in ascending order by
+ * their base addresses. Also does garbage collection by
+ * combining adjacent nodes.
+ *
+ * returns 0 if success
+ */
+int acpiphp_resource_sort_and_combine (struct pci_resource **head)
+{
+ struct pci_resource *node1;
+ struct pci_resource *node2;
+ int out_of_order = 1;
+
+ if (!(*head))
+ return 1;
+
+ dbg("*head->next = %p\n",(*head)->next);
+
+ if (!(*head)->next)
+ return 0; /* only one item on the list, already sorted! */
+
+ dbg("*head->base = 0x%x\n",(u32)(*head)->base);
+ dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
+ while (out_of_order) {
+ out_of_order = 0;
+
+ /* Special case for swapping list head */
+ if (((*head)->next) &&
+ ((*head)->base > (*head)->next->base)) {
+ node1 = *head;
+ (*head) = (*head)->next;
+ node1->next = (*head)->next;
+ (*head)->next = node1;
+ out_of_order++;
+ }
+
+ node1 = (*head);
+
+ while (node1->next && node1->next->next) {
+ if (node1->next->base > node1->next->next->base) {
+ out_of_order++;
+ node2 = node1->next;
+ node1->next = node1->next->next;
+ node1 = node1->next;
+ node2->next = node1->next;
+ node1->next = node2;
+ } else
+ node1 = node1->next;
+ }
+ } /* End of out_of_order loop */
+
+ node1 = *head;
+
+ while (node1 && node1->next) {
+ if ((node1->base + node1->length) == node1->next->base) {
+ /* Combine */
+ dbg("8..\n");
+ node1->length += node1->next->length;
+ node2 = node1->next;
+ node1->next = node1->next->next;
+ kfree(node2);
+ } else
+ node1 = node1->next;
+ }
+
+ return 0;
+}
+
+
+/**
+ * acpiphp_make_resource - make resource structure
+ * @base: base address of a resource
+ * @length: length of a resource
+ */
+struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
+{
+ struct pci_resource *res;
+
+ res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ if (res) {
+ memset(res, 0, sizeof(struct pci_resource));
+ res->base = base;
+ res->length = length;
+ }
+
+ return res;
+}
+
+
+/**
+ * acpiphp_move_resource - move linked resources from one to another
+ * @from: head of linked resource list
+ * @to: head of linked resource list
+ */
+void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
+{
+ struct pci_resource *tmp;
+
+ while (*from) {
+ tmp = (*from)->next;
+ (*from)->next = *to;
+ *to = *from;
+ *from = tmp;
+ }
+
+ /* *from = NULL is guaranteed */
+}
+
+
+/**
+ * acpiphp_free_resource - free all linked resources
+ * @res: head of linked resource list
+ */
+void acpiphp_free_resource (struct pci_resource **res)
+{
+ struct pci_resource *tmp;
+
+ while (*res) {
+ tmp = (*res)->next;
+ kfree(*res);
+ *res = tmp;
+ }
+
+ /* *res = NULL is guaranteed */
+}
+
+
+/* debug support functions; will go away sometime :) */
+static void dump_resource(struct pci_resource *head)
+{
+ struct pci_resource *p;
+ int cnt;
+
+ p = head;
+ cnt = 0;
+
+ while (p) {
+ dbg("[%02d] %08x - %08x\n",
+ cnt++, (u32)p->base, (u32)p->base + p->length - 1);
+ p = p->next;
+ }
+}
+
+void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
+{
+ dbg("I/O resource:\n");
+ dump_resource(bridge->io_head);
+ dbg("MEM resource:\n");
+ dump_resource(bridge->mem_head);
+ dbg("PMEM resource:\n");
+ dump_resource(bridge->p_mem_head);
+ dbg("BUS resource:\n");
+ dump_resource(bridge->bus_head);
+}
+
+void acpiphp_dump_func_resource(struct acpiphp_func *func)
+{
+ dbg("I/O resource:\n");
+ dump_resource(func->io_head);
+ dbg("MEM resource:\n");
+ dump_resource(func->mem_head);
+ dbg("PMEM resource:\n");
+ dump_resource(func->p_mem_head);
+ dbg("BUS resource:\n");
+ dump_resource(func->bus_head);
+}
diff --git a/trunk/drivers/pci/hotplug/cpqphp_core.c b/trunk/drivers/pci/hotplug/cpqphp_core.c
index 8c6d3987d461..afbccfa5217d 100644
--- a/trunk/drivers/pci/hotplug/cpqphp_core.c
+++ b/trunk/drivers/pci/hotplug/cpqphp_core.c
@@ -60,7 +60,6 @@ static void __iomem *smbios_start;
static void __iomem *cpqhp_rom_start;
static int power_mode;
static int debug;
-static int initialized;
#define DRIVER_VERSION "0.9.8"
#define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman "
@@ -1272,6 +1271,7 @@ static int one_time_init(void)
{
int loop;
int retval = 0;
+ static int initialized = 0;
if (initialized)
return 0;
@@ -1441,8 +1441,7 @@ static void __exit unload_cpqphpd(void)
}
// Stop the notification mechanism
- if (initialized)
- cpqhp_event_stop_thread();
+ cpqhp_event_stop_thread();
//unmap the rom address
if (cpqhp_rom_start)
diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c
index b5ab9aa6ff7c..30206ac43c44 100644
--- a/trunk/drivers/pci/msi.c
+++ b/trunk/drivers/pci/msi.c
@@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static kmem_cache_t* msi_cachep;
static int pci_msi_enable = 1;
-static int last_alloc_vector;
-static int nr_released_vectors;
+static int last_alloc_vector = 0;
+static int nr_released_vectors = 0;
static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
-static int nr_msix_devices;
+static int nr_msix_devices = 0;
#ifndef CONFIG_X86_IO_APIC
int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
@@ -170,31 +170,45 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
return 0; /* never anything pending */
}
-static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
+static void release_msi(unsigned int vector);
+static void shutdown_msi_irq(unsigned int vector)
{
- startup_msi_irq_wo_maskbit(vector);
- unmask_MSI_irq(vector);
- return 0; /* never anything pending */
+ release_msi(vector);
}
-static void shutdown_msi_irq(unsigned int vector)
+#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq
+static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
+static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
+static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
+static void end_msi_irq_wo_maskbit(unsigned int vector)
+{
+ move_msi(vector);
+ ack_APIC_irq();
+}
+
+static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
{
struct msi_desc *entry;
unsigned long flags;
spin_lock_irqsave(&msi_lock, flags);
entry = msi_desc[vector];
- if (entry && entry->dev)
- entry->msi_attrib.state = 0; /* Mark it not active */
+ if (!entry || !entry->dev) {
+ spin_unlock_irqrestore(&msi_lock, flags);
+ return 0;
+ }
+ entry->msi_attrib.state = 1; /* Mark it active */
spin_unlock_irqrestore(&msi_lock, flags);
-}
-static void end_msi_irq_wo_maskbit(unsigned int vector)
-{
- move_msi(vector);
- ack_APIC_irq();
+ unmask_MSI_irq(vector);
+ return 0; /* never anything pending */
}
+#define shutdown_msi_irq_w_maskbit shutdown_msi_irq
+#define enable_msi_irq_w_maskbit unmask_MSI_irq
+#define disable_msi_irq_w_maskbit mask_MSI_irq
+#define ack_msi_irq_w_maskbit mask_MSI_irq
+
static void end_msi_irq_w_maskbit(unsigned int vector)
{
move_msi(vector);
@@ -202,10 +216,6 @@ static void end_msi_irq_w_maskbit(unsigned int vector)
ack_APIC_irq();
}
-static void do_nothing(unsigned int vector)
-{
-}
-
/*
* Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
* which implement the MSI-X Capability Structure.
@@ -213,10 +223,10 @@ static void do_nothing(unsigned int vector)
static struct hw_interrupt_type msix_irq_type = {
.typename = "PCI-MSI-X",
.startup = startup_msi_irq_w_maskbit,
- .shutdown = shutdown_msi_irq,
- .enable = unmask_MSI_irq,
- .disable = mask_MSI_irq,
- .ack = mask_MSI_irq,
+ .shutdown = shutdown_msi_irq_w_maskbit,
+ .enable = enable_msi_irq_w_maskbit,
+ .disable = disable_msi_irq_w_maskbit,
+ .ack = ack_msi_irq_w_maskbit,
.end = end_msi_irq_w_maskbit,
.set_affinity = set_msi_irq_affinity
};
@@ -229,10 +239,10 @@ static struct hw_interrupt_type msix_irq_type = {
static struct hw_interrupt_type msi_irq_w_maskbit_type = {
.typename = "PCI-MSI",
.startup = startup_msi_irq_w_maskbit,
- .shutdown = shutdown_msi_irq,
- .enable = unmask_MSI_irq,
- .disable = mask_MSI_irq,
- .ack = mask_MSI_irq,
+ .shutdown = shutdown_msi_irq_w_maskbit,
+ .enable = enable_msi_irq_w_maskbit,
+ .disable = disable_msi_irq_w_maskbit,
+ .ack = ack_msi_irq_w_maskbit,
.end = end_msi_irq_w_maskbit,
.set_affinity = set_msi_irq_affinity
};
@@ -245,10 +255,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = {
static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
.typename = "PCI-MSI",
.startup = startup_msi_irq_wo_maskbit,
- .shutdown = shutdown_msi_irq,
- .enable = do_nothing,
- .disable = do_nothing,
- .ack = do_nothing,
+ .shutdown = shutdown_msi_irq_wo_maskbit,
+ .enable = enable_msi_irq_wo_maskbit,
+ .disable = disable_msi_irq_wo_maskbit,
+ .ack = ack_msi_irq_wo_maskbit,
.end = end_msi_irq_wo_maskbit,
.set_affinity = set_msi_irq_affinity
};
@@ -397,7 +407,7 @@ static struct msi_desc* alloc_msi_entry(void)
{
struct msi_desc *entry;
- entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
+ entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
if (!entry)
return NULL;
@@ -786,6 +796,18 @@ void pci_disable_msi(struct pci_dev* dev)
}
}
+static void release_msi(unsigned int vector)
+{
+ struct msi_desc *entry;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msi_lock, flags);
+ entry = msi_desc[vector];
+ if (entry && entry->dev)
+ entry->msi_attrib.state = 0; /* Mark it not active */
+ spin_unlock_irqrestore(&msi_lock, flags);
+}
+
static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
{
struct msi_desc *entry;
@@ -902,7 +924,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
/**
* pci_enable_msix - configure device's MSI-X capability structure
* @dev: pointer to the pci_dev data structure of MSI-X device function
- * @entries: pointer to an array of MSI-X entries
+ * @data: pointer to an array of MSI-X entries
* @nvec: number of MSI-X vectors requested for allocation by device driver
*
* Setup the MSI-X capability structure of device function with the number
diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h
index 390f1851c0f1..bef21ae3cbd0 100644
--- a/trunk/drivers/pci/msi.h
+++ b/trunk/drivers/pci/msi.h
@@ -41,11 +41,11 @@ static inline void move_msi(int vector) {}
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
#define PCI_MSIX_FLAGS_BITMASK (1 << 0)
+#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
+#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
+#define PCI_MSIX_ENTRY_DATA_OFFSET 8
+#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
#define PCI_MSIX_ENTRY_SIZE 16
-#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0
-#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4
-#define PCI_MSIX_ENTRY_DATA_OFFSET 8
-#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12
#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO)
@@ -64,6 +64,7 @@ static inline void move_msi(int vector) {}
#define msi_enable(control, num) multi_msi_enable(control, num); \
control |= PCI_MSI_FLAGS_ENABLE
+#define msix_control_reg msi_control_reg
#define msix_table_offset_reg(base) (base + 0x04)
#define msix_pba_offset_reg(base) (base + 0x08)
#define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE
diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c
index cc9d65388e62..a15f94072a6f 100644
--- a/trunk/drivers/pci/pci-sysfs.c
+++ b/trunk/drivers/pci/pci-sysfs.c
@@ -60,18 +60,15 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf)
char * str = buf;
int i;
int max = 7;
- u64 start, end;
if (pci_dev->subordinate)
max = DEVICE_COUNT_RESOURCE;
for (i = 0; i < max; i++) {
- struct resource *res = &pci_dev->resource[i];
- pci_resource_to_user(pci_dev, i, res, &start, &end);
- str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
- (unsigned long long)start,
- (unsigned long long)end,
- (unsigned long long)res->flags);
+ str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",
+ pci_resource_start(pci_dev,i),
+ pci_resource_end(pci_dev,i),
+ pci_resource_flags(pci_dev,i));
}
return (str - buf);
}
@@ -316,21 +313,8 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
struct device, kobj));
struct resource *res = (struct resource *)attr->private;
enum pci_mmap_state mmap_type;
- u64 start, end;
- int i;
- for (i = 0; i < PCI_ROM_RESOURCE; i++)
- if (res == &pdev->resource[i])
- break;
- if (i >= PCI_ROM_RESOURCE)
- return -ENODEV;
-
- /* pci_mmap_page_range() expects the same kind of entry as coming
- * from /proc/bus/pci/ which is a "user visible" value. If this is
- * different from the resource itself, arch will do necessary fixup.
- */
- pci_resource_to_user(pdev, i, res, &start, &end);
- vma->vm_pgoff += start >> PAGE_SHIFT;
+ vma->vm_pgoff += res->start >> PAGE_SHIFT;
mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
return pci_mmap_page_range(pdev, vma, mmap_type, 0);
diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c
index 6a0a82f0508b..fd48b201eb53 100644
--- a/trunk/drivers/pci/probe.c
+++ b/trunk/drivers/pci/probe.c
@@ -374,11 +374,8 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
struct pci_bus *child;
child = pci_alloc_child_bus(parent, dev, busnr);
- if (child) {
- spin_lock(&pci_bus_lock);
+ if (child)
list_add_tail(&child->node, &parent->children);
- spin_unlock(&pci_bus_lock);
- }
return child;
}
@@ -414,7 +411,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
{
struct pci_bus *child;
int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
- u32 buses, i;
+ u32 buses;
u16 bctl;
pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -450,7 +447,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
return max;
}
- child = pci_add_new_bus(bus, dev, busnr);
+ child = pci_alloc_child_bus(bus, dev, busnr);
if (!child)
return max;
child->primary = buses & 0xFF;
@@ -473,11 +470,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
/* Clear errors */
pci_write_config_word(dev, PCI_STATUS, 0xffff);
- /* Prevent assigning a bus number that already exists.
- * This can happen when a bridge is hot-plugged */
- if (pci_find_bus(pci_domain_nr(bus), max+1))
- return max;
- child = pci_add_new_bus(bus, dev, ++max);
+ child = pci_alloc_child_bus(bus, dev, ++max);
buses = (buses & 0xff000000)
| ((unsigned int)(child->primary) << 0)
| ((unsigned int)(child->secondary) << 8)
@@ -508,11 +501,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
* as cards with a PCI-to-PCI bridge can be
* inserted later.
*/
- for (i=0; iglobal_list);
- spin_lock(&pci_bus_lock);
list_add_tail(&dev->bus_list, &bus->devices);
- spin_unlock(&pci_bus_lock);
return dev;
}
@@ -891,9 +878,7 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
goto err_out;
}
- spin_lock(&pci_bus_lock);
list_add_tail(&b->node, &pci_root_buses);
- spin_unlock(&pci_bus_lock);
memset(dev, 0, sizeof(*dev));
dev->parent = parent;
@@ -926,6 +911,8 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
b->subordinate = pci_scan_child_bus(b);
+ pci_bus_add_devices(b);
+
return b;
sys_create_link_err:
@@ -935,9 +922,7 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus,
class_dev_reg_err:
device_unregister(dev);
dev_reg_err:
- spin_lock(&pci_bus_lock);
list_del(&b->node);
- spin_unlock(&pci_bus_lock);
err_out:
kfree(dev);
kfree(b);
diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c
index 7988fc8df3fd..e68bbfb1e7c3 100644
--- a/trunk/drivers/pci/proc.c
+++ b/trunk/drivers/pci/proc.c
@@ -355,20 +355,14 @@ static int show_device(struct seq_file *m, void *v)
dev->device,
dev->irq);
/* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
- for (i=0; i<7; i++) {
- u64 start, end;
- pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
+ for(i=0; i<7; i++)
seq_printf(m, LONG_FORMAT,
- ((unsigned long)start) |
+ dev->resource[i].start |
(dev->resource[i].flags & PCI_REGION_FLAG_MASK));
- }
- for (i=0; i<7; i++) {
- u64 start, end;
- pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
+ for(i=0; i<7; i++)
seq_printf(m, LONG_FORMAT,
dev->resource[i].start < dev->resource[i].end ?
- (unsigned long)(end - start) + 1 : 0);
- }
+ dev->resource[i].end - dev->resource[i].start + 1 : 0);
seq_putc(m, '\t');
if (drv)
seq_printf(m, "%s", drv->name);
diff --git a/trunk/drivers/pci/remove.c b/trunk/drivers/pci/remove.c
index 27a294b6965d..96f077f9a659 100644
--- a/trunk/drivers/pci/remove.c
+++ b/trunk/drivers/pci/remove.c
@@ -18,21 +18,17 @@ static void pci_free_resources(struct pci_dev *dev)
static void pci_destroy_dev(struct pci_dev *dev)
{
- if (!list_empty(&dev->global_list)) {
- pci_proc_detach_device(dev);
- pci_remove_sysfs_dev_files(dev);
- device_unregister(&dev->dev);
- spin_lock(&pci_bus_lock);
- list_del(&dev->global_list);
- dev->global_list.next = dev->global_list.prev = NULL;
- spin_unlock(&pci_bus_lock);
- }
+ pci_proc_detach_device(dev);
+ pci_remove_sysfs_dev_files(dev);
+ device_unregister(&dev->dev);
/* Remove the device from the device lists, and prevent any further
* list accesses from this device */
spin_lock(&pci_bus_lock);
list_del(&dev->bus_list);
+ list_del(&dev->global_list);
dev->bus_list.next = dev->bus_list.prev = NULL;
+ dev->global_list.next = dev->global_list.prev = NULL;
spin_unlock(&pci_bus_lock);
pci_free_resources(dev);
diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c
index 6b628de948af..1ba84be0b4c0 100644
--- a/trunk/drivers/pci/setup-bus.c
+++ b/trunk/drivers/pci/setup-bus.c
@@ -72,10 +72,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
for (list = head.next; list;) {
res = list->res;
idx = res - &list->dev->resource[0];
- if (pci_assign_resource(list->dev, idx)) {
- res->start = 0;
- res->flags = 0;
- }
+ pci_assign_resource(list->dev, idx);
tmp = list;
list = list->next;
kfree(tmp);
diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c
index d5afd557fe37..cabddd49f6ff 100644
--- a/trunk/drivers/pcmcia/ds.c
+++ b/trunk/drivers/pcmcia/ds.c
@@ -847,7 +847,7 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]);
pcmcia_device_stringattr(prod_id3, prod_id[2]);
pcmcia_device_stringattr(prod_id4, prod_id[3]);
-static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev, char *buf)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
int i;
diff --git a/trunk/drivers/scsi/3w-9xxx.c b/trunk/drivers/scsi/3w-9xxx.c
index bc6e4627c7a1..34dbc37a79d4 100644
--- a/trunk/drivers/scsi/3w-9xxx.c
+++ b/trunk/drivers/scsi/3w-9xxx.c
@@ -1916,9 +1916,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev)
} /* End __twa_shutdown() */
/* Wrapper for __twa_shutdown */
-static void twa_shutdown(struct pci_dev *pdev)
+static void twa_shutdown(struct device *dev)
{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
+ struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
__twa_shutdown(tw_dev);
@@ -2140,7 +2140,9 @@ static struct pci_driver twa_driver = {
.id_table = twa_pci_tbl,
.probe = twa_probe,
.remove = twa_remove,
- .shutdown = twa_shutdown
+ .driver = {
+ .shutdown = twa_shutdown
+ }
};
/* This function is called on driver initialization */
diff --git a/trunk/drivers/scsi/3w-xxxx.c b/trunk/drivers/scsi/3w-xxxx.c
index 973c51fb0fe2..b6dc576da430 100644
--- a/trunk/drivers/scsi/3w-xxxx.c
+++ b/trunk/drivers/scsi/3w-xxxx.c
@@ -2264,9 +2264,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev)
} /* End __tw_shutdown() */
/* Wrapper for __tw_shutdown */
-static void tw_shutdown(struct pci_dev *pdev)
+static void tw_shutdown(struct device *dev)
{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
+ struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
__tw_shutdown(tw_dev);
@@ -2451,7 +2451,9 @@ static struct pci_driver tw_driver = {
.id_table = tw_pci_tbl,
.probe = tw_probe,
.remove = tw_remove,
- .shutdown = tw_shutdown,
+ .driver = {
+ .shutdown = tw_shutdown
+ }
};
/* This function is called on driver initialization */
diff --git a/trunk/drivers/scsi/ahci.c b/trunk/drivers/scsi/ahci.c
index c5623694d10f..9a547ca9c864 100644
--- a/trunk/drivers/scsi/ahci.c
+++ b/trunk/drivers/scsi/ahci.c
@@ -304,19 +304,26 @@ static int ahci_port_start(struct ata_port *ap)
struct device *dev = ap->host_set->dev;
struct ahci_host_priv *hpriv = ap->host_set->private_data;
struct ahci_port_priv *pp;
+ int rc;
void *mem, *mmio = ap->host_set->mmio_base;
void *port_mmio = ahci_port_base(mmio, ap->port_no);
dma_addr_t mem_dma;
+ rc = ata_port_start(ap);
+ if (rc)
+ return rc;
+
pp = kmalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp)
- return -ENOMEM;
+ if (!pp) {
+ rc = -ENOMEM;
+ goto err_out;
+ }
memset(pp, 0, sizeof(*pp));
mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
if (!mem) {
- kfree(pp);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto err_out_kfree;
}
memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
@@ -366,6 +373,12 @@ static int ahci_port_start(struct ata_port *ap)
readl(port_mmio + PORT_CMD); /* flush */
return 0;
+
+err_out_kfree:
+ kfree(pp);
+err_out:
+ ata_port_stop(ap);
+ return rc;
}
@@ -391,6 +404,7 @@ static void ahci_port_stop(struct ata_port *ap)
dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
pp->cmd_slot, pp->cmd_slot_dma);
kfree(pp);
+ ata_port_stop(ap);
}
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c
index babd48363402..80d022625c82 100644
--- a/trunk/drivers/scsi/ipr.c
+++ b/trunk/drivers/scsi/ipr.c
@@ -6012,7 +6012,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev,
/**
* ipr_shutdown - Shutdown handler.
- * @pdev: pci device struct
+ * @dev: device struct
*
* This function is invoked upon system shutdown/reboot. It will issue
* an adapter shutdown to the adapter to flush the write cache.
@@ -6020,9 +6020,9 @@ static int __devinit ipr_probe(struct pci_dev *pdev,
* Return value:
* none
**/
-static void ipr_shutdown(struct pci_dev *pdev)
+static void ipr_shutdown(struct device *dev)
{
- struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
+ struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev));
unsigned long lock_flags = 0;
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -6068,7 +6068,9 @@ static struct pci_driver ipr_driver = {
.id_table = ipr_pci_table,
.probe = ipr_probe,
.remove = ipr_remove,
- .shutdown = ipr_shutdown,
+ .driver = {
+ .shutdown = ipr_shutdown,
+ },
};
/**
diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c
index cb535fa185b9..36b401fee1f1 100644
--- a/trunk/drivers/scsi/libata-core.c
+++ b/trunk/drivers/scsi/libata-core.c
@@ -1408,9 +1408,7 @@ void __sata_phy_reset(struct ata_port *ap)
if (ap->flags & ATA_FLAG_SATA_RESET) {
/* issue phy wake/reset */
scr_write_flush(ap, SCR_CONTROL, 0x301);
- /* Couldn't find anything in SATA I/II specs, but
- * AHCI-1.1 10.4.2 says at least 1 ms. */
- mdelay(1);
+ udelay(400); /* FIXME: a guess */
}
scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
@@ -1922,7 +1920,6 @@ static const char * ata_dma_blacklist [] = {
"HITACHI CDR-8335",
"HITACHI CDR-8435",
"Toshiba CD-ROM XM-6202B",
- "TOSHIBA CD-ROM XM-1702BC",
"CD-532E-A",
"E-IDE CD-ROM CR-840",
"CD-ROM Drive/F5A",
@@ -1930,6 +1927,7 @@ static const char * ata_dma_blacklist [] = {
"SAMSUNG CD-ROM SC-148C",
"SAMSUNG CD-ROM SC",
"SanDisk SDP3B-64",
+ "SAMSUNG CD-ROM SN-124",
"ATAPI CD-ROM DRIVE 40X MAXIMUM",
"_NEC DV5800A",
};
diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c
index a70cdf31311c..ec81532eb845 100644
--- a/trunk/drivers/scsi/megaraid.c
+++ b/trunk/drivers/scsi/megaraid.c
@@ -5036,9 +5036,9 @@ megaraid_remove_one(struct pci_dev *pdev)
}
static void
-megaraid_shutdown(struct pci_dev *pdev)
+megaraid_shutdown(struct device *dev)
{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
+ struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
adapter_t *adapter = (adapter_t *)host->hostdata;
__megaraid_shutdown(adapter);
@@ -5070,7 +5070,9 @@ static struct pci_driver megaraid_pci_driver = {
.id_table = megaraid_pci_tbl,
.probe = megaraid_probe_one,
.remove = __devexit_p(megaraid_remove_one),
- .shutdown = megaraid_shutdown,
+ .driver = {
+ .shutdown = megaraid_shutdown,
+ },
};
static int __init megaraid_init(void)
diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c
index 10506f9cd0c9..621dee8b8cb2 100644
--- a/trunk/drivers/scsi/scsi_lib.c
+++ b/trunk/drivers/scsi/scsi_lib.c
@@ -632,7 +632,7 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index)
{
struct scsi_host_sg_pool *sgp;
- BUG_ON(index >= SG_MEMPOOL_NR);
+ BUG_ON(index > SG_MEMPOOL_NR);
sgp = scsi_sg_pools + index;
mempool_free(sgl, sgp->pool);
diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c
index 9224fc3184ea..34e75bc8f4cc 100644
--- a/trunk/drivers/serial/8250.c
+++ b/trunk/drivers/serial/8250.c
@@ -105,7 +105,7 @@ static struct old_serial_port old_serial_port[] = {
SERIAL_PORT_DFNS /* defined in asm/serial.h */
};
-#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
+#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS)
#ifdef CONFIG_SERIAL_8250_RSA
@@ -993,24 +993,21 @@ static void autoconfig_irq(struct uart_8250_port *up)
up->port.irq = (irq > 0) ? irq : 0;
}
-static inline void __stop_tx(struct uart_8250_port *p)
-{
- if (p->ier & UART_IER_THRI) {
- p->ier &= ~UART_IER_THRI;
- serial_out(p, UART_IER, p->ier);
- }
-}
-
static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
- __stop_tx(up);
+ if (up->ier & UART_IER_THRI) {
+ up->ier &= ~UART_IER_THRI;
+ serial_out(up, UART_IER, up->ier);
+ }
/*
- * We really want to stop the transmitter from sending.
+ * We only do this from uart_stop - if we run out of
+ * characters to send, we don't want to prevent the
+ * FIFO from emptying.
*/
- if (up->port.type == PORT_16C950) {
+ if (up->port.type == PORT_16C950 && tty_stop) {
up->acr |= UART_ACR_TXDIS;
serial_icr_write(up, UART_ACR, up->acr);
}
@@ -1034,11 +1031,10 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
transmit_chars(up);
}
}
-
/*
- * Re-enable the transmitter if we disabled it.
+ * We only do this from uart_start
*/
- if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
+ if (tty_start && up->port.type == PORT_16C950) {
up->acr &= ~UART_ACR_TXDIS;
serial_icr_write(up, UART_ACR, up->acr);
}
@@ -1159,7 +1155,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
return;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
- __stop_tx(up);
+ serial8250_stop_tx(&up->port, 0);
return;
}
@@ -1178,7 +1174,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
DEBUG_INTR("THRE...");
if (uart_circ_empty(xmit))
- __stop_tx(up);
+ serial8250_stop_tx(&up->port, 0);
}
static _INLINE_ void check_modem_status(struct uart_8250_port *up)
@@ -1380,10 +1376,13 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
+ unsigned long flags;
unsigned char status;
unsigned int ret;
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
+ spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig
index e0d0a470ddfc..e879bce160df 100644
--- a/trunk/drivers/serial/Kconfig
+++ b/trunk/drivers/serial/Kconfig
@@ -86,7 +86,7 @@ config SERIAL_8250_ACPI
namespace, say Y here. If unsure, say N.
config SERIAL_8250_NR_UARTS
- int "Maximum number of 8250/16550 serial ports"
+ int "Maximum number of non-legacy 8250/16550 serial ports"
depends on SERIAL_8250
default "4"
help
diff --git a/trunk/drivers/serial/au1x00_uart.c b/trunk/drivers/serial/au1x00_uart.c
index 6104aeef1243..5400dc2c087e 100644
--- a/trunk/drivers/serial/au1x00_uart.c
+++ b/trunk/drivers/serial/au1x00_uart.c
@@ -556,10 +556,13 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
+ unsigned long flags;
unsigned char status;
unsigned int ret;
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
+ spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
diff --git a/trunk/drivers/serial/ip22zilog.c b/trunk/drivers/serial/ip22zilog.c
index ea5bf4d4daa3..3ea46c069f6f 100644
--- a/trunk/drivers/serial/ip22zilog.c
+++ b/trunk/drivers/serial/ip22zilog.c
@@ -518,28 +518,27 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re
static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
{
struct zilog_channel *channel;
+ unsigned long flags;
unsigned char status;
+ spin_lock_irqsave(&port->lock, flags);
+
channel = ZILOG_CHANNEL_FROM_PORT(port);
status = readb(&channel->control);
ZSDELAY();
+ spin_unlock_irqrestore(&port->lock, flags);
+
return status;
}
/* The port lock is not held. */
static unsigned int ip22zilog_tx_empty(struct uart_port *port)
{
- unsigned long flags;
unsigned char status;
unsigned int ret;
- spin_lock_irqsave(&port->lock, flags);
-
status = ip22zilog_read_channel_status(port);
-
- spin_unlock_irqrestore(&port->lock, flags);
-
if (status & Tx_BUF_EMP)
ret = TIOCSER_TEMT;
else
@@ -548,7 +547,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port)
return ret;
}
-/* The port lock is held and interrupts are disabled. */
+/* The port lock is not held. */
static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
{
unsigned char status;
diff --git a/trunk/drivers/serial/mpsc.c b/trunk/drivers/serial/mpsc.c
index e43276c6a954..a2a643318002 100644
--- a/trunk/drivers/serial/mpsc.c
+++ b/trunk/drivers/serial/mpsc.c
@@ -1058,9 +1058,12 @@ mpsc_get_mctrl(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
u32 mflags, status;
+ ulong iflags;
+ spin_lock_irqsave(&pi->port.lock, iflags);
status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
readl(pi->mpsc_base + MPSC_CHR_10);
+ spin_unlock_irqrestore(&pi->port.lock, iflags);
mflags = 0;
if (status & 0x1)
diff --git a/trunk/drivers/serial/pmac_zilog.c b/trunk/drivers/serial/pmac_zilog.c
index 1c9f71617123..85abd8a045e0 100644
--- a/trunk/drivers/serial/pmac_zilog.c
+++ b/trunk/drivers/serial/pmac_zilog.c
@@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
/*
* Get Modem Control bits (only the input ones, the core will
* or that with a cached value of the control ones)
- * The port lock is held and interrupts are disabled.
+ * The port lock is not held.
*/
static unsigned int pmz_get_mctrl(struct uart_port *port)
{
@@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port)
if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
return 0;
- status = read_zsreg(uap, R0);
+ status = pmz_peek_status(to_pmz(port));
ret = 0;
if (status & DCD)
diff --git a/trunk/drivers/serial/pxa.c b/trunk/drivers/serial/pxa.c
index 461c81c93207..08b08d6ae904 100644
--- a/trunk/drivers/serial/pxa.c
+++ b/trunk/drivers/serial/pxa.c
@@ -274,11 +274,14 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port)
static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
{
struct uart_pxa_port *up = (struct uart_pxa_port *)port;
+ unsigned long flags;
unsigned char status;
unsigned int ret;
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
+ spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c
index 139863a787f3..36b1ae083fb7 100644
--- a/trunk/drivers/serial/serial_core.c
+++ b/trunk/drivers/serial/serial_core.c
@@ -182,13 +182,6 @@ static int uart_startup(struct uart_state *state, int init_hw)
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
}
- if (info->flags & UIF_CTS_FLOW) {
- spin_lock_irq(&port->lock);
- if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
- info->tty->hw_stopped = 1;
- spin_unlock_irq(&port->lock);
- }
-
info->flags |= UIF_INITIALIZED;
clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -835,10 +828,7 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
if ((!file || !tty_hung_up_p(file)) &&
!(tty->flags & (1 << TTY_IO_ERROR))) {
result = port->mctrl;
-
- spin_lock_irq(&port->lock);
result |= port->ops->get_mctrl(port);
- spin_unlock_irq(&port->lock);
}
up(&state->sem);
@@ -1141,16 +1131,6 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios
spin_unlock_irqrestore(&state->port->lock, flags);
}
- /* Handle turning on CRTSCTS */
- if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
- spin_lock_irqsave(&state->port->lock, flags);
- if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
- tty->hw_stopped = 1;
- state->port->ops->stop_tx(state->port, 0);
- }
- spin_unlock_irqrestore(&state->port->lock, flags);
- }
-
#if 0
/*
* No need to wake up processes in open wait, since they
@@ -1389,7 +1369,6 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
DECLARE_WAITQUEUE(wait, current);
struct uart_info *info = state->info;
struct uart_port *port = state->port;
- unsigned int mctrl;
info->blocked_open++;
state->count--;
@@ -1437,10 +1416,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* and wait for the carrier to indicate that the
* modem is ready for us.
*/
- spin_lock_irq(&port->lock);
- mctrl = port->ops->get_mctrl(port);
- spin_unlock_irq(&port->lock);
- if (mctrl & TIOCM_CAR)
+ if (port->ops->get_mctrl(port) & TIOCM_CAR)
break;
up(&state->sem);
@@ -1642,9 +1618,7 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
if(capable(CAP_SYS_ADMIN))
{
- spin_lock_irq(&port->lock);
status = port->ops->get_mctrl(port);
- spin_unlock_irq(&port->lock);
ret += sprintf(buf + ret, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
diff --git a/trunk/drivers/serial/serial_txx9.c b/trunk/drivers/serial/serial_txx9.c
index d085030df70b..3f1051a4a13f 100644
--- a/trunk/drivers/serial/serial_txx9.c
+++ b/trunk/drivers/serial/serial_txx9.c
@@ -442,10 +442,13 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port)
static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
{
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ unsigned long flags;
unsigned int ret;
+ spin_lock_irqsave(&up->port.lock, flags);
ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
| ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
+ spin_unlock_irqrestore(&up->port.lock, flags);
return ret;
}
diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c
index 8d198880756a..10e2990a40d4 100644
--- a/trunk/drivers/serial/sunsab.c
+++ b/trunk/drivers/serial/sunsab.c
@@ -426,15 +426,18 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl)
sunsab_tx_idle(up);
}
-/* port->lock is held by caller and interrupts are disabled. */
+/* port->lock is not held. */
static unsigned int sunsab_get_mctrl(struct uart_port *port)
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+ unsigned long flags;
unsigned char val;
unsigned int result;
result = 0;
+ spin_lock_irqsave(&up->port.lock, flags);
+
val = readb(&up->regs->r.pvr);
result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
@@ -444,6 +447,8 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port)
val = readb(&up->regs->r.star);
result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
return result;
}
diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c
index d57a3553aea3..ddc97c905e14 100644
--- a/trunk/drivers/serial/sunsu.c
+++ b/trunk/drivers/serial/sunsu.c
@@ -572,10 +572,13 @@ static unsigned int sunsu_tx_empty(struct uart_port *port)
static unsigned int sunsu_get_mctrl(struct uart_port *port)
{
struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+ unsigned long flags;
unsigned char status;
unsigned int ret;
+ spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
+ spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c
index bff42a7b89d0..8e65206d3d76 100644
--- a/trunk/drivers/serial/sunzilog.c
+++ b/trunk/drivers/serial/sunzilog.c
@@ -610,28 +610,27 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
{
struct zilog_channel __iomem *channel;
+ unsigned long flags;
unsigned char status;
+ spin_lock_irqsave(&port->lock, flags);
+
channel = ZILOG_CHANNEL_FROM_PORT(port);
status = sbus_readb(&channel->control);
ZSDELAY();
+ spin_unlock_irqrestore(&port->lock, flags);
+
return status;
}
/* The port lock is not held. */
static unsigned int sunzilog_tx_empty(struct uart_port *port)
{
- unsigned long flags;
unsigned char status;
unsigned int ret;
- spin_lock_irqsave(&port->lock, flags);
-
status = sunzilog_read_channel_status(port);
-
- spin_unlock_irqrestore(&port->lock, flags);
-
if (status & Tx_BUF_EMP)
ret = TIOCSER_TEMT;
else
@@ -640,7 +639,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port)
return ret;
}
-/* The port lock is held and interrupts are disabled. */
+/* The port lock is not held. */
static unsigned int sunzilog_get_mctrl(struct uart_port *port)
{
unsigned char status;
diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c
index 06d7d4390fe7..7afa222f6802 100644
--- a/trunk/fs/aio.c
+++ b/trunk/fs/aio.c
@@ -58,7 +58,6 @@ static DEFINE_SPINLOCK(fput_lock);
static LIST_HEAD(fput_head);
static void aio_kick_handler(void *);
-static void aio_queue_work(struct kioctx *);
/* aio_setup
* Creates the slab caches used by the aio routines, panic on
@@ -748,14 +747,6 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
* has already been kicked */
if (kiocbIsKicked(iocb)) {
__queue_kicked_iocb(iocb);
-
- /*
- * __queue_kicked_iocb will always return 1 here, because
- * iocb->ki_run_list is empty at this point so it should
- * be safe to unconditionally queue the context into the
- * work queue.
- */
- aio_queue_work(ctx);
}
}
return ret;
diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c
index 561e63a14966..13e5938a64f6 100644
--- a/trunk/fs/buffer.c
+++ b/trunk/fs/buffer.c
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(thaw_bdev);
*/
static void do_sync(unsigned long wait)
{
- wakeup_pdflush(0);
+ wakeup_bdflush(0);
sync_inodes(0); /* All mappings, inodes and their blockdevs */
DQUOT_SYNC(NULL);
sync_supers(); /* Write the superblocks */
@@ -497,7 +497,7 @@ static void free_more_memory(void)
struct zone **zones;
pg_data_t *pgdat;
- wakeup_pdflush(1024);
+ wakeup_bdflush(1024);
yield();
for_each_pgdat(pgdat) {
diff --git a/trunk/fs/char_dev.c b/trunk/fs/char_dev.c
index a69a5d8a406f..e82aac9cc2f5 100644
--- a/trunk/fs/char_dev.c
+++ b/trunk/fs/char_dev.c
@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
struct char_device_struct *cd = NULL, **cp;
int i = major_to_index(major);
- down(&chrdevs_lock);
+ up(&chrdevs_lock);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major == major &&
(*cp)->baseminor == baseminor &&
diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c
index e463dca008e4..ccd632fcc6d8 100644
--- a/trunk/fs/ext3/balloc.c
+++ b/trunk/fs/ext3/balloc.c
@@ -749,24 +749,24 @@ ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
* to find a free region that is of my size and has not
* been reserved.
*
+ * on succeed, it returns the reservation window to be appended to.
+ * failed, return NULL.
*/
-static int find_next_reservable_window(
+static struct ext3_reserve_window_node *find_next_reservable_window(
struct ext3_reserve_window_node *search_head,
- struct ext3_reserve_window_node *my_rsv,
- struct super_block * sb, int start_block,
+ unsigned long size, int *start_block,
int last_block)
{
struct rb_node *next;
struct ext3_reserve_window_node *rsv, *prev;
int cur;
- int size = my_rsv->rsv_goal_size;
/* TODO: make the start of the reservation window byte-aligned */
/* cur = *start_block & ~7;*/
- cur = start_block;
+ cur = *start_block;
rsv = search_head;
if (!rsv)
- return -1;
+ return NULL;
while (1) {
if (cur <= rsv->rsv_end)
@@ -782,11 +782,11 @@ static int find_next_reservable_window(
* space with expected-size (or more)...
*/
if (cur > last_block)
- return -1; /* fail */
+ return NULL; /* fail */
prev = rsv;
next = rb_next(&rsv->rsv_node);
- rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node);
+ rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node);
/*
* Reached the last reservation, we can just append to the
@@ -813,25 +813,8 @@ static int find_next_reservable_window(
* return the reservation window that we could append to.
* succeed.
*/
-
- if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
- rsv_window_remove(sb, my_rsv);
-
- /*
- * Let's book the whole avaliable window for now. We will check the
- * disk bitmap later and then, if there are free blocks then we adjust
- * the window size if it's larger than requested.
- * Otherwise, we will remove this node from the tree next time
- * call find_next_reservable_window.
- */
- my_rsv->rsv_start = cur;
- my_rsv->rsv_end = cur + size - 1;
- my_rsv->rsv_alloc_hit = 0;
-
- if (prev != my_rsv)
- ext3_rsv_window_add(sb, my_rsv);
-
- return 0;
+ *start_block = cur;
+ return prev;
}
/**
@@ -869,7 +852,6 @@ static int find_next_reservable_window(
* @sb: the super block
* @group: the group we are trying to allocate in
* @bitmap_bh: the block group block bitmap
- *
*/
static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
int goal, struct super_block *sb,
@@ -878,10 +860,10 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
struct ext3_reserve_window_node *search_head;
int group_first_block, group_end_block, start_block;
int first_free_block;
+ int reservable_space_start;
+ struct ext3_reserve_window_node *prev_rsv;
struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root;
unsigned long size;
- int ret;
- spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
group * EXT3_BLOCKS_PER_GROUP(sb);
@@ -893,7 +875,6 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
start_block = goal + group_first_block;
size = my_rsv->rsv_goal_size;
-
if (!rsv_is_empty(&my_rsv->rsv_window)) {
/*
* if the old reservation is cross group boundary
@@ -927,8 +908,6 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
my_rsv->rsv_goal_size= size;
}
}
-
- spin_lock(rsv_lock);
/*
* shift the search start to the window near the goal block
*/
@@ -942,16 +921,11 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
* need to check the bitmap after we found a reservable window.
*/
retry:
- ret = find_next_reservable_window(search_head, my_rsv, sb,
- start_block, group_end_block);
-
- if (ret == -1) {
- if (!rsv_is_empty(&my_rsv->rsv_window))
- rsv_window_remove(sb, my_rsv);
- spin_unlock(rsv_lock);
- return -1;
- }
-
+ prev_rsv = find_next_reservable_window(search_head, size,
+ &start_block, group_end_block);
+ if (prev_rsv == NULL)
+ goto failed;
+ reservable_space_start = start_block;
/*
* On success, find_next_reservable_window() returns the
* reservation window where there is a reservable space after it.
@@ -963,9 +937,8 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
* block. Search start from the start block of the reservable space
* we just found.
*/
- spin_unlock(rsv_lock);
first_free_block = bitmap_search_next_usable_block(
- my_rsv->rsv_start - group_first_block,
+ reservable_space_start - group_first_block,
bitmap_bh, group_end_block - group_first_block + 1);
if (first_free_block < 0) {
@@ -973,29 +946,54 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
* no free block left on the bitmap, no point
* to reserve the space. return failed.
*/
- spin_lock(rsv_lock);
- if (!rsv_is_empty(&my_rsv->rsv_window))
- rsv_window_remove(sb, my_rsv);
- spin_unlock(rsv_lock);
- return -1; /* failed */
+ goto failed;
}
-
start_block = first_free_block + group_first_block;
/*
* check if the first free block is within the
- * free space we just reserved
+ * free space we just found
*/
- if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end)
- return 0; /* success */
+ if ((start_block >= reservable_space_start) &&
+ (start_block < reservable_space_start + size))
+ goto found_rsv_window;
/*
* if the first free bit we found is out of the reservable space
- * continue search for next reservable space,
+ * this means there is no free block on the reservable space
+ * we should continue search for next reservable space,
* start from where the free block is,
* we also shift the list head to where we stopped last time
*/
- search_head = my_rsv;
- spin_lock(rsv_lock);
+ search_head = prev_rsv;
goto retry;
+
+found_rsv_window:
+ /*
+ * great! the reservable space contains some free blocks.
+ * if the search returns that we should add the new
+ * window just next to where the old window, we don't
+ * need to remove the old window first then add it to the
+ * same place, just update the new start and new end.
+ */
+ if (my_rsv != prev_rsv) {
+ if (!rsv_is_empty(&my_rsv->rsv_window))
+ rsv_window_remove(sb, my_rsv);
+ }
+ my_rsv->rsv_start = reservable_space_start;
+ my_rsv->rsv_end = my_rsv->rsv_start + size - 1;
+ my_rsv->rsv_alloc_hit = 0;
+ if (my_rsv != prev_rsv) {
+ ext3_rsv_window_add(sb, my_rsv);
+ }
+ return 0; /* succeed */
+failed:
+ /*
+ * failed to find a new reservation window in the current
+ * group, remove the current(stale) reservation window
+ * if there is any
+ */
+ if (!rsv_is_empty(&my_rsv->rsv_window))
+ rsv_window_remove(sb, my_rsv);
+ return -1; /* failed */
}
/*
@@ -1025,6 +1023,7 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
int goal, struct ext3_reserve_window_node * my_rsv,
int *errp)
{
+ spinlock_t *rsv_lock;
unsigned long group_first_block;
int ret = 0;
int fatal;
@@ -1053,6 +1052,7 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
goto out;
}
+ rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
/*
* goal is a group relative block number (if there is a goal)
* 0 < goal < EXT3_BLOCKS_PER_GROUP(sb)
@@ -1078,21 +1078,30 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
* then we could go to allocate from the reservation window directly.
*/
while (1) {
- if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
- !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) {
+ struct ext3_reserve_window rsv_copy;
+
+ rsv_copy._rsv_start = my_rsv->rsv_start;
+ rsv_copy._rsv_end = my_rsv->rsv_end;
+
+ if (rsv_is_empty(&rsv_copy) || (ret < 0) ||
+ !goal_in_my_reservation(&rsv_copy, goal, group, sb)) {
+ spin_lock(rsv_lock);
ret = alloc_new_reservation(my_rsv, goal, sb,
group, bitmap_bh);
+ rsv_copy._rsv_start = my_rsv->rsv_start;
+ rsv_copy._rsv_end = my_rsv->rsv_end;
+ spin_unlock(rsv_lock);
if (ret < 0)
break; /* failed */
- if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb))
+ if (!goal_in_my_reservation(&rsv_copy, goal, group, sb))
goal = -1;
}
- if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
- || (my_rsv->rsv_end < group_first_block))
+ if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
+ || (rsv_copy._rsv_end < group_first_block))
BUG();
ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
- &my_rsv->rsv_window);
+ &rsv_copy);
if (ret >= 0) {
my_rsv->rsv_alloc_hit++;
break; /* succeed */
diff --git a/trunk/fs/ext3/file.c b/trunk/fs/ext3/file.c
index 98e78345ead9..5ad8cf0292df 100644
--- a/trunk/fs/ext3/file.c
+++ b/trunk/fs/ext3/file.c
@@ -36,11 +36,7 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
/* if we are the last writer on the inode, drop the block reservation */
if ((filp->f_mode & FMODE_WRITE) &&
(atomic_read(&inode->i_writecount) == 1))
- {
- down(&EXT3_I(inode)->truncate_sem);
ext3_discard_reservation(inode);
- up(&EXT3_I(inode)->truncate_sem);
- }
if (is_dx(inode) && filp->private_data)
ext3_htree_free_dir_info(filp->private_data);
diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c
index a6d1779d7de4..b4b3e8a39131 100644
--- a/trunk/fs/ext3/super.c
+++ b/trunk/fs/ext3/super.c
@@ -944,8 +944,7 @@ static int parse_options (char * options, struct super_block *sb,
"for remount\n");
return 0;
}
- if (match_int(&args[0], &option) != 0)
- return 0;
+ match_int(&args[0], &option);
*n_blocks_count = option;
break;
case Opt_nobh:
diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c
index 3e31c4a736f1..8ccee8415488 100644
--- a/trunk/fs/fat/inode.c
+++ b/trunk/fs/fat/inode.c
@@ -1331,21 +1331,12 @@ void __exit fat_cache_destroy(void);
static int __init init_fat_fs(void)
{
- int err;
-
- err = fat_cache_init();
- if (err)
- return err;
-
- err = fat_init_inodecache();
- if (err)
- goto failed;
+ int ret;
- return 0;
-
-failed:
- fat_cache_destroy();
- return err;
+ ret = fat_cache_init();
+ if (ret < 0)
+ return ret;
+ return fat_init_inodecache();
}
static void __exit exit_fat_fs(void)
diff --git a/trunk/fs/freevxfs/vxfs.h b/trunk/fs/freevxfs/vxfs.h
index 583bd78086d8..8da0252642a4 100644
--- a/trunk/fs/freevxfs/vxfs.h
+++ b/trunk/fs/freevxfs/vxfs.h
@@ -37,6 +37,7 @@
* superblocks of the Veritas Filesystem.
*/
#include
+#include "vxfs_kcompat.h"
/*
diff --git a/trunk/fs/freevxfs/vxfs_bmap.c b/trunk/fs/freevxfs/vxfs_bmap.c
index d3f6b2835bc8..bc4b57da306a 100644
--- a/trunk/fs/freevxfs/vxfs_bmap.c
+++ b/trunk/fs/freevxfs/vxfs_bmap.c
@@ -101,7 +101,7 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
return 0;
fail_size:
- printk("vxfs: indirect extent too big!\n");
+ printk("vxfs: indirect extent to big!\n");
fail_buf:
return 0;
}
diff --git a/trunk/fs/freevxfs/vxfs_fshead.c b/trunk/fs/freevxfs/vxfs_fshead.c
index 6dee109aeea4..05b19f70bf97 100644
--- a/trunk/fs/freevxfs/vxfs_fshead.c
+++ b/trunk/fs/freevxfs/vxfs_fshead.c
@@ -78,18 +78,17 @@ vxfs_getfsh(struct inode *ip, int which)
struct buffer_head *bp;
bp = vxfs_bread(ip, which);
- if (bp) {
+ if (buffer_mapped(bp)) {
struct vxfs_fsh *fhp;
- if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
- goto out;
+ if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL)))
+ return NULL;
memcpy(fhp, bp->b_data, sizeof(*fhp));
- put_bh(bp);
+ brelse(bp);
return (fhp);
}
-out:
- brelse(bp);
+
return NULL;
}
diff --git a/trunk/fs/freevxfs/vxfs_kcompat.h b/trunk/fs/freevxfs/vxfs_kcompat.h
new file mode 100644
index 000000000000..342a4cc860f4
--- /dev/null
+++ b/trunk/fs/freevxfs/vxfs_kcompat.h
@@ -0,0 +1,49 @@
+#ifndef _VXFS_KCOMPAT_H
+#define _VXFS_KCOMPAT_H
+
+#include
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+
+#include
+
+typedef long sector_t;
+
+/* From include/linux/fs.h (Linux 2.5.2-pre3) */
+static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
+{
+ return bread(sb->s_dev, block, sb->s_blocksize);
+}
+
+/* Dito. */
+static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block)
+{
+ bh->b_state |= 1 << BH_Mapped;
+ bh->b_dev = sb->s_dev;
+ bh->b_blocknr = block;
+}
+
+/* From fs/block_dev.c (Linux 2.5.2-pre2) */
+static inline int sb_set_blocksize(struct super_block *sb, int size)
+{
+ int bits;
+ if (set_blocksize(sb->s_dev, size) < 0)
+ return 0;
+ sb->s_blocksize = size;
+ for (bits = 9, size >>= 9; size >>= 1; bits++)
+ ;
+ sb->s_blocksize_bits = bits;
+ return sb->s_blocksize;
+}
+
+/* Dito. */
+static inline int sb_min_blocksize(struct super_block *sb, int size)
+{
+ int minsize = get_hardsect_size(sb->s_dev);
+ if (size < minsize)
+ size = minsize;
+ return sb_set_blocksize(sb, size);
+}
+
+#endif /* Kernel 2.4 */
+#endif /* _VXFS_KCOMPAT_H */
diff --git a/trunk/fs/freevxfs/vxfs_lookup.c b/trunk/fs/freevxfs/vxfs_lookup.c
index 554eb455722c..506ae251d2c0 100644
--- a/trunk/fs/freevxfs/vxfs_lookup.c
+++ b/trunk/fs/freevxfs/vxfs_lookup.c
@@ -61,13 +61,13 @@ struct file_operations vxfs_dir_operations = {
};
-static inline u_long
+static __inline__ u_long
dir_pages(struct inode *inode)
{
return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
}
-static inline u_long
+static __inline__ u_long
dir_blocks(struct inode *ip)
{
u_long bsize = ip->i_sb->s_blocksize;
@@ -79,7 +79,7 @@ dir_blocks(struct inode *ip)
*
* len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
*/
-static inline int
+static __inline__ int
vxfs_match(int len, const char * const name, struct vxfs_direct *de)
{
if (len != de->d_namelen)
@@ -89,7 +89,7 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de)
return !memcmp(name, de->d_name, len);
}
-static inline struct vxfs_direct *
+static __inline__ struct vxfs_direct *
vxfs_next_entry(struct vxfs_direct *de)
{
return ((struct vxfs_direct *)((char*)de + de->d_reclen));
diff --git a/trunk/fs/freevxfs/vxfs_olt.c b/trunk/fs/freevxfs/vxfs_olt.c
index 133476201d84..7a204e31aad9 100644
--- a/trunk/fs/freevxfs/vxfs_olt.c
+++ b/trunk/fs/freevxfs/vxfs_olt.c
@@ -38,7 +38,7 @@
#include "vxfs_olt.h"
-static inline void
+static __inline__ void
vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
{
if (infp->vsi_fshino)
@@ -46,7 +46,7 @@ vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
infp->vsi_fshino = fshp->olt_fsino[0];
}
-static inline void
+static __inline__ void
vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
{
if (infp->vsi_iext)
@@ -54,7 +54,7 @@ vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
infp->vsi_iext = ilistp->olt_iext[0];
}
-static inline u_long
+static __inline__ u_long
vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
{
if (sbp->s_blocksize % bsize)
@@ -104,8 +104,8 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
goto fail;
}
- oaddr = bp->b_data + op->olt_size;
- eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+ oaddr = (char *)bp->b_data + op->olt_size;
+ eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
while (oaddr < eaddr) {
struct vxfs_oltcommon *ocp =
diff --git a/trunk/fs/freevxfs/vxfs_subr.c b/trunk/fs/freevxfs/vxfs_subr.c
index 50aae77651b2..5e305612054a 100644
--- a/trunk/fs/freevxfs/vxfs_subr.c
+++ b/trunk/fs/freevxfs/vxfs_subr.c
@@ -36,6 +36,7 @@
#include
#include
+#include "vxfs_kcompat.h"
#include "vxfs_extern.h"
diff --git a/trunk/fs/freevxfs/vxfs_super.c b/trunk/fs/freevxfs/vxfs_super.c
index 27f66d3e8a04..0ae2c7b8182a 100644
--- a/trunk/fs/freevxfs/vxfs_super.c
+++ b/trunk/fs/freevxfs/vxfs_super.c
@@ -155,11 +155,12 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
sbp->s_flags |= MS_RDONLY;
- infp = kcalloc(1, sizeof(*infp), GFP_KERNEL);
+ infp = kmalloc(sizeof(*infp), GFP_KERNEL);
if (!infp) {
printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
return -ENOMEM;
}
+ memset(infp, 0, sizeof(*infp));
bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
if (!bsize) {
@@ -195,7 +196,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
#endif
sbp->s_magic = rsbp->vs_magic;
- sbp->s_fs_info = infp;
+ sbp->s_fs_info = (void *)infp;
infp->vsi_raw = rsbp;
infp->vsi_bp = bp;
@@ -262,7 +263,7 @@ vxfs_init(void)
sizeof(struct vxfs_inode_info), 0,
SLAB_RECLAIM_ACCOUNT, NULL, NULL);
if (vxfs_inode_cachep)
- return register_filesystem(&vxfs_fs_type);
+ return (register_filesystem(&vxfs_fs_type));
return -ENOMEM;
}
diff --git a/trunk/fs/nfs/nfs3acl.c b/trunk/fs/nfs/nfs3acl.c
index 1b7a3ef2f813..ee3536fc84a3 100644
--- a/trunk/fs/nfs/nfs3acl.c
+++ b/trunk/fs/nfs/nfs3acl.c
@@ -2,7 +2,7 @@
#include
#include
#include
-#include
+#include
#include
#define NFSDBG_FACILITY NFSDBG_PROC
@@ -53,9 +53,9 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
struct posix_acl *acl;
int type, error = 0;
- if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
+ if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
type = ACL_TYPE_ACCESS;
- else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
+ else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
type = ACL_TYPE_DEFAULT;
else
return -EOPNOTSUPP;
@@ -82,9 +82,9 @@ int nfs3_setxattr(struct dentry *dentry, const char *name,
struct posix_acl *acl;
int type, error;
- if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
+ if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
type = ACL_TYPE_ACCESS;
- else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
+ else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
type = ACL_TYPE_DEFAULT;
else
return -EOPNOTSUPP;
@@ -103,9 +103,9 @@ int nfs3_removexattr(struct dentry *dentry, const char *name)
struct inode *inode = dentry->d_inode;
int type;
- if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
+ if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
type = ACL_TYPE_ACCESS;
- else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
+ else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
type = ACL_TYPE_DEFAULT;
else
return -EOPNOTSUPP;
diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c
index be24ead89d94..de340ffd33c3 100644
--- a/trunk/fs/nfsd/vfs.c
+++ b/trunk/fs/nfsd/vfs.c
@@ -46,9 +46,10 @@
#include
#include
#include