Exemplo n.º 1
0
static void ep1_start(void)
{
	PRINTKD( "[%lu]ep1_start dma_len %d remain %d pkt %d\n", (jiffies-start_time)*10, ep1_curdmalen, ep1_remain,
		rx_pktsize);
	
	sa1100_clear_dma(dmachn_rx);
	
	if (!ep1_curdmalen) {
		// ep1_curdmalen is min (rx_pktsize , ep1_remain) 
	  	ep1_curdmalen = rx_pktsize;
		if (ep1_curdmalen > ep1_remain)
			ep1_curdmalen = ep1_remain;

		ep1_curdmapos = pci_map_single(NULL, ep1_curdmabuf, ep1_curdmalen, PCI_DMA_FROMDEVICE);
	}

	UDC_write( Ser0UDCOMP, ep1_curdmalen - 1);
	
	sa1100_start_dma(dmachn_rx, ep1_curdmapos, ep1_curdmalen);

	if ( naking ) {
		/* turn off NAK of OUT packets, if set */
		UDC_flip( Ser0UDCCS1, UDCCS1_RPC );
		naking = 0;
	}
}
Exemplo n.º 2
0
int ep1_init(dma_regs_t *chn)
{
	UDC_write( Ser0UDCOMP, rx_pktsize-1 );
	dmachn_rx = chn;
	sa1100_clear_dma(dmachn_rx);
	ep1_done(-EAGAIN);
	return 0;
}
Exemplo n.º 3
0
void ep1_reset(void)
{
	if (currentPort) {
		rx_pktsize = 8; // OJO
	}
	else
	{	
		rx_pktsize = 1; // OJO
	}

	sa1100_clear_dma(dmachn_rx);
	UDC_clear(Ser0UDCCS1, UDCCS1_FST);
	ep1_done(-EINTR);
}
Exemplo n.º 4
0
/*
 * We want to get here as soon as possible, and get the receiver setup.
 * We use the existing buffer.
 */
static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
{
	if (!si->rxskb) {
		printk(KERN_ERR "sa1100_ir: rx buffer went missing\n");
		return;
	}

	/*
	 * First empty receive FIFO
	 */
	Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;

	/*
	 * Enable the DMA, receiver and receive interrupt.
	 */
	sa1100_clear_dma(si->rxdma);
	sa1100_start_dma(si->rxdma, si->rxbuf_dma, HPSIR_MAX_RXLEN);
	Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE;
}
Exemplo n.º 5
0
/*
 * Note: rev A0-B2 chips don't like FST
 */
void udc_ep2_halt(struct sausb_dev *usb, int halt)
{
	usb->ep[1].host_halt = halt;

	if (halt) {
		usb->ep[1].udccs |= UDCCS2_FST;
		udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
	} else {
		sa1100_clear_dma(usb->ep[1].dmach);

		udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
		udc_set_cs2(0, UDCCS2_FST, 0);
		udc_set_cs2(UDCCS2_SST, UDCCS2_SST, 0);

		usb->ep[1].udccs &= ~UDCCS2_FST;

		udc_ep2_done(usb, -EINTR);
	}
}
Exemplo n.º 6
0
int udc_ep2_send(struct sausb_dev *usb, char *buf, int len)
{
	unsigned long flags;
	dma_addr_t dma;
	int ret;

	if (!buf || len == 0) {
printk("%s: returning -EINVAL. buf = %x, len = %x\n",__FUNCTION__,(int)buf,len);
		return -EINVAL;
	}

#if 1
/* NCB added to resolve aligment problem */


	if (len > SEND_BUFFER_SIZE) {
printk("%s: buffer too big %d\n",__FUNCTION__,len);
	    return -EINVAL;
	}
	    
/* try to let usb tx drain */
	if (usb->ep[1].buflen) {
#if 0
	    int i;
printk("%s: busy sending %d - waiting 5secs\n",__FUNCTION__,usb->ep[1].buflen);
	    for (i=0; i<500; i++) {
		udelay(10000);
		if (!usb->ep[1].buflen)
		    break;
	    }
#endif
	    if (usb->ep[1].buflen) {
printk("%s: busy sending %d - returning -EBUSY\n",__FUNCTION__,usb->ep[1].buflen);
		return -EBUSY;
	    }
	}
	    
/* start by not manipulating the buffer while anything remaining to be sent */
	spin_lock_irqsave(&usb->lock, flags);

	if (index+len>SEND_BUFFER_SIZE) {
//	    printk("usb_send: udc_ep2_send - len is %x, reduced to 4096\n",len);
	    index=0;
	}
	else
	    // align index on a 32 bit boundary
	    while (index%3)
		index++;
	
	/* copy buffer to aligned memory area */
	memcpy(send_buffer+index,buf,len);
	dma = dma_map_single(usb->dev, send_buffer+index, len, DMA_TO_DEVICE);
#else
	dma = dma_map_single(usb->dev, buf, len, DMA_TO_DEVICE);
	spin_lock_irqsave(&usb->lock, flags);
#endif

	do {
		if (!usb->ep[1].configured) {
printk("%s: -ENODEV\n",__FUNCTION__);
			ret = -ENODEV;
			break;
		}

		if (usb->ep[1].buflen) {
printk("%s: -EBUSY\n",__FUNCTION__);
			ret = -EBUSY;
			break;
		}

		usb->ep[1].bufdma = dma;
		usb->ep[1].buflen = len;
		usb->ep[1].pktdma = dma;
		ep2_remain = len;

		sa1100_clear_dma(usb->ep[1].dmach);

		ep2_start(usb);
		ret = 0;
	} while (0);
	spin_unlock_irqrestore(&usb->lock, flags);

#if 0
if (ret == -EBUSY) {
	printk("%s: busy so resetting endpoint\n",__FUNCTION__);	
//	sa1100_clear_dma(usb->ep[1].dmach);
//	ep2_start(usb);
	udc_ep2_send_reset(usb);
	}
	else
#endif
	if (ret) {
printk("%s: returning -%d\n",__FUNCTION__,ret);
		dma_unmap_single(usb->dev, dma, len, DMA_TO_DEVICE);
	}

	return ret;
}
Exemplo n.º 7
0
void udc_ep2_int_hndlr(struct sausb_dev *usb)
{
	u32 status = Ser0UDCCS2;

	// check for stupid silicon bug.
	if (Ser0UDCAR != usb->ctl->address)
		Ser0UDCAR = usb->ctl->address;

	udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0);

	if (!(status & UDCCS2_TPC)) {
	    char *buf = (char *) usb->ep[1].bufdma;
	    int len = usb->ep[1].buflen;
		printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
printk("%s: hmm, what to do here?\n",__FUNCTION__);	
//		udc_ep2_send_reset(usb);
printk("%s: Buffer is %x length %d\n",__FUNCTION__,(int)buf,len);	
    if (buf && len) {
printk("%s: Retransmitting\n",__FUNCTION__);	
		udc_ep2_send(usb, buf, len);
    }
		return;
	}

	sa1100_stop_dma(usb->ep[1].dmach);

	if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
		printk("usb_send: transmit error %x\n", status);
		usb->ep[1].fifo_errs ++;
		udc_ep2_done(usb, -EIO);
	} else {
		unsigned int imp;
#if 1		// 22Feb01ww/Oleg
		imp = ep2_curdmalen;
#else
		// this is workaround for case when setting
		// of Ser0UDCIMP was failed
		imp = Ser0UDCIMP + 1;
#endif
		usb->ep[1].pktdma += imp;
		ep2_remain -= imp;

		usb->ep[1].bytes += imp;
		usb->ep[1].packets++;

		sa1100_clear_dma(usb->ep[1].dmach);

#if 0
    /* induce horrible 5ms delay */
	    {
		udelay(1000);
		udelay(1000);
		udelay(1000);
		udelay(1000);
		udelay(1000);
	    }
#endif

		if (ep2_remain != 0) {
			ep2_start(usb);
		} else {
			udc_ep2_done(usb, 0);
		}
	}
}