Messages in this thread Patch in this message |  | | Subject | Qic02 module patch | Date | Sat, 23 Nov 96 18:07:03 CET | From | Tekno Soft Snc <> |
| |
Hi all,
this patch modularize the Qic02 standard driver. It must be applied to the current development kernel (2.1.12).
Bye!
Roberto Fichera - email MC3641@mclink.it
--- cut here --- cut here --- cut here --- cut here --- cut here --- cut here
--- linux/drivers/char/Config.in.orig Sat Nov 23 16:43:43 1996 +++ linux/drivers/char/Config.in Sat Nov 23 16:44:55 1996 @@ -29,8 +29,8 @@ bool 'Support for user misc device modules' CONFIG_UMISC -bool 'QIC-02 tape support' CONFIG_QIC02_TAPE -if [ "$CONFIG_QIC02_TAPE" = "y" ]; then +tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE +if [ "$CONFIG_QIC02_TAPE" != "n" ]; then bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then comment 'Edit configuration parameters in ./include/linux/tpqic02.h!' --- linux/drivers/char/Makefile.orig Sat Nov 23 16:45:27 1996 +++ linux/drivers/char/Makefile Sat Nov 23 16:46:50 1996 @@ -170,8 +170,12 @@ L_OBJS += rtc.o endif -ifdef CONFIG_QIC02_TAPE -L_OBJS += tpqic02.o +ifeq ($(CONFIG_QIC02_TAPE),y) + L_OBJS += tpqic02.o +else + ifeq ($(CONFIG_QIC02_TAPE),m) + M_OBJS += tpqic02.o + endif endif ifeq ($(CONFIG_FTAPE),y) --- linux/drivers/char/tpqic02.c.orig Sat Nov 23 17:02:01 1996 +++ linux/drivers/char/tpqic02.c Sat Nov 23 17:44:58 1996 @@ -195,11 +195,28 @@ /* + * Changes: + * + * 1996/11/23: Roberto Fichera - mc3641@mclink.it + * Module patch aligned to 2.1.x + * + * 1996/08/12: Roberto Fichera - mc3641@mclink.it + * Some cleanup when resetting dead drives. In this case the + * module can't be removed. Special thanks to taylorix@uni-paderborn.de + * + * 1996/05/20: Roberto Fichera - mc3641@mclink.it + * Modularized + */ + + +/* #define TDEBUG */ #define REALLY_SLOW_IO /* it sure is ... */ +#include <linux/module.h> +#include <linux/malloc.h> #include <linux/sched.h> #include <linux/timer.h> #include <linux/fs.h> @@ -212,6 +229,7 @@ #include <linux/tpqic02.h> #include <linux/config.h> #include <linux/mm.h> +#include <linux/ioport.h> #include <asm/dma.h> #include <asm/system.h> @@ -333,8 +351,12 @@ * at 512 bytes, to prevent problems with 64k boundaries. */ +#ifndef MODULE static volatile char qic02_tape_buf[TPQBUF_SIZE+TAPE_BLKSIZE]; /* A really good compiler would be able to align this at 512 bytes... :-( */ +#else +static volatile char *qic02_tape_buf=(char *)NULL; +#endif /* MODULE */ static unsigned long buffaddr; /* aligned physical address of buffer */ @@ -2253,6 +2275,7 @@ unsigned short dens = 0; int s; + MOD_INC_USE_COUNT; if (TP_DIAGS(dev)) { printk("qic02_tape_open: dev=%s, flags=%x ", @@ -2260,25 +2283,35 @@ } if (MINOR(dev)==255) /* special case for resetting */ - if (suser()) - return (tape_reset(1)==TE_OK) ? -EAGAIN : -ENXIO; - else - return -EPERM; + if (suser()) { + int back; + back = tape_reset(1)==TE_OK; + MOD_DEC_USE_COUNT; + return back ? -EAGAIN : -ENXIO; + } else { + MOD_DEC_USE_COUNT; + return -EPERM; + } - if (status_dead==YES) + if (status_dead==YES) { /* Allow `mt reset' ioctl() even when already open()ed. */ + MOD_DEC_USE_COUNT; return 0; + } /* Only one at a time from here on... */ if (filp->f_count>1) { /* filp->f_count==1 for the first open() */ + MOD_DEC_USE_COUNT; return -EBUSY; } - if (status_zombie==YES) + if (status_zombie==YES) { /* no irq/dma/port stuff allocated yet, no reset done * yet, so return until MTSETCONFIG has been done. */ + MOD_DEC_USE_COUNT; return 0; + } status_bytes_rd = NO; status_bytes_wr = NO; @@ -2318,6 +2351,7 @@ if (s != TE_OK) { tpqputs(TPQD_ALWAYS, "open: sense() failed"); + MOD_DEC_USE_COUNT; return -EIO; } @@ -2327,6 +2361,7 @@ */ if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) { tpqputs(TPQD_ALWAYS, "No tape present."); + MOD_DEC_USE_COUNT; return -EIO; } @@ -2355,6 +2390,7 @@ s = do_qic_cmd(QCMD_REWIND, TIM_R); if (s != 0) { tpqputs(TPQD_ALWAYS, "open: rewind failed"); + MOD_DEC_USE_COUNT; return -EIO; } } @@ -2366,12 +2402,14 @@ if (status_dead==YES) { tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset"); if (tape_reset(1)!=TE_OK) { + MOD_DEC_USE_COUNT; return -ENXIO; } else { status_dead = NO; if (tp_sense(~(TP_ST1|TP_ILL)) != TE_OK) { tpqputs(TPQD_ALWAYS, "open: tp_sense() failed\n"); status_dead = YES; /* try reset next time */ + MOD_DEC_USE_COUNT; return -EIO; } } @@ -2384,8 +2422,10 @@ * so we must have done a rewind by now. If not, just skip over. * Only give set density command when minor bits have changed. */ - if (TP_DENS(current_tape_dev) == TP_DENS(dev) ) + if (TP_DENS(current_tape_dev) == TP_DENS(dev) ) { + MOD_DEC_USE_COUNT; return 0; + } current_tape_dev = dev; need_rewind = NO; @@ -2425,6 +2465,7 @@ if (s != 0) { status_dead = YES; /* force reset */ current_tape_dev = 0; /* earlier 0xff80 */ + MOD_DEC_USE_COUNT; return -EIO; } @@ -2440,6 +2481,8 @@ printk("qic02_tape_release: dev=%s\n", kdevname(dev)); + MOD_DEC_USE_COUNT; + if (status_zombie==YES) /* don't rewind in zombie mode */ return; @@ -2815,6 +2858,7 @@ { free_irq(QIC02_TAPE_IRQ, NULL); free_dma(QIC02_TAPE_DMA); + release_region(QIC02_TAPE_PORT, 4); status_zombie = YES; } /* qic02_release_resources */ @@ -2852,6 +2896,19 @@ return -1; } + /* Check the request IO region */ + if (check_region(QIC02_TAPE_PORT, 4) < 0) { + printk(TPQIC02_NAME ": can't allocate I/O region 0x%04x-0x%04x for QIC-02 tape", + QIC02_TAPE_PORT, QIC02_TAPE_PORT+4); + free_irq(QIC02_TAPE_IRQ, NULL); + free_dma(QIC02_TAPE_DMA); + status_zombie = YES; + return -1; + } + + /* Now we can allocate the requested IO region */ + request_region(QIC02_TAPE_PORT, 4, "QIC-02"); + printk(TPQIC02_NAME ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n", QIC02_TAPE_IRQ, QIC02_TAPE_DMA, ((QIC02_TAPE_IFC==ARCHIVE) || (QIC02_TAPE_IFC==MOUNTAIN))? @@ -2914,6 +2971,18 @@ printk(TPQIC02_NAME ": DMA buffers: %u blocks", NR_BLK_BUF); +#ifdef MODULE + /* On a module we must allocate the buffer in low memory */ + qic02_tape_buf = (char *)kmalloc((size_t)(TPQBUF_SIZE+TAPE_BLKSIZE), GFP_DMA); + if (qic02_tape_buf == (char *)NULL) { + printk (TPQIC02_NAME ": kmalloc() failed to allocate low-memory\n"); + free_irq(QIC02_TAPE_IRQ, NULL); + free_dma(QIC02_TAPE_DMA); + release_region(QIC02_TAPE_PORT, 4); + return -ENODEV; + } +#endif /* MODULE */ + /* Setup the page-address for the dma transfer. * This assumes a one-to-one identity mapping between * kernel addresses and physical memory. @@ -2924,6 +2993,12 @@ #ifndef CONFIG_MAX_16M if (buffaddr+TPQBUF_SIZE>=0x1000000) { printk(TPQIC02_NAME ": DMA buffer *must* be in lower 16MB\n"); + free_irq(QIC02_TAPE_IRQ, NULL); + free_dma(QIC02_TAPE_DMA); + release_region(QIC02_TAPE_PORT, 4); +#ifdef MODULE + kfree((void *)qic02_tape_buf); +#endif /* MODULE */ return -ENODEV; } #endif @@ -2934,6 +3009,10 @@ #ifndef CONFIG_QIC02_DYNCONF free_irq(QIC02_TAPE_IRQ, NULL); free_dma(QIC02_TAPE_DMA); + release_region(QIC02_TAPE_PORT, 4); +#ifdef MODULE + kfree((void *)qic02_tape_buf); +#endif /* MODULE */ #endif return -ENODEV; } @@ -2950,6 +3029,10 @@ status_dead = YES; free_irq(QIC02_TAPE_IRQ, NULL); free_dma(QIC02_TAPE_DMA); + release_region(QIC02_TAPE_PORT, 4); +#ifdef MODULE + kfree((void *)qic02_tape_buf); +#endif /* MODULE */ unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME); return -ENODEV; } else { @@ -2973,3 +3056,20 @@ return 0; } /* qic02_tape_init */ +#ifdef MODULE +int init_module(void) +{ + printk("tpqic02.c:v0.3 23/11/96 modular version by Roberto Fichera - MC3641@mclink.it\n"); + + return qic02_tape_init(); +} + +void cleanup_module(void) +{ + free_irq(QIC02_TAPE_IRQ, NULL); + free_dma(QIC02_TAPE_DMA); + release_region(QIC02_TAPE_PORT, 4); + kfree((void *)qic02_tape_buf); + unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME); +} +#endif /* MODULE */ --- linux/include/linux/tpqic02.h.orig Sat Nov 23 17:32:37 1996 +++ linux/include/linux/tpqic02.h Sat Nov 23 17:35:20 1996 @@ -12,7 +12,8 @@ #include <linux/config.h> -#if CONFIG_QIC02_TAPE +#if CONFIG_QIC02_TAPE || \ + CONFIG_QIC02_TAPE_MODULE /* need to have QIC02_TAPE_DRIVE and QIC02_TAPE_IFC expand to something */ #include <linux/mtio.h> --- cut here --- cut here --- cut here --- cut here --- cut here --- cut here
|  |