Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b66fa17c
Commit
b66fa17c
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.3.99pre5
parent
de0d207b
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
578 additions
and
478 deletions
+578
-478
Makefile
Makefile
+1
-1
arch/i386/kernel/Makefile
arch/i386/kernel/Makefile
+1
-1
arch/i386/kernel/pci-i386.h
arch/i386/kernel/pci-i386.h
+39
-1
arch/i386/kernel/pci-irq.c
arch/i386/kernel/pci-irq.c
+431
-0
arch/i386/kernel/pci-pc.c
arch/i386/kernel/pci-pc.c
+75
-460
drivers/net/Space.c
drivers/net/Space.c
+1
-1
drivers/pci/pci.c
drivers/pci/pci.c
+18
-1
drivers/usb/usb.c
drivers/usb/usb.c
+6
-8
fs/namei.c
fs/namei.c
+1
-1
fs/nfs/inode.c
fs/nfs/inode.c
+1
-1
include/linux/pci.h
include/linux/pci.h
+3
-1
include/linux/usb.h
include/linux/usb.h
+1
-2
No files found.
Makefile
View file @
b66fa17c
VERSION
=
2
PATCHLEVEL
=
3
SUBLEVEL
=
99
EXTRAVERSION
=
-pre
4
EXTRAVERSION
=
-pre
5
KERNELRELEASE
=
$(VERSION)
.
$(PATCHLEVEL)
.
$(SUBLEVEL)$(EXTRAVERSION)
...
...
arch/i386/kernel/Makefile
View file @
b66fa17c
...
...
@@ -24,7 +24,7 @@ O_OBJS += pci-i386.o
ifdef
CONFIG_VISWS
O_OBJS
+=
pci-visws.o
else
O_OBJS
+=
pci-pc.o
O_OBJS
+=
pci-pc.o
pci-irq.o
endif
endif
...
...
arch/i386/kernel/pci-i386.h
View file @
b66fa17c
...
...
@@ -18,7 +18,6 @@
#define PCI_NO_SORT 0x100
#define PCI_BIOS_SORT 0x200
#define PCI_NO_CHECKS 0x400
#define PCI_PEER_FIXUP 0x800
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
...
...
@@ -28,3 +27,42 @@ extern unsigned int pci_probe;
void
pcibios_resource_survey
(
void
);
int
pcibios_enable_resources
(
struct
pci_dev
*
);
/* pci-pc.c */
extern
int
pcibios_last_bus
;
extern
struct
pci_bus
*
pci_root_bus
;
extern
struct
pci_ops
*
pci_root_ops
;
struct
irq_routing_table
*
pcibios_get_irq_routing_table
(
void
);
int
pcibios_set_irq_routing
(
struct
pci_dev
*
dev
,
int
pin
,
int
irq
);
/* pci-irq.c */
struct
irq_info
{
u8
bus
,
devfn
;
/* Bus, device and function */
struct
{
u8
link
;
/* IRQ line ID, chipset dependent, 0=not routed */
u16
bitmap
;
/* Available IRQs */
}
__attribute__
((
packed
))
irq
[
4
];
u8
slot
;
/* Slot number, 0=onboard */
u8
rfu
;
}
__attribute__
((
packed
));
struct
irq_routing_table
{
u32
signature
;
/* PIRQ_SIGNATURE should be here */
u16
version
;
/* PIRQ_VERSION */
u16
size
;
/* Table size in bytes */
u8
rtr_bus
,
rtr_devfn
;
/* Where the interrupt router lies */
u16
exclusive_irqs
;
/* IRQs devoted exclusively to PCI usage */
u16
rtr_vendor
,
rtr_device
;
/* Vendor and device ID of interrupt router */
u32
miniport_data
;
/* Crap */
u8
rfu
[
11
];
u8
checksum
;
/* Modulo 256 checksum must give zero */
struct
irq_info
slots
[
0
];
}
__attribute__
((
packed
));
extern
unsigned
int
pcibios_irq_mask
;
void
pcibios_fixup_irqs
(
void
);
int
pcibios_lookup_irq
(
struct
pci_dev
*
dev
,
int
assign
);
arch/i386/kernel/pci-irq.c
0 → 100644
View file @
b66fa17c
/*
* Low-Level PCI Support for PC -- Routing of Interrupts
*
* (c) 1999--2000 Martin Mares <mj@suse.cz>
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
#include "pci-i386.h"
extern
int
skip_ioapic_setup
;
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
#define PIRQ_VERSION 0x0100
static
struct
irq_routing_table
*
pirq_table
;
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
*/
unsigned
int
pcibios_irq_mask
=
~
0
;
static
unsigned
pirq_penalty
[
16
]
=
{
10000
,
10000
,
10000
,
100
,
100
,
0
,
0
,
100
,
0
,
0
,
0
,
0
,
100
,
1000
,
1000
,
1000
};
struct
irq_router
{
char
*
name
;
u16
vendor
,
device
;
int
(
*
get
)(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
);
int
(
*
set
)(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
new
);
};
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
static
struct
irq_routing_table
*
__init
pirq_find_routing_table
(
void
)
{
u8
*
addr
;
struct
irq_routing_table
*
rt
;
int
i
;
u8
sum
;
for
(
addr
=
(
u8
*
)
__va
(
0xf0000
);
addr
<
(
u8
*
)
__va
(
0x100000
);
addr
+=
16
)
{
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
;
i
<
rt
->
size
;
i
++
)
sum
+=
addr
[
i
];
if
(
!
sum
)
{
DBG
(
"PCI: Interrupt Routing Table found at 0x%p
\n
"
,
rt
);
return
rt
;
}
}
return
NULL
;
}
/*
* If we have a IRQ routing table, use it to search for peer host
* bridges. It's a gross hack, but since there are no other known
* ways how to get a list of buses, we have to go this way.
*/
static
void
__init
pirq_peer_trick
(
void
)
{
struct
irq_routing_table
*
rt
=
pirq_table
;
u8
busmap
[
256
];
int
i
;
struct
irq_info
*
e
;
memset
(
busmap
,
0
,
sizeof
(
busmap
));
for
(
i
=
0
;
i
<
(
rt
->
size
-
sizeof
(
struct
irq_routing_table
))
/
sizeof
(
struct
irq_info
);
i
++
)
{
e
=
&
rt
->
slots
[
i
];
#ifdef DEBUG
{
int
j
;
DBG
(
"%02x:%02x slot=%02x"
,
e
->
bus
,
e
->
devfn
/
8
,
e
->
slot
);
for
(
j
=
0
;
j
<
4
;
j
++
)
DBG
(
" %d:%02x/%04x"
,
j
,
e
->
irq
[
j
].
link
,
e
->
irq
[
j
].
bitmap
);
DBG
(
"
\n
"
);
}
#endif
busmap
[
e
->
bus
]
=
1
;
}
for
(
i
=
1
;
i
<
256
;
i
++
)
/*
* It might be a secondary bus, but in this case its parent is already
* known (ascending bus order) and therefore pci_scan_bus returns immediately.
*/
if
(
busmap
[
i
]
&&
pci_scan_bus
(
i
,
pci_root_bus
->
ops
,
NULL
))
printk
(
"PCI: Discovered primary peer bus %02x [IRQ]
\n
"
,
i
);
pcibios_last_bus
=
-
1
;
}
/*
* Code for querying and setting of IRQ routes on various interrupt routers.
*/
static
void
eisa_set_level_irq
(
unsigned
int
irq
)
{
unsigned
char
mask
=
1
<<
(
irq
&
7
);
unsigned
int
port
=
0x4d0
+
(
irq
>>
3
);
unsigned
char
val
=
inb
(
port
);
if
(
!
(
val
&
mask
))
{
DBG
(
" -> edge"
);
outb
(
val
|
mask
,
port
);
}
}
static
int
pirq_ali_set
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
irq
)
{
static
unsigned
char
irqmap
[
16
]
=
{
0
,
8
,
0
,
2
,
4
,
5
,
7
,
6
,
0
,
1
,
3
,
9
,
11
,
0
,
13
,
15
};
unsigned
int
val
=
irqmap
[
irq
];
pirq
--
;
if
(
val
&&
pirq
<
8
)
{
u8
x
;
unsigned
reg
=
0x48
+
(
pirq
>>
1
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
x
=
(
pirq
&
1
)
?
((
x
&
0x0f
)
|
(
val
<<
4
))
:
((
x
&
0xf0
)
|
val
);
pci_write_config_byte
(
router
,
reg
,
x
);
eisa_set_level_irq
(
irq
);
return
1
;
}
return
0
;
}
static
int
pirq_piix_get
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
)
{
u8
x
;
pci_read_config_byte
(
router
,
pirq
,
&
x
);
return
(
x
<
16
)
?
x
:
0
;
}
static
int
pirq_piix_set
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
irq
)
{
pci_write_config_byte
(
router
,
pirq
,
irq
);
return
1
;
}
static
int
pirq_via_get
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
)
{
u8
x
;
int
reg
=
0x55
+
(
pirq
>>
1
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
return
(
pirq
&
1
)
?
(
x
>>
4
)
:
(
x
&
0x0f
);
}
static
int
pirq_via_set
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
irq
)
{
u8
x
;
int
reg
=
0x55
+
(
pirq
>>
1
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
x
=
(
pirq
&
1
)
?
((
x
&
0x0f
)
|
(
irq
<<
4
))
:
((
x
&
0xf0
)
|
irq
);
pci_write_config_byte
(
router
,
reg
,
x
);
return
1
;
}
static
int
pirq_opti_get
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
)
{
u8
x
;
int
reg
=
0xb8
+
(
pirq
>>
5
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
return
(
pirq
&
0x10
)
?
(
x
>>
4
)
:
(
x
&
0x0f
);
}
static
int
pirq_opti_set
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
irq
)
{
u8
x
;
int
reg
=
0xb8
+
(
pirq
>>
5
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
x
=
(
pirq
&
0x10
)
?
((
x
&
0x0f
)
|
(
irq
<<
4
))
:
((
x
&
0xf0
)
|
irq
);
pci_write_config_byte
(
router
,
reg
,
x
);
return
1
;
}
#ifdef CONFIG_PCI_BIOS
static
int
pirq_bios_set
(
struct
pci_dev
*
router
,
struct
pci_dev
*
dev
,
int
pirq
,
int
irq
)
{
struct
pci_dev
*
bridge
;
int
pin
=
pci_get_interrupt_pin
(
dev
,
&
bridge
);
return
pcibios_set_irq_routing
(
bridge
,
pin
,
irq
);
}
static
struct
irq_router
pirq_bios_router
=
{
"BIOS"
,
0
,
0
,
NULL
,
pirq_bios_set
};
#endif
static
struct
irq_router
pirq_routers
[]
=
{
{
"PIIX"
,
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371FB_0
,
pirq_piix_get
,
pirq_piix_set
},
{
"PIIX"
,
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371SB_0
,
pirq_piix_get
,
pirq_piix_set
},
{
"PIIX"
,
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371AB_0
,
pirq_piix_get
,
pirq_piix_set
},
{
"ALI"
,
PCI_VENDOR_ID_AL
,
PCI_DEVICE_ID_AL_M1533
,
NULL
,
pirq_ali_set
},
{
"VIA"
,
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_82C586_0
,
pirq_via_get
,
pirq_via_set
},
{
"VIA"
,
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_82C596
,
pirq_via_get
,
pirq_via_set
},
{
"VIA"
,
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_82C686
,
pirq_via_get
,
pirq_via_set
},
{
"OPTI"
,
PCI_VENDOR_ID_OPTI
,
PCI_DEVICE_ID_OPTI_82C700
,
pirq_opti_get
,
pirq_opti_set
},
{
"default"
,
0
,
0
,
NULL
,
NULL
}
};
static
struct
irq_router
*
pirq_router
;
static
struct
pci_dev
*
pirq_router_dev
;
static
void
__init
pirq_find_router
(
void
)
{
struct
irq_routing_table
*
rt
=
pirq_table
;
u16
rvendor
,
rdevice
;
struct
irq_router
*
r
;
#ifdef CONFIG_PCI_BIOS
if
(
!
rt
->
signature
)
{
printk
(
"PCI: Using BIOS for IRQ routing
\n
"
);
pirq_router
=
&
pirq_bios_router
;
return
;
}
#endif
if
(
!
(
pirq_router_dev
=
pci_find_slot
(
rt
->
rtr_bus
,
rt
->
rtr_devfn
)))
{
DBG
(
"PCI: Interrupt router not found
\n
"
);
return
;
}
if
(
rt
->
rtr_vendor
)
{
rvendor
=
rt
->
rtr_vendor
;
rdevice
=
rt
->
rtr_device
;
}
else
{
/*
* Several BIOSes forget to set the router type. In such cases, we
* use chip vendor/device. This doesn't guarantee us semantics of
* PIRQ values, but was found to work in practice and it's still
* better than not trying.
*/
DBG
(
"PCI: Guessed interrupt router ID from %s
\n
"
,
pirq_router_dev
->
slot_name
);
rvendor
=
pirq_router_dev
->
vendor
;
rdevice
=
pirq_router_dev
->
device
;
}
for
(
r
=
pirq_routers
;
r
->
vendor
;
r
++
)
if
(
r
->
vendor
==
rvendor
&&
r
->
device
==
rdevice
)
break
;
pirq_router
=
r
;
printk
(
"PCI: Using IRQ router %s [%04x/%04x] at %s
\n
"
,
r
->
name
,
rvendor
,
rdevice
,
pirq_router_dev
->
slot_name
);
}
static
struct
irq_info
*
pirq_get_info
(
struct
pci_dev
*
dev
,
int
pin
)
{
struct
irq_routing_table
*
rt
=
pirq_table
;
int
entries
=
(
rt
->
size
-
sizeof
(
struct
irq_routing_table
))
/
sizeof
(
struct
irq_info
);
struct
irq_info
*
info
;
for
(
info
=
rt
->
slots
;
entries
--
;
info
++
)
if
(
info
->
bus
==
dev
->
bus
->
number
&&
PCI_SLOT
(
info
->
devfn
)
==
PCI_SLOT
(
dev
->
devfn
))
return
info
;
return
NULL
;
}
int
pcibios_lookup_irq
(
struct
pci_dev
*
dev
,
int
assign
)
{
struct
irq_info
*
info
;
int
i
,
pirq
,
pin
,
newirq
;
int
irq
=
0
;
u32
mask
;
struct
irq_router
*
r
=
pirq_router
;
struct
pci_dev
*
dev2
,
*
d
;
char
*
msg
=
NULL
;
if
(
!
pirq_table
)
return
0
;
/* Find IRQ routing entry */
pin
=
pci_get_interrupt_pin
(
dev
,
&
d
);
if
(
pin
<
0
)
{
DBG
(
" -> no interrupt pin
\n
"
);
return
0
;
}
DBG
(
"IRQ for %s(%d) via %s"
,
dev
->
slot_name
,
pin
,
d
->
slot_name
);
info
=
pirq_get_info
(
d
,
pin
);
if
(
!
info
)
{
DBG
(
" -> not found in routing table
\n
"
);
return
0
;
}
pirq
=
info
->
irq
[
pin
].
link
;
mask
=
info
->
irq
[
pin
].
bitmap
;
if
(
!
pirq
)
{
DBG
(
" -> not routed
\n
"
);
return
0
;
}
DBG
(
" -> PIRQ %02x, mask %04x, excl %04x"
,
pirq
,
mask
,
pirq_table
->
exclusive_irqs
);
if
(
pcibios_irq_mask
!=
~
0
)
mask
&=
pcibios_irq_mask
;
else
mask
&=
pirq_table
->
exclusive_irqs
;
/* Find the best IRQ to assign */
newirq
=
0
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
!
(
mask
&
(
1
<<
i
)))
continue
;
if
(
pirq_penalty
[
i
]
<
pirq_penalty
[
newirq
])
newirq
=
i
;
}
DBG
(
" -> newirq=%d"
,
newirq
);
/* Try to get current IRQ */
if
(
r
->
get
&&
(
irq
=
r
->
get
(
pirq_router_dev
,
d
,
pirq
)))
{
DBG
(
" -> got IRQ %d
\n
"
,
irq
);
msg
=
"Found"
;
}
else
if
(
assign
&&
newirq
&&
r
->
set
&&
(
dev
->
class
>>
8
)
!=
PCI_CLASS_DISPLAY_VGA
)
{
DBG
(
" -> assigning IRQ %d"
,
newirq
);
if
(
r
->
set
(
pirq_router_dev
,
d
,
pirq
,
newirq
))
{
DBG
(
" ... OK
\n
"
);
msg
=
"Assigned"
;
irq
=
newirq
;
}
}
if
(
!
irq
)
{
DBG
(
" ... failed
\n
"
);
if
(
newirq
&&
mask
==
(
1
<<
newirq
))
{
msg
=
"Guessed"
;
irq
=
newirq
;
}
else
return
0
;
}
printk
(
"PCI: %s IRQ %d for device %s
\n
"
,
msg
,
irq
,
dev
->
slot_name
);
/* Update IRQ for all devices with the same pirq value */
pci_for_each_dev
(
dev2
)
{
if
((
pin
=
pci_get_interrupt_pin
(
dev2
,
&
d
))
>=
0
&&
(
info
=
pirq_get_info
(
d
,
pin
))
&&
info
->
irq
[
pin
].
link
==
pirq
)
{
dev2
->
irq
=
irq
;
pirq_penalty
[
irq
]
++
;
if
(
dev
!=
dev2
)
printk
(
"PCI: The same IRQ used for device %s
\n
"
,
dev2
->
slot_name
);
}
}
return
1
;
}
void
__init
pcibios_fixup_irqs
(
void
)
{
struct
pci_dev
*
dev
;
u8
pin
;
DBG
(
"PCI: IRQ fixup
\n
"
);
pirq_table
=
pirq_find_routing_table
();
#ifdef CONFIG_PCI_BIOS
if
(
!
pirq_table
&&
(
pci_probe
&
PCI_BIOS_IRQ_SCAN
))
pirq_table
=
pcibios_get_irq_routing_table
();
#endif
if
(
pirq_table
)
{
pirq_peer_trick
();
pirq_find_router
();
}
pci_for_each_dev
(
dev
)
{
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
*/
if
(
dev
->
irq
>=
16
)
{
DBG
(
"%s: ignoring bogus IRQ %d
\n
"
,
dev
->
slot_name
,
dev
->
irq
);
dev
->
irq
=
0
;
}
pirq_penalty
[
dev
->
irq
]
++
;
}
pci_for_each_dev
(
dev
)
{
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
#if defined(CONFIG_X86_IO_APIC)
/*
* Recalculate IRQ numbers if we use the I/O APIC.
*/
if
(
!
skip_ioapic_setup
)
{
int
irq
;
if
(
pin
)
{
pin
--
;
/* interrupt pins are numbered starting from 1 */
irq
=
IO_APIC_get_PCI_irq_vector
(
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
pin
);
/*
* Will be removed completely if things work out well with fuzzy parsing
*/
#if 0
if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
struct pci_dev * bridge = dev->bus->self;
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n",
bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
}
#endif
if
(
irq
>=
0
)
{
printk
(
"PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d
\n
"
,
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
pin
,
irq
);
dev
->
irq
=
irq
;
}
}
pirq_table
=
NULL
;
/* Avoid automatic IRQ assignment */
}
#endif
/*
* Still no IRQ? Try to lookup one...
*/
if
(
pin
&&
!
dev
->
irq
)
pcibios_lookup_irq
(
dev
,
0
);
}
}
arch/i386/kernel/pci-pc.c
View file @
b66fa17c
...
...
@@ -10,9 +10,6 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/segment.h>
#include <asm/io.h>
...
...
@@ -22,35 +19,9 @@
unsigned
int
pci_probe
=
PCI_PROBE_BIOS
|
PCI_PROBE_CONF1
|
PCI_PROBE_CONF2
;
static
struct
pci_bus
*
pci_root_bus
;
static
struct
pci_ops
*
pci_root_ops
;
/*
* IRQ routing table provided by the BIOS
*/
struct
irq_info
{
u8
bus
,
devfn
;
/* Bus, device and function */
struct
{
u8
link
;
/* IRQ line ID, chipset dependent, 0=not routed */
u16
bitmap
;
/* Available IRQs */
}
__attribute__
((
packed
))
irq
[
4
];
u8
slot
;
/* Slot number, 0=onboard */
u8
rfu
;
}
__attribute__
((
packed
));
struct
irq_routing_table
{
u32
signature
;
/* PIRQ_SIGNATURE should be here */
u16
version
;
/* PIRQ_VERSION */
u16
size
;
/* Table size in bytes */
u8
rtr_bus
,
rtr_devfn
;
/* Where the interrupt router lies */
u16
exclusive_irqs
;
/* IRQs devoted exclusively to PCI usage */
u16
rtr_vendor
,
rtr_device
;
/* Vendor and device ID of interrupt router */
u32
miniport_data
;
/* Crap */
u8
rfu
[
11
];
u8
checksum
;
/* Modulo 256 checksum must give zero */
struct
irq_info
slots
[
0
];
}
__attribute__
((
packed
));
int
pcibios_last_bus
=
-
1
;
struct
pci_bus
*
pci_root_bus
;
struct
pci_ops
*
pci_root_ops
;
/*
* Direct access to PCI hardware...
...
...
@@ -378,7 +349,7 @@ static int pci_bios_present;
static
int
__init
check_pcibios
(
void
)
{
u32
signature
,
eax
,
ebx
,
ecx
;
u8
status
,
major_ver
,
minor_ver
,
hw_mech
,
last_bus
;
u8
status
,
major_ver
,
minor_ver
,
hw_mech
;
unsigned
long
flags
,
pcibios_entry
;
if
((
pcibios_entry
=
bios32_service
(
PCI_SERVICE
)))
{
...
...
@@ -403,16 +374,17 @@ static int __init check_pcibios(void)
hw_mech
=
eax
&
0xff
;
major_ver
=
(
ebx
>>
8
)
&
0xff
;
minor_ver
=
ebx
&
0xff
;
last_bus
=
ecx
&
0xff
;
if
(
pcibios_last_bus
<
0
)
pcibios_last_bus
=
ecx
&
0xff
;
DBG
(
"PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x
\n
"
,
status
,
hw_mech
,
major_ver
,
minor_ver
,
last_bus
);
status
,
hw_mech
,
major_ver
,
minor_ver
,
pcibios_
last_bus
);
if
(
status
||
signature
!=
PCI_SIGNATURE
)
{
printk
(
KERN_ERR
"PCI: BIOS BUG #%x[%08x] found, report to <mj@suse.cz>
\n
"
,
status
,
signature
);
return
0
;
}
printk
(
"PCI: PCI BIOS revision %x.%02x entry at 0x%lx
\n
"
,
major_ver
,
minor_ver
,
pcibios_entry
);
printk
(
"PCI: PCI BIOS revision %x.%02x entry at 0x%lx
, last bus=%d
\n
"
,
major_ver
,
minor_ver
,
pcibios_entry
,
pcibios_last_bus
);
#ifdef CONFIG_PCI_DIRECT
if
(
!
(
hw_mech
&
PCIBIOS_HW_TYPE1
))
pci_probe
&=
~
PCI_PROBE_CONF1
;
...
...
@@ -670,7 +642,7 @@ static void __init pcibios_sort(void)
}
/*
*
Ask BIOS for IRQ Routing Table
*
BIOS Functions for IRQ Routing
*/
struct
irq_routing_options
{
...
...
@@ -679,28 +651,20 @@ struct irq_routing_options {
u16
segment
;
}
__attribute__
((
packed
));
static
unsigned
long
pcibios_irq_page
__initdata
=
0
;
static
inline
void
__init
pcibios_free_irq_routing_table
(
void
)
{
if
(
pcibios_irq_page
)
free_page
(
pcibios_irq_page
);
}
static
struct
irq_routing_table
*
__init
pcibios_get_irq_routing_table
(
void
)
struct
irq_routing_table
*
__init
pcibios_get_irq_routing_table
(
void
)
{
struct
irq_routing_options
opt
;
struct
irq_routing_table
*
rt
;
struct
irq_routing_table
*
rt
=
NULL
;
int
ret
,
map
;
unsigned
long
page
;
if
(
!
(
pci_probe
&
PCI_BIOS_IRQ_SCAN
))
if
(
!
pci_bios_present
)
return
NULL
;
page
=
__get_free_page
(
GFP_KERNEL
);
if
(
!
page
)
return
NULL
;
pcibios_irq_page
=
__get_free_page
(
GFP_KERNEL
);
if
(
!
pcibios_irq_page
)
return
0
;
rt
=
(
void
*
)
pcibios_irq_page
;
opt
.
table
=
rt
->
slots
;
opt
.
size
=
PAGE_SIZE
-
sizeof
(
struct
irq_routing_table
);
opt
.
table
=
(
struct
irq_info
*
)
page
;
opt
.
size
=
PAGE_SIZE
;
opt
.
segment
=
__KERNEL_DS
;
DBG
(
"PCI: Fetching IRQ routing table... "
);
...
...
@@ -719,17 +683,39 @@ static struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
"D"
((
long
)
&
opt
),
"S"
(
&
pci_indirect
));
DBG
(
"OK ret=%d, size=%d, map=%x
\n
"
,
ret
,
opt
.
size
,
map
);
if
(
ret
&
0xff00
)
{
if
(
ret
&
0xff00
)
printk
(
KERN_ERR
"PCI: Error %02x when fetching IRQ routing table.
\n
"
,
(
ret
>>
8
)
&
0xff
);
return
0
;
else
if
(
opt
.
size
)
{
rt
=
kmalloc
(
sizeof
(
struct
irq_routing_table
)
+
opt
.
size
,
GFP_KERNEL
);
if
(
rt
)
{
memset
(
rt
,
0
,
sizeof
(
struct
irq_routing_table
));
rt
->
size
=
opt
.
size
+
sizeof
(
struct
irq_routing_table
);
rt
->
exclusive_irqs
=
map
;
memcpy
(
rt
->
slots
,
(
void
*
)
page
,
opt
.
size
);
printk
(
"PCI: Using BIOS Interrupt Routing Table
\n
"
);
}
}
memset
(
rt
,
0
,
sizeof
(
struct
irq_routing_table
));
rt
->
size
=
opt
.
size
+
sizeof
(
struct
irq_routing_table
);
printk
(
"PCI: Using BIOS Interrupt Routing Table
\n
"
);
free_page
(
page
);
return
rt
;
}
int
pcibios_set_irq_routing
(
struct
pci_dev
*
dev
,
int
pin
,
int
irq
)
{
int
ret
;
__asm__
(
"lcall (%%esi); cld
\n\t
"
"jc 1f
\n\t
"
"xor %%ah, %%ah
\n
"
"1:"
:
"=a"
(
ret
)
:
"0"
(
PCIBIOS_SET_PCI_HW_INT
),
"b"
((
dev
->
bus
->
number
<<
8
)
|
dev
->
devfn
),
"c"
((
irq
<<
8
)
|
(
pin
+
10
)),
"S"
(
&
pci_indirect
));
return
!
(
ret
&
0xff00
);
}
#endif
/*
...
...
@@ -786,75 +772,33 @@ static void __init pcibios_fixup_ghosts(struct pci_bus *b)
}
/*
* In case there are peer host bridges, scan bus behind each of them.
* Although several sources claim that the host bridges should have
* header type 1 and be assigned a bus number as for PCI2PCI bridges,
* the reality doesn't pass this test and the bus number is usually
* set by BIOS to the first free value.
* Discover remaining PCI buses in case there are peer host bridges.
* We use the number of last PCI bus provided by the PCI BIOS.
*/
static
void
__init
pcibios_fixup_peer_bridges
(
void
)
{
struct
list_head
*
l
n
;
struct
pci_bus
*
b
=
pci_root_
bus
;
int
n
,
cnt
=-
1
;
struct
pci_ops
*
ops
=
pci_root_bus
->
ops
;
int
n
;
struct
pci_bus
bus
;
struct
pci_dev
dev
;
u16
l
;
#ifdef CONFIG_PCI_DIRECT
/*
* Don't search for peer host bridges if we use config type 2
* since it reads bogus values for non-existent buses and
* chipsets supporting multiple primary buses use conf1 anyway.
*/
if
(
ops
==
&
pci_direct_conf2
)
if
(
pcibios_last_bus
<=
0
||
pcibios_last_bus
>=
0xff
)
return
;
#endif
DBG
(
"PCI: Peer bridge fixup
\n
"
);
for
(
ln
=
b
->
devices
.
next
;
ln
!=
&
b
->
devices
;
ln
=
ln
->
next
)
if
((
pci_dev_b
(
ln
)
->
class
>>
8
)
==
PCI_CLASS_BRIDGE_HOST
)
cnt
++
;
n
=
b
->
subordinate
+
1
;
while
(
n
<=
0xff
)
{
int
found
=
0
;
u16
l
;
struct
pci_bus
bus
;
struct
pci_dev
dev
;
for
(
n
=
0
;
n
<=
pcibios_last_bus
;
n
++
)
{
if
(
pci_bus_exists
(
&
pci_root_buses
,
n
))
continue
;
bus
.
number
=
n
;
bus
.
ops
=
ops
;
bus
.
ops
=
pci_root_
ops
;
dev
.
bus
=
&
bus
;
for
(
dev
.
devfn
=
0
;
dev
.
devfn
<
256
;
dev
.
devfn
+=
8
)
if
(
!
pci_read_config_word
(
&
dev
,
PCI_VENDOR_ID
,
&
l
)
&&
l
!=
0x0000
&&
l
!=
0xffff
)
{
#ifdef CONFIG_PCI_BIOS
if
(
pci_bios_present
)
{
int
err
,
idx
=
0
;
u8
bios_bus
,
bios_dfn
;
u16
d
;
pci_read_config_word
(
&
dev
,
PCI_DEVICE_ID
,
&
d
);
DBG
(
"BIOS test for %02x:%02x (%04x:%04x)
\n
"
,
n
,
dev
.
devfn
,
l
,
d
);
while
(
!
(
err
=
pci_bios_find_device
(
l
,
d
,
idx
,
&
bios_bus
,
&
bios_dfn
))
&&
(
bios_bus
!=
n
||
bios_dfn
!=
dev
.
devfn
))
idx
++
;
if
(
err
)
break
;
}
#endif
DBG
(
"Found device at %02x:%02x
\n
"
,
n
,
dev
.
devfn
);
found
++
;
if
(
!
pci_read_config_word
(
&
dev
,
PCI_CLASS_DEVICE
,
&
l
)
&&
l
==
PCI_CLASS_BRIDGE_HOST
)
cnt
++
;
DBG
(
"Found device at %02x:%02x [%04x]
\n
"
,
n
,
dev
.
devfn
,
l
);
printk
(
"PCI: Discovered peer bus %02x
\n
"
,
n
);
pci_scan_bus
(
n
,
pci_root_ops
,
NULL
);
break
;
}
if
(
cnt
--
<=
0
)
break
;
if
(
found
)
{
printk
(
"PCI: Discovered primary peer bus %02x
\n
"
,
n
);
b
=
pci_scan_bus
(
n
,
ops
,
NULL
);
if
(
b
)
n
=
b
->
subordinate
;
}
n
++
;
}
}
...
...
@@ -881,6 +825,7 @@ static void __init pci_fixup_i450nx(struct pci_dev *d)
if
(
suba
<
subb
)
pci_scan_bus
(
suba
+
1
,
pci_root_ops
,
NULL
);
/* Bus B */
}
pcibios_last_bus
=
-
1
;
}
static
void
__init
pci_fixup_i450gx
(
struct
pci_dev
*
d
)
...
...
@@ -893,6 +838,7 @@ static void __init pci_fixup_i450gx(struct pci_dev *d)
pci_read_config_byte
(
d
,
0x4a
,
&
busno
);
printk
(
"PCI: i440KX/GX host bridge %s: secondary bus %02x
\n
"
,
d
->
slot_name
,
busno
);
pci_scan_bus
(
busno
,
pci_root_ops
,
NULL
);
pcibios_last_bus
=
-
1
;
}
static
void
__init
pci_fixup_rcc
(
struct
pci_dev
*
d
)
...
...
@@ -905,6 +851,7 @@ static void __init pci_fixup_rcc(struct pci_dev *d)
pci_read_config_byte
(
d
,
0x44
,
&
busno
);
printk
(
"PCI: RCC host bridge: secondary bus %02x
\n
"
,
busno
);
pci_scan_bus
(
busno
,
pci_root_ops
,
NULL
);
pcibios_last_bus
=
-
1
;
}
static
void
__init
pci_fixup_compaq
(
struct
pci_dev
*
d
)
...
...
@@ -917,6 +864,7 @@ static void __init pci_fixup_compaq(struct pci_dev *d)
pci_read_config_byte
(
d
,
0xc8
,
&
busno
);
printk
(
"PCI: Compaq host bridge: secondary bus %02x
\n
"
,
busno
);
pci_scan_bus
(
busno
,
pci_root_ops
,
NULL
);
pcibios_last_bus
=
-
1
;
}
static
void
__init
pci_fixup_umc_ide
(
struct
pci_dev
*
d
)
...
...
@@ -976,333 +924,6 @@ struct pci_fixup pcibios_fixups[] = {
{
0
}
};
/*
* Fix up IRQs of all PCI devices.
*/
extern
int
skip_ioapic_setup
;
#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
#define PIRQ_VERSION 0x0100
static
struct
irq_routing_table
*
pirq_table
;
/*
* Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
*/
static
struct
irq_routing_table
*
__init
pcibios_find_irq_routing_table
(
void
)
{
u8
*
addr
;
struct
irq_routing_table
*
rt
;
int
i
;
u8
sum
;
for
(
addr
=
(
u8
*
)
__va
(
0xf0000
);
addr
<
(
u8
*
)
__va
(
0x100000
);
addr
+=
16
)
{
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
;
i
<
rt
->
size
;
i
++
)
sum
+=
addr
[
i
];
if
(
!
sum
)
{
printk
(
"PCI: Interrupt Routing Table found at 0x%p [router type %04x/%04x]
\n
"
,
rt
,
rt
->
rtr_vendor
,
rt
->
rtr_device
);
return
rt
;
}
}
return
NULL
;
}
/*
* If we have a IRQ routing table, use it to search for peer host
* bridges. It's a gross hack, but since there are no other known
* ways how to get a list of buses, we have to go this way.
*/
static
void
__init
pcibios_irq_peer_trick
(
struct
irq_routing_table
*
rt
)
{
u8
busmap
[
256
];
int
i
;
struct
irq_info
*
e
;
memset
(
busmap
,
0
,
sizeof
(
busmap
));
for
(
i
=
0
;
i
<
(
rt
->
size
-
sizeof
(
struct
irq_routing_table
))
/
sizeof
(
struct
irq_info
);
i
++
)
{
e
=
&
rt
->
slots
[
i
];
DBG
(
"b=%02x d=%02x s=%02x
\n
"
,
e
->
bus
,
e
->
devfn
,
e
->
slot
);
busmap
[
e
->
bus
]
=
1
;
}
for
(
i
=
1
;
i
<
256
;
i
++
)
/*
* It might be a secondary bus, but in this case its parent is already
* known (ascending bus order) and therefore pci_scan_bus returns immediately.
*/
if
(
busmap
[
i
]
&&
pci_scan_bus
(
i
,
pci_root_bus
->
ops
,
NULL
))
printk
(
"PCI: Discovered primary peer bus %02x [IRQ]
\n
"
,
i
);
}
static
void
ali_set_level_irq
(
unsigned
irq
)
{
unsigned
char
mask
=
1
<<
(
irq
&
7
);
unsigned
int
port
=
0x4d0
+
(
irq
>>
3
);
unsigned
char
val
=
inb
(
port
);
if
(
val
&
mask
)
{
DBG
(
"PCI irq %d was level
\n
"
,
irq
);
return
;
}
DBG
(
"PCI irq %d was edge, turning into level-triggered
\n
"
,
irq
);
outb
(
val
|
mask
,
port
);
}
static
int
ali_set_irq
(
struct
pci_dev
*
router
,
unsigned
pirq
,
unsigned
irq
)
{
if
(
irq
<
15
)
{
static
unsigned
char
irqmap
[
16
]
=
{
0
,
8
,
0
,
2
,
4
,
5
,
7
,
6
,
0
,
1
,
3
,
9
,
11
,
0
,
13
,
15
};
unsigned
char
val
=
irqmap
[
irq
];
if
(
val
&&
pirq
<
8
)
{
u8
byte
;
unsigned
offset
=
0x48
+
(
pirq
>>
1
);
unsigned
shift
=
(
pirq
&
1
)
<<
2
;
pci_read_config_byte
(
router
,
offset
,
&
byte
);
DBG
(
"ALI: old %04x=%02x
\n
"
,
offset
,
byte
);
byte
&=
~
(
0xf
<<
shift
);
byte
|=
val
<<
shift
;
DBG
(
"ALI: new %04x=%02x
\n
"
,
offset
,
byte
);
pci_write_config_byte
(
router
,
offset
,
byte
);
ali_set_level_irq
(
irq
);
return
irq
;
}
}
return
0
;
}
/*
* In case BIOS forgets to tell us about IRQ, we try to look it up in the routing
* table, but unfortunately we have to know the interrupt router chip.
*/
/*
* Never use: 0, 1, 2 (timer, keyboard, and cascade)
* Avoid using: 13, 14 and 15 (FP error and IDE).
* Penalize: 3, 4, 7, 12 (known ISA uses: serial, parallel and mouse)
*/
static
unsigned
int
pcibios_irq_mask
=
0xfff8
;
static
unsigned
pcibios_irq_penalty
[
16
]
=
{
10000
,
10000
,
10000
,
100
,
100
,
0
,
0
,
100
,
0
,
0
,
0
,
0
,
100
,
1000
,
1000
,
1000
};
static
char
*
pcibios_lookup_irq
(
struct
pci_dev
*
dev
,
struct
irq_routing_table
*
rt
,
int
pin
,
int
assign
)
{
struct
irq_info
*
q
;
struct
pci_dev
*
router
;
int
i
,
pirq
,
newirq
,
reg
;
u32
rtrid
,
mask
;
u8
x
,
y
;
char
*
msg
=
NULL
;
pin
--
;
DBG
(
"IRQ for %s(%d)"
,
dev
->
slot_name
,
pin
);
while
(
dev
->
bus
->
self
)
{
pin
=
(
pin
+
PCI_SLOT
(
dev
->
devfn
))
%
4
;
dev
=
dev
->
bus
->
self
;
DBG
(
" -> %s(%d)"
,
dev
->
slot_name
,
pin
);
}
for
(
q
=
rt
->
slots
,
i
=
rt
->
size
-
sizeof
(
struct
irq_routing_table
);
i
&&
(
q
->
bus
!=
dev
->
bus
->
number
||
PCI_SLOT
(
q
->
devfn
)
!=
PCI_SLOT
(
dev
->
devfn
));
i
-=
sizeof
(
struct
irq_info
),
q
++
)
;
if
(
!
i
)
{
DBG
(
" -> not found in routing table
\n
"
);
return
NULL
;
}
pirq
=
q
->
irq
[
pin
].
link
;
mask
=
q
->
irq
[
pin
].
bitmap
;
if
(
!
pirq
)
{
DBG
(
" -> not routed
\n
"
);
return
NULL
;
}
DBG
(
" -> PIRQ %02x, mask %04x"
,
pirq
,
mask
);
newirq
=
0
;
if
(
assign
&&
(
dev
->
class
>>
8
)
!=
PCI_CLASS_DISPLAY_VGA
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
!
(
mask
&
pcibios_irq_mask
&
(
1
<<
i
)))
continue
;
if
(
pcibios_irq_penalty
[
i
]
<
pcibios_irq_penalty
[
newirq
])
newirq
=
i
;
}
}
if
(
!
(
router
=
pci_find_slot
(
rt
->
rtr_bus
,
rt
->
rtr_devfn
)))
{
DBG
(
" -> router not found
\n
"
);
return
NULL
;
}
#define ID(x,y) ((x << 16) | y)
rtrid
=
ID
(
rt
->
rtr_vendor
,
rt
->
rtr_device
);
if
(
!
rtrid
)
{
/*
* Several BIOSes forget to set the router type. In such cases, we
* use chip vendor/device. This doesn't guarantee us semantics of
* PIRQ values, but was found to work in practice and it's still
* better than not trying.
*/
DBG
(
" [%s]"
,
router
->
slot_name
);
rtrid
=
ID
(
router
->
vendor
,
router
->
device
);
}
switch
(
rtrid
)
{
case
ID
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371FB_0
):
case
ID
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371SB_0
):
case
ID
(
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_82371AB_0
):
/* Intel PIIX: PIRQ holds configuration register address */
pci_read_config_byte
(
router
,
pirq
,
&
x
);
if
(
x
<
16
)
{
DBG
(
" -> [PIIX] %02x
\n
"
,
x
);
newirq
=
x
;
msg
=
"PIIX"
;
}
else
if
(
newirq
)
{
DBG
(
" -> [PIIX] set to %02x
\n
"
,
newirq
);
pci_write_config_byte
(
router
,
pirq
,
newirq
);
msg
=
"PIIX-NEW"
;
}
else
DBG
(
" -> [PIIX] sink
\n
"
);
break
;
case
ID
(
PCI_VENDOR_ID_AL
,
PCI_DEVICE_ID_AL_M1533
):
newirq
=
ali_set_irq
(
router
,
pirq
-
1
,
newirq
);
if
(
newirq
)
msg
=
"ALI"
;
break
;
case
ID
(
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_82C596
):
case
ID
(
PCI_VENDOR_ID_VIA
,
PCI_DEVICE_ID_VIA_82C686
):
reg
=
0x55
+
(
pirq
>>
1
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
y
=
(
pirq
&
1
)
?
(
x
>>
4
)
:
(
x
&
0x0f
);
if
(
y
)
{
DBG
(
" -> [VIA] %02x
\n
"
,
y
);
newirq
=
y
;
msg
=
"VIA"
;
}
else
if
(
newirq
)
{
DBG
(
" -> [VIA] set to %02x
\n
"
,
newirq
);
x
=
(
pirq
&
1
)
?
((
x
&
0x0f
)
|
(
newirq
<<
4
))
:
((
x
&
0xf0
)
|
newirq
);
pci_write_config_byte
(
router
,
reg
,
x
);
msg
=
"VIA-NEW"
;
}
else
DBG
(
" -> [VIA] sink
\n
"
);
break
;
case
ID
(
PCI_VENDOR_ID_OPTI
,
PCI_DEVICE_ID_OPTI_82C700
):
reg
=
0xb8
+
(
pirq
>>
5
);
pci_read_config_byte
(
router
,
reg
,
&
x
);
y
=
(
pirq
&
0x10
)
?
(
x
>>
4
)
:
(
x
&
0x0f
);
if
(
y
)
{
DBG
(
" -> [OPTI] %02x
\n
"
,
y
);
newirq
=
y
;
msg
=
"OPTI"
;
}
else
if
(
newirq
)
{
DBG
(
" -> [OPTI] set to %02x
\n
"
,
newirq
);
x
=
(
pirq
&
0x10
)
?
((
x
&
0x0f
)
|
(
newirq
<<
4
))
:
((
x
&
0xf0
)
|
newirq
);
pci_write_config_byte
(
router
,
reg
,
y
);
msg
=
"OPTI-NEW"
;
}
else
DBG
(
" -> [OPTI] sink
\n
"
);
break
;
default:
DBG
(
" -> unknown router %04x/%04x
\n
"
,
rt
->
rtr_vendor
,
rt
->
rtr_device
);
if
(
newirq
&&
mask
==
(
1
<<
newirq
))
{
/* Only one IRQ available -> use it */
msg
=
"guess"
;
}
}
#undef ID
if
(
msg
)
{
dev
->
irq
=
newirq
;
pcibios_irq_penalty
[
newirq
]
++
;
}
return
msg
;
}
static
void
__init
pcibios_fixup_irqs
(
void
)
{
struct
irq_routing_table
*
rtable
;
struct
pci_dev
*
dev
;
u8
pin
;
DBG
(
"PCI: IRQ fixup
\n
"
);
rtable
=
pirq_table
=
pcibios_find_irq_routing_table
();
#ifdef CONFIG_PCI_BIOS
if
(
!
rtable
&&
pci_bios_present
)
rtable
=
pcibios_get_irq_routing_table
();
#endif
if
(
rtable
)
pcibios_irq_peer_trick
(
rtable
);
pci_for_each_dev
(
dev
)
{
/*
* If the BIOS has set an out of range IRQ number, just ignore it.
* Also keep track of which IRQ's are already in use.
*/
if
(
dev
->
irq
>=
16
)
{
DBG
(
"%s: ignoring bogus IRQ %d
\n
"
,
dev
->
slot_name
,
dev
->
irq
);
dev
->
irq
=
0
;
}
pcibios_irq_penalty
[
dev
->
irq
]
++
;
}
pci_for_each_dev
(
dev
)
{
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
#if defined(CONFIG_X86_IO_APIC)
/*
* Recalculate IRQ numbers if we use the I/O APIC.
*/
if
(
!
skip_ioapic_setup
)
{
int
irq
;
if
(
pin
)
{
pin
--
;
/* interrupt pins are numbered starting from 1 */
irq
=
IO_APIC_get_PCI_irq_vector
(
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
pin
);
/*
* Will be removed completely if things work out well with fuzzy parsing
*/
#if 0
if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
struct pci_dev * bridge = dev->bus->self;
pin = (pin + PCI_SLOT(dev->devfn)) % 4;
irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
PCI_SLOT(bridge->devfn), pin);
if (irq >= 0)
printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n",
bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
}
#endif
if
(
irq
>=
0
)
{
printk
(
"PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d
\n
"
,
dev
->
bus
->
number
,
PCI_SLOT
(
dev
->
devfn
),
pin
,
irq
);
dev
->
irq
=
irq
;
}
}
pirq_table
=
NULL
;
/* Avoid automatic IRQ assignment */
}
#endif
/*
* Still no IRQ? Try to assign one...
*/
if
(
pin
&&
!
dev
->
irq
&&
pirq_table
)
{
char
*
msg
=
pcibios_lookup_irq
(
dev
,
pirq_table
,
pin
,
0
);
if
(
msg
)
printk
(
"PCI: Found IRQ %d for device %s [%s]
\n
"
,
dev
->
irq
,
dev
->
slot_name
,
msg
);
}
}
#ifdef CONFIG_PCI_BIOS
pcibios_free_irq_routing_table
();
#endif
}
/*
* Called after each bus is probed, but before its children
* are examined.
...
...
@@ -1349,8 +970,7 @@ void __init pcibios_init(void)
pci_root_bus
=
pci_scan_bus
(
0
,
pci_root_ops
,
NULL
);
pcibios_fixup_irqs
();
if
(
pci_probe
&
PCI_PEER_FIXUP
)
pcibios_fixup_peer_bridges
();
pcibios_fixup_peer_bridges
();
pcibios_resource_survey
();
#ifdef CONFIG_PCI_BIOS
...
...
@@ -1390,15 +1010,15 @@ char * __init pcibios_setup(char *str)
return
NULL
;
}
#endif
else
if
(
!
strcmp
(
str
,
"peer"
))
{
pci_probe
|=
PCI_PEER_FIXUP
;
return
NULL
;
}
else
if
(
!
strcmp
(
str
,
"rom"
))
{
else
if
(
!
strcmp
(
str
,
"rom"
))
{
pci_probe
|=
PCI_ASSIGN_ROMS
;
return
NULL
;
}
else
if
(
!
strncmp
(
str
,
"irqmask="
,
8
))
{
pcibios_irq_mask
=
simple_strtol
(
str
+
8
,
NULL
,
0
);
return
NULL
;
}
else
if
(
!
strncmp
(
str
,
"lastbus="
,
8
))
{
pcibios_last_bus
=
simple_strtol
(
str
+
8
,
NULL
,
0
);
return
NULL
;
}
return
str
;
}
...
...
@@ -1412,15 +1032,10 @@ int pcibios_enable_device(struct pci_dev *dev)
if
(
!
dev
->
irq
)
{
u8
pin
;
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
pin
)
{
char
*
msg
;
if
(
pirq_table
&&
((
msg
=
pcibios_lookup_irq
(
dev
,
pirq_table
,
pin
,
1
))))
printk
(
"PCI: Assigned IRQ %d to device %s [%s]
\n
"
,
dev
->
irq
,
dev
->
slot_name
,
msg
);
else
printk
(
KERN_WARNING
"PCI: No IRQ known for interrupt pin %c of device %s.%s
\n
"
,
'A'
+
pin
-
1
,
dev
->
slot_name
,
(
pci_probe
&
PCI_BIOS_IRQ_SCAN
)
?
""
:
" Please try using pci=biosirq."
);
}
if
(
pin
&&
!
pcibios_lookup_irq
(
dev
,
1
))
printk
(
KERN_WARNING
"PCI: No IRQ known for interrupt pin %c of device %s.%s
\n
"
,
'A'
+
pin
-
1
,
dev
->
slot_name
,
(
pci_probe
&
PCI_BIOS_IRQ_SCAN
)
?
""
:
" Please try using pci=biosirq."
);
}
return
0
;
}
drivers/net/Space.c
View file @
b66fa17c
...
...
@@ -186,7 +186,7 @@ struct devprobe eisa_probes[] __initdata = {
{
ne3210_probe
,
0
},
#endif
#ifdef CONFIG_DEFXX
{
dfx_probe
,
0
}
.
{
dfx_probe
,
0
}
,
#endif
{
NULL
,
0
},
};
...
...
drivers/pci/pci.c
View file @
b66fa17c
...
...
@@ -254,6 +254,23 @@ pci_enable_device(struct pci_dev *dev)
return
0
;
}
int
pci_get_interrupt_pin
(
struct
pci_dev
*
dev
,
struct
pci_dev
**
bridge
)
{
u8
pin
;
pci_read_config_byte
(
dev
,
PCI_INTERRUPT_PIN
,
&
pin
);
if
(
!
pin
)
return
-
1
;
pin
--
;
while
(
dev
->
bus
->
self
)
{
pin
=
(
pin
+
PCI_SLOT
(
dev
->
devfn
))
%
4
;
dev
=
dev
->
bus
->
self
;
}
*
bridge
=
dev
;
return
pin
;
}
/*
* Registration of PCI drivers and handling of hot-pluggable devices.
*/
...
...
@@ -961,7 +978,7 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
return
max
;
}
static
int
__init
pci_bus_exists
(
const
struct
list_head
*
list
,
int
nr
)
int
__init
pci_bus_exists
(
const
struct
list_head
*
list
,
int
nr
)
{
const
struct
list_head
*
l
;
...
...
drivers/usb/usb.c
View file @
b66fa17c
...
...
@@ -1720,11 +1720,15 @@ int usb_new_device(struct usb_device *dev)
info
(
"USB new device connect, assigned device number %d"
,
dev
->
devnum
);
dev
->
maxpacketsize
=
0
;
/* Default to 8 byte max packet size */
/* USB v1.1 5.5.3 */
/* We read the first 8 bytes from the device descriptor to get to */
/* the bMaxPacketSize0 field. Then we set the maximum packet size */
/* for the control pipe, and retrieve the rest */
dev
->
epmaxpacketin
[
0
]
=
8
;
dev
->
epmaxpacketout
[
0
]
=
8
;
/* We still haven't set the Address yet */
/* Even though we have assigned an address for the device, we */
/* haven't told it what it's address is yet */
addr
=
dev
->
devnum
;
dev
->
devnum
=
0
;
...
...
@@ -1740,12 +1744,6 @@ int usb_new_device(struct usb_device *dev)
}
dev
->
epmaxpacketin
[
0
]
=
dev
->
descriptor
.
bMaxPacketSize0
;
dev
->
epmaxpacketout
[
0
]
=
dev
->
descriptor
.
bMaxPacketSize0
;
switch
(
dev
->
descriptor
.
bMaxPacketSize0
)
{
case
8
:
dev
->
maxpacketsize
=
0
;
break
;
case
16
:
dev
->
maxpacketsize
=
1
;
break
;
case
32
:
dev
->
maxpacketsize
=
2
;
break
;
case
64
:
dev
->
maxpacketsize
=
3
;
break
;
}
dev
->
devnum
=
addr
;
...
...
fs/namei.c
View file @
b66fa17c
...
...
@@ -522,7 +522,7 @@ static inline int
walk_init_root
(
const
char
*
name
,
unsigned
flags
,
struct
nameidata
*
nd
)
{
if
(
current
->
personality
!=
PER_LINUX
)
if
(
__emul_lookup_dentry
(
name
,
flags
,
nd
))
;
if
(
__emul_lookup_dentry
(
name
,
flags
,
nd
))
return
0
;
nd
->
mnt
=
mntget
(
current
->
fs
->
rootmnt
);
nd
->
dentry
=
dget
(
current
->
fs
->
root
);
...
...
fs/nfs/inode.c
View file @
b66fa17c
...
...
@@ -198,7 +198,7 @@ nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
static
inline
unsigned
long
nfs_calc_block_size
(
u64
tsize
)
{
loff_t
used
=
(
tsize
+
511
)
/
512
;
loff_t
used
=
(
tsize
+
511
)
>>
9
;
return
(
used
>
ULONG_MAX
)
?
ULONG_MAX
:
used
;
}
...
...
include/linux/pci.h
View file @
b66fa17c
...
...
@@ -465,6 +465,7 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
/* Generic PCI functions used internally */
void
pci_init
(
void
);
int
pci_bus_exists
(
const
struct
list_head
*
list
,
int
nr
);
struct
pci_bus
*
pci_scan_bus
(
int
bus
,
struct
pci_ops
*
ops
,
void
*
sysdata
);
struct
pci_bus
*
pci_alloc_primary_bus
(
int
bus
);
struct
pci_dev
*
pci_scan_slot
(
struct
pci_dev
*
temp
);
...
...
@@ -474,7 +475,8 @@ void pci_name_device(struct pci_dev *dev);
char
*
pci_class_name
(
u32
class
);
void
pci_read_bridge_bases
(
struct
pci_bus
*
child
);
struct
resource
*
pci_find_parent_resource
(
const
struct
pci_dev
*
dev
,
struct
resource
*
res
);
int
pci_setup_device
(
struct
pci_dev
*
dev
);
int
pci_setup_device
(
struct
pci_dev
*
dev
);
int
pci_get_interrupt_pin
(
struct
pci_dev
*
dev
,
struct
pci_dev
**
bridge
);
/* Generic PCI functions exported to card drivers */
...
...
include/linux/usb.h
View file @
b66fa17c
...
...
@@ -539,7 +539,6 @@ struct usb_device {
atomic_t
refcnt
;
/* Reference count */
int
maxpacketsize
;
/* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */
unsigned
int
toggle
[
2
];
/* one bit for each endpoint ([0] = IN, [1] = OUT) */
unsigned
int
halted
[
2
];
/* endpoint halts; one bit per endpoint # & direction; */
/* [0] = IN, [1] = OUT */
...
...
@@ -686,7 +685,7 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
static
inline
unsigned
int
__create_pipe
(
struct
usb_device
*
dev
,
unsigned
int
endpoint
)
{
return
(
dev
->
devnum
<<
8
)
|
(
endpoint
<<
15
)
|
(
dev
->
slow
<<
26
)
|
dev
->
maxpacketsize
;
return
(
dev
->
devnum
<<
8
)
|
(
endpoint
<<
15
)
|
(
dev
->
slow
<<
26
);
}
static
inline
unsigned
int
__default_pipe
(
struct
usb_device
*
dev
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment