patch-2.4.4 linux/drivers/s390/char/tapeblock.c
Next file: linux/drivers/s390/char/tapeblock.h
Previous file: linux/drivers/s390/char/tape34xx.h
Back to the patch index
Back to the overall index
- Lines: 241
- Date:
Thu Apr 12 12:16:35 2001
- Orig file:
v2.4.3/linux/drivers/s390/char/tapeblock.c
- Orig date:
Tue Feb 13 14:13:44 2001
diff -u --recursive --new-file v2.4.3/linux/drivers/s390/char/tapeblock.c linux/drivers/s390/char/tapeblock.c
@@ -4,15 +4,17 @@
* drivers/s390/char/tapeblock.c
* block device frontend for tape device driver
*
- * S390 version
- * Copyright (C) 2000 IBM Corporation
- * Author(s): Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ * S390 and zSeries version
+ * Copyright (C) 2001 IBM Corporation
+ * Author(s): Carsten Otte <cotte@de.ibm.com>
+ * Tuan Ngo-Anh <ngoanh@de.ibm.com>
+ *
*
- * UNDER CONSTRUCTION: Work in progress...:-)
****************************************************************************
*/
#include "tapedefs.h"
+#include <linux/config.h>
#include <linux/blkdev.h>
#include <linux/blk.h>
#include <linux/version.h>
@@ -22,6 +24,7 @@
#include <asm/s390dyn.h>
#include <linux/compatmac.h>
#ifdef MODULE
+#define __NO_VERSION__
#include <linux/module.h>
#endif
#include "tape.h"
@@ -51,6 +54,21 @@
static request_queue_t* tapeblock_getqueue (kdev_t kdev);
+#ifdef CONFIG_DEVFS_FS
+void
+tapeblock_mkdevfstree (tape_info_t* tape) {
+ tape->devfs_block_dir=devfs_mk_dir (tape->devfs_dir, "block", tape);
+ tape->devfs_disc=devfs_register(tape->devfs_block_dir, "disc",DEVFS_FL_DEFAULT,
+ tapeblock_major, tape->blk_minor,
+ TAPEBLOCK_DEFAULTMODE, &tapeblock_fops, tape);
+}
+
+void
+tapeblock_rmdevfstree (tape_info_t* tape) {
+ devfs_unregister(tape->devfs_disc);
+ devfs_unregister(tape->devfs_block_dir);
+}
+#endif
void
tapeblock_setup(tape_info_t* tape) {
@@ -59,9 +77,12 @@
hardsect_size[tapeblock_major][tape->blk_minor]=512;
blk_init_queue (&tape->request_queue, tape_request_fn);
blk_queue_headactive (&tape->request_queue, 0);
+#ifdef CONFIG_DEVFS_FS
+ tapeblock_mkdevfstree(tape);
+#endif
}
-void
+int
tapeblock_init(void) {
int result;
tape_frontend_t* blkfront,*temp;
@@ -69,7 +90,11 @@
tape_init();
/* Register the tape major number to the kernel */
+#ifdef CONFIG_DEVFS_FS
+ result = devfs_register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
+#else
result = register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
+#endif
if (result < 0) {
PRINT_WARN(KERN_ERR "tape: can't get major %d for block device\n", tapeblock_major);
panic ("cannot get major number for tape block device");
@@ -89,6 +114,10 @@
blkfront = kmalloc(sizeof(tape_frontend_t),GFP_KERNEL);
if (blkfront==NULL) panic ("no mem for tape block device structure");
blkfront->device_setup=tapeblock_setup;
+#ifdef CONFIG_DEVFS_FS
+ blkfront->mkdevfstree = tapeblock_mkdevfstree;
+ blkfront->rmdevfstree = tapeblock_rmdevfstree;
+#endif
blkfront->next=NULL;
if (first_frontend==NULL) {
first_frontend=blkfront;
@@ -103,6 +132,7 @@
tapeblock_setup(tape);
tape=tape->next;
}
+ return 0;
}
@@ -111,7 +141,7 @@
unregister_blkdev(tapeblock_major, "tBLK");
}
-static int
+int
tapeblock_open(struct inode *inode, struct file *filp) {
tape_info_t *ti;
kdev_t dev;
@@ -140,7 +170,7 @@
ti->position=-1;
s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
- rc=tapeblock_mediumdetect(ti);
+ rc=tapeblock_mediumdetect(ti);
if (rc) return rc; // in case of errors, we don't have a size of the medium
dev = MKDEV (tapeblock_major, MINOR (inode->i_rdev)); /* Get the device */
s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
@@ -155,12 +185,10 @@
return 0;
}
-static int
+int
tapeblock_release(struct inode *inode, struct file *filp) {
long lockflags;
tape_info_t *ti,*lastti;
-
- inode = filp->f_dentry->d_inode;
ti = first_tape_info;
while ((ti != NULL) && (ti->blk_minor != MINOR (inode->i_rdev)))
ti = (tape_info_t *) ti->next;
@@ -177,7 +205,7 @@
}
if ((ti == NULL) || (tapestate_get (ti) != TS_IDLE)) {
#ifdef TAPE_DEBUG
- debug_text_event (tape_debug_area,6,"b:notidle!");
+ debug_text_event (tape_debug_area,3,"b:notidle!");
#endif
return -ENXIO; /* error in tape_release */
}
@@ -191,6 +219,7 @@
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif /* MODULE */
+ invalidate_buffers(inode->i_rdev);
return 0;
}
@@ -226,7 +255,7 @@
tape->discipline->free_bread(tape->cqr,tape);
tape->cqr=NULL;
tape->current_request=NULL;
- tapestate_set(tape,TS_IDLE);
+ if (tapestate_get(tape)!=TS_NOT_OPER) tapestate_set(tape,TS_IDLE);
return;
}
@@ -258,7 +287,17 @@
tapeblock_end_request (tape); // check state, inform user, free mem, dev=idl
}
if (tape->cqr!=NULL) BUG(); // tape should be idle now, request should be freed!
- if (list_empty(&tape->request_queue.queue_head)) { // nothing more to do ;)
+ if (tapestate_get (tape) == TS_NOT_OPER) {
+ tape->blk_minor=tape->rew_minor=tape->nor_minor=-1;
+ tape->devinfo.irq=-1;
+ return;
+ }
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+ if (list_empty (&tape->request_queue.queue_head)) {
+#else
+ if (tape->request_queue==NULL) {
+#endif
+ // nothing more to do or device has dissapeared;)
#ifdef TAPE_DEBUG
debug_text_event (tape_debug_area,6,"b:Qempty");
#endif
@@ -342,8 +381,9 @@
if (atomic_compare_and_swap(0,1,&tape->bh_scheduled)) {
return;
}
-
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
INIT_LIST_HEAD(&tape->bh_tq.list);
+#endif
tape->bh_tq.sync = 0;
tape->bh_tq.routine = (void *) (void *) run_tapeblock_exec_IO;
tape->bh_tq.data = tape;
@@ -376,13 +416,14 @@
return NULL;
}
-static int tapeblock_mediumdetect(tape_info_t* tape) {
- ccw_req_t* cqr;
+int tapeblock_mediumdetect(tape_info_t* tape) {
+ ccw_req_t* cqr;
int losize=1,hisize=1,rc;
long lockflags;
#ifdef TAPE_DEBUG
debug_text_event (tape_debug_area,3,"b:medDet");
#endif
+ PRINT_WARN("Detecting media size. This will take _long_, so get yourself a coffee...\n");
while (1) { //is interruped by break
hisize=hisize << 1; // try twice the size tested before
cqr=tape->discipline->mtseek (tape, hisize);
@@ -415,6 +456,12 @@
s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
break;
}
+ 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);
+ return -ENODEV;
+ }
if (tapestate_get (tape) != TS_DONE) {
tapestate_set (tape, TS_IDLE);
s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
@@ -449,6 +496,12 @@
s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
return -EIO;
}
+ 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);
+ return -ENODEV;
+ }
if (tapestate_get (tape) != TS_DONE) {
tapestate_set (tape, TS_IDLE);
s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
@@ -482,6 +535,12 @@
return -ERESTARTSYS;
}
s390irq_spin_lock_irqsave (tape->devinfo.irq, lockflags);
+ 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);
+ return -ENODEV;
+ }
if (tapestate_get (tape) == TS_FAILED) {
tapestate_set (tape, TS_IDLE);
s390irq_spin_unlock_irqrestore (tape->devinfo.irq, lockflags);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)