Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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, &current_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;
}