View of xos/drivers/floppy_motor.c


XOS | Parent Directory | View | Download

/* Copyright (C) 2008  Emmanuel Varoquaux
 
   This file is part of XOS.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
#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     /* 500 ms */
#define UPTIME          5000    /* 5 s */
 
/* etats du moteur */
#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); /* enable motor */
  state = STARTING;
  alarm_set(&alarm, SPINUP_TIME);
}
 
static void stop_motor()
{
  outb(inbp(FD_DOR) & 0x0c, FD_DOR); /* disable motor */
  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();
}