* [GIT PULL] FireWire update
@ 2007-12-10 21:25 Stefan Richter
[not found] ` <59ad55d30712110818u2717b329j80778ec7cc290988@mail.gmail.com>
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Richter @ 2007-12-10 21:25 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel
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 the following FireWire subsystem update.
This considerably enhances compatibility of the new firewire-ohci driver
with a number of controllers. It shrinks the list of chips with trouble
with isochronous reception to VIA VT6306 and some variants of VT6307.
The patch is somewhat big for this late -rc phase, and it has so far only
surfaced in 2.6.24-rc4-mm1 and in recent Fedora test kernels. But the
author and I did a lot of tests with as much previously working chips as
we could get our hands on (some more than listed below) to make sure that
there is no regression.
drivers/firewire/fw-ohci.c | 175 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 155 insertions(+), 20 deletions(-)
Jarod Wilson (1):
firewire: OHCI 1.0 Isochronous Receive support
Full log and diff:
commit a186b4a6b22fdc96a1ed63da483d267b5d00839e
Author: Jarod Wilson <jwilson@redhat.com>
Date: Mon Dec 3 13:43:12 2007 -0500
firewire: OHCI 1.0 Isochronous Receive support
Third rendition of FireWire OHCI 1.0 Isochronous Receive support, using a
zer-copy method similar to OHCI 1.1 which puts the IR data payload directly
into the userspace buffer. The zero-copy implementation eliminates the
video artifacts, audio popping, and buffer underrun problems seen with
version 1 of this patch, as well as fixing a regression in OHCI 1.1 support
introduced by version 2 of this patch.
Successfully tested in OHCI 1.1 mode on the following chipsets:
- NEC uPD72847 (rev 01), OHCI 1.1 (PCI)
- Ti XIO2200(A) (rev 01), OHCI 1.1 (PCIe)
- Ti TSB41AB2 (rev 01), OHCI 1.1 (PCI on SB Audigy)
- Apple UniNorth 2 (rev 81), OHCI 1.1 (PowerBook G4 onboard)
Successfully tested in OHCI 1.0 mode on the following chipsets:
- Agere FW323 (rev 06), OHCI 1.0 (Mac Mini onboard)
- Agere FW323 (rev 06), OHCI 1.0 (PCI)
- Via VT6306 (rev 46), OHCI 1.0 (PCI)
- NEC OrangeLink (rev 01), OHCI 1.0 (PCI)
- NEC uPD72847 (rev 01), OHCI 1.1 (PCI)
- Ti XIO2200(A) (rev 01), OHCI 1.1 (PCIe)
The bulk of testing was done in an x86_64 system, but was also successfully
sanity-tested on other systems, including a PPC(32) PowerBook G4 and an i686
EPIA M10k. Crude benchmarking (watching top during capture) puts the cpu
utilization during capture on the EPIA's 1GHz Via C3 processor around 13%,
which is down from 30% with the v1 code.
Some implementation details:
To maintain the same userspace API as dual-buffer mode, we set up two
descriptors for every incoming packet. The first is an INPUT_MORE descriptor,
pointing to a buffer large enough to hold just the packet's iso headers,
immediately followed by an INPUT_LAST descriptor, pointing to a chunk of the
userspace buffer big enough for the packet's data payload. With this setup,
each incoming packet fills in these two descriptors in a manner that very
closely emulates dual-buffer receive, to the point where the bulk of the
handle_ir_* code is now identical between the two (and probably primed for
some restructuring to share code between them).
The only caveat I have at the moment is that neither of my OHCI 1.0 Via
VT6307-based FireWire controllers work particularly well with this code
for reasons I have yet to figure out.
Signed-off-by: Jarod Wilson <jwilson@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index c9b9081..436a855 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -437,6 +437,21 @@ static void ar_context_run(struct ar_context *ctx)
flush_writes(ctx->ohci);
}
+static struct descriptor *
+find_branch_descriptor(struct descriptor *d, int z)
+{
+ int b, key;
+
+ b = (le16_to_cpu(d->control) & DESCRIPTOR_BRANCH_ALWAYS) >> 2;
+ key = (le16_to_cpu(d->control) & DESCRIPTOR_KEY_IMMEDIATE) >> 8;
+
+ /* figure out which descriptor the branch address goes in */
+ if (z == 2 && (b == 3 || key == 2))
+ return d;
+ else
+ return d + z - 1;
+}
+
static void context_tasklet(unsigned long data)
{
struct context *ctx = (struct context *) data;
@@ -455,7 +470,7 @@ static void context_tasklet(unsigned long data)
address = le32_to_cpu(last->branch_address);
z = address & 0xf;
d = ctx->buffer + (address - ctx->buffer_bus) / sizeof(*d);
- last = (z == 2) ? d : d + z - 1;
+ last = find_branch_descriptor(d, z);
if (!ctx->callback(ctx, d, last))
break;
@@ -566,7 +581,7 @@ static void context_append(struct context *ctx,
ctx->head_descriptor = d + z + extra;
ctx->prev_descriptor->branch_address = cpu_to_le32(d_bus | z);
- ctx->prev_descriptor = z == 2 ? d : d + z - 1;
+ ctx->prev_descriptor = find_branch_descriptor(d, z);
dma_sync_single_for_device(ctx->ohci->card.device, ctx->buffer_bus,
ctx->buffer_size, DMA_TO_DEVICE);
@@ -655,7 +670,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
driver_data = (struct driver_data *) &d[3];
driver_data->packet = packet;
packet->driver_data = driver_data;
-
+
if (packet->payload_length > 0) {
payload_bus =
dma_map_single(ohci->card.device, packet->payload,
@@ -903,7 +918,7 @@ at_context_transmit(struct context *ctx, struct fw_packet *packet)
if (retval < 0)
packet->callback(packet, &ctx->ohci->card, packet->ack);
-
+
}
static void bus_reset_tasklet(unsigned long data)
@@ -1431,6 +1446,57 @@ static int handle_ir_dualbuffer_packet(struct context *context,
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 descriptor *pd = d + 1;
+ __le32 *ir_header;
+ size_t header_length;
+ void *p, *end;
+ int i, z;
+
+ if (pd->res_count == pd->req_count)
+ /* Descriptor(s) not done yet, stop iteration */
+ return 0;
+
+ header_length = le16_to_cpu(d->req_count);
+
+ i = ctx->header_length;
+ z = le32_to_cpu(pd->branch_address) & 0xf;
+ p = d + z;
+ end = p + header_length;
+
+ while (p < end && i + ctx->base.header_size <= PAGE_SIZE) {
+ /*
+ * The iso header is byteswapped to little endian by
+ * the controller, but the remaining header quadlets
+ * are big endian. We want to present all the headers
+ * as big endian, so we have to swap the first quadlet.
+ */
+ *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
+ memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
+ i += ctx->base.header_size;
+ p += ctx->base.header_size + 4;
+ }
+
+ ctx->header_length = i;
+
+ if (le16_to_cpu(pd->control) & DESCRIPTOR_IRQ_ALWAYS) {
+ ir_header = (__le32 *) (d + z);
+ ctx->base.callback(&ctx->base,
+ le32_to_cpu(ir_header[0]) & 0xffff,
+ ctx->header_length, ctx->header,
+ ctx->base.callback_data);
+ ctx->header_length = 0;
+ }
+
+
+ return 1;
+}
+
static int handle_it_packet(struct context *context,
struct descriptor *d,
struct descriptor *last)
@@ -1466,14 +1532,12 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
} 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(-ENOSYS);
-
spin_lock_irqsave(&ohci->lock, flags);
index = ffs(*mask) - 1;
if (index >= 0)
@@ -1532,7 +1596,9 @@ static int ohci_start_iso(struct fw_iso_context *base,
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;
@@ -1738,7 +1804,6 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
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,
@@ -1777,6 +1842,81 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
}
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, *pd = NULL;
+ struct fw_iso_packet *p;
+ dma_addr_t d_bus, page_bus;
+ u32 z, header_z, rest;
+ int i, page, offset, packet_count, header_size;
+
+ if (packet->skip) {
+ d = context_get_descriptors(&ctx->context, 1, &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, 1, 0);
+ }
+
+ /* one descriptor for header, one for payload */
+ /* FIXME: handle cases where we need multiple desc. for payload */
+ z = 2;
+ 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);
+
+ /* Get header size in number of descriptors. */
+ header_z = DIV_ROUND_UP(header_size, sizeof(*d));
+ page = payload >> PAGE_SHIFT;
+ offset = payload & ~PAGE_MASK;
+ rest = p->payload_length;
+
+ for (i = 0; i < packet_count; i++) {
+ /* d points to the header descriptor */
+ d = context_get_descriptors(&ctx->context,
+ z + header_z, &d_bus);
+ if (d == NULL)
+ return -ENOMEM;
+
+ d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE);
+ d->req_count = cpu_to_le16(header_size);
+ d->res_count = d->req_count;
+ d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d)));
+
+ /* pd points to the payload descriptor */
+ pd = d + 1;
+ pd->control = cpu_to_le16(DESCRIPTOR_STATUS |
+ DESCRIPTOR_INPUT_LAST |
+ DESCRIPTOR_BRANCH_ALWAYS);
+ if (p->interrupt)
+ pd->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS);
+
+ pd->req_count = cpu_to_le16(rest);
+ pd->res_count = pd->req_count;
+
+ page_bus = page_private(buffer->pages[page]);
+ pd->data_address = cpu_to_le32(page_bus + offset);
+
+ context_append(&ctx->context, d, z, header_z);
+ }
+
+ return 0;
+}
+
+static int
ohci_queue_iso(struct fw_iso_context *base,
struct fw_iso_packet *packet,
struct fw_iso_buffer *buffer,
@@ -1790,8 +1930,9 @@ ohci_queue_iso(struct fw_iso_context *base,
return ohci_queue_iso_receive_dualbuffer(base, packet,
buffer, payload);
else
- /* FIXME: Implement fallback for OHCI 1.0 controllers. */
- return -ENOSYS;
+ return ohci_queue_iso_receive_packet_per_buffer(base, packet,
+ buffer,
+ payload);
}
static const struct fw_card_driver ohci_driver = {
@@ -1911,12 +2052,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff);
- if (ohci->version < OHCI_VERSION_1_1) {
- fw_notify(" Isochronous I/O is not yet implemented for "
- "OHCI 1.0 chips.\n");
- fw_notify(" Cameras, audio devices etc. won't work on "
- "this controller with this driver version.\n");
- }
return 0;
fail_self_id:
--
Stefan Richter
-=====-=-=== ==-- -=-=-
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [GIT PULL] FireWire update
[not found] ` <59ad55d30712110818u2717b329j80778ec7cc290988@mail.gmail.com>
@ 2007-12-11 17:40 ` Stefan Richter
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Richter @ 2007-12-11 17:40 UTC (permalink / raw)
To: Kristian Høgsberg
Cc: Linus Torvalds, Andrew Morton, linux1394-devel, linux-kernel
Kristian Høgsberg wrote:
> On Dec 10, 2007 4:25 PM, Stefan Richter <stefanr@s5r6.in-berlin.de> wrote:
>> This considerably enhances compatibility of the new firewire-ohci driver
...
> And I worked with Jarod on this so I'll add a
>
> Signed-off-by: Kristian Høgsberg <krh@redhat.com>
The commit already went public; nevertheless I much appreciate the
sign-off and your work on the OHCI 1.0 issue. Thanks.
--
Stefan Richter
-=====-=-=== ==-- -=-==
http://arcgraph.de/sr/
^ permalink raw reply [flat|nested] 9+ messages in thread
* [git pull] FireWire update
@ 2011-07-11 13:42 Stefan Richter
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Richter @ 2011-07-11 13:42 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel
Linus, please pull from the movieboard branch at
git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git movieboard
to receive the following quirks workaround for the IEEE 1394 (FireWire)
subsystem. This is a hopefully temporary bandaid for a comparably rare
piece of hardware.
Thanks.
Stefan Richter (1):
firewire: ohci: do not bind to Pinnacle cards, avert panic
drivers/firewire/ohci.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
commit 7f7e37115a8b6724f26d0637a04e1d35e3c59717
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date: Sun Jul 10 00:23:03 2011 +0200
firewire: ohci: do not bind to Pinnacle cards, avert panic
When firewire-ohci is bound to a Pinnacle MovieBoard, eventually a
"Register access failure" is logged and an interrupt storm or a kernel
panic happens. https://bugzilla.kernel.org/show_bug.cgi?id=36622
Until this is sorted out (if that is going to succeed at all), let's
just prevent firewire-ohci from touching these devices.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: <stable@kernel.org>
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 438e6c8..ebb8973 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -264,6 +264,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
+#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
#define QUIRK_CYCLE_TIMER 1
#define QUIRK_RESET_PACKET 2
@@ -3190,6 +3191,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
int i, err;
size_t size;
+ if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) {
+ dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n");
+ return -ENOSYS;
+ }
+
ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
if (ohci == NULL) {
err = -ENOMEM;
--
Stefan Richter
-=====-==-== -=== -=-==
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [GIT PULL] firewire update
@ 2008-06-27 19:05 Stefan Richter
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Richter @ 2008-06-27 19:05 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel
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 the following one-liner.
Richard Sharpe (1):
firewire: fw-sbp2: fix parsing of logical unit directories
drivers/firewire/fw-sbp2.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
commit 0e3e2eabf4fbc0162e1f1eb4fd90cb3e9513a554
Author: Richard Sharpe <realrichardsharpe@gmail.com>
Date: Tue Jun 24 19:11:13 2008 -0700
firewire: fw-sbp2: fix parsing of logical unit directories
There is a small off-by-one bug in firewire-sbp2. This causes problems
when a device exports multiple LUN Directories. I found it when trying
to talk to a SONY DVD Jukebox.
Signed-off-by: Richard Sharpe <realrichardsharpe@gmail.com>
Acked-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (op. order, changelog)
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index b2458bb..227d2e0 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -1051,7 +1051,8 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
break;
case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
- if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0)
+ /* Adjust for the increment in the iterator */
+ if (sbp2_scan_logical_unit_dir(tgt, ci.p - 1 + value) < 0)
return -ENOMEM;
break;
}
--
Stefan Richter
-=====-==--- -==- ==-==
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [GIT PULL] FireWire update
2008-03-27 20:37 ` Stefan Richter
@ 2008-03-31 8:46 ` Stefan Richter
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Richter @ 2008-03-31 8:46 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel
I wrote:
> 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 the following update for the firewire subsystem.
>
> drivers/firewire/fw-ohci.c | 9 +++++----
> 1 files changed, 5 insertions(+), 4 deletions(-)
>
> Jarod Wilson (1):
> firewire: fw-ohci: plug dma memory leak in AR handler
Ping.
This stops firewire-ohci from feeding random arguments to
dma_free_coherent().
--
Stefan Richter
-=====-==--- --== =====
http://arcgraph.de/sr/
^ permalink raw reply [flat|nested] 9+ messages in thread
* [GIT PULL] FireWire update
2008-03-20 17:28 ` [GIT PULL] FireWire update Stefan Richter
@ 2008-03-27 20:37 ` Stefan Richter
2008-03-31 8:46 ` Stefan Richter
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Richter @ 2008-03-27 20:37 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel
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 the following update for the firewire subsystem.
drivers/firewire/fw-ohci.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
Jarod Wilson (1):
firewire: fw-ohci: plug dma memory leak in AR handler
commit 6b84236d37ef602d1e4f52b27162c20394e83359
Author: Jarod Wilson <jwilson@redhat.com>
Date: Tue Mar 25 16:47:16 2008 -0400
firewire: fw-ohci: plug dma memory leak in AR handler
There's an ugly little memory leak in firewire-ohci's
ar_context_tasklet(), where we're not freeing up some of the memory we
use for each ar_buffer, due to a moving pointer. The problem has been
there for a while, but didn't get noticed until after converting the AR
routines over to use coherent DMA and I started running into I/O stall-
outs with the following message output repeatedly to the console:
PCI-DMA: Out of IOMMU space for 53248 bytes at device 0000:04:09.0
Plugging this leak is definitely necessary, but unfortunately, isn't the
entire answer to my problem, it only increases the amount of I/O that I
can do before hitting the problem. Still working on tracking down the
root cause..
Signed-off-by: Jarod Wilson <jwilson@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 996d61f..ca6d51e 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -401,7 +401,8 @@ static void ar_context_tasklet(unsigned long data)
if (d->res_count == 0) {
size_t size, rest, offset;
- dma_addr_t buffer_bus;
+ dma_addr_t start_bus;
+ void *start;
/*
* This descriptor is finished and we may have a
@@ -410,9 +411,9 @@ static void ar_context_tasklet(unsigned long data)
*/
offset = offsetof(struct ar_buffer, data);
- buffer_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
+ start = buffer = ab;
+ start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
- buffer = ab;
ab = ab->next;
d = &ab->descriptor;
size = buffer + PAGE_SIZE - ctx->pointer;
@@ -427,7 +428,7 @@ static void ar_context_tasklet(unsigned long data)
buffer = handle_ar_packet(ctx, buffer);
dma_free_coherent(ohci->card.device, PAGE_SIZE,
- buffer, buffer_bus);
+ start, start_bus);
ar_context_add_page(ctx);
} else {
buffer = ctx->pointer;
Thanks,
--
Stefan Richter
-=====-==--- --== ==-==
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [GIT PULL] FireWire update
2008-03-14 18:07 ` Stefan Richter
@ 2008-03-20 17:28 ` Stefan Richter
2008-03-27 20:37 ` Stefan Richter
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Richter @ 2008-03-20 17:28 UTC (permalink / raw)
To: Linus Torvalds, Andrew Morton; +Cc: linux-kernel, linux1394-devel
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 the following update for the firewire subsystem.
drivers/firewire/fw-transaction.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
Stefan Richter (1):
firewire: fix panic in handle_at_packet
commit 10a4c735515a5afc317abe4d697a4c95f6d9d764
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date: Sun Mar 16 00:56:41 2008 +0100
firewire: fix panic in handle_at_packet
This fixes a use-after-free bug in the handling of split transactions.
The AT DMA handler of the request was occasionally executed after the
AR DMA handler of the response. The AT DMA handler then accessed an
already freed packet.
Reported by Johannes Berg.
http://bugzilla.kernel.org/show_bug.cgi?id=9617
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Tested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Jarod Wilson <jwilson@redhat.com>
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 99529e5..e6f1bda 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -736,6 +736,12 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
break;
}
+ /*
+ * The response handler may be executed while the request handler
+ * is still pending. Cancel the request handler.
+ */
+ card->driver->cancel_packet(card, &t->packet);
+
t->callback(card, rcode, data, data_length, t->callback_data);
}
EXPORT_SYMBOL(fw_core_handle_response);
Thanks,
--
Stefan Richter
-=====-==--- --== =-=--
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [GIT PULL] FireWire update
@ 2007-11-07 1:20 Stefan Richter
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Richter @ 2007-11-07 1:20 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel
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 the following fix for a regression since 2.6.24-rc1.
(Or apply from this e-mail.)
drivers/firewire/fw-sbp2.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
Stefan Richter (1):
firewire: fw-sbp2: fix refcounting
Full log and diff:
commit 7c45d1913f0a1d597eb4bc3b2c962bc2967da9ea
Author: Stefan Richter <stefanr@s5r6.in-berlin.de>
Date: Wed Nov 7 01:11:56 2007 +0100
firewire: fw-sbp2: fix refcounting
Since patch "fw-sbp2: use an own workqueue (fix system responsiveness)"
increased parallelism between fw-sbp2 and fw-core, it was possible that
fw-sbp2 didn't release the SCSI device when the FireWire device was
disconnected.
This happened if sbp2_update() ran during sbp2_login(), because a bus
reset occurred during sbp2_login(). The sbp2_login() work would [try
to] reschedule itself because it failed due to the bus reset, and it
would _not_ drop its reference on the target. However, sbp2_update()
would schedule sbp2_login() too before sbp2_login() rescheduled itself
and hence sbp2_update() would take an additional reference. And then
we would have one reference too many.
The fix is to _always_ drop the reference when leaving the sbp2_login()
work. If the sbp2_login() work reschedules itself, it takes a
reference, but only if it wasn't already rescheduled by sbp2_update().
Ditto in the sbp2_reconnect() work.
The resulting code is actually simpler than before: We _always_ take
a reference when successfully scheduling work. And we _always_ drop
a reference when leaving a workqueue job. No exceptions.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 5596df6..624ff3e 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -650,13 +650,14 @@ static void sbp2_login(struct work_struct *work)
if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
if (lu->retries++ < 5) {
- queue_delayed_work(sbp2_wq, &lu->work,
- DIV_ROUND_UP(HZ, 5));
+ if (queue_delayed_work(sbp2_wq, &lu->work,
+ DIV_ROUND_UP(HZ, 5)))
+ kref_get(&lu->tgt->kref);
} else {
fw_error("failed to login to %s LUN %04x\n",
unit->device.bus_id, lu->lun);
- kref_put(&lu->tgt->kref, sbp2_release_target);
}
+ kref_put(&lu->tgt->kref, sbp2_release_target);
return;
}
@@ -914,7 +915,9 @@ static void sbp2_reconnect(struct work_struct *work)
lu->retries = 0;
PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
}
- queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5));
+ if (queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5)))
+ kref_get(&lu->tgt->kref);
+ kref_put(&lu->tgt->kref, sbp2_release_target);
return;
}
--
Stefan Richter
-=====-=-=== =-== --===
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [GIT PULL] FireWire update
@ 2007-11-04 13:41 Stefan Richter
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Richter @ 2007-11-04 13:41 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, linux1394-devel
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 the following IEEE 1394 subsystem update.
This fixes "2.6.24-rc1-54866.. fails to boot: kernel BUG at
include/linux/scatterlist.h:49!", bug# 9296.
drivers/ieee1394/dma.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
Jens Axboe (1):
ieee1394: iso and async streams: s/g list fix
Full log and diff:
commit 9e66269d40229cd9823024120910a43af57a9d72
Author: Jens Axboe <jens.axboe@oracle.com>
Date: Sun Nov 4 09:44:56 2007 +0100
ieee1394: iso and async streams: s/g list fix
Torsten Kaiser wrote:
> Looking that calltrace upwards, it seems replacing the
> memset(dma->sglist,...) with sg_init_table(...) would fix the BUG_ON()
> as that inits the SG_MAGIC.
Tested-by: Torsten Kaiser <just.for.lkml@googlemail.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index f5f4983..7c4eb39 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -103,8 +103,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
goto err;
}
- /* just to be safe - this will become unnecessary once sglist->address goes away */
- memset(dma->sglist, 0, dma->n_pages * sizeof(*dma->sglist));
+ sg_init_table(dma->sglist, dma->n_pages);
/* fill scatter/gather list with pages */
for (i = 0; i < dma->n_pages; i++) {
--
Stefan Richter
-=====-=-=== =-== --=--
http://arcgraph.de/sr/
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-07-11 13:43 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-10 21:25 [GIT PULL] FireWire update Stefan Richter
[not found] ` <59ad55d30712110818u2717b329j80778ec7cc290988@mail.gmail.com>
2007-12-11 17:40 ` Stefan Richter
-- strict thread matches above, loose matches on Subject: below --
2011-07-11 13:42 [git pull] " Stefan Richter
2008-06-27 19:05 [GIT PULL] firewire update Stefan Richter
2008-01-30 22:53 [GIT PULL] FireWire updates post 2.6.24 Stefan Richter
2008-02-02 13:05 ` [GIT PULL] IEEE 1394 regression fix Stefan Richter
2008-02-25 17:58 ` [GIT PULL] FireWire updates Stefan Richter
2008-03-02 12:47 ` Stefan Richter
2008-03-14 18:07 ` Stefan Richter
2008-03-20 17:28 ` [GIT PULL] FireWire update Stefan Richter
2008-03-27 20:37 ` Stefan Richter
2008-03-31 8:46 ` Stefan Richter
2007-11-07 1:20 Stefan Richter
2007-11-04 13:41 Stefan Richter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).