in ohci.c [3373:3427]
static int queue_iso_buffer_fill(struct iso_context *ctx,
struct fw_iso_packet *packet,
struct fw_iso_buffer *buffer,
unsigned long payload)
{
struct descriptor *d;
dma_addr_t d_bus, page_bus;
int page, offset, rest, z, i, length;
page = payload >> PAGE_SHIFT;
offset = payload & ~PAGE_MASK;
rest = packet->payload_length;
/* We need one descriptor for each page in the buffer. */
z = DIV_ROUND_UP(offset + rest, PAGE_SIZE);
if (WARN_ON(offset & 3 || rest & 3 || page + z > buffer->page_count))
return -EFAULT;
for (i = 0; i < z; i++) {
d = context_get_descriptors(&ctx->context, 1, &d_bus);
if (d == NULL)
return -ENOMEM;
d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
DESCRIPTOR_BRANCH_ALWAYS);
if (packet->skip && i == 0)
d->control |= cpu_to_le16(DESCRIPTOR_WAIT);
if (packet->interrupt && i == z - 1)
d->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS);
if (offset + rest < PAGE_SIZE)
length = rest;
else
length = PAGE_SIZE - offset;
d->req_count = cpu_to_le16(length);
d->res_count = d->req_count;
d->transfer_status = 0;
page_bus = page_private(buffer->pages[page]);
d->data_address = cpu_to_le32(page_bus + offset);
dma_sync_single_range_for_device(ctx->context.ohci->card.device,
page_bus, offset, length,
DMA_FROM_DEVICE);
rest -= length;
offset = 0;
page++;
context_append(&ctx->context, d, 1, 0);
}
return 0;
}