Qic02 module patch

Tekno Soft Snc (MC3641@mclink.it)
Sat, 23 Nov 96 18:07:03 CET


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