usb: xhci-mtk: add some schedule error number
This is used to provide more information about which case causes bandwidth schedule failure. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Link: https://lore.kernel.org/r/9771f44093053b581e9c4be4b7fb68d9fcecad08.1615170625.git.chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
bf7da03ae4
commit
ccda8c224c
@ -25,6 +25,13 @@
|
||||
*/
|
||||
#define TT_MICROFRAMES_MAX 9
|
||||
|
||||
/* schedule error type */
|
||||
#define ESCH_SS_Y6 1001
|
||||
#define ESCH_SS_OVERLAP 1002
|
||||
#define ESCH_CS_OVERFLOW 1003
|
||||
#define ESCH_BW_OVERFLOW 1004
|
||||
#define ESCH_FIXME 1005
|
||||
|
||||
/* mtk scheduler bitmasks */
|
||||
#define EP_BPKTS(p) ((p) & 0x7f)
|
||||
#define EP_BCSCOUNT(p) (((p) & 0x7) << 8)
|
||||
@ -32,6 +39,24 @@
|
||||
#define EP_BOFFSET(p) ((p) & 0x3fff)
|
||||
#define EP_BREPEAT(p) (((p) & 0x7fff) << 16)
|
||||
|
||||
static char *sch_error_string(int err_num)
|
||||
{
|
||||
switch (err_num) {
|
||||
case ESCH_SS_Y6:
|
||||
return "Can't schedule Start-Split in Y6";
|
||||
case ESCH_SS_OVERLAP:
|
||||
return "Can't find a suitable Start-Split location";
|
||||
case ESCH_CS_OVERFLOW:
|
||||
return "The last Complete-Split is greater than 7";
|
||||
case ESCH_BW_OVERFLOW:
|
||||
return "Bandwidth exceeds the maximum limit";
|
||||
case ESCH_FIXME:
|
||||
return "FIXME, to be resolved";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static int is_fs_or_ls(enum usb_device_speed speed)
|
||||
{
|
||||
return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
|
||||
@ -412,7 +437,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
|
||||
for (j = 0; j < sch_ep->cs_count; j++) {
|
||||
tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
|
||||
if (tmp > FS_PAYLOAD_MAX)
|
||||
return -ERANGE;
|
||||
return -ESCH_BW_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,11 +462,11 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
|
||||
* must never schedule Start-Split in Y6
|
||||
*/
|
||||
if (!(start_ss == 7 || last_ss < 6))
|
||||
return -ERANGE;
|
||||
return -ESCH_SS_Y6;
|
||||
|
||||
for (i = 0; i < sch_ep->cs_count; i++)
|
||||
if (test_bit(offset + i, tt->ss_bit_map))
|
||||
return -ERANGE;
|
||||
return -ESCH_SS_OVERLAP;
|
||||
|
||||
} else {
|
||||
u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
|
||||
@ -451,14 +476,14 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
|
||||
* must never schedule Start-Split in Y6
|
||||
*/
|
||||
if (start_ss == 6)
|
||||
return -ERANGE;
|
||||
return -ESCH_SS_Y6;
|
||||
|
||||
/* one uframe for ss + one uframe for idle */
|
||||
start_cs = (start_ss + 2) % 8;
|
||||
last_cs = start_cs + cs_count - 1;
|
||||
|
||||
if (last_cs > 7)
|
||||
return -ERANGE;
|
||||
return -ESCH_CS_OVERFLOW;
|
||||
|
||||
if (sch_ep->ep_type == ISOC_IN_EP)
|
||||
extra_cs_count = (last_cs == 7) ? 1 : 2;
|
||||
@ -470,7 +495,7 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
|
||||
cs_count = 7; /* HW limit */
|
||||
|
||||
if (test_bit(offset, tt->ss_bit_map))
|
||||
return -ERANGE;
|
||||
return -ESCH_SS_OVERLAP;
|
||||
|
||||
sch_ep->cs_count = cs_count;
|
||||
/* one for ss, the other for idle */
|
||||
@ -562,7 +587,7 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
u32 esit_boundary;
|
||||
u32 min_num_budget;
|
||||
u32 min_cs_count;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Search through all possible schedule microframes.
|
||||
@ -597,7 +622,7 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
bw_boundary = get_bw_boundary(sch_ep->speed);
|
||||
/* check bandwidth */
|
||||
if (min_bw > bw_boundary)
|
||||
return -ERANGE;
|
||||
return ret ? ret : -ESCH_BW_OVERFLOW;
|
||||
|
||||
sch_ep->offset = min_index;
|
||||
sch_ep->cs_count = min_cs_count;
|
||||
@ -765,7 +790,8 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
|
||||
ret = check_sch_bw(sch_bw, sch_ep);
|
||||
if (ret) {
|
||||
xhci_err(xhci, "Not enough bandwidth!\n");
|
||||
xhci_err(xhci, "Not enough bandwidth! (%s)\n",
|
||||
sch_error_string(-ret));
|
||||
return -ENOSPC;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user