📄 usb_uhci.c
字号:
void *data = buffer;
int leni = transfer_len;
int len = 0;
int status = 0;
int stat = 0;
int i;
unsigned short cstatus;
unsigned short bmRType_bReq;
unsigned short wValue;
unsigned short wIndex;
unsigned short wLength;
if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
printf("Root-Hub submit IRQ: NOT implemented\n");
#if 0
uhci->rh.urb = urb;
uhci->rh.send = 1;
uhci->rh.interval = urb->interval;
rh_init_int_timer (urb);
#endif
return 0;
}
bmRType_bReq = cmd->requesttype | cmd->request << 8;
wValue = swap_16(cmd->value);
wIndex = swap_16(cmd->index);
wLength = swap_16(cmd->length);
usb_display_Req(bmRType_bReq);
for (i = 0; i < 8; i++)
rh.c_p_r[i] = 0;
USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
dev->devnum, 8, cmd->requesttype,cmd->request, wValue, wIndex, wLength);
switch (bmRType_bReq) {
/* Request Destination:
without flags: Device,
RH_INTERFACE: interface,
RH_ENDPOINT: endpoint,
RH_CLASS means HUB here,
RH_OTHER | RH_CLASS almost ever means HUB_PORT here
*/
case RH_GET_STATUS:
*(unsigned short *) data = swap_16(1);
len=2;
break;
case RH_GET_STATUS | RH_INTERFACE:
*(unsigned short *) data = swap_16(0);
len=2;
break;
case RH_GET_STATUS | RH_ENDPOINT:
*(unsigned short *) data = swap_16(0);
len=2;
break;
case RH_GET_STATUS | RH_CLASS:
*(unsigned long *) data = swap_32(0);
len=4;
break; /* hub power ** */
case RH_GET_STATUS | RH_OTHER | RH_CLASS:
status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
((status & USBPORTSC_PEC) >> (3 - 1)) |
(rh.c_p_r[wIndex - 1] << (0 + 4));
status = (status & USBPORTSC_CCS) |
((status & USBPORTSC_PE) >> (2 - 1)) |
((status & USBPORTSC_SUSP) >> (12 - 2)) |
((status & USBPORTSC_PR) >> (9 - 4)) |
(1 << 8) | /* power on ** */
((status & USBPORTSC_LSDA) << (-8 + 9));
*(unsigned short *) data = swap_16(status);
*(unsigned short *) (data + 2) = swap_16(cstatus);
len=4;
break;
case RH_CLEAR_FEATURE | RH_ENDPOINT:
switch (wValue) {
case (RH_ENDPOINT_STALL):
len=0;
break;
}
break;
case RH_CLEAR_FEATURE | RH_CLASS:
switch (wValue) {
case (RH_C_HUB_OVER_CURRENT):
len=0; /* hub power over current ** */
break;
}
break;
case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
usb_display_wValue(wValue,wIndex);
switch (wValue) {
case (RH_PORT_ENABLE):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) & ~USBPORTSC_PE;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
case (RH_PORT_SUSPEND):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) & ~USBPORTSC_SUSP;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
case (RH_PORT_POWER):
len=0; /* port power ** */
break;
case (RH_C_PORT_CONNECTION):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) | USBPORTSC_CSC;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
case (RH_C_PORT_ENABLE):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) | USBPORTSC_PEC;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
case (RH_C_PORT_SUSPEND):
/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
len=0;
break;
case (RH_C_PORT_OVER_CURRENT):
len=0;
break;
case (RH_C_PORT_RESET):
rh.c_p_r[wIndex - 1] = 0;
len=0;
break;
}
break;
case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
usb_display_wValue(wValue,wIndex);
switch (wValue) {
case (RH_PORT_SUSPEND):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) | USBPORTSC_SUSP;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
case (RH_PORT_RESET):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) | USBPORTSC_PR;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
wait_ms(10);
status = (status & 0xfff5) & ~USBPORTSC_PR;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
udelay(10);
status = (status & 0xfff5) | USBPORTSC_PE;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
wait_ms(10);
status = (status & 0xfff5) | 0xa;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
case (RH_PORT_POWER):
len=0; /* port power ** */
break;
case (RH_PORT_ENABLE):
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) | USBPORTSC_PE;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
break;
}
break;
case RH_SET_ADDRESS:
rh.devnum = wValue;
len=0;
break;
case RH_GET_DESCRIPTOR:
switch ((wValue & 0xff00) >> 8) {
case (0x01): /* device descriptor */
i=sizeof(root_hub_config_des);
status=i > wLength ? wLength : i;
len = leni > status ? status : leni;
memcpy (data, root_hub_dev_des, len);
break;
case (0x02): /* configuration descriptor */
i=sizeof(root_hub_config_des);
status=i > wLength ? wLength : i;
len = leni > status ? status : leni;
memcpy (data, root_hub_config_des, len);
break;
case (0x03): /*string descriptors */
if(wValue==0x0300) {
i=sizeof(root_hub_str_index0);
status = i > wLength ? wLength : i;
len = leni > status ? status : leni;
memcpy (data, root_hub_str_index0, len);
break;
}
if(wValue==0x0301) {
i=sizeof(root_hub_str_index1);
status = i > wLength ? wLength : i;
len = leni > status ? status : leni;
memcpy (data, root_hub_str_index1, len);
break;
}
stat = USB_ST_STALLED;
}
break;
case RH_GET_DESCRIPTOR | RH_CLASS:
root_hub_hub_des[2] = 2;
i=sizeof(root_hub_hub_des);
status= i > wLength ? wLength : i;
len = leni > status ? status : leni;
memcpy (data, root_hub_hub_des, len);
break;
case RH_GET_CONFIGURATION:
*(unsigned char *) data = 0x01;
len = 1;
break;
case RH_SET_CONFIGURATION:
len=0;
break;
default:
stat = USB_ST_STALLED;
}
USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n",stat,
in16r(usb_base_addr + USBPORTSC1), in16r(usb_base_addr + USBPORTSC2));
dev->act_len=len;
dev->status=stat;
return stat;
}
/********************************************************************************
* Some Debug Routines
*/
#ifdef USB_RH_DEBUG
static void usb_display_Req(unsigned short req)
{
USB_RH_PRINTF("- Root-Hub Request: ");
switch (req) {
case RH_GET_STATUS:
USB_RH_PRINTF("Get Status ");
break;
case RH_GET_STATUS | RH_INTERFACE:
USB_RH_PRINTF("Get Status Interface ");
break;
case RH_GET_STATUS | RH_ENDPOINT:
USB_RH_PRINTF("Get Status Endpoint ");
break;
case RH_GET_STATUS | RH_CLASS:
USB_RH_PRINTF("Get Status Class");
break; /* hub power ** */
case RH_GET_STATUS | RH_OTHER | RH_CLASS:
USB_RH_PRINTF("Get Status Class Others");
break;
case RH_CLEAR_FEATURE | RH_ENDPOINT:
USB_RH_PRINTF("Clear Feature Endpoint ");
break;
case RH_CLEAR_FEATURE | RH_CLASS:
USB_RH_PRINTF("Clear Feature Class ");
break;
case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
USB_RH_PRINTF("Clear Feature Other Class ");
break;
case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
USB_RH_PRINTF("Set Feature Other Class ");
break;
case RH_SET_ADDRESS:
USB_RH_PRINTF("Set Address ");
break;
case RH_GET_DESCRIPTOR:
USB_RH_PRINTF("Get Descriptor ");
break;
case RH_GET_DESCRIPTOR | RH_CLASS:
USB_RH_PRINTF("Get Descriptor Class ");
break;
case RH_GET_CONFIGURATION:
USB_RH_PRINTF("Get Configuration ");
break;
case RH_SET_CONFIGURATION:
USB_RH_PRINTF("Get Configuration ");
break;
default:
USB_RH_PRINTF("****UNKNOWN**** 0x%04X ",req);
}
USB_RH_PRINTF("\n");
}
static void usb_display_wValue(unsigned short wValue,unsigned short wIndex)
{
switch (wValue) {
case (RH_PORT_ENABLE):
USB_RH_PRINTF("Root-Hub: Enable Port %d\n",wIndex);
break;
case (RH_PORT_SUSPEND):
USB_RH_PRINTF("Root-Hub: Suspend Port %d\n",wIndex);
break;
case (RH_PORT_POWER):
USB_RH_PRINTF("Root-Hub: Port Power %d\n",wIndex);
break;
case (RH_C_PORT_CONNECTION):
USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n",wIndex);
break;
case (RH_C_PORT_ENABLE):
USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n",wIndex);
break;
case (RH_C_PORT_SUSPEND):
USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n",wIndex);
break;
case (RH_C_PORT_OVER_CURRENT):
USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",wIndex);
break;
case (RH_C_PORT_RESET):
USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n",wIndex);
break;
default:
USB_RH_PRINTF("Root-Hub: unknown %x %x\n",wValue,wIndex);
break;
}
}
#endif
#ifdef USB_UHCI_DEBUG
static int usb_display_td(uhci_td_t *td)
{
unsigned long tmp;
int valid;
printf("TD at %p:\n",td);
tmp=swap_32(td->link);
printf("Link points to 0x%08lX, %s first, %s, %s\n",tmp&0xfffffff0,
((tmp & 0x4)==0x4) ? "Depth" : "Breath",
((tmp & 0x2)==0x2) ? "QH" : "TD",
((tmp & 0x1)==0x1) ? "invalid" : "valid");
valid=((tmp & 0x1)==0x0);
tmp=swap_32(td->status);
printf(" %s %ld Errors %s %s %s \n %s %s %s %s %s %s\n Len 0x%lX\n",
(((tmp>>29)&0x1)==0x1) ? "SPD Enable" : "SPD Disable",
((tmp>>28)&0x3),
(((tmp>>26)&0x1)==0x1) ? "Low Speed" : "Full Speed",
(((tmp>>25)&0x1)==0x1) ? "ISO " : "",
(((tmp>>24)&0x1)==0x1) ? "IOC " : "",
(((tmp>>23)&0x1)==0x1) ? "Active " : "Inactive ",
(((tmp>>22)&0x1)==0x1) ? "Stalled" : "",
(((tmp>>21)&0x1)==0x1) ? "Data Buffer Error" : "",
(((tmp>>20)&0x1)==0x1) ? "Babble" : "",
(((tmp>>19)&0x1)==0x1) ? "NAK" : "",
(((tmp>>18)&0x1)==0x1) ? "Bitstuff Error" : "",
(tmp&0x7ff));
tmp=swap_32(td->info);
printf(" MaxLen 0x%lX\n",((tmp>>21)&0x7FF));
printf(" %s Endpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",((tmp>>19)&0x1)==0x1 ? "TOGGLE" : "",
((tmp>>15)&0xF),((tmp>>8)&0x7F),tmp&0xFF);
tmp=swap_32(td->buffer);
printf(" Buffer 0x%08lX\n",tmp);
printf(" DEV %08lX\n",td->dev_ptr);
return valid;
}
void usb_show_td(int max)
{
int i;
if(max>0) {
for(i=0;i<max;i++) {
usb_display_td(&tmp_td[i]);
}
}
else {
i=0;
do {
printf("tmp_td[%d]\n",i);
}while(usb_display_td(&tmp_td[i++]));
}
}
#endif
#endif /* CONFIG_USB_UHCI */
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -