rpms/kernel/F-7 linux-2.6-firewire-ohci-1.0-iso-receive.patch, NONE, 1.1 kernel-2.6.spec, 1.3379, 1.3380
Jarod Wilson (jwilson)
fedora-extras-commits at redhat.com
Wed Nov 14 23:20:42 UTC 2007
- Previous message (by thread): rpms/olpc-utils/OLPC-2 .cvsignore,1.9,1.10 sources,1.10,1.11
- Next message (by thread): rpms/telepathy-haze/devel .cvsignore, 1.2, 1.3 sources, 1.2, 1.3 telepathy-haze.spec, 1.2, 1.3 telepathy-haze-fix-deprecated-tp_debug-call.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: jwilson
Update of /cvs/pkgs/rpms/kernel/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv1045
Modified Files:
kernel-2.6.spec
Added Files:
linux-2.6-firewire-ohci-1.0-iso-receive.patch
Log Message:
* Wed Nov 14 2007 Jarod Wilson <jwilson at redhat.com>
- Initial FireWire OHCI 1.0 Isochronous Receive support (#344851)
linux-2.6-firewire-ohci-1.0-iso-receive.patch:
--- NEW FILE linux-2.6-firewire-ohci-1.0-iso-receive.patch ---
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-14 17:41:26.000000000 -0500
@@ -71,6 +71,13 @@ struct db_descriptor {
__le32 reserved1;
} __attribute__((aligned(16)));
+struct ppb_context {
+ /* the userspace buffer */
+ u64 buffer;
+ /* ofset into userspace buffer to put data, 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 +132,8 @@ struct iso_context {
struct context context;
void *header;
size_t header_length;
+ struct fw_iso_buffer *iso_buffer;
+ u32 data_start;
};
#define CONFIG_ROM_SIZE 1024
@@ -1403,6 +1412,69 @@ 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;
+ struct device *dev = context->ohci->card.device;
+ struct ppb_context *ppbc;
+ void *p;
+ u32 length, rest, offset;
+ int i, page, timestamp;
+
+ 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 ppb_context *) (d + 1);
+ p = (void *) ppbc->buffer;
+ timestamp = le32_to_cpu(* (__le32 *) p) & 0xffff;
+ i = ctx->header_length;
+
+ /* Put properly formatted headers where they belong */
+ *(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;
+
+ /* Put data payload where it belongs */
+ 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 +1510,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 +1574,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 +1782,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 +1820,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 ppb_context *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 ppb_context *) (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 +1920,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 = {
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-7/kernel-2.6.spec,v
retrieving revision 1.3379
retrieving revision 1.3380
diff -u -r1.3379 -r1.3380
--- kernel-2.6.spec 12 Nov 2007 22:00:38 -0000 1.3379
+++ kernel-2.6.spec 14 Nov 2007 23:20:07 -0000 1.3380
@@ -627,6 +627,7 @@
Patch750: linux-2.6-firewire-multi-lun.patch
Patch751: linux-2.6-firewire-lockdep.patch
+Patch752: linux-2.6-firewire-ohci-1.0-iso-receive.patch
Patch770: linux-2.6-acpi-sleep-fix-GPE-suspend-cleanup.patch
Patch771: linux-2.6-acpi-suspend-wrong-order-of-GPE-restore.patch
@@ -1343,6 +1344,7 @@
#
ApplyPatch linux-2.6-firewire-multi-lun.patch
ApplyPatch linux-2.6-firewire-lockdep.patch
+ApplyPatch linux-2.6-firewire-ohci-1.0-iso-receive.patch
# USB
#
@@ -2309,6 +2311,9 @@
%endif
%changelog
+* Wed Nov 14 2007 Jarod Wilson <jwilson at redhat.com>
+- Initial FireWire OHCI 1.0 Isochronous Receive support (#344851)
+
* Mon Nov 12 2007 Chuck Ebbert <cebbert at redhat.com>
- Disable USB autosuspend by default.
- Fix oops in CIFS when mounting a filesystem a second time.
- Previous message (by thread): rpms/olpc-utils/OLPC-2 .cvsignore,1.9,1.10 sources,1.10,1.11
- Next message (by thread): rpms/telepathy-haze/devel .cvsignore, 1.2, 1.3 sources, 1.2, 1.3 telepathy-haze.spec, 1.2, 1.3 telepathy-haze-fix-deprecated-tp_debug-call.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list