Index: i386/i386/busdma_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/busdma_machdep.c,v retrieving revision 1.32 diff -u -r1.32 busdma_machdep.c --- i386/i386/busdma_machdep.c 4 Feb 2003 16:30:27 -0000 1.32 +++ i386/i386/busdma_machdep.c 16 Feb 2003 02:21:08 -0000 @@ -403,11 +403,8 @@ { vm_offset_t vaddr; vm_offset_t paddr; -#ifdef __GNUC__ - bus_dma_segment_t dm_segments[dmat->nsegments]; -#else - bus_dma_segment_t dm_segments[BUS_DMAMAP_NSEGS]; -#endif + bus_dma_segment_t stack_dm_segments[BUS_DMAMAP_NSEGS]; + bus_dma_segment_t *dm_segments; bus_dma_segment_t *sg; int seg; int error; @@ -463,6 +460,14 @@ splx(s); } + if (dmat->nsegments > BUS_DMAMAP_NSEGS) { + dm_segments = malloc(dmat->nsegments * sizeof(bus_dma_segment_t), + M_DEVBUF, (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : 0); + if (dm_segments == NULL) + return ENOMEM; + } else + dm_segments = stack_dm_segments; + vaddr = (vm_offset_t)buf; sg = &dm_segments[0]; seg = 1; @@ -484,7 +489,8 @@ if (sg->ds_len == 0) { sg->ds_addr = paddr; sg->ds_len = size; - } else if (paddr == nextpaddr) { + } else if (paddr == nextpaddr && + sg->ds_len + size < dmat->maxsegsz) { sg->ds_len += size; } else { /* Go to the next segment */ @@ -508,6 +514,9 @@ } (*callback)(callback_arg, dm_segments, seg, error); + + if (dm_segments != stack_dm_segments) + free(dm_segments, M_DEVBUF); return (0); }