📄 usb_phci.c
字号:
phci_reg_read16(REG_ATL_BUFF_LEN, &data_read); printk(" Buffer_len = %x", data_read); data_read = 0; phci_reg_read16(REG_INTL_BLK_PL_SIZE, &data_read); printk(" Block_pl_size = %x\n", data_read); data_read = 0; phci_reg_read32(REG_INTL_PTD_DONE_MAP, &data_read); printk("done_map = %x", data_read); data_read = 0; phci_reg_read32(REG_INTL_PTD_SKIP_MAP, &data_read); printk(" skip_map %x\n", data_read); data_read = 0; phci_reg_read32(REG_INTL_PTD_LAST_PTD,&data_read); printk("last_ptd_map %x", data_read); }}void phci_urb_print (urb_t * urb, char * str, int small) { unsigned int pipe= urb->pipe; if (!urb->dev || !urb->dev->bus) { printk("%s URB: no dev", str); return; } if (urb->status != 0) printk("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)", str, sphci_get_current_frame_number (urb->dev), usb_pipedevice (pipe), usb_pipeendpoint (pipe), usb_pipeout (pipe)? 'O': 'I', usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): (usb_pipecontrol (pipe)? "CTRL": "BULK"), urb->transfer_flags, urb->actual_length, urb->transfer_buffer_length, urb->status, urb->status); if (!small) { int i, len; if (usb_pipecontrol (pipe)) { printk (KERN_DEBUG __FILE__ ": cmd(8):"); for (i = 0; i < 8 ; i++) printk (" %02x", ((__u8 *) urb->setup_packet) [i]); printk ("\n"); } if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { printk (KERN_DEBUG __FILE__ ": data(%d/%d):", urb->actual_length, urb->transfer_buffer_length); len = usb_pipeout (pipe)? urb->transfer_buffer_length: urb->actual_length; for (i = 0; i < 16 && i < len; i++) printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); printk ("%s stat:%d\n", i < len? "...": "", urb->status); } } }#endif /* __PHCI_DEBUG_DETAIL__ *//*--------------------------------------------------------------* * HC TD-PTD map buffers initialization functions * *--------------------------------------------------------------*/void phci_init_map_buffers(phci_t *phci) { td_ptd_map_buff_t *ptd_map_buff; __u8 buff_type, ptd_index; __u32 bitmap; func_debug(("phci_init_map_buffers(phci = 0x%p)\n",phci)) /* initialize for each buffer type */ for(buff_type = 0; buff_type < TD_PTD_TOTAL_BUFF_TYPES; buff_type++) { ptd_map_buff = &(td_ptd_map_buff[buff_type]); ptd_map_buff->buffer_type = buff_type; /* Set buffer type */#ifdef CONFIG_USB_PHCD_PING_PONG ptd_map_buff->ping_pong_status = 0; /* Set ping pong status to not in use */ ptd_map_buff->ping_ptd_index = TD_PTD_INV_PTD_INDEX; /* ping ptd index is invalid index */ ptd_map_buff->pong_ptd_index = TD_PTD_INV_PTD_INDEX; /* pong ptd index is invalid index */#endif /* CONFIG_USB_PHCD_PING_PONG */ ptd_map_buff->active_ptds = 0; /* active td's = 0 */ ptd_map_buff->total_ptds = 0; /* total td's = 0 */ ptd_map_buff->max_ptds = td_ptd_buff_type_max_ptds[buff_type]; /* set maximum ptds for this buffer type */ ptd_map_buff->active_ptd_bitmap = 0; /* no active ptds */ ptd_map_buff->skip_ptd_bitmap = 0xFFFFFFFF; /* Skip all ptds */ ptd_map_buff->pending_ptd_bitmap = 0x00000000; /* Initially no pending ptds */ bitmap = 0x00000001; for(ptd_index = 0; ptd_index < ptd_map_buff->max_ptds; ptd_index++) { ptd_map_buff->active_ptd_bitmask |= bitmap; bitmap <<= 1; } ptd_map_buff->ram_buff_addr = hc_ram_buff_address[buff_type]; /* Buffer lengths for each buffer */ ptd_map_buff->done_head = NULL; /* No done ptd's */ ptd_map_buff->frame_number = INVALID_FRAME_NUMBER; /* Invalid frame number */ ptd_map_buff->regs.buffer_length = hc_ram_buff_lengths[buff_type]; /* Buffer lengths for each buffer */ ptd_map_buff->regs.buffer_port = hc_ram_buff_port_reg[buff_type]; /* Buffer accessing port register */ ptd_map_buff->regs.block_pl_size = hc_ram_buff_block_pl_size[buff_type]; /* Block pay load size */ ptd_map_buff->regs.toggle_rate = HC_ISTL_DEF_TOGGLE_RATE; /* toggle rate for ISTL buffer */ ptd_map_buff->regs.last_ptd = 0; /* Last PTD for ATL & INTL is zero */ ptd_map_buff->regs.ptd_done_map = 0; /* No PTD is done */ ptd_map_buff->regs.ptd_skip_map = 0; /* Skip all PTD */ ptd_map_buff->regs.curr_active_ptd = 0; /* current active ptd is zero */ ptd_map_buff->regs.threshold_count = HC_DEF_ATL_THRESHOLD_COUNT; /* Default ptd thereshold for ATL */ ptd_map_buff->regs.threshold_timeout = HC_DEF_ATL_THRESHOLD_TIMEOUT; /* Default thereshold timeout for ATL */ /* For each ptd index of this buffer, set the fiedls */ bitmap = 0x00000001;// for(ptd_index = 0; ptd_index < ptd_map_buff->max_ptds; ptd_index++) for(ptd_index = 0; ptd_index < TD_PTD_MAX_BUFF_TDS; ptd_index++){ ptd_map_buff->map_list[ptd_index].state = TD_PTD_NEW; /* Set the td_ptd as new */ ptd_map_buff->map_list[ptd_index].total_bytes = 0; /* total bytes to 0 */ ptd_map_buff->map_list[ptd_index].ptd_bitmap = bitmap; /* set the bitmap for this buffer */ ptd_map_buff->map_list[ptd_index].td = NULL; ptd_map_buff->map_list[ptd_index].ed = NULL; ptd_map_buff->map_list[ptd_index].ping_pong = TD_PTD_NO_PING_PONG; ptd_map_buff->map_list[ptd_index].ram_addr = 0xFFFF; bitmap <<= 1; }/* for( ptd_index */ } /* for(buff_type */} /* phci_init_map_buffers *//* This function is called when ep is linked to the oprational ep list. It searches for the free td_ptd_index. If the ping pong ptd is not set, sets the next free td_ptd_index to pong ptd index *//*--------------------------------------------------------------* * HC get td ptd index from TD-PTD map buffer * *--------------------------------------------------------------*/void phci_get_td_ptd_index(ed_t *ed) { __u8 buff_type = td_ptd_pipe_x_buff_type[ed->type]; __u8 td_ptd_index, index; __u8 max_ptds; td_ptd_map_buff_t *ptd_map_buff = &(td_ptd_map_buff[buff_type]); func_debug(("phci_get_td_ptd_index(ed = 0x%p)\n",ed)) /* ATL PTDs can wait */ max_ptds = (buff_type == TD_PTD_BUFF_TYPE_ATL) ? TD_PTD_MAX_BUFF_TDS : ptd_map_buff->max_ptds; for(td_ptd_index = 0; td_ptd_index < max_ptds; td_ptd_index++) { /* Find the first free slot */ if(ptd_map_buff->map_list[td_ptd_index].state == TD_PTD_NEW) { /* Found a free slot */ if( ed->td_ptd_index == TD_PTD_INV_PTD_INDEX ) { ed->td_ptd_index = td_ptd_index; }#ifdef CONFIG_USB_PHCD_PING_PONG else { /* Might be a bulk pong ptd index (bulk, not already * ping is running and not a pending one) */ if( (ed->type != PIPE_BULK) || (td_ptd_index >= ptd_map_buff->max_ptds) || (ptd_map_buff->ping_ptd_index != TD_PTD_INV_PTD_INDEX) ) { break; } ptd_map_buff->ping_ptd_index = ed->td_ptd_index; ptd_map_buff->pong_ptd_index = td_ptd_index; }#endif /* CONFIG_USB_PHCD_PING_PONG */ ptd_map_buff->map_list[td_ptd_index].state = TD_PTD_OPER; /* put ptd_index to operational state */ ptd_map_buff->map_list[td_ptd_index].td = NULL; /* No td transfer is in progress */ ptd_map_buff->map_list[td_ptd_index].ed = ed; /* initialize the ed pointer */ ptd_map_buff->map_list[td_ptd_index].ping_pong = 0; /* initialize the ping pong flag */ ptd_map_buff->total_ptds ++; /* update # of total td's */ if( ed->type == PIPE_ISOCHRONOUS) { /* reserve additional indexes for ISTL buffer */ for(index=0; index < ptd_map_buff->regs.toggle_rate;index++) { /* for serving till the toggle rate */ ptd_map_buff->map_list[td_ptd_index+index].state = TD_PTD_OPER; ptd_map_buff->map_list[td_ptd_index+index].ed = ed; /* initialize the ed pointer */ } ptd_map_buff = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ISTL1]); for(index=0; index < ptd_map_buff->regs.toggle_rate;index++) { /* for serving till the toggle rate */ ptd_map_buff->map_list[td_ptd_index+index].state = TD_PTD_OPER; ptd_map_buff->map_list[td_ptd_index+index].ed = ed; /* initialize the ed pointer */ } } break; } } return;} /* phci_get_td_ptd_index *//*--------------------------------------------------------------* * HC release td ptd index from TD-PTD map buffer * *--------------------------------------------------------------*/void phci_release_td_ptd_index(ed_t *ed) { __u8 td_ptd_index = ed->td_ptd_index; __u8 buff_type = td_ptd_pipe_x_buff_type[ed->type]; td_ptd_map_buff_t *ptd_map_buff; td_ptd_map_buff_t *ptd_map_buff1; td_ptd_map_t *ptd_map; __u8 index; __u32 ptd_bitmap = 0, skip_map; func_debug(("phci_release_td_ptd_index(ed = 0x%p)\n",ed)) if( td_ptd_index != TD_PTD_INV_PTD_INDEX) { ptd_map_buff = &(td_ptd_map_buff[buff_type]); #ifdef CONFIG_USB_PHCD_PING_PONG /* Check if this is ping pong ptd ed or not, if yes clear the pong ptd index also */ if( ed->type == PIPE_BULK && ptd_map_buff->ping_ptd_index == td_ptd_index){ ptd_map = &(ptd_map_buff->map_list[ptd_map_buff->pong_ptd_index]); ptd_map_buff->total_ptds --; if(ptd_map->td) ptd_map_buff->active_ptds--; ptd_map_buff->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap)); ptd_map->state = TD_PTD_NEW; ptd_map->td = NULL; ptd_map->ed = NULL; ptd_bitmap |= ptd_map->ptd_bitmap; ptd_map_buff->ping_ptd_index = TD_PTD_INV_PTD_INDEX; ptd_map_buff->pong_ptd_index = TD_PTD_INV_PTD_INDEX; ptd_map_buff->ping_pong_status = 0; }#endif /* CONFIG_USB_PHCD_PING_PONG */ ptd_map = &(ptd_map_buff->map_list[td_ptd_index]); ptd_map_buff->total_ptds --; if(ed->type == PIPE_ISOCHRONOUS) { /* For isochronous pipe, clear all the td_ptd_index of toggle rate */ for(index = 0; index < ptd_map_buff->regs.toggle_rate; index++) { ptd_map = &(ptd_map_buff->map_list[td_ptd_index+index]); ptd_map_buff->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap)); ptd_map->state = TD_PTD_NEW; ptd_map->td = NULL; ptd_map->ed = NULL; } ptd_map_buff1 = &(td_ptd_map_buff[TD_PTD_BUFF_TYPE_ISTL1]); for(index = 0; index < ptd_map_buff->regs.toggle_rate; index++) { ptd_map = &(ptd_map_buff1->map_list[td_ptd_index+index]); ptd_map_buff1->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap)); ptd_map->state = TD_PTD_NEW; ptd_map->td = NULL; ptd_map->ed = NULL; } } else { if(ptd_map->td) ptd_map_buff->active_ptds--; /* this ed is deleted in between */ ptd_map_buff->active_ptd_bitmap &= (~(ptd_map->ptd_bitmap)); ptd_map->state = TD_PTD_NEW; ptd_map->td = NULL; ptd_map->ed = NULL; ptd_bitmap |= ptd_map->ptd_bitmap; } ed->td_ptd_index = TD_PTD_INV_PTD_INDEX; if(buff_type == TD_PTD_BUFF_TYPE_ATL) { phci_reg_read32(REG_ATL_PTD_SKIP_MAP, &skip_map); /* Read the ATL skip map */ skip_map |= ptd_map->ptd_bitmap; phci_reg_write32(REG_ATL_PTD_SKIP_MAP,skip_map); /* Skip all ptds */ } } return;} /* end of phci_release_td_ptd_index *//* Applicable only for ATL buffer */void phci_move_pending_td_ptds(td_ptd_map_buff_t *ptd_map_buff) { ed_t *ed; td_t *td; td_ptd_map_t *ptd_map; __u8 td_ptd_index; if(ptd_map_buff->pending_ptd_bitmap) { /* There are some pending ptd maps that need to be moved to Active ptd map */ for(td_ptd_index = 0; td_ptd_index < TD_PTD_MAX_BUFF_TDS; td_ptd_index++) { ptd_map = &(ptd_map_buff->map_list[td_ptd_index]); if(ptd_map->ptd_bitmap & ptd_map_buff->pending_ptd_bitmap) { /* This PTD is pending */ if(td_ptd_index < ptd_map_buff->max_ptds) { /* Just update the Active map */ ptd_map_buff->active_ptd_bitmap |= ptd_map->ptd_bitmap; ptd_map_buff->pending_ptd_bitmap &= (~ptd_map->ptd_bitmap); } else { /* Check if there is room to accomodate this */ if((ptd_map_buff->active_ptd_bitmap & ptd_map_buff->active_ptd_bitmask) != ptd_map_buff->active_ptd_bitmask){ ed = ptd_map->ed; /* Store ED and TD */ td = ptd_map->td; phci_release_td_ptd_index(ed); phci_get_td_ptd_index(ed); ptd_map_buff->active_ptd_bitmap |= ptd_map_buff->map_list[ed->td_ptd_index].ptd_bitmap; ptd_map_buff->pending_ptd_bitmap &= (~ptd_map->ptd_bitmap); } /* Otherwise wait for some one to come to get free */ } } } }}/*--------------------------------------------------------------* *--------------------------------------------------------------* phci_fill_send_ptd:: send_ptd_bitmap: 32bit map for the ptds to be sent ptd_map_buff: map buffer pointer of buffer to be written Skip all the PTDs that are going to be filled by this function. 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. Check and update the Last Ptd, thereshold level. remove the skip map so that PTD's processing starts *--------------------------------------------------------------* *--------------------------------------------------------------*/void phci_fill_send_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 */ __u32 active_ptd_bitmap = 0x0; td_t *td; ed_t *ed; __u8 index = 0; __u32 finished_map = send_ptd_bitmap; __u32 ram_addr; __u32 data_read;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -