Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[directfd] Add support for 2880k discs, multiple open/close #1721

Merged
merged 4 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 53 additions & 24 deletions elks/arch/i86/drivers/block/directfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ static struct floppy_struct floppy_type[] = {
{720, 9, 2, 40, 1, 0x23, 0x01, 0xDF, 0x50, NULL}, /* 360kB in 1.2MB drive */
{1440, 9, 2, 80, 0, 0x23, 0x01, 0xDF, 0x50, NULL}, /* 720kB in 1.2MB drive */
{2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL}, /* 1.44MB diskette */
{5760, 36, 2, 80, 0, 0x1B, 0x03, 0xCF, 0x6C, NULL}, /* 2.88MB diskette (UNTESTED) */
/* totSectors/secPtrack/heads/tracks/stretch/gap/Drate/S&Hrates/fmtGap/nm/ */
};

Expand All @@ -216,6 +217,8 @@ static struct floppy_struct floppy_types[] = {
{1440, 9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, "720k"}, /* 3.5" 720kB diskette */
{2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, "1.44M"}, /* 1.44MB diskette */
{1440, 9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, "720k/AT"}, /* 3.5" 720kB diskette */
{5760, 36, 2, 80, 0, 0x1B, 0x03, 0xCF, 0x6C, "2.88M"},/* 2.88MB diskette (UNTESTED) */
{2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, "1.44M"}, /* 1.44MB diskette */
};

/* Auto-detection: Disk type used until the next media change occurs. */
Expand Down Expand Up @@ -302,6 +305,8 @@ static void redo_fd_request(void);
static void recal_interrupt(void);
static void floppy_shutdown(void);
static void motor_off_callback(int);
static int floppy_register(void);
static void floppy_deregister(void);

/*
* These are global variables, as that's the easiest way to give
Expand Down Expand Up @@ -1437,17 +1442,17 @@ static int fd_ioctl(struct inode *inode,
return err;
}

static int CMOS_READ(int addr)
static int INITPROC CMOS_READ(int addr)
{
outb_p(addr, 0x70);
return inb_p(0x71);
}

static struct floppy_struct *find_base(int drive, int code)
static struct floppy_struct * INITPROC find_base(int drive, int code)
{
struct floppy_struct *base;

if (code > 0 && code < 5) {
if (code > 0 && code < 6) {
base = &floppy_types[(code - 1) * 2];
printk("df%d is %s (%d)", drive, base->name, code);
return base;
Expand All @@ -1456,26 +1461,26 @@ static struct floppy_struct *find_base(int drive, int code)
return NULL;
}

static void config_types(void)
static void INITPROC config_types(void)
{
printk("Floppy drive(s) [CMOS]: ");
printk("df: CMOS ");
base_type[0] = find_base(0, (CMOS_READ(0x10) >> 4) & 0xF);
if (((CMOS_READ(0x14) >> 6) & 1) == 0)
base_type[1] = NULL;
else {
if (((CMOS_READ(0x14) >> 6) & 1) != 0) {
printk(", ");
base_type[1] = find_base(1, CMOS_READ(0x10) & 0xF);
}
base_type[2] = base_type[3] = NULL;
printk("\n");
}

static int floppy_open(struct inode *inode, struct file *filp)
{
int drive, dev;

dev = drive = DEVICE_NR(inode->i_rdev);
fd_ref[dev]++;
drive = DEVICE_NR(inode->i_rdev);
dev = drive & 3;
if (++fd_ref[dev] == 1) {
floppy_register();
}
buffer_drive = buffer_track = -1; /* FIXME: Don't invalidate buffer if
* this is a reopen of the currently
* bufferd drive. */
Expand Down Expand Up @@ -1513,6 +1518,7 @@ static void floppy_release(struct inode *inode, struct file *filp)
fsync_dev(dev);
invalidate_inodes(dev);
invalidate_buffers(dev);
floppy_deregister();
}
}

Expand Down Expand Up @@ -1553,26 +1559,38 @@ static void floppy_interrupt(int unused, struct pt_regs *unused1)
handler();
}

void INITPROC floppy_init(void)
/* non-portable, should use int_vector_set and new function get_int_vector */
#define FLOPPY_VEC (_MK_FP(0, (FLOPPY_IRQ+8) << 2))
static __u32 old_floppy_vec;

static void floppy_deregister(void)
{
outb(0x0c, FD_DOR); /* all motors off, enable IRQ and DMA */
free_dma(FLOPPY_DMA);
clr_irq();
free_irq(FLOPPY_IRQ);
*(__u32 __far *)FLOPPY_VEC = old_floppy_vec;
enable_irq(FLOPPY_IRQ);
set_irq();
}

static int floppy_register(void)
{
int err;

outb(current_DOR, FD_DOR); /* all motors off, DMA, /RST (0x0c) */
if (register_blkdev(MAJOR_NR, DEVICE_NAME, &floppy_fops)) {
printk("Unable to get major %d for floppy\n", MAJOR_NR);
return;
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
current_DOR = 0x0c;
outb(0x0c, FD_DOR); /* all motors off, enable IRQ and DMA */

config_types();
old_floppy_vec = *((__u32 __far *)FLOPPY_VEC);
err = request_irq(FLOPPY_IRQ, floppy_interrupt, INT_GENERIC);
if (err) {
printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ);
return; /* should be able to signal failure back to the caller */
printk("df: IRQ %d busy\n", FLOPPY_IRQ);
return err;
}
if (request_dma(FLOPPY_DMA, DEVICE_NAME)) {
printk("df: DMA %d busy\n", FLOPPY_DMA);
return -EBUSY;
}

if (request_dma(FLOPPY_DMA, (void *)DEVICE_NAME))
printk("Unable to grab DMA%d for the floppy driver\n", FLOPPY_DMA);

/* Try to determine the floppy controller type */
DEVICE_INTR = ignore_interrupt; /* don't ask ... */
Expand All @@ -1599,6 +1617,17 @@ void INITPROC floppy_init(void)
reset_floppy();
}
#endif
return 0;
}

void INITPROC floppy_init(void)
{
if (register_blkdev(MAJOR_NR, DEVICE_NAME, &floppy_fops)) {
printk("df: init error\n");
return;
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
config_types();
}

#if 0
Expand Down
44 changes: 20 additions & 24 deletions elks/arch/i86/drivers/block/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linuxmt/types.h>
#include <linuxmt/kernel.h>
#include <linuxmt/errno.h>
#include <linuxmt/debug.h>
#include <arch/dma.h>
#include <arch/system.h>

Expand Down Expand Up @@ -64,32 +65,15 @@ static struct dma_chan dma_chan_busy[MAX_DMA_CHANNELS] = {
__ret; \
} )

#ifdef ONE_DAY

int get_dma_list(char *buf)
{
int i, len = 0;

for (i = 0; i < MAX_DMA_CHANNELS; i++)
if (dma_chan_busy[i].lock)
len += sprintf(buf + len, "%2d: %s\n",
i, dma_chan_busy[i].device_id);
return len;
} /* get_dma_list */

#endif

int request_dma(unsigned char dma, void *device)
int request_dma(unsigned char dma, const char *device)
{
char *device_id = device;

if (dma >= MAX_DMA_CHANNELS)
return -EINVAL;

if (xchg(&dma_chan_busy[dma].lock, 1) != 0)
return -EBUSY;

dma_chan_busy[dma].device_id = device_id;
dma_chan_busy[dma].device_id = device;

/* old flag was 0, now contains 1 to indicate busy */
return 0;
Expand All @@ -98,7 +82,7 @@ int request_dma(unsigned char dma, void *device)
void free_dma(unsigned char dma)
{
if (dma >= MAX_DMA_CHANNELS)
printk("Trying to free DMA%u\n", dma);
debug("Trying to free DMA%u\n", dma);
else if (!xchg(&dma_chan_busy[dma].lock, 0)) {
printk("Trying to free free DMA%u\n", dma);
} } /* free_dma */
Expand All @@ -108,7 +92,7 @@ void free_dma(unsigned char dma)
void enable_dma(unsigned char dma)
{
if (dma >= MAX_DMA_CHANNELS)
printk("Trying to enable DMA%u\n", dma);
debug("Trying to enable DMA%u\n", dma);
else if (dma <= 3)
dma_outb(dma, DMA1_MASK_REG);
else
Expand All @@ -118,7 +102,7 @@ void enable_dma(unsigned char dma)
void disable_dma(unsigned char dma)
{
if (dma >= MAX_DMA_CHANNELS)
printk("Trying to disable DMA%u\n", dma);
debug("Trying to disable DMA%u\n", dma);
else if (dma <= 3)
dma_outb(dma | 4, DMA1_MASK_REG);
else
Expand All @@ -136,7 +120,7 @@ void disable_dma(unsigned char dma)
void clear_dma_ff(unsigned char dma)
{
if (dma >= MAX_DMA_CHANNELS)
printk("Trying to disable DMA%u\n", dma);
debug("Trying to disable DMA%u\n", dma);
else if (dma <= 3)
dma_outb(0, DMA1_CLEAR_FF_REG);
else
Expand All @@ -148,7 +132,7 @@ void clear_dma_ff(unsigned char dma)
void set_dma_mode(unsigned char dma, unsigned char mode)
{
if (dma >= MAX_DMA_CHANNELS)
printk("Trying to disable DMA%u\n", dma);
debug("Trying to disable DMA%u\n", dma);
else if (dma <= 3)
dma_outb(mode | dma, DMA1_MODE_REG);
else
Expand Down Expand Up @@ -225,6 +209,7 @@ void set_dma_count(unsigned char dma, unsigned int count)
}
}

#if UNUSED
/* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
Expand All @@ -247,4 +232,15 @@ int get_dma_residue(unsigned char dma)
return (dma <= 3) ? count : (count << 1);
}

int get_dma_list(char *buf)
{
int i, len = 0;

for (i = 0; i < MAX_DMA_CHANNELS; i++)
if (dma_chan_busy[i].lock)
len += sprintf(buf + len, "%2d: %s\n", i, dma_chan_busy[i].device_id);
return len;
}
#endif

#endif
2 changes: 1 addition & 1 deletion elks/include/arch/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ extern void set_dma_page(unsigned char,unsigned char);
extern void set_dma_addr(unsigned char,unsigned long);
extern void set_dma_count(unsigned char,unsigned int);
extern int get_dma_residue(unsigned char);
extern int request_dma(unsigned char,void *);
extern int request_dma(unsigned char,const char *);
extern void free_dma(unsigned char);

#endif
4 changes: 2 additions & 2 deletions elks/include/arch/ports.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,5 @@
#define HD1_AT_IRQ 14 /* missing request_irq call*/
#define HD2_AT_IRQ 15 /* missing request_irq call*/

/* obsolete - experimental floppy drive, floppy.c (won't compile)*/
#define FLOPPY_IRQ 6 /* missing request_irq call*/
/* direct floppy driver, directfd.c */
#define FLOPPY_IRQ 6
2 changes: 2 additions & 0 deletions elks/include/linuxmt/devnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#define DEV_FD1 MKDEV(BIOSHD_MAJOR, 40)
#define DEV_FD2 MKDEV(BIOSHD_MAJOR, 48)
#define DEV_FD3 MKDEV(BIOSHD_MAJOR, 56)
#define DEV_DF0 MKDEV(FLOPPY_MAJOR, 0)
#define DEV_DF1 MKDEV(FLOPPY_MAJOR, 1)
#define DEV_ROM MKDEV(ROMFLASH_MAJOR, 0)

/* char devices */
Expand Down
2 changes: 2 additions & 0 deletions elks/init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ static struct dev_name_struct {
{ "hdd", DEV_HDD },
{ "fd0", DEV_FD0 },
{ "fd1", DEV_FD1 },
{ "df0", DEV_DF0 },
{ "df1", DEV_DF1 },
{ "ttyS0", DEV_TTYS0 },
{ "ttyS1", DEV_TTYS1 },
{ "tty1", DEV_TTY1 },
Expand Down
2 changes: 2 additions & 0 deletions libc/misc/devname.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ static struct dev_name_struct {
{ "hdd", S_IFBLK, DEV_HDD },
{ "fd0", S_IFBLK, DEV_FD0 },
{ "fd1", S_IFBLK, DEV_FD1 },
{ "df0", S_IFBLK, DEV_DF0 },
{ "df1", S_IFBLK, DEV_DF1 },
{ "ssd", S_IFBLK, MKDEV(SSD_MAJOR, 0) },
{ "rd0", S_IFBLK, MKDEV(RAM_MAJOR, 0) },
{ "ttyS0", S_IFCHR, DEV_TTYS0 },
Expand Down