#include "floppy_reg.h"
#include <alarm.h>
#include <alarm_struct.h>
#include <condition.h>
#include <condition_struct.h>
#include <asm.h>
#define SPINUP_TIME 500
#define UPTIME 5000
#define STOPPED 0
#define STARTING 1
#define STARTED 2
static int state;
static struct condition_struct started_condition;
static struct alarm_struct alarm;
static int locked;
static void start_motor()
{
outb((inbp(FD_DOR) & 0x0c) | 0x10, FD_DOR);
state = STARTING;
alarm_set(&alarm, SPINUP_TIME);
}
static void stop_motor()
{
outb(inbp(FD_DOR) & 0x0c, FD_DOR);
state = STOPPED;
}
static void alarm_handler()
{
switch (state) {
case STARTING:
state = STARTED;
if (locked)
condition_signal(&started_condition);
else
alarm_set(&alarm, UPTIME);
return;
case STARTED:
stop_motor();
return;
}
}
void floppy_motor_lock()
{
locked = 1;
cli();
if (state == STARTED)
alarm_unset(&alarm);
sti();
}
void floppy_motor_unlock()
{
locked = 0;
if (state == STARTED)
alarm_set(&alarm, UPTIME);
}
void floppy_motor_init()
{
state = STOPPED;
condition_init(&started_condition);
alarm_init(&alarm, alarm_handler);
locked = 0;
}
void floppy_motor_enable()
{
if (state == STOPPED)
start_motor();
}
void floppy_motor_wait_until_started()
{
cli();
while (state != STARTED)
condition_wait(&started_condition);
sti();
}