Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
9e0c7afd
Commit
9e0c7afd
authored
Jun 17, 2006
by
Ralf Baechle
Browse files
[MIPS] IP27: Extract pci_ops into separate file.
Signed-off-by:
Ralf Baechle
<
ralf@linux-mips.org
>
parent
3a115456
Changes
3
Hide whitespace changes
Inline
Side-by-side
arch/mips/pci/Makefile
View file @
9e0c7afd
...
...
@@ -43,7 +43,7 @@ obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o
obj-$(CONFIG_MOMENCO_OCELOT_G)
+=
fixup-ocelot-g.o pci-ocelot-g.o
obj-$(CONFIG_PMC_YOSEMITE)
+=
fixup-yosemite.o ops-titan.o ops-titan-ht.o
\
pci-yosemite.o
obj-$(CONFIG_SGI_IP27)
+=
pci-ip27.o
obj-$(CONFIG_SGI_IP27)
+=
ops-bridge.o
pci-ip27.o
obj-$(CONFIG_SGI_IP32)
+=
fixup-ip32.o ops-mace.o pci-ip32.o
obj-$(CONFIG_SIBYTE_SB1250)
+=
fixup-sb1250.o pci-sb1250.o
obj-$(CONFIG_SIBYTE_BCM112X)
+=
fixup-sb1250.o pci-sb1250.o
...
...
arch/mips/pci/ops-bridge.c
0 → 100644
View file @
9e0c7afd
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include
<linux/pci.h>
#include
<asm/paccess.h>
#include
<asm/pci/bridge.h>
#include
<asm/sn/arch.h>
#include
<asm/sn/intr.h>
#include
<asm/sn/sn0/hub.h>
/*
* The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
* not really documented, so right now I can't write code which uses it.
* Therefore we use type 0 accesses for now even though they won't work
* correcly for PCI-to-PCI bridges.
*
* The function is complicated by the ultimate brokeness of the IOC3 chip
* which is used in SGI systems. The IOC3 can only handle 32-bit PCI
* accesses and does only decode parts of it's address space.
*/
static
int
pci_conf0_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
;
int
res
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
where
^
(
4
-
size
)];
if
(
size
==
1
)
res
=
get_dbe
(
*
value
,
(
u8
*
)
addr
);
else
if
(
size
==
2
)
res
=
get_dbe
(
*
value
,
(
u16
*
)
addr
);
else
res
=
get_dbe
(
*
value
,
(
u32
*
)
addr
);
return
res
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
{
*
value
=
0
;
return
PCIBIOS_SUCCESSFUL
;
}
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
l
[
where
>>
2
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
*
value
=
(
cf
>>
shift
)
&
mask
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_conf1_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
busno
=
bus
->
number
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
;
int
res
;
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
(
where
^
(
4
-
size
))];
if
(
size
==
1
)
res
=
get_dbe
(
*
value
,
(
u8
*
)
addr
);
else
if
(
size
==
2
)
res
=
get_dbe
(
*
value
,
(
u16
*
)
addr
);
else
res
=
get_dbe
(
*
value
,
(
u32
*
)
addr
);
return
res
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
{
*
value
=
0
;
return
PCIBIOS_SUCCESSFUL
;
}
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
where
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
*
value
=
(
cf
>>
shift
)
&
mask
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
if
(
bus
->
number
>
0
)
return
pci_conf1_read_config
(
bus
,
devfn
,
where
,
size
,
value
);
return
pci_conf0_read_config
(
bus
,
devfn
,
where
,
size
,
value
);
}
static
int
pci_conf0_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
,
smask
;
int
res
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
where
^
(
4
-
size
)];
if
(
size
==
1
)
{
res
=
put_dbe
(
value
,
(
u8
*
)
addr
);
}
else
if
(
size
==
2
)
{
res
=
put_dbe
(
value
,
(
u16
*
)
addr
);
}
else
{
res
=
put_dbe
(
value
,
(
u32
*
)
addr
);
}
if
(
res
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to touch the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
return
PCIBIOS_SUCCESSFUL
;
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
l
[
where
>>
2
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
smask
=
mask
<<
shift
;
cf
=
(
cf
&
~
smask
)
|
((
value
&
mask
)
<<
shift
);
if
(
put_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_conf1_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
int
busno
=
bus
->
number
;
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
,
smask
;
int
res
;
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
(
where
^
(
4
-
size
))];
if
(
size
==
1
)
{
res
=
put_dbe
(
value
,
(
u8
*
)
addr
);
}
else
if
(
size
==
2
)
{
res
=
put_dbe
(
value
,
(
u16
*
)
addr
);
}
else
{
res
=
put_dbe
(
value
,
(
u32
*
)
addr
);
}
if
(
res
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to touch the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
return
PCIBIOS_SUCCESSFUL
;
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
l
[
where
>>
2
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
smask
=
mask
<<
shift
;
cf
=
(
cf
&
~
smask
)
|
((
value
&
mask
)
<<
shift
);
if
(
put_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
if
(
bus
->
number
>
0
)
return
pci_conf1_write_config
(
bus
,
devfn
,
where
,
size
,
value
);
return
pci_conf0_write_config
(
bus
,
devfn
,
where
,
size
,
value
);
}
struct
pci_ops
bridge_pci_ops
=
{
.
read
=
pci_read_config
,
.
write
=
pci_write_config
,
};
arch/mips/pci/pci-ip27.c
View file @
9e0c7afd
...
...
@@ -40,297 +40,7 @@ static struct bridge_controller bridges[MAX_PCI_BUSSES];
struct
bridge_controller
*
irq_to_bridge
[
MAX_PCI_BUSSES
*
MAX_DEVICES_PER_PCIBUS
];
int
irq_to_slot
[
MAX_PCI_BUSSES
*
MAX_DEVICES_PER_PCIBUS
];
/*
* The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
* not really documented, so right now I can't write code which uses it.
* Therefore we use type 0 accesses for now even though they won't work
* correcly for PCI-to-PCI bridges.
*
* The function is complicated by the ultimate brokeness of the IOC3 chip
* which is used in SGI systems. The IOC3 can only handle 32-bit PCI
* accesses and does only decode parts of it's address space.
*/
static
int
pci_conf0_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
;
int
res
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
where
^
(
4
-
size
)];
if
(
size
==
1
)
res
=
get_dbe
(
*
value
,
(
u8
*
)
addr
);
else
if
(
size
==
2
)
res
=
get_dbe
(
*
value
,
(
u16
*
)
addr
);
else
res
=
get_dbe
(
*
value
,
(
u32
*
)
addr
);
return
res
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
{
*
value
=
0
;
return
PCIBIOS_SUCCESSFUL
;
}
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
l
[
where
>>
2
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
*
value
=
(
cf
>>
shift
)
&
mask
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_conf1_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
busno
=
bus
->
number
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
;
int
res
;
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
(
where
^
(
4
-
size
))];
if
(
size
==
1
)
res
=
get_dbe
(
*
value
,
(
u8
*
)
addr
);
else
if
(
size
==
2
)
res
=
get_dbe
(
*
value
,
(
u16
*
)
addr
);
else
res
=
get_dbe
(
*
value
,
(
u32
*
)
addr
);
return
res
?
PCIBIOS_DEVICE_NOT_FOUND
:
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
{
*
value
=
0
;
return
PCIBIOS_SUCCESSFUL
;
}
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
where
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
*
value
=
(
cf
>>
shift
)
&
mask
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_read_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
value
)
{
if
(
bus
->
number
>
0
)
return
pci_conf1_read_config
(
bus
,
devfn
,
where
,
size
,
value
);
return
pci_conf0_read_config
(
bus
,
devfn
,
where
,
size
,
value
);
}
static
int
pci_conf0_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
,
smask
;
int
res
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
c
[
where
^
(
4
-
size
)];
if
(
size
==
1
)
{
res
=
put_dbe
(
value
,
(
u8
*
)
addr
);
}
else
if
(
size
==
2
)
{
res
=
put_dbe
(
value
,
(
u16
*
)
addr
);
}
else
{
res
=
put_dbe
(
value
,
(
u32
*
)
addr
);
}
if
(
res
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to touch the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
return
PCIBIOS_SUCCESSFUL
;
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
l
[
where
>>
2
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
smask
=
mask
<<
shift
;
cf
=
(
cf
&
~
smask
)
|
((
value
&
mask
)
<<
shift
);
if
(
put_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_conf1_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
struct
bridge_controller
*
bc
=
BRIDGE_CONTROLLER
(
bus
);
bridge_t
*
bridge
=
bc
->
base
;
int
slot
=
PCI_SLOT
(
devfn
);
int
fn
=
PCI_FUNC
(
devfn
);
int
busno
=
bus
->
number
;
volatile
void
*
addr
;
u32
cf
,
shift
,
mask
,
smask
;
int
res
;
bridge
->
b_pci_cfg
=
(
busno
<<
16
)
|
(
slot
<<
11
);
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
PCI_VENDOR_ID
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to look at it for real ...
*/
if
(
cf
==
(
PCI_VENDOR_ID_SGI
|
(
PCI_DEVICE_ID_SGI_IOC3
<<
16
)))
goto
oh_my_gawd
;
addr
=
&
bridge
->
b_type1_cfg
.
c
[(
fn
<<
8
)
|
(
where
^
(
4
-
size
))];
if
(
size
==
1
)
{
res
=
put_dbe
(
value
,
(
u8
*
)
addr
);
}
else
if
(
size
==
2
)
{
res
=
put_dbe
(
value
,
(
u16
*
)
addr
);
}
else
{
res
=
put_dbe
(
value
,
(
u32
*
)
addr
);
}
if
(
res
)
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
oh_my_gawd:
/*
* IOC3 is fucked fucked beyond believe ... Don't even give the
* generic PCI code a chance to touch the wrong register.
*/
if
((
where
>=
0x14
&&
where
<
0x40
)
||
(
where
>=
0x48
))
return
PCIBIOS_SUCCESSFUL
;
/*
* IOC3 is fucked fucked beyond believe ... Don't try to access
* anything but 32-bit words ...
*/
addr
=
&
bridge
->
b_type0_cfg_dev
[
slot
].
f
[
fn
].
l
[
where
>>
2
];
if
(
get_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
shift
=
((
where
&
3
)
<<
3
);
mask
=
(
0xffffffffU
>>
((
4
-
size
)
<<
3
));
smask
=
mask
<<
shift
;
cf
=
(
cf
&
~
smask
)
|
((
value
&
mask
)
<<
shift
);
if
(
put_dbe
(
cf
,
(
u32
*
)
addr
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_SUCCESSFUL
;
}
static
int
pci_write_config
(
struct
pci_bus
*
bus
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
value
)
{
if
(
bus
->
number
>
0
)
return
pci_conf1_write_config
(
bus
,
devfn
,
where
,
size
,
value
);
return
pci_conf0_write_config
(
bus
,
devfn
,
where
,
size
,
value
);
}
static
struct
pci_ops
bridge_pci_ops
=
{
.
read
=
pci_read_config
,
.
write
=
pci_write_config
,
};