diff --git a/elks/arch/i86/drivers/block/directfd.c b/elks/arch/i86/drivers/block/directfd.c index 79aa35f2b..fb3e35f02 100644 --- a/elks/arch/i86/drivers/block/directfd.c +++ b/elks/arch/i86/drivers/block/directfd.c @@ -305,7 +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 void floppy_setup(void); +static int floppy_register(void); +static void floppy_deregister(void); /* * These are global variables, as that's the easiest way to give @@ -1478,7 +1479,7 @@ static int floppy_open(struct inode *inode, struct file *filp) drive = DEVICE_NR(inode->i_rdev); dev = drive & 3; if (++fd_ref[dev] == 1) { - floppy_setup(); + floppy_register(); } buffer_drive = buffer_track = -1; /* FIXME: Don't invalidate buffer if * this is a reopen of the currently @@ -1517,6 +1518,7 @@ static void floppy_release(struct inode *inode, struct file *filp) fsync_dev(dev); invalidate_inodes(dev); invalidate_buffers(dev); + floppy_deregister(); } } @@ -1557,22 +1559,38 @@ static void floppy_interrupt(int unused, struct pt_regs *unused1) handler(); } -static void floppy_setup(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; - static char once = 0; - if (once) return; /* execute this routine only once for now */ - once = 1; - outb(current_DOR, FD_DOR); /* all motors off, DMA, /RST (0x0c) */ + current_DOR = 0x0c; + outb(0x0c, FD_DOR); /* all motors off, enable IRQ and DMA */ + + 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,7 @@ static void floppy_setup(void) reset_floppy(); } #endif + return 0; } void INITPROC floppy_init(void) diff --git a/elks/arch/i86/drivers/block/dma.c b/elks/arch/i86/drivers/block/dma.c index 52059fb63..dbbb5b998 100644 --- a/elks/arch/i86/drivers/block/dma.c +++ b/elks/arch/i86/drivers/block/dma.c @@ -64,32 +64,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; @@ -225,6 +208,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 +231,16 @@ 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; +} /* get_dma_list */ +#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