patch-2.4.8 linux/drivers/s390/char/tapechar.c

Next file: linux/drivers/s390/char/tapechar.h
Previous file: linux/drivers/s390/char/tapeblock.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.7/linux/drivers/s390/char/tapechar.c linux/drivers/s390/char/tapechar.c
@@ -58,30 +58,30 @@
 
 #ifdef CONFIG_DEVFS_FS
 void
-tapechar_mkdevfstree (tape_info_t* tape) {
-    tape->devfs_char_dir=devfs_mk_dir (tape->devfs_dir, "char", tape);
-    tape->devfs_nonrewinding=devfs_register(tape->devfs_char_dir, "nonrewinding",
+tapechar_mkdevfstree (tape_info_t* ti) {
+    ti->devfs_char_dir=devfs_mk_dir (ti->devfs_dir, "char", ti);
+    ti->devfs_nonrewinding=devfs_register(ti->devfs_char_dir, "nonrewinding",
 					    DEVFS_FL_DEFAULT,tape_major, 
-					    tape->nor_minor, TAPECHAR_DEFAULTMODE, 
-					    &tape_fops, tape);
-    tape->devfs_rewinding=devfs_register(tape->devfs_char_dir, "rewinding",
-					 DEVFS_FL_DEFAULT, tape_major, tape->rew_minor,
-					 TAPECHAR_DEFAULTMODE, &tape_fops, tape);
+					    ti->nor_minor, TAPECHAR_DEFAULTMODE, 
+					    &tape_fops, ti);
+    ti->devfs_rewinding=devfs_register(ti->devfs_char_dir, "rewinding",
+					 DEVFS_FL_DEFAULT, tape_major, ti->rew_minor,
+					 TAPECHAR_DEFAULTMODE, &tape_fops, ti);
 }
 
 void
-tapechar_rmdevfstree (tape_info_t* tape) {
-    devfs_unregister(tape->devfs_nonrewinding);
-    devfs_unregister(tape->devfs_rewinding);
-    devfs_unregister(tape->devfs_char_dir);
+tapechar_rmdevfstree (tape_info_t* ti) {
+    devfs_unregister(ti->devfs_nonrewinding);
+    devfs_unregister(ti->devfs_rewinding);
+    devfs_unregister(ti->devfs_char_dir);
 }
 #endif
 
 void
-tapechar_setup (tape_info_t * tape)
+tapechar_setup (tape_info_t * ti)
 {
 #ifdef CONFIG_DEVFS_FS
-    tapechar_mkdevfstree(tape);
+    tapechar_mkdevfstree(ti);
 #endif
 }
 
@@ -90,7 +90,7 @@
 {
 	int result;
 	tape_frontend_t *charfront,*temp;
-	tape_info_t* tape;
+	tape_info_t* ti;
 
 	tape_init();
 
@@ -137,10 +137,10 @@
 		temp=temp->next;
 	    temp->next=charfront;
 	}
-	tape=first_tape_info;
-	while (tape!=NULL) {
-	    tapechar_setup(tape);
-	    tape=tape->next;
+	ti=first_tape_info;
+	while (ti!=NULL) {
+	    tapechar_setup(ti);
+	    ti=ti->next;
 	}
 }
 
@@ -157,17 +157,17 @@
 tape_read (struct file *filp, char *data, size_t count, loff_t * ppos)
 {
 	long lockflags;
-	tape_info_t *tape;
+	tape_info_t *ti;
 	size_t block_size;
 	ccw_req_t *cqr;
 	int rc;
 #ifdef TAPE_DEBUG
         debug_text_event (tape_debug_area,6,"c:read");
 #endif /* TAPE_DEBUG */
-	tape = first_tape_info;
-	while ((tape != NULL) && (tape->rew_filp != filp) && (tape->nor_filp != filp))
-		tape = (tape_info_t *) tape->next;
-	if (tape == NULL) {
+	ti = first_tape_info;
+	while ((ti != NULL) && (ti->rew_filp != filp) && (ti->nor_filp != filp))
+		ti = (tape_info_t *) ti->next;
+	if (ti == NULL) {
 #ifdef TAPE_DEBUG
 	        debug_text_event (tape_debug_area,6,"c:nodev");
 #endif /* TAPE_DEBUG */
@@ -180,62 +180,62 @@
 #endif /* TAPE_DEBUG */
 		return -EOVERFLOW;	/* errno=75 Value too large for def. data type */
 	}
-	if (tape->block_size == 0) {
+	if (ti->block_size == 0) {
 		block_size = count;
 	} else {
-		block_size = tape->block_size;
+		block_size = ti->block_size;
 	}
 #ifdef TAPE_DEBUG
 	debug_text_event (tape_debug_area,6,"c:nbytes:");
 	debug_int_event (tape_debug_area,6,block_size);
 #endif
-	cqr = tape->discipline->read_block (data, block_size, tape);
+	cqr = ti->discipline->read_block (data, block_size, ti);
 	if (!cqr) {
 		return -ENOBUFS;
 	}
-	s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-	tape->cqr = cqr;
-	tape->wanna_wakeup=0;
-	rc = do_IO (tape->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
+	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+	ti->cqr = cqr;
+	ti->wanna_wakeup=0;
+	rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
 	if (rc) {
-	    tapestate_set(tape,TS_IDLE);
+	    tapestate_set(ti,TS_IDLE);
 	    kfree (cqr);
-	    s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+	    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 	    return rc;
 	}
-	s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-	wait_event_interruptible (tape->wq,tape->wanna_wakeup);
-	tape->cqr = NULL;
-	tape->discipline->free_read_block (cqr, tape);
+	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+	wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+	ti->cqr = NULL;
+	ti->discipline->free_read_block (cqr, ti);
 	if (signal_pending (current)) {
-		tapestate_set (tape, TS_IDLE);
+		tapestate_set (ti, TS_IDLE);
 		return -ERESTARTSYS;
 	}
-	s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-	if (tapestate_get (tape) == TS_FAILED) {
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-		return tape->rc;
-	}
-	if (tapestate_get (tape) == TS_NOT_OPER) {
-	    tape->blk_minor=tape->rew_minor=tape->nor_minor=-1;
-	    tape->devinfo.irq=-1;
-	    s390irq_spin_unlock_irqrestore (tape->devinfo.irq,lockflags);
+	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+	if (tapestate_get (ti) == TS_FAILED) {
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+		return ti->rc;
+	}
+	if (tapestate_get (ti) == TS_NOT_OPER) {
+	    ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
+	    ti->devinfo.irq=-1;
+	    s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
 	    return -ENODEV;
 	}
-	if (tapestate_get (tape) != TS_DONE) {
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+	if (tapestate_get (ti) != TS_DONE) {
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 		return -EIO;
 	}
-	tapestate_set (tape, TS_IDLE);
-	s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+	tapestate_set (ti, TS_IDLE);
+	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 #ifdef TAPE_DEBUG
 	debug_text_event (tape_debug_area,6,"c:rbytes:");
-	debug_int_event (tape_debug_area,6,block_size - tape->devstat.rescnt);
+	debug_int_event (tape_debug_area,6,block_size - ti->devstat.rescnt);
 #endif	/* TAPE_DEBUG */
-	filp->f_pos += block_size - tape->devstat.rescnt;
-	return block_size - tape->devstat.rescnt;
+	filp->f_pos += block_size - ti->devstat.rescnt;
+	return block_size - ti->devstat.rescnt;
 }
 
 /*
@@ -245,7 +245,7 @@
 tape_write (struct file *filp, const char *data, size_t count, loff_t * ppos)
 {
 	long lockflags;
-	tape_info_t *tape;
+	tape_info_t *ti;
 	size_t block_size;
 	ccw_req_t *cqr;
 	int nblocks, i, rc;
@@ -253,10 +253,10 @@
 #ifdef TAPE_DEBUG
 	debug_text_event (tape_debug_area,6,"c:write");
 #endif
-	tape = first_tape_info;
-	while ((tape != NULL) && (tape->nor_filp != filp) && (tape->rew_filp != filp))
-		tape = (tape_info_t *) tape->next;
-	if (tape == NULL)
+	ti = first_tape_info;
+	while ((ti != NULL) && (ti->nor_filp != filp) && (ti->rew_filp != filp))
+		ti = (tape_info_t *) ti->next;
+	if (ti == NULL)
 		return -ENODEV;
 	if (ppos != &filp->f_pos) {
 		/* "A request was outside the capabilities of the device." */
@@ -265,14 +265,14 @@
 #endif
 		return -EOVERFLOW;	/* errno=75 Value too large for def. data type */
 	}
-	if ((tape->block_size != 0) && (count % tape->block_size != 0))
+	if ((ti->block_size != 0) && (count % ti->block_size != 0))
 		return -EIO;
-	if (tape->block_size == 0) {
+	if (ti->block_size == 0) {
 		block_size = count;
 		nblocks = 1;
 	} else {
-		block_size = tape->block_size;
-		nblocks = count / (tape->block_size);
+		block_size = ti->block_size;
+		nblocks = count / (ti->block_size);
 	}
 #ifdef TAPE_DEBUG
 	        debug_text_event (tape_debug_area,6,"c:nbytes:");
@@ -281,50 +281,50 @@
 	        debug_int_event (tape_debug_area,6,nblocks);
 #endif
 	for (i = 0; i < nblocks; i++) {
-		cqr = tape->discipline->write_block (data + i * block_size, block_size, tape);
+		cqr = ti->discipline->write_block (data + i * block_size, block_size, ti);
 		if (!cqr) {
 			return -ENOBUFS;
 		}
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tape->cqr = cqr;
-		tape->wanna_wakeup=0;
-		rc = do_IO (tape->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-		wait_event_interruptible (tape->wq,tape->wanna_wakeup);
-		tape->cqr = NULL;
-		tape->discipline->free_write_block (cqr, tape);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		ti->cqr = cqr;
+		ti->wanna_wakeup=0;
+		rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+		wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+		ti->cqr = NULL;
+		ti->discipline->free_write_block (cqr, ti);
 		if (signal_pending (current)) {
-			tapestate_set (tape, TS_IDLE);
+			tapestate_set (ti, TS_IDLE);
 			return -ERESTARTSYS;
 		}
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		if (tapestate_get (tape) == TS_FAILED) {
-			tapestate_set (tape, TS_IDLE);
-			s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-                        if ((tape->rc==-ENOSPC) && (i!=0))
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		if (tapestate_get (ti) == TS_FAILED) {
+			tapestate_set (ti, TS_IDLE);
+			s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+                        if ((ti->rc==-ENOSPC) && (i!=0))
 			  return i*block_size;
-			return tape->rc;
+			return ti->rc;
 		}
-		if (tapestate_get (tape) == TS_NOT_OPER) {
-		    tape->blk_minor=tape->rew_minor=tape->nor_minor=-1;
-		    tape->devinfo.irq=-1;
-		    s390irq_spin_unlock_irqrestore (tape->devinfo.irq,lockflags);
+		if (tapestate_get (ti) == TS_NOT_OPER) {
+		    ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
+		    ti->devinfo.irq=-1;
+		    s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
 		    return -ENODEV;
 		}
-		if (tapestate_get (tape) != TS_DONE) {
-			tapestate_set (tape, TS_IDLE);
-			s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+		if (tapestate_get (ti) != TS_DONE) {
+			tapestate_set (ti, TS_IDLE);
+			s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 			return -EIO;
 		}
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 #ifdef TAPE_DEBUG
 	        debug_text_event (tape_debug_area,6,"c:wbytes:"); 
-		debug_int_event (tape_debug_area,6,block_size - tape->devstat.rescnt);
+		debug_int_event (tape_debug_area,6,block_size - ti->devstat.rescnt);
 #endif
-		filp->f_pos += block_size - tape->devstat.rescnt;
-		written += block_size - tape->devstat.rescnt;
-		if (tape->devstat.rescnt > 0)
+		filp->f_pos += block_size - ti->devstat.rescnt;
+		written += block_size - ti->devstat.rescnt;
+		if (ti->devstat.rescnt > 0)
 			return written;
 	}
 #ifdef TAPE_DEBUG
@@ -337,7 +337,7 @@
 static int
 tape_mtioctop (struct file *filp, short mt_op, int mt_count)
 {
-	tape_info_t *tape;
+	tape_info_t *ti;
 	ccw_req_t *cqr = NULL;
 	int rc;
 	long lockflags;
@@ -348,113 +348,118 @@
 	debug_text_event (tape_debug_area,6,"c:arg:");
 	debug_int_event (tape_debug_area,6,mt_count);
 #endif
-	tape = first_tape_info;
-	while ((tape != NULL) && (tape->rew_filp != filp) && (tape->nor_filp != filp))
-		tape = (tape_info_t *) tape->next;
-	if (tape == NULL)
+	ti = first_tape_info;
+	while ((ti != NULL) && (ti->rew_filp != filp) && (ti->nor_filp != filp))
+		ti = (tape_info_t *) ti->next;
+	if (ti == NULL)
 		return -ENODEV;
 	switch (mt_op) {
 	case MTREW:		// rewind
 
-		cqr = tape->discipline->mtrew (tape, mt_count);
+		cqr = ti->discipline->mtrew (ti, mt_count);
 		break;
 	case MTOFFL:		// put drive offline
 
-		cqr = tape->discipline->mtoffl (tape, mt_count);
+		cqr = ti->discipline->mtoffl (ti, mt_count);
 		break;
 	case MTUNLOAD:		// unload the tape
 
-		cqr = tape->discipline->mtunload (tape, mt_count);
+		cqr = ti->discipline->mtunload (ti, mt_count);
 		break;
 	case MTWEOF:		// write tapemark
 
-		cqr = tape->discipline->mtweof (tape, mt_count);
+		cqr = ti->discipline->mtweof (ti, mt_count);
 		break;
 	case MTFSF:		// forward space file
 
-		cqr = tape->discipline->mtfsf (tape, mt_count);
+		cqr = ti->discipline->mtfsf (ti, mt_count);
 		break;
 	case MTBSF:		// backward space file
 
-		cqr = tape->discipline->mtbsf (tape, mt_count);
+		cqr = ti->discipline->mtbsf (ti, mt_count);
 		break;
 	case MTFSFM:		// forward space file, stop at BOT side
 
-		cqr = tape->discipline->mtfsfm (tape, mt_count);
+		cqr = ti->discipline->mtfsfm (ti, mt_count);
 		break;
 	case MTBSFM:		// backward space file, stop at BOT side
 
-		cqr = tape->discipline->mtbsfm (tape, mt_count);
+		cqr = ti->discipline->mtbsfm (ti, mt_count);
 		break;
 	case MTFSR:		// forward space file
 
-		cqr = tape->discipline->mtfsr (tape, mt_count);
+		cqr = ti->discipline->mtfsr (ti, mt_count);
 		break;
 	case MTBSR:		// backward space file
 
-		cqr = tape->discipline->mtbsr (tape, mt_count);
+		cqr = ti->discipline->mtbsr (ti, mt_count);
 		break;
 	case MTNOP:
-		cqr = tape->discipline->mtnop (tape, mt_count);
+		cqr = ti->discipline->mtnop (ti, mt_count);
 		break;
 	case MTEOM:		// postion at the end of portion
 
 	case MTRETEN:		// retension the tape
 
-		cqr = tape->discipline->mteom (tape, mt_count);
+		cqr = ti->discipline->mteom (ti, mt_count);
 		break;
 	case MTERASE:
-		cqr = tape->discipline->mterase (tape, mt_count);
+		cqr = ti->discipline->mterase (ti, mt_count);
 		break;
 	case MTSETDENSITY:
-		cqr = tape->discipline->mtsetdensity (tape, mt_count);
+		cqr = ti->discipline->mtsetdensity (ti, mt_count);
 		break;
 	case MTSEEK:
-		cqr = tape->discipline->mtseek (tape, mt_count);
+		cqr = ti->discipline->mtseek (ti, mt_count);
 		break;
 	case MTSETDRVBUFFER:
-		cqr = tape->discipline->mtsetdrvbuffer (tape, mt_count);
+		cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count);
 		break;
 	case MTLOCK:
-		cqr = tape->discipline->mtsetdrvbuffer (tape, mt_count);
+		cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count);
 		break;
 	case MTUNLOCK:
-		cqr = tape->discipline->mtsetdrvbuffer (tape, mt_count);
+		cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count);
 		break;
 	case MTLOAD:
-		cqr = tape->discipline->mtload (tape, mt_count);
-		break;
+		cqr = ti->discipline->mtload (ti, mt_count);
+		if (cqr!=NULL) break; // if backend driver has an load function ->use it
+		// if no medium is in, wait until it gets inserted
+		if (ti->medium_is_unloaded) {
+		    wait_event_interruptible (ti->wq,ti->medium_is_unloaded==0);
+		}
+		return 0;
 	case MTCOMPRESSION:
-		cqr = tape->discipline->mtcompression (tape, mt_count);
+		cqr = ti->discipline->mtcompression (ti, mt_count);
 		break;
 	case MTSETPART:
-		cqr = tape->discipline->mtsetpart (tape, mt_count);
+		cqr = ti->discipline->mtsetpart (ti, mt_count);
 		break;
 	case MTMKPART:
-		cqr = tape->discipline->mtmkpart (tape, mt_count);
+		cqr = ti->discipline->mtmkpart (ti, mt_count);
 		break;
 	case MTTELL:		// return number of block relative to current file
 
-		cqr = tape->discipline->mttell (tape, mt_count);
+		cqr = ti->discipline->mttell (ti, mt_count);
 		break;
 	case MTSETBLK:
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tape->block_size = mt_count;
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		ti->block_size = mt_count;
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 #ifdef TAPE_DEBUG
 		debug_text_event (tape_debug_area,6,"c:setblk:");
 	        debug_int_event (tape_debug_area,6,mt_count);
 #endif
 		return 0;
 	case MTRESET:
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tape->kernbuf = tape->userbuf = NULL;
-		tapestate_set (tape, TS_IDLE);
-		tape->block_size = 0;
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		ti->kernbuf = ti->userbuf = NULL;
+		tapestate_set (ti, TS_IDLE);
+		ti->block_size = 0;
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 #ifdef TAPE_DEBUG
 		debug_text_event (tape_debug_area,6,"c:devreset:");
-		debug_int_event (tape_debug_area,6,tape->blk_minor);
+		debug_int_event (tape_debug_area,6,ti->blk_minor);
 #endif
 		return 0;
 	default:
@@ -469,43 +474,49 @@
 #endif
 		return -ENOSPC;
 	}
-	s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-	tape->cqr = cqr;
-	tape->wanna_wakeup=0;
-	rc = do_IO (tape->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
-	s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-	wait_event_interruptible (tape->wq,tape->wanna_wakeup);
-	tape->cqr = NULL;
-	if (tape->kernbuf != NULL) {
-		kfree (tape->kernbuf);
-		tape->kernbuf = NULL;
+	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+	ti->cqr = cqr;
+	ti->wanna_wakeup=0;
+	rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
+	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+	wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+	ti->cqr = NULL;
+	if (ti->kernbuf != NULL) {
+		kfree (ti->kernbuf);
+		ti->kernbuf = NULL;
 	}
 	tape_free_request (cqr);
+	// if medium was unloaded, update the corresponding variable.
+	switch (mt_op) {
+	case MTOFFL:
+	case MTUNLOAD:
+	    ti->medium_is_unloaded=1;
+	}
 	if (signal_pending (current)) {
-		tapestate_set (tape, TS_IDLE);
+		tapestate_set (ti, TS_IDLE);
 		return -ERESTARTSYS;
 	}
-	s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-	if (((mt_op == MTEOM) || (mt_op == MTRETEN)) && (tapestate_get (tape) == TS_FAILED))
-		tapestate_set (tape, TS_DONE);
-	if (tapestate_get (tape) == TS_FAILED) {
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-		return tape->rc;
-	}
-	if (tapestate_get (tape) == TS_NOT_OPER) {
-	    tape->blk_minor=tape->rew_minor=tape->nor_minor=-1;
-	    tape->devinfo.irq=-1;
-	    s390irq_spin_unlock_irqrestore (tape->devinfo.irq,lockflags);
+	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+	if (((mt_op == MTEOM) || (mt_op == MTRETEN)) && (tapestate_get (ti) == TS_FAILED))
+		tapestate_set (ti, TS_DONE);
+	if (tapestate_get (ti) == TS_FAILED) {
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+		return ti->rc;
+	}
+	if (tapestate_get (ti) == TS_NOT_OPER) {
+	    ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
+	    ti->devinfo.irq=-1;
+	    s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
 	    return -ENODEV;
 	}
-	if (tapestate_get (tape) != TS_DONE) {
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+	if (tapestate_get (ti) != TS_DONE) {
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 		return -EIO;
 	}
-	tapestate_set (tape, TS_IDLE);
-	s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+	tapestate_set (ti, TS_IDLE);
+	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 	switch (mt_op) {
 	case MTRETEN:		//need to rewind the tape after moving to eom
 
@@ -531,7 +542,7 @@
 	    unsigned int cmd, unsigned long arg)
 {
 	long lockflags;
-	tape_info_t *tape;
+	tape_info_t *ti;
 	ccw_req_t *cqr;
 	struct mtop op;		/* structure for MTIOCTOP */
 	struct mtpos pos;	/* structure for MTIOCPOS */
@@ -541,19 +552,19 @@
 #ifdef TAPE_DEBUG
 	debug_text_event (tape_debug_area,6,"c:ioct");
 #endif
-	tape = first_tape_info;
-	while ((tape != NULL) &&
-	       (tape->rew_minor != MINOR (inode->i_rdev)) &&
-	       (tape->nor_minor != MINOR (inode->i_rdev)))
-		tape = (tape_info_t *) tape->next;
-	if (tape == NULL) {
+	ti = first_tape_info;
+	while ((ti != NULL) &&
+	       (ti->rew_minor != MINOR (inode->i_rdev)) &&
+	       (ti->nor_minor != MINOR (inode->i_rdev)))
+		ti = (tape_info_t *) ti->next;
+	if (ti == NULL) {
 #ifdef TAPE_DEBUG
 	        debug_text_event (tape_debug_area,6,"c:nodev");
 #endif
 		return -ENODEV;
 	}
 	// check for discipline ioctl overloading
-	if ((rc = tape->discipline->discipline_ioctl_overload (inode, filp, cmd, arg))
+	if ((rc = ti->discipline->discipline_ioctl_overload (inode, filp, cmd, arg))
 	    != -EINVAL) {
 #ifdef TAPE_DEBUG
 	    debug_text_event (tape_debug_area,6,"c:ioverloa");
@@ -563,71 +574,72 @@
 
 	switch (cmd) {
 	case MTIOCTOP:		/* tape op command */
-		if (copy_from_user (&op, (char *) arg, sizeof (struct mtop)))
+		if (copy_from_user (&op, (char *) arg, sizeof (struct mtop))) {
 			 return -EFAULT;
+		}
 		return (tape_mtioctop (filp, op.mt_op, op.mt_count));
 	case MTIOCPOS:		/* query tape position */
-		cqr = tape->discipline->mttell (tape, 0);
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tape->cqr = cqr;
-		tape->wanna_wakeup=0;
-		do_IO (tape->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-		wait_event_interruptible (tape->wq,tape->wanna_wakeup);
-		pos.mt_blkno = tape->rc;
-		tape->cqr = NULL;
-		if (tape->kernbuf != NULL) {
-			kfree (tape->kernbuf);
-			tape->kernbuf = NULL;
+		cqr = ti->discipline->mttell (ti, 0);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		ti->cqr = cqr;
+		ti->wanna_wakeup=0;
+		do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+		wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+		pos.mt_blkno = ti->rc;
+		ti->cqr = NULL;
+		if (ti->kernbuf != NULL) {
+			kfree (ti->kernbuf);
+			ti->kernbuf = NULL;
 		}
 		tape_free_request (cqr);
 		if (signal_pending (current)) {
-			tapestate_set (tape, TS_IDLE);
+			tapestate_set (ti, TS_IDLE);
 			return -ERESTARTSYS;
 		}
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 		if (copy_to_user ((char *) arg, &pos, sizeof (struct mtpos)))
 			 return -EFAULT;
 		return 0;
 	case MTIOCGET:
-		get.mt_erreg = tape->rc;
-		cqr = tape->discipline->mttell (tape, 0);
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tape->cqr = cqr;
-		tape->wanna_wakeup=0;
-		do_IO (tape->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
-		wait_event_interruptible (tape->wq,tape->wanna_wakeup);
-		get.mt_blkno = tape->rc;
+		get.mt_erreg = ti->rc;
+		cqr = ti->discipline->mttell (ti, 0);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		ti->cqr = cqr;
+		ti->wanna_wakeup=0;
+		do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
+		wait_event_interruptible (ti->wq,ti->wanna_wakeup);
+		get.mt_blkno = ti->rc;
 		get.mt_fileno = 0;
 		get.mt_type = MT_ISUNKNOWN;
-		get.mt_resid = tape->devstat.rescnt;
-		get.mt_dsreg = tape->devstat.ii.sense.data[3];
+		get.mt_resid = ti->devstat.rescnt;
+		get.mt_dsreg = ti->devstat.ii.sense.data[3];
 		get.mt_gstat = 0;
-		if (tape->devstat.ii.sense.data[1] & 0x08)
+		if (ti->devstat.ii.sense.data[1] & 0x08)
 			get.mt_gstat &= GMT_BOT (1);	// BOT
 
-		if (tape->devstat.ii.sense.data[1] & 0x02)
+		if (ti->devstat.ii.sense.data[1] & 0x02)
 			get.mt_gstat &= GMT_WR_PROT (1);	// write protected
 
-		if (tape->devstat.ii.sense.data[1] & 0x40)
+		if (ti->devstat.ii.sense.data[1] & 0x40)
 			get.mt_gstat &= GMT_ONLINE (1);		//drive online
 
-		tape->cqr = NULL;
-		if (tape->kernbuf != NULL) {
-			kfree (tape->kernbuf);
-			tape->kernbuf = NULL;
+		ti->cqr = NULL;
+		if (ti->kernbuf != NULL) {
+			kfree (ti->kernbuf);
+			ti->kernbuf = NULL;
 		}
 		tape_free_request (cqr);
 		if (signal_pending (current)) {
-			tapestate_set (tape, TS_IDLE);
+			tapestate_set (ti, TS_IDLE);
 			return -ERESTARTSYS;
 		}
-		s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
-		tapestate_set (tape, TS_IDLE);
-		s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
+		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
+		tapestate_set (ti, TS_IDLE);
+		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
 		if (copy_to_user ((char *) arg, &get, sizeof (struct mtget)))
 			 return -EFAULT;
 		return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)