📄 hc_isp116x.c
字号:
printk ("%d\t", itl_interval[i]); } printk (KERN_DEBUG "\n\n"); }}*//************************************************************************//* interrupt handler, do the following work: read data from * ITLBuffer and ATLBuffer and call on a tasklet to finish * any future work!! *//************************************************************************/static void hc_interrupt (int irq, void * __hci, struct pt_regs * r){#ifdef CONFIG_ARCH_SITSANG if (!(SITSANG_BIPR_RW & SITSANG_BIPR_USB_HC_IRQ)) return ; SITSANG_BIMR_RW &= ~SITSANG_BIMR_USB_HC_IRQ; SITSANG_BIPR_RW = SITSANG_BIPR_USB_HC_IRQ;#endif int time_tmp = 0; hci_t * hci = __hci; unsigned long flag; unsigned char* ptd_p; hci->iso_buffer_index = 0; hcipriv_t * hp = &hci->hp; itl_data_t* itl_data_p; int ints_uP; int ints = 0; int time_left = 0; if ((ints_uP = (READ_REG16 (hci, HcuPInterrupt) & READ_REG16 (hci, HcuPInterruptEnable))) == 0) { printk ("int1 %x %x\n", ints_uP, ints); printk (KERN_DEBUG "register information:\n"); printk (KERN_DEBUG "HcControl: %x HcCommandStatus: %x HcInterruptStatus: %x \n", READ_REG32(hci,HcControl),\ READ_REG32(hci, HcCommandStatus), READ_REG32(hci, HcInterruptStatus)); printk (KERN_DEBUG "HcInterruptEnable: %x HcFmInterval: %x HcFmRemaining: %x \n", READ_REG32(hci,HcInterruptEnable), READ_REG32(hci, HcFmInterval), READ_REG32(hci, HcFmRemaining)); printk (KERN_DEBUG "HcRhDescriptorA: %x HcRhStatus: %x HcHardwareConfiguration: %x \n", READ_REG32(hci,HcRhDescriptorA), READ_REG32(hci, HcRhStatus), READ_REG32(hci, HcHardwareConfiguration)); printk (KERN_DEBUG "HcuPInterruptEnable: %x HcITLBufferLength: %x HcATLBufferLength: %x \n", READ_REG32(hci,HcuPInterruptEnable), READ_REG32(hci, HcITLBufferLength), READ_REG32(hci, HcATLBufferLength)); if ( (READ_REG32(hci, HcControl)==0) && (READ_REG32(hci, HcInterruptEnable)==0) ) { chip_reset = 1; goto int_reset_next; }/* if (work_flag>40 && cleanup==0 && READ_REG32(hci,HcInterruptEnable)==0x00) { printk (KERN_EMERG "Chip reset happened, we will renew the module.\n"); tasklet_schedule (&hci->ChipReset); } goto out;*/ } if (chip_reset==1) { chip_reset = 0; }int_reset_next: WRITE_REG16 (hci, ints_uP, HcuPInterrupt); if ((ints_uP & OPR_Reg) && (ints = (READ_REG32 (hci, HcInterruptStatus)))) { if (ints & OHCI_INTR_SO) { printk("USB Schedule overrun\n"); WRITE_REG32 (hci, OHCI_INTR_SO, HcInterruptEnable); } if (ints & OHCI_INTR_SF) { WRITE_REG32 (hci, OHCI_INTR_SF, HcInterruptEnable); } WRITE_REG32 (hci, ints, HcInterruptStatus); WRITE_REG32 (hci, OHCI_INTR_MIE, HcInterruptEnable); }/* if (timer_switch==0) { init_timer(&isp_timer); isp_timer.function = isp_timeout; isp_timer.data = (unsigned long)jiffies; isp_timer.expires = jiffies + HZ; add_timer(&isp_timer); timer_switch = 1; }*/ hci->frame_number = GET_FRAME_NUMBER (hci); hci->buffer_status = READ_REG16 (hci, HcBufferStatus);// printk (KERN_DEBUG "in hc_interrupt: int: %x frame_num: %x \n", ints_uP, hci->frame_number); Buffer_History[Buffer_History_p] = hci->buffer_status; Buffer_History_p = (Buffer_History_p+1)%10; if ( ints_uP & SOFITLInt ) { if ( last_HcFmNumber==-1 ) { last_HcFmNumber = hci->frame_number; } else { if ( hci->frame_number>last_HcFmNumber ) { if ( (hci->frame_number-last_HcFmNumber)>1 ) { if ((last_HcBufferStatus & ITL1BufferFull)||(last_HcBufferStatus & ITL0BufferFull)) { if ( itl_reset==0 ) { miss_flag = 1; } else { global_itl++; if (global_itl==10) { global_itl--; 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; } 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); } } } } } last_HcFmNumber = hci->frame_number; } last_HcBufferStatus = hci->buffer_status; } /*******************************************************************************//* read ITL1 first, if there is an buffer overflow HC will stop at ITL1 * There will be a quirk in sh_done_list if this happens!!! * we will call sh_done_list in bottomhalf. *//******************************************************************************/ if (ints_uP & SOFITLInt) { //decide whether buffer dies if (itl_buffer_die!=0 && itl_buffer_die!=1) { //once itl_buffer_die happens, it will never go here!! if (hci->buffer_status & ITL0BufferDone) { itl_buffer_count0 = 0; } if (hci->buffer_status & ITL1BufferDone) { itl_buffer_count1 = 0; } if (hci->buffer_status & ITL0BufferFull) { itl_buffer_count0++; } if (hci->buffer_status & ITL1BufferFull) { itl_buffer_count1++; } if (itl_buffer_count0 >= 5) { itl_buffer_die = 0; ITL0_die_flag = 1; } if (itl_buffer_count1 >= 5) { itl_buffer_die = 1; ITL1_die_flag = 1; } } if (hci->buffer_status & ITL1BufferDone) { time_left = READ_REG32(hci, HcFmRemaining); if (time_left<0x300) { 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; } 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->itl1_len = READ_REG16 (hci, HcReadBackITL1Length); if (hp->itl1_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->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; }#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->itl1_len, HcTransferCounter); READ_REGn16 (hci, HcITLBufferPort, hp->itl1_len, itl_data_p->data_buf); spin_unlock_irqrestore (&hci->hci_lock, flag);#endif list_add (&itl_data_p->list, &hci->itl_list); } } else if (hci->buffer_status & ITL0BufferDone) { time_left = READ_REG32(hci, HcFmRemaining); if (time_left<0x300) { 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -