@@ -185,12 +185,12 @@ static void dwc3_ep_inc_deq(struct dwc3_ep *dep)
185
185
* layers that it has completed.
186
186
*/
187
187
void dwc3_gadget_giveback (struct dwc3_ep * dep , struct dwc3_request * req ,
188
- int status )
188
+ int status , bool giveback )
189
189
{
190
190
struct dwc3 * dwc = dep -> dwc ;
191
191
192
192
req -> started = false;
193
- list_del (& req -> list );
193
+ list_del_init (& req -> list );
194
194
req -> remaining = 0 ;
195
195
196
196
if (req -> request .status == - EINPROGRESS )
@@ -204,9 +204,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
204
204
205
205
trace_dwc3_gadget_giveback (req );
206
206
207
- spin_unlock (& dwc -> lock );
208
- usb_gadget_giveback_request (& dep -> endpoint , & req -> request );
209
- spin_lock (& dwc -> lock );
207
+ if (giveback ) {
208
+ spin_unlock (& dwc -> lock );
209
+ usb_gadget_giveback_request (& dep -> endpoint , & req -> request );
210
+ spin_lock (& dwc -> lock );
211
+ }
210
212
211
213
if (dep -> number > 1 )
212
214
pm_runtime_put (dwc -> dev );
@@ -530,7 +532,7 @@ static void stream_timeout_function(unsigned long arg)
530
532
531
533
spin_lock_irqsave (& dwc -> lock , flags );
532
534
dwc3_stop_active_transfer (dwc , dep -> number , true);
533
- __dwc3_gadget_kick_transfer (dep , 0 );
535
+ __dwc3_gadget_kick_transfer (dep , 0 , true );
534
536
spin_unlock_irqrestore (& dwc -> lock , flags );
535
537
}
536
538
@@ -732,13 +734,13 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
732
734
while (!list_empty (& dep -> started_list )) {
733
735
req = next_request (& dep -> started_list );
734
736
735
- dwc3_gadget_giveback (dep , req , - ESHUTDOWN );
737
+ dwc3_gadget_giveback (dep , req , - ESHUTDOWN , true );
736
738
}
737
739
738
740
while (!list_empty (& dep -> pending_list )) {
739
741
req = next_request (& dep -> pending_list );
740
742
741
- dwc3_gadget_giveback (dep , req , - ESHUTDOWN );
743
+ dwc3_gadget_giveback (dep , req , - ESHUTDOWN , true );
742
744
}
743
745
}
744
746
@@ -872,6 +874,7 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
872
874
873
875
req -> epnum = dep -> number ;
874
876
req -> dep = dep ;
877
+ INIT_LIST_HEAD (& req -> list );
875
878
876
879
dep -> allocated_requests ++ ;
877
880
@@ -1246,7 +1249,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
1246
1249
}
1247
1250
}
1248
1251
1249
- int __dwc3_gadget_kick_transfer (struct dwc3_ep * dep , u16 cmd_param )
1252
+ int __dwc3_gadget_kick_transfer (struct dwc3_ep * dep , u16 cmd_param , bool giveback )
1250
1253
{
1251
1254
struct dwc3_gadget_ep_cmd_params params ;
1252
1255
struct dwc3_request * req ;
@@ -1289,14 +1292,15 @@ int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param)
1289
1292
if (req -> trb )
1290
1293
memset (req -> trb , 0 , sizeof (struct dwc3_trb ));
1291
1294
dep -> queued_requests -- ;
1292
- dwc3_gadget_giveback (dep , req , ret );
1295
+ dwc3_gadget_giveback (dep , req , ret , giveback );
1293
1296
return ret ;
1294
1297
}
1295
1298
1296
1299
dep -> flags |= DWC3_EP_BUSY ;
1297
1300
1298
1301
if (starting ) {
1299
- if (dep -> stream_capable ) {
1302
+ /* FIXME: Enable this again once it works properly */
1303
+ if (dep -> stream_capable && 0 ) {
1300
1304
dep -> stream_timeout_timer .expires = jiffies +
1301
1305
msecs_to_jiffies (STREAM_TIMEOUT );
1302
1306
add_timer (& dep -> stream_timeout_timer );
@@ -1334,7 +1338,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,
1334
1338
*/
1335
1339
uf = cur_uf + max_t (u32 , 4 , dep -> interval );
1336
1340
1337
- __dwc3_gadget_kick_transfer (dep , uf );
1341
+ __dwc3_gadget_kick_transfer (dep , uf , true );
1338
1342
}
1339
1343
1340
1344
static void dwc3_gadget_start_isoc (struct dwc3 * dwc ,
@@ -1410,7 +1414,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
1410
1414
!(dep -> flags & DWC3_EP_MISSED_ISOC )) {
1411
1415
WARN_ON_ONCE (!dep -> resource_index );
1412
1416
ret = __dwc3_gadget_kick_transfer (dep ,
1413
- dep -> resource_index );
1417
+ dep -> resource_index , false );
1414
1418
}
1415
1419
1416
1420
goto out ;
@@ -1419,7 +1423,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
1419
1423
if (!dwc3_calc_trbs_left (dep ))
1420
1424
return 0 ;
1421
1425
1422
- ret = __dwc3_gadget_kick_transfer (dep , 0 );
1426
+ ret = __dwc3_gadget_kick_transfer (dep , 0 , false );
1423
1427
out :
1424
1428
if (ret == - EBUSY )
1425
1429
ret = 0 ;
@@ -1461,93 +1465,45 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
1461
1465
1462
1466
spin_lock_irqsave (& dwc -> lock , flags );
1463
1467
1468
+ /* Not queued, nothing to do */
1469
+ if (list_empty (& req -> list ))
1470
+ goto out0 ;
1471
+
1464
1472
list_for_each_entry (r , & dep -> pending_list , list ) {
1473
+ if (r == req )
1474
+ goto out1 ;
1475
+ }
1476
+
1477
+ list_for_each_entry (r , & dep -> started_list , list ) {
1465
1478
if (r == req )
1466
1479
break ;
1467
1480
}
1468
1481
1469
1482
if (r != req ) {
1470
- list_for_each_entry (r , & dep -> started_list , list ) {
1471
- if (r == req )
1472
- break ;
1473
- }
1474
- if (r == req ) {
1475
- /* wait until it is processed */
1476
- dwc3_stop_active_transfer (dwc , dep -> number , true);
1477
-
1478
- /*
1479
- * If request was already started, this means we had to
1480
- * stop the transfer. With that we also need to ignore
1481
- * all TRBs used by the request, however TRBs can only
1482
- * be modified after completion of END_TRANSFER
1483
- * command. So what we do here is that we wait for
1484
- * END_TRANSFER completion and only after that, we jump
1485
- * over TRBs by clearing HWO and incrementing dequeue
1486
- * pointer.
1487
- *
1488
- * Note that we have 2 possible types of transfers here:
1489
- *
1490
- * i) Linear buffer request
1491
- * ii) SG-list based request
1492
- *
1493
- * SG-list based requests will have r->num_pending_sgs
1494
- * set to a valid number (> 0). Linear requests,
1495
- * normally use a single TRB.
1496
- *
1497
- * For each of these two cases, if r->unaligned flag is
1498
- * set, one extra TRB has been used to align transfer
1499
- * size to wMaxPacketSize.
1500
- *
1501
- * All of these cases need to be taken into
1502
- * consideration so we don't mess up our TRB ring
1503
- * pointers.
1504
- */
1505
- wait_event_lock_irq (dep -> wait_end_transfer ,
1506
- !(dep -> flags & DWC3_EP_END_TRANSFER_PENDING ),
1507
- dwc -> lock );
1508
-
1509
- if (!r -> trb )
1510
- goto out1 ;
1511
-
1512
- if (r -> num_pending_sgs ) {
1513
- struct dwc3_trb * trb ;
1514
- int i = 0 ;
1515
-
1516
- for (i = 0 ; i < r -> num_pending_sgs ; i ++ ) {
1517
- trb = r -> trb + i ;
1518
- trb -> ctrl &= ~DWC3_TRB_CTRL_HWO ;
1519
- dwc3_ep_inc_deq (dep );
1520
- }
1521
-
1522
- if (r -> unaligned || r -> zero ) {
1523
- trb = r -> trb + r -> num_pending_sgs + 1 ;
1524
- trb -> ctrl &= ~DWC3_TRB_CTRL_HWO ;
1525
- dwc3_ep_inc_deq (dep );
1526
- }
1527
- } else {
1528
- struct dwc3_trb * trb = r -> trb ;
1529
-
1530
- trb -> ctrl &= ~DWC3_TRB_CTRL_HWO ;
1531
- dwc3_ep_inc_deq (dep );
1532
-
1533
- if (r -> unaligned || r -> zero ) {
1534
- trb = r -> trb + 1 ;
1535
- trb -> ctrl &= ~DWC3_TRB_CTRL_HWO ;
1536
- dwc3_ep_inc_deq (dep );
1537
- }
1538
- }
1539
- goto out1 ;
1540
- }
1541
1483
dev_err (dwc -> dev , "request %pK was not queued to %s\n" ,
1542
1484
request , ep -> name );
1543
1485
ret = - EINVAL ;
1544
1486
goto out0 ;
1545
1487
}
1546
1488
1489
+ if (dep -> stream_capable )
1490
+ del_timer (& dep -> stream_timeout_timer );
1491
+
1492
+ dep -> aborted_trbs = r -> trb ;
1493
+ if (r -> num_pending_sgs )
1494
+ dep -> num_aborted_trbs = r -> num_pending_sgs ;
1495
+ else
1496
+ dep -> num_aborted_trbs = 1 ;
1497
+
1498
+ if (r -> unaligned || r -> zero )
1499
+ dep -> num_aborted_trbs += 1 ;
1500
+
1501
+ dwc3_stop_active_transfer (dwc , dep -> number , true);
1502
+
1547
1503
out1 :
1548
1504
/* giveback the request */
1549
1505
dep -> queued_requests -- ;
1550
- dwc3_gadget_giveback (dep , req , - ECONNRESET );
1506
+ dwc3_gadget_giveback (dep , req , - ECONNRESET , true );
1551
1507
1552
1508
out0 :
1553
1509
spin_unlock_irqrestore (& dwc -> lock , flags );
@@ -2456,10 +2412,10 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
2456
2412
* to kick transfer again if (req->num_pending_sgs > 0)
2457
2413
*/
2458
2414
if (req -> num_pending_sgs )
2459
- return __dwc3_gadget_kick_transfer (dep , 0 );
2415
+ return __dwc3_gadget_kick_transfer (dep , 0 , true );
2460
2416
}
2461
2417
2462
- dwc3_gadget_giveback (dep , req , status );
2418
+ dwc3_gadget_giveback (dep , req , status , true );
2463
2419
2464
2420
if (ret ) {
2465
2421
if ((event -> status & DEPEVT_STATUS_IOC ) &&
@@ -2560,7 +2516,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
2560
2516
if (!usb_endpoint_xfer_isoc (dep -> endpoint .desc )) {
2561
2517
int ret ;
2562
2518
2563
- ret = __dwc3_gadget_kick_transfer (dep , 0 );
2519
+ ret = __dwc3_gadget_kick_transfer (dep , 0 , true );
2564
2520
if (!ret || ret == - EBUSY )
2565
2521
return ;
2566
2522
}
@@ -2609,7 +2565,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
2609
2565
} else {
2610
2566
int ret ;
2611
2567
2612
- ret = __dwc3_gadget_kick_transfer (dep , 0 );
2568
+ ret = __dwc3_gadget_kick_transfer (dep , 0 , true );
2613
2569
if (!ret || ret == - EBUSY )
2614
2570
return ;
2615
2571
}
@@ -2638,6 +2594,19 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
2638
2594
cmd = DEPEVT_PARAMETER_CMD (event -> parameters );
2639
2595
2640
2596
if (cmd == DWC3_DEPCMD_ENDTRANSFER ) {
2597
+ if (dep -> aborted_trbs ) {
2598
+ struct dwc3_trb * trb = dep -> aborted_trbs ;
2599
+ int i = 0 ;
2600
+
2601
+ for (i = 0 ; i < dep -> num_aborted_trbs ; i ++ ) {
2602
+ trb -> ctrl &= ~DWC3_TRB_CTRL_HWO ;
2603
+ dwc3_ep_inc_deq (dep );
2604
+ trb ++ ;
2605
+ }
2606
+
2607
+ dep -> aborted_trbs = NULL ;
2608
+ dep -> num_aborted_trbs = 0 ;
2609
+ }
2641
2610
dep -> flags &= ~DWC3_EP_END_TRANSFER_PENDING ;
2642
2611
wake_up (& dep -> wait_end_transfer );
2643
2612
}
@@ -2736,7 +2705,7 @@ void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force)
2736
2705
cmd |= DWC3_DEPCMD_PARAM (dep -> resource_index );
2737
2706
memset (& params , 0 , sizeof (params ));
2738
2707
ret = dwc3_send_gadget_ep_cmd (dep , cmd , & params );
2739
- WARN_ON_ONCE (ret );
2708
+ WARN_ON_ONCE (ret && ret != - ETIMEDOUT );
2740
2709
dep -> flags &= ~DWC3_EP_BUSY ;
2741
2710
2742
2711
/*
0 commit comments