|
|
867c1e |
From 51d219681f4e073bbaf0a6e540f42447f1a18edf Mon Sep 17 00:00:00 2001
|
|
|
867c1e |
From: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
Date: Thu, 22 Aug 2013 02:15:59 +0200
|
|
|
867c1e |
Subject: [PATCH 3/5] floppy: Implement media format sensing.
|
|
|
867c1e |
|
|
|
867c1e |
RH-Author: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
Message-id: <1377137759-16089-4-git-send-email-famz@redhat.com>
|
|
|
867c1e |
Patchwork-id: 53681
|
|
|
867c1e |
O-Subject: [RHEL-7 seabios PATCH 3/3] floppy: Implement media format sensing.
|
|
|
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 |
Check for lower capacity media in the floppy drive and set the
|
|
|
867c1e |
corresponding controller data rate for it.
|
|
|
867c1e |
|
|
|
867c1e |
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
|
|
|
867c1e |
(cherry picked from commit e7c5a7ef782673f00faf3371721562806e931cdb)
|
|
|
867c1e |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
|
|
|
867c1e |
Conflicts:
|
|
|
867c1e |
src/floppy.c
|
|
|
867c1e |
Context conflict. Upstream 89a2f96d converted VAR16VISIBLE
|
|
|
867c1e |
to VARFSEG, which we don't have yet. So keep the original
|
|
|
867c1e |
type.
|
|
|
867c1e |
|
|
|
867c1e |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
---
|
|
|
867c1e |
src/floppy.c | 123 +++++++++++++++++++++++++++++++++++++----------------------
|
|
|
867c1e |
1 file changed, 78 insertions(+), 45 deletions(-)
|
|
|
867c1e |
|
|
|
867c1e |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
867c1e |
---
|
|
|
867c1e |
src/floppy.c | 123 ++++++++++++++++++++++++++++++++++++---------------------
|
|
|
867c1e |
1 files changed, 78 insertions(+), 45 deletions(-)
|
|
|
867c1e |
|
|
|
867c1e |
diff --git a/src/floppy.c b/src/floppy.c
|
|
|
867c1e |
index 429ccb5..f00349d 100644
|
|
|
867c1e |
--- a/src/floppy.c
|
|
|
867c1e |
+++ b/src/floppy.c
|
|
|
867c1e |
@@ -51,29 +51,37 @@ struct floppy_dbt_s diskette_param_table VAR16FIXED(0xefc7);
|
|
|
867c1e |
|
|
|
867c1e |
struct floppyinfo_s {
|
|
|
867c1e |
struct chs_s chs;
|
|
|
867c1e |
- u8 config_data;
|
|
|
867c1e |
- u8 media_state;
|
|
|
867c1e |
+ u8 floppy_size;
|
|
|
867c1e |
+ u8 data_rate;
|
|
|
867c1e |
};
|
|
|
867c1e |
|
|
|
867c1e |
+#define FLOPPY_SIZE_525 0x01
|
|
|
867c1e |
+#define FLOPPY_SIZE_350 0x02
|
|
|
867c1e |
+
|
|
|
867c1e |
+#define FLOPPY_RATE_500K 0x00
|
|
|
867c1e |
+#define FLOPPY_RATE_300K 0x01
|
|
|
867c1e |
+#define FLOPPY_RATE_250K 0x02
|
|
|
867c1e |
+#define FLOPPY_RATE_1M 0x03
|
|
|
867c1e |
+
|
|
|
867c1e |
struct floppyinfo_s FloppyInfo[] VAR16VISIBLE = {
|
|
|
867c1e |
// Unknown
|
|
|
867c1e |
{ {0, 0, 0}, 0x00, 0x00},
|
|
|
867c1e |
// 1 - 360KB, 5.25" - 2 heads, 40 tracks, 9 sectors
|
|
|
867c1e |
- { {2, 40, 9}, 0x00, 0x25},
|
|
|
867c1e |
+ { {2, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K},
|
|
|
867c1e |
// 2 - 1.2MB, 5.25" - 2 heads, 80 tracks, 15 sectors
|
|
|
867c1e |
- { {2, 80, 15}, 0x00, 0x25},
|
|
|
867c1e |
+ { {2, 80, 15}, FLOPPY_SIZE_525, FLOPPY_RATE_500K},
|
|
|
867c1e |
// 3 - 720KB, 3.5" - 2 heads, 80 tracks, 9 sectors
|
|
|
867c1e |
- { {2, 80, 9}, 0x00, 0x17},
|
|
|
867c1e |
+ { {2, 80, 9}, FLOPPY_SIZE_350, FLOPPY_RATE_250K},
|
|
|
867c1e |
// 4 - 1.44MB, 3.5" - 2 heads, 80 tracks, 18 sectors
|
|
|
867c1e |
- { {2, 80, 18}, 0x00, 0x17},
|
|
|
867c1e |
+ { {2, 80, 18}, FLOPPY_SIZE_350, FLOPPY_RATE_500K},
|
|
|
867c1e |
// 5 - 2.88MB, 3.5" - 2 heads, 80 tracks, 36 sectors
|
|
|
867c1e |
- { {2, 80, 36}, 0xCC, 0xD7},
|
|
|
867c1e |
+ { {2, 80, 36}, FLOPPY_SIZE_350, FLOPPY_RATE_1M},
|
|
|
867c1e |
// 6 - 160k, 5.25" - 1 heads, 40 tracks, 8 sectors
|
|
|
867c1e |
- { {1, 40, 8}, 0x00, 0x27},
|
|
|
867c1e |
+ { {1, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K},
|
|
|
867c1e |
// 7 - 180k, 5.25" - 1 heads, 40 tracks, 9 sectors
|
|
|
867c1e |
- { {1, 40, 9}, 0x00, 0x27},
|
|
|
867c1e |
+ { {1, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K},
|
|
|
867c1e |
// 8 - 320k, 5.25" - 2 heads, 40 tracks, 8 sectors
|
|
|
867c1e |
- { {2, 40, 8}, 0x00, 0x27},
|
|
|
867c1e |
+ { {2, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K},
|
|
|
867c1e |
};
|
|
|
867c1e |
|
|
|
867c1e |
struct drive_s *
|
|
|
867c1e |
@@ -341,44 +349,69 @@ floppy_drive_recal(u8 floppyid)
|
|
|
867c1e |
}
|
|
|
867c1e |
|
|
|
867c1e |
static int
|
|
|
867c1e |
+floppy_drive_readid(u8 floppyid, u8 data_rate, u8 head)
|
|
|
867c1e |
+{
|
|
|
867c1e |
+ int ret = floppy_select_drive(floppyid);
|
|
|
867c1e |
+ if (ret)
|
|
|
867c1e |
+ return ret;
|
|
|
867c1e |
+
|
|
|
867c1e |
+ // Set data rate.
|
|
|
867c1e |
+ outb(data_rate, PORT_FD_DIR);
|
|
|
867c1e |
+
|
|
|
867c1e |
+ // send Read Sector Id command
|
|
|
867c1e |
+ struct floppy_pio_s pio;
|
|
|
867c1e |
+ pio.cmdlen = 2;
|
|
|
867c1e |
+ pio.resplen = 7;
|
|
|
867c1e |
+ pio.waitirq = 1;
|
|
|
867c1e |
+ pio.data[0] = 0x4a; // 0a: Read Sector Id
|
|
|
867c1e |
+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
+ ret = floppy_pio(&pio;;
|
|
|
867c1e |
+ if (ret)
|
|
|
867c1e |
+ return ret;
|
|
|
867c1e |
+ if (pio.data[0] & 0xc0)
|
|
|
867c1e |
+ return -1;
|
|
|
867c1e |
+ return 0;
|
|
|
867c1e |
+}
|
|
|
867c1e |
+
|
|
|
867c1e |
+static int
|
|
|
867c1e |
floppy_media_sense(struct drive_s *drive_g)
|
|
|
867c1e |
{
|
|
|
867c1e |
- // for now cheat and get drive type from CMOS,
|
|
|
867c1e |
- // assume media is same as drive type
|
|
|
867c1e |
-
|
|
|
867c1e |
- // ** config_data **
|
|
|
867c1e |
- // Bitfields for diskette media control:
|
|
|
867c1e |
- // Bit(s) Description (Table M0028)
|
|
|
867c1e |
- // 7-6 last data rate set by controller
|
|
|
867c1e |
- // 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps
|
|
|
867c1e |
- // 5-4 last diskette drive step rate selected
|
|
|
867c1e |
- // 00=0Ch, 01=0Dh, 10=0Eh, 11=0Ah
|
|
|
867c1e |
- // 3-2 {data rate at start of operation}
|
|
|
867c1e |
- // 1-0 reserved
|
|
|
867c1e |
-
|
|
|
867c1e |
- // ** media_state **
|
|
|
867c1e |
- // Bitfields for diskette drive media state:
|
|
|
867c1e |
- // Bit(s) Description (Table M0030)
|
|
|
867c1e |
- // 7-6 data rate
|
|
|
867c1e |
- // 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps
|
|
|
867c1e |
- // 5 double stepping required (e.g. 360kB in 1.2MB)
|
|
|
867c1e |
- // 4 media type established
|
|
|
867c1e |
- // 3 drive capable of supporting 4MB media
|
|
|
867c1e |
- // 2-0 on exit from BIOS, contains
|
|
|
867c1e |
- // 000 trying 360kB in 360kB
|
|
|
867c1e |
- // 001 trying 360kB in 1.2MB
|
|
|
867c1e |
- // 010 trying 1.2MB in 1.2MB
|
|
|
867c1e |
- // 011 360kB in 360kB established
|
|
|
867c1e |
- // 100 360kB in 1.2MB established
|
|
|
867c1e |
- // 101 1.2MB in 1.2MB established
|
|
|
867c1e |
- // 110 reserved
|
|
|
867c1e |
- // 111 all other formats/drives
|
|
|
867c1e |
-
|
|
|
867c1e |
- u8 ftype = GET_GLOBAL(drive_g->floppy_type);
|
|
|
867c1e |
- SET_BDA(floppy_last_data_rate, GET_GLOBAL(FloppyInfo[ftype].config_data));
|
|
|
867c1e |
+ u8 ftype = GET_GLOBAL(drive_g->floppy_type), stype = ftype;
|
|
|
867c1e |
u8 floppyid = GET_GLOBAL(drive_g->cntl_id);
|
|
|
867c1e |
- SET_BDA(floppy_media_state[floppyid]
|
|
|
867c1e |
- , GET_GLOBAL(FloppyInfo[ftype].media_state));
|
|
|
867c1e |
+
|
|
|
867c1e |
+ u8 data_rate = GET_GLOBAL(FloppyInfo[stype].data_rate);
|
|
|
867c1e |
+ int ret = floppy_drive_readid(floppyid, data_rate, 0);
|
|
|
867c1e |
+ if (ret) {
|
|
|
867c1e |
+ // Attempt media sense.
|
|
|
867c1e |
+ for (stype=1; ; stype++) {
|
|
|
867c1e |
+ if (stype >= ARRAY_SIZE(FloppyInfo))
|
|
|
867c1e |
+ return DISK_RET_EMEDIA;
|
|
|
867c1e |
+ if (stype==ftype
|
|
|
867c1e |
+ || (GET_GLOBAL(FloppyInfo[stype].floppy_size)
|
|
|
867c1e |
+ != GET_GLOBAL(FloppyInfo[ftype].floppy_size))
|
|
|
867c1e |
+ || (GET_GLOBAL(FloppyInfo[stype].chs.heads)
|
|
|
867c1e |
+ > GET_GLOBAL(FloppyInfo[ftype].chs.heads))
|
|
|
867c1e |
+ || (GET_GLOBAL(FloppyInfo[stype].chs.cylinders)
|
|
|
867c1e |
+ > GET_GLOBAL(FloppyInfo[ftype].chs.cylinders))
|
|
|
867c1e |
+ || (GET_GLOBAL(FloppyInfo[stype].chs.spt)
|
|
|
867c1e |
+ > GET_GLOBAL(FloppyInfo[ftype].chs.spt)))
|
|
|
867c1e |
+ continue;
|
|
|
867c1e |
+ data_rate = GET_GLOBAL(FloppyInfo[stype].data_rate);
|
|
|
867c1e |
+ ret = floppy_drive_readid(floppyid, data_rate, 0);
|
|
|
867c1e |
+ if (!ret)
|
|
|
867c1e |
+ break;
|
|
|
867c1e |
+ }
|
|
|
867c1e |
+ }
|
|
|
867c1e |
+
|
|
|
867c1e |
+ u8 old_data_rate = GET_BDA(floppy_media_state[floppyid]) >> 6;
|
|
|
867c1e |
+ SET_BDA(floppy_last_data_rate, (old_data_rate<<2) | (data_rate<<6));
|
|
|
867c1e |
+ u8 media = (stype == 1 ? 0x04 : (stype == 2 ? 0x05 : 0x07));
|
|
|
867c1e |
+ u8 fms = (data_rate<<6) | FMS_MEDIA_DRIVE_ESTABLISHED | media;
|
|
|
867c1e |
+ if (GET_GLOBAL(FloppyInfo[stype].chs.cylinders)
|
|
|
867c1e |
+ < GET_GLOBAL(FloppyInfo[ftype].chs.cylinders))
|
|
|
867c1e |
+ fms |= FMS_DOUBLE_STEPPING;
|
|
|
867c1e |
+ SET_BDA(floppy_media_state[floppyid], fms);
|
|
|
867c1e |
+
|
|
|
867c1e |
return DISK_RET_SUCCESS;
|
|
|
867c1e |
}
|
|
|
867c1e |
|
|
|
867c1e |
--
|
|
|
867c1e |
1.7.1
|
|
|
867c1e |
|