@@ -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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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
+#include
#include
-#include
#ifdef CONFIG_NFSD_V4
+#include
#include
#include
#include
@@ -1871,10 +1872,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type)
return ERR_PTR(-EOPNOTSUPP);
switch(type) {
case ACL_TYPE_ACCESS:
- name = POSIX_ACL_XATTR_ACCESS;
+ name = XATTR_NAME_ACL_ACCESS;
break;
case ACL_TYPE_DEFAULT:
- name = POSIX_ACL_XATTR_DEFAULT;
+ name = XATTR_NAME_ACL_DEFAULT;
break;
default:
return ERR_PTR(-EOPNOTSUPP);
@@ -1918,17 +1919,17 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
return -EOPNOTSUPP;
switch(type) {
case ACL_TYPE_ACCESS:
- name = POSIX_ACL_XATTR_ACCESS;
+ name = XATTR_NAME_ACL_ACCESS;
break;
case ACL_TYPE_DEFAULT:
- name = POSIX_ACL_XATTR_DEFAULT;
+ name = XATTR_NAME_ACL_DEFAULT;
break;
default:
return -EOPNOTSUPP;
}
if (acl && acl->a_count) {
- size = posix_acl_xattr_size(acl->a_count);
+ size = xattr_acl_size(acl->a_count);
value = kmalloc(size, GFP_KERNEL);
if (!value)
return -ENOMEM;
diff --git a/trunk/fs/udf/namei.c b/trunk/fs/udf/namei.c
index 4673157b262f..3f6dc7112bc6 100644
--- a/trunk/fs/udf/namei.c
+++ b/trunk/fs/udf/namei.c
@@ -159,7 +159,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
char *nameptr;
uint8_t lfi;
uint16_t liu;
- loff_t size;
+ loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
kernel_lb_addr bloc, eloc;
uint32_t extoffset, elen, offset;
struct buffer_head *bh = NULL;
@@ -167,8 +167,6 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
if (!dir)
return NULL;
- size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
-
f_pos = (udf_ext0_offset(dir) >> 2);
fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h
index 9ad142476f33..c627bc408a6b 100644
--- a/trunk/include/acpi/acpi_bus.h
+++ b/trunk/include/acpi/acpi_bus.h
@@ -108,21 +108,6 @@ typedef int (*acpi_op_unbind) (struct acpi_device *device);
typedef int (*acpi_op_match) (struct acpi_device *device,
struct acpi_driver *driver);
-struct acpi_bus_ops {
- u32 acpi_op_add:1;
- u32 acpi_op_remove:1;
- u32 acpi_op_lock:1;
- u32 acpi_op_start:1;
- u32 acpi_op_stop:1;
- u32 acpi_op_suspend:1;
- u32 acpi_op_resume:1;
- u32 acpi_op_scan:1;
- u32 acpi_op_bind:1;
- u32 acpi_op_unbind:1;
- u32 acpi_op_match:1;
- u32 reserved:21;
-};
-
struct acpi_device_ops {
acpi_op_add add;
acpi_op_remove remove;
@@ -342,9 +327,9 @@ int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data);
int acpi_bus_receive_event (struct acpi_bus_event *event);
int acpi_bus_register_driver (struct acpi_driver *driver);
int acpi_bus_unregister_driver (struct acpi_driver *driver);
+int acpi_bus_scan (struct acpi_device *start);
int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
acpi_handle handle, int type);
-int acpi_bus_start (struct acpi_device *device);
int acpi_match_ids (struct acpi_device *device, char *ids);
diff --git a/trunk/include/acpi/acpi_drivers.h b/trunk/include/acpi/acpi_drivers.h
index 4ec722d73381..c62e92ec43b2 100644
--- a/trunk/include/acpi/acpi_drivers.h
+++ b/trunk/include/acpi/acpi_drivers.h
@@ -68,7 +68,6 @@ void acpi_pci_irq_del_prt (int segment, int bus);
struct pci_bus;
-acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id);
int acpi_pci_bind (struct acpi_device *device);
int acpi_pci_unbind (struct acpi_device *device);
int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
diff --git a/trunk/include/asm-alpha/pci.h b/trunk/include/asm-alpha/pci.h
index b7806aa3785c..0c7b57bc043a 100644
--- a/trunk/include/asm-alpha/pci.h
+++ b/trunk/include/asm-alpha/pci.h
@@ -223,25 +223,6 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr,
/* Nothing to do. */
}
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- unsigned long cacheline_size;
- u8 byte;
-
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
- if (byte == 0)
- cacheline_size = 1024;
- else
- cacheline_size = (int) byte * 4;
-
- *strat = PCI_DMA_BURST_BOUNDARY;
- *strategy_parameter = cacheline_size;
-}
-#endif
-
/* TODO: integrate with include/asm-generic/pci.h ? */
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
diff --git a/trunk/include/asm-arm/arch-s3c2410/audio.h b/trunk/include/asm-arm/arch-s3c2410/audio.h
deleted file mode 100644
index 0d276e67f2fb..000000000000
--- a/trunk/include/asm-arm/arch-s3c2410/audio.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* linux/include/asm-arm/arch-s3c2410/audio.h
- *
- * (c) 2004-2005 Simtec Electronics
- * http://www.simtec.co.uk/products/SWLINUX/
- * Ben Dooks
- *
- * S3C24XX - Audio platfrom_device info
- *
- * 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.
- *
- * Changelog:
- * 20-Nov-2004 BJD Created file
- * 07-Mar-2005 BJD Added suspend/resume calls
-*/
-
-#ifndef __ASM_ARCH_AUDIO_H
-#define __ASM_ARCH_AUDIO_H __FILE__
-
-/* struct s3c24xx_iis_ops
- *
- * called from the s3c24xx audio core to deal with the architecture
- * or the codec's setup and control.
- *
- * the pointer to itself is passed through in case the caller wants to
- * embed this in an larger structure for easy reference to it's context.
-*/
-
-struct s3c24xx_iis_ops {
- struct module *owner;
-
- int (*startup)(struct s3c24xx_iis_ops *me);
- void (*shutdown)(struct s3c24xx_iis_ops *me);
- int (*suspend)(struct s3c24xx_iis_ops *me);
- int (*resume)(struct s3c24xx_iis_ops *me);
-
- int (*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
- int (*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
- int (*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt);
-};
-
-struct s3c24xx_platdata_iis {
- const char *codec_clk;
- struct s3c24xx_iis_ops *ops;
- int (*match_dev)(struct device *dev);
-};
-
-#endif /* __ASM_ARCH_AUDIO_H */
diff --git a/trunk/include/asm-arm/pci.h b/trunk/include/asm-arm/pci.h
index e300646fe650..40ffaefbeb1a 100644
--- a/trunk/include/asm-arm/pci.h
+++ b/trunk/include/asm-arm/pci.h
@@ -42,16 +42,6 @@ static inline void pcibios_penalize_isa_irq(int irq)
#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
diff --git a/trunk/include/asm-arm/tlbflush.h b/trunk/include/asm-arm/tlbflush.h
index 8a864b118569..9387a5e1ffe0 100644
--- a/trunk/include/asm-arm/tlbflush.h
+++ b/trunk/include/asm-arm/tlbflush.h
@@ -235,7 +235,7 @@ extern struct cpu_tlb_fns cpu_tlb;
#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
-static inline void flush_tlb_all(void)
+static inline void local_flush_tlb_all(void)
{
const int zero = 0;
const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -253,7 +253,7 @@ static inline void flush_tlb_all(void)
asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
}
-static inline void flush_tlb_mm(struct mm_struct *mm)
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
{
const int zero = 0;
const int asid = ASID(mm);
@@ -282,7 +282,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
}
static inline void
-flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
{
const int zero = 0;
const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -313,7 +313,7 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
}
-static inline void flush_tlb_kernel_page(unsigned long kaddr)
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
{
const int zero = 0;
const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -384,8 +384,24 @@ static inline void clean_pmd_entry(pmd_t *pmd)
/*
* Convert calls to our calling convention.
*/
-#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
-#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
+#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
+#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
+
+#ifndef CONFIG_SMP
+#define flush_tlb_all local_flush_tlb_all
+#define flush_tlb_mm local_flush_tlb_mm
+#define flush_tlb_page local_flush_tlb_page
+#define flush_tlb_kernel_page local_flush_tlb_kernel_page
+#define flush_tlb_range local_flush_tlb_range
+#define flush_tlb_kernel_range local_flush_tlb_kernel_range
+#else
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
+extern void flush_tlb_kernel_page(unsigned long kaddr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+#endif
/*
* if PG_dcache_dirty is set for the page, we need to ensure that any
diff --git a/trunk/include/asm-frv/pci.h b/trunk/include/asm-frv/pci.h
index b4efe5e3591a..a6a469231f62 100644
--- a/trunk/include/asm-frv/pci.h
+++ b/trunk/include/asm-frv/pci.h
@@ -57,16 +57,6 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
*/
#define PCI_DMA_BUS_IS_PHYS (1)
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
/*
* These are pretty much arbitary with the CoMEM implementation.
* We have the whole address space to ourselves.
diff --git a/trunk/include/asm-i386/pci.h b/trunk/include/asm-i386/pci.h
index 3561899eb826..fb749b85a739 100644
--- a/trunk/include/asm-i386/pci.h
+++ b/trunk/include/asm-i386/pci.h
@@ -99,16 +99,6 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
#endif /* __KERNEL__ */
/* implement the pci_ DMA API in terms of the generic device dma_ one */
diff --git a/trunk/include/asm-ia64/iosapic.h b/trunk/include/asm-ia64/iosapic.h
index 1093f35b3b90..38a7a72791cc 100644
--- a/trunk/include/asm-ia64/iosapic.h
+++ b/trunk/include/asm-ia64/iosapic.h
@@ -71,11 +71,8 @@ static inline void iosapic_eoi(char __iomem *iosapic, u32 vector)
}
extern void __init iosapic_system_init (int pcat_compat);
-extern int __devinit iosapic_init (unsigned long address,
+extern void __init iosapic_init (unsigned long address,
unsigned int gsi_base);
-#ifdef CONFIG_HOTPLUG
-extern int iosapic_remove (unsigned int gsi_base);
-#endif /* CONFIG_HOTPLUG */
extern int gsi_to_vector (unsigned int gsi);
extern int gsi_to_irq (unsigned int gsi);
extern void iosapic_enable_intr (unsigned int vector);
@@ -97,14 +94,11 @@ extern unsigned int iosapic_version (char __iomem *addr);
extern void iosapic_pci_fixup (int);
#ifdef CONFIG_NUMA
-extern void __devinit map_iosapic_to_node (unsigned int, int);
+extern void __init map_iosapic_to_node (unsigned int, int);
#endif
#else
#define iosapic_system_init(pcat_compat) do { } while (0)
-#define iosapic_init(address,gsi_base) (-EINVAL)
-#ifdef CONFIG_HOTPLUG
-#define iosapic_remove(gsi_base) (-ENODEV)
-#endif /* CONFIG_HOTPLUG */
+#define iosapic_init(address,gsi_base) do { } while (0)
#define iosapic_register_intr(gsi,polarity,trigger) (gsi)
#define iosapic_unregister_intr(irq) do { } while (0)
#define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0)
diff --git a/trunk/include/asm-ia64/pci.h b/trunk/include/asm-ia64/pci.h
index 0c4c5d801d3f..a8314ee4e7d2 100644
--- a/trunk/include/asm-ia64/pci.h
+++ b/trunk/include/asm-ia64/pci.h
@@ -82,25 +82,6 @@ extern int pcibios_prep_mwi (struct pci_dev *);
#define sg_dma_len(sg) ((sg)->dma_length)
#define sg_dma_address(sg) ((sg)->dma_address)
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- unsigned long cacheline_size;
- u8 byte;
-
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
- if (byte == 0)
- cacheline_size = 1024;
- else
- cacheline_size = (int) byte * 4;
-
- *strat = PCI_DMA_BURST_MULTIPLE;
- *strategy_parameter = cacheline_size;
-}
-#endif
-
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
diff --git a/trunk/include/asm-mips/pci.h b/trunk/include/asm-mips/pci.h
index 2d323b6e147d..c9c576b48556 100644
--- a/trunk/include/asm-mips/pci.h
+++ b/trunk/include/asm-mips/pci.h
@@ -130,16 +130,6 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
dma64_addr_t dma_addr, size_t len, int direction);
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
extern void pcibios_resource_to_bus(struct pci_dev *dev,
struct pci_bus_region *region, struct resource *res);
diff --git a/trunk/include/asm-parisc/pci.h b/trunk/include/asm-parisc/pci.h
index ee741c150176..0763c2982fb0 100644
--- a/trunk/include/asm-parisc/pci.h
+++ b/trunk/include/asm-parisc/pci.h
@@ -230,25 +230,6 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x)
/* export the pci_ DMA API in terms of the dma_ one */
#include
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- unsigned long cacheline_size;
- u8 byte;
-
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
- if (byte == 0)
- cacheline_size = 1024;
- else
- cacheline_size = (int) byte * 4;
-
- *strat = PCI_DMA_BURST_MULTIPLE;
- *strategy_parameter = cacheline_size;
-}
-#endif
-
extern void
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res);
diff --git a/trunk/include/asm-ppc/pci.h b/trunk/include/asm-ppc/pci.h
index db0a2a0ec74d..ce5ae6d048f5 100644
--- a/trunk/include/asm-ppc/pci.h
+++ b/trunk/include/asm-ppc/pci.h
@@ -69,16 +69,6 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
#define pci_unmap_len(PTR, LEN_NAME) (0)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
/*
* At present there are very few 32-bit PPC machines that can have
* memory above the 4GB point, and we don't support that.
@@ -113,12 +103,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file,
unsigned long size,
pgprot_t prot);
-#define HAVE_ARCH_PCI_RESOURCE_TO_USER
-extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
- const struct resource *rsrc,
- u64 *start, u64 *end);
-
-
#endif /* __KERNEL__ */
#endif /* __PPC_PCI_H */
diff --git a/trunk/include/asm-ppc64/byteorder.h b/trunk/include/asm-ppc64/byteorder.h
index 8b57da62b674..80327532de64 100644
--- a/trunk/include/asm-ppc64/byteorder.h
+++ b/trunk/include/asm-ppc64/byteorder.h
@@ -40,6 +40,7 @@ static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
}
+#if 0
static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
{
__u16 result;
@@ -62,8 +63,17 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
return result;
}
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value)
+{
+ __u64 result;
+#error implement me
+}
+
#define __arch__swab16(x) ___arch__swab16(x)
#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab64(x) ___arch__swab64(x)
+
+#endif
/* The same, but returns converted value from the location pointer by addr. */
#define __arch__swab16p(addr) ld_le16(addr)
diff --git a/trunk/include/asm-ppc64/pci.h b/trunk/include/asm-ppc64/pci.h
index d12dfce21e20..6cd593f660a0 100644
--- a/trunk/include/asm-ppc64/pci.h
+++ b/trunk/include/asm-ppc64/pci.h
@@ -78,25 +78,6 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
return 0;
}
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- unsigned long cacheline_size;
- u8 byte;
-
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
- if (byte == 0)
- cacheline_size = 1024;
- else
- cacheline_size = (int) byte * 4;
-
- *strat = PCI_DMA_BURST_MULTIPLE;
- *strategy_parameter = cacheline_size;
-}
-#endif
-
extern int pci_domain_nr(struct pci_bus *bus);
/* Decide whether to display the domain number in /proc */
@@ -155,13 +136,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file,
unsigned long size,
pgprot_t prot);
-#ifdef CONFIG_PPC_MULTIPLATFORM
-#define HAVE_ARCH_PCI_RESOURCE_TO_USER
-extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
- const struct resource *rsrc,
- u64 *start, u64 *end);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
#endif /* __KERNEL__ */
diff --git a/trunk/include/asm-sh/pci.h b/trunk/include/asm-sh/pci.h
index 26044889c770..9c3b63d0105e 100644
--- a/trunk/include/asm-sh/pci.h
+++ b/trunk/include/asm-sh/pci.h
@@ -96,16 +96,6 @@ static inline void pcibios_penalize_isa_irq(int irq)
#define sg_dma_address(sg) (virt_to_bus((sg)->dma_address))
#define sg_dma_len(sg) ((sg)->length)
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
/* Board-specific fixup routines. */
extern void pcibios_fixup(void);
extern void pcibios_fixup_irqs(void);
diff --git a/trunk/include/asm-sh64/pci.h b/trunk/include/asm-sh64/pci.h
index c68870e02d91..8cc14e139750 100644
--- a/trunk/include/asm-sh64/pci.h
+++ b/trunk/include/asm-sh64/pci.h
@@ -86,16 +86,6 @@ static inline void pcibios_penalize_isa_irq(int irq)
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->length)
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
/* Board-specific fixup routines. */
extern void pcibios_fixup(void);
extern void pcibios_fixup_irqs(void);
diff --git a/trunk/include/asm-sparc/pci.h b/trunk/include/asm-sparc/pci.h
index 44bb38758c96..d200a25a7373 100644
--- a/trunk/include/asm-sparc/pci.h
+++ b/trunk/include/asm-sparc/pci.h
@@ -144,16 +144,6 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
#define pci_dac_dma_supported(dev, mask) (0)
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
diff --git a/trunk/include/asm-sparc64/pci.h b/trunk/include/asm-sparc64/pci.h
index 84e41c1ef3f8..2a0c85cd1c11 100644
--- a/trunk/include/asm-sparc64/pci.h
+++ b/trunk/include/asm-sparc64/pci.h
@@ -220,25 +220,6 @@ static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
return (dma_addr == PCI_DMA_ERROR_CODE);
}
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- unsigned long cacheline_size;
- u8 byte;
-
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
- if (byte == 0)
- cacheline_size = 1024;
- else
- cacheline_size = (int) byte * 4;
-
- *strat = PCI_DMA_BURST_BOUNDARY;
- *strategy_parameter = cacheline_size;
-}
-#endif
-
/* Return the index of the PCI controller for device PDEV. */
extern int pci_domain_nr(struct pci_bus *bus);
diff --git a/trunk/include/asm-v850/pci.h b/trunk/include/asm-v850/pci.h
index 8e79be0fe99d..e41941447b49 100644
--- a/trunk/include/asm-v850/pci.h
+++ b/trunk/include/asm-v850/pci.h
@@ -81,16 +81,6 @@ extern void
pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
dma_addr_t dma_addr);
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
static inline void pcibios_add_platform_entries(struct pci_dev *dev)
{
}
diff --git a/trunk/include/asm-x86_64/pci.h b/trunk/include/asm-x86_64/pci.h
index c1961db88fac..8712520ca47f 100644
--- a/trunk/include/asm-x86_64/pci.h
+++ b/trunk/include/asm-x86_64/pci.h
@@ -123,16 +123,6 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr,
flush_write_buffers();
}
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
- enum pci_dma_burst_strategy *strat,
- unsigned long *strategy_parameter)
-{
- *strat = PCI_DMA_BURST_INFINITY;
- *strategy_parameter = ~0UL;
-}
-#endif
-
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h
index ef8483673aa3..b123cc08773d 100644
--- a/trunk/include/linux/acpi.h
+++ b/trunk/include/linux/acpi.h
@@ -342,19 +342,11 @@ struct acpi_table_ecdt {
/* PCI MMCONFIG */
-/* Defined in PCI Firmware Specification 3.0 */
-struct acpi_table_mcfg_config {
- u32 base_address;
- u32 base_reserved;
- u16 pci_segment_group_number;
- u8 start_bus_number;
- u8 end_bus_number;
- u8 reserved[4];
-} __attribute__ ((packed));
struct acpi_table_mcfg {
struct acpi_table_header header;
u8 reserved[8];
- struct acpi_table_mcfg_config config[0];
+ u32 base_address;
+ u32 base_reserved;
} __attribute__ ((packed));
/* Table Handlers */
@@ -399,7 +391,6 @@ int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
-int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size);
void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
@@ -416,13 +407,9 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu);
int acpi_unmap_lsapic(int cpu);
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
-int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
-int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
-
extern int acpi_mp_config;
-extern struct acpi_table_mcfg_config *pci_mmcfg_config;
-extern int pci_mmcfg_config_num;
+extern u32 pci_mmcfg_base_addr;
extern int sbf_port ;
diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h
index 0881b5cdee3d..21a8674cd149 100644
--- a/trunk/include/linux/blkdev.h
+++ b/trunk/include/linux/blkdev.h
@@ -96,7 +96,6 @@ struct io_context {
void put_io_context(struct io_context *ioc);
void exit_io_context(void);
-struct io_context *current_io_context(int gfp_flags);
struct io_context *get_io_context(int gfp_flags);
void copy_io_context(struct io_context **pdst, struct io_context **psrc);
void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
diff --git a/trunk/include/linux/byteorder/swabb.h b/trunk/include/linux/byteorder/swabb.h
index d5f2a3205109..d28d9a804d3b 100644
--- a/trunk/include/linux/byteorder/swabb.h
+++ b/trunk/include/linux/byteorder/swabb.h
@@ -92,32 +92,29 @@
#endif /* OPTIMIZE */
-static inline __u32 __fswahw32(__u32 x)
+static __inline__ __const__ __u32 __fswahw32(__u32 x)
{
return __arch__swahw32(x);
}
-
-static inline __u32 __swahw32p(__u32 *x)
+static __inline__ __u32 __swahw32p(__u32 *x)
{
return __arch__swahw32p(x);
}
-
-static inline void __swahw32s(__u32 *addr)
+static __inline__ void __swahw32s(__u32 *addr)
{
__arch__swahw32s(addr);
}
-static inline __u32 __fswahb32(__u32 x)
+
+static __inline__ __const__ __u32 __fswahb32(__u32 x)
{
return __arch__swahb32(x);
}
-
-static inline __u32 __swahb32p(__u32 *x)
+static __inline__ __u32 __swahb32p(__u32 *x)
{
return __arch__swahb32p(x);
}
-
-static inline void __swahb32s(__u32 *addr)
+static __inline__ void __swahb32s(__u32 *addr)
{
__arch__swahb32s(addr);
}
diff --git a/trunk/include/linux/etherdevice.h b/trunk/include/linux/etherdevice.h
index cf3847edc50f..a1478258d002 100644
--- a/trunk/include/linux/etherdevice.h
+++ b/trunk/include/linux/etherdevice.h
@@ -25,7 +25,6 @@
#define _LINUX_ETHERDEVICE_H
#include
-#include
#include
#ifdef __KERNEL__
@@ -66,7 +65,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
*/
static inline int is_multicast_ether_addr(const u8 *addr)
{
- return ((addr[0] != 0xff) && (0x01 & addr[0]));
+ return addr[0] & 0x01;
}
/**
diff --git a/trunk/include/linux/i2c-dev.h b/trunk/include/linux/i2c-dev.h
index 541695679762..d228230ffe5d 100644
--- a/trunk/include/linux/i2c-dev.h
+++ b/trunk/include/linux/i2c-dev.h
@@ -25,7 +25,6 @@
#define _LINUX_I2C_DEV_H
#include
-#include
/* Some IOCTL commands are defined in */
/* Note: 10-bit addresses are NOT supported! */
diff --git a/trunk/include/linux/in6.h b/trunk/include/linux/in6.h
index dcf5720ffcbb..f8256c582845 100644
--- a/trunk/include/linux/in6.h
+++ b/trunk/include/linux/in6.h
@@ -156,7 +156,7 @@ struct in6_flowlabel_req
#define IPV6_CHECKSUM 7
#define IPV6_HOPLIMIT 8
#define IPV6_NEXTHOP 9
-#define IPV6_AUTHHDR 10 /* obsolete */
+#define IPV6_AUTHHDR 10
#define IPV6_FLOWINFO 11
#define IPV6_UNICAST_HOPS 16
diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h
index 069d3b84d311..12277799c007 100644
--- a/trunk/include/linux/irq.h
+++ b/trunk/include/linux/irq.h
@@ -85,10 +85,9 @@ extern int no_irq_affinity;
extern int noirqdebug_setup(char *str);
extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
- struct irqaction *action);
+ struct irqaction *action);
extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
- int action_ret, struct pt_regs *regs);
+extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret);
extern int can_request_irq(unsigned int irq, unsigned long irqflags);
extern void init_irq_proc(void);
diff --git a/trunk/include/linux/netlink.h b/trunk/include/linux/netlink.h
index 27e4d164a108..3029cad63a01 100644
--- a/trunk/include/linux/netlink.h
+++ b/trunk/include/linux/netlink.h
@@ -168,7 +168,6 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
nlh->nlmsg_flags = flags;
nlh->nlmsg_pid = pid;
nlh->nlmsg_seq = seq;
- memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
return nlh;
}
diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h
index 66798b46f308..b5238bd18830 100644
--- a/trunk/include/linux/pci.h
+++ b/trunk/include/linux/pci.h
@@ -734,20 +734,16 @@ void pcibios_update_irq(struct pci_dev *, int irq);
/* Generic PCI functions used internally */
extern struct pci_bus *pci_find_bus(int domain, int busnr);
-void pci_bus_add_devices(struct pci_bus *bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
{
- struct pci_bus *root_bus;
- root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
- if (root_bus)
- pci_bus_add_devices(root_bus);
- return root_bus;
+ return pci_scan_bus_parented(NULL, bus, ops, sysdata);
}
int pci_scan_slot(struct pci_bus *bus, int devfn);
struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
unsigned int pci_scan_child_bus(struct pci_bus *bus);
void pci_bus_add_device(struct pci_dev *dev);
+void pci_bus_add_devices(struct pci_bus *bus);
void pci_name_device(struct pci_dev *dev);
char *pci_class_name(u32 class);
void pci_read_bridge_bases(struct pci_bus *child);
@@ -874,15 +870,6 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass
#define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle)
#define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
-enum pci_dma_burst_strategy {
- PCI_DMA_BURST_INFINITY, /* make bursts as large as possible,
- strategy_parameter is N/A */
- PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter
- byte boundaries */
- PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of
- strategy_parameter byte boundaries */
-};
-
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
extern struct pci_dev *isa_bridge;
#endif
@@ -985,8 +972,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif
-#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
-
#endif /* !CONFIG_PCI */
/* these helpers provide future and backwards compatibility
@@ -1031,20 +1016,6 @@ static inline char *pci_name(struct pci_dev *pdev)
#define pci_pretty_name(dev) ""
#endif
-
-/* Some archs don't want to expose struct resource to userland as-is
- * in sysfs and /proc
- */
-#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER
-static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
- const struct resource *rsrc, u64 *start, u64 *end)
-{
- *start = rsrc->start;
- *end = rsrc->end;
-}
-#endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */
-
-
/*
* The world is not perfect and supplies us with broken PCI devices.
* For at least a part of these bugs we need a work-around, so both
diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h
index c3ee1ae4545a..1e0bc6a8d653 100644
--- a/trunk/include/linux/pci_ids.h
+++ b/trunk/include/linux/pci_ids.h
@@ -62,8 +62,6 @@
#define PCI_BASE_CLASS_SYSTEM 0x08
#define PCI_CLASS_SYSTEM_PIC 0x0800
-#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010
-#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020
#define PCI_CLASS_SYSTEM_DMA 0x0801
#define PCI_CLASS_SYSTEM_TIMER 0x0802
#define PCI_CLASS_SYSTEM_RTC 0x0803
diff --git a/trunk/include/linux/pkt_cls.h b/trunk/include/linux/pkt_cls.h
index bd2c5a2bbbf5..25d2d67c1faf 100644
--- a/trunk/include/linux/pkt_cls.h
+++ b/trunk/include/linux/pkt_cls.h
@@ -276,7 +276,6 @@ struct tc_rsvp_pinfo
__u8 protocol;
__u8 tunnelid;
__u8 tunnelhdr;
- __u8 pad;
};
/* ROUTE filter */
diff --git a/trunk/include/linux/pkt_sched.h b/trunk/include/linux/pkt_sched.h
index 60ffcb9c5791..1d9da36eb9db 100644
--- a/trunk/include/linux/pkt_sched.h
+++ b/trunk/include/linux/pkt_sched.h
@@ -221,11 +221,9 @@ struct tc_gred_qopt
/* gred setup */
struct tc_gred_sopt
{
- __u32 DPs;
- __u32 def_DP;
- __u8 grio;
- __u8 pad1;
- __u16 pad2;
+ __u32 DPs;
+ __u32 def_DP;
+ __u8 grio;
};
/* HTB section */
@@ -353,7 +351,6 @@ struct tc_cbq_ovl
#define TC_CBQ_OVL_DROP 3
#define TC_CBQ_OVL_RCLASSIC 4
unsigned char priority2;
- __u16 pad;
__u32 penalty;
};
diff --git a/trunk/include/linux/rtnetlink.h b/trunk/include/linux/rtnetlink.h
index 657c05ab8f9e..d021888b58f1 100644
--- a/trunk/include/linux/rtnetlink.h
+++ b/trunk/include/linux/rtnetlink.h
@@ -363,8 +363,6 @@ enum
struct rta_session
{
__u8 proto;
- __u8 pad1;
- __u16 pad2;
union {
struct {
@@ -637,13 +635,10 @@ struct ifinfomsg
struct prefixmsg
{
unsigned char prefix_family;
- unsigned char prefix_pad1;
- unsigned short prefix_pad2;
int prefix_ifindex;
unsigned char prefix_type;
unsigned char prefix_len;
unsigned char prefix_flags;
- unsigned char prefix_pad3;
};
enum
@@ -903,9 +898,7 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi
memcpy(skb_put(skb, attrlen), data, attrlen); })
#define RTA_PUT_NOHDR(skb, attrlen, data) \
-({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \
- memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \
- RTA_ALIGN(attrlen) - attrlen); })
+ RTA_APPEND(skb, RTA_ALIGN(attrlen), data)
#define RTA_PUT_U8(skb, attrtype, value) \
({ u8 _tmp = (value); \
@@ -985,7 +978,6 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
rta->rta_type = attrtype;
rta->rta_len = size;
- memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
return rta;
}
diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h
index 5b5f434ac9a0..ebfe1250f0a4 100644
--- a/trunk/include/linux/sysctl.h
+++ b/trunk/include/linux/sysctl.h
@@ -641,7 +641,6 @@ enum {
NET_SCTP_ADDIP_ENABLE = 13,
NET_SCTP_PRSCTP_ENABLE = 14,
NET_SCTP_SNDBUF_POLICY = 15,
- NET_SCTP_SACK_TIMEOUT = 16,
};
/* /proc/sys/net/bridge */
diff --git a/trunk/include/linux/usb_ch9.h b/trunk/include/linux/usb_ch9.h
index ee21e6bf3867..39e7ff4ffd28 100644
--- a/trunk/include/linux/usb_ch9.h
+++ b/trunk/include/linux/usb_ch9.h
@@ -19,7 +19,7 @@
#ifndef __LINUX_USB_CH9_H
#define __LINUX_USB_CH9_H
-#include /* __u8 etc */
+#include /* __u8 etc */
/*-------------------------------------------------------------------------*/
@@ -294,8 +294,8 @@ struct usb_endpoint_descriptor {
__le16 wMaxPacketSize;
__u8 bInterval;
- /* NOTE: these two are _only_ in audio endpoints. */
- /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
+ // NOTE: these two are _only_ in audio endpoints.
+ // use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof.
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h
index acbfc525576d..4e0edce53760 100644
--- a/trunk/include/linux/videodev2.h
+++ b/trunk/include/linux/videodev2.h
@@ -221,8 +221,6 @@ struct v4l2_pix_format
/* Vendor-specific formats */
#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
-#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */
-#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
/*
* F O R M A T E N U M E R A T I O N
diff --git a/trunk/include/linux/writeback.h b/trunk/include/linux/writeback.h
index 542dbaee6512..d5c3fe1bf33d 100644
--- a/trunk/include/linux/writeback.h
+++ b/trunk/include/linux/writeback.h
@@ -85,7 +85,7 @@ static inline void wait_on_inode(struct inode *inode)
/*
* mm/page-writeback.c
*/
-int wakeup_pdflush(long nr_pages);
+int wakeup_bdflush(long nr_pages);
void laptop_io_completion(void);
void laptop_sync_completion(void);
void throttle_vm_writeout(void);
diff --git a/trunk/include/linux/xattr_acl.h b/trunk/include/linux/xattr_acl.h
new file mode 100644
index 000000000000..7a1f9b93a45f
--- /dev/null
+++ b/trunk/include/linux/xattr_acl.h
@@ -0,0 +1,50 @@
+/*
+ File: linux/xattr_acl.h
+
+ (extended attribute representation of access control lists)
+
+ (C) 2000 Andreas Gruenbacher,
+*/
+
+#ifndef _LINUX_XATTR_ACL_H
+#define _LINUX_XATTR_ACL_H
+
+#include
+
+#define XATTR_NAME_ACL_ACCESS "system.posix_acl_access"
+#define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default"
+
+#define XATTR_ACL_VERSION 0x0002
+
+typedef struct {
+ __u16 e_tag;
+ __u16 e_perm;
+ __u32 e_id;
+} xattr_acl_entry;
+
+typedef struct {
+ __u32 a_version;
+ xattr_acl_entry a_entries[0];
+} xattr_acl_header;
+
+static inline size_t xattr_acl_size(int count)
+{
+ return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry);
+}
+
+static inline int xattr_acl_count(size_t size)
+{
+ if (size < sizeof(xattr_acl_header))
+ return -1;
+ size -= sizeof(xattr_acl_header);
+ if (size % sizeof(xattr_acl_entry))
+ return -1;
+ return size / sizeof(xattr_acl_entry);
+}
+
+struct posix_acl * posix_acl_from_xattr(const void *value, size_t size);
+int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
+
+
+
+#endif /* _LINUX_XATTR_ACL_H */
diff --git a/trunk/include/media/tuner.h b/trunk/include/media/tuner.h
index 4794c5632360..2dd8310901e8 100644
--- a/trunk/include/media/tuner.h
+++ b/trunk/include/media/tuner.h
@@ -1,6 +1,5 @@
-/* $Id: tuner.h,v 1.33 2005/06/21 14:58:08 mkrufky Exp $
- *
+/*
tuner.h - definition for different tuners
Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
@@ -24,8 +23,6 @@
#ifndef _TUNER_H
#define _TUNER_H
-#include
-
#include "id.h"
#define ADDR_UNSET (255)
@@ -91,7 +88,7 @@
#define TUNER_LG_NTSC_TAPE 47
#define TUNER_TNF_8831BGFF 48
-#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
+#define TUNER_MICROTUNE_4042FI5 49 /* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */
#define TUNER_TCL_2002N 50
#define TUNER_PHILIPS_FM1256_IH3 51
@@ -101,18 +98,18 @@
#define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */
#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
-#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
#define TUNER_YMEC_TVF_8531MF 58
#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */
-#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */
+#define TUNER_THOMSON_DTT7611 60
#define TUNER_TENA_9533_DI 61
-
#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
-#define TUNER_PHILIPS_FMD1216ME_MK3 63
#define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio"
+#define TUNER_THOMSON_DTT7611 60
+
#define NOTUNER 0
#define PAL 1 /* PAL_BG */
#define PAL_I 2
@@ -197,15 +194,11 @@ struct tuner {
unsigned char i2c_easy_mode[2];
unsigned char i2c_set_freq[8];
- /* used to keep track of audmode */
- unsigned int audmode;
-
/* function ptrs */
void (*tv_freq)(struct i2c_client *c, unsigned int freq);
void (*radio_freq)(struct i2c_client *c, unsigned int freq);
int (*has_signal)(struct i2c_client *c);
int (*is_stereo)(struct i2c_client *c);
- int (*set_tuner)(struct i2c_client *c, struct v4l2_tuner *v);
};
extern unsigned int tuner_debug;
@@ -213,7 +206,6 @@ extern unsigned const int tuner_count;
extern int microtune_init(struct i2c_client *c);
extern int tda8290_init(struct i2c_client *c);
-extern int tea5767_tuner_init(struct i2c_client *c);
extern int default_tuner_init(struct i2c_client *c);
#define tuner_warn(fmt, arg...) \
diff --git a/trunk/include/net/ieee80211.h b/trunk/include/net/ieee80211.h
index db09580ad14b..7fe57f957a51 100644
--- a/trunk/include/net/ieee80211.h
+++ b/trunk/include/net/ieee80211.h
@@ -94,8 +94,6 @@ struct eapol {
u16 length;
} __attribute__ ((packed));
-#define IEEE80211_1ADDR_LEN 10
-#define IEEE80211_2ADDR_LEN 16
#define IEEE80211_3ADDR_LEN 24
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_FCS_LEN 4
@@ -302,6 +300,23 @@ struct ieee80211_snap_hdr {
#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
+/* Information Element IDs */
+#define WLAN_EID_SSID 0
+#define WLAN_EID_SUPP_RATES 1
+#define WLAN_EID_FH_PARAMS 2
+#define WLAN_EID_DS_PARAMS 3
+#define WLAN_EID_CF_PARAMS 4
+#define WLAN_EID_TIM 5
+#define WLAN_EID_IBSS_PARAMS 6
+#define WLAN_EID_CHALLENGE 16
+#define WLAN_EID_RSN 48
+#define WLAN_EID_GENERIC 221
+
+#define IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
+
+
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
@@ -426,10 +441,6 @@ struct ieee80211_stats {
struct ieee80211_device;
-#if 0 /* for later */
-#include "ieee80211_crypt.h"
-#endif
-
#define SEC_KEY_1 (1<<0)
#define SEC_KEY_2 (1<<1)
#define SEC_KEY_3 (1<<2)
@@ -477,6 +488,15 @@ Total: 28-2340 bytes
*/
+struct ieee80211_header_data {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[6];
+ u8 addr2[6];
+ u8 addr3[6];
+ u16 seq_ctrl;
+};
+
#define BEACON_PROBE_SSID_ID_POSITION 12
/* Management Frame Information Element Types */
@@ -521,7 +541,7 @@ struct ieee80211_info_element {
*/
struct ieee80211_authentication {
- struct ieee80211_hdr_3addr header;
+ struct ieee80211_header_data header;
u16 algorithm;
u16 transaction;
u16 status;
@@ -530,7 +550,7 @@ struct ieee80211_authentication {
struct ieee80211_probe_response {
- struct ieee80211_hdr_3addr header;
+ struct ieee80211_header_data header;
u32 time_stamp[2];
u16 beacon_interval;
u16 capability;
@@ -628,6 +648,12 @@ enum ieee80211_state {
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+extern inline int is_broadcast_ether_addr(const u8 *addr)
+{
+ return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
+ (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
+}
+
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
@@ -761,21 +787,21 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
extern inline int ieee80211_get_hdrlen(u16 fc)
{
- int hdrlen = IEEE80211_3ADDR_LEN;
+ int hdrlen = 24;
switch (WLAN_FC_GET_TYPE(fc)) {
case IEEE80211_FTYPE_DATA:
if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = IEEE80211_4ADDR_LEN;
+ hdrlen = 30; /* Addr4 */
break;
case IEEE80211_FTYPE_CTL:
switch (WLAN_FC_GET_STYPE(fc)) {
case IEEE80211_STYPE_CTS:
case IEEE80211_STYPE_ACK:
- hdrlen = IEEE80211_1ADDR_LEN;
+ hdrlen = 10;
break;
default:
- hdrlen = IEEE80211_2ADDR_LEN;
+ hdrlen = 16;
break;
}
break;
diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h
index 69324465e8b3..771b47e30f86 100644
--- a/trunk/include/net/ipv6.h
+++ b/trunk/include/net/ipv6.h
@@ -183,6 +183,7 @@ struct ipv6_txoptions
struct ipv6_opt_hdr *hopopt;
struct ipv6_opt_hdr *dst0opt;
struct ipv6_rt_hdr *srcrt; /* Routing Header */
+ struct ipv6_opt_hdr *auth;
struct ipv6_opt_hdr *dst1opt;
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
diff --git a/trunk/include/net/sctp/constants.h b/trunk/include/net/sctp/constants.h
index 5999e5684bbf..4868c7f7749d 100644
--- a/trunk/include/net/sctp/constants.h
+++ b/trunk/include/net/sctp/constants.h
@@ -263,11 +263,23 @@ enum { SCTP_MIN_PMTU = 576 };
enum { SCTP_MAX_DUP_TSNS = 16 };
enum { SCTP_MAX_GABS = 16 };
-/* Heartbeat interval - 30 secs */
-#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ)
+/* Here we define the default timers. */
-/* Delayed sack timer - 200ms */
+/* cookie timer def = ? seconds */
+#define SCTP_DEFAULT_TIMEOUT_T1_COOKIE (3 * HZ)
+
+/* init timer def = 3 seconds */
+#define SCTP_DEFAULT_TIMEOUT_T1_INIT (3 * HZ)
+
+/* shutdown timer def = 300 ms */
+#define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000)
+
+/* 0 seconds + RTO */
+#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (10 * HZ)
+
+/* recv timer def = 200ms (in usec) */
#define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000)
+#define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */
/* RTO.Initial - 3 seconds
* RTO.Min - 1 second
diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h
index 47727c7cc628..dfad4d3c581c 100644
--- a/trunk/include/net/sctp/structs.h
+++ b/trunk/include/net/sctp/structs.h
@@ -161,9 +161,6 @@ extern struct sctp_globals {
*/
int sndbuf_policy;
- /* Delayed SACK timeout 200ms default*/
- int sack_timeout;
-
/* HB.interval - 30 seconds */
int hb_interval;
@@ -220,7 +217,6 @@ extern struct sctp_globals {
#define sctp_sndbuf_policy (sctp_globals.sndbuf_policy)
#define sctp_max_retrans_path (sctp_globals.max_retrans_path)
#define sctp_max_retrans_init (sctp_globals.max_retrans_init)
-#define sctp_sack_timeout (sctp_globals.sack_timeout)
#define sctp_hb_interval (sctp_globals.hb_interval)
#define sctp_max_instreams (sctp_globals.max_instreams)
#define sctp_max_outstreams (sctp_globals.max_outstreams)
diff --git a/trunk/init/main.c b/trunk/init/main.c
index b5e421e39ede..d324801729ba 100644
--- a/trunk/init/main.c
+++ b/trunk/init/main.c
@@ -383,13 +383,6 @@ static void noinline rest_init(void)
numa_default_policy();
unlock_kernel();
preempt_enable_no_resched();
-
- /*
- * The boot idle thread must execute schedule()
- * at least one to get things moving:
- */
- schedule();
-
cpu_idle();
}
diff --git a/trunk/kernel/irq/autoprobe.c b/trunk/kernel/irq/autoprobe.c
index 3467097ca61a..98d62d8efeaf 100644
--- a/trunk/kernel/irq/autoprobe.c
+++ b/trunk/kernel/irq/autoprobe.c
@@ -9,7 +9,6 @@
#include
#include
#include
-#include
/*
* Autodetection depends on the fact that any interrupt that
@@ -27,7 +26,7 @@ static DECLARE_MUTEX(probe_sem);
*/
unsigned long probe_irq_on(void)
{
- unsigned long val;
+ unsigned long val, delay;
irq_desc_t *desc;
unsigned int i;
@@ -46,7 +45,8 @@ unsigned long probe_irq_on(void)
}
/* Wait for longstanding interrupts to trigger. */
- msleep(20);
+ for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+ /* about 20ms delay */ barrier();
/*
* enable any unassigned irqs
@@ -68,7 +68,8 @@ unsigned long probe_irq_on(void)
/*
* Wait for spurious interrupts to trigger
*/
- msleep(100);
+ for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+ /* about 100ms delay */ barrier();
/*
* Now filter out any obviously spurious interrupts
diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c
index c29f83c16497..436c7d93c00a 100644
--- a/trunk/kernel/irq/handle.c
+++ b/trunk/kernel/irq/handle.c
@@ -172,7 +172,7 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
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/kernel/irq/spurious.c b/trunk/kernel/irq/spurious.c
index 7df9abd5ec86..ba039e827d58 100644
--- a/trunk/kernel/irq/spurious.c
+++ b/trunk/kernel/irq/spurious.c
@@ -11,83 +11,6 @@
#include
#include
-static int irqfixup;
-
-/*
- * Recovery handler for misrouted interrupts.
- */
-
-static int misrouted_irq(int irq, struct pt_regs *regs)
-{
- int i;
- irq_desc_t *desc;
- int ok = 0;
- int work = 0; /* Did we do work for a real IRQ */
-
- for(i = 1; i < NR_IRQS; i++) {
- struct irqaction *action;
-
- if (i == irq) /* Already tried */
- continue;
- desc = &irq_desc[i];
- spin_lock(&desc->lock);
- action = desc->action;
- /* Already running on another processor */
- if (desc->status & IRQ_INPROGRESS) {
- /*
- * Already running: If it is shared get the other
- * CPU to go looking for our mystery interrupt too
- */
- if (desc->action && (desc->action->flags & SA_SHIRQ))
- desc->status |= IRQ_PENDING;
- spin_unlock(&desc->lock);
- continue;
- }
- /* Honour the normal IRQ locking */
- desc->status |= IRQ_INPROGRESS;
- spin_unlock(&desc->lock);
- while (action) {
- /* Only shared IRQ handlers are safe to call */
- if (action->flags & SA_SHIRQ) {
- if (action->handler(i, action->dev_id, regs) ==
- IRQ_HANDLED)
- ok = 1;
- }
- action = action->next;
- }
- local_irq_disable();
- /* Now clean up the flags */
- spin_lock(&desc->lock);
- action = desc->action;
-
- /*
- * While we were looking for a fixup someone queued a real
- * IRQ clashing with our walk
- */
-
- while ((desc->status & IRQ_PENDING) && action) {
- /*
- * Perform real IRQ processing for the IRQ we deferred
- */
- work = 1;
- spin_unlock(&desc->lock);
- handle_IRQ_event(i, regs, action);
- spin_lock(&desc->lock);
- desc->status &= ~IRQ_PENDING;
- }
- desc->status &= ~IRQ_INPROGRESS;
- /*
- * If we did actual work for the real IRQ line we must let the
- * IRQ controller clean up too
- */
- if(work)
- desc->handler->end(i);
- spin_unlock(&desc->lock);
- }
- /* So the caller can adjust the irq error counts */
- return ok;
-}
-
/*
* If 99,900 of the previous 100,000 interrupts have not been handled
* then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -108,8 +31,7 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
printk(KERN_ERR "irq event %d: bogus return value %x\n",
irq, action_ret);
} else {
- printk(KERN_ERR "irq %d: nobody cared (try booting with "
- "the \"irqpoll\" option)\n", irq);
+ printk(KERN_ERR "irq %d: nobody cared!\n", irq);
}
dump_stack();
printk(KERN_ERR "handlers:\n");
@@ -133,8 +55,7 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio
}
}
-void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
- struct pt_regs *regs)
+void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
{
if (action_ret != IRQ_HANDLED) {
desc->irqs_unhandled++;
@@ -142,15 +63,6 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
report_bad_irq(irq, desc, action_ret);
}
- if (unlikely(irqfixup)) {
- /* Don't punish working computers */
- if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
- int ok = misrouted_irq(irq, regs);
- if (action_ret == IRQ_NONE)
- desc->irqs_unhandled -= ok;
- }
- }
-
desc->irq_count++;
if (desc->irq_count < 100000)
return;
@@ -182,24 +94,3 @@ int __init noirqdebug_setup(char *str)
__setup("noirqdebug", noirqdebug_setup);
-static int __init irqfixup_setup(char *str)
-{
- irqfixup = 1;
- printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
- printk(KERN_WARNING "This may impact system performance.\n");
- return 1;
-}
-
-__setup("irqfixup", irqfixup_setup);
-
-static int __init irqpoll_setup(char *str)
-{
- irqfixup = 2;
- printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
- "enabled\n");
- printk(KERN_WARNING "This may significantly impact system "
- "performance\n");
- return 1;
-}
-
-__setup("irqpoll", irqpoll_setup);
diff --git a/trunk/kernel/itimer.c b/trunk/kernel/itimer.c
index a72cb0e5aa4b..1dc988e0d2c7 100644
--- a/trunk/kernel/itimer.c
+++ b/trunk/kernel/itimer.c
@@ -153,15 +153,11 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
switch (which) {
case ITIMER_REAL:
-again:
spin_lock_irq(&tsk->sighand->siglock);
interval = tsk->signal->it_real_incr;
val = it_real_value(tsk->signal);
- /* We are sharing ->siglock with it_real_fn() */
- if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) {
- spin_unlock_irq(&tsk->sighand->siglock);
- goto again;
- }
+ if (val)
+ del_timer_sync(&tsk->signal->real_timer);
tsk->signal->it_real_incr =
timeval_to_jiffies(&value->it_interval);
it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c
index cdd4dcd8fb63..7843548cf2d9 100644
--- a/trunk/kernel/kexec.c
+++ b/trunk/kernel/kexec.c
@@ -241,7 +241,7 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
unsigned long nr_segments,
- struct kexec_segment __user *segments)
+ struct kexec_segment *segments)
{
int result;
struct kimage *image;
@@ -650,7 +650,7 @@ static kimage_entry_t *kimage_dst_used(struct kimage *image,
}
}
- return NULL;
+ return 0;
}
static struct page *kimage_alloc_page(struct kimage *image,
@@ -696,7 +696,7 @@ static struct page *kimage_alloc_page(struct kimage *image,
/* Allocate a page, if we run out of memory give up */
page = kimage_alloc_pages(gfp_mask, 0);
if (!page)
- return NULL;
+ return 0;
/* If the page cannot be used file it away */
if (page_to_pfn(page) >
(KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
@@ -754,7 +754,7 @@ static int kimage_load_normal_segment(struct kimage *image,
unsigned long maddr;
unsigned long ubytes, mbytes;
int result;
- unsigned char __user *buf;
+ unsigned char *buf;
result = 0;
buf = segment->buf;
@@ -818,7 +818,7 @@ static int kimage_load_crash_segment(struct kimage *image,
unsigned long maddr;
unsigned long ubytes, mbytes;
int result;
- unsigned char __user *buf;
+ unsigned char *buf;
result = 0;
buf = segment->buf;
diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c
index 5f2182d42241..e2b0d3e4dd06 100644
--- a/trunk/kernel/sched.c
+++ b/trunk/kernel/sched.c
@@ -4166,14 +4166,6 @@ void show_state(void)
read_unlock(&tasklist_lock);
}
-/**
- * init_idle - set up an idle thread for a given CPU
- * @idle: task in question
- * @cpu: cpu the idle task belongs to
- *
- * NOTE: this function does not set the idle thread's NEED_RESCHED
- * flag, to make booting more robust.
- */
void __devinit init_idle(task_t *idle, int cpu)
{
runqueue_t *rq = cpu_rq(cpu);
@@ -4191,6 +4183,7 @@ void __devinit init_idle(task_t *idle, int cpu)
#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
idle->oncpu = 1;
#endif
+ set_tsk_need_resched(idle);
spin_unlock_irqrestore(&rq->lock, flags);
/* Set the preempt count _outside_ the spinlocks! */
diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c
index a6329fa8f862..613b99a55917 100644
--- a/trunk/mm/page-writeback.c
+++ b/trunk/mm/page-writeback.c
@@ -354,7 +354,7 @@ static void background_writeout(unsigned long _min_pages)
* the whole world. Returns 0 if a pdflush thread was dispatched. Returns
* -1 if all pdflush threads were busy.
*/
-int wakeup_pdflush(long nr_pages)
+int wakeup_bdflush(long nr_pages)
{
if (nr_pages == 0) {
struct writeback_state wbs;
diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c
index cfffe5098d53..1fa312a8db77 100644
--- a/trunk/mm/vmscan.c
+++ b/trunk/mm/vmscan.c
@@ -972,7 +972,7 @@ int try_to_free_pages(struct zone **zones, unsigned int gfp_mask)
* writeout. So in laptop mode, write out the whole world.
*/
if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) {
- wakeup_pdflush(laptop_mode ? 0 : total_scanned);
+ wakeup_bdflush(laptop_mode ? 0 : total_scanned);
sc.may_writepage = 1;
}
diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c
index 2d52fee63a8c..03ae4edddac3 100644
--- a/trunk/net/bridge/br_netfilter.c
+++ b/trunk/net/bridge/br_netfilter.c
@@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
* doesn't use the bridge parent of the indev by using
* the BRNF_DONT_TAKE_PARENT mask. */
if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
- nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
+ nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;
nf_bridge->physindev = (struct net_device *)in;
}
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
diff --git a/trunk/net/bridge/netfilter/ebt_log.c b/trunk/net/bridge/netfilter/ebt_log.c
index 662975be3d1d..e4ae34b88925 100644
--- a/trunk/net/bridge/netfilter/ebt_log.c
+++ b/trunk/net/bridge/netfilter/ebt_log.c
@@ -61,6 +61,8 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
{
struct ebt_log_info *info = (struct ebt_log_info *)data;
char level_string[4] = "< >";
+ union {struct iphdr iph; struct tcpudphdr ports;
+ struct arphdr arph; struct arppayload arpp;} u;
level_string[1] = '0' + info->loglevel;
spin_lock_bh(&ebt_log_lock);
@@ -86,7 +88,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
}
printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
- printk(" IP tos=0x%02X, IP proto=%d", ih->tos,
+ printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos,
ih->protocol);
if (ih->protocol == IPPROTO_TCP ||
ih->protocol == IPPROTO_UDP) {
@@ -125,7 +127,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
ah->ar_pln == sizeof(uint32_t)) {
struct arppayload _arpp, *ap;
- ap = skb_header_pointer(skb, sizeof(_arph),
+ ap = skb_header_pointer(skb, sizeof(u.arph),
sizeof(_arpp), &_arpp);
if (ap == NULL) {
printk(" INCOMPLETE ARP payload");
diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c
index 1beb782ac41b..851eb927ed97 100644
--- a/trunk/net/core/neighbour.c
+++ b/trunk/net/core/neighbour.c
@@ -1598,8 +1598,6 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
read_lock_bh(&tbl->lock);
ndtmsg->ndtm_family = tbl->family;
- ndtmsg->ndtm_pad1 = 0;
- ndtmsg->ndtm_pad2 = 0;
RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval);
@@ -1685,8 +1683,6 @@ static int neightbl_fill_param_info(struct neigh_table *tbl,
read_lock_bh(&tbl->lock);
ndtmsg->ndtm_family = tbl->family;
- ndtmsg->ndtm_pad1 = 0;
- ndtmsg->ndtm_pad2 = 0;
RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
if (neightbl_fill_parms(skb, parms) < 0)
@@ -1876,8 +1872,6 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n,
struct ndmsg *ndm = NLMSG_DATA(nlh);
ndm->ndm_family = n->ops->family;
- ndm->ndm_pad1 = 0;
- ndm->ndm_pad2 = 0;
ndm->ndm_flags = n->flags;
ndm->ndm_type = n->type;
ndm->ndm_ifindex = n->dev->ifindex;
diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c
index 4b1bb30e6381..e013d836a7ab 100644
--- a/trunk/net/core/rtnetlink.c
+++ b/trunk/net/core/rtnetlink.c
@@ -126,7 +126,6 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data
rta->rta_type = attrtype;
rta->rta_len = size;
memcpy(RTA_DATA(rta), data, attrlen);
- memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
}
size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
@@ -189,7 +188,6 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags);
r = NLMSG_DATA(nlh);
r->ifi_family = AF_UNSPEC;
- r->__ifi_pad = 0;
r->ifi_type = dev->type;
r->ifi_index = dev->ifindex;
r->ifi_flags = dev_get_flags(dev);
diff --git a/trunk/net/core/wireless.c b/trunk/net/core/wireless.c
index 3ff5639c0b78..b2fe378dfbf8 100644
--- a/trunk/net/core/wireless.c
+++ b/trunk/net/core/wireless.c
@@ -1102,7 +1102,6 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb,
nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
r = NLMSG_DATA(nlh);
r->ifi_family = AF_UNSPEC;
- r->__ifi_pad = 0;
r->ifi_type = dev->type;
r->ifi_index = dev->ifindex;
r->ifi_flags = dev->flags;
diff --git a/trunk/net/ethernet/eth.c b/trunk/net/ethernet/eth.c
index ab60ea63688e..6617ea47d365 100644
--- a/trunk/net/ethernet/eth.c
+++ b/trunk/net/ethernet/eth.c
@@ -92,9 +92,10 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
* Set the source hardware address.
*/
- if(!saddr)
- saddr = dev->dev_addr;
- memcpy(eth->h_source,saddr,dev->addr_len);
+ if(saddr)
+ memcpy(eth->h_source,saddr,dev->addr_len);
+ else
+ memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
/*
* Anyway, the loopback-device should never use this function...
diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c
index b56e88edf1b3..0671569ee6f0 100644
--- a/trunk/net/ipv4/fib_trie.c
+++ b/trunk/net/ipv4/fib_trie.c
@@ -43,7 +43,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#define VERSION "0.324"
+#define VERSION "0.323"
#include
#include
@@ -341,10 +341,8 @@ static struct leaf *leaf_new(void)
static struct leaf_info *leaf_info_new(int plen)
{
struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
- if(li) {
- li->plen = plen;
- INIT_LIST_HEAD(&li->falh);
- }
+ li->plen = plen;
+ INIT_LIST_HEAD(&li->falh);
return li;
}
@@ -881,8 +879,8 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
return (struct node*) tn;
}
-static struct list_head *
-fib_insert_node(struct trie *t, int *err, u32 key, int plen)
+static struct list_head *
+fib_insert_node(struct trie *t, u32 key, int plen)
{
int pos, newpos;
struct tnode *tp = NULL, *tn = NULL;
@@ -942,6 +940,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
if(tp && IS_LEAF(tp))
BUG();
+ t->revision++;
/* Case 1: n is a leaf. Compare prefixes */
@@ -950,10 +949,8 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
li = leaf_info_new(plen);
- if(! li) {
- *err = -ENOMEM;
- goto err;
- }
+ if(! li)
+ BUG();
fa_head = &li->falh;
insert_leaf_info(&l->list, li);
@@ -962,19 +959,14 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
t->size++;
l = leaf_new();
- if(! l) {
- *err = -ENOMEM;
- goto err;
- }
+ if(! l)
+ BUG();
l->key = key;
li = leaf_info_new(plen);
- if(! li) {
- tnode_free((struct tnode *) l);
- *err = -ENOMEM;
- goto err;
- }
+ if(! li)
+ BUG();
fa_head = &li->falh;
insert_leaf_info(&l->list, li);
@@ -1011,14 +1003,9 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
newpos = 0;
tn = tnode_new(key, newpos, 1); /* First tnode */
}
+ if(!tn)
+ trie_bug("tnode_pfx_new failed");
- if(!tn) {
- free_leaf_info(li);
- tnode_free((struct tnode *) l);
- *err = -ENOMEM;
- goto err;
- }
-
NODE_SET_PARENT(tn, tp);
missbit=tkey_extract_bits(key, newpos, 1);
@@ -1040,9 +1027,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
}
/* Rebalance the trie */
t->trie = trie_rebalance(t, tp);
-done:
- t->revision++;
-err:;
+done:;
return fa_head;
}
@@ -1171,12 +1156,8 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
* Insert new entry to the list.
*/
- if(!fa_head) {
- fa_head = fib_insert_node(t, &err, key, plen);
- err = 0;
- if(err)
- goto out_free_new_fa;
- }
+ if(!fa_head)
+ fa_head = fib_insert_node(t, key, plen);
write_lock_bh(&fib_lock);
@@ -1189,9 +1170,6 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
succeeded:
return 0;
-
-out_free_new_fa:
- kmem_cache_free(fn_alias_kmem, new_fa);
out:
fib_release_info(fi);
err:;
diff --git a/trunk/net/ipv4/ip_input.c b/trunk/net/ipv4/ip_input.c
index c703528e0bcd..af2ec88bbb2f 100644
--- a/trunk/net/ipv4/ip_input.c
+++ b/trunk/net/ipv4/ip_input.c
@@ -283,18 +283,14 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
struct iphdr *iph = skb->nh.iph;
- int err;
/*
* Initialise the virtual path cache for the packet. It describes
* how the packet travels inside Linux networking.
*/
if (skb->dst == NULL) {
- if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
- if (err == -EHOSTUNREACH)
- IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
+ if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))
goto drop;
- }
}
#ifdef CONFIG_NET_CLS_ROUTE
diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c
index 6ce5c3292f9f..ee07aec215a0 100644
--- a/trunk/net/ipv4/ip_output.c
+++ b/trunk/net/ipv4/ip_output.c
@@ -188,13 +188,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
skb = skb2;
}
-#ifdef CONFIG_BRIDGE_NETFILTER
- /* bridge-netfilter defers calling some IP hooks to the bridge layer
- * and still needs the conntrack reference.
- */
- if (skb->nf_bridge == NULL)
-#endif
- nf_reset(skb);
+ nf_reset(skb);
if (hh) {
int hh_alen;
diff --git a/trunk/net/ipv4/ipconfig.c b/trunk/net/ipv4/ipconfig.c
index d2bf8e1930a3..f2509034ce72 100644
--- a/trunk/net/ipv4/ipconfig.c
+++ b/trunk/net/ipv4/ipconfig.c
@@ -1149,10 +1149,8 @@ static int __init ic_dynamic(void)
ic_rarp_cleanup();
#endif
- if (!ic_got_reply) {
- ic_myaddr = INADDR_NONE;
+ if (!ic_got_reply)
return -1;
- }
printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
((ic_got_reply & IC_RARP) ? "RARP"
diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c
index 7833d920bdba..e4f809a93f47 100644
--- a/trunk/net/ipv4/ipmr.c
+++ b/trunk/net/ipv4/ipmr.c
@@ -297,7 +297,6 @@ static int vif_delete(int vifi)
static void ipmr_destroy_unres(struct mfc_cache *c)
{
struct sk_buff *skb;
- struct nlmsgerr *e;
atomic_dec(&cache_resolve_queue_len);
@@ -307,9 +306,7 @@ static void ipmr_destroy_unres(struct mfc_cache *c)
nlh->nlmsg_type = NLMSG_ERROR;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
skb_trim(skb, nlh->nlmsg_len);
- e = NLMSG_DATA(nlh);
- e->error = -ETIMEDOUT;
- memset(&e->msg, 0, sizeof(e->msg));
+ ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
} else
kfree_skb(skb);
@@ -502,7 +499,6 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void)
static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
{
struct sk_buff *skb;
- struct nlmsgerr *e;
/*
* Play the pending entries through our router
@@ -519,9 +515,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
nlh->nlmsg_type = NLMSG_ERROR;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
skb_trim(skb, nlh->nlmsg_len);
- e = NLMSG_DATA(nlh);
- e->error = -EMSGSIZE;
- memset(&e->msg, 0, sizeof(e->msg));
+ ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE;
}
err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
} else
diff --git a/trunk/net/ipv4/ipvs/ip_vs_conn.c b/trunk/net/ipv4/ipvs/ip_vs_conn.c
index 9f16ab309106..fd6feb5499fe 100644
--- a/trunk/net/ipv4/ipvs/ip_vs_conn.c
+++ b/trunk/net/ipv4/ipvs/ip_vs_conn.c
@@ -548,6 +548,7 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
{
if (del_timer(&cp->timer))
mod_timer(&cp->timer, jiffies);
+ __ip_vs_conn_put(cp);
}
@@ -763,6 +764,7 @@ void ip_vs_random_dropentry(void)
{
int idx;
struct ip_vs_conn *cp;
+ struct ip_vs_conn *ct;
/*
* Randomly scan 1/32 of the whole table every second
@@ -799,12 +801,21 @@ void ip_vs_random_dropentry(void)
continue;
}
+ /*
+ * Drop the entry, and drop its ct if not referenced
+ */
+ atomic_inc(&cp->refcnt);
+ ct_write_unlock(hash);
+
+ if ((ct = cp->control))
+ atomic_inc(&ct->refcnt);
IP_VS_DBG(4, "del connection\n");
ip_vs_conn_expire_now(cp);
- if (cp->control) {
+ if (ct) {
IP_VS_DBG(4, "del conn template\n");
- ip_vs_conn_expire_now(cp->control);
+ ip_vs_conn_expire_now(ct);
}
+ ct_write_lock(hash);
}
ct_write_unlock(hash);
}
@@ -818,6 +829,7 @@ static void ip_vs_conn_flush(void)
{
int idx;
struct ip_vs_conn *cp;
+ struct ip_vs_conn *ct;
flush_again:
for (idx=0; idxrefcnt);
+ ct_write_unlock(idx);
+ if ((ct = cp->control))
+ atomic_inc(&ct->refcnt);
IP_VS_DBG(4, "del connection\n");
ip_vs_conn_expire_now(cp);
- if (cp->control) {
+ if (ct) {
IP_VS_DBG(4, "del conn template\n");
- ip_vs_conn_expire_now(cp->control);
+ ip_vs_conn_expire_now(ct);
}
+ ct_write_lock(idx);
}
ct_write_unlock_bh(idx);
}
diff --git a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 6706d3a1bc4f..9cde8c61f525 100644
--- a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -30,7 +30,7 @@
#include
#include
-#define CLUSTERIP_VERSION "0.7"
+#define CLUSTERIP_VERSION "0.6"
#define DEBUG_CLUSTERIP
@@ -524,9 +524,8 @@ arp_mangle(unsigned int hook,
|| arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN)
return NF_ACCEPT;
- /* we only want to mangle arp requests and replies */
- if (arp->ar_op != htons(ARPOP_REPLY)
- && arp->ar_op != htons(ARPOP_REQUEST))
+ /* we only want to mangle arp replies */
+ if (arp->ar_op != htons(ARPOP_REPLY))
return NF_ACCEPT;
payload = (void *)(arp+1);
diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c
index 12a1cf306f67..80cf633d9f4a 100644
--- a/trunk/net/ipv4/route.c
+++ b/trunk/net/ipv4/route.c
@@ -1909,7 +1909,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
*/
if ((err = fib_lookup(&fl, &res)) != 0) {
if (!IN_DEV_FORWARD(in_dev))
- goto e_hostunreach;
+ goto e_inval;
goto no_route;
}
free_res = 1;
@@ -1933,7 +1933,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
}
if (!IN_DEV_FORWARD(in_dev))
- goto e_hostunreach;
+ goto e_inval;
if (res.type != RTN_UNICAST)
goto martian_destination;
@@ -2025,11 +2025,6 @@ out: return err;
"%u.%u.%u.%u, dev %s\n",
NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
#endif
-
-e_hostunreach:
- err = -EHOSTUNREACH;
- goto done;
-
e_inval:
err = -EINVAL;
goto done;
diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c
index 77004b9456c0..a54d4ef3fd35 100644
--- a/trunk/net/ipv6/addrconf.c
+++ b/trunk/net/ipv6/addrconf.c
@@ -2777,7 +2777,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
read_lock_bh(&idev->lock);
switch (type) {
case UNICAST_ADDR:
- /* unicast address incl. temp addr */
+ /* unicast address */
for (ifa = idev->addr_list; ifa;
ifa = ifa->if_next, ip_idx++) {
if (ip_idx < s_ip_idx)
@@ -2788,6 +2788,19 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
NLM_F_MULTI)) <= 0)
goto done;
}
+ /* temp addr */
+#ifdef CONFIG_IPV6_PRIVACY
+ for (ifa = idev->tempaddr_list; ifa;
+ ifa = ifa->tmp_next, ip_idx++) {
+ if (ip_idx < s_ip_idx)
+ continue;
+ if ((err = inet6_fill_ifaddr(skb, ifa,
+ NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq, RTM_NEWADDR,
+ NLM_F_MULTI)) <= 0)
+ goto done;
+ }
+#endif
break;
case MULTICAST_ADDR:
/* multicast address */
@@ -2910,7 +2923,6 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
r = NLMSG_DATA(nlh);
r->ifi_family = AF_INET6;
- r->__ifi_pad = 0;
r->ifi_type = dev->type;
r->ifi_index = dev->ifindex;
r->ifi_flags = dev_get_flags(dev);
@@ -3018,12 +3030,9 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags);
pmsg = NLMSG_DATA(nlh);
pmsg->prefix_family = AF_INET6;
- pmsg->prefix_pad1 = 0;
- pmsg->prefix_pad2 = 0;
pmsg->prefix_ifindex = idev->dev->ifindex;
pmsg->prefix_len = pinfo->prefix_len;
pmsg->prefix_type = pinfo->type;
- pmsg->prefix_pad3 = 0;
pmsg->prefix_flags = 0;
if (pinfo->onlink)
diff --git a/trunk/net/ipv6/ip6_flowlabel.c b/trunk/net/ipv6/ip6_flowlabel.c
index b6c73da5ff35..0e5f7499debb 100644
--- a/trunk/net/ipv6/ip6_flowlabel.c
+++ b/trunk/net/ipv6/ip6_flowlabel.c
@@ -244,6 +244,7 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
opt_space->opt_nflen = 0;
}
opt_space->dst1opt = fopt->dst1opt;
+ opt_space->auth = fopt->auth;
opt_space->opt_flen = fopt->opt_flen;
return opt_space;
}
diff --git a/trunk/net/sched/act_api.c b/trunk/net/sched/act_api.c
index 249c61936ea0..9594206e6035 100644
--- a/trunk/net/sched/act_api.c
+++ b/trunk/net/sched/act_api.c
@@ -439,8 +439,6 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
- t->tca__pad1 = 0;
- t->tca__pad2 = 0;
x = (struct rtattr*) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -582,8 +580,6 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
- t->tca__pad1 = 0;
- t->tca__pad2 = 0;
x = (struct rtattr *) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -691,9 +687,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
- t->tca__pad1 = 0;
- t->tca__pad2 = 0;
-
+
x = (struct rtattr*) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -848,8 +842,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
cb->nlh->nlmsg_type, sizeof(*t));
t = NLMSG_DATA(nlh);
t->tca_family = AF_UNSPEC;
- t->tca__pad1 = 0;
- t->tca__pad2 = 0;
x = (struct rtattr *) skb->tail;
RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
diff --git a/trunk/net/sched/cls_api.c b/trunk/net/sched/cls_api.c
index 3b5714ef4d1a..1616bf5c9627 100644
--- a/trunk/net/sched/cls_api.c
+++ b/trunk/net/sched/cls_api.c
@@ -331,8 +331,6 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
tcm = NLMSG_DATA(nlh);
tcm->tcm_family = AF_UNSPEC;
- tcm->tcm__pad1 = 0;
- tcm->tcm__pad1 = 0;
tcm->tcm_ifindex = tp->q->dev->ifindex;
tcm->tcm_parent = tp->classid;
tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
diff --git a/trunk/net/sched/cls_rsvp.h b/trunk/net/sched/cls_rsvp.h
index 006168d69376..232fb9196810 100644
--- a/trunk/net/sched/cls_rsvp.h
+++ b/trunk/net/sched/cls_rsvp.h
@@ -618,7 +618,6 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
pinfo.protocol = s->protocol;
pinfo.tunnelid = s->tunnelid;
pinfo.tunnelhdr = f->tunnelhdr;
- pinfo.pad = 0;
RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
if (f->res.classid)
RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
diff --git a/trunk/net/sched/sch_api.c b/trunk/net/sched/sch_api.c
index 05e6e0a799da..97c1c75d5c78 100644
--- a/trunk/net/sched/sch_api.c
+++ b/trunk/net/sched/sch_api.c
@@ -770,8 +770,6 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
tcm = NLMSG_DATA(nlh);
tcm->tcm_family = AF_UNSPEC;
- tcm->tcm__pad1 = 0;
- tcm->tcm__pad2 = 0;
tcm->tcm_ifindex = q->dev->ifindex;
tcm->tcm_parent = clid;
tcm->tcm_handle = q->handle;
diff --git a/trunk/net/sched/sch_cbq.c b/trunk/net/sched/sch_cbq.c
index 09453f997d8c..d43e3b8cbf6a 100644
--- a/trunk/net/sched/sch_cbq.c
+++ b/trunk/net/sched/sch_cbq.c
@@ -1528,7 +1528,6 @@ static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
opt.strategy = cl->ovl_strategy;
opt.priority2 = cl->priority2+1;
- opt.pad = 0;
opt.penalty = (cl->penalty*1000)/HZ;
RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
return skb->len;
@@ -1564,8 +1563,6 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
if (cl->police) {
opt.police = cl->police;
- opt.__res1 = 0;
- opt.__res2 = 0;
RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
}
return skb->len;
diff --git a/trunk/net/sctp/endpointola.c b/trunk/net/sctp/endpointola.c
index c44bf4165c6e..2ec0320fac3b 100644
--- a/trunk/net/sctp/endpointola.c
+++ b/trunk/net/sctp/endpointola.c
@@ -102,9 +102,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
/* Set up the base timeout information. */
ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0;
ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
- msecs_to_jiffies(sp->rtoinfo.srto_initial);
+ SCTP_DEFAULT_TIMEOUT_T1_COOKIE;
ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
- msecs_to_jiffies(sp->rtoinfo.srto_initial);
+ SCTP_DEFAULT_TIMEOUT_T1_INIT;
ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] =
msecs_to_jiffies(sp->rtoinfo.srto_initial);
ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
@@ -117,9 +117,12 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
= 5 * msecs_to_jiffies(sp->rtoinfo.srto_max);
- ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
- ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout;
- ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ;
+ ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] =
+ SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+ ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
+ SCTP_DEFAULT_TIMEOUT_SACK;
+ ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
+ sp->autoclose * HZ;
/* Use SCTP specific send buffer space queues. */
ep->sndbuf_policy = sctp_sndbuf_policy;
diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c
index e7f37faba7c0..5135e1a25d25 100644
--- a/trunk/net/sctp/protocol.c
+++ b/trunk/net/sctp/protocol.c
@@ -1050,10 +1050,7 @@ SCTP_STATIC __init int sctp_init(void)
sctp_sndbuf_policy = 0;
/* HB.interval - 30 seconds */
- sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
-
- /* delayed SACK timeout */
- sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK;
+ sctp_hb_interval = 30 * HZ;
/* Implementation specific variables. */
diff --git a/trunk/net/sctp/sysctl.c b/trunk/net/sctp/sysctl.c
index dc4893474f18..7fc31849312b 100644
--- a/trunk/net/sctp/sysctl.c
+++ b/trunk/net/sctp/sysctl.c
@@ -47,8 +47,6 @@
static ctl_handler sctp_sysctl_jiffies_ms;
static long rto_timer_min = 1;
static long rto_timer_max = 86400000; /* One day */
-static long sack_timer_min = 1;
-static long sack_timer_max = 500;
static ctl_table sctp_table[] = {
{
@@ -189,17 +187,6 @@ static ctl_table sctp_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec
},
- {
- .ctl_name = NET_SCTP_SACK_TIMEOUT,
- .procname = "sack_timeout",
- .data = &sctp_sack_timeout,
- .maxlen = sizeof(long),
- .mode = 0644,
- .proc_handler = &proc_doulongvec_ms_jiffies_minmax,
- .strategy = &sctp_sysctl_jiffies_ms,
- .extra1 = &sack_timer_min,
- .extra2 = &sack_timer_max,
- },
{ .ctl_name = 0 }
};
diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c
index a63b69179607..0ec0fde6e6c5 100644
--- a/trunk/net/sctp/transport.c
+++ b/trunk/net/sctp/transport.c
@@ -103,6 +103,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
/* Set up the heartbeat timer. */
init_timer(&peer->hb_timer);
+ peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
peer->hb_timer.function = sctp_generate_heartbeat_event;
peer->hb_timer.data = (unsigned long)peer;