FreeBSD/sys/dev/vnic/nicvf_queues.c
/* Free RBDR ring and its receive buffers */
Free RBDR ring and its receive buffers
Free RBDR ring and its receive buffers
static void
nicvf_free_rbdr(struct nicvf *nic, struct rbdr *rbdr)
{
	struct mbuf *mbuf;
	struct queue_set *qs;
	struct rbdr_entry_t *desc;
	struct rbuf_info *rinfo;
	bus_addr_t buf_addr;
	int head, tail, idx;
	int err;
	qs = nic->qs;
	if ((qs == NULL) || (rbdr == NULL))
		return;
	rbdr->enable = FALSE;
	if (rbdr->rbdr_taskq != NULL) {
		while (taskqueue_cancel(rbdr->rbdr_taskq,
		    &rbdr->rbdr_task_nowait, NULL) != 0) {
			taskqueue_drain(rbdr->rbdr_taskq,
			    &rbdr->rbdr_task_nowait);
		}
		taskqueue_free(rbdr->rbdr_taskq);
		rbdr->rbdr_taskq = NULL;
		while (taskqueue_cancel(taskqueue_thread,
		    &rbdr->rbdr_task, NULL) != 0) {
			taskqueue_drain(taskqueue_thread, &rbdr->rbdr_task);
		}
	}
	if (rbdr->rbdr_buff_dmat != NULL) {
		head = rbdr->head;
		tail = rbdr->tail;
		while (head != tail) {
			desc = GET_RBDR_DESC(rbdr, head);
			buf_addr = desc->buf_addr << NICVF_RCV_BUF_ALIGN;
			rinfo = GET_RBUF_INFO(PHYS_TO_DMAP(buf_addr));
			bus_dmamap_unload(rbdr->rbdr_buff_dmat, rinfo->dmap);
			mbuf = rinfo->mbuf;
			m_freem(mbuf);
			head++;
			head &= (rbdr->dmem.q_len - 1);
		}
		desc = GET_RBDR_DESC(rbdr, tail);
		buf_addr = desc->buf_addr << NICVF_RCV_BUF_ALIGN;
		rinfo = GET_RBUF_INFO(PHYS_TO_DMAP(buf_addr));
		bus_dmamap_unload(rbdr->rbdr_buff_dmat, rinfo->dmap);
		mbuf = rinfo->mbuf;
		m_freem(mbuf);
		for (idx = 0; idx < qs->rbdr_len; idx++) {
			if (rbdr->rbdr_buff_dmaps[idx] == NULL)
				continue;
			err = bus_dmamap_destroy(rbdr->rbdr_buff_dmat,
			    rbdr->rbdr_buff_dmaps[idx]);
			KASSERT(err == 0,
			    ("%s: Could not destroy DMA map for RB, desc: %d",
			    __func__, idx));
			rbdr->rbdr_buff_dmaps[idx] = NULL;
		}
		err = bus_dma_tag_destroy(rbdr->rbdr_buff_dmat);
		KASSERT(err == 0,
		    ("%s: Trying to destroy BUSY DMA tag", __func__));
		rbdr->head = 0;
		rbdr->tail = 0;
	}
	nicvf_free_q_desc_mem(nic, &rbdr->dmem);
}
static void nicvf_free_rbdr ( struct nicvf * nic , struct rbdr * rbdr ) { struct mbuf * mbuf ; struct queue_set * qs ; struct rbdr_entry_t * desc ; struct rbuf_info * rinfo ; bus_addr_t buf_addr ; int head , tail , idx ; int err ; qs = nic -> qs ; if ( ( qs == NULL ) || ( rbdr == NULL ) ) return ; rbdr -> enable = FALSE ; if ( rbdr -> rbdr_taskq != NULL ) { while ( taskqueue_cancel ( rbdr -> rbdr_taskq , & rbdr -> rbdr_task_nowait , NULL ) != 0 ) { taskqueue_drain ( rbdr -> rbdr_taskq , & rbdr -> rbdr_task_nowait ) ; } taskqueue_free ( rbdr -> rbdr_taskq ) ; rbdr -> rbdr_taskq = NULL ; while ( taskqueue_cancel ( taskqueue_thread , & rbdr -> rbdr_task , NULL ) != 0 ) { taskqueue_drain ( taskqueue_thread , & rbdr -> rbdr_task ) ; } } if ( rbdr -> rbdr_buff_dmat != NULL ) { head = rbdr -> head ; tail = rbdr -> tail ; while ( head != tail ) { desc = GET_RBDR_DESC ( rbdr , head ) ; buf_addr = desc -> buf_addr << NICVF_RCV_BUF_ALIGN ; rinfo = GET_RBUF_INFO ( PHYS_TO_DMAP ( buf_addr ) ) ; bus_dmamap_unload ( rbdr -> rbdr_buff_dmat , rinfo -> dmap ) ; mbuf = rinfo -> mbuf ; m_freem ( mbuf ) ; head ++ ; head &= ( rbdr -> dmem . q_len - 1 ) ; } desc = GET_RBDR_DESC ( rbdr , tail ) ; buf_addr = desc -> buf_addr << NICVF_RCV_BUF_ALIGN ; rinfo = GET_RBUF_INFO ( PHYS_TO_DMAP ( buf_addr ) ) ; bus_dmamap_unload ( rbdr -> rbdr_buff_dmat , rinfo -> dmap ) ; mbuf = rinfo -> mbuf ; m_freem ( mbuf ) ; for ( idx = 0 ; idx < qs -> rbdr_len ; idx ++ ) { if ( rbdr -> rbdr_buff_dmaps [ idx ] == NULL ) continue ; err = bus_dmamap_destroy ( rbdr -> rbdr_buff_dmat , rbdr -> rbdr_buff_dmaps [ idx ] ) ; KASSERT ( err == 0 , ( " " , __func__ , idx ) ) ; rbdr -> rbdr_buff_dmaps [ idx ] = NULL ; } err = bus_dma_tag_destroy ( rbdr -> rbdr_buff_dmat ) ; KASSERT ( err == 0 , ( " " , __func__ ) ) ; rbdr -> head = 0 ; rbdr -> tail = 0 ; } nicvf_free_q_desc_mem ( nic , & rbdr -> dmem ) ; }
Free RBDR ring and its receive buffers
Free RBDR ring and its receive buffers
/* Remove tasks */ /* Finish the nowait task first */ /* Now finish the sleepable task */ /*
	 * Free all of the memory under the RB descriptors.
	 * There are assumptions here:
	 * 1. Corresponding RBDR is disabled
	 *    - it is safe to operate using head and tail indexes
	 * 2. All bffers that were received are properly freed by
	 *    the receive handler
	 *    - there is no need to unload DMA map and free MBUF for other
	 *      descriptors than unused ones
	 */ /* This will destroy everything including rinfo! */ /* Free tail descriptor */ /* This will destroy everything including rinfo! */ /* Destroy DMA maps */ /* Now destroy the tag */ /* Free RBDR ring */