📄 usb_phci.c
字号:
#ifdef CONFIG_USB_PHCD_PING_PONG __u8 ping_pong_flag = 0;#endif /* CONFIG_USB_PHCD_PING_PONG */ func_debug(("phci_fill_send_ptd(phci = 0x%p, send_ptd_map = 0x%x, ptd_map_buff = 0x%p)\n",phci,send_ptd_bitmap, ptd_map_buff)) if(!send_ptd_bitmap) { if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ATL) { if(!ptd_map_buff->active_ptds){ /* No ptds are active */ ptd_map_buff->regs.threshold_count = 0; /* Set the thereshol count from logic */ /* Update the same in HC */ phci_reg_write16(REG_ATL_THRESHOLD_COUNT,ptd_map_buff->regs.threshold_count); phci_reg_write32(REG_ATL_PTD_SKIP_MAP,0xFFFFFFFF); /* Skip all ptds */ phci_reg_read16(REG_BUFF_STS,&data_read); /* Read the buffer status register */ data_read &= (~ATL_ACTIVE); /* Deactivate ATL */ phci->hcd_operational_flags &= (~ATL_ACTIVE); phci_reg_write16(REG_BUFF_STS,data_read); /* Deactivate ATL buffers */ } } if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_INTL) { if(!ptd_map_buff->active_ptds){ phci_reg_write32(REG_INTL_PTD_SKIP_MAP,0xFFFFFFFF);/* Skip all ptds */ phci_reg_read16(REG_BUFF_STS,&data_read); /* Read the buffer status register */ data_read &= (~INTL_ACTIVE); /* Deactivate ATL */ phci->hcd_operational_flags &= (~INTL_ACTIVE); phci_reg_write16(REG_BUFF_STS,data_read); /* Deactivate ATL/INTL buffers */ } } return; /* If there is nothing to do, just return it */ } /* Take care of pending ATL ptds */ if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ATL) { ptd_map_buff->pending_ptd_bitmap |= (send_ptd_bitmap & (~ptd_map_buff->active_ptd_bitmask)); send_ptd_bitmap &= ptd_map_buff->active_ptd_bitmask; if(!send_ptd_bitmap) return; } switch(ptd_map_buff->buffer_type) { case TD_PTD_BUFF_TYPE_INTL: /* Skip the PTD's in ATL & INTL so that we can write the PTD's into the buffer */ phci_reg_read32(REG_INTL_PTD_SKIP_MAP, &(ptd_map_buff->regs.ptd_skip_map)); /* Read the ATL skip map */ ptd_map_buff->regs.ptd_skip_map |= send_ptd_bitmap; /* Add the new ptds to be skipped */ phci_reg_write32(REG_INTL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map); /* The HC don;t touch the ptds */ break; case TD_PTD_BUFF_TYPE_ATL: /* Skip the PTD's in ATL & INTL so that we can write the PTD's into the buffer */ phci_reg_read32(REG_ATL_PTD_SKIP_MAP, &(ptd_map_buff->regs.ptd_skip_map)); /* Read the ATL skip map */ ptd_map_buff->regs.ptd_skip_map |= send_ptd_bitmap; /* Add the new ptds to be skipped */ phci_reg_write32(REG_ATL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map); /* The HC don;t touch the ptds */ break; } for( index = 0; (index < ptd_map_buff->max_ptds) || (finished_map != 0); index++) { td_ptd_map = &(ptd_map_buff->map_list[index]); if(td_ptd_map->ptd_bitmap & finished_map) { /* This ptd needs to be filled */ /* Start filling the ram_data to send it to HC */ td = td_ptd_map->td; ed = td->ed; /* start filling the ptd header */ total_bytes = HC_PTD_HEADER_SIZE; /* ptd total bytes to be written to HC buffer, initialize to ptd header */ /**********************************************************************/ /* ptd_header[0]: 7..0 actual bytes(7...0) 0(always) */ /**********************************************************************/ ram_data[0] = 0; /************************************************************************/ /* ptd_header[1]: 7..4 completion code(3...0) 1111 (always) */ /* ptd_header[1]: 3 active(0) 1 (always) */ /* ptd_header[1]: 2 toggle(0) from ed&td */ /* ptd_header[1]: 1..0 actual bytes(9..8) 0 (always) */ /************************************************************************/ ram_data[1] = (PTD_CC_MASK | PTD_ACTIVE); if( td->hwINFO & HC_GTD_MLSB) { /* fill toggle bit from td hw info */ ram_data[1] |= (((__u8)((td->hwINFO & HC_GTD_TLSB) >> 24)) << 2); } else { /* fill toggle bit from ed hw info */ ram_data[1] |= (((__u8)((ed->hwHeadP & HC_ED_TOGGLE) >> 1)) << 2); } /**********************************************************************/ /* ptd_header[2]: 7..0 Max.PacketSize(7...0) from ed MPS */ /**********************************************************************/ ram_data[2] = ((__u8)((ed->hwINFO & HC_ED_MPS) >> 16)); /************************************************************************/ /* ptd_header[3]: 7..4 End point number(3...0) from ED EN */ /* ptd_header[3]: 3 reserved(0) 0 (always) */ /* ptd_header[3]: 2 speed(0) from ED */ /* ptd_header[3]: 1..0 Max.PacketSize(9..8) from ED MPS */ /************************************************************************/ ram_data[3] = (((__u8)((ed->hwINFO & HC_ED_EN) >> 7)) << 4); if(ed->hwINFO & HC_ED_SPD) { /* Check if speed device or not */ ram_data[3] |= PTD_SPEED; } ram_data[3] |= (((__u8)((ed->hwINFO & HC_ED_MPS) >> 24)) & 0x03); /********************************************************************************/ /* ptd_header[4]: 7..0 Total Bytes(7...0) from td cbp & be */ /* ptd_header[5]: 1..0 total bytes(9..8) from td cbp & be */ /********************************************************************************/ if(td->hwCBP) { payload_bytes = td->hwBE - td->hwCBP + 1; /* get the total bytes from td cbp & be */ ram_data[4] = (__u8)payload_bytes; ram_data[5] = (__u8)(payload_bytes >> 8); } else { /* Null data packet */ payload_bytes = 0; ram_data[4] = 0; ram_data[5] = 0; } /********************************************************************************/ /* ptd_header[5]: 7 paired(0) from ping_pong input */ /* ptd_header[5]: 6 ping_pong(0) from ping_pong input */ /* ptd_header[5]: 5..4 reserved(1..0) 00 always */ /* ptd_header[5]: 3..2 token direction(1..0) from ed DIR */ /* ptd_header[5]: 1..0 total bytes(9..8) already filled before */ /********************************************************************************/#ifdef CONFIG_USB_PHCD_PING_PONG if(td_ptd_map->ping_pong) ping_pong_flag = 1; ram_data[5] |= td_ptd_map->ping_pong;#endif /* CONFIG_USB_PHCD_PING_PONG */ byte_data = (__u8)((ed->hwINFO & HC_ED_DIR) >> 11); if(byte_data != OHCI_OUT && byte_data != OHCI_IN) { byte_data = (__u8)((td->hwINFO & HC_GTD_DP) >> 19); } ram_data[5] |= (byte_data << 2); /********************************************************************************/ /* ptd_header[6]: 7 format(0) 0 always */ /* ptd_header[6]: 6..0 function address(6..0) from ED FA */ /********************************************************************************/ ram_data[6] = ((__u8)(ed->hwINFO & HC_ED_FA)); /*************************************************************************************/ /* ptd_header[7]: 7..0 Frame Number/Int polling Interval(7..0) poll_frame# input*/ /*************************************************************************************/ ram_data[7] = 0; if(ed->type == PIPE_INTERRUPT) { __u8 int_interval, byte; int_interval = (ed->int_interval >> 1); byte = 0; while(int_interval) {int_interval >>= 1; byte++;}#ifdef CONFIG_USB_PHCD_EVEN_SCH ram_data[7] = (byte << 5); /* Check the last 5 bits of Interrupt polling interval */ ram_data[7] |= ed->int_branch ;#else ram_data[7] = (byte << 1); /* Always schedule on even frame */#endif /* CONFIG_USB_PHCD_EVEN_SCH */ } /* start sendig the data for this ptd */ ram_addr = ptd_map_buff->ram_buff_addr+index*(ptd_map_buff->regs.block_pl_size + HC_PTD_HEADER_SIZE); ptd_payload = (__u8*)(td->hwCBP); if( (byte_data != OHCI_IN ) && payload_bytes && ptd_payload ) { /* Don's send data in case of IN token */ total_bytes += payload_bytes; fnvPhciRamWrite(phci,payload_bytes, HC_DIR_ADDR_INCREMENT, (ram_addr+HC_PTD_HEADER_SIZE), ptd_payload); } if(ram_addr < 2*HC_ISTL_BUFFER_LENGTH) printk("Something bad is going to happen, trying to write at %x for A/INTL ptd's", ram_addr); fnvPhciRamWrite(phci,HC_PTD_HEADER_SIZE, HC_DIR_ADDR_INCREMENT, ram_addr, ram_data); /* Send the ptd header */ td_ptd_map->total_bytes = payload_bytes+HC_PTD_HEADER_SIZE; /* Set the total bytes size for this td-ptd map */ ptd_map_buff->active_ptd_bitmap |= td_ptd_map->ptd_bitmap; /* Set this ptd is active in active ptd map */ ptd_map_buff->active_ptds++; finished_map &= (~(td_ptd_map->ptd_bitmap)); /* Set this ptd as finished one */ } } switch(ptd_map_buff->buffer_type) { case TD_PTD_BUFF_TYPE_ATL: ptd_map_buff->regs.threshold_count = atl_active_ptd_X_threshold_ptd[ptd_map_buff->active_ptds] ; /* Set the thereshol count from logic */#ifdef CONFIG_USB_PHCD_PING_PONG /* PING PONG pair of PTDs will be treated as one PTD */ if(ptd_map_buff->regs.threshold_count) ptd_map_buff->regs.threshold_count -= ping_pong_flag;#endif /* CONFIG_USB_PHCD_PING_PONG */ phci_reg_write16(REG_ATL_THRESHOLD_COUNT,ptd_map_buff->regs.threshold_count); /* Update the same in HC */ phci_reg_read16(REG_ATL_THRESHOLD_COUNT,&data_read); /* Update the same in HC */ /* Set the Last PTD in ATL */ /* Calculate the last ptd in ATL */ active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap; ptd_map_buff->regs.last_ptd = 0x1; active_ptd_bitmap >>= 1; /* * Last PTD is already set at the time of initialization to the maximum TDs * So no need of dynamic update */#if 0 while(active_ptd_bitmap) { /* right shift till active ptd bitmap becomes zero */ ptd_map_buff->regs.last_ptd <<= 1; active_ptd_bitmap >>= 1; } phci_reg_write32(REG_ATL_PTD_LAST_PTD,ptd_map_buff->regs.last_ptd); /* Update the last ATL ptd in HC */#endif /* Activate the PTD's in ATL so that we can start the PTD's in the buffer */ ptd_map_buff->regs.ptd_skip_map &= (~send_ptd_bitmap); /* remove the skip on new ptd's */ phci_reg_write32(REG_ATL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map); /* write into the skip map buffer */ phci_reg_read16(REG_BUFF_STS,&data_read); /* Activate ATL buffer processing */ if(!(data_read & ATL_ACTIVE)) { data_read |= ATL_ACTIVE; phci->hcd_operational_flags |= ATL_ACTIVE; phci_reg_write16(REG_BUFF_STS,data_read); /* Activate ATL buffer processing */ } break; case TD_PTD_BUFF_TYPE_INTL: active_ptd_bitmap = ptd_map_buff->active_ptd_bitmap; ptd_map_buff->regs.last_ptd = 0x1; active_ptd_bitmap >>= 1; /* Activate the PTD's in INTL so that we can start the PTD's in the buffer */ ptd_map_buff->regs.ptd_skip_map &= (~send_ptd_bitmap); /* remove the skip on new ptd's */ phci_reg_write32(REG_INTL_PTD_SKIP_MAP,ptd_map_buff->regs.ptd_skip_map); /* write into the skip map buffer */ phci_reg_read16(REG_BUFF_STS,&data_read); /* Activate INTL buffer processing */ if(!(data_read & INTL_ACTIVE)) { phci->hcd_operational_flags |= INTL_ACTIVE; data_read |= INTL_ACTIVE; phci_reg_write16(REG_BUFF_STS,data_read); /* Activate INTL buffer processing */ } phci_reg_read32(REG_INTL_PTD_SKIP_MAP,&ptd_map_buff->regs.ptd_skip_map); /* write into the skip map buffer */ break; }} /* phci_fill_send_ptd *//*--------------------------------------------------------------* *--------------------------------------------------------------* phci_fill_send_isoc_ptd:: send_ptd_bitmap: 32bit map for the ptds to be sent ptd_map_buff: map buffer pointer of buffer to be written fill the ptd buffer and send it to HC Fill into the HC buffer all the ptd's indicated by the bitmap into their corresponding locations in the buffer. activate the corresponding istl buffer *--------------------------------------------------------------* *--------------------------------------------------------------*/void phci_fill_send_isoc_ptd(phci_t *phci,__u32 send_ptd_bitmap,td_ptd_map_buff_t *ptd_map_buff) { td_ptd_map_t *td_ptd_map; __u8 *ptd_payload = NULL; __u8 ram_data[TD_PTD_MAX_BUFF_TDS]; __u8 byte_data = 0; __u16 payload_bytes = 0; /* ptd payload bytes */ __u16 total_bytes = HC_PTD_HEADER_SIZE; /* ptd total bytes to be written to HC buffer */ td_t *td; ed_t *ed; __u8 index = 0; __u32 finished_map = send_ptd_bitmap; __u32 ram_addr = ptd_map_buff->ram_buff_addr; __u32 ram_buff_sts; detail_debug(("phci_fill_send_isoc_ptd(phci = 0x%p, send_ptd_map = 0x%x, ptd_map_buff = 0x%p)\n",phci,send_ptd_bitmap, ptd_map_buff)) ptd_map_buff->active_ptd_bitmap = 0; /* Set this ptd is active in active ptd map */ if(!send_ptd_bitmap) return; /* If there is nothing to do, just return it */ phci_reg_read16(REG_BUFF_STS, &ram_buff_sts); /* Activate ITL buffer processing */ if(ptd_map_buff->buffer_type == TD_PTD_BUFF_TYPE_ISTL0) { ram_buff_sts |= ISTL_0_BUFF_FULL; } else { ram_buff_sts |= ISTL_1_BUFF_FULL; } phci_reg_write16(REG_BUFF_STS,ram_buff_sts); /* Activate ITL buffer processing */ for( index = 0; (index < ptd_map_buff->max_ptds) || (finished_map != 0); index++) { td_ptd_map = &(ptd_map_buff->map_list[index]); if(td_ptd_map->ptd_bitmap & finished_map) { /* This ptd needs to be filled */ /* Start filling the ram_data to send it to HC */ td = td_ptd_map->td; ed = td->ed; /* start filling the ptd header */ total_bytes = HC_PTD_HEADER_SIZE; /* ptd total bytes to be written to HC buffer, initialize to ptd header */ /**********************************************************************/ /* ptd_header[0]: 7..0 actual bytes(7...0) 0(always) */ /**********************************************************************/ ram_data[0] = 0; /************************************************************************/ /* ptd_header[1]: 7..4 completion code(3...0) 1111 (always) */ /* ptd_header[1]: 3 active(0) 1 (always) */ /* ptd_header[1]: 2 toggle(0) always data0 */ /* ptd_header[1]: 1..0 actual bytes(9..8) 0 (always) */ /**********
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -