Browse Source

qcacmn: Free sdio hif device when hif_device_inserted fails

hif_device_inserted may be failed when installing sdio wlan module,
which causes memory leak.

To fix this memory leak, free the hif_sdio_dev and its related DMA
buffers when sdio driver fails in hif_device_inserted.

Change-Id: I6ee53cd2a55fbb1492c66caa260ba8b3681526e6
CRs-Fixed: 2131539
bings 7 years ago
parent
commit
be998d8c2d
1 changed files with 22 additions and 7 deletions
  1. 22 7
      hif/src/sdio/native_sdio/src/hif.c

+ 22 - 7
hif/src/sdio/native_sdio/src/hif.c

@@ -1719,7 +1719,7 @@ static int hif_device_inserted(struct sdio_func *func,
 					AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
 						("%s: CMD52 to set bus width failed: %d\n",
 						 __func__, ret));
-					return ret;
+					goto del_hif_dev;;
 				}
 				device->host->ios.bus_width =
 					MMC_BUS_WIDTH_1;
@@ -1740,7 +1740,7 @@ static int hif_device_inserted(struct sdio_func *func,
 					("%s: CMD52 to bus width failed: %d\n",
 					 __func__,
 						 ret));
-					return ret;
+					goto del_hif_dev;
 				}
 				device->host->ios.bus_width =
 					MMC_BUS_WIDTH_4;
@@ -1761,7 +1761,7 @@ static int hif_device_inserted(struct sdio_func *func,
 					("%s: CMD52 to bus width failed: %d\n",
 							 __func__,
 							 ret));
-					return ret;
+					goto del_hif_dev;
 				}
 				device->host->ios.bus_width =
 					MMC_BUS_WIDTH_8;
@@ -1773,7 +1773,8 @@ static int hif_device_inserted(struct sdio_func *func,
 				("%s: MMC bus width %d is not supported.\n",
 						 __func__,
 						 mmcbuswidth));
-				return ret = QDF_STATUS_E_FAILURE;
+				ret = QDF_STATUS_E_FAILURE;
+				goto del_hif_dev;
 			}
 			AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
 				("%s: Set MMC bus width to %dBit.\n",
@@ -1808,9 +1809,23 @@ static int hif_device_inserted(struct sdio_func *func,
 	sema_init(&device->sem_async, 0);
 
 	ret = hif_enable_func(device, func);
-
-	return (ret == QDF_STATUS_SUCCESS || ret == QDF_STATUS_E_PENDING)
-						? 0 : QDF_STATUS_E_FAILURE;
+	if ((ret == QDF_STATUS_SUCCESS || ret == QDF_STATUS_E_PENDING))
+		return 0;
+	ret = QDF_STATUS_E_FAILURE;
+del_hif_dev:
+	del_hif_device(device);
+	for (i = 0; i < MAX_HIF_DEVICES; ++i) {
+		if (hif_devices[i] == device) {
+			hif_devices[i] = NULL;
+			break;
+		}
+	}
+	if (i == MAX_HIF_DEVICES) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+			("%s: No hif_devices[] slot for %pK",
+			__func__, device));
+	}
+	return ret;
 }
 
 /**