aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/ohci.c')
-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)