debug_x.c revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
#ifdef USB_DISK
/*******************************************************************************
*
*
* Copyright 2003 Steven James <pyro@linuxlabs.com> and
* LinuxLabs http://www.linuxlabs.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
******************************************************************************/
#include <etherboot.h>
#include <pci.h>
#include <timer.h>
#include <lib.h>
#define DEBUG_THIS DEBUG_USB
#include <debug.h>
#define DPRINTF debug
#include "usb.h"
#include "uhci.h"
#include "debug_x.h"
//#include <string.h>
void dump_link( link_pointer_t *link, char *prefix)
{
DPRINTF("%saddr: %08x\n", prefix, MEM_ADDR(link->link) );
DPRINTF("%s raw addr: %04x\n", prefix, (link->link) <<4 );
DPRINTF("%sterminate: %x\n", prefix, link->terminate);
DPRINTF("%squeue: %x\n", prefix, link->queue);
DPRINTF("%sdepth: %x\n", prefix, link->depth);
}
void dump_frame_list( link_pointer_t *addr, char *prefix)
{
int i;
DPRINTF("%sFRAMELIST:\n",prefix);
for(i=0;i<10; i++) {
dump_link(addr+i, prefix);
if(addr[i].queue)
dump_queue_head( MEM_ADDR(addr[i].link), "");
else
dump_td( MEM_ADDR(addr[i].link), "");
}
}
void dump_hex(uchar *data, int len, char *prefix)
{
int i=0;
while(i<len) {
if(!i%16) {
DPRINTF("\n%s %04x: ", prefix, i);
}
else {
DPRINTF(": ");
}
DPRINTF("%02x", data[i++]);
}
DPRINTF("\n");
}
void dump_uhci(uint32_t port)
{
#if 0
unsigned long value;
#endif
DPRINTF("HCI at %08x\n", port);
#if 0
value = inw(port);
DPRINTF("Command: %04x\n", value);
value = inw(port+2);
DPRINTF("USBSTS: %04x\n", value);
value = inw(port+4);
DPRINTF("USBINTR: %04x\n", value);
value = inw(port+6);
DPRINTF("FRNUM: %04x\n", value);
value = inl(port+8);
DPRINTF("FLBASEADD: %08x\n", value);
value = inb(port+0x0c);
DPRINTF("SOFMOD: %02x\n", value);
value = inw(port+0x10);
DPRINTF("PORTSTS1: %04x\n", value);
value = inw(port+0x12);
DPRINTF("PORTSTS2: %04x\n", value);
#endif
}
void dump_td( td_t *td, char *prefix)
{
char newpre[64];
newpre[0]='\t';
strcpy(newpre+1, prefix);
DPRINTF("%sTD(%08x):\n", prefix, td);
switch(td->packet_type) {
case SETUP_TOKEN:
DPRINTF("%stype: SETUP\n", prefix);
break;
case OUT_TOKEN:
DPRINTF("%stype: OUT\n", prefix);
break;
case IN_TOKEN:
DPRINTF("%stype: IN\n", prefix);
break;
default:
DPRINTF("%stype: INVALID (%02x)\n", prefix, td->packet_type);
break;
}
DPRINTF("%sretries: %x\n", prefix, td->retrys);
if(td->isochronous) {
DPRINTF("%sisochronous\n", prefix);
}
if(td->interrupt) {
DPRINTF("%sIOC\n", prefix);
}
if(td->lowspeed) {
DPRINTF("%slowspeed\n", prefix);
}
if(td->detect_short) {
DPRINTF("%sDETECT_SHORT\n", prefix);
}
DPRINTF("%sactive: %04x\n", prefix, td->active);
DPRINTF("%sdevice_addr: %02x\n", prefix, td->device_addr);
DPRINTF("%sendpoint: %1x\n", prefix, td->endpoint);
DPRINTF("%sdata_toggle: %1x\n", prefix, td->data_toggle);
DPRINTF("%smax_transfer: %x\n", prefix, td->max_transfer);
DPRINTF("%sactual: %x\n", prefix, td->actual);
DPRINTF("%slink:\n", prefix);
if(td->stall) {
DPRINTF("%sSTALL\n", prefix);
}
if(td->bitstuff) {
DPRINTF("%sBITSTUFF ERROR\n", prefix);
}
if(td->crc) {
DPRINTF("%sCRC ERROR\n", prefix);
}
if(td->nak) {
DPRINTF("%sNAK ERROR\n", prefix);
}
if(td->babble) {
DPRINTF("%sBABBLE ERROR\n", prefix);
}
if(td->buffer_error) {
DPRINTF("%sBUFFER ERROR\n", prefix);
}
if(MEM_ADDR(td->link.link) == td) {
DPRINTF("link loops back to me!\n");
return;
}
dump_link(&(td->link), newpre);
if(!td->link.terminate) {
if(td->link.queue)
dump_queue_head(MEM_ADDR(td->link.link), prefix );
else
dump_td(MEM_ADDR(td->link.link), prefix);
}
}
void dump_queue_head( queue_head_t *qh, char *prefix)
{
char newpre[64];
newpre[0] = '\t';
strcpy(newpre+1, prefix);
DPRINTF("%sQUEUE HEAD(%x):\n", prefix, qh);
DPRINTF("%sdepth:\n", prefix);
dump_link( &(qh->depth), newpre);
if(!qh->depth.terminate) {
if(qh->depth.queue) {
dump_queue_head(MEM_ADDR(qh->depth.link), newpre);
}
else {
dump_td( MEM_ADDR(qh->depth.link), newpre);
}
}
DPRINTF("%sbredth:\n", prefix);
dump_link( &(qh->bredth), newpre);
if(!qh->bredth.terminate) {
if(qh->bredth.queue) {
dump_queue_head(MEM_ADDR(qh->bredth.link), newpre);
}
else {
dump_td( MEM_ADDR(qh->bredth.link), newpre);
}
}
}
void dump_transaction( transaction_t *trans, char *prefix)
{
char newpre[64];
newpre[0] = '\t';
strcpy(newpre+1, prefix);
DPRINTF("%s TRANSACTION(%x):\n", prefix, trans);
dump_queue_head( trans->qh, newpre);
DPRINTF("%s TDs:\n", prefix);
dump_td( trans->td_list, newpre);
DPRINTF("\n");
if(trans->next)
dump_transaction(trans->next, prefix);
}
void dump_usbdev( usbdev_t *dev, char *prefix)
{
char newpre[64];
int i;
newpre[0] = '\t';
strcpy(newpre+1, prefix);
DPRINTF("%saddress: %x\n", prefix, dev->address);
DPRINTF("%sclass: %x\n", prefix, dev->class);
DPRINTF("%ssubclass: %x\n", prefix, dev->subclass);
DPRINTF("%sbulk_in: %x\n", prefix, dev->bulk_in);
DPRINTF("%sbulk_out: %x\n", prefix, dev->bulk_out);
DPRINTF("%sinterrupt: %x\n", prefix, dev->interrupt);
DPRINTF("%sep toggle:\n", prefix);
for(i=0;i<MAX_EP;i++) {
DPRINTF("%s%x\n", newpre, dev->toggle[i]);
}
DPRINTF("%sep max_packet:\n", prefix);
for(i=0;i<MAX_EP;i++) {
DPRINTF("%s%x\n", newpre, dev->max_packet[i]);
}
}
void dump_all_usbdev(char *prefix)
{
int i;
for(i=0;i<MAX_USB_DEV;i++) {
if(usb_device[i].address) {
DPRINTF("%sDEVICE: %x\n", prefix, i);
dump_usbdev( usb_device +i, prefix);
}
}
}
void dump_device_descriptor( device_descriptor_t *des, char *prefix)
{
DPRINTF("%sbLength: %02x\n", prefix, des->bLength);
DPRINTF("%stype: %02x\n", prefix, des->type);
DPRINTF("%sbcdVersion: %1x%1x\n", prefix, des->bcdVersion[1], des->bcdVersion[0]);
DPRINTF("%sClass: %02x\n",prefix, des->Class);
DPRINTF("%sSubClass: %02x\n",prefix, des->SubClass);
DPRINTF("%sprotocol: %02x\n",prefix, des->protocol);
DPRINTF("%smax_packet: %x\n",prefix, des->max_packet);
DPRINTF("%sidVendor: %04x\n", prefix, des->idVendor);
DPRINTF("%sidProduct: %04x\n", prefix, des->idProduct);
DPRINTF("%sbcdDeviceVersion: %1x%1x\n", prefix, des->bcdDevice[1], des->bcdDevice[0]);
DPRINTF("%siManufacturor: %02x\n", prefix, des->iManufacturor);
DPRINTF("%siProduct: %02x\n", prefix, des->iProduct);
DPRINTF("%siSerial: %02x\n", prefix, des->iSerial);
DPRINTF("%sbNumConfig: %02x\n", prefix, des->bNumConfig);
}
void dump_interface_descriptor( interface_descriptor_t *iface, char *prefix)
{
DPRINTF("%sbLength: %02x\n", prefix, iface->bLength);
DPRINTF("%stype: %02x\n", prefix, iface->type);
DPRINTF("%sbInterfaceNumber: %02x\n", prefix, iface->bInterfaceNumber);
DPRINTF("%sbAlternateSetting: %02x\n", prefix, iface->bAlternateSetting);
DPRINTF("%sbNumEndpoints: %02x\n", prefix, iface->bNumEndpoints);
DPRINTF("%sbInterfaceClass: %02x\n", prefix, iface->bInterfaceClass);
DPRINTF("%sbInterfaceSubClass: %02x\n", prefix, iface->bInterfaceSubClass);
DPRINTF("%sbInterfaceProtocol: %02x\n", prefix, iface->bInterfaceProtocol);
DPRINTF("%siInterface: %02x\n", prefix, iface->iInterface);
}
void dump_endpoint_descriptor( endpoint_descriptor_t *ep, char *prefix)
{
DPRINTF("%sbLength: %02x\n", prefix, ep->bLength);
DPRINTF("%stype: %02x\n", prefix, ep->type);
DPRINTF("%sbEndpointAddress: %02x\n", prefix, ep->bEndpointAddress);
DPRINTF("%sbmAttributes: %02x\n", prefix, ep->bmAttributes);
DPRINTF("%swMaxPacketSize: %02x\n", prefix, ep->wMaxPacketSize);
DPRINTF("%sbInterval: %02x\n", prefix, ep->bInterval);
}
void dump_config_descriptor( uchar *des, char *prefix) // YES uchar *
{
config_descriptor_t *config;
interface_descriptor_t *iface;
endpoint_descriptor_t *ep;
char newpre[64];
int i;
memset(newpre,0,sizeof(newpre));
newpre[0] = '\t';
strcpy(newpre+1, prefix);
config = (config_descriptor_t *) des;
iface = (interface_descriptor_t *) (des + config->bLength);
ep = (endpoint_descriptor_t *) (des + config->bLength + iface->bLength);
// now, the config itself
DPRINTF("%sbLength: %02x\n", prefix, config->bLength);
DPRINTF("%stype: %02x\n", prefix, config->type);
DPRINTF("%swTotalLength: %04x\n", prefix, config->wTotalLength);
DPRINTF("%sbNumInterfaces: %02x\n", prefix, config->bNumInterfaces);
DPRINTF("%sbConfigurationValue: %02x\n", prefix, config->bConfigurationValue);
DPRINTF("%siConfiguration: %02x\n", prefix, config->iConfiguration);
DPRINTF("%sbmAttributes: %02x\n", prefix, config->bmAttributes);
DPRINTF("%sbMaxPower: %02x\n", prefix, config->bMaxPower);
DPRINTF("\n%sInterface(%x):\n", prefix, iface);
dump_interface_descriptor(iface, newpre);
newpre[1] = '\t';
strcpy(newpre+2, prefix);
for(i=0; i<iface->bNumEndpoints; i++) {
DPRINTF("\n%sEndpoint (%x):\n", newpre+1, ep+i);
dump_endpoint_descriptor( ep+i, newpre);
}
}
// Some control message bmRequestType defines
#define CTRL_DEVICE 0
#define CONTROL_INTERFACE 1
#define CONTROL_ENDPOINT 2
#define CONTROL_OTHER 3
#define CONTROL_RECIPIENT_MASK 0x1f
#define CONTROL_TYPE_STD 0
#define CONTROL_TYPE_CLASS 0x20
#define CONTROL_CLASS_VENDOR 0x40
#define CONTROL_CLASS_MASK 0x60
#define CONTROL_OUT 0
#define CONTROL_IN 0x80
#define CONTROL_DIR_MASK 0x80
// bRequest values
#define GET_STATUS 0
#define CLEAR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADDRESS 5
#define GET_DESCRIPTOR 6
#define SET_DESCRIPTOR 7
#define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
#define SYNC_FRAME 12
// descriptor types
#define DEVICE_DESC 1
#define CONFIGURATION_DESC 2
#define STRING_DESC 3
#define INTERFACE_DESC 4
#define ENDPOINT_DESC 5
#define OTHERSPEED_DESC 7
#define POWER_DESC 8
// features
#define FEATURE_HALT 0
void dump_ctrlmsg( ctrl_msg_t *msg, char *prefix)
{
DPRINTF("%sbmRequestType: %02x\n", prefix, msg->bmRequestType);
DPRINTF("%sbRequest: %02x\n", prefix, msg->bRequest);
DPRINTF("%swValue: %04x\n", prefix, msg->wValue);
DPRINTF("%swIndex: %04x\n", prefix, msg->wIndex);
DPRINTF("%swLength: %04x\n", prefix, msg->wLength);
}
#endif