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

📄 au1x00_usb_ohci.c

📁 linux下的BOOT程序原码,有需要的可以来下,保证好用
💻 C
📖 第 1 页 / 共 4 页
字号:
		}	}	dev->status = stat;	dev->act_len = transfer_len;#ifdef DEBUG	pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));#else	wait_ms(1);#endif	/* free TDs in urb_priv */	urb_free_priv (&urb_priv);	return 0;}/* submit routines called from usb.c */int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		int transfer_len){	info("submit_bulk_msg");	return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);}int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		int transfer_len, struct devrequest *setup){	int maxsize = usb_maxpacket(dev, pipe);	info("submit_control_msg");#ifdef DEBUG	urb_priv.actual_length = 0;	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));#else	wait_ms(1);#endif	if (!maxsize) {		err("submit_control_message: pipesize for pipe %lx is zero",			pipe);		return -1;	}	if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {		gohci.rh.dev = dev;		/* root hub - redirect */		return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,			setup);	}	return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);}int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,		int transfer_len, int interval){	info("submit_int_msg");	return -1;}/*-------------------------------------------------------------------------* * HC functions *-------------------------------------------------------------------------*//* reset the HC and BUS */static int hc_reset (ohci_t *ohci){	int timeout = 30;	int smm_timeout = 50; /* 0,5 sec */	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */		writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */		info("USB HC TakeOver from SMM");		while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {			wait_ms (10);			if (--smm_timeout == 0) {				err("USB HC TakeOver failed!");				return -1;			}		}	}	/* Disable HC interrupts */	writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);	dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",		ohci->slot_name,		readl (&ohci->regs->control));	/* Reset USB (needed by some controllers) */	writel (0, &ohci->regs->control);	/* HC Reset requires max 10 us delay */	writel (OHCI_HCR,  &ohci->regs->cmdstatus);	while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {		if (--timeout == 0) {			err("USB HC reset timed out!");			return -1;		}		udelay (1);	}	return 0;}/*-------------------------------------------------------------------------*//* Start an OHCI controller, set the BUS operational * enable interrupts * connect the virtual root hub */static int hc_start (ohci_t * ohci){	__u32 mask;	unsigned int fminterval;	ohci->disabled = 1;	/* Tell the controller where the control and bulk lists are	 * The lists are empty now. */	writel (0, &ohci->regs->ed_controlhead);	writel (0, &ohci->regs->ed_bulkhead);	writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */	fminterval = 0x2edf;	writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);	fminterval |= ((((fminterval - 210) * 6) / 7) << 16);	writel (fminterval, &ohci->regs->fminterval);	writel (0x628, &ohci->regs->lsthresh);	/* start controller operations */	ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;	ohci->disabled = 0;	writel (ohci->hc_control, &ohci->regs->control);	/* disable all interrupts */	mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |			OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |			OHCI_INTR_OC | OHCI_INTR_MIE);	writel (mask, &ohci->regs->intrdisable);	/* clear all interrupts */	mask &= ~OHCI_INTR_MIE;	writel (mask, &ohci->regs->intrstatus);	/* Choose the interrupts we care about now  - but w/o MIE */	mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;	writel (mask, &ohci->regs->intrenable);#ifdef	OHCI_USE_NPS	/* required for AMD-756 and some Mac platforms */	writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,		&ohci->regs->roothub.a);	writel (RH_HS_LPSC, &ohci->regs->roothub.status);#endif	/* OHCI_USE_NPS */#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);})	/* POTPGT delay is bits 24-31, in 2 ms units. */	mdelay ((roothub_a (ohci) >> 23) & 0x1fe);	/* connect the virtual root hub */	ohci->rh.devnum = 0;	return 0;}/*-------------------------------------------------------------------------*//* an interrupt happens */static inthc_interrupt (void){	ohci_t *ohci = &gohci;	struct ohci_regs *regs = ohci->regs;	int ints;	int stat = -1;	if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) {		ints =	OHCI_INTR_WDH;	} else {		ints = readl (&regs->intrstatus);	}	/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */	if (ints & OHCI_INTR_RHSC) {		got_rhsc = 1;	}	if (ints & OHCI_INTR_UE) {		ohci->disabled++;		err ("OHCI Unrecoverable Error, controller usb-%s disabled",			ohci->slot_name);		/* e.g. due to PCI Master/Target Abort */#ifdef	DEBUG		ohci_dump (ohci, 1);#else	wait_ms(1);#endif		/* FIXME: be optimistic, hope that bug won't repeat often. */		/* Make some non-interrupt context restart the controller. */		/* Count and limit the retries though; either hardware or */		/* software errors can go forever... */		hc_reset (ohci);		return -1;	}	if (ints & OHCI_INTR_WDH) {		wait_ms(1);		writel (OHCI_INTR_WDH, &regs->intrdisable);		stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));		writel (OHCI_INTR_WDH, &regs->intrenable);	}	if (ints & OHCI_INTR_SO) {		dbg("USB Schedule overrun\n");		writel (OHCI_INTR_SO, &regs->intrenable);		stat = -1;	}	/* FIXME:  this assumes SOF (1/ms) interrupts don't get lost... */	if (ints & OHCI_INTR_SF) {		unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;		wait_ms(1);		writel (OHCI_INTR_SF, &regs->intrdisable);		if (ohci->ed_rm_list[frame] != NULL)			writel (OHCI_INTR_SF, &regs->intrenable);		stat = 0xff;	}	writel (ints, &regs->intrstatus);	return stat;}/*-------------------------------------------------------------------------*//*-------------------------------------------------------------------------*//* De-allocate all resources.. */static void hc_release_ohci (ohci_t *ohci){	dbg ("USB HC release ohci usb-%s", ohci->slot_name);	if (!ohci->disabled)		hc_reset (ohci);}/*-------------------------------------------------------------------------*/#define __read_32bit_c0_register(source, sel)				\({ int __res;								\	if (sel == 0)							\		__asm__ __volatile__(					\			"mfc0\t%0, " #source "\n\t"			\			: "=r" (__res));				\	else								\		__asm__ __volatile__(					\			".set\tmips32\n\t"				\			"mfc0\t%0, " #source ", " #sel "\n\t"		\			".set\tmips0\n\t"				\			: "=r" (__res));				\	__res;								\})#define read_c0_prid()		__read_32bit_c0_register($15, 0)/* * low level initalisation routine, called from usb.c */static char ohci_inited = 0;int usb_lowlevel_init(void){	u32 pin_func;	u32 sys_freqctrl, sys_clksrc;	u32 prid = read_c0_prid();	dbg("in usb_lowlevel_init\n");	/* zero and disable FREQ2 */	sys_freqctrl = au_readl(SYS_FREQCTRL0);	sys_freqctrl &= ~0xFFF00000;	au_writel(sys_freqctrl, SYS_FREQCTRL0);	/* zero and disable USBH/USBD clocks */	sys_clksrc = au_readl(SYS_CLKSRC);	sys_clksrc &= ~0x00007FE0;	au_writel(sys_clksrc, SYS_CLKSRC);	sys_freqctrl = au_readl(SYS_FREQCTRL0);	sys_freqctrl &= ~0xFFF00000;	sys_clksrc = au_readl(SYS_CLKSRC);	sys_clksrc &= ~0x00007FE0;	switch (prid & 0x000000FF) {	case 0x00: /* DA */	case 0x01: /* HA */	case 0x02: /* HB */		/* CPU core freq to 48MHz to slow it way down... */		au_writel(4, SYS_CPUPLL);		/*		 * Setup 48MHz FREQ2 from CPUPLL for USB Host		 */		/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */		sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));		au_writel(sys_freqctrl, SYS_FREQCTRL0);		/* CPU core freq to 384MHz */		au_writel(0x20, SYS_CPUPLL);		printf("Au1000: 48MHz OHCI workaround enabled\n");		break;	default:  /* HC and newer */		/* FREQ2 = aux/2 = 48 MHz */		sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));		au_writel(sys_freqctrl, SYS_FREQCTRL0);		break;	}	/*	 * Route 48MHz FREQ2 into USB Host and/or Device	 */	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));	au_writel(sys_clksrc, SYS_CLKSRC);	/* configure pins GPIO[14:9] as GPIO */	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);	au_writel(pin_func, SYS_PINFUNC);	au_writel(0x2800, SYS_TRIOUTCLR);	au_writel(0x0030, SYS_OUTPUTCLR);	dbg("OHCI board setup complete\n");	/* enable host controller */	au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);	udelay(1000);	au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);	udelay(1000);	/* wait for reset complete (read register twice; see au1500 errata) */	while (au_readl(USB_HOST_CONFIG),	       !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))		udelay(1000);	dbg("OHCI clock running\n");	memset (&gohci, 0, sizeof (ohci_t));	memset (&urb_priv, 0, sizeof (urb_priv_t));	/* align the storage */	if ((__u32)&ghcca[0] & 0xff) {		err("HCCA not aligned!!");		return -1;	}	phcca = &ghcca[0];	info("aligned ghcca %p", phcca);	memset(&ohci_dev, 0, sizeof(struct ohci_device));	if ((__u32)&ohci_dev.ed[0] & 0x7) {		err("EDs not aligned!!");		return -1;	}	memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));	if ((__u32)gtd & 0x7) {		err("TDs not aligned!!");		return -1;	}	ptd = gtd;	gohci.hcca = phcca;	memset (phcca, 0, sizeof (struct ohci_hcca));	gohci.disabled = 1;	gohci.sleeping = 0;	gohci.irq = -1;	gohci.regs = (struct ohci_regs *)(USB_OHCI_BASE | 0xA0000000);	gohci.flags = 0;	gohci.slot_name = "au1x00";	dbg("OHCI revision: 0x%08x\n"	       "  RH: a: 0x%08x b: 0x%08x\n",	       readl(&gohci.regs->revision),	       readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b));	if (hc_reset (&gohci) < 0)		goto errout;	/* FIXME this is a second HC reset; why?? */	writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);	wait_ms (10);	if (hc_start (&gohci) < 0)		goto errout;#ifdef	DEBUG	ohci_dump (&gohci, 1);#else	wait_ms(1);#endif	ohci_inited = 1;	return 0;  errout:	err("OHCI initialization error\n");	hc_release_ohci (&gohci);	/* Initialization failed */	au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);	return -1;}int usb_lowlevel_stop(void){	/* this gets called really early - before the controller has */	/* even been initialized! */	if (!ohci_inited)		return 0;	/* TODO release any interrupts, etc. */	/* call hc_release_ohci() here ? */	hc_reset (&gohci);	/* may not want to do this */	/* Disable clock */	au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);	return 0;}#endif /* CONFIG_USB_OHCI */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -