A_STATUS BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) { A_STATUS status = A_ERROR; A_UINT32 lastWord = 0; A_UINT32 lastWordOffset = length & ~0x3; A_UINT32 unalignedBytes = length & 0x3; status = BMILZStreamStart (device, address); if (A_FAILED(status)) { return A_ERROR; } if (unalignedBytes) { /* copy the last word into a zero padded buffer */ A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes); } status = BMILZData(device, buffer, lastWordOffset); if (A_FAILED(status)) { return A_ERROR; } if (unalignedBytes) { status = BMILZData(device, (A_UINT8 *)&lastWord, 4); } if (A_SUCCESS(status)) { // // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // status = BMILZStreamStart (device, 0x00); if (A_FAILED(status)) { return A_ERROR; } } return status; }
A_STATUS download_binary (HIF_DEVICE *hifDevice, A_UINT32 address, wchar_t *fileName, wchar_t *fileRoot, A_BOOL bCompressed, AR6K_BIN_CACHE_INFO *pBinCache) { A_STATUS status = A_OK; A_UCHAR *buffer = NULL; A_UINT32 length = 0; A_UINT32 fileSize = 0; A_UINT32 next_address=0; A_INT32 file_left = 0; size_t nSize; wchar_t filePath[128]; HANDLE fd = NULL; BY_HANDLE_FILE_INFORMATION finfo; A_BOOL fillCache = FALSE; A_MEMZERO(&finfo, sizeof(finfo)); if ( wcslen(fileName) + wcslen(fileRoot) > 127 ) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Name Very Long :: ====>"); return A_ERROR; } wcscpy(filePath,fileRoot); wcscat(filePath,fileName); ATHR_DISPLAY_MSG (L"file %s \n",filePath); do { if (pBinCache->Valid) { /* binary cache is valid */ if (bCompressed) { status = BMILZStreamStart (hifDevice, address); if (A_FAILED(status)) { break; } } if (bCompressed) { A_UINT32 lastWord = 0; A_UINT32 lastWordOffset = pBinCache->ActualLength & ~0x3; A_UINT32 unalignedBytes = pBinCache->ActualLength & 0x3; if (unalignedBytes) { /* copy the last word into a zero padded buffer */ A_MEMCPY(&lastWord, &pBinCache->pData[lastWordOffset], unalignedBytes); } status = BMILZData(hifDevice, pBinCache->pData, lastWordOffset); if (A_FAILED(status)) { break; } if (unalignedBytes) { status = BMILZData(hifDevice, (A_UINT8 *)&lastWord, 4); } } else { status = BMIWriteMemory(hifDevice, address, pBinCache->pData, A_ROUND_UP(pBinCache->ActualLength,4)); } if (bCompressed && A_SUCCESS(status)) { // // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // status = BMILZStreamStart (hifDevice, 0x00); if (A_FAILED(status)) { break; } } /* all done */ break; } //Determine the length of the file if ( (fd = CreateFile (filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { status = A_ERROR; ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Not Found :: ====> %s", filePath); break; } if (!GetFileInformationByHandle(fd, &finfo)) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: File Size Error :: ====> %s", filePath); status = A_ERROR; break; } fileSize = finfo.nFileSizeLow; file_left = fileSize; if ((pBinCache->pData != NULL) && (!pBinCache->Static)) { /* binary caching is supported */ A_ASSERT(!pBinCache->Valid); if (fileSize <= pBinCache->MaxLength) { /* size if good, flag to cache this binary when read from the filesystem */ fillCache = TRUE; pBinCache->ActualLength = 0; /* reset */ } else { /* cache is not big enough to hold data */ A_ASSERT(FALSE); ATHR_DISPLAY_MSG (L"AR6K::WARNING!!!! :: File :%s (%d bytes) too big for cache (max=%d)", filePath, fileSize, pBinCache->MaxLength); } } // // zero data buffer and init length // buffer = (A_UCHAR *)A_MALLOC(MAX_BUF); if (NULL == buffer) { status = A_ERROR; break; } if (bCompressed) { status = BMILZStreamStart (hifDevice, address); if (status != A_OK) { break; } } while (file_left) { length = (file_left < (MAX_BUF)) ? file_left : MAX_BUF; if (bCompressed) { // // 0 pad last word of data to avoid messy uncompression // ((A_UINT32 *)buffer)[((length-1)/4)] = 0; } if (!ReadFile( fd, buffer, length, &nSize, NULL) || nSize != length) { ATHR_DISPLAY_MSG (L"CAR6K::WARNING!!!! :: ReadFile Error :: ====>"); status = A_ERROR; break; } next_address = address + fileSize - file_left; // // We round up the requested length because some SDIO Host controllers can't handle other lengths. // This generally isn't a problem for users, but it's something to be aware of. // length = A_ROUND_UP(length, 4); if (bCompressed) { status = BMILZData(hifDevice, buffer, length); } else { status = BMIWriteMemory(hifDevice, next_address, buffer, length); } if (status != A_OK) { break; } if (fillCache) { CopyChunkToBinCache(pBinCache, buffer, length); } if (file_left >= MAX_BUF) { file_left = file_left - MAX_BUF; } else { file_left = 0; } }; if (status != A_OK) { break; } if (fillCache) { /* cache was filled, mark it valid */ pBinCache->Valid = TRUE; } if (bCompressed) { // // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // status = BMILZStreamStart (hifDevice, 0x00); if (status != A_OK) { break; } } } while (FALSE); if (buffer) { free (buffer); buffer = NULL; } if (fd) { CloseHandle (fd); } return status; }