Skip to content

Commit

Permalink
Merge pull request #1721 from ghaerr/df2880
Browse files Browse the repository at this point in the history
[directfd] Add support for 2880k discs, multiple open/close
  • Loading branch information
ghaerr authored Sep 15, 2023
2 parents de8909a + 9ddcb62 commit c00b057
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 51 deletions.
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

0 comments on commit c00b057

Please sign in to comment.