⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_uhci.c

📁 适合KS8695X
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -