From: Jens Axboe <axboe@suse.de>

Here is the port of the floppy smp fixes from 2.4



 drivers/block/floppy.c |   32 +++++++++++++++++++++++++++-----
 1 files changed, 27 insertions(+), 5 deletions(-)

diff -puN drivers/block/floppy.c~floppy-smp-fixes drivers/block/floppy.c
--- 25/drivers/block/floppy.c~floppy-smp-fixes	2003-07-25 23:42:33.000000000 -0700
+++ 25-akpm/drivers/block/floppy.c	2003-07-25 23:42:33.000000000 -0700
@@ -249,6 +249,7 @@ static int irqdma_allocated;
 
 static struct request *current_req;
 static struct request_queue floppy_queue;
+static void do_fd_request(request_queue_t * q);
 
 #ifndef fd_get_dma_residue
 #define fd_get_dma_residue() get_dma_residue(FLOPPY_DMA)
@@ -631,7 +632,8 @@ static const char *timeout_message;
 static void is_alive(const char *message)
 {
 	/* 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);
 	}
 }
@@ -661,7 +663,7 @@ static int output_log_pos;
 #define current_reqD -1
 #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)
 		drive = current_drive;
@@ -680,6 +682,15 @@ static void reschedule_timeout(int drive
 	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)
 {
 	if (a > b)
@@ -908,7 +919,7 @@ static int _lock_fdc(int drive, int inte
 	}
 	command_status = FD_COMMAND_NONE;
 
-	reschedule_timeout(drive, "lock fdc", 0);
+	__reschedule_timeout(drive, "lock fdc", 0);
 	set_fdc(drive);
 	return 0;
 }
@@ -922,17 +933,23 @@ if (lock_fdc(drive,interruptible)) retur
 /* unlocks the driver */
 static inline void unlock_fdc(void)
 {
+	unsigned long flags;
+
 	raw_cmd = 0;
-	if (!fdc_busy)
+	if (!test_bit(0, &fdc_busy))
 		DPRINT("FDC access conflict!\n");
 
 	if (do_floppy)
 		DPRINT("device interrupt still active at FDC release: %p!\n",
 			do_floppy);
 	command_status = FD_COMMAND_NONE;
+	spin_lock_irqsave(&floppy_lock, flags);
 	del_timer(&fd_timeout);
 	cont = NULL;
 	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();
 	wake_up(&fdc_wait);
 }
@@ -1010,9 +1027,13 @@ static struct timer_list fd_timer = TIME
 
 static void cancel_activity(void)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&floppy_lock, flags);
 	do_floppy = NULL;
 	PREPARE_WORK(&floppy_work, (void*)(void*)empty, NULL);
 	del_timer(&fd_timer);
+	spin_unlock_irqrestore(&floppy_lock, flags);
 }
 
 /* this function makes sure that the disk stays in the drive during the
@@ -2995,7 +3016,7 @@ static void do_fd_request(request_queue_
 		printk("sect=%ld flags=%lx\n", (long)current_req->sector, current_req->flags);
 		return;
 	}
-	if (fdc_busy){
+	if (test_bit(0, &fdc_busy)) {
 		/* fdc busy, this new request will be treated when the
 		   current one is done */
 		is_alive("do fd request, old request running");
@@ -4261,6 +4282,7 @@ int __init floppy_init(void)
 			floppy_sizes[i] = MAX_DISK_SIZE << 1;
 
 	blk_init_queue(&floppy_queue, do_fd_request, &floppy_lock);
+	blk_queue_max_sectors(&floppy_queue, 64);
 	reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
 	config_types();
 

_