Commit 053e8280 authored by Jens Axboe's avatar Jens Axboe Committed by Linus Torvalds

[PATCH] floppy smp fix

This is a port of some smp fixes I did for 2.4 floppy.c

Andrew did the re-diffing.
parent aeeadf91
...@@ -249,6 +249,7 @@ static int irqdma_allocated; ...@@ -249,6 +249,7 @@ static int irqdma_allocated;
static struct request *current_req; static struct request *current_req;
static struct request_queue *floppy_queue; static struct request_queue *floppy_queue;
static void do_fd_request(request_queue_t * q);
#ifndef fd_get_dma_residue #ifndef fd_get_dma_residue
#define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA) #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
...@@ -631,7 +632,8 @@ static const char *timeout_message; ...@@ -631,7 +632,8 @@ static const char *timeout_message;
static void is_alive(const char *message) static void is_alive(const char *message)
{ {
/* this routine checks whether the floppy driver is "alive" */ /* this routine checks whether the floppy driver is "alive" */
if (fdc_busy && command_status < 2 && !timer_pending(&fd_timeout)){ if (test_bit(0, &fdc_busy) && command_status < 2
&& !timer_pending(&fd_timeout)) {
DPRINT("timeout handler died: %s\n",message); DPRINT("timeout handler died: %s\n",message);
} }
} }
...@@ -661,7 +663,7 @@ static int output_log_pos; ...@@ -661,7 +663,7 @@ static int output_log_pos;
#define current_reqD -1 #define current_reqD -1
#define MAXTIMEOUT -2 #define MAXTIMEOUT -2
static void reschedule_timeout(int drive, const char *message, int marg) static void __reschedule_timeout(int drive, const char *message, int marg)
{ {
if (drive == current_reqD) if (drive == current_reqD)
drive = current_drive; drive = current_drive;
...@@ -680,6 +682,15 @@ static void reschedule_timeout(int drive, const char *message, int marg) ...@@ -680,6 +682,15 @@ static void reschedule_timeout(int drive, const char *message, int marg)
timeout_message = message; timeout_message = message;
} }
static void reschedule_timeout(int drive, const char *message, int marg)
{
unsigned long flags;
spin_lock_irqsave(&floppy_lock, flags);
__reschedule_timeout(drive, message, marg);
spin_unlock_irqrestore(&floppy_lock, flags);
}
static int maximum(int a, int b) static int maximum(int a, int b)
{ {
if (a > b) if (a > b)
...@@ -908,7 +919,7 @@ static int _lock_fdc(int drive, int interruptible, int line) ...@@ -908,7 +919,7 @@ static int _lock_fdc(int drive, int interruptible, int line)
} }
command_status = FD_COMMAND_NONE; command_status = FD_COMMAND_NONE;
reschedule_timeout(drive, "lock fdc", 0); __reschedule_timeout(drive, "lock fdc", 0);
set_fdc(drive); set_fdc(drive);
return 0; return 0;
} }
...@@ -922,17 +933,23 @@ if (lock_fdc(drive,interruptible)) return -EINTR; ...@@ -922,17 +933,23 @@ if (lock_fdc(drive,interruptible)) return -EINTR;
/* unlocks the driver */ /* unlocks the driver */
static inline void unlock_fdc(void) static inline void unlock_fdc(void)
{ {
unsigned long flags;
raw_cmd = 0; raw_cmd = 0;
if (!fdc_busy) if (!test_bit(0, &fdc_busy))
DPRINT("FDC access conflict!\n"); DPRINT("FDC access conflict!\n");
if (do_floppy) if (do_floppy)
DPRINT("device interrupt still active at FDC release: %p!\n", DPRINT("device interrupt still active at FDC release: %p!\n",
do_floppy); do_floppy);
command_status = FD_COMMAND_NONE; command_status = FD_COMMAND_NONE;
spin_lock_irqsave(&floppy_lock, flags);
del_timer(&fd_timeout); del_timer(&fd_timeout);
cont = NULL; cont = NULL;
clear_bit(0, &fdc_busy); clear_bit(0, &fdc_busy);
if (elv_next_request(floppy_queue))
do_fd_request(floppy_queue);
spin_unlock_irqrestore(&floppy_lock, flags);
floppy_release_irq_and_dma(); floppy_release_irq_and_dma();
wake_up(&fdc_wait); wake_up(&fdc_wait);
} }
...@@ -1010,9 +1027,13 @@ static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0); ...@@ -1010,9 +1027,13 @@ static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0);
static void cancel_activity(void) static void cancel_activity(void)
{ {
unsigned long flags;
spin_lock_irqsave(&floppy_lock, flags);
do_floppy = NULL; do_floppy = NULL;
PREPARE_WORK(&floppy_work, (void*)(void*)empty, NULL); PREPARE_WORK(&floppy_work, (void*)(void*)empty, NULL);
del_timer(&fd_timer); del_timer(&fd_timer);
spin_unlock_irqrestore(&floppy_lock, flags);
} }
/* this function makes sure that the disk stays in the drive during the /* this function makes sure that the disk stays in the drive during the
...@@ -2995,7 +3016,7 @@ static void do_fd_request(request_queue_t * q) ...@@ -2995,7 +3016,7 @@ static void do_fd_request(request_queue_t * q)
printk("sect=%ld flags=%lx\n", (long)current_req->sector, current_req->flags); printk("sect=%ld flags=%lx\n", (long)current_req->sector, current_req->flags);
return; return;
} }
if (fdc_busy){ if (test_bit(0, &fdc_busy)) {
/* fdc busy, this new request will be treated when the /* fdc busy, this new request will be treated when the
current one is done */ current one is done */
is_alive("do fd request, old request running"); is_alive("do fd request, old request running");
...@@ -4245,6 +4266,7 @@ int __init floppy_init(void) ...@@ -4245,6 +4266,7 @@ int __init floppy_init(void)
} }
floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); floppy_queue = blk_init_queue(do_fd_request, &floppy_lock);
blk_queue_max_sectors(floppy_queue, 64);
if (!floppy_queue) { if (!floppy_queue) {
err = -ENOMEM; err = -ENOMEM;
goto fail_queue; goto fail_queue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment