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

📄 ehci-hcd-fotg2xx.c

📁 WiFi IP-Cam solution. FIC8120 platform VIA VT6656 USB Module driver source code.
💻 C
📖 第 1 页 / 共 3 页
字号:
	//Add Einsn@VIA#if 1    ehci->i_thresh = 8;#else	if (HCC_ISOC_CACHE (hcc_params)) 	// full frame cache		ehci->i_thresh = 8;	else					// N microframes cached		ehci->i_thresh = 2 + HCC_ISOC_THRES (hcc_params);#endif//End Add	ehci->reclaim = 0;	ehci->next_uframe = -1;	/* controller state:  unknown --> reset *///printk("ehci_start4\n");	/* EHCI spec section 4.1 */	if ((retval = ehci_reset (ehci)) != 0) {		ehci_mem_cleanup (ehci);		return retval;	}	writel (INTR_MASK, &ehci->regs->intr_enable);	writel (ehci->periodic_dma, &ehci->regs->frame_list);	/*	 * dedicate a qh for the async ring head, since we couldn't unlink	 * a 'real' qh without stopping the async schedule [4.8].  use it	 * as the 'reclamation list head' too.	 * its dummy is used in hw_alt_next of many tds, to prevent the qh	 * from automatically advancing to the next td after short reads.	 */	ehci->async->qh_next.qh = 0;	ehci->async->hw_next = QH_NEXT (ehci->async->qh_dma);	ehci->async->hw_info1 = cpu_to_le32 (QH_HEAD);	ehci->async->hw_token = cpu_to_le32 (QTD_STS_HALT);	ehci->async->hw_qtd_next = EHCI_LIST_END;	ehci->async->qh_state = QH_STATE_LINKED;	ehci->async->hw_alt_next = QTD_NEXT (ehci->async->dummy->qtd_dma);	writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);	/*	 * hcc_params controls whether ehci->regs->segment must (!!!)	 * be used; it constrains QH/ITD/SITD and QTD locations.	 * pci_pool consistent memory always uses segment zero.	 * streaming mappings for I/O buffers, like pci_map_single(),	 * can return segments above 4GB, if the device allows.	 *	 * NOTE:  the dma mask is visible through dma_supported(), so	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all	 * host side drivers though.	 *///Add Einsn@VIA#if  0	if (HCC_64BIT_ADDR (hcc_params)) {		writel (0, &ehci->regs->segment);		if (!pci_set_dma_mask (ehci->hcd.pdev, 0xffffffffffffffffULL))			ehci_info (ehci, "enabled 64bit PCI DMA\n");	}#endif //printk("ehci_start5\n");	/* help hc dma work well with cachelines *///	pci_set_mwi (ehci->hcd.pdev);	/* clere has no member upt enables, set irq latency */	temp = readl (&ehci->regs->command) & 0xff;	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)		log2_irq_thresh = 0;	temp |= 1 << (16 + log2_irq_thresh);//Einsn Mask <002>  2007-05-22 #if 0	// if hc can park (ehci >= 0.96), default is 3 packets per async QH 	if (HCC_PGM_FRAMELISTLEN (hcc_params)) {		/* periodic schedule size can be smaller than default */		temp &= ~(3 << 2);		temp |= (EHCI_TUNE_FLS << 2);		switch (EHCI_TUNE_FLS) {		case 0: ehci->periodic_size = 1024; break;		case 1: ehci->periodic_size = 512; break;		case 2: ehci->periodic_size = 256; break;		default:	BUG ();		}	}#endif 	temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),	// Philips, Intel, and maybe others need CMD_RUN before the	// root hub will detect new devices (why?); NEC doesn't//Add Einsn@VIA#if 0		temp |= CMD_RUN;#endif 	writel (temp, &ehci->regs->command);	dbg_cmd (ehci, "init", temp);	/* set async sleep time = 10 us ... ? */	init_timer (&ehci->watchdog);	ehci->watchdog.function = ehci_watchdog;	ehci->watchdog.data = (unsigned long) ehci;//printk("ehci_start6\n");	/* wire up the root hub */	bus = hcd_to_bus (hcd);	bus->root_hub = udev = usb_alloc_dev (NULL, bus);	if (!udev) {done2:		ehci_mem_cleanup (ehci);		return -ENOMEM;	}	/*	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices	 * are explicitly handed to companion controller(s), so no TT is	 * involved with the root hub.	 */	ehci->hcd.state = USB_STATE_READY;//Add Einsn@VIA#if 0	writel (FLAG_CF, &ehci->regs->configured_flag);#endif 	readl (&ehci->regs->command);	/* unblock posted write */        /* PCI Serial Bus Release Number is at 0x60 offset *///Einsn@VIA	pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);	temp = readw (&ehci->caps->hci_version);//Einsn Mask <003>  2007-05-22 		/*	ehci_info (ehci,		"USB %x.%x enabled, EHCI %x.%02x, driver %s\n",		((tempbyte & 0xf0)>>4), (tempbyte & 0x0f),		temp >> 8, temp & 0xff, DRIVER_VERSION);*/	/*	 * From here on, khubd concurrently accesses the root	 * hub; drivers will be talking to enumerated devices.	 *	 * Before this point the HC was idle/ready.  After, khubd	 * and device drivers may start it running.	 *///printk("ehci_start7\n");	usb_connect (udev);	udev->speed = USB_SPEED_HIGH;//Start;;Faraday-EHCI(FOTG2XX)	ehci->hcd.bus->otg_port = 1;//Faraday OTG dafault port=1	printk("Set OTG port=1\n");//End;;Faraday-EHCI(FOTG2XX)	if (hcd_register_root (hcd) != 0) {		if (hcd->state == USB_STATE_RUNNING)			ehci_ready (ehci);		ehci_reset (ehci);		bus->root_hub = 0;		retval = -ENODEV;		goto done2;	}	create_debug_files (ehci);//*** Connect Host to OTG //For OTG//Start;;Faraday-EHCI(FOTG2XX)    //Init otg port	ehci->transceiver = FOTG2XX_get_otg_transceiver();	if (ehci->transceiver) {	   int	status = otg_set_host(ehci->transceiver,ehci->hcd.bus);	   DBG_HOST_EHCI("init %s transceiver, status %d\n",					 ehci->transceiver->label, status);	   if (status) {	      if (ehci->transceiver)		     printk("??? HCD=>otg_set_host fail ...\n");			 return status;	   }	}	else {	   printk("can't find transceiver\n");	   return -ENODEV;	}//End;;Faraday-EHCI(FOTG2XX)	return 0;}/* always called by thread; normally rmmod */static void ehci_stop (struct usb_hcd *hcd){	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);	ehci_dbg (ehci, "stop\n");	/* no more interrupts ... */	if (hcd->state == USB_STATE_RUNNING)		ehci_ready (ehci);	if (in_interrupt ()) {		/* must not happen!! */		ehci_err (ehci, "stopped in_interrupt!\n");		return;	}	del_timer_sync (&ehci->watchdog);	ehci_reset (ehci);//Einsn Mask <002>  2007-05-22 #if 0	/* let companion controllers work when we aren't */	writel (0, &ehci->regs->configured_flag);#endif	remove_debug_files (ehci);	/* root hub is shut down separately (first, when possible) */	spin_lock_irq (&ehci->lock);	ehci_work (ehci, NULL);	spin_unlock_irq (&ehci->lock);	ehci_mem_cleanup (ehci);#ifdef	EHCI_STATS	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld\n",		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim);	ehci_dbg (ehci, "complete %ld unlink %ld\n",		ehci->stats.complete, ehci->stats.unlink);#endif	dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));}static int ehci_get_frame (struct usb_hcd *hcd){	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);	return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;}/*-------------------------------------------------------------------------*/#ifdef	CONFIG_PM/* suspend/resume, section 4.3 */static int ehci_suspend (struct usb_hcd *hcd, u32 state){	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);	int			ports;	int			i;	dbg ("%s: suspend to %d", hcd_to_bus (hcd)->bus_name, state);	ports = HCS_N_PORTS (ehci->hcs_params);	// FIXME:  This assumes what's probably a D3 level suspend...	// FIXME:  usb wakeup events on this bus should resume the machine.	// pci config register PORTWAKECAP controls which ports can do it;	// bios may have initted the register...	/* suspend each port, then stop the hc */	for (i = 0; i < ports; i++) {		int	temp = readl (&ehci->regs->port_status [i]);#if 0    if (((temp & PORT_PE) == 0))      continue;#else		if ((temp & PORT_PE) == 0				|| (temp & PORT_OWNER) != 0)			continue;      #endifdbg ("%s: suspend port %d", hcd_to_bus (hcd)->bus_name, i);/*Einsn@VIA	*/	temp |= PORT_SUSPEND;/*Einsn@VIA	*/	writel (temp, &ehci->regs->port_status [i]);	}	if (hcd->state == USB_STATE_RUNNING)		ehci_ready (ehci);	writel (readl (&ehci->regs->command) & ~CMD_RUN, &ehci->regs->command);// save pci FLADJ value	/* who tells PCI to reduce power consumption? */	return 0;}static int ehci_resume (struct usb_hcd *hcd){	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);	int			ports;	int			i;	dbg ("%s: resume", hcd_to_bus (hcd)->bus_name);	ports = HCS_N_PORTS (ehci->hcs_params);	// FIXME:  if controller didn't retain state,	// return and let generic code clean it up	// test configured_flag ?	/* resume HC and each port */// restore pci FLADJ value	// khubd and drivers will set HC running, if needed;	hcd->state = USB_STATE_READY;	// FIXME Philips/Intel/... etc don't really have a "READY"	// state ... turn on CMD_RUN too	for (i = 0; i < ports; i++) {		int	temp = readl (&ehci->regs->port_status [i]);#if 0    if (((temp & PORT_PE) == 0))      continue;#else		if ((temp & PORT_PE) == 0				|| (temp & PORT_SUSPEND) != 0)			continue;#endif  dbg ("%s: resume port %d", hcd_to_bus (hcd)->bus_name, i);		temp |= PORT_RESUME;		writel (temp, &ehci->regs->port_status [i]);		readl (&ehci->regs->command);	/* unblock posted writes */		wait_ms (20);		temp &= ~PORT_RESUME;		writel (temp, &ehci->regs->port_status [i]);	}	readl (&ehci->regs->command);	/* unblock posted writes */	return 0;}#endif//Start;;Faraday-EHCI(FOTG2XX)static int ehci_disconnect_for_OTG (struct usb_hcd *hcd, u32 state){	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);	int			ports;	int			i,iTemp;    DBG_HOST_EHCI("### >>> Enter ehci-hcd.c file --> ehci_disconnect_for_OTG function \n");	ports = HCS_N_PORTS (ehci->hcs_params);	// FIXME:  This assumes what's probably a D3 level suspend...	// FIXME:  usb wakeup events on this bus should resume the machine.	// pci config register PORTWAKECAP controls which ports can do it;	// bios may have initted the register...	/* suspend each port, then stop the hc */	for (i = 0; i < ports; i++) {		int	temp = readl (&ehci->regs->port_status [i]);        if (((temp & PORT_PE) == 0))           continue;        dbg ("%s: suspend port %d", hcd->bus_name, i);        //Bruce;;04212005;;		temp |= PORT_SUSPEND;        //Bruce;;04212005;;		writel (temp, &ehci->regs->port_status [i]);	}	if (hcd->state == USB_STATE_RUNNING)		ehci_ready (ehci);	while (readl (&ehci->regs->status) & (STS_ASS | STS_PSS))		udelay (100);	writel (readl (&ehci->regs->command) & ~CMD_RUN, &ehci->regs->command);#if 0    iTemp = readl (&ehci->regs->port_status [0]);    if (iTemp&PORT_RESUME)    {       printk("TEMP===========> Detected the PORT_RESUME signal...\n");       iTemp &= ~PORT_RESUME;       writel (iTemp, &ehci->regs->port_status [0]);	}#endif#if 1    //Suspend the host;;    iTemp = readl (&ehci->regs->port_status [0]);    iTemp |= PORT_SUSPEND;    writel (iTemp, &ehci->regs->port_status [0]);#endif	return 0;}//End;;Faraday-EHCI(FOTG2XX)/*-------------------------------------------------------------------------*//* * ehci_work is called from some interrupts, timers, and so on. * it calls driver completion functions, after dropping ehci->lock. */static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs){	if (ehci->reclaim_ready)		end_unlink_async (ehci, regs);	scan_async (ehci, regs);	if (ehci->next_uframe != -1)		scan_periodic (ehci, regs);}/*-------------------------------------------------------------------------*/static void ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs){	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);	u32			status;	int			bh;	spin_lock (&ehci->lock);	status = readl (&ehci->regs->status);	/* e.g. cardbus physical eject */	if (status == ~(u32) 0) {		ehci_dbg (ehci, "device removed\n");		goto dead;	}	status &= INTR_MASK;	if (!status)			/* irq sharing? */		goto done;	/* clear (just) interrupts */	writel (status, &ehci->regs->status);

⌨️ 快捷键说明

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