aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorAndy Leiserson <andy@leiserson.org>2013-04-24 12:10:32 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2013-04-28 17:36:44 -0400
commitbe8dcab942e1c0ec2aa13eb2af2a79ab51b46293 (patch)
treed5f1ec9ebb15860df7ca0e4fb8e5eb07a0e20277 /drivers/firewire
parent8db491490b88c8b016b41ad56ac980c4cbb06d7a (diff)
firewire: ohci: fix VIA VT6306 video reception
Add quirk for VT6306 wake bit behavior. VT6306 seems to reread the wrong descriptor when the wake bit is written. work around by putting a copy of the branch address in the first descriptor of the block. [Stefan R: This fixes the known broken video reception via gstreamer on VIA VT6306. 100% repeatable testcase: $ gst-launch-0.10 dv1394src \! dvdemux \! dvdec \! xvimagesink with a camcorder or other DV source connected. Likewise for MPEG2-TS reception via gstreamer, e.g. from TV settop boxes. Perhaps this also fixes dv4l on VT6306, but this is as yet untested. Kino, dvgrab or FFADO had not been affected by this chip quirk. Additional comments from Andy:] I've looked into some problems with the wake bit on a vt6306 family chip (1106:3044, rev 46). I used this firewire card in a mythtv setup (ISO receive MPEG2 stream) with Debian 2.6.32 kernels for ~2 years without problems. Since upgrading to 3.2, I've been having problems with the input stream freezing -- input data stops until I restart mythtv (I expect closing and reopening the device would be sufficient). This happens infrequently, maybe one out of 20 recordings. I eventually determined that the problem is more likely to occur if the system is loaded. I isolated the kernel version as the triggering SW factor and then specifically the change from dualbuffer back to packet-per-buffer DMA mode. The possibility that the controller does not properly respond to the wake bit was suggested in https://bugzilla.redhat.com/show_bug.cgi?id=415841, but not proven. Based on the fact that dualbuffer mode worked while packet-per-buffer has trouble, I guessed that upon seeing the wake bit written, the vt6306 controller only checks the branch address in the first descriptor of the block, even if that is not the correct place to look (because the block has multiple descriptors). This theory seems to be correct. When the ISO reception is hung, I am able to resume it by manually writing the branch address to the first descriptor in the block, and then writing the wake bit. I've had luck so far with the attached patch, so I'm including it. It's probably not a complete solution -- I haven't tested transmit modes to see whether they have a similar issue. I doubt that the quirk test is any cheaper than just writing the extra branch address in all cases, but it does reduce the risk of breaking other hardware. [Stefan R: omitted QUIRK_NO_MSI from VT6306 quirks table entry, changed whitespace] Signed-off-by: Andy Leiserson <andy@leiserson.org> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/ohci.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 673c8970749e..a309d89f4df7 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -68,6 +68,8 @@
68#define DESCRIPTOR_BRANCH_ALWAYS (3 << 2) 68#define DESCRIPTOR_BRANCH_ALWAYS (3 << 2)
69#define DESCRIPTOR_WAIT (3 << 0) 69#define DESCRIPTOR_WAIT (3 << 0)
70 70
71#define DESCRIPTOR_CMD (0xf << 12)
72
71struct descriptor { 73struct descriptor {
72 __le16 req_count; 74 __le16 req_count;
73 __le16 control; 75 __le16 control;
@@ -149,10 +151,11 @@ struct context {
149 struct descriptor *last; 151 struct descriptor *last;
150 152
151 /* 153 /*
152 * The last descriptor in the DMA program. It contains the branch 154 * The last descriptor block in the DMA program. It contains the branch
153 * address that must be updated upon appending a new descriptor. 155 * address that must be updated upon appending a new descriptor.
154 */ 156 */
155 struct descriptor *prev; 157 struct descriptor *prev;
158 int prev_z;
156 159
157 descriptor_callback_t callback; 160 descriptor_callback_t callback;
158 161
@@ -270,7 +273,9 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
270#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 273#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
271#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020 274#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
272#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025 275#define PCI_DEVICE_ID_TI_TSB82AA2 0x8025
276#define PCI_DEVICE_ID_VIA_VT630X 0x3044
273#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd 277#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
278#define PCI_REV_ID_VIA_VT6306 0x46
274 279
275#define QUIRK_CYCLE_TIMER 1 280#define QUIRK_CYCLE_TIMER 1
276#define QUIRK_RESET_PACKET 2 281#define QUIRK_RESET_PACKET 2
@@ -278,6 +283,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
278#define QUIRK_NO_1394A 8 283#define QUIRK_NO_1394A 8
279#define QUIRK_NO_MSI 16 284#define QUIRK_NO_MSI 16
280#define QUIRK_TI_SLLZ059 32 285#define QUIRK_TI_SLLZ059 32
286#define QUIRK_IR_WAKE 64
281 287
282/* In case of multiple matches in ohci_quirks[], only the first one is used. */ 288/* In case of multiple matches in ohci_quirks[], only the first one is used. */
283static const struct { 289static const struct {
@@ -319,6 +325,9 @@ static const struct {
319 {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID, 325 {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
320 QUIRK_RESET_PACKET}, 326 QUIRK_RESET_PACKET},
321 327
328 {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT630X, PCI_REV_ID_VIA_VT6306,
329 QUIRK_CYCLE_TIMER | QUIRK_IR_WAKE},
330
322 {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID, 331 {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
323 QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, 332 QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
324}; 333};
@@ -333,6 +342,7 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0"
333 ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) 342 ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A)
334 ", disable MSI = " __stringify(QUIRK_NO_MSI) 343 ", disable MSI = " __stringify(QUIRK_NO_MSI)
335 ", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059) 344 ", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059)
345 ", IR wake unreliable = " __stringify(QUIRK_IR_WAKE)
336 ")"); 346 ")");
337 347
338#define OHCI_PARAM_DEBUG_AT_AR 1 348#define OHCI_PARAM_DEBUG_AT_AR 1
@@ -1157,6 +1167,7 @@ static int context_init(struct context *ctx, struct fw_ohci *ohci,
1157 ctx->buffer_tail->used += sizeof(*ctx->buffer_tail->buffer); 1167 ctx->buffer_tail->used += sizeof(*ctx->buffer_tail->buffer);
1158 ctx->last = ctx->buffer_tail->buffer; 1168 ctx->last = ctx->buffer_tail->buffer;
1159 ctx->prev = ctx->buffer_tail->buffer; 1169 ctx->prev = ctx->buffer_tail->buffer;
1170 ctx->prev_z = 1;
1160 1171
1161 return 0; 1172 return 0;
1162} 1173}
@@ -1221,14 +1232,35 @@ static void context_append(struct context *ctx,
1221{ 1232{
1222 dma_addr_t d_bus; 1233 dma_addr_t d_bus;
1223 struct descriptor_buffer *desc = ctx->buffer_tail; 1234 struct descriptor_buffer *desc = ctx->buffer_tail;
1235 struct descriptor *d_branch;
1224 1236
1225 d_bus = desc->buffer_bus + (d - desc->buffer) * sizeof(*d); 1237 d_bus = desc->buffer_bus + (d - desc->buffer) * sizeof(*d);
1226 1238
1227 desc->used += (z + extra) * sizeof(*d); 1239 desc->used += (z + extra) * sizeof(*d);
1228 1240
1229 wmb(); /* finish init of new descriptors before branch_address update */ 1241 wmb(); /* finish init of new descriptors before branch_address update */
1230 ctx->prev->branch_address = cpu_to_le32(d_bus | z); 1242
1231 ctx->prev = find_branch_descriptor(d, z); 1243 d_branch = find_branch_descriptor(ctx->prev, ctx->prev_z);
1244 d_branch->branch_address = cpu_to_le32(d_bus | z);
1245
1246 /*
1247 * VT6306 incorrectly checks only the single descriptor at the
1248 * CommandPtr when the wake bit is written, so if it's a
1249 * multi-descriptor block starting with an INPUT_MORE, put a copy of
1250 * the branch address in the first descriptor.
1251 *
1252 * Not doing this for transmit contexts since not sure how it interacts
1253 * with skip addresses.
1254 */
1255 if (unlikely(ctx->ohci->quirks & QUIRK_IR_WAKE) &&
1256 d_branch != ctx->prev &&
1257 (ctx->prev->control & cpu_to_le16(DESCRIPTOR_CMD)) ==
1258 cpu_to_le16(DESCRIPTOR_INPUT_MORE)) {
1259 ctx->prev->branch_address = cpu_to_le32(d_bus | z);
1260 }
1261
1262 ctx->prev = d;
1263 ctx->prev_z = z;
1232} 1264}
1233 1265
1234static void context_stop(struct context *ctx) 1266static void context_stop(struct context *ctx)