Beispiel #1
0
int
bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
                        bus_dma_segment_t *segs, int *nsegs, int flags)
{
    int error;

    flags |= BUS_DMA_NOWAIT;
    *nsegs = -1;
    error = _bus_dmamap_load_mbuf_sg(dmat, map, m0, segs, nsegs, flags);
    ++*nsegs;
    _bus_dmamap_complete(dmat, map, segs, *nsegs, error);
    return (error);
}
Beispiel #2
0
int
bus_dmamap_load_ccb(bus_dma_tag_t dmat, bus_dmamap_t map, union ccb *ccb,
                    bus_dmamap_callback_t *callback, void *callback_arg,
                    int flags)
{
    bus_dma_segment_t *segs;
    struct ccb_hdr *ccb_h;
    struct memdesc mem;
    int error;
    int nsegs;

    ccb_h = &ccb->ccb_h;
    if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) {
        callback(callback_arg, NULL, 0, 0);
        return (0);
    }
    if ((flags & BUS_DMA_NOWAIT) == 0) {
        mem = memdesc_ccb(ccb);
        _bus_dmamap_waitok(dmat, map, &mem, callback, callback_arg);
    }
    nsegs = -1;
    error = _bus_dmamap_load_ccb(dmat, map, ccb, &nsegs, flags);
    nsegs++;

    CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
         __func__, dmat, flags, error, nsegs);

    if (error == EINPROGRESS)
        return (error);

    segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
    if (error)
        (*callback)(callback_arg, segs, 0, error);
    else
        (*callback)(callback_arg, segs, nsegs, error);
    /*
     * Return ENOMEM to the caller so that it can pass it up the stack.
     * This error only happens when NOWAIT is set, so deferral is disabled.
     */
    if (error == ENOMEM)
        return (error);

    return (0);
}
Beispiel #3
0
/*
 * Map the buffer buf into bus space using the dmamap map.
 */
int
bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
                bus_size_t buflen, bus_dmamap_callback_t *callback,
                void *callback_arg, int flags)
{
    bus_dma_segment_t *segs;
    struct memdesc mem;
    int error;
    int nsegs;

    if ((flags & BUS_DMA_NOWAIT) == 0) {
        mem = memdesc_vaddr(buf, buflen);
        _bus_dmamap_waitok(dmat, map, &mem, callback, callback_arg);
    }

    nsegs = -1;
    error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, kernel_pmap,
                                    flags, NULL, &nsegs);
    nsegs++;

    CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
         __func__, dmat, flags, error, nsegs);

    if (error == EINPROGRESS)
        return (error);

    segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
    if (error)
        (*callback)(callback_arg, segs, 0, error);
    else
        (*callback)(callback_arg, segs, nsegs, 0);

    /*
     * Return ENOMEM to the caller so that it can pass it up the stack.
     * This error only happens when NOWAIT is set, so deferral is disabled.
     */
    if (error == ENOMEM)
        return (error);

    return (0);
}
Beispiel #4
0
int
bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio,
                    bus_dmamap_callback2_t *callback, void *callback_arg, int flags)
{
    bus_dma_segment_t *segs;
    int nsegs, error;

    flags |= BUS_DMA_NOWAIT;
    nsegs = -1;
    error = _bus_dmamap_load_uio(dmat, map, uio, &nsegs, flags);
    nsegs++;

    segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
    if (error)
        (*callback)(callback_arg, segs, 0, 0, error);
    else
        (*callback)(callback_arg, segs, nsegs, uio->uio_resid, error);

    CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
         __func__, dmat, flags, error, nsegs);
    return (error);
}
Beispiel #5
0
int
bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
                     bus_dmamap_callback2_t *callback, void *callback_arg, int flags)
{
    bus_dma_segment_t *segs;
    int nsegs, error;

    flags |= BUS_DMA_NOWAIT;
    nsegs = -1;
    error = _bus_dmamap_load_mbuf_sg(dmat, map, m0, NULL, &nsegs, flags);
    ++nsegs;

    segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
    if (error)
        (*callback)(callback_arg, segs, 0, 0, error);
    else
        (*callback)(callback_arg, segs, nsegs, m0->m_pkthdr.len, error);

    CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
         __func__, dmat, flags, error, nsegs);
    return (error);
}
Beispiel #6
0
int
bus_dmamap_load_mem(bus_dma_tag_t dmat, bus_dmamap_t map,
                    struct memdesc *mem, bus_dmamap_callback_t *callback,
                    void *callback_arg, int flags)
{
    bus_dma_segment_t *segs;
    int error;
    int nsegs;

    if ((flags & BUS_DMA_NOWAIT) == 0)
        _bus_dmamap_waitok(dmat, map, mem, callback, callback_arg);

    nsegs = -1;
    error = 0;
    switch (mem->md_type) {
    case MEMDESC_VADDR:
        error = _bus_dmamap_load_buffer(dmat, map, mem->u.md_vaddr,
                                        mem->md_opaque, kernel_pmap, flags, NULL, &nsegs);
        break;
    case MEMDESC_PADDR:
        error = _bus_dmamap_load_phys(dmat, map, mem->u.md_paddr,
                                      mem->md_opaque, flags, NULL, &nsegs);
        break;
    case MEMDESC_VLIST:
        error = _bus_dmamap_load_vlist(dmat, map, mem->u.md_list,
                                       mem->md_opaque, kernel_pmap, &nsegs, flags);
        break;
    case MEMDESC_PLIST:
        error = _bus_dmamap_load_plist(dmat, map, mem->u.md_list,
                                       mem->md_opaque, &nsegs, flags);
        break;
    case MEMDESC_BIO:
        error = _bus_dmamap_load_bio(dmat, map, mem->u.md_bio,
                                     &nsegs, flags);
        break;
    case MEMDESC_UIO:
        error = _bus_dmamap_load_uio(dmat, map, mem->u.md_uio,
                                     &nsegs, flags);
        break;
    case MEMDESC_MBUF:
        error = _bus_dmamap_load_mbuf_sg(dmat, map, mem->u.md_mbuf,
                                         NULL, &nsegs, flags);
        break;
    case MEMDESC_CCB:
        error = _bus_dmamap_load_ccb(dmat, map, mem->u.md_ccb, &nsegs,
                                     flags);
        break;
    }
    nsegs++;

    CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
         __func__, dmat, flags, error, nsegs);

    if (error == EINPROGRESS)
        return (error);

    segs = _bus_dmamap_complete(dmat, map, NULL, nsegs, error);
    if (error)
        (*callback)(callback_arg, segs, 0, error);
    else
        (*callback)(callback_arg, segs, nsegs, 0);

    /*
     * Return ENOMEM to the caller so that it can pass it up the stack.
     * This error only happens when NOWAIT is set, so deferral is disabled.
     */
    if (error == ENOMEM)
        return (error);

    return (0);
}