Beispiel #1
0
/*
 * Update the
 */
int ide_driveid_update (ide_drive_t *drive)
{
    /*
     * Re-read drive->id for possible DMA mode
     * change (copied from ide-probe.c)
     */
    struct hd_driveid *id;
    unsigned long timeout, flags;

    SELECT_MASK(HWIF(drive), drive, 1);
    if (IDE_CONTROL_REG)
        OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
    ide_delay_50ms();
    OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG);
    timeout = jiffies + WAIT_WORSTCASE;
    do
    {
        if (0 < (signed long)(jiffies - timeout))
        {
            SELECT_MASK(HWIF(drive), drive, 0);
            return 0;	/* drive timed-out */
        }
        ide_delay_50ms();	/* give drive a breather */
    }
    while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT);
    ide_delay_50ms();	/* wait for IRQ and DRQ_STAT */
    if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT))
    {
        SELECT_MASK(HWIF(drive), drive, 0);
        printk("%s: CHECK for good STATUS\n", drive->name);
        return 0;
    }
    __save_flags(flags);	/* local CPU only */
    __cli();		/* local CPU only; some systems need this */
    SELECT_MASK(HWIF(drive), drive, 0);
    id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
    if (!id)
    {
        __restore_flags(flags);	/* local CPU only */
        return 0;
    }
    ide_input_data(drive, id, SECTOR_WORDS);
    (void) GET_STAT();	/* clear drive IRQ */
    ide__sti();		/* local CPU only */
    __restore_flags(flags);	/* local CPU only */
    ide_fix_driveid(id);
    if (id)
    {
        drive->id->dma_ultra = id->dma_ultra;
        drive->id->dma_mword = id->dma_mword;
        drive->id->dma_1word = id->dma_1word;
        /* anything more ? */
        kfree(id);
    }

    return 1;
}
Beispiel #2
0
/*
 * promise_read_intr() is the handler for disk read/multread interrupts
 */
static ide_startstop_t promise_read_intr (ide_drive_t *drive)
{
	byte stat;
	int i;
	unsigned int sectors_left, sectors_avail, nsect;
	struct request *rq;

	if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
		return ide_error(drive, "promise_read_intr", stat);
	}

read_again:
	do {
	    sectors_left = IN_BYTE(IDE_NSECTOR_REG);
	    IN_BYTE(IDE_SECTOR_REG);
	} while (IN_BYTE(IDE_NSECTOR_REG) != sectors_left);
	rq = HWGROUP(drive)->rq;
	sectors_avail = rq->nr_sectors - sectors_left;

read_next:
	rq = HWGROUP(drive)->rq;
	if ((nsect = rq->current_nr_sectors) > sectors_avail)
		nsect = sectors_avail;
	sectors_avail -= nsect;
	ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
#ifdef DEBUG
	printk("%s:  promise_read: sectors(%ld-%ld), buffer=0x%08lx, "
	       "remaining=%ld\n", drive->name, rq->sector, rq->sector+nsect-1, 
	       (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect);
#endif
	rq->sector += nsect;
	rq->buffer += nsect<<9;
	rq->errors = 0;
	i = (rq->nr_sectors -= nsect);
	if ((rq->current_nr_sectors -= nsect) <= 0)
		ide_end_request(1, HWGROUP(drive));
	if (i > 0) {
		if (sectors_avail)
		    goto read_next;
		stat = GET_STAT();
		if(stat & DRQ_STAT)
		    goto read_again;
		if(stat & BUSY_STAT) {
		    ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL);
		    return ide_started;
		}
		printk("Ah! promise read intr: sectors left !DRQ !BUSY\n");
		return ide_error(drive, "promise read intr", stat);
	}
	return ide_stopped;
}
Beispiel #3
0
static __inline__ int
wait_for_ready(ide_drive_t *drive)
{
	/* Timeout bumped for some powerbooks */
	int timeout = 2000;
	byte stat;

	while(--timeout) {
		stat = GET_STAT();
		if(!(stat & BUSY_STAT)) {
			if (drive->ready_stat == 0)
				break;
			else if((stat & drive->ready_stat) || (stat & ERR_STAT))
				break;
		}
		mdelay(1);
	}
	if((stat & ERR_STAT) || timeout <= 0) {
		if (stat & ERR_STAT) {
			printk(KERN_ERR "ide_pmac: wait_for_ready, error status: %x\n", stat);
		}
		return 1;
	}
	return 0;
}
/* timer : first half work */
static void bh1721_poll_timer(unsigned long data)
{
	D("enter %s \n", __func__);
	if(!GET_STAT(IR)) {
		DERR("Enter %s during polling disabled\n", __func__);
		return;
	}
	schedule_work(&the_data.work);
}
/* timer stop : timer unregister */
static void bh1721_poll_timer_stop(void)
{
	D("enter %s \n", __func__);
	if(!GET_STAT(IR)) {
		DERR("Enter %s during poll disabled\n", __func__);
		return;
	}
	del_timer_sync(&the_data.timer);
	flush_work(&the_data.work);
	CLR_STAT(IR);
}
/* timer start : timer register */
static void bh1721_poll_timer_start(void)
{
	D("enter %s \n", __func__);
	if(GET_STAT(IR)) {
		DERR("Enter %s during poll enabled\n", __func__);
		return;
	}
	SET_STAT(IR);
	setup_timer(&the_data.timer, bh1721_poll_timer,
						(unsigned long)&the_data);
	INIT_WORK(&the_data.work, bh1721_poll_timer_work);
	schedule_work(&the_data.work);
}
static ssize_t als_control_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	return sprintf(buf,
			" lux		= %4d, \t test_lux	= %4d\n"
			" poll time(ms)	= %4d,\n"
			" resmode	= %4d, \t resol		= %4d\n"
			" scail_m	= %4d, \t scail_n	= %4d\n"
			" blink_on	= %4d, \t led_value 	= %4d\n"
			" lux_min	= %4d, \t lux_blink	= %4d\n"
			" blink_c	= %4d, \t\n"
			" PS		= %4d, \t LG		= %4d\n"
			" CA		= %4d, \t IR		= %4d\n",
			the_data.lux, 		the_data.test_lux,
			the_data.polling,
			the_data.resmode, 	the_data.resol,
			the_data.scail_m, 	the_data.scail_n,
			the_data.blink_on,	the_data.led_value,
			the_data.lux_min,	the_data.lux_blink,
			the_data.blink_c,
			GET_STAT(PS),		GET_STAT(LG),
			GET_STAT(CA),		GET_STAT(IR));
}
Beispiel #8
0
/*
 * do_pdc4030_io() is called from do_rw_disk, having had the block number
 * already set up. It issues a READ or WRITE command to the Promise
 * controller, assuming LBA has been used to set up the block number.
 */
ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq)
{
	unsigned long timeout;
	byte stat;

	if (rq->cmd == READ) {
	    ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
	    OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
/* The card's behaviour is odd at this point. If the data is
   available, DRQ will be true, and no interrupt will be
   generated by the card. If this is the case, we need to simulate
   an interrupt. Ugh! Otherwise, if an interrupt will occur, bit0
   of the SELECT register will be high, so we can just return and
   be interrupted.*/
	    timeout = jiffies + HZ/20; /* 50ms wait */
	    do {
		stat=GET_STAT();
		if(stat & DRQ_STAT) {
                    disable_irq(HWIF(drive)->irq);
		    ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL);
                    enable_irq(HWIF(drive)->irq);
		    return ide_stopped;
		}
		if(IN_BYTE(IDE_SELECT_REG) & 0x01)
		    return ide_started;
		udelay(1);
	    } while (time_before(jiffies, timeout));
	    printk("%s: reading: No DRQ and not waiting - Odd!\n",
		   drive->name);
	    return ide_started;
	}
	if (rq->cmd == WRITE) {
	    ide_startstop_t startstop;
	    OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
	    if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
		printk("%s: no DRQ after issuing PROMISE_WRITE\n", drive->name);
		return startstop;
	    }
	    if (!drive->unmask)
		__cli();	/* local CPU only */
	    HWGROUP(drive)->wrq = *rq; /* scratchpad */
	    return promise_write(drive);
	}
	printk("%s: bad command: %d\n", drive->name, rq->cmd);
	ide_end_request(0, HWGROUP(drive));
	return ide_stopped;
}
/* dvi gpio control */
static int dvi_high(int on)
{
	if (on != 0 && on != 1) {
		DERR("%s : on value : %dis not valid \n", __func__, on);
		return -1;
	}

	if(!GET_STAT(IR))
		msleep(2);

	if(on)
		SET_STAT(LG);
	else
		CLR_STAT(LG);

	gpio_set_value(DVI_GPIO_PIN, on);
	return 0;

}
Beispiel #10
0
/*
 * dma_intr() is the handler for disk read/write DMA interrupts
 */
static void dma_intr (ide_drive_t *drive)
{
	byte stat, dma_stat;
	int i;
	struct request *rq = HWGROUP(drive)->rq;
	unsigned short dma_base = HWIF(drive)->dma_base;

	dma_stat = inb(dma_base+2);		/* get DMA status */
	outb(inb(dma_base)&~1, dma_base);	/* stop DMA operation */
	stat = GET_STAT();			/* get drive status */
	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
		if ((dma_stat & 7) == 4) {	/* verify good DMA status */
			rq = HWGROUP(drive)->rq;
			for (i = rq->nr_sectors; i > 0;) {
				i -= rq->current_nr_sectors;
				ide_end_request(1, HWGROUP(drive));
			}
			return;
		}
		printk("%s: bad DMA status: 0x%02x\n", drive->name, dma_stat);
	}
	sti();
	ide_error(drive, "dma_intr", stat);
}
Beispiel #11
0
/*
 * promise_write_pollfunc() is the handler for disk write completion polling.
 */
static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
{
	int i;
	ide_hwgroup_t *hwgroup = HWGROUP(drive);
	struct request *rq;

        if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
            if (time_before(jiffies, hwgroup->poll_timeout)) {
                ide_set_handler (drive, &promise_write_pollfunc, 1, NULL);
                return ide_started; /* continue polling... */
            }
            printk("%s: write timed-out!\n",drive->name);
            return ide_error (drive, "write timeout", GET_STAT());
        }
        
	if (ide_multwrite(drive, 4))
		return ide_stopped;
        rq = hwgroup->rq;
        for (i = rq->nr_sectors; i > 0;) {
            i -= rq->current_nr_sectors;
            ide_end_request(1, hwgroup);
        }
        return ide_stopped;
}
Beispiel #12
0
/*
 * dma_intr() is the handler for disk read/write DMA interrupts
 */
void ide_dma_intr (ide_drive_t *drive)
{
	int i;
	byte stat, dma_stat;

	DPRINT("ide_dma_intr\n");
	dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
	stat = GET_STAT();			/* get drive status */
	DPRINT("stat=%02x\n", stat);
	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
		if (!dma_stat) {
			struct request *rq = HWGROUP(drive)->rq;
			rq = HWGROUP(drive)->rq;
			for (i = rq->nr_sectors; i > 0;) {
				i -= rq->current_nr_sectors;
				ide_end_request(1, HWGROUP(drive));
			}
			return;
		}
		printk("%s: dma_intr: bad DMA status\n", drive->name);
	}
	ide__sti();	/* local CPU only */
	ide_error(drive, "dma_intr", stat);
}
Beispiel #13
0
/*
 * Set a new transfer mode at the drive
 */
int cs5530_set_xfer_mode (ide_drive_t *drive, byte mode)
{
	int		i, error = 1;
	byte		stat;
	ide_hwif_t	*hwif = HWIF(drive);

	printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, strmode(mode));
	/*
	 * If this is a DMA mode setting, then turn off all DMA bits.
	 * We will set one of them back on afterwards, if all goes well.
	 *
	 * Not sure why this is needed (it looks very silly),
	 * but other IDE chipset drivers also do this fiddling.  ???? -ml
 	 */
	switch (mode) {
		case XFER_UDMA_4:
		case XFER_UDMA_3:
		case XFER_UDMA_2:
		case XFER_UDMA_1:
		case XFER_UDMA_0:
		case XFER_MW_DMA_2:
		case XFER_MW_DMA_1:
		case XFER_MW_DMA_0:
		case XFER_SW_DMA_2:
		case XFER_SW_DMA_1:
		case XFER_SW_DMA_0:
			drive->id->dma_ultra &= ~0xFF00;
			drive->id->dma_mword &= ~0x0F00;
			drive->id->dma_1word &= ~0x0F00;
	}

	/*
	 * Select the drive, and issue the SETFEATURES command
	 */
	disable_irq(hwif->irq);
	udelay(1);
	SELECT_DRIVE(HWIF(drive), drive);
	udelay(1);
	if (IDE_CONTROL_REG)
		OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
	OUT_BYTE(mode, IDE_NSECTOR_REG);
	OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
	OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
	udelay(1);	/* spec allows drive 400ns to assert "BUSY" */

	/*
	 * Wait for drive to become non-BUSY
	 */
	if ((stat = GET_STAT()) & BUSY_STAT) {
		unsigned long flags, timeout;
		__save_flags(flags);	/* local CPU only */
		ide__sti();		/* local CPU only -- for jiffies */
		timeout = jiffies + WAIT_CMD;
		while ((stat = GET_STAT()) & BUSY_STAT) {
			if (0 < (signed long)(jiffies - timeout))
				break;
		}
		__restore_flags(flags); /* local CPU only */
	}

	/*
	 * Allow status to settle, then read it again.
	 * A few rare drives vastly violate the 400ns spec here,
	 * so we'll wait up to 10usec for a "good" status
	 * rather than expensively fail things immediately.
	 */
	for (i = 0; i < 10; i++) {
		udelay(1);
		if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
			error = 0;
			break;
		}
	}
	enable_irq(hwif->irq);

	/*
	 * Turn dma bit on if all is okay
	 */
	if (error) {
		(void) ide_dump_status(drive, "cs5530_set_xfer_mode", stat);
	} else {
		switch (mode) {
			case XFER_UDMA_4:   drive->id->dma_ultra |= 0x1010; break;
			case XFER_UDMA_3:   drive->id->dma_ultra |= 0x0808; break;
			case XFER_UDMA_2:   drive->id->dma_ultra |= 0x0404; break;
			case XFER_UDMA_1:   drive->id->dma_ultra |= 0x0202; break;
			case XFER_UDMA_0:   drive->id->dma_ultra |= 0x0101; break;
			case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break;
			case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break;
			case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break;
			case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break;
			case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break;
			case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
		}
	}
	return error;
}
void handle_Control ( )
{
	unsigned int usb_cnt=0;
	if((EP_STATUS_OUT & 0x01)||(EP_STATUS_IN & 0x01))                                                                                          // 8 byte setup data received
	{     
		EP_STATUS_OUT = 0x01;                                                                                 // write 1 to clear
		EP_STATUS_IN = 0x01;

		EP_STATE[0] = EP_IDLE;    // force EP_STATE[0] to EP_IDLE
		system.usbp0_data.wait_out_report=0;

		if (CNT0 == 8)                // Make sure that EP 0 has an Out Packet of size 8 byte
		{                                
			// added on 2011.5.8 to fix usb set_report error.
			if (EP0_ADDR_DEF==0x21 && EP0_ADDR_DEF_1 == 0x09 )
			{
				USBINT0 = 0xc0;
				Set_Report();
				system.usbp0_data.report_id=EP0_ADDR_DEF_2;
				system.usbp0_data.report_type = EP0_ADDR_DEF_3;
		
				set_ep_rdy(EP_0);			// 1:Endpoint 0 ready for transfer USB data.
			}
			else if(EP0_ADDR_DEF==0x21 && EP0_ADDR_DEF_1 == 0x01 )
			{								// Fix SET_CUR request error
				SET_CUR();
			}
			else
			{
				fifo_Read (EP_0, 8, (UINT8 *) & setup);
				// Get setup Packet off of Fifo,
				// it is currently Big-Endian

				// Compiler Specific - these next three
				// statements swap the bytes of the
				// setup packet words to Big Endian so
				// they can be compared to other 16-bit
				// values elsewhere properly
//				USBINT0 = 0xc0;
//				set_ep_rdy(EP_0);			// 1:Endpoint 0 ready for transfer USB data.
				setup.wValue.i = setup.wValue.c[MSB] + ((int)setup.wValue.c[LSB] << 8);			// High byte and low byte exchange()
				setup.wIndex.i = setup.wIndex.c[MSB] + ( (int)setup.wIndex.c[LSB] << 8);
				setup.wLength.i = setup.wLength.c[MSB] + ( (int)setup.wLength.c[LSB] << 8);

				// Intercept HID class - specific requests
				// Class request.
//				if( (setup.bmRequestType & ~ 0x80) == DSC_HID) 
				if((setup.bmRequestType & cRequestType) == cClassReq)
				{
					#if	0
					switch (setup.bRequest) 
					{
						case GET_REPORT:
							Get_Report ( );
							break;
						case SET_REPORT:
							Set_Report();          
							break;
						case GET_IDLE:
							Get_Idle ( );
							break;
						case SET_IDLE:
							Set_Idle ( );
							break;
						case GET_PROTOCOL:
							Get_Protocol ( );
							break;
						case SET_PROTOCOL:
							Set_Protocol ( );
							break;
						default:
							force_Stall ( );      // Send stall to host if invalid
							break;                 // request
					}
					#endif
					switch(setup.bRequest)
					{
					// bmRequestType, bRequest, bChannelNum.(CN), bControlSelect(CS, include volume, mute etc.), bInterfaceNO, bTerminal/unit ID, wLength.
					// CTL: 21 01 00 02  00 05 02 00
					// DO:  00 00
						case cSET_CUR:
							if(setup.wIndex.c[1] >= 3)		// HID interface.
							{
								Get_Report();
							}
							else
								SET_CUR();
							break;

						case cSET_MIN:
							if(setup.wIndex.c[1] >= 3)		// HID interface.
							{
								Get_Idle();
							}
							else
								SET_MIN();
							break;

						case cSET_MAX:
							SET_MAX();
							break;

						case cSET_RES:
							SET_RES();
							break;

						case cSET_MEM:
							SET_MEM();
							break;

/*
						case GET_REPORT:
							Get_Report();
							break;
*/
						case SET_REPORT:
							Set_Report();          
							break;
/*								
						case GET_IDLE:
							Get_Idle ( );
							break;
*/	
						case SET_IDLE:
							Set_Idle ( );
							break;
								
						case cGET_CUR:
							GET_CUR();
							break;

						case cGET_MIN:
							GET_MIN();
							break;

						case cGET_MAX:
							GET_MAX();
							break;

						case cGET_RES:
							GET_RES();
							break;

						case cGET_MEM:
							GET_MEM();
							break;

						case cGET_STAT:
							GET_STAT();
							break;
							
						default:
							force_Stall ( );      // Send stall to host if invalid
							break;                 // request
					}
					
				} 
				else
				{
					// Standard request.
					switch (setup.bRequest)       // Call correct subroutine to handle
					{                             // each kind of standard request
						case GET_STATUS:
							Get_Status ( );
							break;
						case CLEAR_FEATURE:
							Clear_Feature ( );
							break;
						case SET_FEATURE:
							Set_Feature ( );
							break;
						case SET_ADDRESS:
							Set_Address ( );
							break;
						case GET_DESCRIPTOR:
							Get_Descriptor ( );
							break;
						case GET_CONFIGURATION:
							Get_Configuration ( );
							break;
						case SET_CONFIGURATION:
							Set_Configuration( );
							break;
						case GET_INTERFACE:
							Get_Interface ( );
							break;
						case SET_INTERFACE:		// 01 0b   00 00(wValue)   01 00(wIndex)   00 00
							Set_Interface ( );	// wValue:Interface alternate setting(0x0 is zero bandwith alternate setting, 0x01 is normal isochronous operate)
							break;				// wIndex: Interface number of one of the audiostreaming interface.
						default:
							force_Stall ( );                 // Send stall to host if invalid request
							break;
					}
				}
			}
		}      
		else 
		{
			force_Stall ( );                       // if rec setup data is not 8 byte , protacal stall
		}
	}   
	else if (EP_STATE[0] == EP_SET_ADDRESS)     // Handle Status Phase of Set Address
	{
		FUNCT_ADR = setup.wValue.c[LSB];         // set usb Address SFR
		EP_STATE[0] = EP_IDLE;


	}
	else if (EP_STATE[0] == EP_WAIT_STATUS)
	{
		EP_STATE[0] = EP_IDLE;

		wait_tx_status=0;
	}   
	else if (EP_STATE[0] == EP_RX)              // See if endpoint should transmit
	{  							// Out Token. PC->Device.
		if (DATASIZE >= EP0_PACKET_SIZE)
		{
			fifo_Read(EP_0, EP0_PACKET_SIZE, (unsigned char * )DATAPTR);
			// Advance data pointer
			DATAPTR  += EP0_PACKET_SIZE;
			// Decrement data size
			DATASIZE -= EP0_PACKET_SIZE;
			// Increment data sent counter
			DATASENT += EP0_PACKET_SIZE;            
		}
		else
		{
			// read bytes from FIFO
//			// Report type: 0x01 input, 0x02 output, 0x03 feature report.
			if( system.usbp0_data.wait_out_report && (system.usbp0_data.report_type==PC_SET_REPORT_2) && (system.usbp0_data.report_id==PC_SET_REPORT_1) )
			{
				system.usbp0_data.wait_out_report=0;
				DATAPTR = & EP0_ADDR_DEF;
			
				if(PC_SET_REPORT_1 == DATAPTR[0])
				{
					DATAPTR++;
					DATASIZE--;
				}

				for ( system.usbp0_data.report_cnt = 0;         // read  num = NO  fifo_data;   
					system.usbp0_data.report_cnt< DATASIZE;
					system.usbp0_data.report_cnt ++ )
				{
					system.usbp0_data.set_report_data[system.usbp0_data.report_cnt] = DATAPTR[system.usbp0_data.report_cnt];
				}
				system.usbp0_data.aceept = 1;  
				system.usbp0_data.reday_report_flag = 0;
				set_report_status_phace=1;
			}
			else
			{
				fifo_Read (EP_0, DATASIZE, (UINT8 * ) DATAPTR);
				// KEYBOARD_OUT_REPORT
				if (system.usbp0_data.wait_out_report)
				{
					numlock_sta = system.usbp0_data.out_report[0] & 0x01;
					system.usbp0_data.out_report_index = DATASIZE;
					system.usbp0_data.wait_out_report=0;
					set_report_status_phace=1;
				}

			}

			set_Wait_Status ( );                  // set Endpoint to EP_WAIT_STATUS
		}

		if ( (DATASENT == setup.wLength.i) && (set_report_status_phace==0) )
		{
			set_Wait_Status ( );
		}
		set_report_status_phace=0;
	}   
    
	if (EP_STATE[0] == EP_TX)                                        // See if endpoint should transmit
	{     									// In Token, device->PC

		if ((DATASIZE == 0))// || (DATASENT == setup.wLength.i))   // when all data has been sent over
		{

			set_Wait_Status ( );

		}
		else
		{   
			CFG_EP0_1 = 0xc0; 
			if (DATASIZE >= EP0_PACKET_SIZE)
			{
				// Break Data into multiple packets if larger than Max Packet
				fifo_Write (EP_0, EP0_PACKET_SIZE, (unsigned char*)DATAPTR);
				// Advance data pointer
				DATAPTR  += EP0_PACKET_SIZE;
				// Decrement data size
				DATASIZE -= EP0_PACKET_SIZE;
				// Increment data sent counter
				DATASENT += EP0_PACKET_SIZE;
			}

			else
			{

				// If data is less than Max Packet size or zero
				fifo_Write (EP_0, DATASIZE, (unsigned char*)DATAPTR);
				// Increment data sent counter
				DATASENT += DATASIZE;
				// Decrement data size
				DATASIZE = 0;
				USBINT0 = 0xc0;   
				EP_RDY = 0x01 ;

				// when usb_reset and send ok inttrupt (USBINT0&0x48)!=0 // when setup come (EP_STATUS & 0x01) will set
				 while(((USBINT0 & 0x4C) == 0) && ((EP_STATUS_OUT & 0x01) == 0));   //wait usb_reset, suspend or sending end interrupt  happend, wait setup come
				if((USBINT0&0x40) !=0) 
				{  
					CFG_EP0_1 =0x40;
					EP_RDY = 0x01 ;
					USBINT0 = 0xc0;
					EP_STATE[0]= EP_WAIT_STATUS;

				}
				wait_tx_status = 1; 
				system.usbp0_data.wait_out_report=0;
			} 
		}   
	}


	if (system.usbp0_data.wait_out_report==0 && wait_tx_status ==0)  
	{  
		USBINT0 = 0xc0;
		//   set_ep_rdy(EP_0);   // set ready to receive or send next packet
		EP_RDY = 0x01 ;  
	}
}
Beispiel #15
0
/*
 * Verify that we are doing an approved SETFEATURES_XFER with respect
 * to the hardware being able to support request.  Since some hardware
 * can improperly report capabilties, we check to see if the host adapter
 * in combination with the device (usually a disk) properly detect
 * and acknowledge each end of the ribbon.
 */
int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
{
    if ((cmd == WIN_SETFEATURES) &&
            (nsect > XFER_UDMA_2) &&
            (feature == SETFEATURES_XFER))
    {
        if (!HWIF(drive)->udma_four)
        {
            printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name);
            return 1;
        }
#ifndef CONFIG_IDEDMA_IVB
        if ((drive->id->hw_config & 0x6000) == 0)
        {
#else /* !CONFIG_IDEDMA_IVB */
        if (((drive->id->hw_config & 0x2000) == 0) ||
                ((drive->id->hw_config & 0x4000) == 0))
        {
#endif /* CONFIG_IDEDMA_IVB */
            printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name);
            return 1;
        }
    }
    return 0;
}

/*
 * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
 * 1 : Safe to update drive->id DMA registers.
 * 0 : OOPs not allowed.
 */
int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
{
    if ((cmd == WIN_SETFEATURES) &&
            (nsect >= XFER_SW_DMA_0) &&
            (feature == SETFEATURES_XFER) &&
            (drive->id->dma_ultra ||
             drive->id->dma_mword ||
             drive->id->dma_1word))
        return 1;

    return 0;
}

/*
 *  All hosts that use the 80c ribbon mus use!
 */
byte eighty_ninty_three (ide_drive_t *drive)
{
    return ((byte) ((HWIF(drive)->udma_four) &&
#ifndef CONFIG_IDEDMA_IVB
                    (drive->id->hw_config & 0x4000) &&
#endif /* CONFIG_IDEDMA_IVB */
                    (drive->id->hw_config & 0x6000)) ? 1 : 0);
}

/*
 * Similar to ide_wait_stat(), except it never calls ide_error internally.
 * This is a kludge to handle the new ide_config_drive_speed() function,
 * and should not otherwise be used anywhere.  Eventually, the tuneproc's
 * should be updated to return ide_startstop_t, in which case we can get
 * rid of this abomination again.  :)   -ml
 *
 * It is gone..........
 *
 * const char *msg == consider adding for verbose errors.
 */
int ide_config_drive_speed (ide_drive_t *drive, byte speed)
{
    ide_hwif_t *hwif = HWIF(drive);
    int	i, error = 1;
    byte stat;

#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
    byte unit = (drive->select.b.unit & 0x01);
    outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */

    /*
     * Don't use ide_wait_cmd here - it will
     * attempt to set_geometry and recalibrate,
     * but for some reason these don't work at
     * this point (lost interrupt).
     */
    /*
     * Select the drive, and issue the SETFEATURES command
     */
    disable_irq(hwif->irq);	/* disable_irq_nosync ?? */
    udelay(1);
    SELECT_DRIVE(HWIF(drive), drive);
    SELECT_MASK(HWIF(drive), drive, 0);
    udelay(1);
    if (IDE_CONTROL_REG)
        OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
    OUT_BYTE(speed, IDE_NSECTOR_REG);
    OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
    OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
    if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
        OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
    udelay(1);
    /*
     * Wait for drive to become non-BUSY
     */
    if ((stat = GET_STAT()) & BUSY_STAT)
    {
        unsigned long flags, timeout;
        __save_flags(flags);	/* local CPU only */
        ide__sti();		/* local CPU only -- for jiffies */
        timeout = jiffies + WAIT_CMD;
        while ((stat = GET_STAT()) & BUSY_STAT)
        {
            if (0 < (signed long)(jiffies - timeout))
                break;
        }
        __restore_flags(flags); /* local CPU only */
    }

    /*
     * Allow status to settle, then read it again.
     * A few rare drives vastly violate the 400ns spec here,
     * so we'll wait up to 10usec for a "good" status
     * rather than expensively fail things immediately.
     * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
     */
    for (i = 0; i < 10; i++)
    {
        udelay(1);
        if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT))
        {
            error = 0;
            break;
        }
    }

    SELECT_MASK(HWIF(drive), drive, 0);

    enable_irq(hwif->irq);

    if (error)
    {
        (void) ide_dump_status(drive, "set_drive_speed_status", stat);
        return error;
    }

    drive->id->dma_ultra &= ~0xFF00;
    drive->id->dma_mword &= ~0x0F00;
    drive->id->dma_1word &= ~0x0F00;

#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
    if (speed > XFER_PIO_4)
    {
        outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
    }
    else
    {
        outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
    }
#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */

    switch(speed)
    {
    case XFER_UDMA_7:
        drive->id->dma_ultra |= 0x8080;
        break;
    case XFER_UDMA_6:
        drive->id->dma_ultra |= 0x4040;
        break;
    case XFER_UDMA_5:
        drive->id->dma_ultra |= 0x2020;
        break;
    case XFER_UDMA_4:
        drive->id->dma_ultra |= 0x1010;
        break;
    case XFER_UDMA_3:
        drive->id->dma_ultra |= 0x0808;
        break;
    case XFER_UDMA_2:
        drive->id->dma_ultra |= 0x0404;
        break;
    case XFER_UDMA_1:
        drive->id->dma_ultra |= 0x0202;
        break;
    case XFER_UDMA_0:
        drive->id->dma_ultra |= 0x0101;
        break;
    case XFER_MW_DMA_2:
        drive->id->dma_mword |= 0x0404;
        break;
    case XFER_MW_DMA_1:
        drive->id->dma_mword |= 0x0202;
        break;
    case XFER_MW_DMA_0:
        drive->id->dma_mword |= 0x0101;
        break;
    case XFER_SW_DMA_2:
        drive->id->dma_1word |= 0x0404;
        break;
    case XFER_SW_DMA_1:
        drive->id->dma_1word |= 0x0202;
        break;
    case XFER_SW_DMA_0:
        drive->id->dma_1word |= 0x0101;
        break;
    default:
        break;
    }
    return error;
}