#define MAX_MEMBLOCK (32 * 1024) /* Block size used for downloading of dongle image */
#define MAX_DATA_BUF (64 * 1024) /* Must be large enough to hold biggest possible glom */
+#define MAX_MEM_BUF 4096
#ifndef DHD_FIRSTREAD
#define DHD_FIRSTREAD 32
#endif /* defined (BT_OVER_SDIO) */
uint txglomframes; /* Number of tx glom frames (superframes) */
uint txglompkts; /* Number of packets from tx glom frames */
+ uint8 *membuf; /* Buffer for receiving big glom packet */
} dhd_bus_t;
dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
else
dsize = size;
+ if (dsize > MAX_MEM_BUF) {
+ DHD_ERROR(("%s: dsize %d > %d\n", __FUNCTION__, dsize, MAX_MEM_BUF));
+ goto xfer_done;
+ }
/* Set the backplane window to include the start address */
if ((bcmerror = dhdsdio_set_siaddr_window(bus, address))) {
DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
__FUNCTION__, (write ? "write" : "read"), dsize, sdaddr,
(address & SBSDIO_SBWINDOW_MASK)));
- if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize))) {
+ if (write)
+ memcpy(bus->membuf, data, dsize);
+ if ((bcmerror = bcmsdh_rwdata(bus->sdh, write, sdaddr, bus->membuf, dsize))) {
DHD_ERROR(("%s: membytes transfer failed\n", __FUNCTION__));
break;
}
+ if (!write)
+ memcpy(data, bus->membuf, dsize);
/* Adjust for next transfer (if any) */
if ((size -= dsize)) {
(uint8 *)&bus->resetinstr, sizeof(bus->resetinstr));
if (bcmerror == BCME_OK) {
-#ifdef CONFIG_VMAP_STACK
- char *tmp;
- tmp = kmalloc(4, GFP_KERNEL);
- if (!tmp)
- goto fail;
-#else
uint32 tmp;
-#endif
+
/* verify write */
-#ifdef CONFIG_VMAP_STACK
- bcmerror = dhdsdio_membytes(bus, FALSE, 0,
- (uint8 *)tmp, 4);
-#else
bcmerror = dhdsdio_membytes(bus, FALSE, 0,
- (uint8 *)&tmp, sizeof(tmp));
-#endif
-#ifdef CONFIG_VMAP_STACK
- if (bcmerror == BCME_OK && *(uint32*)tmp != bus->resetinstr)
-#else
- if (bcmerror == BCME_OK && tmp != bus->resetinstr)
-#endif
- {
- DHD_ERROR(("%s: Filed to write 0x%08x to addr 0\n",
+ (uint8 *)&tmp, sizeof(tmp));
+
+ if (bcmerror == BCME_OK && tmp != bus->resetinstr) {
+ DHD_ERROR(("%s: Failed to write 0x%08x to addr 0\n",
__FUNCTION__, bus->resetinstr));
-#ifdef CONFIG_VMAP_STACK
- DHD_ERROR(("%s: contents of addr 0 is 0x%08x\n",
- __FUNCTION__, *(uint32*)tmp));
-#else
DHD_ERROR(("%s: contents of addr 0 is 0x%08x\n",
- __FUNCTION__, tmp));
-#endif
+ __FUNCTION__, tmp));
bcmerror = BCME_SDIO_ERROR;
-#ifdef CONFIG_VMAP_STACK
- kfree(tmp);
-#endif
goto fail;
}
-#ifdef CONFIG_VMAP_STACK
- kfree(tmp);
-#endif
}
/* now remove reset and halt and continue to run CR4 */
DHD_OS_PREFREE(bus->dhd, bus->rxbuf, bus->rxblen);
goto fail;
}
+ /* Allocate buffer to membuf */
+ bus->membuf = MALLOC(osh, MAX_MEM_BUF);
+ if (bus->membuf == NULL) {
+ DHD_ERROR(("%s: MALLOC of %d-byte membuf failed\n",
+ __FUNCTION__, MAX_MEM_BUF));
+ if (bus->databuf) {
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+ MFREE(osh, bus->databuf, MAX_DATA_BUF);
+#endif
+ bus->databuf = NULL;
+ }
+ /* release rxbuf which was already located as above */
+ if (!bus->rxblen)
+ DHD_OS_PREFREE(bus->dhd, bus->rxbuf, bus->rxblen);
+ goto fail;
+ }
+ memset(bus->membuf, 0, MAX_MEM_BUF);
/* Align the buffer */
if ((uintptr)bus->databuf % DHD_SDALIGN)
bus->databuf = NULL;
}
+ if (bus->membuf) {
+ MFREE(osh, bus->membuf, MAX_DATA_BUF);
+ bus->membuf = NULL;
+ }
+
if (bus->vars && bus->varsz) {
MFREE(osh, bus->vars, bus->varsz);
bus->vars = NULL;