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); } }
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(); }