Skip to contentSkip to conversation

s390 (5/8): tape driver fixes.

PATCH New Martin Schwidefsky 1 participant 1 message Oct 21, 2003 s390

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 s390 (5/8): tape driver fixes.

- Fix device reference counting.
- Fix online-offline-online cycle.
- Add module license gpl.

diffstat:

 drivers/s390/char/tape.h       |    3 -
 drivers/s390/char/tape_34xx.c  |    9 +--
 drivers/s390/char/tape_block.c |   18 +++++--
 drivers/s390/char/tape_char.c  |    7 +-
 drivers/s390/char/tape_core.c  |   98 +++++++++++++++++++++--------------------
 5 files changed, 73 insertions(+), 62 deletions(-)
drivers/s390/char/tape.h +2 -1
diff -urN linux-2.6/drivers/s390/char/tape.h linux-2.6-s390/drivers/s390/char/tape.h
@@ -246,7 +246,8 @@
 extern int tape_generic_remove(struct ccw_device *);
 
 extern struct tape_device *tape_get_device(int devindex);
-extern void tape_put_device(struct tape_device *);
+extern struct tape_device *tape_get_device_reference(struct tape_device *);
+extern struct tape_device *tape_put_device(struct tape_device *);
 
 /* Externals from tape_char.c */
 extern int tapechar_init(void);
drivers/s390/char/tape_34xx.c +4 -5
diff -urN linux-2.6/drivers/s390/char/tape_34xx.c linux-2.6-s390/drivers/s390/char/tape_34xx.c
@@ -104,7 +104,7 @@
 			DBF_EVENT(3, "T34XX: internal error: unknown work\n");
 	}
 
-	tape_put_device(p->device);
+	p->device = tape_put_device(p->device);
 	kfree(p);
 }
 
@@ -123,8 +123,7 @@
 	memset(p, 0, sizeof(*p));
 	INIT_WORK(&p->work, tape_34xx_work_handler, p);
 
-	atomic_inc(&device->ref_count);
-	p->device = device;
+	p->device = tape_get_device_reference(device);
 	p->op     = op;
 
 	schedule_work(&p->work);
@@ -1041,7 +1040,7 @@
 {
 	int rc;
 
-	DBF_EVENT(3, "34xx init: $Revision: 1.8 $\n");
+	DBF_EVENT(3, "34xx init: $Revision: 1.9 $\n");
 	/* Register driver for 3480/3490 tapes. */
 	rc = ccw_driver_register(&tape_34xx_driver);
 	if (rc)
@@ -1060,7 +1059,7 @@
 MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
 MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
 MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
-		   "device driver ($Revision: 1.8 $)");
+		   "device driver ($Revision: 1.9 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_34xx_init);
drivers/s390/char/tape_block.c +12 -6
diff -urN linux-2.6/drivers/s390/char/tape_block.c linux-2.6-s390/drivers/s390/char/tape_block.c
@@ -214,7 +214,8 @@
 	if (!disk)
 		return -ENOMEM;
 
-	tasklet_init(&d->tasklet, tapeblock_tasklet, (unsigned long)device);
+	tasklet_init(&d->tasklet, tapeblock_tasklet,
+		(unsigned long) tape_get_device_reference(device));
 
 	spin_lock_init(&d->request_queue_lock);
 	q = blk_init_queue(tapeblock_request_fn, &d->request_queue_lock);
@@ -239,7 +240,7 @@
 	disk->major = tapeblock_major;
 	disk->first_minor = device->first_minor;
 	disk->fops = &tapeblock_fops;
-	disk->private_data = device;
+	disk->private_data = tape_get_device_reference(device);
 	disk->queue = q;
 	//set_capacity(disk, size);
 
@@ -262,10 +263,12 @@
 	struct tape_blk_data *d = &device->blk_data;
 
 	del_gendisk(d->disk);
+	d->disk->private_data = tape_put_device(d->disk->private_data);
 	put_disk(d->disk);
 	blk_cleanup_queue(d->request_queue);
 
 	tasklet_kill(&d->tasklet);
+	tape_put_device(device);
 }
 
 /*
@@ -301,9 +304,9 @@
 static int
 tapeblock_open(struct inode *inode, struct file *filp)
 {
-	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct tape_device *device = disk->private_data;
-	int rc;
+	struct gendisk *	disk;
+	struct tape_device *	device;
+	int			rc;
 
 	/*
 	 * FIXME: this new tapeblock_open function is from 2.5.69.
@@ -311,6 +314,9 @@
 	 * pointer from disk->private_data. It is stored in 
 	 * tapeblock_setup_device but WITHOUT proper ref-counting.
 	 */
+	disk   = inode->i_bdev->bd_disk;
+	device = tape_get_device_reference(disk->private_data);
+
 	rc = tape_open(device);
 	if (rc)
 		goto put_device;
@@ -341,8 +347,8 @@
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct tape_device *device = disk->private_data;
 
-	tape_release(device);
 	tape_unassign(device);
+	tape_release(device);
 	tape_put_device(device);
 
 	return 0;
drivers/s390/char/tape_char.c +4 -3
diff -urN linux-2.6/drivers/s390/char/tape_char.c linux-2.6-s390/drivers/s390/char/tape_char.c
@@ -267,8 +267,9 @@
 {
 	struct tape_device *device;
 
-	device = (struct tape_device *) filp->private_data;
 	DBF_EVENT(6, "TCHAR:release: %x\n", iminor(inode));
+	device = (struct tape_device *) filp->private_data;
+
 #if 0
 	// FIXME: this is broken. Either MTWEOF/MTWEOF/MTBSR is done
 	// EVERYTIME the user switches from write to something different
@@ -287,9 +288,9 @@
 		device->char_data.idal_buf = NULL;
 	}
 	device->char_data.block_size = 0;
-	tape_release(device);
 	tape_unassign(device);
-	tape_put_device(device);
+	tape_release(device);
+	filp->private_data = tape_put_device(device);
 	return 0;
 }
 
drivers/s390/char/tape_core.c +51 -47

182 lines not on this page · raw message