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.c85
1 files changed, 64 insertions, 21 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index bd3c61b6dd8..f903d7b6f34 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -208,9 +208,11 @@ struct fw_ohci {
208 struct context at_request_ctx; 208 struct context at_request_ctx;
209 struct context at_response_ctx; 209 struct context at_response_ctx;
210 210
211 u32 it_context_support;
211 u32 it_context_mask; /* unoccupied IT contexts */ 212 u32 it_context_mask; /* unoccupied IT contexts */
212 struct iso_context *it_context_list; 213 struct iso_context *it_context_list;
213 u64 ir_context_channels; /* unoccupied channels */ 214 u64 ir_context_channels; /* unoccupied channels */
215 u32 ir_context_support;
214 u32 ir_context_mask; /* unoccupied IR contexts */ 216 u32 ir_context_mask; /* unoccupied IR contexts */
215 struct iso_context *ir_context_list; 217 struct iso_context *ir_context_list;
216 u64 mc_channels; /* channels in use by the multichannel IR context */ 218 u64 mc_channels; /* channels in use by the multichannel IR context */
@@ -338,7 +340,7 @@ static void log_irqs(u32 evt)
338 !(evt & OHCI1394_busReset)) 340 !(evt & OHCI1394_busReset))
339 return; 341 return;
340 342
341 fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, 343 fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
342 evt & OHCI1394_selfIDComplete ? " selfID" : "", 344 evt & OHCI1394_selfIDComplete ? " selfID" : "",
343 evt & OHCI1394_RQPkt ? " AR_req" : "", 345 evt & OHCI1394_RQPkt ? " AR_req" : "",
344 evt & OHCI1394_RSPkt ? " AR_resp" : "", 346 evt & OHCI1394_RSPkt ? " AR_resp" : "",
@@ -351,6 +353,7 @@ static void log_irqs(u32 evt)
351 evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", 353 evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "",
352 evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", 354 evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "",
353 evt & OHCI1394_regAccessFail ? " regAccessFail" : "", 355 evt & OHCI1394_regAccessFail ? " regAccessFail" : "",
356 evt & OHCI1394_unrecoverableError ? " unrecoverableError" : "",
354 evt & OHCI1394_busReset ? " busReset" : "", 357 evt & OHCI1394_busReset ? " busReset" : "",
355 evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | 358 evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
356 OHCI1394_RSPkt | OHCI1394_reqTxComplete | 359 OHCI1394_RSPkt | OHCI1394_reqTxComplete |
@@ -1326,21 +1329,8 @@ static int at_context_queue_packet(struct context *ctx,
1326 DESCRIPTOR_IRQ_ALWAYS | 1329 DESCRIPTOR_IRQ_ALWAYS |
1327 DESCRIPTOR_BRANCH_ALWAYS); 1330 DESCRIPTOR_BRANCH_ALWAYS);
1328 1331
1329 /* 1332 /* FIXME: Document how the locking works. */
1330 * If the controller and packet generations don't match, we need to 1333 if (ohci->generation != packet->generation) {
1331 * bail out and try again. If IntEvent.busReset is set, the AT context
1332 * is halted, so appending to the context and trying to run it is
1333 * futile. Most controllers do the right thing and just flush the AT
1334 * queue (per section 7.2.3.2 of the OHCI 1.1 specification), but
1335 * some controllers (like a JMicron JMB381 PCI-e) misbehave and wind
1336 * up stalling out. So we just bail out in software and try again
1337 * later, and everyone is happy.
1338 * FIXME: Test of IntEvent.busReset may no longer be necessary since we
1339 * flush AT queues in bus_reset_tasklet.
1340 * FIXME: Document how the locking works.
1341 */
1342 if (ohci->generation != packet->generation ||
1343 reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
1344 if (packet->payload_mapped) 1334 if (packet->payload_mapped)
1345 dma_unmap_single(ohci->card.device, payload_bus, 1335 dma_unmap_single(ohci->card.device, payload_bus,
1346 packet->payload_length, DMA_TO_DEVICE); 1336 packet->payload_length, DMA_TO_DEVICE);
@@ -1590,6 +1580,47 @@ static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
1590 1580
1591} 1581}
1592 1582
1583static void detect_dead_context(struct fw_ohci *ohci,
1584 const char *name, unsigned int regs)
1585{
1586 u32 ctl;
1587
1588 ctl = reg_read(ohci, CONTROL_SET(regs));
1589 if (ctl & CONTEXT_DEAD) {
1590#ifdef CONFIG_FIREWIRE_OHCI_DEBUG
1591 fw_error("DMA context %s has stopped, error code: %s\n",
1592 name, evts[ctl & 0x1f]);
1593#else
1594 fw_error("DMA context %s has stopped, error code: %#x\n",
1595 name, ctl & 0x1f);
1596#endif
1597 }
1598}
1599
1600static void handle_dead_contexts(struct fw_ohci *ohci)
1601{
1602 unsigned int i;
1603 char name[8];
1604
1605 detect_dead_context(ohci, "ATReq", OHCI1394_AsReqTrContextBase);
1606 detect_dead_context(ohci, "ATRsp", OHCI1394_AsRspTrContextBase);
1607 detect_dead_context(ohci, "ARReq", OHCI1394_AsReqRcvContextBase);
1608 detect_dead_context(ohci, "ARRsp", OHCI1394_AsRspRcvContextBase);
1609 for (i = 0; i < 32; ++i) {
1610 if (!(ohci->it_context_support & (1 << i)))
1611 continue;
1612 sprintf(name, "IT%u", i);
1613 detect_dead_context(ohci, name, OHCI1394_IsoXmitContextBase(i));
1614 }
1615 for (i = 0; i < 32; ++i) {
1616 if (!(ohci->ir_context_support & (1 << i)))
1617 continue;
1618 sprintf(name, "IR%u", i);
1619 detect_dead_context(ohci, name, OHCI1394_IsoRcvContextBase(i));
1620 }
1621 /* TODO: maybe try to flush and restart the dead contexts */
1622}
1623
1593static u32 cycle_timer_ticks(u32 cycle_timer) 1624static u32 cycle_timer_ticks(u32 cycle_timer)
1594{ 1625{
1595 u32 ticks; 1626 u32 ticks;
@@ -1904,6 +1935,9 @@ static irqreturn_t irq_handler(int irq, void *data)
1904 fw_notify("isochronous cycle inconsistent\n"); 1935 fw_notify("isochronous cycle inconsistent\n");
1905 } 1936 }
1906 1937
1938 if (unlikely(event & OHCI1394_unrecoverableError))
1939 handle_dead_contexts(ohci);
1940
1907 if (event & OHCI1394_cycle64Seconds) { 1941 if (event & OHCI1394_cycle64Seconds) {
1908 spin_lock(&ohci->lock); 1942 spin_lock(&ohci->lock);
1909 update_bus_time(ohci); 1943 update_bus_time(ohci);
@@ -2141,7 +2175,9 @@ static int ohci_enable(struct fw_card *card,
2141 OHCI1394_selfIDComplete | 2175 OHCI1394_selfIDComplete |
2142 OHCI1394_regAccessFail | 2176 OHCI1394_regAccessFail |
2143 OHCI1394_cycle64Seconds | 2177 OHCI1394_cycle64Seconds |
2144 OHCI1394_cycleInconsistent | OHCI1394_cycleTooLong | 2178 OHCI1394_cycleInconsistent |
2179 OHCI1394_unrecoverableError |
2180 OHCI1394_cycleTooLong |
2145 OHCI1394_masterIntEnable; 2181 OHCI1394_masterIntEnable;
2146 if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) 2182 if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
2147 irqs |= OHCI1394_busReset; 2183 irqs |= OHCI1394_busReset;
@@ -2657,6 +2693,10 @@ static int ohci_start_iso(struct fw_iso_context *base,
2657 u32 control = IR_CONTEXT_ISOCH_HEADER, match; 2693 u32 control = IR_CONTEXT_ISOCH_HEADER, match;
2658 int index; 2694 int index;
2659 2695
2696 /* the controller cannot start without any queued packets */
2697 if (ctx->context.last->branch_address == 0)
2698 return -ENODATA;
2699
2660 switch (ctx->base.type) { 2700 switch (ctx->base.type) {
2661 case FW_ISO_CONTEXT_TRANSMIT: 2701 case FW_ISO_CONTEXT_TRANSMIT:
2662 index = ctx - ohci->it_context_list; 2702 index = ctx - ohci->it_context_list;
@@ -2715,6 +2755,7 @@ static int ohci_stop_iso(struct fw_iso_context *base)
2715 } 2755 }
2716 flush_writes(ohci); 2756 flush_writes(ohci);
2717 context_stop(&ctx->context); 2757 context_stop(&ctx->context);
2758 tasklet_kill(&ctx->context.tasklet);
2718 2759
2719 return 0; 2760 return 0;
2720} 2761}
@@ -3207,15 +3248,17 @@ static int __devinit pci_probe(struct pci_dev *dev,
3207 3248
3208 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); 3249 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
3209 ohci->ir_context_channels = ~0ULL; 3250 ohci->ir_context_channels = ~0ULL;
3210 ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); 3251 ohci->ir_context_support = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
3211 reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); 3252 reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
3253 ohci->ir_context_mask = ohci->ir_context_support;
3212 ohci->n_ir = hweight32(ohci->ir_context_mask); 3254 ohci->n_ir = hweight32(ohci->ir_context_mask);
3213 size = sizeof(struct iso_context) * ohci->n_ir; 3255 size = sizeof(struct iso_context) * ohci->n_ir;
3214 ohci->ir_context_list = kzalloc(size, GFP_KERNEL); 3256 ohci->ir_context_list = kzalloc(size, GFP_KERNEL);
3215 3257
3216 reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); 3258 reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
3217 ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); 3259 ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
3218 reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); 3260 reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
3261 ohci->it_context_mask = ohci->it_context_support;
3219 ohci->n_it = hweight32(ohci->it_context_mask); 3262 ohci->n_it = hweight32(ohci->it_context_mask);
3220 size = sizeof(struct iso_context) * ohci->n_it; 3263 size = sizeof(struct iso_context) * ohci->n_it;
3221 ohci->it_context_list = kzalloc(size, GFP_KERNEL); 3264 ohci->it_context_list = kzalloc(size, GFP_KERNEL);
@@ -3266,7 +3309,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
3266 fail_disable: 3309 fail_disable:
3267 pci_disable_device(dev); 3310 pci_disable_device(dev);
3268 fail_free: 3311 fail_free:
3269 kfree(&ohci->card); 3312 kfree(ohci);
3270 pmac_ohci_off(dev); 3313 pmac_ohci_off(dev);
3271 fail: 3314 fail:
3272 if (err == -ENOMEM) 3315 if (err == -ENOMEM)
@@ -3310,7 +3353,7 @@ static void pci_remove(struct pci_dev *dev)
3310 pci_iounmap(dev, ohci->registers); 3353 pci_iounmap(dev, ohci->registers);
3311 pci_release_region(dev, 0); 3354 pci_release_region(dev, 0);
3312 pci_disable_device(dev); 3355 pci_disable_device(dev);
3313 kfree(&ohci->card); 3356 kfree(ohci);
3314 pmac_ohci_off(dev); 3357 pmac_ohci_off(dev);
3315 3358
3316 fw_notify("Removed fw-ohci device.\n"); 3359 fw_notify("Removed fw-ohci device.\n");