static int unipro_continue_xfer(struct unipro_xfer_descriptor *desc)
{
    size_t xfer_len;

    desc->remaining_xfer_len -= desc->dma_arg.unipro_tx_arg.next_transfer_len;

    xfer_len = unipro_get_tx_free_buffer_space(desc->cport);
    if (!xfer_len)
        return -ENOSPC;

    xfer_len = MIN(desc->remaining_xfer_len, xfer_len);
    desc->dma_arg.unipro_tx_arg.next_transfer_len = xfer_len;

    if (xfer_len == desc->remaining_xfer_len)
        desc->dma_arg.unipro_tx_arg.eom_addr = CPORT_EOM_BIT(desc->cport);

    return 0;
}
static int unipro_dma_xfer(struct unipro_xfer_descriptor *desc,
                           struct dma_channel *channel)
{
    int retval;
    size_t xfer_len;
    void *cport_buf;
    void *xfer_buf;

    xfer_len = unipro_get_tx_free_buffer_space(desc->cport);
    if (!xfer_len)
        return -ENOSPC;

    xfer_len = MIN(desc->remaining_xfer_len, xfer_len);

    desc->channel = channel;
    desc->dma_arg.unipro_tx_arg.next_transfer_len = xfer_len;
    if (xfer_len == desc->remaining_xfer_len)
        desc->dma_arg.unipro_tx_arg.eom_addr = CPORT_EOM_BIT(desc->cport);

    DBG_UNIPRO("xfer: chan=%u, len=%zu\n", channel->id, xfer_len);

    cport_buf = desc->cport->tx_buf;
    xfer_buf = (void*) desc->data;

    /* resuming a paused xfer */
    if (desc->remaining_xfer_len != desc->len) {
        cport_buf = (char*) cport_buf + 1; /* skip the start byte */

        /* move buffer offset to the beginning of the remaning bytes to xfer */
        xfer_buf = (char*) xfer_buf + (desc->len - desc->remaining_xfer_len);
    }

    retval = device_dma_transfer(unipro_dma.dev, channel->id, xfer_buf,
                                 cport_buf, xfer_len, &desc->dma_arg);
    if (retval) {
        lowsyslog("unipro: failed to start DMA transfer: %d\n", retval);
        return retval;
    }

    return 0;
}
Exemple #3
0
/**
 * @brief           Set EOM (End Of Message) flag
 * @param[in]       cport: CPort handle
 */
static inline void unipro_set_eom_flag(struct cport *cport)
{
    putreg8(1, CPORT_EOM_BIT(cport));
}