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

📄 hc_isp116x.c

📁 嵌入式USB主控制器ISP1161的驱动编程
💻 C
📖 第 1 页 / 共 4 页
字号:
				itl_data_p->len = 1000;				itl_data_p->frame_number = hci->frame_number;				if (itl_reset==0) {					itl_data_p->sequence = 0;					global_itl = 1;					if ( miss_flag==1 ) {						miss_flag = 0;						itl_data_p->sequence = 1;						global_itl = 2;					}					itl_reset = 1;				} else {					itl_data_p->sequence = global_itl++;				}				if (global_itl==10) {					global_itl = 0;				}				itl_data_p->len = actual_len+8;				itl_data_p->data_buf[0] = 0xc1;				itl_data_p->data_buf[1] = 0x07;				itl_data_p->data_buf[2] = 0xff;				itl_data_p->data_buf[3] = 0x1b;				itl_data_p->data_buf[4] = 0xc1;				itl_data_p->data_buf[5] = 0x0b;				itl_data_p->data_buf[6] = 0x82;				itl_data_p->data_buf[7] = 0x00;				list_add (&itl_data_p->list, &hci->itl_list);				if (ints_uP & ATLInt) {					ATLInt_save = 1;				}				time_left = READ_REG32(hci, HcFmRemaining);                                if (time_left<0x150 || time_left>0x300) {                                        goto out;                                } else {                                        hp->tlp = 0;                                        sh_scan_iso_urb_list (hci, &hci->iso_list, hci->frame_number);                                        if (hp->tlp >0) {       /* updated in hc_add_trans() */                                                hp->units_left = hp->itl_buffer_len;                                                char* hp_tmp = hp->tl;                                                int num_tmp = 0;                                                if (hp_tmp[5] && (1 << 3)) {                                                        num_tmp = hp->tlp;                                                        hp->tlp = 8;                                                }                                                                                                                                                                             spin_lock_irqsave (&hci->hci_lock, flag);                                                WRITE_REG16 (hci, hp->tlp, HcTransferCounter);                                                WRITE_REGn16 (hci, HcITLBufferPort, hp->tlp, hp->tl);                                                spin_unlock_irqrestore (&hci->hci_lock, flag);                                                                                                                                                                             if (hp_tmp[5] && (1 << 3)) {                                                        hp->tlp = num_tmp;                                                }                                        }                                        goto out;                                }			}			if (time_left<0x500) {				itl_data_p = (itl_data_t *)kmalloc(sizeof(itl_data_t),GFP_ATOMIC);				if (!itl_data_p) {					printk (KERN_EMERG "error in kmalloc!!\n");					goto do_atl;				}				itl_data_p->data_buf = (__u8 *)kmalloc (1000+8, GFP_ATOMIC);				if (!(itl_data_p->data_buf)) {					printk (KERN_EMERG "error in kmalloc!!\n");					goto do_atl;				}				itl_data_p->len = 1000;				itl_data_p->frame_number = hci->frame_number;				if (itl_reset==0) {					itl_data_p->sequence = 0;					global_itl = 1;					if ( miss_flag==1 ) {						miss_flag = 0;						itl_data_p->sequence = 1;						global_itl = 2;					}					itl_reset = 1;				} else {					itl_data_p->sequence = global_itl++;				}				if (global_itl==10) {					global_itl = 0;				}				spin_lock_irqsave (&hci->hci_lock, flag); 				WRITE_REG16 (hci, 8, HcTransferCounter);				READ_REGn16 (hci, HcITLBufferPort, 8, itl_data_p->data_buf);				spin_unlock_irqrestore (&hci->hci_lock, flag);				itl_data_p->len = actual_len+8;				list_add (&itl_data_p->list, &hci->itl_list);				hp->tlp = 0;				sh_scan_iso_urb_list (hci, &hci->iso_list, hci->frame_number);				if (hp->tlp >0) {       /* updated in hc_add_trans() */					hp->units_left = hp->itl_buffer_len;					char* hp_tmp = hp->tl;					int num_tmp = 0;					if (hp_tmp[5] && (1 << 3)) {						num_tmp = hp->tlp;						hp->tlp = 8;					}					spin_lock_irqsave (&hci->hci_lock, flag);					WRITE_REG16 (hci, hp->tlp, HcTransferCounter);					WRITE_REGn16 (hci, HcITLBufferPort, hp->tlp, hp->tl);					spin_unlock_irqrestore (&hci->hci_lock, flag);					if (hp_tmp[5] && (1 << 3)) {						hp->tlp = num_tmp;					}				}				if (ints_uP&ATLInt && (READ_REG32(hci, HcFmRemaining)<0x160)) {					ATLInt_save = 1;					goto out;				} else {					goto do_atl;				}			} else if (time_left<0x1500 && time_left>=0x500) {				itl_data_p = (itl_data_t *)kmalloc(sizeof(itl_data_t),GFP_ATOMIC);				if (!itl_data_p) {					printk (KERN_EMERG "error in kmalloc!!\n");					goto do_atl;				}				itl_data_p->data_buf = (__u8 *)kmalloc (hp->itl1_len+8, GFP_ATOMIC);				if (!(itl_data_p->data_buf)) {					printk (KERN_EMERG "error in kmalloc!!\n");					goto do_atl;				}				itl_data_p->len = hp->itl1_len;				itl_data_p->frame_number = hci->frame_number;				if (itl_reset==0) {					itl_data_p->sequence = 0;					global_itl = 1;					if ( miss_flag==1 ) {						miss_flag = 0;						itl_data_p->sequence = 1;						global_itl = 2;					}					itl_reset = 1;				} else {					itl_data_p->sequence = global_itl++;				}				if (global_itl==10) {					global_itl = 0;				}				spin_lock_irqsave (&hci->hci_lock, flag); 				WRITE_REG16 (hci, 8, HcTransferCounter);				READ_REGn16 (hci, HcITLBufferPort, 8, itl_data_p->data_buf);				spin_unlock_irqrestore (&hci->hci_lock, flag);				list_add (&itl_data_p->list, &hci->itl_list);				goto write_itl;			}			hp->itl0_len = READ_REG16 (hci, HcReadBackITL0Length);			if (hp->itl0_len > 0) {				itl_data_p = (itl_data_t *)kmalloc(sizeof(itl_data_t),GFP_ATOMIC);				if (!itl_data_p) {					printk (KERN_EMERG "error in kmalloc!!\n");					goto do_atl;				}				itl_data_p->data_buf = (__u8 *)kmalloc (hp->itl0_len+8, GFP_ATOMIC);				if (!(itl_data_p->data_buf)) {					printk (KERN_EMERG "error in kmalloc!!\n");					goto do_atl;				}				itl_data_p->len = hp->itl0_len;				itl_data_p->frame_number = hci->frame_number;				if (itl_reset==0) {					itl_data_p->sequence = 0;					global_itl = 1;					if ( miss_flag==1 ) {						miss_flag = 0;						itl_data_p->sequence = 1;						global_itl = 2;					}					itl_reset = 1;				} else {					itl_data_p->sequence = global_itl++;				}				if (global_itl==10) {					global_itl = 0;				}#ifdef USE_FAST_ACCESS				spin_lock_irqsave (&hci->hci_lock, flag); 				WRITE_REG16 (hci, 8, HcTransferCounter);				READ_REGn16 (hci, HcITLBufferPort, 8, itl_data_p->data_buf);				spin_unlock_irqrestore (&hci->hci_lock, flag);								ptd_p = itl_data_p->data_buf;				actual_len = ( ptd_p[0]|((ptd_p[1]& 0x03)<<8) );				if ( actual_len!=0 ){										actual_len = actual_len + 8;					spin_lock_irqsave (&hci->hci_lock, flag); 					WRITE_REG16 (hci, actual_len, HcTransferCounter);					itl_data_p->data_buf = ptd_p+8;					READ_REGn16 (hci, HcITLBufferPort, actual_len, itl_data_p->data_buf);					spin_unlock_irqrestore (&hci->hci_lock, flag);								} else {					actual_len = 0;					}				itl_data_p->len = actual_len+8;				proc_itl_stream += actual_len;				itl_data_len += actual_len;#else								spin_lock_irqsave (&hci->hci_lock, flag); 				WRITE_REG16 (hci, hp->itl0_len, HcTransferCounter);				READ_REGn16 (hci, HcITLBufferPort, hp->itl0_len, itl_data_p->data_buf);				spin_unlock_irqrestore (&hci->hci_lock, flag);#endif				list_add (&itl_data_p->list, &hci->itl_list);			}             	}write_itl:		tasklet_schedule (&hci->bottomHalf);		hp->tlp = 0;     		sh_scan_iso_urb_list (hci, &hci->iso_list, hci->frame_number);    		if (hp->tlp >0) {	/* updated in hc_add_trans() */			hp->units_left = hp->itl_buffer_len;			char* hp_tmp = hp->tl;			int num_tmp = 0;			if (hp_tmp[5] && (1 << 3)) {				num_tmp = hp->tlp;				hp->tlp = 8;			}				spin_lock_irqsave (&hci->hci_lock, flag); 			WRITE_REG16 (hci, hp->tlp, HcTransferCounter);			WRITE_REGn16 (hci, HcITLBufferPort, hp->tlp, hp->tl);			spin_unlock_irqrestore (&hci->hci_lock, flag);					if (hp_tmp[5] && (1 << 3)) {				hp->tlp = num_tmp;			}		}	}/***********************************************************************//*	we will handle ATL after Read ITL buffer!! * *//***********************************************************************/do_atl:	time_left = READ_REG32(hci, HcFmRemaining);	if (time_left<0x200) {		if (ints_uP&ATLInt) {			ATLInt_save = 1;		}		goto out;	}		if ( (ints_uP & ATLInt) && (!(ints_uP & SOFITLInt)) ) {		ATLInt_save = 1;		goto out;	}        if (ints_uP & ATLInt) {		if ((hci->buffer_status & ATLBufferFull) && (hci->buffer_status & ATLBufferDone)) {			if (hp->atl_len > 0) {								spin_lock_irqsave (&hci->hci_lock, flag); 				WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);				READ_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);				spin_unlock_irqrestore (&hci->hci_lock, flag);				hp->tlp = 0;				hci->td_array = &hci->a_td_array;				sh_done_list (hci);			}			hp->tlp = 0;			if ( READ_REG16(hci, HcuPInterrupt)&SOFITLInt ) {				printk (KERN_DEBUG "warning : interrupt happened in atl \n");			}		} else { 			ATL_quirk_flag = 1;//			hc_reset (hci);			goto out;		} 	} else if(ATLInt_save==1) {			ATLInt_save = 0;			if ((hci->buffer_status & ATLBufferFull) && (hci->buffer_status & ATLBufferDone)) {				if (hp->atl_len > 0) {					spin_lock_irqsave (&hci->hci_lock, flag); 					WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);					READ_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);					spin_unlock_irqrestore (&hci->hci_lock, flag);					hp->tlp = 0;					hci->td_array = &hci->a_td_array;					sh_done_list (hci);				}				hp->tlp = 0;			}		}	time_left = READ_REG32(hci, HcFmRemaining);	if (time_left<0x100) {		goto out;	}	if (!hci->td_array->len)		sh_del_list (hci);	hci->td_array = &hci->a_td_array;	hci->buffer_status = READ_REG16 (hci, HcBufferStatus);	if (hci->td_array->len == 0 && !(hci->buffer_status & ATLBufferFull)) {		hp->units_left = hp->atl_buffer_len;		hp->tlp = 0;		sh_schedule_trans (hci);		hc_mark_last_trans (hci);		hp->atl_len = hp->tlp;		if (hp->atl_len > 0) {						if (work_flag<50) {				work_flag++;			}			spin_lock_irqsave (&hci->hci_lock, flag); 			WRITE_REG16 (hci, hp->atl_len, HcTransferCounter);			WRITE_REGn16 (hci, HcATLBufferPort, hp->atl_len, hp->tl);			spin_unlock_irqrestore (&hci->hci_lock, flag);		}	}out:#ifdef CONFIG_ARCH_SITSANG        SITSANG_BIPR_RW = SITSANG_BIPR_USB_HC_IRQ;        SITSANG_BIMR_RW |= SITSANG_BIMR_USB_HC_IRQ;#endif}/***********************************************************************************//*	hc_interrupt_bh do the following job: parse the data read from isp1161A1 *	and arrange future transactions, that is write new PTDs into isp1161A1 * *//***********************************************************************************/void hc_interrupt_bh (unsigned long __hci){	hci_t* hci = (hci_t *)__hci;	hci->bh_in_progress = 1;     		itl_done_list (hci);		hci->bh_in_progress = 0;//	printk (KERN_DEBUG "leave bh \n\n");}/*-------------------------------------------------------------------------* * HC functions *-------------------------------------------------------------------------*//* reset the HC and BUS */static int hc_reset (hci_t * hci){	int timeout = 30;	/* Disable HC interrupts */	printk (KERN_DEBUG "call hc_reset!!\n");	WRITE_REG16 (hci, 0,HcuPInterruptEnable);	WRITE_REG16 (hci, InterruptPinEnable | HC_HARDWARE_CONFIG, HcHardwareConfiguration);	WRITE_REG16 (hci, InterruptOutputPolarity | HC_HARDWARE_CONFIG, HcHardwareConfiguration);	dbg ("USB HC reset_hc usb-: ctrl = 0x%x ;",		READ_REG32 (hci, HcControl));  	/* Reset USB (needed by some controllers) *///	WRITE_REG32 (hci, 0, HcControl);//	WRITE_REG0 (hci, HcSoftwareReset);       WRITE_REG16 (hci, 0xf6, HcSoftwareReset);	/* HC Reset requires max 10 us delay */	WRITE_REG32 (hci, OHCI_HCR, HcCommandStatus);	while ((READ_REG32 (hci, HcCommandStatus) & OHCI_HCR) != 0) {		if (--timeout == 0) {			printk ("USB HC reset timed out!\n");			return -1;		}		udelay (10);	}	return 0;}/*-------------------------------------------------------------------------*//* Start an host controller, set the BUS operational * enable interrupts * connect the virtual root hub */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->itl_buffer_len = 1024+256;	hp->atl_buffer_len = 4096 - 2 * hp->itl_buffer_len; /* 2048 */	WRITE_REG16 (hci, hp->itl_buffer_len, HcITLBufferLength);	WRITE_REG16 (hci, hp->atl_buffer_len, HcATLBufferLength);	/* Enable IRQ's */	WRITE_REG16 (hci,		     InterruptPinEnable | HC_HARDWARE_CONFIG,		     HcHardwareConfiguration);	WRITE_REG16 (hci, 0, HcDMAConfiguration);	maxlen = (hp->itl_buffer_len > hp->atl_buffer_len) ? hp->itl_buffer_len : hp->atl_buffer_len;	hp->tl = kmalloc (maxlen, GFP_ATOMIC);	if (!hp->tl)		return -ENOMEM;	memset (hp->tl, 0, maxlen);	return 0;}static int hc_start (hci_t * hci)

⌨️ 快捷键说明

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