示例#1
0
文件: fd.c 项目: huangrui/Thunix
/* seek to track */
static int seek(int track, int head)
{
        //LOG("seek() called ...\n");
        
	/*
	if (track == 0) {
		LOG("RECALIBRATE...\n");
                recalibrate();
		return TRUE;
	}
	*/

        if (fdc_track == track) 
                return TRUE;   /* already there*/

        /* send actual command bytes */
        send_byte(FD_SEEK);
        send_byte(head << 2);
        send_byte(track);
        
        /* wait until seek finished */
        if ( !wait_fdc(TRUE) )
                ;//return FALSE;  /* time out */
        
	//LOG("ST0: %x\t ST1: %x\n", sr0, fdc_track);
        if ( ((sr0 & 0xF8) != 0x20) || (fdc_track != track)) {
		LOG("Seek track#: %d failed\n", track);
                return FALSE;
        } else {
                LOG("Seek track#: %d OK ...\n", track);
                return TRUE;
        }
}
示例#2
0
文件: fd.c 项目: huangrui/Thunix
/* recalibrate the drive */
static void recalibrate(void)
{

        //LOG("recalibrate() called ...\n");

        /*turn the motor on first */
        motor_on();
        
        /* send actual command bytes */
        send_byte(FD_RECALIBRATE);
        send_byte(0);

        /* wait until seek finished */
        wait_fdc(TRUE);
}
示例#3
0
static void recalibrate(struct fdd *d)
{
	int i;
	
	for (i = 0; i < 13; i++) {
		fdc_out(d->fdc->base_port, FDC_RECALIBRATE);
		fdc_out(d->fdc->base_port, d->number);
		wait_fdc(d);
		/* Send a `sense interrupt status' command */
		fdc_out(d->fdc->base_port, FDC_SENSE);
		d->fdc->sr0 = fdc_in(d->fdc->base_port);
		d->track = fdc_in(d->fdc->base_port);

		if (!(d->fdc->sr0 & 0x10)) break;	// Exit if unit check is not set
	}

	DEBUG(DL_DBG, ("drive(%d), sr0(0x%x), track(%d)\n",
		       d->number, d->fdc->sr0, d->track));
}
示例#4
0
int flpy_seek(struct fdd *d, uint32_t track)
{
	if (d->track == track) return 0;
	fdc_out(d->fdc->base_port, FDC_SEEK);
	fdc_out(d->fdc->base_port, d->number);
	fdc_out(d->fdc->base_port, track);

	if (wait_fdc(d)) return -1;	// Timeout

	/* Send a `sense interrupt status' command */
	fdc_out(d->fdc->base_port, FDC_SENSE);
	d->fdc->sr0 = fdc_in(d->fdc->base_port);
	d->track = fdc_in(d->fdc->base_port);

	/* Check that seek worked */
	if ((d->fdc->sr0 != 0x20 + d->number) || (d->track != track)) {
		DEBUG(DL_ERR, ("error on drive(%d)\n"
			       "* sr0(0x%x), track(%d), expected(%d)\n",
			       d->number, d->fdc->sr0, d->track, track));
		return -1;	// TODO: return an error code
	}

	return 0;
}
示例#5
0
文件: fd.c 项目: huangrui/Thunix
/*
 *    reset the floppy.
 *
 *    The first thing that the driver needs to do is reset the controller.This 
 * will put it in a known state. To reset the primary floppy controller,(in C)
 *
 * 1.write 0x00 to the DIGITAL_OUTPUT_REG of the desired controller
 * 2.write 0x0C to the DIGITAL_OUTPUT_REG of the desired controller
 * 3.wait for an interrupt from the controller
 * 4.check interrupt status (this is function 0x08 of controllers)
 * 5.write 0x00 to the CONFIG_CONTROL_REG
 * 6.configure the drive desired on the controller (function 0x03 of controller)
 * 7.calibrate the drive (function 0x07 of controller)
 *
 */
static void reset( )
{
        //LOG("reset() called ...\n");

        /* stop the motor and disable IRQ/DMA */
        outb_p(0x0c,FD_DOR);

        /* program data rate (500K/s) */
        outb_p(0,FD_DCR);
        
        /* re-enable interrupts */
        outb_p(0x1c,FD_DOR);

        /* resetting triggered an interrupt - handle it */
        done = TRUE;
        wait_fdc(TRUE);

        /* specify drive timings (got these off the BIOS) */
        send_byte(FD_SPECIFY);
        send_byte(0xdf);      /* SRT = 3ms, HUT = 240ms */
        send_byte(0x06);      /* HLT = 16ms, ND = 0     */

        recalibrate();
}
示例#6
0
文件: fd.c 项目: huangrui/Thunix
/*
 * And now, it's time to implenent the read or write function, that's
 * all the floppy driver mean!
 * 
 * Read/Write one sector once.
 */
static int floppy_rw(int sector, char *buf, int command)
{
	int head;
	char *dma_buffer = buf;
	static char tmp_dma_buffer[512];

	//LOG("TMP dma buffer: %p\n", tmp_dma_buffer);

        lba_to_chs(sector, &head, &track, &sector);
	LOG("head: %d \ttrack: %d \tsector: %d\n", head, track, sector);

        /* turn it on if not */
        motor_on();

        if (inb_p(FD_DIR) & 0x80) {
                changed = TRUE;
                seek(1, head);        /* clear "disk change" status */
                recalibrate();
                motor_off();
                printk("floppy_rw: Disk change detected. You are going to DIE:)\n");
                
                pause();  /* just put it in DIE */
        }

        /* move head to the right track */
        if (!seek(track, head)) {
                motor_off();
                printk("floppy_rw: Error seeking to track#%d\n", track);
                return FALSE;
        }
                
	if ((unsigned long)buf >= 0xff000) {
		dma_buffer = tmp_dma_buffer;
		if (command == FD_WRITE)
			memcpy(dma_buffer, buf, 512);
	}

        setup_DMA((unsigned long)dma_buffer, command);

        send_byte(command);
        send_byte(head<<2 | 0);
        send_byte(track);
        send_byte(head);
	send_byte(sector);
        send_byte(2);           /* sector size = 125 * 2^(2) */
        send_byte(floppy.sector);
        send_byte(0);
        send_byte(0xFF);        /* sector size(only two valid vaules, 0xff when n!=0*/

        if (!wait_fdc(FALSE)) {
                //LOG("wait fdc failed!\n");
                //return 0;
                /*
                printk("Time out, trying operation again after reset() \n");
                reset();
                return floppy_rw(sector, buf, command);
                */
        }

        motor_off();

        if (/*res != 7 || */(ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73) ) {
                if (ST1 & 0x02) 
                        LOG("Drive is write protected!\n");
                else
                        LOG("floppy_rw: bad interrupt!\n");

                return -EIO;
        } else {
		LOG("floppy_rw: OK\n");
		if ((unsigned long)buf >= 0xff000 && command == FD_READ)
			memcpy(buf, dma_buffer, 512);
		return 0;
        }
}