Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd4edf19 authored by Hauke Mehrtens's avatar Hauke Mehrtens Committed by John W. Linville
Browse files

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: default avatarHauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1cabf7db
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 __iomem **eromptr)
	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 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_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
		bcma_erom_push_ent(eromptr);
		return -EINVAL;
		return (u32)-EINVAL;
	}

	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 *core)
{
	s32 tmp;
	u32 tmp;
	u8 i, j;
	s32 cia, cib;
	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
	 */
	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 */
		tmp = bcma_erom_get_addr_desc(bus, eromptr,
					      SCAN_ADDR_TYPE_BRIDGE, 0);
		if (tmp <= 0) {
		if (tmp == 0 || IS_ERR_VALUE(tmp)) {
			return -EILSEQ;
		} else {
			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++) {
			tmp = bcma_erom_get_addr_desc(bus, eromptr,
				SCAN_ADDR_TYPE_SLAVE, i);
			if (tmp < 0) {
			if (IS_ERR_VALUE(tmp)) {
				/* no more entries for port _i_ */
				/* pr_debug("erom: slave port %d "
				 * "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++) {
			tmp = bcma_erom_get_addr_desc(bus, eromptr,
				SCAN_ADDR_TYPE_MWRAP, i);
			if (tmp < 0) {
			if (IS_ERR_VALUE(tmp)) {
				/* no more entries for port _i_ */
				/* pr_debug("erom: master wrapper %d "
				 * "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++) {
			tmp = bcma_erom_get_addr_desc(bus, eromptr,
				SCAN_ADDR_TYPE_SWRAP, i + hack);
			if (tmp < 0) {
			if (IS_ERR_VALUE(tmp)) {
				/* no more entries for port _i_ */
				/* pr_debug("erom: master wrapper %d "
				 * has %d descriptors\n", i, j); */