void dma1_channel6_isr() { if (state == ADC_WORKING) state = ADC_CH6_DONE; else if (state == ADC_CH5_DONE) dma_complete(); else cm3_assert(0); }
void mac_drv_clear_rx_queue(struct s_smc *smc) { struct s_smt_fp_rxd volatile *r ; struct s_smt_fp_rxd volatile *next_rxd ; struct s_smt_rx_queue *queue ; int frag_count ; int i ; if (smc->hw.hw_state != STOPPED) { SK_BREAK() ; SMT_PANIC(smc,HWM_E0012,HWM_E0012_MSG) ; return ; } queue = smc->hw.fp.rx[QUEUE_R1] ; DB_RX("clear_rx_queue",0,0,5) ; /* * dma_complete and mac_drv_clear_rxd for all RxDs / receive buffers */ r = queue->rx_curr_get ; while (queue->rx_used) { DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; DB_RX("switch OWN bit of RxD 0x%x ",r,0,5) ; r->rxd_rbctrl &= ~cpu_to_le32(BMU_OWN) ; frag_count = 1 ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ; r = r->rxd_next ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; while (r != queue->rx_curr_put && !(r->rxd_rbctrl & cpu_to_le32(BMU_ST_BUF))) { DB_RX("Check STF bit in %x",(void *)r,0,5) ; r->rxd_rbctrl &= ~cpu_to_le32(BMU_OWN) ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ; r = r->rxd_next ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; frag_count++ ; } DB_RX("STF bit found",0,0,5) ; next_rxd = r ; for (r=queue->rx_curr_get,i=frag_count; i ; r=r->rxd_next,i--){ DB_RX("dma_complete for RxD %x",(void *)r,0,5) ; dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR); } DB_RX("mac_drv_clear_rxd: RxD %x frag_count %d ", (void *)queue->rx_curr_get,frag_count,5) ; mac_drv_clear_rxd(smc,queue->rx_curr_get,frag_count) ; queue->rx_curr_get = next_rxd ; queue->rx_used -= frag_count ; queue->rx_free += frag_count ; } }
static void dma_bdrv_cb(void *opaque, int ret) { DMAAIOCB *dbs = (DMAAIOCB *)opaque; target_phys_addr_t cur_addr, cur_len; void *mem; dbs->acb = NULL; dbs->sector_num += dbs->iov.size / 512; dma_bdrv_unmap(dbs); if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { dma_complete(dbs, ret); return; } while (dbs->sg_cur_index < dbs->sg->nsg) { cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte; cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte; mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->to_dev); if (!mem) break; qemu_iovec_add(&dbs->iov, mem, cur_len); dbs->sg_cur_byte += cur_len; if (dbs->sg_cur_byte == dbs->sg->sg[dbs->sg_cur_index].len) { dbs->sg_cur_byte = 0; ++dbs->sg_cur_index; } } if (dbs->iov.size == 0) { cpu_register_map_client(dbs, continue_after_map_failure); return; } dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov, dbs->iov.size / 512, dma_bdrv_cb, dbs); if (!dbs->acb) { dma_complete(dbs, -EIO); } }
static void dma_aio_cancel(BlockDriverAIOCB *acb) { DMAAIOCB *dbs = container_of(acb, DMAAIOCB, common); if (dbs->acb) { BlockDriverAIOCB *acb = dbs->acb; dbs->acb = NULL; dbs->in_cancel = true; bdrv_aio_cancel(acb); dbs->in_cancel = false; } dbs->common.cb = NULL; dma_complete(dbs, 0); }
static void dma_blk_cb(void *opaque, int ret) { DMAAIOCB *dbs = (DMAAIOCB *)opaque; dma_addr_t cur_addr, cur_len; void *mem; trace_dma_blk_cb(dbs, ret); dbs->acb = NULL; dbs->sector_num += dbs->iov.size / 512; if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) { dma_complete(dbs, ret); return; } dma_blk_unmap(dbs); while (dbs->sg_cur_index < dbs->sg->nsg) { cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte; cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte; mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir); if (!mem) break; qemu_iovec_add(&dbs->iov, mem, cur_len); dbs->sg_cur_byte += cur_len; if (dbs->sg_cur_byte == dbs->sg->sg[dbs->sg_cur_index].len) { dbs->sg_cur_byte = 0; ++dbs->sg_cur_index; } } if (dbs->iov.size == 0) { trace_dma_map_wait(dbs); dbs->bh = aio_bh_new(blk_get_aio_context(dbs->blk), reschedule_dma, dbs); cpu_register_map_client(dbs->bh); return; } if (dbs->iov.size & ~BDRV_SECTOR_MASK) { qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK); } dbs->acb = dbs->io_func(dbs->blk, dbs->sector_num, &dbs->iov, dbs->iov.size / 512, dma_blk_cb, dbs); assert(dbs->acb); }
void process_receive(struct s_smc *smc) { int i ; int n ; int frag_count ; /* number of RxDs of the curr rx buf */ int used_frags ; /* number of RxDs of the curr frame */ struct s_smt_rx_queue *queue ; /* points to the queue ctl struct */ struct s_smt_fp_rxd volatile *r ; /* rxd pointer */ struct s_smt_fp_rxd volatile *rxd ; /* first rxd of rx frame */ u_long rbctrl ; /* receive buffer control word */ u_long rfsw ; /* receive frame status word */ u_short rx_used ; u_char far *virt ; char far *data ; SMbuf *mb ; u_char fc ; /* Frame control */ int len ; /* Frame length */ smc->os.hwm.detec_count = 0 ; queue = smc->hw.fp.rx[QUEUE_R1] ; NDD_TRACE("RHxB",0,0,0) ; for ( ; ; ) { r = queue->rx_curr_get ; rx_used = queue->rx_used ; frag_count = 0 ; #ifdef USE_BREAK_ISR if (smc->os.hwm.leave_isr) { goto rx_end ; } #endif #ifdef NDIS_OS2 if (offDepth) { smc->os.hwm.rx_break = 1 ; goto rx_end ; } smc->os.hwm.rx_break = 0 ; #endif #ifdef ODI2 if (smc->os.hwm.rx_break) { goto rx_end ; } #endif n = 0 ; do { DB_RX("Check RxD %x for OWN and EOF",(void *)r,0,5) ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; rbctrl = le32_to_cpu(CR_READ(r->rxd_rbctrl)); if (rbctrl & BMU_OWN) { NDD_TRACE("RHxE",r,rfsw,rbctrl) ; DB_RX("End of RxDs",0,0,4) ; goto rx_end ; } /* * out of RxD detection */ if (!rx_used) { SK_BREAK() ; SMT_PANIC(smc,HWM_E0009,HWM_E0009_MSG) ; /* Either we don't have an RxD or all * RxDs are filled. Therefore it's allowed * for to set the STOPPED flag */ smc->hw.hw_state = STOPPED ; mac_drv_clear_rx_queue(smc) ; smc->hw.hw_state = STARTED ; mac_drv_fill_rxd(smc) ; smc->os.hwm.detec_count = 0 ; goto rx_end ; } rfsw = le32_to_cpu(r->rxd_rfsw) ; if ((rbctrl & BMU_STF) != ((rbctrl & BMU_ST_BUF) <<5)) { /* * The BMU_STF bit is deleted, 1 frame is * placed into more than 1 rx buffer * * skip frame by setting the rx len to 0 * * if fragment count == 0 * The missing STF bit belongs to the * current frame, search for the * EOF bit to complete the frame * else * the fragment belongs to the next frame, * exit the loop and process the frame */ SK_BREAK() ; rfsw = 0 ; if (frag_count) { break ; } } n += rbctrl & 0xffff ; r = r->rxd_next ; frag_count++ ; rx_used-- ; } while (!(rbctrl & BMU_EOF)) ; used_frags = frag_count ; DB_RX("EOF set in RxD, used_frags = %d ",used_frags,0,5) ; /* may be next 2 DRV_BUF_FLUSH() can be skipped, because */ /* BMU_ST_BUF will not be changed by the ASIC */ DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; while (rx_used && !(r->rxd_rbctrl & cpu_to_le32(BMU_ST_BUF))) { DB_RX("Check STF bit in %x",(void *)r,0,5) ; r = r->rxd_next ; DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ; frag_count++ ; rx_used-- ; } DB_RX("STF bit found",0,0,5) ; /* * The received frame is finished for the process receive */ rxd = queue->rx_curr_get ; queue->rx_curr_get = r ; queue->rx_free += frag_count ; queue->rx_used = rx_used ; /* * ASIC Errata no. 7 (STF - Bit Bug) */ rxd->rxd_rbctrl &= cpu_to_le32(~BMU_STF) ; for (r=rxd, i=frag_count ; i ; r=r->rxd_next, i--){ DB_RX("dma_complete for RxD %x",(void *)r,0,5) ; dma_complete(smc,(union s_fp_descr volatile *)r,DMA_WR); } smc->hw.fp.err_stats.err_valid++ ; smc->mib.m[MAC0].fddiMACCopied_Ct++ ; /* the length of the data including the FC */ len = (rfsw & RD_LENGTH) - 4 ; DB_RX("frame length = %d",len,0,4) ; /* * check the frame_length and all error flags */ if (rfsw & (RX_MSRABT|RX_FS_E|RX_FS_CRC|RX_FS_IMPL)){ if (rfsw & RD_S_MSRABT) { DB_RX("Frame aborted by the FORMAC",0,0,2) ; smc->hw.fp.err_stats.err_abort++ ; } /* * check frame status */ if (rfsw & RD_S_SEAC2) { DB_RX("E-Indicator set",0,0,2) ; smc->hw.fp.err_stats.err_e_indicator++ ; } if (rfsw & RD_S_SFRMERR) { DB_RX("CRC error",0,0,2) ; smc->hw.fp.err_stats.err_crc++ ; } if (rfsw & RX_FS_IMPL) { DB_RX("Implementer frame",0,0,2) ; smc->hw.fp.err_stats.err_imp_frame++ ; } goto abort_frame ; } if (len > FDDI_RAW_MTU-4) { DB_RX("Frame too long error",0,0,2) ; smc->hw.fp.err_stats.err_too_long++ ; goto abort_frame ; } /* * SUPERNET 3 Bug: FORMAC delivers status words * of aborded frames to the BMU */ if (len <= 4) { DB_RX("Frame length = 0",0,0,2) ; goto abort_frame ; } if (len != (n-4)) { DB_RX("BMU: rx len differs: [%d:%d]",len,n,4); smc->os.hwm.rx_len_error++ ; goto abort_frame ; } /* * Check SA == MA */ virt = (u_char far *) rxd->rxd_virt ; DB_RX("FC = %x",*virt,0,2) ; if (virt[12] == MA[5] && virt[11] == MA[4] && virt[10] == MA[3] && virt[9] == MA[2] && virt[8] == MA[1] && (virt[7] & ~GROUP_ADDR_BIT) == MA[0]) { goto abort_frame ; } /* * test if LLC frame */ if (rfsw & RX_FS_LLC) { /* * if pass_llc_promisc is disable * if DA != Multicast or Broadcast or DA!=MA * abort the frame */ if (!smc->os.hwm.pass_llc_promisc) { if(!(virt[1] & GROUP_ADDR_BIT)) { if (virt[6] != MA[5] || virt[5] != MA[4] || virt[4] != MA[3] || virt[3] != MA[2] || virt[2] != MA[1] || virt[1] != MA[0]) { DB_RX("DA != MA and not multi- or broadcast",0,0,2) ; goto abort_frame ; } } } /* * LLC frame received */ DB_RX("LLC - receive",0,0,4) ; mac_drv_rx_complete(smc,rxd,frag_count,len) ; } else { if (!(mb = smt_get_mbuf(smc))) { smc->hw.fp.err_stats.err_no_buf++ ; DB_RX("No SMbuf; receive terminated",0,0,4) ; goto abort_frame ; } data = smtod(mb,char *) - 1 ; /* * copy the frame into a SMT_MBuf */ #ifdef USE_OS_CPY hwm_cpy_rxd2mb(rxd,data,len) ; #else for (r=rxd, i=used_frags ; i ; r=r->rxd_next, i--){ n = le32_to_cpu(r->rxd_rbctrl) & RD_LENGTH ; DB_RX("cp SMT frame to mb: len = %d",n,0,6) ; memcpy(data,r->rxd_virt,n) ; data += n ; } data = smtod(mb,char *) - 1 ; #endif fc = *(char *)mb->sm_data = *data ; mb->sm_len = len - 1 ; /* len - fc */ data++ ; /* * SMT frame received */ switch(fc) { case FC_SMT_INFO : smc->hw.fp.err_stats.err_smt_frame++ ; DB_RX("SMT frame received ",0,0,5) ; if (smc->os.hwm.pass_SMT) { DB_RX("pass SMT frame ",0,0,5) ; mac_drv_rx_complete(smc, rxd, frag_count,len) ; } else { DB_RX("requeue RxD",0,0,5) ; mac_drv_requeue_rxd(smc,rxd,frag_count); } smt_received_pack(smc,mb,(int)(rfsw>>25)) ; break ; case FC_SMT_NSA : smc->hw.fp.err_stats.err_smt_frame++ ; DB_RX("SMT frame received ",0,0,5) ; /* if pass_NSA set pass the NSA frame or */ /* pass_SMT set and the A-Indicator */ /* is not set, pass the NSA frame */ if (smc->os.hwm.pass_NSA || (smc->os.hwm.pass_SMT && !(rfsw & A_INDIC))) { DB_RX("pass SMT frame ",0,0,5) ; mac_drv_rx_complete(smc, rxd, frag_count,len) ; } else { DB_RX("requeue RxD",0,0,5) ; mac_drv_requeue_rxd(smc,rxd,frag_count); } smt_received_pack(smc,mb,(int)(rfsw>>25)) ; break ; case FC_BEACON : if (smc->os.hwm.pass_DB) { DB_RX("pass DB frame ",0,0,5) ; mac_drv_rx_complete(smc, rxd, frag_count,len) ; } else { DB_RX("requeue RxD",0,0,5) ; mac_drv_requeue_rxd(smc,rxd,frag_count); } smt_free_mbuf(smc,mb) ; break ; default : /* * unknown FC abord the frame */ DB_RX("unknown FC error",0,0,2) ; smt_free_mbuf(smc,mb) ; DB_RX("requeue RxD",0,0,5) ; mac_drv_requeue_rxd(smc,rxd,frag_count) ; if ((fc & 0xf0) == FC_MAC) smc->hw.fp.err_stats.err_mac_frame++ ; else smc->hw.fp.err_stats.err_imp_frame++ ; break ; } } DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ; NDD_TRACE("RHx1",queue->rx_curr_get,0,0) ; continue ; /*--------------------------------------------------------------------*/ abort_frame: DB_RX("requeue RxD",0,0,5) ; mac_drv_requeue_rxd(smc,rxd,frag_count) ; DB_RX("next RxD is %x ",queue->rx_curr_get,0,3) ; NDD_TRACE("RHx2",queue->rx_curr_get,0,0) ; } rx_end: #ifdef ALL_RX_COMPLETE mac_drv_all_receives_complete(smc) ; #endif return ; /* lint bug: needs return detect end of function */ }