Commit 3d315130 authored by Ben Collins's avatar Ben Collins

[IEEE1394]: Fix test in ohci_soft_reset(), and handle hot-unplugged cardbus cards better.

parent 072152fc
...@@ -174,6 +174,7 @@ static void dma_trm_reset(struct dma_trm_ctx *d); ...@@ -174,6 +174,7 @@ static void dma_trm_reset(struct dma_trm_ctx *d);
static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
enum context_type type, int ctx, int num_desc, enum context_type type, int ctx, int num_desc,
int buf_size, int split_buf_size, int context_base); int buf_size, int split_buf_size, int context_base);
static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d);
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); static void free_dma_rcv_ctx(struct dma_rcv_ctx *d);
static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
...@@ -358,7 +359,7 @@ static void ohci_soft_reset(struct ti_ohci *ohci) { ...@@ -358,7 +359,7 @@ static void ohci_soft_reset(struct ti_ohci *ohci) {
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
for (i = 0; i < OHCI_LOOP_COUNT; i++) { for (i = 0; i < OHCI_LOOP_COUNT; i++) {
if (!reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset) if (!(reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset))
break; break;
mdelay(1); mdelay(1);
} }
...@@ -1077,6 +1078,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) ...@@ -1077,6 +1078,7 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
DBGMSG(ohci->id, "Listening disabled on channel %d", arg); DBGMSG(ohci->id, "Listening disabled on channel %d", arg);
if (ohci->ir_legacy_channels == 0) { if (ohci->ir_legacy_channels == 0) {
stop_dma_rcv_ctx(&ohci->ir_legacy_context);
free_dma_rcv_ctx(&ohci->ir_legacy_context); free_dma_rcv_ctx(&ohci->ir_legacy_context);
DBGMSG(ohci->id, "ISO receive legacy context deactivated"); DBGMSG(ohci->id, "ISO receive legacy context deactivated");
} }
...@@ -2249,6 +2251,14 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id, ...@@ -2249,6 +2251,14 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id,
if (!event) if (!event)
return IRQ_NONE; return IRQ_NONE;
/* If event is ~(u32)0 cardbus card was ejected. In this case
* we just return, and clean up in the ohci1394_pci_remove
* function. */
if (event == ~(u32) 0) {
DBGMSG(ohci->id, "Device removed.");
return IRQ_NONE;
}
DBGMSG(ohci->id, "IntEvent: %08x", event); DBGMSG(ohci->id, "IntEvent: %08x", event);
if (event & OHCI1394_unrecoverableError) { if (event & OHCI1394_unrecoverableError) {
...@@ -2811,15 +2821,8 @@ static void dma_trm_tasklet (unsigned long data) ...@@ -2811,15 +2821,8 @@ static void dma_trm_tasklet (unsigned long data)
spin_unlock_irqrestore(&d->lock, flags); spin_unlock_irqrestore(&d->lock, flags);
} }
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d)
{ {
int i;
if (d->ohci == NULL)
return;
DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx);
if (d->ctrlClear) { if (d->ctrlClear) {
ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
...@@ -2831,6 +2834,17 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) ...@@ -2831,6 +2834,17 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
tasklet_kill(&d->task); tasklet_kill(&d->task);
} }
} }
}
static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
{
int i;
if (d->ohci == NULL)
return;
DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx);
if (d->buf_cpu) { if (d->buf_cpu) {
for (i=0; i<d->num_desc; i++) for (i=0; i<d->num_desc; i++)
...@@ -2982,19 +2996,6 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d) ...@@ -2982,19 +2996,6 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d)
DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx); DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx);
if (d->ctrlClear) {
ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
if (d->type == DMA_CTX_ISO) {
/* disable interrupts */
reg_write(d->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << d->ctx);
ohci1394_unregister_iso_tasklet(d->ohci,
&d->ohci->it_legacy_tasklet);
} else {
tasklet_kill(&d->task);
}
}
if (d->prg_cpu) { if (d->prg_cpu) {
for (i=0; i<d->num_desc; i++) for (i=0; i<d->num_desc; i++)
if (d->prg_cpu[i] && d->prg_bus[i]) { if (d->prg_cpu[i] && d->prg_bus[i]) {
...@@ -3511,6 +3512,8 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) ...@@ -3511,6 +3512,8 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
free_irq(ohci->dev->irq, ohci); free_irq(ohci->dev->irq, ohci);
case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE: case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE:
/* The ohci_soft_reset() stops all DMA contexts, so we
* dont need to do this. */
/* Free AR dma */ /* Free AR dma */
free_dma_rcv_ctx(&ohci->ar_req_context); free_dma_rcv_ctx(&ohci->ar_req_context);
free_dma_rcv_ctx(&ohci->ar_resp_context); free_dma_rcv_ctx(&ohci->ar_resp_context);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment