/* * Configure the DMA controller, load the DMA descriptors, but don't start the * DMA controller yet. Only issue the ATA command.
*/ staticvoid pxa_bmdma_setup(struct ata_queued_cmd *qc)
{
qc->ap->ops->sff_exec_command(qc->ap, &qc->tf);
}
/* * Wait until the DMA transfer completes, then stop the DMA controller.
*/ staticvoid pxa_bmdma_stop(struct ata_queued_cmd *qc)
{ struct pata_pxa_data *pd = qc->ap->private_data; enum dma_status status;
status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, NULL); if (status != DMA_ERROR && status != DMA_COMPLETE &&
wait_for_completion_timeout(&pd->dma_done, HZ))
ata_dev_err(qc->dev, "Timeout waiting for DMA completion!");
dmaengine_terminate_all(pd->dma_chan);
}
/* * Read DMA status. The bmdma_stop() will take care of properly finishing the * DMA transfer so we always have DMA-complete interrupt here.
*/ staticunsignedchar pxa_bmdma_status(struct ata_port *ap)
{ struct pata_pxa_data *pd = ap->private_data; unsignedchar ret = ATA_DMA_INTR; struct dma_tx_state state; enum dma_status status;
status = dmaengine_tx_status(pd->dma_chan, pd->dma_cookie, &state); if (status != DMA_COMPLETE)
ret |= ATA_DMA_ERR;
return ret;
}
/* * No IRQ register present so we do nothing.
*/ staticvoid pxa_irq_clear(struct ata_port *ap)
{
}
/* * Check for ATAPI DMA. ATAPI DMA is unsupported by this driver. It's still * unclear why ATAPI has DMA issues.
*/ staticint pxa_check_atapi_dma(struct ata_queued_cmd *qc)
{ return -EOPNOTSUPP;
}
/* * Resource validation, three resources are needed: * - CMD port base address * - CTL port base address * - DMA port base address * - IRQ pin
*/ if (pdev->num_resources != 4) {
dev_err(&pdev->dev, "invalid number of resources\n"); return -EINVAL;
}
/* * CMD port base address
*/
cmd_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(cmd_res == NULL)) return -EINVAL;
/* * CTL port base address
*/
ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (unlikely(ctl_res == NULL)) return -EINVAL;
/* * DMA port base address
*/
dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (unlikely(dma_res == NULL)) return -EINVAL;
/* * Allocate and load driver's internal data structure
*/
data = devm_kzalloc(&pdev->dev, sizeof(struct pata_pxa_data),
GFP_KERNEL); if (!data) return -ENOMEM;
/* * Request the DMA channel
*/
data->dma_chan = dma_request_chan(&pdev->dev, "data"); if (IS_ERR(data->dma_chan)) return PTR_ERR(data->dma_chan);
ret = dmaengine_slave_config(data->dma_chan, &config); if (ret < 0) {
dev_err(&pdev->dev, "dma configuration failed: %d\n", ret); return ret;
}
/* * Activate the ATA host
*/
ret = ata_host_activate(host, irq, ata_sff_interrupt,
pdata->irq_flags, &pxa_ata_sht); if (ret)
dma_release_channel(data->dma_chan);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.