Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 257711 Details for
Bug 344851
[firewire] juju stack lacks full support for ohci 1.0 controllers
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
FireWire OHCI 1.0 Iso Receive support patch
linux-2.6-firewire-ohci-1_0-iso-receive.patch (text/plain), 6.92 KB, created by
Jarod Wilson
on 2007-11-14 05:43:05 UTC
(
hide
)
Description:
FireWire OHCI 1.0 Iso Receive support patch
Filename:
MIME Type:
Creator:
Jarod Wilson
Created:
2007-11-14 05:43:05 UTC
Size:
6.92 KB
patch
obsolete
>diff -Naurp linux-2.6.23.noarch/drivers/firewire/fw-ohci.c linux-2.6.23.noarch.fw/drivers/firewire/fw-ohci.c >--- linux-2.6.23.noarch/drivers/firewire/fw-ohci.c 2007-10-09 16:31:38.000000000 -0400 >+++ linux-2.6.23.noarch.fw/drivers/firewire/fw-ohci.c 2007-11-13 23:13:49.000000000 -0500 >@@ -71,6 +71,14 @@ struct db_descriptor { > __le32 reserved1; > } __attribute__((aligned(16))); > >+struct packet_per_buffer_ctx { >+ /* the userspace buffer is */ >+ u64 buffer; >+ /* ofset into userspace buffer where >+ * data should go. 0 to append */ >+ u32 data_start; >+}; >+ > #define CONTROL_SET(regs) (regs) > #define CONTROL_CLEAR(regs) ((regs) + 4) > #define COMMAND_PTR(regs) ((regs) + 12) >@@ -125,6 +133,9 @@ struct iso_context { > struct context context; > void *header; > size_t header_length; >+ /* The address of the buffer we're using */ >+ struct fw_iso_buffer *iso_buffer; >+ u32 data_start; > }; > > #define CONFIG_ROM_SIZE 1024 >@@ -1403,6 +1414,66 @@ static int handle_ir_dualbuffer_packet(s > return 1; > } > >+static int handle_ir_packet_per_buffer(struct context *context, >+ struct descriptor *d, >+ struct descriptor *last) >+{ >+ struct iso_context *ctx = >+ container_of(context, struct iso_context, context); >+ struct page **pages = ctx->iso_buffer->pages; >+ void *p; >+ u32 length, rest, offset; >+ int page, i, timestamp; >+ struct packet_per_buffer_ctx *ppbc; >+ struct device *dev = context->ohci->card.device; >+ >+ if (d->res_count == d->req_count) >+ /* This descriptor isn't done yet, stop iteration. */ >+ return 0; >+ >+ dma_unmap_single(dev, le32_to_cpu(d->data_address), >+ le16_to_cpu(d->req_count), DMA_FROM_DEVICE); >+ >+ ppbc = (struct packet_per_buffer_ctx *) (d + 1); >+ p = (void *) ppbc->buffer; >+ timestamp = le32_to_cpu(* (__le32 *) p) & 0xffff; >+ i = ctx->header_length; >+ *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4)); >+ memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4); >+ ctx->header_length += ctx->base.header_size; >+ >+ if (ppbc->data_start != 0) >+ ctx->data_start = ppbc->data_start; >+ page = ctx->data_start >> PAGE_SHIFT; >+ offset = ctx->data_start & ~PAGE_MASK; >+ rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count) - >+ ctx->base.header_size - 4; >+ p += ctx->base.header_size + 4; >+ >+ while (rest > 0) { >+ if (offset + rest < PAGE_SIZE) >+ length = rest; >+ else >+ length = PAGE_SIZE - offset; >+ >+ memcpy(page_address(pages[page]) + offset, p, length); >+ offset = (offset + length) & ~PAGE_MASK; >+ page++; >+ rest -= length; >+ } >+ >+ if (le16_to_cpu(d->control) & DESCRIPTOR_IRQ_ALWAYS) { >+ ctx->base.callback(&ctx->base, timestamp, >+ ctx->header_length, ctx->header, >+ ctx->base.callback_data); >+ ctx->header_length = 0; >+ } >+ >+ kfree((void *) (unsigned long) ppbc->buffer); >+ >+ return 1; >+} >+ > static int handle_it_packet(struct context *context, > struct descriptor *d, > struct descriptor *last) >@@ -1438,14 +1509,12 @@ ohci_allocate_iso_context(struct fw_card > } else { > mask = &ohci->ir_context_mask; > list = ohci->ir_context_list; >- callback = handle_ir_dualbuffer_packet; >+ if (ohci->version >= OHCI_VERSION_1_1) >+ callback = handle_ir_dualbuffer_packet; >+ else >+ callback = handle_ir_packet_per_buffer; > } > >- /* FIXME: We need a fallback for pre 1.1 OHCI. */ >- if (callback == handle_ir_dualbuffer_packet && >- ohci->version < OHCI_VERSION_1_1) >- return ERR_PTR(-EINVAL); >- > spin_lock_irqsave(&ohci->lock, flags); > index = ffs(*mask) - 1; > if (index >= 0) >@@ -1504,7 +1573,9 @@ static int ohci_start_iso(struct fw_iso_ > context_run(&ctx->context, match); > } else { > index = ctx - ohci->ir_context_list; >- control = IR_CONTEXT_DUAL_BUFFER_MODE | IR_CONTEXT_ISOCH_HEADER; >+ control = IR_CONTEXT_ISOCH_HEADER; >+ if (ohci->version >= OHCI_VERSION_1_1) >+ control |= IR_CONTEXT_DUAL_BUFFER_MODE; > match = (tags << 28) | (sync << 8) | ctx->base.channel; > if (cycle >= 0) { > match |= (cycle & 0x07fff) << 12; >@@ -1710,7 +1781,6 @@ ohci_queue_iso_receive_dualbuffer(struct > offset = payload & ~PAGE_MASK; > rest = p->payload_length; > >- /* FIXME: OHCI 1.0 doesn't support dual buffer receive */ > /* FIXME: make packet-per-buffer/dual-buffer a context option */ > while (rest > 0) { > d = context_get_descriptors(&ctx->context, >@@ -1749,6 +1819,93 @@ ohci_queue_iso_receive_dualbuffer(struct > } > > static int >+ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, >+ struct fw_iso_packet *packet, >+ struct fw_iso_buffer *buffer, >+ unsigned long payload) >+{ >+ struct iso_context *ctx = container_of(base, struct iso_context, base); >+ struct descriptor *d = NULL; >+ struct fw_iso_packet *p; >+ void *tmpbuf; >+ dma_addr_t d_bus, tmpbuf_bus; >+ u32 z, length; >+ int i, packet_count, header_size; >+ >+ struct context *context = &ctx->context; >+ struct device *dev = context->ohci->card.device; >+ struct packet_per_buffer_ctx *ppbc; >+ >+ /* save iso_buffer pointer for packet handling later */ >+ ctx->iso_buffer = buffer; >+ >+ z = 1; >+ >+ if (packet->skip) { >+ d = context_get_descriptors(&ctx->context, z, &d_bus); >+ if (d == NULL) >+ return -ENOMEM; >+ >+ d->control = cpu_to_le16(DESCRIPTOR_STATUS | >+ DESCRIPTOR_INPUT_LAST | >+ DESCRIPTOR_BRANCH_ALWAYS | >+ DESCRIPTOR_WAIT); >+ context_append(&ctx->context, d, z, 0); >+ } >+ >+ p = packet; >+ >+ /* >+ * The OHCI controller puts the status word in the >+ * buffer too, so we need 4 extra bytes per packet. >+ */ >+ packet_count = p->header_length / ctx->base.header_size; >+ header_size = packet_count * (ctx->base.header_size + 4); >+ >+ for (i = 0; i < packet_count; i++) { >+ d = context_get_descriptors(&ctx->context, z + 1, &d_bus); >+ if (d == NULL) >+ return -ENOMEM; >+ >+ d->control = cpu_to_le16(DESCRIPTOR_STATUS | >+ DESCRIPTOR_INPUT_LAST | >+ DESCRIPTOR_BRANCH_ALWAYS); >+ >+ length = p->payload_length + header_size; >+ >+ tmpbuf = kmalloc(length, GFP_KERNEL); >+ if (tmpbuf == NULL) >+ return -ENOMEM; >+ >+ d->req_count = cpu_to_le16(length); >+ d->res_count = d->req_count; >+ >+ tmpbuf_bus = dma_map_single(dev, tmpbuf, >+ length, DMA_FROM_DEVICE); >+ if (dma_mapping_error(tmpbuf_bus)) { >+ kfree(tmpbuf); >+ return -ENOMEM; >+ } >+ >+ d->data_address = cpu_to_le32(tmpbuf_bus); >+ >+ ppbc = (struct packet_per_buffer_ctx *) (d + 1); >+ if (i == 0) >+ ppbc->data_start = payload; >+ else >+ ppbc->data_start = 0; >+ ppbc->buffer = (unsigned long) tmpbuf; >+ >+ context_append(&ctx->context, d, z, 1); >+ } >+ >+ if (p->interrupt) >+ d->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS); >+ >+ return 0; >+} >+ >+static int > ohci_queue_iso(struct fw_iso_context *base, > struct fw_iso_packet *packet, > struct fw_iso_buffer *buffer, >@@ -1762,8 +1919,9 @@ ohci_queue_iso(struct fw_iso_context *ba > return ohci_queue_iso_receive_dualbuffer(base, packet, > buffer, payload); > else >- /* FIXME: Implement fallback for OHCI 1.0 controllers. */ >- return -EINVAL; >+ return ohci_queue_iso_receive_packet_per_buffer(base, packet, >+ buffer, >+ payload); > } > > static const struct fw_card_driver ohci_driver = {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 344851
:
233701
|
257711
|
274231
|
274241
|
275941
|
275971