mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-08-22 00:42:01 +02:00
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: 3d82904559
("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://lore.kernel.org/r/PH7PR07MB95382CCD50549DABAEFD6156DD7CA@PH7PR07MB9538.namprd07.prod.outlook.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
bec15191d5
commit
2831a81077
|
@ -327,12 +327,13 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||||
case TRB_RESET_EP:
|
case TRB_RESET_EP:
|
||||||
case TRB_HALT_ENDPOINT:
|
case TRB_HALT_ENDPOINT:
|
||||||
ret = scnprintf(str, size,
|
ret = scnprintf(str, size,
|
||||||
"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
|
"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c %c",
|
||||||
cdnsp_trb_type_string(type),
|
cdnsp_trb_type_string(type),
|
||||||
ep_num, ep_id % 2 ? "out" : "in",
|
ep_num, ep_id % 2 ? "out" : "in",
|
||||||
TRB_TO_EP_INDEX(field3), field1, field0,
|
TRB_TO_EP_INDEX(field3), field1, field0,
|
||||||
TRB_TO_SLOT_ID(field3),
|
TRB_TO_SLOT_ID(field3),
|
||||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
field3 & TRB_CYCLE ? 'C' : 'c',
|
||||||
|
field3 & TRB_ESP ? 'P' : 'p');
|
||||||
break;
|
break;
|
||||||
case TRB_STOP_RING:
|
case TRB_STOP_RING:
|
||||||
ret = scnprintf(str, size,
|
ret = scnprintf(str, size,
|
||||||
|
|
|
@ -414,6 +414,7 @@ static int cdnsp_ep0_std_request(struct cdnsp_device *pdev,
|
||||||
void cdnsp_setup_analyze(struct cdnsp_device *pdev)
|
void cdnsp_setup_analyze(struct cdnsp_device *pdev)
|
||||||
{
|
{
|
||||||
struct usb_ctrlrequest *ctrl = &pdev->setup;
|
struct usb_ctrlrequest *ctrl = &pdev->setup;
|
||||||
|
struct cdnsp_ep *pep;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
u16 len;
|
u16 len;
|
||||||
|
|
||||||
|
@ -427,10 +428,21 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pep = &pdev->eps[0];
|
||||||
|
|
||||||
/* Restore the ep0 to Stopped/Running state. */
|
/* Restore the ep0 to Stopped/Running state. */
|
||||||
if (pdev->eps[0].ep_state & EP_HALTED) {
|
if (pep->ep_state & EP_HALTED) {
|
||||||
trace_cdnsp_ep0_halted("Restore to normal state");
|
if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_HALTED)
|
||||||
cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0);
|
cdnsp_halt_endpoint(pdev, pep, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Halt Endpoint Command for SSP2 for ep0 preserve current
|
||||||
|
* endpoint state and driver has to synchronize the
|
||||||
|
* software endpoint state with endpoint output context
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
pep->ep_state &= ~EP_HALTED;
|
||||||
|
pep->ep_state |= EP_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -987,6 +987,12 @@ enum cdnsp_setup_dev {
|
||||||
#define STREAM_ID_FOR_TRB(p) ((((p)) << 16) & GENMASK(31, 16))
|
#define STREAM_ID_FOR_TRB(p) ((((p)) << 16) & GENMASK(31, 16))
|
||||||
#define SCT_FOR_TRB(p) (((p) << 1) & 0x7)
|
#define SCT_FOR_TRB(p) (((p) << 1) & 0x7)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Halt Endpoint Command TRB field.
|
||||||
|
* The ESP bit only exists in the SSP2 controller.
|
||||||
|
*/
|
||||||
|
#define TRB_ESP BIT(9)
|
||||||
|
|
||||||
/* Link TRB specific fields. */
|
/* Link TRB specific fields. */
|
||||||
#define TRB_TC BIT(1)
|
#define TRB_TC BIT(1)
|
||||||
|
|
||||||
|
|
|
@ -2485,7 +2485,8 @@ void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index)
|
||||||
{
|
{
|
||||||
cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_HALT_ENDPOINT) |
|
cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_HALT_ENDPOINT) |
|
||||||
SLOT_ID_FOR_TRB(pdev->slot_id) |
|
SLOT_ID_FOR_TRB(pdev->slot_id) |
|
||||||
EP_ID_FOR_TRB(ep_index));
|
EP_ID_FOR_TRB(ep_index) |
|
||||||
|
(!ep_index ? TRB_ESP : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num)
|
void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user