示例#1
0
void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag)
{
	uint16_t v;
	cy_as_device *dev_p;

	dev_p = cy_as_device_find_from_tag(tag);

	/*
	 * only power management interrupts can occur before the
	 * antioch API setup is complete. if this is a PM interrupt
	 *  handle it here; otherwise output a warning message.
	 */
	if (dev_p == 0) {
		v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG);
		if (v == CY_AS_MEM_P0_INTR_REG_PMINT) {
			/* Read the PWR_MAGT_STAT register
			 * to clear this interrupt. */
			v = cy_as_hal_read_register(tag,
				CY_AS_MEM_PWR_MAGT_STAT);
		} else
			cy_as_hal_print_message("stray antioch "
				"interrupt detected"
				", tag not associated "
				"with any created device.");
		return;
	}

	/* Make sure we got a valid object from CyAsDeviceFindFromTag */
	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);

	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG);

	if (v & CY_AS_MEM_P0_INTR_REG_MCUINT)
		cy_as_mcu_interrupt_handler(dev_p);

	if (v & CY_AS_MEM_P0_INTR_REG_PMINT)
		cy_as_power_management_interrupt_handler(dev_p);

	if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT)
		cy_as_pll_lock_loss_interrupt_handler(dev_p);

	/* If the interrupt module is not running, no mailbox
	 * interrupts are expected from the west bridge. */
	if (cy_as_device_is_intr_running(dev_p) == 0)
		return;

	if (v & CY_AS_MEM_P0_INTR_REG_MBINT)
		cy_as_mail_box_interrupt_handler(dev_p);
}
void cy_as_hal_dump_reg(cy_as_hal_device_tag tag)
{
	u16		data16;
	int 	i;
	int	retval = 0;
	printk(KERN_ERR "=======================================\n");
	printk(KERN_ERR "========   Astoria REG Dump      =========\n");
	for ( i=0 ; i<256 ; i++ )
	{
		data16 = cy_as_hal_read_register(tag, i);
		printk(KERN_ERR "%4.4x ", data16);
		if( i%8 == 7 )
			printk(KERN_ERR "\n");
	}
	printk(KERN_ERR "=======================================\n\n");

	printk(KERN_ERR "========   Astoria REG Test      =========\n");
	
	cy_as_hal_write_register(tag, CY_AS_MEM_MCU_MAILBOX1, 0xAAAA);
	cy_as_hal_write_register(tag, CY_AS_MEM_MCU_MAILBOX2, 0x5555);
	cy_as_hal_write_register(tag, CY_AS_MEM_MCU_MAILBOX3, 0xB4C3);

	data16 = cy_as_hal_read_register(tag, CY_AS_MEM_MCU_MAILBOX1);
	if( data16 != 0xAAAA)
	{
		printk(KERN_ERR "REG Test Error in CY_AS_MEM_MCU_MAILBOX1 - %4.4x\n", data16);
		retval = 1; 
	}
	data16 = cy_as_hal_read_register(tag, CY_AS_MEM_MCU_MAILBOX2);
	if( data16 != 0x5555)
	{
		printk(KERN_ERR "REG Test Error in CY_AS_MEM_MCU_MAILBOX2 - %4.4x\n", data16);
		retval = 1;
	}
	data16 = cy_as_hal_read_register(tag, CY_AS_MEM_MCU_MAILBOX3);
	if( data16 != 0xB4C3)
	{	
		printk(KERN_ERR "REG Test Error in CY_AS_MEM_MCU_MAILBOX3 - %4.4x\n", data16);
		retval = 1;
	}

	if( retval)
		printk(KERN_ERR "REG Test fail !!!!!\n");
	else
		printk(KERN_ERR "REG Test success !!!!!\n");

	printk(KERN_ERR "=======================================\n\n");
}
示例#3
0
/*
 * Set the DRQ mask register for the given endpoint number.  If state is
 * CyTrue, the DRQ interrupt for the given endpoint is enabled, otherwise
 * it is disabled.
 */
static void
cy_as_dma_set_drq(cy_as_device *dev_p,
		cy_as_end_point_number_t ep, cy_bool state)
{
	uint16_t mask ;
	uint16_t v ;
	uint32_t intval ;

	/*
	 * there are not DRQ register bits for EP0 and EP1
	 */
	if (ep == 0 || ep == 1)
		return ;

	/*
	 * disable interrupts while we do this to be sure the state of the
	 * DRQ mask register is always well defined.
	 */
	intval = cy_as_hal_disable_interrupts() ;

	/*
	 * set the DRQ bit to the given state for the ep given
	 */
	mask = (1 << ep) ;
	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK) ;

	if (state)
		v |= mask ;
	else
		v &= ~mask ;

	cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK, v) ;
	cy_as_hal_enable_interrupts(intval) ;
}
示例#4
0
void
cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p)
{
	uint16_t v;

	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT);
	v = v;
}
示例#5
0
void
cy_as_power_management_interrupt_handler(cy_as_device *dev_p)
{
	uint16_t v;

	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT);
	v = v;
}
示例#6
0
void  hal_reset(cy_as_hal_device_tag tag)
{
    cy_as_hal_print_message("<1> send soft hard rst: "
                            "MEM_RST_CTRL_REG_HARD...\n");
    cy_as_hal_write_register(tag, CY_AS_MEM_RST_CTRL_REG,
                             CY_AS_MEM_RST_CTRL_REG_HARD);
    mdelay(60);

    cy_as_hal_print_message("<1> after RST: si_rev_REG:%x, "
                            "PNANDCFG_reg:%x\n",
                            cy_as_hal_read_register(tag, CY_AS_MEM_CM_WB_CFG_ID),
                            cy_as_hal_read_register(tag, CY_AS_MEM_PNAND_CFG)
                           );

    /* set it to LBD */
    cy_as_hal_write_register(tag, CY_AS_MEM_PNAND_CFG,
                             PNAND_REG_CFG_INIT_VAL);
}
示例#7
0
void
cy_as_mcu_interrupt_handler(cy_as_device *dev_p)
{
	/* Read and clear the interrupt. */
	uint16_t v;

	v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT);
	v = v;
}
示例#8
0
/*
* Wait for all entries in the DMA queue associated
* the given endpoint to be drained.  This function
* will not return until all the DMA data has been
* transferred.
*/
cy_as_return_status_t
cy_as_dma_drain_queue(cy_as_device *dev_p,
	cy_as_end_point_number_t ep, cy_bool kickstart)
{
	cy_as_dma_end_point *ep_p ;
	int loopcount = 200 ;
	uint32_t mask ;

	/*
	* make sure the endpoint is valid
	*/
	if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0]))
		return CY_AS_ERROR_INVALID_ENDPOINT ;

	/* Get the endpoint pointer based on the endpoint number */
	ep_p = CY_AS_NUM_EP(dev_p, ep) ;

	/*
	* if the endpoint is empty of traffic, we return
	* with success immediately
	*/
	mask = cy_as_hal_disable_interrupts() ;
	if (ep_p->queue_p == 0) {
		cy_as_hal_enable_interrupts(mask) ;
		return CY_AS_ERROR_SUCCESS ;
	} else {
		/*
		 * add 10 seconds to the time out value for each 64 KB segment
		 * of data to be transferred.
		 */
		if (ep_p->queue_p->size > 0x10000)
			loopcount += ((ep_p->queue_p->size / 0x10000) * 100) ;
	}
	cy_as_hal_enable_interrupts(mask) ;

	/* If we are already sleeping on this endpoint, it is an error */
	if (cy_as_dma_end_point_is_sleeping(ep_p))
		return CY_AS_ERROR_NESTED_SLEEP ;

	/*
	* we disable the endpoint while the queue drains to
	* prevent any additional requests from being queued while we are waiting
	*/
	cy_as_dma_enable_end_point(dev_p, ep,
		cy_false, cy_as_direction_dont_change) ;

	if (kickstart) {
		/*
		* now, kick start the DMA if necessary
		*/
		cy_as_dma_kick_start(dev_p, ep) ;
	}

	/*
	* check one last time before we begin sleeping to see if the
	* queue is drained.
	*/
	if (ep_p->queue_p == 0) {
		cy_as_dma_enable_end_point(dev_p, ep, cy_true,
			cy_as_direction_dont_change) ;
		return CY_AS_ERROR_SUCCESS ;
	}

	while (loopcount-- > 0) {
		/*
		 * sleep for 10 ms maximum (per loop) while
		 * waiting for the transfer to complete.
		 */
		cy_as_dma_end_point_set_sleep_state(ep_p) ;
		cy_as_hal_sleep_on(&ep_p->channel, 10) ;

		/* If we timed out, the sleep bit will still be set */
		cy_as_dma_end_point_set_wake_state(ep_p) ;

		/* Check the queue to see if is drained */
		if (ep_p->queue_p == 0) {
			/*
			 * clear the endpoint running and in transit flags
			 * for the endpoint, now that its DMA queue is empty.
			 */
			cy_as_dma_end_point_clear_in_transit(ep_p) ;
			cy_as_dma_end_point_set_stopped(ep_p) ;

			cy_as_dma_enable_end_point(dev_p, ep,
				cy_true, cy_as_direction_dont_change) ;
			return CY_AS_ERROR_SUCCESS ;
		}
	}

	printk(KERN_ERR"cyasdevice:timeout 0xA0 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0xA0));
	printk(KERN_ERR"cyasdevice:timeout 0xA1 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0xA1));
	printk(KERN_ERR"cyasdevice:timeout 0xA2 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0xA2));
	printk(KERN_ERR"cyasdevice:timeout 0x90 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0x90));
	printk(KERN_ERR"cyasdevice:timeout 0x91 = 0x%x\n",cy_as_hal_read_register(dev_p->tag,0x91));
	/*
	 * the DMA operation that has timed out can be cancelled, so that later
	 * operations on this queue can proceed.
	 */
	cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_TIMEOUT) ;
	cy_as_dma_enable_end_point(dev_p, ep,
		cy_true, cy_as_direction_dont_change) ;
	return CY_AS_ERROR_TIMEOUT ;
}
/*
 * Astoria DMA read request, APP_CPU reads from WB ep buffer
 */
static void cy_service_e_p_dma_read_request(
			cy_as_omap_dev_kernel *dev_p, uint8_t ep)
{
	cy_as_hal_device_tag tag = (cy_as_hal_device_tag)dev_p ;
	uint16_t  v, i, size;
	uint16_t	*dptr;
	uint16_t ep_dma_reg = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2;
    register void     *read_addr ;
    register uint16_t a,b,c,d,e,f,g,h ;
	/*
	 * get the XFER size frtom WB eP DMA REGISTER
	 */
	v = cy_as_hal_read_register(tag, ep_dma_reg);

	/*
	 * amount of data in EP buff in  bytes
	 */
	size =  v & CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK;

	/*
	 * memory pointer for this DMA packet xfer (sub_segment)
	 */
	dptr = (uint16_t *) end_points[ep].data_p;

	read_addr = dev_p->m_vma_addr_base + CYAS_DEV_CALC_EP_ADDR(ep) ;

	cy_as_hal_assert(size != 0);

	if (size) {
	     /*
		 * Now, read the data from the device
		 */
		for(i = size/16 ; i > 0 ; i--) {
			a = (unsigned short) readw (read_addr) ;
			b = (unsigned short) readw (read_addr) ;
			c = (unsigned short) readw (read_addr) ;
			d = (unsigned short) readw (read_addr) ;
			e = (unsigned short) readw (read_addr) ;
			f = (unsigned short) readw (read_addr) ;
			g = (unsigned short) readw (read_addr) ;
			h = (unsigned short) readw (read_addr) ;
	                *dptr++ = a ;
	                *dptr++ = b ;
	                *dptr++ = c ;
	                *dptr++ = d ;
	                *dptr++ = e ;
	                *dptr++ = f ;
	                *dptr++ = g ;
	                *dptr++ = h ;
		}
	
		switch ((size & 0xF)/2) {
		case 7:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
		case 6:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
		case 5:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
		case 4:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
		case 3:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
		case 2:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
		case 1:
		    *dptr = (unsigned short) readw(read_addr) ;
		    dptr++ ;
	            break ;
		}
	
		if (size & 1) {
			/* Odd sized packet */
			uint16_t d = (unsigned short) readw (read_addr) ;
			*((uint8_t *)dptr) = (d & 0xff) ;
		}
	}

	/*
	 * clear DMAVALID bit indicating that the data has been read
	 */
	cy_as_hal_write_register(tag, ep_dma_reg, 0) ;

	end_points[ep].seg_xfer_cnt += size;
	end_points[ep].req_xfer_cnt += size;

	/*
	 *  pre-advance data pointer (if it's outside sg
	 * list it will be reset anyway
	 */
	end_points[ep].data_p += size;

	if (prep_for_next_xfer(tag, ep)) {
		/*
		 * we have more data to read in this request,
		 * setup next dma packet due tell WB how much
		 * data we are going to xfer next
		 */
		v = end_points[ep].dma_xfer_sz/*HAL_DMA_PKT_SZ*/ |
				CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL ;
		cy_as_hal_write_register(tag, ep_dma_reg, v);
	} else {
		end_points[ep].pending	  = cy_false ;
		end_points[ep].type		 = cy_as_hal_none ;
		end_points[ep].buffer_valid = cy_false ;

		/*
		 * notify the API that we are done with rq on this EP
		 */
		if (callback) {
			DBGPRN("<1>trigg rd_dma completion cb: xfer_sz:%d\n",
				end_points[ep].req_xfer_cnt);
				callback(tag, ep,
					end_points[ep].req_xfer_cnt,
					CY_AS_ERROR_SUCCESS);
		}
	}
}
/*
 * west bridge astoria ISR (Interrupt handler)
 */
static irqreturn_t cy_astoria_int_handler(int irq,
				void *dev_id, struct pt_regs *regs)
{
	cy_as_omap_dev_kernel *dev_p;
	uint16_t		  read_val = 0 ;
	uint16_t		  mask_val = 0 ;

	/*
	* debug stuff, counts number of loops per one intr trigger
	*/
	uint16_t		  drq_loop_cnt = 0;
	uint8_t		   irq_pin;
	/*
	 * flags to watch
	 */
	const uint16_t	sentinel = (CY_AS_MEM_P0_INTR_REG_MCUINT |
				CY_AS_MEM_P0_INTR_REG_MBINT |
				CY_AS_MEM_P0_INTR_REG_PMINT |
				CY_AS_MEM_P0_INTR_REG_PLLLOCKINT);

	/*
	 * sample IRQ pin level (just for statistics)
	 */
	irq_pin = __gpio_get_value(AST_INT);

	/*
	 * this one just for debugging
	 */
	intr_sequence_num++ ;

	/*
	 * astoria device handle
	 */
	dev_p = dev_id;

	/*
	 * read Astoria intr register
	 */
	read_val = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
						CY_AS_MEM_P0_INTR_REG) ;

	/*
	 * save current mask value
	 */
	mask_val = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
						CY_AS_MEM_P0_INT_MASK_REG) ;

	DBGPRN("<1>HAL__intr__enter:_seq:%d, P0_INTR_REG:%x\n",
			intr_sequence_num, read_val);

	/*
	 * Disable WB interrupt signal generation while we are in ISR
	 */
	cy_as_hal_write_register((cy_as_hal_device_tag)dev_p,
					CY_AS_MEM_P0_INT_MASK_REG, 0x0000) ;

	/*
	* this is a DRQ Interrupt
	*/
	if (read_val & CY_AS_MEM_P0_INTR_REG_DRQINT) {

		do {
			/*
			 * handle DRQ interrupt
			 */
			drq_loop_cnt++;

			cy_handle_d_r_q_interrupt(dev_p) ;

			/*
			 * spending to much time in ISR may impact
			 * average system performance
			 */
			if (drq_loop_cnt >= MAX_DRQ_LOOPS_IN_ISR)
				break;

		/*
		 * Keep processing if there is another DRQ int flag
		 */
		} while (cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
					CY_AS_MEM_P0_INTR_REG) &
					CY_AS_MEM_P0_INTR_REG_DRQINT);
	}

	if (read_val & sentinel)
		cy_as_intr_service_interrupt((cy_as_hal_device_tag)dev_p) ;

	DBGPRN("<1>_hal:_intr__exit seq:%d, mask=%4.4x,"
			"int_pin:%d DRQ_jobs:%d\n",
			intr_sequence_num,
			mask_val,
			irq_pin,
			drq_loop_cnt);

	/*
	 * re-enable WB hw interrupts
	 */
	cy_as_hal_write_register((cy_as_hal_device_tag)dev_p,
					CY_AS_MEM_P0_INT_MASK_REG, mask_val) ;

	return IRQ_HANDLED ;
}
/*
 * init OMAP h/w resources
 */
int cy_as_hal_omap_cram_start(const char *pgm,
				cy_as_hal_device_tag *tag, cy_bool debug)
{
	cy_as_omap_dev_kernel *dev_p ;
	int i;
	u16 data16[4];
	uint32_t err = 0;
	/* No debug mode support through argument as of now */
	(void)debug;

	have_irq = false;

	/*
	 * Initialize the HAL level endpoint DMA data.
	 */
	for (i = 0 ; i < sizeof(end_points)/sizeof(end_points[0]) ; i++) {
		end_points[i].data_p = 0 ;
		end_points[i].pending = cy_false ;
		end_points[i].size = 0 ;	/* No debug mode support through argument as of now */
	(void)debug;
		
		end_points[i].type = cy_as_hal_none ;
		end_points[i].sg_list_enabled = cy_false;

		/*
		 * by default the DMA transfers to/from the E_ps don't
		 * use sg_list that implies that the upper devices like
		 * blockdevice have to enable it for the E_ps in their
		 * initialization code
		 */
	}

	/* allocate memory for OMAP HAL*/
	dev_p = (cy_as_omap_dev_kernel *)cy_as_hal_alloc(
						sizeof(cy_as_omap_dev_kernel)) ;
	if (dev_p == 0) {
		cy_as_hal_print_message("out of memory allocating OMAP"
					"device structure\n") ;
		return 0 ;
	}

	dev_p->m_sig = CY_AS_OMAP_CRAM_HAL_SIG;

	/* initialize OMAP hardware and StartOMAPKernelall gpio pins */
	err = cy_as_hal_processor_hw_init(dev_p);
	if(err)
		goto bus_acc_error;

	/*
	 * Now perform a hard reset of the device to have
	 * the new settings take effect
	 */
	__gpio_set_value(AST_WAKEUP, 1);

	/*
	 * do Astoria  h/w reset
	 */
	DBGPRN(KERN_INFO"-_-_pulse -> westbridge RST pin\n");

	/*
	 * NEGATIVE PULSE on RST pin
	 */
	__gpio_set_value(AST_RESET, 0);
	mdelay(1);
	__gpio_set_value(AST_RESET, 1);
	mdelay(50);


   /*
	*  NOTE: if you want to capture bus activity on the LA,
	*  don't use printks in between the activities you want to capture.
	*  prinks may take milliseconds, and the data of interest
	*  will fall outside the LA capture window/buffer
	*/
	cy_as_hal_dump_reg((cy_as_hal_device_tag)dev_p);

	data16[0] = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p, CY_AS_MEM_CM_WB_CFG_ID);

	if ( (data16[0]&0xA100 != 0xA100) ||  (data16[0]&0xA200 != 0xA200))  {
		/*
		 * astoria device is not found
		 */
		printk(KERN_ERR "ERROR: astoria device is not found, "
			"CY_AS_MEM_CM_WB_CFG_ID %4.4x", data16[0]);
		goto bus_acc_error;
	}

	cy_as_hal_print_message(KERN_INFO" register access test:"
				"\n CY_AS_MEM_CM_WB_CFG_ID:%4.4x\n"
				"after cfg_wr:%4.4x\n\n",
				data16[0], data16[1]);

	dev_p->thread_flag = 1 ;
	spin_lock_init(&int_lock) ;
	dev_p->m_next_p = m_omap_list_p ;

	m_omap_list_p = dev_p ;
	*tag = dev_p;

	cy_as_hal_configure_interrupts((void *)dev_p);

	cy_as_hal_print_message(KERN_INFO"OMAP3430__hal started tag:%p"
				", kernel HZ:%d\n", dev_p, HZ);

	/*
	 *make processor to storage endpoints SG assisted by default
	 */
	cy_as_hal_set_ep_dma_mode(4, true);
	cy_as_hal_set_ep_dma_mode(8, true);

	return 1 ;

	/*
	 * there's been a NAND bus access error or
	 * astoria device is not connected
	 */
bus_acc_error:
	/*
	 * at this point hal tag hasn't been set yet
	 * so the device will not call omap_stop
	 */
	cy_as_hal_omap_hardware_deinit(dev_p);
	cy_as_hal_free(dev_p) ;
	return 0;
}
/*
 * HANDLE DRQINT from Astoria (called in AS_Intr context
 */
static void cy_handle_d_r_q_interrupt(cy_as_omap_dev_kernel *dev_p)
{
	uint16_t v ;
	static uint8_t service_ep = 2 ;

	/*
	 * We've got DRQ INT, read DRQ STATUS Register */
	v = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
			CY_AS_MEM_P0_DRQ) ;

	if (v == 0) {
#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("stray DRQ interrupt detected\n") ;
#endif
		return;
	}

	/*
	 * Now, pick a given DMA request to handle, for now, we just
	 * go round robin.  Each bit position in the service_mask
	 * represents an endpoint from EP2 to EP15.  We rotate through
	 * each of the endpoints to find one that needs to be serviced.
	 */
	while ((v & (1 << service_ep)) == 0) {

		if (service_ep == 15)
			service_ep = 2 ;
		else
			service_ep++ ;
	}

	if (end_points[service_ep].type == cy_as_hal_write) {
		/*
		 * handle DMA WRITE REQUEST: app_cpu will
		 * write data into astoria EP buffer
		 */
		cy_service_e_p_dma_write_request(dev_p, service_ep) ;
	} else if (end_points[service_ep].type == cy_as_hal_read) {
		/*
		 * handle DMA READ REQUEST: cpu will
		 * read EP buffer from Astoria
		 */
		cy_service_e_p_dma_read_request(dev_p, service_ep) ;
	}
#ifndef WESTBRIDGE_NDEBUG
	else
		cy_as_hal_print_message("cyashalomap:interrupt,"
					" w/o pending DMA job,"
					"-check DRQ_MASK logic\n") ;
#endif

	/*
	 * Now bump the EP ahead, so other endpoints get
	 * a shot before the one we just serviced
	 */
	if (end_points[service_ep].type == cy_as_hal_none) {
		if (service_ep == 15)
			service_ep = 2 ;
		else
			service_ep++ ;
	}

}