Exemplo n.º 1
0
static void
awg_start_locked(struct awg_softc *sc)
{
	struct mbuf *m;
	uint32_t val;
	if_t ifp;
	int cnt, nsegs;

	AWG_ASSERT_LOCKED(sc);

	if (!sc->link)
		return;

	ifp = sc->ifp;

	if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
	    IFF_DRV_RUNNING)
		return;

	for (cnt = 0; ; cnt++) {
		if (sc->tx.queued >= TX_DESC_COUNT - TX_MAX_SEGS) {
			if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
			break;
		}

		m = if_dequeue(ifp);
		if (m == NULL)
			break;

		nsegs = awg_setup_txbuf(sc, sc->tx.cur, &m);
		if (nsegs == 0) {
			if_sendq_prepend(ifp, m);
			break;
		}
		if_bpfmtap(ifp, m);
		sc->tx.cur = TX_SKIP(sc->tx.cur, nsegs);
	}

	if (cnt != 0) {
		bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);

		/* Start and run TX DMA */
		val = RD4(sc, EMAC_TX_CTL_1);
		WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_START);
	}
}
Exemplo n.º 2
0
void async_fault_processing()
{
	struct nand_chip *chip;
	int i, j, k, l, plane, block, page;

	fm.power_fail_flag = 1;
	memset(damaged_block, 0xFF, sizeof(damaged_block));

	//on-going operation들 fault 처리
	for (i = 0; i < NUM_OF_BUS; i++)
	{
		for (j = 0; j < CHIPS_PER_BUS; j++)
		{
			if (fm_status->wq[i][j].status == OP_STARTED)
			{
				fm_status->wq[i][j].ftl_req.addr;

				chip = &fm.buses[i].chips[j];
				plane = addr_to_plane(fm_status->wq[i][j].ftl_req.addr);
				block = addr_to_block(fm_status->wq[i][j].ftl_req.addr);
				page = addr_to_page(fm_status->wq[i][j].ftl_req.addr);

				switch (fm_status->wq[i][j].ftl_req.cmd)
				{
				case PAGE_PROGRAM_FINISH:
					if (chip->cmd == PAGE_PROGRAM_MP)
					{
						for (k = 0; k < PLANES_PER_CHIP; k++)
						{
							damaged_block[i][j][k] = block;
							chip->planes[k].blocks[block].pages[page].state = page_state_transition(chip->planes[k].blocks[block].pages[page].state, PROGRAM_PF);
						}
					}
					else
					{
						damaged_block[i][j][plane] = block;
						chip->planes[plane].blocks[block].pages[page].state = page_state_transition(chip->planes[plane].blocks[block].pages[page].state, PROGRAM_PF);
					}
					break;

				case BLOCK_ERASE:
					if (chip->cmd == BLOCK_ERASE_MP)
					{
						for (k = 0; k < PLANES_PER_CHIP; k++)
						{
							damaged_block[i][j][k] = block;
							for (l = 0; l < PAGES_PER_BLOCK; l++)
							{
								chip->planes[k].blocks[block].pages[l].state = page_state_transition(chip->planes[k].blocks[block].pages[l].state, ERASE_PF);
							}
						}
					}
					else
					{
						damaged_block[i][j][plane] = block;
						for (l = 0; l < PAGES_PER_BLOCK; l++)
						{
							chip->planes[plane].blocks[block].pages[l].state = page_state_transition(chip->planes[plane].blocks[block].pages[l].state, ERASE_PF);
						}
					}
				default:
					break;
				}
			}
		}
	}

	//---reset nand flash emulator---
	//clear event queue
	while (eq->eq_size)
	{
		dequeue_event_queue(eq);
	}

	//clear externel request queue
	while (ftl_to_nand->num_of_entries)
	{
		if_dequeue(ftl_to_nand);
	}

	//clear request queue
	for (i = 0; i < NUM_OF_BUS; i++)
	{
		for (j = 0; j < CHIPS_PER_BUS; j++)
		{
			while (request_queue_arr[i + NUM_OF_BUS * j].num_of_entry)
			{
				dequeue_request_queue(i, j, request_queue_arr);
			}

		}
	}
	//clear dynamic scheduler queue
	while (ds_queue->num_of_entries)
	{
		dequeue(ds_queue);
	}

	//clear flash operation queue
	while (fou_queue->num_of_entries)
	{
		dequeue(fou_queue);
	}

	//init chip and bus status
	reset_flash_module_status(fm_status);
	reset_flashmodule(&fm);

	async_fault_gen();
}