scatter


static void dw_mci_write_data_pio(struct dw_mci *host)
{
    struct sg_mapping_iter *sg_miter = &host->sg_miter;
    void *buf;
    unsigned int offset;
    struct mmc_data *data = host->data;
    int shift = host->data_shift;
    u32 status;
    unsigned int len;
    unsigned int fifo_depth = host->fifo_depth;
    unsigned int remain, fcnt;
    printk("[=============== enter %s==============]\n", __func__);

    if(!host->mmc->bus_refs){
        printk("Note: %s host->mmc->bus_refs is 0!!!\n", __func__);
        goto host_put;
    }

    do {
        if (!sg_miter_next(sg_miter)) {
            printk("[=============== do complete %s sg_next 0 ==============]\n", __func__);
            goto done;
        }

        host->sg = sg_miter->piter.sg;
        buf = sg_miter->addr;
        remain = sg_miter->length;
        offset = 0;
        printk("sg: %p, sg_addr: %p, sg_length: %d.\n", host->sg, buf, remain);

        do {
            fcnt = ((fifo_depth -
                 SDMMC_GET_FCNT(mci_readl(host, STATUS)))
                    << shift) - host->part_buf_count;
            len = min(remain, fcnt);
            printk("    fcnt: %d, remain: %d, len: %d\n", fcnt, remain, len);

            if (!len)
                break;
            host->push_data(host, (void *)(buf + offset), len);
            data->bytes_xfered += len;
            offset += len;
            remain -= len;
        } while (remain);

        sg_miter->consumed = offset;
        status = mci_readl(host, MINTSTS);
        printk("sg_consumed: %d, status: 0x%08x.\n", offset, status);
        mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
    } while (status & SDMMC_INT_TXDR); /* if TXDR write again */

    if (!remain) {
        if (!sg_miter_next(sg_miter)) {
            printk("[=============== complete %s sg_next 0, remain 0 ==============]\n", __func__);
            goto done;
        }
        sg_miter->consumed = 0;
        printk("[===============not complete %s sg_miter->consumed = 0, remain 0 ==============]\n", __func__);
    }
    sg_miter_stop(sg_miter);
    printk("[=============== exit no complete %s remain: %d==============]\n", __func__, remain);
    return;

done:
    sg_miter_stop(sg_miter);
host_put:   
    host->sg = NULL;
    smp_wmb();  
    printk("[=============== exit complete %s==============]\n", __func__);
    set_bit(EVENT_XFER_COMPLETE, &host->pending_events);
}

猜你喜欢

转载自blog.csdn.net/x19910304xiaoyao/article/details/54691877