Skip to content

Commit 2831a81

Browse files
pawellcdnsgregkh
authored andcommitted
usb: cdnsp: Fix issue with CV Bad Descriptor test
The SSP2 controller has extra endpoint state preserve bit (ESP) which setting causes that endpoint state will be preserved during Halt Endpoint command. It is used only for EP0. Without this bit the Command Verifier "TD 9.10 Bad Descriptor Test" failed. Setting this bit doesn't have any impact for SSP controller. Fixes: 3d82904 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") Cc: stable <[email protected]> Signed-off-by: Pawel Laszczak <[email protected]> Acked-by: Peter Chen <[email protected]> Link: https://lore.kernel.org/r/PH7PR07MB95382CCD50549DABAEFD6156DD7CA@PH7PR07MB9538.namprd07.prod.outlook.com Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent bec1519 commit 2831a81

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

drivers/usb/cdns3/cdnsp-debug.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,13 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
327327
case TRB_RESET_EP:
328328
case TRB_HALT_ENDPOINT:
329329
ret = scnprintf(str, size,
330-
"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
330+
"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c %c",
331331
cdnsp_trb_type_string(type),
332332
ep_num, ep_id % 2 ? "out" : "in",
333333
TRB_TO_EP_INDEX(field3), field1, field0,
334334
TRB_TO_SLOT_ID(field3),
335-
field3 & TRB_CYCLE ? 'C' : 'c');
335+
field3 & TRB_CYCLE ? 'C' : 'c',
336+
field3 & TRB_ESP ? 'P' : 'p');
336337
break;
337338
case TRB_STOP_RING:
338339
ret = scnprintf(str, size,

drivers/usb/cdns3/cdnsp-ep0.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ static int cdnsp_ep0_std_request(struct cdnsp_device *pdev,
414414
void cdnsp_setup_analyze(struct cdnsp_device *pdev)
415415
{
416416
struct usb_ctrlrequest *ctrl = &pdev->setup;
417+
struct cdnsp_ep *pep;
417418
int ret = -EINVAL;
418419
u16 len;
419420

@@ -427,10 +428,21 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev)
427428
goto out;
428429
}
429430

431+
pep = &pdev->eps[0];
432+
430433
/* Restore the ep0 to Stopped/Running state. */
431-
if (pdev->eps[0].ep_state & EP_HALTED) {
432-
trace_cdnsp_ep0_halted("Restore to normal state");
433-
cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0);
434+
if (pep->ep_state & EP_HALTED) {
435+
if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_HALTED)
436+
cdnsp_halt_endpoint(pdev, pep, 0);
437+
438+
/*
439+
* Halt Endpoint Command for SSP2 for ep0 preserve current
440+
* endpoint state and driver has to synchronize the
441+
* software endpoint state with endpoint output context
442+
* state.
443+
*/
444+
pep->ep_state &= ~EP_HALTED;
445+
pep->ep_state |= EP_STOPPED;
434446
}
435447

436448
/*

drivers/usb/cdns3/cdnsp-gadget.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,12 @@ enum cdnsp_setup_dev {
987987
#define STREAM_ID_FOR_TRB(p) ((((p)) << 16) & GENMASK(31, 16))
988988
#define SCT_FOR_TRB(p) (((p) << 1) & 0x7)
989989

990+
/*
991+
* Halt Endpoint Command TRB field.
992+
* The ESP bit only exists in the SSP2 controller.
993+
*/
994+
#define TRB_ESP BIT(9)
995+
990996
/* Link TRB specific fields. */
991997
#define TRB_TC BIT(1)
992998

drivers/usb/cdns3/cdnsp-ring.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,8 @@ void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index)
24852485
{
24862486
cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_HALT_ENDPOINT) |
24872487
SLOT_ID_FOR_TRB(pdev->slot_id) |
2488-
EP_ID_FOR_TRB(ep_index));
2488+
EP_ID_FOR_TRB(ep_index) |
2489+
(!ep_index ? TRB_ESP : 0));
24892490
}
24902491

24912492
void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num)

0 commit comments

Comments
 (0)