// SPDX-License-Identifier: GPL-2.0 /* * UHCI-specific debugging code. Invaluable when something * goes wrong, but don't get in my face. * * Kernel visible pointers are surrounded in []s and bus * visible pointers are surrounded in ()s * * (C) Copyright 1999 Linus Torvalds * (C) Copyright 1999-2001 Johannes Erdfelt
*/
out += uhci_show_root_hub_state(uhci, out); if (out - buf > len) goto done;
out += sprintf(out, "HC status\n");
out += uhci_show_status(uhci, out, len - (out - buf)); if (out - buf > len) goto tail;
out += sprintf(out, "Periodic load table\n"); for (i = 0; i < MAX_PHASE; ++i) {
out += sprintf(out, "\t%d", uhci->load[i]); if (i % 8 == 7)
*out++ = '\n';
}
out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n",
uhci->total_load,
uhci_to_hcd(uhci)->self.bandwidth_int_reqs,
uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); if (debug <= 1) goto tail;
out += sprintf(out, "Frame List\n");
nframes = 10;
nerrs = 0; for (i = 0; i < UHCI_NUMFRAMES; ++i) {
__hc32 qh_dma;
if (out - buf > len) goto done;
j = 0;
td = uhci->frame_cpu[i];
link = uhci->frame[i]; if (!td) goto check_link;
if (nframes > 0) {
out += sprintf(out, "- Frame %d -> (%08x)\n",
i, hc32_to_cpu(uhci, link));
j = 1;
}
head = &td->fl_list;
tmp = head; do {
td = list_entry(tmp, struct uhci_td, fl_list);
tmp = tmp->next; if (link != LINK_TO_TD(uhci, td)) { if (nframes > 0) {
out += sprintf(out, " link does not match list entry!\n"); if (out - buf > len) goto done;
} else
++nerrs;
} if (nframes > 0) {
out += uhci_show_td(uhci, td, out,
len - (out - buf), 4); if (out - buf > len) goto tail;
}
link = td->link;
} while (tmp != head);
check_link:
qh_dma = uhci_frame_skel_link(uhci, i); if (link != qh_dma) { if (nframes > 0) { if (!j) {
out += sprintf(out, "- Frame %d -> (%08x)\n",
i, hc32_to_cpu(uhci, link));
j = 1;
}
out += sprintf(out, " link does not match QH (%08x)!\n",
hc32_to_cpu(uhci, qh_dma)); if (out - buf > len) goto done;
} else
++nerrs;
}
nframes -= j;
} if (nerrs > 0)
out += sprintf(out, "Skipped %d bad links\n", nerrs);
out += sprintf(out, "Skeleton QHs\n");
if (out - buf > len) goto done;
fsbr_link = 0; for (i = 0; i < UHCI_NUM_SKELQH; ++i) { int cnt = 0;
qh = uhci->skelqh[i];
out += sprintf(out, "- skel_%s_qh\n", qh_names[i]);
out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4); if (out - buf > len) goto tail;
/* Last QH is the Terminating QH, it's different */ if (i == SKEL_TERM) { if (qh_element(qh) != LINK_TO_TD(uhci, uhci->term_td)) {
out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); if (out - buf > len) goto done;
}
link = fsbr_link; if (!link)
link = LINK_TO_QH(uhci, uhci->skel_term_qh); goto check_qh_link;
}
head = &qh->node;
tmp = head->next;
while (tmp != head) {
qh = list_entry(tmp, struct uhci_qh, node);
tmp = tmp->next; if (++cnt <= 10) {
out += uhci_show_qh(uhci, qh, out,
len - (out - buf), 4); if (out - buf > len) goto tail;
} if (!fsbr_link && qh->skel >= SKEL_FSBR)
fsbr_link = LINK_TO_QH(uhci, qh);
} if ((cnt -= 10) > 0)
out += sprintf(out, " Skipped %d QHs\n", cnt);
link = UHCI_PTR_TERM(uhci); if (i <= SKEL_ISO)
; elseif (i < SKEL_ASYNC)
link = LINK_TO_QH(uhci, uhci->skel_async_qh); elseif (!uhci->fsbr_is_on)
; else
link = LINK_TO_QH(uhci, uhci->skel_term_qh);
check_qh_link: if (qh->link != link)
out += sprintf(out, " last QH not linked to next skeleton!\n");
if (out - buf > len) goto done;
}
done: if (out - buf > len)
out += sprintf(out, " ...\n");
tail: return out - buf;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.