@@ -158,7 +158,7 @@ struct context {
158
158
159
159
descriptor_callback_t callback;
160
160
161
- struct tasklet_struct tasklet ;
161
+ struct work_struct work ;
162
162
};
163
163
164
164
struct iso_context {
@@ -1176,9 +1176,9 @@ static void context_retire_descriptors(struct context *ctx)
1176
1176
}
1177
1177
}
1178
1178
1179
- static void context_tasklet(unsigned long data )
1179
+ static void ohci_at_context_work(struct work_struct *work )
1180
1180
{
1181
- struct context *ctx = (struct context *) data ;
1181
+ struct context *ctx = from_work(ctx, work, work) ;
1182
1182
1183
1183
context_retire_descriptors(ctx);
1184
1184
}
@@ -1243,7 +1243,6 @@ static int context_init(struct context *ctx, struct fw_ohci *ohci,
1243
1243
ctx->buffer_tail = list_entry(ctx->buffer_list.next,
1244
1244
struct descriptor_buffer, list);
1245
1245
1246
- tasklet_init(&ctx->tasklet, context_tasklet, (unsigned long)ctx);
1247
1246
ctx->callback = callback;
1248
1247
1249
1248
/*
@@ -1524,13 +1523,17 @@ static int at_context_queue_packet(struct context *ctx,
1524
1523
1525
1524
static void at_context_flush(struct context *ctx)
1526
1525
{
1527
- tasklet_disable(&ctx->tasklet);
1526
+ // Avoid dead lock due to programming mistake.
1527
+ if (WARN_ON_ONCE(current_work() == &ctx->work))
1528
+ return;
1528
1529
1529
- ctx->flushing = true;
1530
- context_tasklet((unsigned long)ctx);
1531
- ctx->flushing = false;
1530
+ disable_work_sync(&ctx->work);
1532
1531
1533
- tasklet_enable(&ctx->tasklet);
1532
+ WRITE_ONCE(ctx->flushing, true);
1533
+ ohci_at_context_work(&ctx->work);
1534
+ WRITE_ONCE(ctx->flushing, false);
1535
+
1536
+ enable_work(&ctx->work);
1534
1537
}
1535
1538
1536
1539
static int handle_at_packet(struct context *context,
@@ -1542,7 +1545,7 @@ static int handle_at_packet(struct context *context,
1542
1545
struct fw_ohci *ohci = context->ohci;
1543
1546
int evt;
1544
1547
1545
- if (last->transfer_status == 0 && !context->flushing)
1548
+ if (last->transfer_status == 0 && !READ_ONCE( context->flushing) )
1546
1549
/* This descriptor isn't done yet, stop iteration. */
1547
1550
return 0;
1548
1551
@@ -1576,7 +1579,7 @@ static int handle_at_packet(struct context *context,
1576
1579
break;
1577
1580
1578
1581
case OHCI1394_evt_missing_ack:
1579
- if (context->flushing)
1582
+ if (READ_ONCE( context->flushing) )
1580
1583
packet->ack = RCODE_GENERATION;
1581
1584
else {
1582
1585
/*
@@ -1598,7 +1601,7 @@ static int handle_at_packet(struct context *context,
1598
1601
break;
1599
1602
1600
1603
case OHCI1394_evt_no_status:
1601
- if (context->flushing) {
1604
+ if (READ_ONCE( context->flushing) ) {
1602
1605
packet->ack = RCODE_GENERATION;
1603
1606
break;
1604
1607
}
@@ -2239,10 +2242,10 @@ static irqreturn_t irq_handler(int irq, void *data)
2239
2242
queue_work(ohci->card.async_wq, &ohci->ar_response_ctx.work);
2240
2243
2241
2244
if (event & OHCI1394_reqTxComplete)
2242
- tasklet_schedule( &ohci->at_request_ctx.tasklet );
2245
+ queue_work(ohci->card.async_wq, &ohci->at_request_ctx.work );
2243
2246
2244
2247
if (event & OHCI1394_respTxComplete)
2245
- tasklet_schedule( &ohci->at_response_ctx.tasklet );
2248
+ queue_work(ohci->card.async_wq, &ohci->at_response_ctx.work );
2246
2249
2247
2250
if (event & OHCI1394_isochRx) {
2248
2251
iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear);
@@ -2684,7 +2687,10 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
2684
2687
struct driver_data *driver_data = packet->driver_data;
2685
2688
int ret = -ENOENT;
2686
2689
2687
- tasklet_disable_in_atomic(&ctx->tasklet);
2690
+ // Avoid dead lock due to programming mistake.
2691
+ if (WARN_ON_ONCE(current_work() == &ctx->work))
2692
+ return 0;
2693
+ disable_work_sync(&ctx->work);
2688
2694
2689
2695
if (packet->ack != 0)
2690
2696
goto out;
@@ -2703,7 +2709,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
2703
2709
packet->callback(packet, &ohci->card, packet->ack);
2704
2710
ret = 0;
2705
2711
out:
2706
- tasklet_enable (&ctx->tasklet );
2712
+ enable_work (&ctx->work );
2707
2713
2708
2714
return ret;
2709
2715
}
@@ -3765,11 +3771,13 @@ static int pci_probe(struct pci_dev *dev,
3765
3771
OHCI1394_AsReqTrContextControlSet, handle_at_packet);
3766
3772
if (err < 0)
3767
3773
return err;
3774
+ INIT_WORK(&ohci->at_request_ctx.work, ohci_at_context_work);
3768
3775
3769
3776
err = context_init(&ohci->at_response_ctx, ohci,
3770
3777
OHCI1394_AsRspTrContextControlSet, handle_at_packet);
3771
3778
if (err < 0)
3772
3779
return err;
3780
+ INIT_WORK(&ohci->at_response_ctx.work, ohci_at_context_work);
3773
3781
3774
3782
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
3775
3783
ohci->ir_context_channels = ~0ULL;
0 commit comments