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

📄 hc_sl811.c

📁 USB驱动实验 基于清华大学的TEB-44B0实验平台
💻 C
📖 第 1 页 / 共 3 页
字号:
 *                 *****************************************************************/static int hc_alloc_trans_buffer (hci_t * hci){	hcipriv_t *hp = &hci->hp;	int maxlen;	hp->itl0_len = 0;	hp->itl1_len = 0;	hp->atl_len = 0;	hp->itl_buffer_len = 1024;	hp->atl_buffer_len = 4096 - 2 * hp->itl_buffer_len;	/* 2048 */	maxlen = (hp->itl_buffer_len > hp->atl_buffer_len) ? hp->itl_buffer_len : hp->atl_buffer_len;	hp->tl = kmalloc (maxlen, GFP_KERNEL);	if (!hp->tl)		return -ENOMEM;	memset (hp->tl, 0, maxlen);	return 0;}/***************************************************************** * * Function Name: getPortStatusAndChange * * This function gets the ports status from SL811 and format it  * to a USB request format * * Input:  hci = data structure for the host controller * * Return value  : port status and change *                 *****************************************************************/static __u32 getPortStatusAndChange (hci_t * hci){	hcipriv_t *hp = &hci->hp;	__u32 portstatus;	DBGFUNC ("enter getPorStatusAndChange\n");	portstatus = hp->RHportStatus->portChange << 16 | hp->RHportStatus->portStatus;	return (portstatus);}/***************************************************************** * * Function Name: setPortChange * * This function set the bit position of portChange. * * Input:  hci = data structure for the host controller *         bitPos = the bit position * * Return value  : none  *                 *****************************************************************/static void setPortChange (hci_t * hci, __u16 bitPos){	hcipriv_t *hp = &hci->hp;	switch (bitPos) {	case PORT_CONNECT_STAT:		hp->RHportStatus->portChange |= bitPos;		break;	case PORT_ENABLE_STAT:		hp->RHportStatus->portChange |= bitPos;		break;	case PORT_RESET_STAT:		hp->RHportStatus->portChange |= bitPos;		break;	case PORT_POWER_STAT:		hp->RHportStatus->portChange |= bitPos;		break;	case PORT_SUSPEND_STAT:		hp->RHportStatus->portChange |= bitPos;		break;	case PORT_OVER_CURRENT_STAT:		hp->RHportStatus->portChange |= bitPos;		break;	}}/***************************************************************** * * Function Name: clrPortChange * * This function clear the bit position of portChange. * * Input:  hci = data structure for the host controller *         bitPos = the bit position * * Return value  : none  *                 *****************************************************************/static void clrPortChange (hci_t * hci, __u16 bitPos){	hcipriv_t *hp = &hci->hp;	switch (bitPos) {	case PORT_CONNECT_CHANGE:		hp->RHportStatus->portChange &= ~bitPos;		break;	case PORT_ENABLE_CHANGE:		hp->RHportStatus->portChange &= ~bitPos;		break;	case PORT_RESET_CHANGE:		hp->RHportStatus->portChange &= ~bitPos;		break;	case PORT_SUSPEND_CHANGE:		hp->RHportStatus->portChange &= ~bitPos;		break;	case PORT_OVER_CURRENT_CHANGE:		hp->RHportStatus->portChange &= ~bitPos;		break;	}}/***************************************************************** * * Function Name: clrPortStatus * * This function clear the bit position of portStatus. * * Input:  hci = data structure for the host controller *         bitPos = the bit position * * Return value  : none  *                 *****************************************************************/static void clrPortStatus (hci_t * hci, __u16 bitPos){	hcipriv_t *hp = &hci->hp;	switch (bitPos) {	case PORT_ENABLE_STAT:		hp->RHportStatus->portStatus &= ~bitPos;		break;	case PORT_RESET_STAT:		hp->RHportStatus->portStatus &= ~bitPos;		break;	case PORT_POWER_STAT:		hp->RHportStatus->portStatus &= ~bitPos;		break;	case PORT_SUSPEND_STAT:		hp->RHportStatus->portStatus &= ~bitPos;		break;	}}/***************************************************************** * * Function Name: setPortStatus * * This function set the bit position of portStatus. * * Input:  hci = data structure for the host controller *         bitPos = the bit position * * Return value  : none  *                 *****************************************************************/static void setPortStatus (hci_t * hci, __u16 bitPos){	hcipriv_t *hp = &hci->hp;	switch (bitPos) {	case PORT_ENABLE_STAT:		hp->RHportStatus->portStatus |= bitPos;		break;	case PORT_RESET_STAT:		hp->RHportStatus->portStatus |= bitPos;		break;	case PORT_POWER_STAT:		hp->RHportStatus->portStatus |= bitPos;		break;	case PORT_SUSPEND_STAT:		hp->RHportStatus->portStatus |= bitPos;		break;	}}/***************************************************************** * * Function Name: hc_start * * This function starts the root hub functionality.  * * Input:  hci = data structure for the host controller * * Return value  : 0  *                 *****************************************************************/static int hc_start (hci_t * hci){	DBGFUNC ("Enter hc_start\n");	rh_connect_rh (hci);	return 0;}/***************************************************************** * * Function Name: hc_alloc_hci * * This function allocates all data structure and store in the  * private data structure.  * * Input:  hci = data structure for the host controller * * Return value  : 0  *                 *****************************************************************/static hci_t *__devinit hc_alloc_hci (void){	hci_t *hci;	hcipriv_t *hp;	portstat_t *ps;	struct usb_bus *bus;	DBGFUNC ("Enter hc_alloc_hci\n");	hci = (hci_t *) kmalloc (sizeof (hci_t), GFP_KERNEL);	if (!hci)		return NULL;	memset (hci, 0, sizeof (hci_t));	hp = &hci->hp;	hp->irq = -1;	hp->hcport = -1;	/* setup root hub port status */	ps = (portstat_t *) kmalloc (sizeof (portstat_t), GFP_KERNEL);	if (!ps)		return NULL;	ps->portStatus = PORT_STAT_DEFAULT;	ps->portChange = PORT_CHANGE_DEFAULT;	hp->RHportStatus = ps;	hci->nakCnt = 0;	hci->last_packet_nak = 0;	hci->a_td_array.len = 0;	hci->i_td_array[0].len = 0;	hci->i_td_array[1].len = 0;	hci->td_array = &hci->a_td_array;	hci->active_urbs = 0;	hci->active_trans = 0;	INIT_LIST_HEAD (&hci->hci_hcd_list);	list_add (&hci->hci_hcd_list, &hci_hcd_list);	init_waitqueue_head (&hci->waitq);	INIT_LIST_HEAD (&hci->ctrl_list);	INIT_LIST_HEAD (&hci->bulk_list);	INIT_LIST_HEAD (&hci->iso_list);	INIT_LIST_HEAD (&hci->intr_list);	INIT_LIST_HEAD (&hci->del_list);	bus = usb_alloc_bus (&hci_device_operations);	if (!bus) {		kfree (hci);		return NULL;	}	hci->bus = bus;	bus->bus_name = "sl811";	bus->hcpriv = (void *) hci;	return hci;}/***************************************************************** * * Function Name: hc_release_hci * * This function De-allocate all resources   * * Input:  hci = data structure for the host controller * * Return value  : 0  *                 *****************************************************************/static void hc_release_hci (hci_t * hci){	hcipriv_t *hp = &hci->hp;	DBGFUNC ("Enter hc_release_hci\n");	/* disconnect all devices */	if (hci->bus->root_hub)		usb_disconnect (&hci->bus->root_hub);	hc_reset (hci);	if (hp->hcport) {		// Disable all Interrupts		SL811Write (hci, SL11H_INTENBLREG, 0x00);		// Remove all Interrups		mdelay(2);		SL811Write (hci, SL11H_INTSTATREG, 0xff);	}	if (hp->tl)		kfree (hp->tl);	sl811_release_regions(hp);	if (hp->irq >= 0) {		free_irq (hp->irq, hci);		hp->irq = -1;	}	usb_deregister_bus (hci->bus);	usb_free_bus (hci->bus);	list_del (&hci->hci_hcd_list);	INIT_LIST_HEAD (&hci->hci_hcd_list);	kfree (hci);}/***************************************************************** * * Function Name: hc_found_hci * * This function request IO memory regions, request IRQ, and * allocate all other resources.  * * Input: addr = first IO address *        addr2 = second IO address *        irq = interrupt number  * * Return: 0 = success or error condition  *                 *****************************************************************/static int __devinit hc_found_hci (int irq, int iobase1, int iobase2){	hci_t *hci;	hcipriv_t *hp;	DBGFUNC ("Enter hc_found_hci\n");	hci = hc_alloc_hci ();	if (!hci) {		return -ENOMEM;	}	init_irq ();	hp = &hci->hp;	if (sl811_request_regions (hp, iobase1, iobase2)) {		hc_release_hci (hci);		return -EBUSY;	}	if (!regTest (hci)) {	    DBGERR (KERN_ERR "regTest: Controller fault!\n");		hc_release_hci (hci);	    return -ENXIO;	/* No such device or address */	}	if (hc_alloc_trans_buffer (hci)) {		hc_release_hci (hci);		return -ENOMEM;	}	usb_register_bus (hci->bus);	if (request_irq (irq, hc_interrupt, SA_SHIRQ, MODNAME, hci) != 0) {		DBGERR ("request interrupt %d failed", irq);		hc_release_hci (hci);		return -EBUSY;	}	hp->irq = irq;	printk (KERN_INFO __FILE__ ": USB SL811 at %x,%x, IRQ %d\n",		hp->hcport, hp->hcport2, irq);	#ifdef SL811_DEBUG_VERBOSE	{	    __u8 u = SL811Read (hci, SL11H_HWREVREG);	    	    DBGVERBOSE ("SL811 HW: %02Xh ", u);	    switch (u & 0xF0) {	    case 0x00: DBGVERBOSE ("SL11H\n");		break;	    case 0x10: DBGVERBOSE ("SL811HS rev1.2\n");	break;	    case 0x20: DBGVERBOSE ("SL811HS rev1.5\n");	break;	    default:   DBGVERBOSE ("unknown!\n");	    }	}	#endif // SL811_DEBUG_VERBOSE	if (hc_reset (hci)) {		hc_release_hci (hci);		return -EBUSY;	}	if (hc_start (hci) < 0) {		DBGERR ("can't start usb-%x", hp->hcport);		hc_release_hci (hci);		return -EBUSY;	}	return 0;}/***************************************************************** * * Function Name: hci_hcd_init * * This is an init function, and it is the first function being called * * Input: none  * * Return: 0 = success or error condition  *                 *****************************************************************/static int __init hci_hcd_init (void){	int ret;#ifndef __arm__	int io_offset = 0;#endif // !__arm__	DBGFUNC ("Enter hci_hcd_init\n");	DBGVERBOSE ("SL811 VERBOSE enabled\n");#ifdef __arm__	ret = hc_found_hci (irq, base_addr, data_reg_addr);#else // __arm__	// registering "another instance"	for (io_offset = 0; io_offset < MAX_CONTROLERS * 2; io_offset += 2) {		ret = hc_found_hci (irq, io_base + io_offset, 0);		if (ret)			return (ret);	} /* endfor */#endif // __arm__	return ret;}/***************************************************************** * * Function Name: hci_hcd_cleanup * * This is a cleanup function, and it is called when module is  * unloaded.  * * Input: none  * * Return: none  *                 *****************************************************************/static void __exit hci_hcd_cleanup (void){	struct list_head *hci_l;	hci_t *hci;	DBGFUNC ("Enter hci_hcd_cleanup\n");	for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) {		hci = list_entry (hci_l, hci_t, hci_hcd_list);		hci_l = hci_l->next;		hc_release_hci (hci);	}}module_init (hci_hcd_init);module_exit (hci_hcd_cleanup);MODULE_AUTHOR ("Pei Liu <pbl@cypress.com>, Henry Nestler <hne@ist1.de>");MODULE_DESCRIPTION ("USB SL811HS Host Controller Driver");

⌨️ 快捷键说明

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