int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, enum dma_data_direction direction) { int i, rc; if (direction == DMA_NONE) BUG(); WARN_ON(nents == 0 || sg[0].length == 0); if (swiotlb) { rc = swiotlb_map_sg(hwdev, sg, nents, direction); } else { for (i = 0; i < nents; i++ ) { sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; sg[i].dma_length = sg[i].length; BUG_ON(!sg[i].page); IOMMU_BUG_ON(address_needs_mapping( hwdev, sg[i].dma_address)); } rc = nents; } flush_write_buffers(); return rc; }
static dma_addr_t nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int direction) { dma_addr_t bus = paddr; WARN_ON(size == 0); if (!check_addr("map_single", hwdev, bus, size)) return bad_dma_address; flush_write_buffers(); return bus; }
static dma_addr_t nommu_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { dma_addr_t bus = page_to_phys(page) + offset; WARN_ON(size == 0); if (!check_addr("map_single", dev, bus, size)) return bad_dma_address; flush_write_buffers(); return bus; }
static THD_FUNCTION(thLogger, arg) { (void)arg; chRegSetThreadName("Logger"); // These nested while() loops require some explanation. // If the current state is running, we should be in the inner loop // always - just storing, etc. But if the SD is not ready yet, // we will be in the outer loop, flushing buffers, and signalling // uint32_t logger_buffers_written = 0; current_msg.global_count = 0; while( !chThdShouldTerminateX() && LS_EXITING != logger_state) { flush_write_buffers(); int8_t current_idx = -1; systime_t sleep_until = chVTGetSystemTimeX() + MS2ST(5); while( !chThdShouldTerminateX() && LS_RUNNING == logger_state ) { if ( current_idx == -1 ) { current_idx = new_write_buffer_idx_to_fill(); if ( current_idx == -1 ) { // no buffers? sleep and try again chThdSleepMilliseconds(1); continue; } } // here we'll have a good buffer to fill up until it's all full! write_buffer_t * wb = &write_buffers[current_idx]; { kbb_current_msg_t * lm = &wb->buffer[wb->current_idx]; chSysLock(); // make sure that we complete a write uninterrupted memcpy(lm, ¤t_msg, sizeof(current_msg)); chSysUnlock(); kbt_getRTC(&lm->rtc); uint8_t * buf = (uint8_t*) lm; // NOTHING must get written after this, ok? lm->header.checksum = calc_checksum_16(buf+KBB_CHECKSUM_START, KBB_MSG_SIZE-KBB_CHECKSUM_START); } // chTimeNow() will roll over every ~49 days // @TODO: make this code handle that (or not, 49 days is a lot!!) while ( sleep_until < chVTGetSystemTimeX() ) { // this code handles for when we skipped a writing-slot // i'm counting a skipped msg as a write error current_msg.write_errors++; current_msg.msg_num++; sleep_until += MS2ST(5); } chThdSleepUntil(sleep_until); sleep_until += MS2ST(5); // Next deadline current_msg.msg_num++; current_msg.global_count++; // @TODO: fix this! if ( current_msg.msg_num%2048 == 0 ) // we write 1MB every 2048 msgs { kbs_setSDCFree(--cardsize_MB); } wb->current_idx++; if ( wb->current_idx == BUFFER_SIZE ) { // we're full up, return it for a new one return_write_buffer_idx_after_filling(current_idx); // now set it to -1, it will get a new one on next loop current_idx = -1; // now we check to see if we need to roll over into a new // file, this has to be in sync with the writer thread!! logger_buffers_written++; if ( logger_buffers_written > MAX_BUFFERS_PER_FILE ) { logger_buffers_written = 0; // we've hit the file size limit, restart counters flush_counters(); } } } chThdSleepMilliseconds(1); } return; }