bcma: fix handling of big addrl
The return value of bcma_erom_get_addr_desc() is a unsigned value and it could wrap around in the two complement writing. This happens for one core in the BCM4708 SoC. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
1cabf7dba5
commit
fd4edf1975
@@ -213,7 +213,7 @@ static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr)
|
|||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
|
static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
|
||||||
u32 type, u8 port)
|
u32 type, u8 port)
|
||||||
{
|
{
|
||||||
u32 addrl, addrh, sizel, sizeh = 0;
|
u32 addrl, addrh, sizel, sizeh = 0;
|
||||||
@@ -225,7 +225,7 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
|
|||||||
((ent & SCAN_ADDR_TYPE) != type) ||
|
((ent & SCAN_ADDR_TYPE) != type) ||
|
||||||
(((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
|
(((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
|
||||||
bcma_erom_push_ent(eromptr);
|
bcma_erom_push_ent(eromptr);
|
||||||
return -EINVAL;
|
return (u32)-EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addrl = ent & SCAN_ADDR_ADDR;
|
addrl = ent & SCAN_ADDR_ADDR;
|
||||||
@@ -273,7 +273,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
|||||||
struct bcma_device_id *match, int core_num,
|
struct bcma_device_id *match, int core_num,
|
||||||
struct bcma_device *core)
|
struct bcma_device *core)
|
||||||
{
|
{
|
||||||
s32 tmp;
|
u32 tmp;
|
||||||
u8 i, j;
|
u8 i, j;
|
||||||
s32 cia, cib;
|
s32 cia, cib;
|
||||||
u8 ports[2], wrappers[2];
|
u8 ports[2], wrappers[2];
|
||||||
@@ -351,11 +351,11 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
|||||||
* the main register space for the core
|
* the main register space for the core
|
||||||
*/
|
*/
|
||||||
tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
|
tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
|
||||||
if (tmp <= 0) {
|
if (tmp == 0 || IS_ERR_VALUE(tmp)) {
|
||||||
/* Try again to see if it is a bridge */
|
/* Try again to see if it is a bridge */
|
||||||
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
SCAN_ADDR_TYPE_BRIDGE, 0);
|
SCAN_ADDR_TYPE_BRIDGE, 0);
|
||||||
if (tmp <= 0) {
|
if (tmp == 0 || IS_ERR_VALUE(tmp)) {
|
||||||
return -EILSEQ;
|
return -EILSEQ;
|
||||||
} else {
|
} else {
|
||||||
bcma_info(bus, "Bridge found\n");
|
bcma_info(bus, "Bridge found\n");
|
||||||
@@ -369,7 +369,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
|||||||
for (j = 0; ; j++) {
|
for (j = 0; ; j++) {
|
||||||
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
SCAN_ADDR_TYPE_SLAVE, i);
|
SCAN_ADDR_TYPE_SLAVE, i);
|
||||||
if (tmp < 0) {
|
if (IS_ERR_VALUE(tmp)) {
|
||||||
/* no more entries for port _i_ */
|
/* no more entries for port _i_ */
|
||||||
/* pr_debug("erom: slave port %d "
|
/* pr_debug("erom: slave port %d "
|
||||||
* "has %d descriptors\n", i, j); */
|
* "has %d descriptors\n", i, j); */
|
||||||
@@ -386,7 +386,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
|||||||
for (j = 0; ; j++) {
|
for (j = 0; ; j++) {
|
||||||
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
SCAN_ADDR_TYPE_MWRAP, i);
|
SCAN_ADDR_TYPE_MWRAP, i);
|
||||||
if (tmp < 0) {
|
if (IS_ERR_VALUE(tmp)) {
|
||||||
/* no more entries for port _i_ */
|
/* no more entries for port _i_ */
|
||||||
/* pr_debug("erom: master wrapper %d "
|
/* pr_debug("erom: master wrapper %d "
|
||||||
* "has %d descriptors\n", i, j); */
|
* "has %d descriptors\n", i, j); */
|
||||||
@@ -404,7 +404,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
|||||||
for (j = 0; ; j++) {
|
for (j = 0; ; j++) {
|
||||||
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
SCAN_ADDR_TYPE_SWRAP, i + hack);
|
SCAN_ADDR_TYPE_SWRAP, i + hack);
|
||||||
if (tmp < 0) {
|
if (IS_ERR_VALUE(tmp)) {
|
||||||
/* no more entries for port _i_ */
|
/* no more entries for port _i_ */
|
||||||
/* pr_debug("erom: master wrapper %d "
|
/* pr_debug("erom: master wrapper %d "
|
||||||
* has %d descriptors\n", i, j); */
|
* has %d descriptors\n", i, j); */
|
||||||
|
Reference in New Issue
Block a user