|
|
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 |
|