📄 hc_isp116x.c
字号:
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 + -