int input(int dev, void *buf, int size) { ret = 0; #ifdef VERBOSE _entry: trl_(); trvd(size); #endif if (dev < 0 || wo) return 0; switch (io_type) { case mmap_io: memcpy(buf, mem, size); ret = size; break; case ioctl_io: ioctl(dev, _IOC(_IOC_READ, ioctl_type, ioctl_num, size & _IOC_SIZEMASK), buf); ret = size; break; case file_io: default: ret = read(dev, buf, size); } return ret; }
int output(int dev, void *buf, int size) { #ifdef VERBOSE _entry: trl_(); trvd(size); #endif ret = 0; if (dev < 0 || ro) return 0; switch (io_type) { case mmap_io: memcpy(mem, buf, size); ret = size; break; case ioctl_io: ioctl(dev, _IOC(_IOC_WRITE, ioctl_type, ioctl_num, size & _IOC_SIZEMASK), buf); break; case file_io: default: ret = write(dev, buf, size); } return ret; }
int io_start(int dev) { struct pollfd pfd[2]; ssize_t data_in_len, data_out_len, len_total = 0; int i = 0; /* TODO: wo, ro */ pfd[0].fd = fileno(stdin); pfd[0].events = POLLIN; pfd[1].fd = dev; pfd[1].events = POLLIN; while (poll(pfd, sizeof(pfd) / sizeof(pfd[0]), -1) > 0) { #ifdef VERBOSE trvd_(i); trvx_(pfd[0].revents); trvx_(pfd[1].revents); trln(); #endif data_in_len = 0; if (pfd[0].revents & POLLIN) { pfd[0].revents = 0; ret = data_in_len = read(fileno(stdin), inbuf, buf_size); if (data_in_len < 0) { usleep(100000); break; } if (!data_in_len && !ignore_eof) { /* read returns 0 on End Of File */ break; } #ifdef VERBOSE trvd_(data_in_len); trln(); #endif again: chkne(ret = output(dev, inbuf, data_in_len)); if (ret < 0 && errno == EAGAIN) { usleep(100000); goto again; } if (data_in_len > 0) len_total += data_in_len; } data_out_len = 0; if (pfd[1].revents & POLLIN) { pfd[1].revents = 0; chkne(ret = data_out_len = input(dev, outbuf, buf_size)); if (data_out_len < 0) { usleep(100000); break; } if (!data_out_len) { /* EOF, don't expect data from the file any more but wee can continue to write */ pfd[1].events = 0; } if (!data_out_len && !ignore_eof) { /* read returns 0 on End Of File */ break; } write(fileno(stdout), outbuf, data_out_len); if (data_out_len > 0) len_total += data_out_len; } #ifdef VERBOSE trl_(); trvd_(i); trvd_(len_total); trvd_(data_in_len); trvd_(data_out_len); trln(); #endif if ((!ignore_eof && pfd[0].revents & POLLHUP) || pfd[1].revents & POLLHUP) break; i++; if (loops && i >= loops) break; usleep(1000 * delay); } #ifdef VERBOSE trl_(); trvd_(i); trvd_(len_total); trvd_(data_in_len); trvd_(data_out_len); trln(); #endif return ret; }
Uint32 LOCAL_NANDWriteHeaderAndData(NAND_InfoHandle hNandInfo, NANDBOOT_HeaderHandle hNandBoot, Uint8 *srcBuf) { Uint32 *ptr; Uint32 currBlockNum,currPageNum,pageCnt,i; Uint32 numBlks, numBlksRemaining; trl_(); trvx_(hNandBoot->startBlock); trvx(hNandBoot->endBlock); trvx(srcBuf); hNandWriteBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); hNandReadBuf = UTIL_allocMem(hNandInfo->dataBytesPerPage); extern __FAR__ Uint32 EXTERNAL_RAM_START, EXTERNAL_RAM_END; trvx(&EXTERNAL_RAM_START); trvx(hNandWriteBuf); trvx(hNandReadBuf); // Unprotect all needed blocks of the flash if (NAND_unProtectBlocks(hNandInfo,hNandBoot->startBlock,hNandBoot->endBlock-hNandBoot->startBlock+1) != E_PASS) { DEBUG_printString("Unprotect failed\r\n"); return E_FAIL; } // Check if device is write protected if (NAND_isWriteProtected(hNandInfo)) { DEBUG_printString("NAND is write protected!\r\n"); return E_FAIL; } // Get total number of blocks needed for each copy numBlks = 0; while ( (numBlks * hNandInfo->pagesPerBlock) < (hNandBoot->numPage + 1) ) { numBlks++; } DEBUG_printString("Number of blocks needed for header and data: 0x"); DEBUG_printHexInt(numBlks); DEBUG_printString("\r\n"); // Init internal current block number counter currBlockNum = hNandBoot->startBlock; // Go to first good block while (NAND_badBlockCheck(hNandInfo,currBlockNum) != E_PASS) { DEBUG_printString("NAND block "); DEBUG_printHexInt(currBlockNum); DEBUG_printString(" is bad!!!\r\n"); currBlockNum++; // Now check to make sure we aren't already out of space if (currBlockNum > (hNandBoot->endBlock + numBlks - 1 )) { DEBUG_printString("No good blocks in allowed range!!!\r\n"); return E_FAIL; } } DEBUG_printString("Attempting to start in block number 0x"); DEBUG_printHexInt(currBlockNum); DEBUG_printString(".\r\n"); // Keep going while we have room to place another copy do { numBlksRemaining = numBlks; // Erase the block where the header goes and the data starts if (NAND_eraseBlocks(hNandInfo,currBlockNum,numBlks) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Erase failed\r\n"); continue; } trl(); // Clear write buffer ptr = (Uint32 *) hNandWriteBuf; for (i=0; i < hNandInfo->dataBytesPerPage >> 2; i++) { ptr[i] = 0xFFFFFFFF; } trl(); // Setup header to be written ptr[0] = hNandBoot->magicNum; ptr[1] = hNandBoot->entryPoint; ptr[2] = hNandBoot->numPage; ptr[3] = currBlockNum; //always start data in current block ptr[4] = 1; //always start data in page 1 (this header goes in page 0) ptr[5] = hNandBoot->ldAddress; // Write the header to page 0 of the current blockNum DEBUG_printString("Writing header and image data to Block "); DEBUG_printHexInt(currBlockNum); DEBUG_printString(", Page "); DEBUG_printHexInt(0); DEBUG_printString("\r\n"); trl(); #ifdef DM35X_REVB #define DM35X_REVC #endif #ifdef DM35X_REVC if (NAND_writePage_ubl_header(hNandInfo, currBlockNum, 0, hNandWriteBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write failed!\r\n"); continue; } #else if (NAND_writePage(hNandInfo, currBlockNum, 0, hNandWriteBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write failed!\r\n"); continue; } #endif UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, currBlockNum, 0, hNandWriteBuf, hNandReadBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write verify failed!\r\n"); continue; } pageCnt = 1; currPageNum = 1; do { // Write the UBL or APP data on a per page basis if (NAND_writePage(hNandInfo, currBlockNum, currPageNum, srcBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString("Write failed, skipping block!\r\n"); if ( (numBlksRemaining == numBlks) || (hNandBoot->forceContigImage) ) break; // If we are still in the first block, we have to go rewrite the header too else { srcBuf -= (hNandInfo->dataBytesPerPage * currPageNum); trvx(srcBuf); pageCnt -= currPageNum; currPageNum = 0; continue; } } UTIL_waitLoop(200); // Verify the page just written if (NAND_verifyPage(hNandInfo, currBlockNum, currPageNum, srcBuf, hNandReadBuf) != E_PASS) { // Attempt to mark block bad NAND_badBlockMark(hNandInfo, currBlockNum); currBlockNum++; DEBUG_printString(RED"Write verify failed, skipping block!\r\n"NOCOLOR); if ( (numBlksRemaining == numBlks) || (hNandBoot->forceContigImage) ) break; // If we are still in the first block, we have to go rewrite the header too else { srcBuf -= (hNandInfo->dataBytesPerPage * currPageNum); trvx(srcBuf); pageCnt -= currPageNum; currPageNum = 0; continue; } } srcBuf += hNandInfo->dataBytesPerPage; pageCnt++; currPageNum++; // If we need to go the next block, or our image is complete, increment current block num if ( (currPageNum == hNandInfo->pagesPerBlock) || (pageCnt >= (hNandBoot->numPage+1)) ) { trvi(currPageNum); currBlockNum++; numBlksRemaining--; srcBuf -= hNandInfo->dataBytesPerPage * currPageNum; currPageNum = 0; } } while ( (pageCnt < (hNandBoot->numPage+1)) && ((currBlockNum + numBlksRemaining - 1)<=hNandBoot->endBlock) ); trvi(pageCnt); } while( (currBlockNum + numBlks - 1)<=hNandBoot->endBlock ); // Protect all blocks NAND_protectBlocks(hNandInfo); // We succeeded in writing all copies that would fit return E_PASS; }