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

📄 usb_phci.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:

} /* 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.fill_status = 0;
			ptd_map_buff->ping_pong.fill_seq = PP_SEQ_PING_PONG;
			ptd_map_buff->ping_pong.fill_count = 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[HC_PTD_HEADER_SIZE];
	__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;


	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->total_ptds){

				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 */
				g_buff_sts &= (~ATL_ACTIVE);
				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->swHeadP & HC_ED_TOGGLE) >> 1)) << 2);
			}
	
			/**********************************************************************/
			/* ptd_header[2]: 7..0		Max.PacketSize(7...0)		from ed MPS	  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -