Date: Fri, 11 Dec 2009 14:23:58 -0500 From: Jay Fenlason Subject: 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 Signed-off-by: Stefan Richter Cc: stable@kernel.org --- drivers/firewire/ohci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) Index: linux-2.6.32/drivers/firewire/ohci.c =================================================================== --- linux-2.6.32.orig/drivers/firewire/ohci.c +++ linux-2.6.32/drivers/firewire/ohci.c @@ -2218,6 +2218,13 @@ static int ohci_queue_iso_receive_dualbu 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) { @@ -2271,7 +2278,7 @@ static int ohci_queue_iso_receive_packet 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; @@ -2309,8 +2316,9 @@ static int ohci_queue_iso_receive_packet 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);