Blame SOURCES/seabios-floppy-Cleanup-floppy-irq-wait-handling.patch

867c1e
From 46ceee9e43c842627ac0f684e1d9d6244edb2a10 Mon Sep 17 00:00:00 2001
867c1e
From: Fam Zheng <famz@redhat.com>
867c1e
Date: Thu, 22 Aug 2013 02:15:58 +0200
867c1e
Subject: [PATCH 2/5] floppy: Cleanup floppy irq wait handling.
867c1e
867c1e
RH-Author: Fam Zheng <famz@redhat.com>
867c1e
Message-id: <1377137759-16089-3-git-send-email-famz@redhat.com>
867c1e
Patchwork-id: 53680
867c1e
O-Subject: [RHEL-7 seabios PATCH 2/3] floppy: Cleanup floppy irq wait handling.
867c1e
Bugzilla: 920140
867c1e
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
867c1e
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
867c1e
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
867c1e
867c1e
From: Kevin O'Connor <kevin@koconnor.net>
867c1e
867c1e
Rename FRS_TIMEOUT to FRS_IRQ - the flag indicates that an irq has
867c1e
been received - it isn't directly related to timeouts.
867c1e
867c1e
On a timeout event, disable the floppy controller instead of doing a
867c1e
full reset.  Also, perform the disable directly in floppy_wait_irq().
867c1e
867c1e
Always wait for the floppy irq after enabling the controller and after
867c1e
a recalibrate command.
867c1e
867c1e
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
867c1e
(cherry picked from commit 6e529bdae4922f48c0d7eaa31613b7a9230e8f95)
867c1e
Signed-off-by: Fam Zheng <famz@redhat.com>
867c1e
---
867c1e
 src/biosvar.h |  2 +-
867c1e
 src/floppy.c  | 88 +++++++++++++++++++++++++++++------------------------------
867c1e
 2 files changed, 45 insertions(+), 45 deletions(-)
867c1e
867c1e
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
867c1e
---
867c1e
 src/biosvar.h |    2 +-
867c1e
 src/floppy.c  |   88 ++++++++++++++++++++++++++++----------------------------
867c1e
 2 files changed, 45 insertions(+), 45 deletions(-)
867c1e
867c1e
diff --git a/src/biosvar.h b/src/biosvar.h
867c1e
index f0a0fd2..252d4d1 100644
867c1e
--- a/src/biosvar.h
867c1e
+++ b/src/biosvar.h
867c1e
@@ -120,7 +120,7 @@ struct bios_data_area_s {
867c1e
 } PACKED;
867c1e
 
867c1e
 // BDA floppy_recalibration_status bitdefs
867c1e
-#define FRS_TIMEOUT (1<<7)
867c1e
+#define FRS_IRQ (1<<7)
867c1e
 
867c1e
 // BDA rtc_wait_flag bitdefs
867c1e
 #define RWS_WAIT_PENDING (1<<0)
867c1e
diff --git a/src/floppy.c b/src/floppy.c
867c1e
index 458bb7a..429ccb5 100644
867c1e
--- a/src/floppy.c
867c1e
+++ b/src/floppy.c
867c1e
@@ -164,63 +164,59 @@ find_floppy_type(u32 size)
867c1e
  ****************************************************************/
867c1e
 
867c1e
 static void
867c1e
-floppy_reset_controller(void)
867c1e
+floppy_disable_controller(void)
867c1e
 {
867c1e
-    // Reset controller
867c1e
-    u8 val8 = inb(PORT_FD_DOR);
867c1e
-    outb(val8 & ~0x04, PORT_FD_DOR);
867c1e
-    outb(val8 | 0x04, PORT_FD_DOR);
867c1e
-
867c1e
-    // Wait for controller to come out of reset
867c1e
-    while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80)
867c1e
-        ;
867c1e
+    outb(inb(PORT_FD_DOR) & ~0x04, PORT_FD_DOR);
867c1e
 }
867c1e
 
867c1e
 static int
867c1e
-wait_floppy_irq(void)
867c1e
+floppy_wait_irq(void)
867c1e
 {
867c1e
-    ASSERT16();
867c1e
-    u8 frs;
867c1e
+    u8 frs = GET_BDA(floppy_recalibration_status);
867c1e
+    SET_BDA(floppy_recalibration_status, frs & ~FRS_IRQ);
867c1e
     for (;;) {
867c1e
-        if (!GET_BDA(floppy_motor_counter))
867c1e
-            return -1;
867c1e
+        if (!GET_BDA(floppy_motor_counter)) {
867c1e
+            floppy_disable_controller();
867c1e
+            return DISK_RET_ETIMEOUT;
867c1e
+        }
867c1e
         frs = GET_BDA(floppy_recalibration_status);
867c1e
-        if (frs & FRS_TIMEOUT)
867c1e
+        if (frs & FRS_IRQ)
867c1e
             break;
867c1e
         // Could use yield_toirq() here, but that causes issues on
867c1e
         // bochs, so use yield() instead.
867c1e
         yield();
867c1e
     }
867c1e
 
867c1e
-    frs &= ~FRS_TIMEOUT;
867c1e
-    SET_BDA(floppy_recalibration_status, frs);
867c1e
-    return 0;
867c1e
+    SET_BDA(floppy_recalibration_status, frs & ~FRS_IRQ);
867c1e
+    return DISK_RET_SUCCESS;
867c1e
 }
867c1e
 
867c1e
-static void
867c1e
-floppy_prepare_controller(u8 floppyid)
867c1e
+static int
867c1e
+floppy_enable_controller(void)
867c1e
 {
867c1e
-    u8 frs = GET_BDA(floppy_recalibration_status);
867c1e
-    SET_BDA(floppy_recalibration_status, frs & ~FRS_TIMEOUT);
867c1e
-
867c1e
-    // turn on motor of selected drive, DMA & int enabled, normal operation
867c1e
-    u8 prev_reset = inb(PORT_FD_DOR) & 0x04;
867c1e
-    u8 dor = 0x10;
867c1e
-    if (floppyid)
867c1e
-        dor = 0x20;
867c1e
-    dor |= 0x0c;
867c1e
-    dor |= floppyid;
867c1e
-    outb(dor, PORT_FD_DOR);
867c1e
+    outb(inb(PORT_FD_DOR) | 0x04, PORT_FD_DOR);
867c1e
+    return floppy_wait_irq();
867c1e
+}
867c1e
 
867c1e
+static int
867c1e
+floppy_select_drive(u8 floppyid)
867c1e
+{
867c1e
     // reset the disk motor timeout value of INT 08
867c1e
     SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS);
867c1e
 
867c1e
-    // wait for drive readiness
867c1e
-    while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80)
867c1e
-        ;
867c1e
+    // Enable controller if it isn't running.
867c1e
+    u8 dor = inb(PORT_FD_DOR);
867c1e
+    if (!(dor & 0x04)) {
867c1e
+        int ret = floppy_enable_controller();
867c1e
+        if (ret)
867c1e
+            return ret;
867c1e
+    }
867c1e
 
867c1e
-    if (!prev_reset)
867c1e
-        wait_floppy_irq();
867c1e
+    // Turn on motor of selected drive, DMA & int enabled, normal operation
867c1e
+    dor = (floppyid ? 0x20 : 0x10) | 0x0c | floppyid;
867c1e
+    outb(dor, PORT_FD_DOR);
867c1e
+
867c1e
+    return DISK_RET_SUCCESS;
867c1e
 }
867c1e
 
867c1e
 struct floppy_pio_s {
867c1e
@@ -233,7 +229,13 @@ struct floppy_pio_s {
867c1e
 static int
867c1e
 floppy_pio(struct floppy_pio_s *pio)
867c1e
 {
867c1e
-    floppy_prepare_controller(pio->data[1] & 1);
867c1e
+    int ret = floppy_select_drive(pio->data[1] & 1);
867c1e
+    if (ret)
867c1e
+        return ret;
867c1e
+
867c1e
+    // wait for drive readiness
867c1e
+    while ((inb(PORT_FD_STATUS) & 0xc0) != 0x80)
867c1e
+        ;
867c1e
 
867c1e
     // send command to controller
867c1e
     int i;
867c1e
@@ -241,11 +243,9 @@ floppy_pio(struct floppy_pio_s *pio)
867c1e
         outb(pio->data[i], PORT_FD_DATA);
867c1e
 
867c1e
     if (pio->waitirq) {
867c1e
-        int ret = wait_floppy_irq();
867c1e
-        if (ret) {
867c1e
-            floppy_reset_controller();
867c1e
-            return DISK_RET_ETIMEOUT;
867c1e
-        }
867c1e
+        int ret = floppy_wait_irq();
867c1e
+        if (ret)
867c1e
+            return ret;
867c1e
     }
867c1e
 
867c1e
     if (!pio->resplen)
867c1e
@@ -330,7 +330,7 @@ floppy_drive_recal(u8 floppyid)
867c1e
     struct floppy_pio_s pio;
867c1e
     pio.cmdlen = 2;
867c1e
     pio.resplen = 0;
867c1e
-    pio.waitirq = 0;
867c1e
+    pio.waitirq = 1;
867c1e
     pio.data[0] = 0x07;  // 07: Recalibrate
867c1e
     pio.data[1] = floppyid; // 0=drive0, 1=drive1
867c1e
     floppy_pio(&pio;;
867c1e
@@ -617,7 +617,7 @@ handle_0e(void)
867c1e
     }
867c1e
     // diskette interrupt has occurred
867c1e
     u8 frs = GET_BDA(floppy_recalibration_status);
867c1e
-    SET_BDA(floppy_recalibration_status, frs | FRS_TIMEOUT);
867c1e
+    SET_BDA(floppy_recalibration_status, frs | FRS_IRQ);
867c1e
 
867c1e
     eoi_pic1();
867c1e
 }
867c1e
-- 
867c1e
1.7.1
867c1e