Commit 6d0be946 authored by Andreas Bombe's avatar Andreas Bombe Committed by Geert Uytterhoeven
Browse files

m68k: amiflop - Get rid of sleep_on calls



Apart from sleep_on() calls that could be easily converted to
wait_event() and completion calls amiflop also used a flag in ms_delay()
and ms_isr() as a custom mutex for ms_delay() without a need for
explicit unlocking.  I converted that to a standard mutex.

The replacement for the unconditional sleep_on() in fd_motor_on() is a
complete_all() together with a INIT_COMPLETION() before the mod_timer()
call.  It appears to me that fd_motor_on() might be called concurrently
and fd_select() does not guarantee mutual exclusivity in the case the
same drive gets selected again.

Signed-off-by: default avatarAndreas Bombe <aeb@debian.org>
Acked-by: default avatarJörg Dorchain <joerg@dorchain.net>
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
parent dc8ee69c
Loading
Loading
Loading
Loading
+16 −24
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ static volatile int fdc_busy = -1;
static volatile int fdc_nested;
static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
 
static DECLARE_WAIT_QUEUE_HEAD(motor_wait);
static DECLARE_COMPLETION(motor_on_completion);

static volatile int selected = -1;	/* currently selected drive */

@@ -184,8 +184,7 @@ static unsigned char mfmencode[16]={
static unsigned char mfmdecode[128];

/* floppy internal millisecond timer stuff */
static volatile int ms_busy = -1;
static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
static DECLARE_COMPLETION(ms_wait_completion);
#define MS_TICKS ((amiga_eclock+50)/1000)

/*
@@ -211,8 +210,7 @@ static int fd_device[4] = { 0, 0, 0, 0 };

static irqreturn_t ms_isr(int irq, void *dummy)
{
	ms_busy = -1;
	wake_up(&ms_wait);
	complete(&ms_wait_completion);
	return IRQ_HANDLED;
}

@@ -220,19 +218,17 @@ static irqreturn_t ms_isr(int irq, void *dummy)
   A more generic routine would do a schedule a la timer.device */
static void ms_delay(int ms)
{
	unsigned long flags;
	int ticks;
	static DEFINE_MUTEX(mutex);

	if (ms > 0) {
		local_irq_save(flags);
		while (ms_busy == 0)
			sleep_on(&ms_wait);
		ms_busy = 0;
		local_irq_restore(flags);
		mutex_lock(&mutex);
		ticks = MS_TICKS*ms-1;
		ciaa.tblo=ticks%256;
		ciaa.tbhi=ticks/256;
		ciaa.crb=0x19; /*count eclock, force load, one-shoot, start */
		sleep_on(&ms_wait);
		wait_for_completion(&ms_wait_completion);
		mutex_unlock(&mutex);
	}
}

@@ -254,8 +250,7 @@ static void get_fdc(int drive)
	printk("get_fdc: drive %d  fdc_busy %d  fdc_nested %d\n",drive,fdc_busy,fdc_nested);
#endif
	local_irq_save(flags);
	while (!try_fdc(drive))
		sleep_on(&fdc_wait);
	wait_event(fdc_wait, try_fdc(drive));
	fdc_busy = drive;
	fdc_nested++;
	local_irq_restore(flags);
@@ -330,7 +325,7 @@ static void fd_deselect (int drive)
static void motor_on_callback(unsigned long nr)
{
	if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
		wake_up (&motor_wait);
		complete_all(&motor_on_completion);
	} else {
		motor_on_timer.expires = jiffies + HZ/10;
		add_timer(&motor_on_timer);
@@ -347,11 +342,12 @@ static int fd_motor_on(int nr)
		unit[nr].motor = 1;
		fd_select(nr);

		INIT_COMPLETION(motor_on_completion);
		motor_on_timer.data = nr;
		mod_timer(&motor_on_timer, jiffies + HZ/2);

		on_attempts = 10;
		sleep_on (&motor_wait);
		wait_for_completion(&motor_on_completion);
		fd_deselect(nr);
	}

@@ -582,8 +578,7 @@ static void raw_read(int drive)
{
	drive&=3;
	get_fdc(drive);
	while (block_flag)
		sleep_on(&wait_fd_block);
	wait_event(wait_fd_block, !block_flag);
	fd_select(drive);
	/* setup adkcon bits correctly */
	custom.adkcon = ADK_MSBSYNC;
@@ -598,8 +593,7 @@ static void raw_read(int drive)

	block_flag = 1;

	while (block_flag)
		sleep_on (&wait_fd_block);
	wait_event(wait_fd_block, !block_flag);

	custom.dsklen = 0;
	fd_deselect(drive);
@@ -616,8 +610,7 @@ static int raw_write(int drive)
		rel_fdc();
		return 0;
	}
	while (block_flag)
		sleep_on(&wait_fd_block);
	wait_event(wait_fd_block, !block_flag);
	fd_select(drive);
	/* clear adkcon bits */
	custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
@@ -1294,8 +1287,7 @@ static int non_int_flush_track (unsigned long nr)
			writepending = 0;
			return 0;
		}
		while (block_flag == 2)
			sleep_on (&wait_fd_block);
		wait_event(wait_fd_block, block_flag != 2);
	}
	else {
		local_irq_restore(flags);