[git,pull] FireWire fix
diff mbox series

Message ID tkrat.c98ccacd8716c278@s5r6.in-berlin.de
State New, archived
Headers show
Series
  • [git,pull] FireWire fix
Related show

Commit Message

Stefan Richter Dec. 11, 2009, 8:59 p.m. UTC
Linus, please pull from the for-linus branch at

    git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git for-linus

to receive a FireWire subsystem fix.

Jay Fenlason (1):
      firewire: ohci: handle receive packets with a data length of zero

 drivers/firewire/ohci.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

Thanks.


commit 8c0c0cc2d9f4c523fde04bdfe41e4380dec8ee54
Author: Jay Fenlason <fenlason@redhat.com>
Date:   Fri Dec 11 14:23:58 2009 -0500

    firewire: ohci: handle receive packets with a data length of zero
    
    Queueing to receive an ISO packet with a payload length of zero
    silently does nothing in dualbuffer mode, and crashes the kernel in
    packet-per-buffer mode.  Return an error in dualbuffer mode, because
    the DMA controller won't let us do what we want, and work correctly in
    packet-per-buffer mode.
    
    Signed-off-by: Jay Fenlason <fenlason@redhat.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
    Cc: stable@kernel.org

Patch
diff mbox series

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index a714775..553c74e 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2189,6 +2189,13 @@  static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
 	page     = payload >> PAGE_SHIFT;
 	offset   = payload & ~PAGE_MASK;
 	rest     = p->payload_length;
+	/*
+	 * The controllers I've tested have not worked correctly when
+	 * second_req_count is zero.  Rather than do something we know won't
+	 * work, return an error
+	 */
+	if (rest == 0)
+		return -EINVAL;
 
 	/* FIXME: make packet-per-buffer/dual-buffer a context option */
 	while (rest > 0) {
@@ -2242,7 +2249,7 @@  static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
 					unsigned long payload)
 {
 	struct iso_context *ctx = container_of(base, struct iso_context, base);
-	struct descriptor *d = NULL, *pd = NULL;
+	struct descriptor *d, *pd;
 	struct fw_iso_packet *p = packet;
 	dma_addr_t d_bus, page_bus;
 	u32 z, header_z, rest;
@@ -2280,8 +2287,9 @@  static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
 		d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d)));
 
 		rest = payload_per_buffer;
+		pd = d;
 		for (j = 1; j < z; j++) {
-			pd = d + j;
+			pd++;
 			pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
 						  DESCRIPTOR_INPUT_MORE);