Skip to content

Commit

Permalink
Register/deregister IRQ and DMA on direct FD driver open/close
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaerr committed Sep 15, 2023
1 parent 5c31b92 commit def03a7
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 34 deletions.
43 changes: 31 additions & 12 deletions elks/arch/i86/drivers/block/directfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
}

Expand Down Expand Up @@ -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 ... */
Expand All @@ -1599,6 +1617,7 @@ static void floppy_setup(void)
reset_floppy();
}
#endif
return 0;
}

void INITPROC floppy_init(void)
Expand Down
34 changes: 15 additions & 19 deletions elks/arch/i86/drivers/block/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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
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

0 comments on commit def03a7

Please sign in to comment.