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

📄 usb_phci.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -