|
|
867c1e |
From 946dd96997625598fd814500e5fbfd457c6d670d Mon Sep 17 00:00:00 2001
|
|
|
867c1e |
From: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
Date: Thu, 22 Aug 2013 02:15:57 +0200
|
|
|
867c1e |
Subject: [PATCH 1/5] floppy: Introduce 'struct floppy_pio_s' for floppy PIO ops.
|
|
|
867c1e |
|
|
|
867c1e |
RH-Author: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
Message-id: <1377137759-16089-2-git-send-email-famz@redhat.com>
|
|
|
867c1e |
Patchwork-id: 53679
|
|
|
867c1e |
O-Subject: [RHEL-7 seabios PATCH 1/3] floppy: Introduce 'struct floppy_pio_s' for floppy PIO ops.
|
|
|
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 |
Populate a struct for the PIO operations and move the PIO manipulation
|
|
|
867c1e |
done in floppy_cmd() to floppy_pio().
|
|
|
867c1e |
|
|
|
867c1e |
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
|
|
|
867c1e |
(cherry picked from commit 9ba374ce1d864b7a50f3657e6b06e7b2d1ec2934)
|
|
|
867c1e |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
867c1e |
---
|
|
|
867c1e |
src/floppy.c | 158 ++++++++++++++++++++++++++++++++++-------------------------
|
|
|
867c1e |
1 file changed, 90 insertions(+), 68 deletions(-)
|
|
|
867c1e |
|
|
|
867c1e |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
867c1e |
---
|
|
|
867c1e |
src/floppy.c | 158 +++++++++++++++++++++++++++++++++-------------------------
|
|
|
867c1e |
1 files changed, 90 insertions(+), 68 deletions(-)
|
|
|
867c1e |
|
|
|
867c1e |
diff --git a/src/floppy.c b/src/floppy.c
|
|
|
867c1e |
index e9f8916..458bb7a 100644
|
|
|
867c1e |
--- a/src/floppy.c
|
|
|
867c1e |
+++ b/src/floppy.c
|
|
|
867c1e |
@@ -223,27 +223,48 @@ floppy_prepare_controller(u8 floppyid)
|
|
|
867c1e |
wait_floppy_irq();
|
|
|
867c1e |
}
|
|
|
867c1e |
|
|
|
867c1e |
+struct floppy_pio_s {
|
|
|
867c1e |
+ u8 cmdlen;
|
|
|
867c1e |
+ u8 resplen;
|
|
|
867c1e |
+ u8 waitirq;
|
|
|
867c1e |
+ u8 data[9];
|
|
|
867c1e |
+};
|
|
|
867c1e |
+
|
|
|
867c1e |
static int
|
|
|
867c1e |
-floppy_pio(u8 *cmd, u8 cmdlen)
|
|
|
867c1e |
+floppy_pio(struct floppy_pio_s *pio)
|
|
|
867c1e |
{
|
|
|
867c1e |
- floppy_prepare_controller(cmd[1] & 1);
|
|
|
867c1e |
+ floppy_prepare_controller(pio->data[1] & 1);
|
|
|
867c1e |
|
|
|
867c1e |
// send command to controller
|
|
|
867c1e |
- u8 i;
|
|
|
867c1e |
- for (i=0; i
|
|
|
867c1e |
- outb(cmd[i], PORT_FD_DATA);
|
|
|
867c1e |
-
|
|
|
867c1e |
- int ret = wait_floppy_irq();
|
|
|
867c1e |
- if (ret) {
|
|
|
867c1e |
- floppy_reset_controller();
|
|
|
867c1e |
- return -1;
|
|
|
867c1e |
+ int i;
|
|
|
867c1e |
+ for (i=0; i<pio->cmdlen; i++)
|
|
|
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 |
}
|
|
|
867c1e |
|
|
|
867c1e |
- return 0;
|
|
|
867c1e |
+ if (!pio->resplen)
|
|
|
867c1e |
+ return DISK_RET_SUCCESS;
|
|
|
867c1e |
+
|
|
|
867c1e |
+ // check port 3f4 for accessibility to status bytes
|
|
|
867c1e |
+ if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0)
|
|
|
867c1e |
+ return DISK_RET_ECONTROLLER;
|
|
|
867c1e |
+
|
|
|
867c1e |
+ // read return status bytes from controller
|
|
|
867c1e |
+ for (i=0; i<pio->resplen; i++)
|
|
|
867c1e |
+ pio->data[i] = inb(PORT_FD_DATA);
|
|
|
867c1e |
+
|
|
|
867c1e |
+ return DISK_RET_SUCCESS;
|
|
|
867c1e |
}
|
|
|
867c1e |
|
|
|
867c1e |
+// Perform a floppy transfer command (setup DMA and issue PIO).
|
|
|
867c1e |
static int
|
|
|
867c1e |
-floppy_cmd(struct disk_op_s *op, u16 count, u8 *cmd, u8 cmdlen)
|
|
|
867c1e |
+floppy_cmd(struct disk_op_s *op, int count, struct floppy_pio_s *pio)
|
|
|
867c1e |
{
|
|
|
867c1e |
// es:bx = pointer to where to place information from diskette
|
|
|
867c1e |
u32 addr = (u32)op->buf_fl;
|
|
|
867c1e |
@@ -255,7 +276,7 @@ floppy_cmd(struct disk_op_s *op, u16 count, u8 *cmd, u8 cmdlen)
|
|
|
867c1e |
return DISK_RET_EBOUNDARY;
|
|
|
867c1e |
|
|
|
867c1e |
u8 mode_register = 0x4a; // single mode, increment, autoinit disable,
|
|
|
867c1e |
- if (cmd[0] == 0xe6)
|
|
|
867c1e |
+ if (pio->data[0] == 0xe6)
|
|
|
867c1e |
// read
|
|
|
867c1e |
mode_register = 0x46;
|
|
|
867c1e |
|
|
|
867c1e |
@@ -277,21 +298,16 @@ floppy_cmd(struct disk_op_s *op, u16 count, u8 *cmd, u8 cmdlen)
|
|
|
867c1e |
|
|
|
867c1e |
outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2
|
|
|
867c1e |
|
|
|
867c1e |
- int ret = floppy_pio(cmd, cmdlen);
|
|
|
867c1e |
+ pio->resplen = 7;
|
|
|
867c1e |
+ pio->waitirq = 1;
|
|
|
867c1e |
+ int ret = floppy_pio(pio);
|
|
|
867c1e |
if (ret)
|
|
|
867c1e |
- return DISK_RET_ETIMEOUT;
|
|
|
867c1e |
-
|
|
|
867c1e |
- // check port 3f4 for accessibility to status bytes
|
|
|
867c1e |
- if ((inb(PORT_FD_STATUS) & 0xc0) != 0xc0)
|
|
|
867c1e |
- return DISK_RET_ECONTROLLER;
|
|
|
867c1e |
+ return ret;
|
|
|
867c1e |
|
|
|
867c1e |
- // read 7 return status bytes from controller
|
|
|
867c1e |
- u8 i;
|
|
|
867c1e |
- for (i=0; i<7; i++) {
|
|
|
867c1e |
- u8 v = inb(PORT_FD_DATA);
|
|
|
867c1e |
- cmd[i] = v;
|
|
|
867c1e |
- SET_BDA(floppy_return_status[i], v);
|
|
|
867c1e |
- }
|
|
|
867c1e |
+ // Populate floppy_return_status in BDA
|
|
|
867c1e |
+ int i;
|
|
|
867c1e |
+ for (i=0; i<7; i++)
|
|
|
867c1e |
+ SET_BDA(floppy_return_status[i], pio->data[i]);
|
|
|
867c1e |
|
|
|
867c1e |
return DISK_RET_SUCCESS;
|
|
|
867c1e |
}
|
|
|
867c1e |
@@ -311,10 +327,13 @@ static void
|
|
|
867c1e |
floppy_drive_recal(u8 floppyid)
|
|
|
867c1e |
{
|
|
|
867c1e |
// send Recalibrate command (2 bytes) to controller
|
|
|
867c1e |
- u8 data[12];
|
|
|
867c1e |
- data[0] = 0x07; // 07: Recalibrate
|
|
|
867c1e |
- data[1] = floppyid; // 0=drive0, 1=drive1
|
|
|
867c1e |
- floppy_pio(data, 2);
|
|
|
867c1e |
+ struct floppy_pio_s pio;
|
|
|
867c1e |
+ pio.cmdlen = 2;
|
|
|
867c1e |
+ pio.resplen = 0;
|
|
|
867c1e |
+ pio.waitirq = 0;
|
|
|
867c1e |
+ pio.data[0] = 0x07; // 07: Recalibrate
|
|
|
867c1e |
+ pio.data[1] = floppyid; // 0=drive0, 1=drive1
|
|
|
867c1e |
+ floppy_pio(&pio;;
|
|
|
867c1e |
|
|
|
867c1e |
u8 frs = GET_BDA(floppy_recalibration_status);
|
|
|
867c1e |
SET_BDA(floppy_recalibration_status, frs | (1<
|
|
|
867c1e |
@@ -423,22 +442,23 @@ floppy_read(struct disk_op_s *op)
|
|
|
867c1e |
|
|
|
867c1e |
// send read-normal-data command (9 bytes) to controller
|
|
|
867c1e |
u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id);
|
|
|
867c1e |
- u8 data[12];
|
|
|
867c1e |
- data[0] = 0xe6; // e6: read normal data
|
|
|
867c1e |
- data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
- data[2] = track;
|
|
|
867c1e |
- data[3] = head;
|
|
|
867c1e |
- data[4] = sector;
|
|
|
867c1e |
- data[5] = FLOPPY_SIZE_CODE;
|
|
|
867c1e |
- data[6] = sector + op->count - 1; // last sector to read on track
|
|
|
867c1e |
- data[7] = FLOPPY_GAPLEN;
|
|
|
867c1e |
- data[8] = FLOPPY_DATALEN;
|
|
|
867c1e |
-
|
|
|
867c1e |
- res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9);
|
|
|
867c1e |
+ struct floppy_pio_s pio;
|
|
|
867c1e |
+ pio.cmdlen = 9;
|
|
|
867c1e |
+ pio.data[0] = 0xe6; // e6: read normal data
|
|
|
867c1e |
+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
+ pio.data[2] = track;
|
|
|
867c1e |
+ pio.data[3] = head;
|
|
|
867c1e |
+ pio.data[4] = sector;
|
|
|
867c1e |
+ pio.data[5] = FLOPPY_SIZE_CODE;
|
|
|
867c1e |
+ pio.data[6] = sector + op->count - 1; // last sector to read on track
|
|
|
867c1e |
+ pio.data[7] = FLOPPY_GAPLEN;
|
|
|
867c1e |
+ pio.data[8] = FLOPPY_DATALEN;
|
|
|
867c1e |
+
|
|
|
867c1e |
+ res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, &pio;;
|
|
|
867c1e |
if (res)
|
|
|
867c1e |
goto fail;
|
|
|
867c1e |
|
|
|
867c1e |
- if (data[0] & 0xc0) {
|
|
|
867c1e |
+ if (pio.data[0] & 0xc0) {
|
|
|
867c1e |
res = DISK_RET_ECONTROLLER;
|
|
|
867c1e |
goto fail;
|
|
|
867c1e |
}
|
|
|
867c1e |
@@ -464,23 +484,24 @@ floppy_write(struct disk_op_s *op)
|
|
|
867c1e |
|
|
|
867c1e |
// send write-normal-data command (9 bytes) to controller
|
|
|
867c1e |
u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id);
|
|
|
867c1e |
- u8 data[12];
|
|
|
867c1e |
- data[0] = 0xc5; // c5: write normal data
|
|
|
867c1e |
- data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
- data[2] = track;
|
|
|
867c1e |
- data[3] = head;
|
|
|
867c1e |
- data[4] = sector;
|
|
|
867c1e |
- data[5] = FLOPPY_SIZE_CODE;
|
|
|
867c1e |
- data[6] = sector + op->count - 1; // last sector to write on track
|
|
|
867c1e |
- data[7] = FLOPPY_GAPLEN;
|
|
|
867c1e |
- data[8] = FLOPPY_DATALEN;
|
|
|
867c1e |
-
|
|
|
867c1e |
- res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, data, 9);
|
|
|
867c1e |
+ struct floppy_pio_s pio;
|
|
|
867c1e |
+ pio.cmdlen = 9;
|
|
|
867c1e |
+ pio.data[0] = 0xc5; // c5: write normal data
|
|
|
867c1e |
+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
+ pio.data[2] = track;
|
|
|
867c1e |
+ pio.data[3] = head;
|
|
|
867c1e |
+ pio.data[4] = sector;
|
|
|
867c1e |
+ pio.data[5] = FLOPPY_SIZE_CODE;
|
|
|
867c1e |
+ pio.data[6] = sector + op->count - 1; // last sector to write on track
|
|
|
867c1e |
+ pio.data[7] = FLOPPY_GAPLEN;
|
|
|
867c1e |
+ pio.data[8] = FLOPPY_DATALEN;
|
|
|
867c1e |
+
|
|
|
867c1e |
+ res = floppy_cmd(op, op->count * DISK_SECTOR_SIZE, &pio;;
|
|
|
867c1e |
if (res)
|
|
|
867c1e |
goto fail;
|
|
|
867c1e |
|
|
|
867c1e |
- if (data[0] & 0xc0) {
|
|
|
867c1e |
- if (data[1] & 0x02)
|
|
|
867c1e |
+ if (pio.data[0] & 0xc0) {
|
|
|
867c1e |
+ if (pio.data[1] & 0x02)
|
|
|
867c1e |
res = DISK_RET_EWRITEPROTECT;
|
|
|
867c1e |
else
|
|
|
867c1e |
res = DISK_RET_ECONTROLLER;
|
|
|
867c1e |
@@ -527,20 +548,21 @@ floppy_format(struct disk_op_s *op)
|
|
|
867c1e |
|
|
|
867c1e |
// send format-track command (6 bytes) to controller
|
|
|
867c1e |
u8 floppyid = GET_GLOBAL(op->drive_g->cntl_id);
|
|
|
867c1e |
- u8 data[12];
|
|
|
867c1e |
- data[0] = 0x4d; // 4d: format track
|
|
|
867c1e |
- data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
- data[2] = FLOPPY_SIZE_CODE;
|
|
|
867c1e |
- data[3] = op->count; // number of sectors per track
|
|
|
867c1e |
- data[4] = FLOPPY_FORMAT_GAPLEN;
|
|
|
867c1e |
- data[5] = FLOPPY_FILLBYTE;
|
|
|
867c1e |
-
|
|
|
867c1e |
- ret = floppy_cmd(op, op->count * 4, data, 6);
|
|
|
867c1e |
+ struct floppy_pio_s pio;
|
|
|
867c1e |
+ pio.cmdlen = 6;
|
|
|
867c1e |
+ pio.data[0] = 0x4d; // 4d: format track
|
|
|
867c1e |
+ pio.data[1] = (head << 2) | floppyid; // HD DR1 DR2
|
|
|
867c1e |
+ pio.data[2] = FLOPPY_SIZE_CODE;
|
|
|
867c1e |
+ pio.data[3] = op->count; // number of sectors per track
|
|
|
867c1e |
+ pio.data[4] = FLOPPY_FORMAT_GAPLEN;
|
|
|
867c1e |
+ pio.data[5] = FLOPPY_FILLBYTE;
|
|
|
867c1e |
+
|
|
|
867c1e |
+ ret = floppy_cmd(op, op->count * 4, &pio;;
|
|
|
867c1e |
if (ret)
|
|
|
867c1e |
return ret;
|
|
|
867c1e |
|
|
|
867c1e |
- if (data[0] & 0xc0) {
|
|
|
867c1e |
- if (data[1] & 0x02)
|
|
|
867c1e |
+ if (pio.data[0] & 0xc0) {
|
|
|
867c1e |
+ if (pio.data[1] & 0x02)
|
|
|
867c1e |
return DISK_RET_EWRITEPROTECT;
|
|
|
867c1e |
return DISK_RET_ECONTROLLER;
|
|
|
867c1e |
}
|
|
|
867c1e |
--
|
|
|
867c1e |
1.7.1
|
|
|
867c1e |
|