@@ -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