Example #1
0
static int
fwdev_freebuf(struct fw_xferq *q)
{
	if (q->flag & FWXFERQ_EXTBUF) {
		if (q->buf != NULL)
			fwdma_free_multiseg(q->buf);
		q->buf = NULL;
		free(q->bulkxfer, M_FW);
		q->bulkxfer = NULL;
		q->flag &= ~FWXFERQ_EXTBUF;
		q->psize = 0;
		q->maxq = FWMAXQUEUE;
	}
	return (0);
}
Example #2
0
/*
 * Allocate multisegment dma buffers
 * each segment size is eqaul to ssize except last segment.
 */
struct fwdma_alloc_multi *
fwdma_malloc_multiseg(struct firewire_comm *fc, int alignment,
		int esize, int n, int flag)
{
	struct fwdma_alloc_multi *am;
	struct fwdma_seg *seg;
	bus_size_t ssize;
	int nseg;

	if (esize > PAGE_SIZE) {
		/* round up to PAGE_SIZE */
		esize = ssize = roundup2(esize, PAGE_SIZE);
		nseg = n;
	} else {
		/* allocate PAGE_SIZE segment for small elements */
		ssize = rounddown(PAGE_SIZE, esize);
		nseg = howmany(n, ssize / esize);
	}
	am = (struct fwdma_alloc_multi *)malloc(sizeof(struct fwdma_alloc_multi)
			+ sizeof(struct fwdma_seg)*nseg, M_FW, M_WAITOK);
	if (am == NULL) {
		printf("fwdma_malloc_multiseg: malloc failed\n");
		return(NULL);
	}
	am->ssize = ssize;
	am->esize = esize;
	am->nseg = 0;
	if (bus_dma_tag_create(
			/*parent*/ fc->dmat,
			/*alignment*/ alignment,
			/*boundary*/ 0,
			/*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
			/*highaddr*/ BUS_SPACE_MAXADDR,
			/*filter*/NULL, /*filterarg*/NULL,
			/*maxsize*/ ssize,
			/*nsegments*/ 1,
			/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
			/*flags*/ BUS_DMA_ALLOCNOW,
#if __FreeBSD_version >= 501102
			/*lockfunc*/busdma_lock_mutex,
			/*lockarg*/&Giant,
#endif
			&am->dma_tag)) {
		printf("fwdma_malloc_multiseg: tag_create failed\n");
		free(am, M_FW);
		return(NULL);
	}

#if 0
#if __FreeBSD_version < 500000
	printf("malloc_multi: ssize=%d nseg=%d\n", ssize, nseg);
#else
	printf("malloc_multi: ssize=%td nseg=%d\n", ssize, nseg);
#endif
#endif
	for (seg = &am->seg[0]; nseg --; seg ++) {
		seg->v_addr = fwdma_malloc_size(am->dma_tag, &seg->dma_map,
			ssize, &seg->bus_addr, flag);
		if (seg->v_addr == NULL) {
			printf("fwdma_malloc_multi: malloc_size failed %d\n",
				am->nseg);
			fwdma_free_multiseg(am);
			return(NULL);
		}
		am->nseg++;
	}
	return(am);
}