コード例 #1
0
int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr,
                   dma_addr_t dma_addr, u32 ext_addr, u32 size)
{
    struct solo_p2m_dev *p2m_dev;
    unsigned int timeout = 0;

    WARN_ON(!size);
    WARN_ON(id >= SOLO_NR_P2M);
    if (!size || id >= SOLO_NR_P2M)
        return -EINVAL;

    p2m_dev = &solo_dev->p2m_dev[id];

    down(&p2m_dev->sem);

start_dma:
    INIT_COMPLETION(p2m_dev->completion);
    p2m_dev->error = 0;
    solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), dma_addr);
    solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), ext_addr);
    solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id),
                   SOLO_P2M_COPY_SIZE(size >> 2));
    solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id),
                   SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) |
                   (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON);

    timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ);

    solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0);

    /* XXX Really looks to me like we will get stuck here if a
     * real PCI P2M error occurs */
    if (p2m_dev->error)
        goto start_dma;

    up(&p2m_dev->sem);

    return (timeout == 0) ? -EAGAIN : 0;
}
コード例 #2
0
ファイル: solo6010-p2m.c プロジェクト: srstrong/solo6x10
	if (WARN_ON_ONCE(p2m_dev->error))
		ret = -EIO;
	else if (timeout == 0)
		ret = -EAGAIN;

	mutex_unlock(&p2m_dev->mutex);

	return ret;
}

void solo_p2m_fill_desc(struct solo_p2m_desc *desc, int wr,
			dma_addr_t dma_addr, u32 ext_addr, u32 size,
			int repeat, u32 ext_size)
{
	desc->cfg = SOLO_P2M_COPY_SIZE(size >> 2);
	desc->ctrl = SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) |
		(wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON;

	if (repeat) {
		desc->cfg |= SOLO_P2M_EXT_INC(ext_size >> 2);
		desc->ctrl |=  SOLO_P2M_PCI_INC(size >> 2) |
			 SOLO_P2M_REPEAT(repeat);
	}

	desc->dma_addr = dma_addr;
	desc->ext_addr = ext_addr;
}

int solo_p2m_dma_t(struct solo6010_dev *solo_dev, int wr,
		   dma_addr_t dma_addr, u32 ext_addr, u32 size,
		   int repeat, u32 ext_size)