diff --git a/elks/arch/i86/drivers/block/directfd.c b/elks/arch/i86/drivers/block/directfd.c index ce630e9bd..fb3e35f02 100644 --- a/elks/arch/i86/drivers/block/directfd.c +++ b/elks/arch/i86/drivers/block/directfd.c @@ -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/ */ }; @@ -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. */ @@ -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 @@ -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; @@ -1456,17 +1461,14 @@ 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"); } @@ -1474,8 +1476,11 @@ 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. */ @@ -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(); } } @@ -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 ... */ @@ -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 diff --git a/elks/arch/i86/drivers/block/dma.c b/elks/arch/i86/drivers/block/dma.c index 52059fb63..289e3f4fd 100644 --- a/elks/arch/i86/drivers/block/dma.c +++ b/elks/arch/i86/drivers/block/dma.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -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; @@ -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 */ @@ -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 @@ -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 @@ -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 @@ -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 @@ -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. @@ -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 diff --git a/elks/include/arch/dma.h b/elks/include/arch/dma.h index ac840e0b2..3497b1e26 100644 --- a/elks/include/arch/dma.h +++ b/elks/include/arch/dma.h @@ -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 diff --git a/elks/include/arch/ports.h b/elks/include/arch/ports.h index 5a6ecbd49..5f9fae3c1 100644 --- a/elks/include/arch/ports.h +++ b/elks/include/arch/ports.h @@ -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 diff --git a/elks/include/linuxmt/devnum.h b/elks/include/linuxmt/devnum.h index 51c1ffc8a..dba287c73 100644 --- a/elks/include/linuxmt/devnum.h +++ b/elks/include/linuxmt/devnum.h @@ -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 */ diff --git a/elks/init/main.c b/elks/init/main.c index 13b76369d..27883dc06 100644 --- a/elks/init/main.c +++ b/elks/init/main.c @@ -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 }, diff --git a/libc/misc/devname.c b/libc/misc/devname.c index 9a51624fa..7c9c7988b 100644 --- a/libc/misc/devname.c +++ b/libc/misc/devname.c @@ -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 },