コード例 #1
0
ファイル: floppy.c プロジェクト: Metabolix/PutkaOS
int floppy_seek_track(uint_t drive, uint_t track)
{
	if (drive >= MAX_DRIVES) {
		return -1;
	}

	if (track == floppy_drives[drive].track) {
		return 0;
	}

	floppy_motor_on(drive);

	prepare_wait_irq(FLOPPY_IRQ);
	floppy_command(SEEK);
	floppy_command(drive);
	floppy_command(track);
	wait_irq(FLOPPY_IRQ);

	floppy_drive_seeked = drive;

	floppy_sense_interrupt();
	if (track != floppy_drives[drive].track) {
		kprintf("FDD: ERROR: fd%u couldn't seek\n", drive);
		floppy_prepare_motor_off(drive);
		return -2;
	}
	/*kprintf("FDD: fd%u: Seeked track succesfully\n", drive);*/
	floppy_prepare_motor_off(drive);
	return 0;
}
コード例 #2
0
ファイル: floppy.c プロジェクト: Metabolix/PutkaOS
void floppy_reset(void)
{
	int a;

	prepare_wait_irq(FLOPPY_IRQ);
	outportb((FLOPPY_FIRST + DIGITAL_OUTPUT_REGISTER), 0x00); /*disable controller*/
	kwait(0, 1000 * 50);
	outportb((FLOPPY_FIRST + DIGITAL_OUTPUT_REGISTER), 0x0c); /*enable controller*/

	kprintf("FDD: Reseted controller\n");
	wait_irq(FLOPPY_IRQ);
	kprintf("FDD: Waited for it\n");

	for(a = 0; a < 4; a++) {
		floppy_sense_interrupt();
	}

	outportb(FLOPPY_FIRST + CONFIGURATION_CONTROL_REGISTER, 0);

	floppy_configure();

	if (floppy_drives[0].type) {
		floppy_calibrate(0);
	}
	if (floppy_drives[1].type) {
		floppy_calibrate(1);
	}
	kprintf("FDD: Calibrated drives\n");
}
コード例 #3
0
ファイル: floppy.c プロジェクト: CyberjujuM/tacos
int init_floppy()
{
	int drive = floppy_get_current_drive();
	uint8_t drive_type = 0;
	uint8_t CCR;
	
	/* On vérifie qu'on a bien un controleur standard, sinon on affiche un warning */
	if(floppy_get_version() != 0x90)
		kerr("WARNING: Floppy driver may not work with 0x%x controler.", floppy_get_version());

	floppy_reset_irq();
	
	// On fait le reset du controler + activation DMA/IRQ
	outb(0x00, FLOPPY_BASE + FLOPPY_DOR);
	outb(0x0C, FLOPPY_BASE + FLOPPY_DOR);
	
	floppy_wait_irq();
	floppy_sense_interrupt(NULL,NULL);
	
	// On regle la vitesse de transfert en fonction du type de disquette
	drive_type = floppy_get_type(drive);
	switch(drive_type)
	{
		case 1: // 300 kbps (01)
		case 3:
			CCR = 0x01;
			break;
			
		case 2: // 500 kbps (00)	
		case 4:
		
			CCR = 0x00;
			break;
		case 5: // 1 Mbps (11)
			CCR= 0x03;
			break;
			
		default:
			CCR = 0x00; // choix arbitraire btw
			break;
	}
	outb(CCR, FLOPPY_BASE + FLOPPY_CCR);
	
	
/* Totalement hardcodé et moche à fortiori*/
	floppy_write_command(SPECIFY);
    floppy_write_command(0xdf); /* steprate = 3ms, unload time = 240ms */
    floppy_write_command(0x02); /* load time = 16ms, no-DMA = 0 */
/* *************************************** */
	
	// On calibre le lecteur
	if(floppy_calibrate()) return -1;
	return 0;
}
コード例 #4
0
ファイル: floppy.c プロジェクト: CyberjujuM/tacos
// Repositionne la tête de lecture sur le cylindre 0
int floppy_calibrate()
{
	int i, st0, cy1 = -1;
	int drive = floppy_get_current_drive();
	
	// Allumer le moteur
	floppy_motor(ON);
	
	// On essaye 5 fois (oui c'est totalement arbitraire)
	for(i=0; i<5; i++)
	{
		// Le recalibrage déclenche l'IRQ, on se prépare donc à attendre l'IRQ
		floppy_reset_irq();
		
		// Procedure de calibrage:
		// On envoi dans un premier temps la commande RECALIBRATE,
		// puis on envoi le numero du lecteur que l'on veut recalibrer
		floppy_write_command(RECALIBRATE);
		floppy_write_command(drive);
		
		// On attend la réponse
		floppy_wait_irq();
		
		// une fois l'IRQ arrivée, on peut récuperer les données de retour via SENSE_INTERRUPT
		floppy_sense_interrupt(&st0, &cy1);
		
		if(st0 & 0xC0)
		{
			static const char * status[] =
			{ 0, "error", "invalid", "drive" };
			klog("floppy_recalibrate: status = %s.", status[st0 >> 6]);
			klog("\tST0:0x%x.\nCY1:0x%x.", st0, cy1);
			continue;
		}
	
		if(!cy1) // si cy1=0, on a bien atteint le cylindre 0 et on peut arreter la calibration
		{
			floppy_motor(OFF);
			return 0;
		}
		
	}
	kerr("floppy_recalibrate: failure.");
	
	floppy_motor(OFF);
	
	return -1;
}