From a9f7119bb8ddfee4c42841ead46ff3eed3d943f3 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Sat, 5 Jan 2019 07:20:00 +0000 Subject: [PATCH] With buggy int13 ah=15, we can mis-identify the floppy devices. We have no option than trust INT13 ah=08 return code during the init phase. PR: 234460 Reported by: Oleh Hushchenkov MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D18723 --- stand/i386/libi386/biosdisk.c | 44 ++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/stand/i386/libi386/biosdisk.c b/stand/i386/libi386/biosdisk.c index 849803b93658..036182d72c2b 100644 --- a/stand/i386/libi386/biosdisk.c +++ b/stand/i386/libi386/biosdisk.c @@ -136,6 +136,8 @@ static int bd_ioctl(struct open_file *f, u_long cmd, void *data); static int bd_print(int verbose); static int cd_print(int verbose); static int fd_print(int verbose); +static void bd_reset_disk(int); +static int bd_get_diskinfo_std(struct bdinfo *); struct devsw biosfd = { .dv_name = "fd", @@ -251,21 +253,53 @@ bd_unit2bios(struct i386_devdesc *dev) return (-1); } +/* + * Use INT13 AH=15 - Read Drive Type. + */ +static int +fd_count(void) +{ + int drive; + + for (drive = 0; drive < MAXBDDEV; drive++) { + bd_reset_disk(drive); + + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x1500; + v86.edx = drive; + v86int(); + + if (V86_CY(v86.efl)) + break; + + if ((v86.eax & 0x300) == 0) + break; + } + + return (drive); +} + /* * Quiz the BIOS for disk devices, save a little info about them. */ static int fd_init(void) { - int unit; + int unit, numfd; bdinfo_t *bd; - for (unit = 0; unit < MAXBDDEV; unit++) { + numfd = fd_count(); + for (unit = 0; unit < numfd; unit++) { if ((bd = calloc(1, sizeof(*bd))) == NULL) break; + + bd->bd_sectorsize = BIOSDISK_SECSIZE; bd->bd_flags = BD_FLOPPY; bd->bd_unit = unit; - if (!bd_int13probe(bd)) { + + /* Use std diskinfo for floppy drive */ + if (bd_get_diskinfo_std(bd) != 0) { free(bd); break; } @@ -382,6 +416,10 @@ bc_add(int biosdev) static int bd_check_extensions(int unit) { + /* do not use ext calls for floppy devices */ + if (unit < 0x80) + return (0); + /* Determine if we can use EDD with this device. */ v86.ctl = V86_FLAGS; v86.addr = 0x13;