public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Updated osst driver for 2.6.x
@ 2003-12-23 17:43 Willem Riede
  2003-12-23 19:26 ` Christoph Hellwig
  0 siblings, 1 reply; 4+ messages in thread
From: Willem Riede @ 2003-12-23 17:43 UTC (permalink / raw)
  To: linux-scsi

Brings 2.6.x version of osst up to par with the 2.4.y version.
Tested against released 2.6.0 kernel.

Changes from what's in the kernel tree today:

- Fixes bug that files shorter than one 32K frame don't get written.
- Supports a proc file for each drive (/proc/scsi/osst/osstX) which provides
  ADRversion_major.minor linux_media_version first_data_ppos eod_frame_ppos filemrk_cnt
- Fix a memory alloc/free mismatch that could have made your kernel unstable after rmmod osst.
- Fix a number of tape (re)positioning bugs around filemarks that affected Amanda, Arkeia and
  Storix backup software.
- Rationalize module parameters.
- Fix time-out skipping to EOD
- Write FM+EOD+Header-update when file write terminated by ioctl
- Follow standard Unix behavior for read at EOD (return zero bytes read twice then error)
- Implement SETBLK ioctl (allowed before first write only)


---------- start patch -------------
--- drivers/scsi/osst.c.orig	2003-12-17 21:58:49.000000000 -0500
+++ drivers/scsi/osst.c	2003-12-23 09:31:52.086888871 -0500
@@ -16,15 +16,15 @@
   Copyright 1992 - 2002 Kai Makisara / Willem Riede
 	 email Kai.Makisara@metla.fi / osst@riede.org
 
-  $Header: /home/cvsroot/Driver/osst.c,v 1.68 2002/12/23 16:33:36 riede Exp $
+  $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
   Some small formal changes - aeb, 950809
 */
 
-static const char * cvsid = "$Id: osst.c,v 1.68 2002/12/23 16:33:36 riede Exp $";
-const char * osst_version = "0.99.0";
+static const char * cvsid = "$Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $";
+const char * osst_version = "0.99.1";
 
 /* The "failure to reconnect" firmware bug */
 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
@@ -36,6 +36,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -846,9 +847,6 @@
 	/* TODO: Error handling */
 	if (STp->poll)
 		retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);
-#if 0// DEBUG
-	printk ("osst_read: wait for frame returned %i\n", retval);
-#endif
 	
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = READ_6;
@@ -1279,14 +1277,14 @@
 	Scsi_Request  * SRpnt = * aSRpnt;
 	unsigned char * buffer, * p;
 	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int             flag, new_frame, i;
-	int             nframes          = STp->cur_frames;
-	int             blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
-	int             frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
+	int		flag, new_frame, i;
+	int		nframes          = STp->cur_frames;
+	int		blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+	int		frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
 						- (nframes + pending - 1);
-	int             logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
+	int		logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
 						- (nframes + pending - 1) * blks_per_frame;
-	char          * name             = tape_name(STp);
+	char	      * name             = tape_name(STp);
 	unsigned long	startwait        = jiffies;
 #if DEBUG
 	int		dbg              = debugging;
@@ -1472,7 +1470,7 @@
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	Scsi_Request  * SRpnt;
-	char          * name      = tape_name(STp);
+	char	      * name      = tape_name(STp);
 	int		expected  = 0;
 	int		attempts  = 1000 / skip;
 	int		flag      = 1;
@@ -2189,6 +2187,7 @@
 	if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
 		if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
 			printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
+		osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
 		if (osst_initiate_read (STp, aSRpnt)) {
 			printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
 			return 0;
@@ -2817,7 +2816,29 @@
 	return result;
 }
 
+static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT)
+{
+	ST_partstat * STps = &(STp->ps[STp->partition]);
+	int result = 0;
+
+	if (STp->write_type != OS_WRITE_NEW_MARK) {
+		/* true unless the user wrote the filemark for us */
+		result = osst_flush_drive_buffer(STp, aSRpnt);
+		if (result < 0) goto out;
+		result = osst_write_filemark(STp, aSRpnt);
+		if (result < 0) goto out;
+
+		if (STps->drv_file >= 0)
+			STps->drv_file++ ;
+		STps->drv_block = 0;
+	}
+	result = osst_write_eod(STp, aSRpnt);
+	osst_write_header(STp, aSRpnt, leave_at_EOT);
 
+	STps->eof = ST_FM;
+out:
+	return result;
+}
 \f

 /* osst versions of st functions - augmented and stripped to suit OnStream only */
 
@@ -2935,7 +2956,7 @@
 					result = (-EIO);
 				}
 			}
-			STps->drv_block = (-1);
+			STps->drv_block = (-1);		/* FIXME - even if write recovery succeeds? */
 		}
 		else {
 			STp->first_frame_position++;
@@ -3628,7 +3649,7 @@
 	/* Change the eof state if no data from tape or buffer */
 	if (total == 0) {
 		if (STps->eof == ST_FM_HIT) {
-			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
+			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
 			STps->drv_block = 0;
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
@@ -4037,8 +4058,8 @@
 		if (debugging)
 		   printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
 #endif
-		osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
-	if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) {
+		if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
+			    (osst_get_logical_frame(STp, &SRpnt, -1, 0)               < 0)) {
 		   ioctl_result = -EIO;
 		   goto os_bypass;
 		}
@@ -4076,6 +4097,23 @@
 		break;
 
 	 case MTSETBLK:           /* Set block length */
+		 if ((STps->drv_block == 0 )			  &&
+		     !STp->dirty				  &&
+		     ((STp->buffer)->buffer_bytes == 0)		  &&
+		     ((arg & MT_ST_BLKSIZE_MASK) >= 512 )	  && 
+		     ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
+		     !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))  ) {
+			 /*
+			  * Only allowed to change the block size if you opened the
+			  * device at the beginning of a file before writing anything.
+			  * Note, that when reading, changing block_size is futile,
+			  * as the size used when writing overrides it.
+			  */
+			 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
+			 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
+					   name, STp->block_size);
+			 return 0;
+		 }
 	 case MTSETDENSITY:       /* Set tape density */
 	 case MTSETDRVBUFFER:     /* Set drive buffering */
 	 case SET_DENS_AND_BLK:   /* Set density and block size */
@@ -4083,11 +4121,11 @@
 		 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
 			 return (-EIO);       /* Not allowed if data in buffer */
 		 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
-		   (arg & MT_ST_BLKSIZE_MASK) != 0 &&
-		   ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
-		    (arg & MT_ST_BLKSIZE_MASK) > STp->max_block ||
-		    (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) {
-			 printk(KERN_WARNING "%s:W: Illegal block size.\n", name);
+		     (arg & MT_ST_BLKSIZE_MASK) != 0                    &&
+		     (arg & MT_ST_BLKSIZE_MASK) != STp->block_size       ) {
+			 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
+						name, (int)(arg & MT_ST_BLKSIZE_MASK),
+						(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
 			 return (-EINVAL);
 		 }
 		 return 0;  /* FIXME silently ignore if block size didn't change */
@@ -4592,22 +4630,7 @@
 					       name, STp->nbr_waits, STp->nbr_finished);
 		}
 #endif
-		if (STp->write_type != OS_WRITE_NEW_MARK) {
-			/* true unless the user wrote the filemark for us */
-			result = osst_flush_drive_buffer(STp, &SRpnt);
-			if (result < 0) goto out;
-			result = osst_write_filemark(STp, &SRpnt);
-			if (result < 0) goto out;
-
-			if (STps->drv_file >= 0)
-				STps->drv_file++ ;
-			STps->drv_block = 0;
-		}
-		result = osst_write_eod(STp, &SRpnt);
-		osst_write_header(STp, &SRpnt, !(STp->rew_at_close));
-
-		STps->eof = ST_FM;
-
+		result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
 #if DEBUG
 		if (debugging)
 			printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
@@ -4618,7 +4641,7 @@
 		STps = &(STp->ps[STp->partition]);
 		if (!STm->sysv || STps->rw != ST_READING) {
 			if (STp->can_bsr)
-		result = osst_flush_buffer(STp, &SRpnt, 0);	/* this is the default path */
+				result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
 			else if (STps->eof == ST_FM_HIT) {
 				result = cross_eof(STp, &SRpnt, FALSE);
 					if (result) {
@@ -4633,7 +4656,7 @@
 		}
 		else if ((STps->eof == ST_NOEOF &&
 			  !(result = cross_eof(STp, &SRpnt, TRUE))) ||
-			  STps->eof == ST_FM_HIT) {
+			 STps->eof == ST_FM_HIT) {
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
 			STps->drv_block = 0;
@@ -4736,6 +4759,7 @@
 #endif
 	if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
 		struct mtop mtc;
+		int    auto_weof = 0;
 
 		if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
 			retval = (-EINVAL);
@@ -4812,10 +4836,41 @@
 			STp->device->was_reset = 0;
 		}
 
-		if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM &&
-		    mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETBLK &&
-		    mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
-			STps->rw = ST_IDLE;  /* Prevent automatic WEOF and fsf */
+		if (mtc.mt_op != MTCOMPRESSION  && mtc.mt_op != MTLOCK         &&
+		    mtc.mt_op != MTNOP          && mtc.mt_op != MTSETBLK       &&
+		    mtc.mt_op != MTSETDENSITY   && mtc.mt_op != MTSETDRVBUFFER && 
+		    mtc.mt_op != MTMKPART       && mtc.mt_op != MTSETPART      &&
+		    mtc.mt_op != MTWEOF         && mtc.mt_op != MTWSM           ) {
+
+			/*
+			 * The user tells us to move to another position on the tape.
+			 * If we were appending to the tape content, that would leave
+			 * the tape without proper end, in that case write EOD and
+			 * update the header to reflect its position.
+			 */
+#if DEBUG
+			printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
+					STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
+					STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
+					STp->logical_blk_num, STps->drv_file, STps->drv_block );
+#endif
+			if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
+				auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
+							!(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
+				i = osst_write_trailer(STp, &SRpnt,
+							!(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
+#if DEBUG
+				printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
+						name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
+						STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
+#endif
+				if (i < 0) {
+					retval = i;
+					goto out;
+				}
+			}
+			STps->rw = ST_IDLE;
+		}
 
 		if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
 			do_door_lock(STp, 0);  /* Ignore result! */
@@ -4873,11 +4928,15 @@
 			retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
 			goto out;
 		}
-			
+
+		if (auto_weof)
+			cross_eof(STp, &SRpnt, FALSE);
+
 		if (mtc.mt_op == MTCOMPRESSION)
-			retval = -EINVAL /*osst_compression(STp, (mtc.mt_count & 1))*/;
+			retval = -EINVAL;       /* OnStream drives don't have compression hardware */
 		else
-
+			/* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
+			 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
 			retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
 		goto out;
 	}
@@ -5360,6 +5419,63 @@
 	return 0;
 }
 
+#ifdef CONFIG_SCSI_PROC_FS
+/*
+ * /proc support for accessing ADR header information
+ */
+static struct proc_dir_entry * osst_proc_dir = NULL;
+static char   osst_proc_dirname[] = "scsi/osst";
+
+static int osst_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int l = 0;
+	OS_Scsi_Tape * STp = (OS_Scsi_Tape *) data;
+
+	if (!osst_proc_dir) return 0;
+
+	if (STp->header_ok && STp->linux_media)
+		l = sprintf(page, "%d.%d LIN%d %8d %8d %8d \n",
+				  STp->header_cache->major_rev,
+				  STp->header_cache->minor_rev,
+				  STp->linux_media_version,
+				  STp->first_data_ppos,
+				  STp->eod_frame_ppos,
+				  STp->filemark_cnt );
+	return l;
+}
+
+static void osst_proc_init(void)
+{
+	osst_proc_dir = create_proc_entry(osst_proc_dirname, S_IFDIR | S_IRUGO | S_IXUGO, NULL);
+	osst_proc_dir->owner = THIS_MODULE;
+}
+
+static void osst_proc_create(OS_Scsi_Tape * STp, char * name)
+{
+	struct proc_dir_entry * p_entry;
+
+	if (!osst_proc_dir) return;
+
+	p_entry = create_proc_read_entry(name, 0444, osst_proc_dir, osst_proc_read, (void *) STp);
+	p_entry->owner = THIS_MODULE;
+}
+
+static void osst_proc_destroy(char * name)
+{
+	if (!osst_proc_dir) return; 
+
+	remove_proc_entry(name, osst_proc_dir);
+}
+
+static void osst_proc_cleanup(void)
+{
+	if (!osst_proc_dir) return;
+
+	remove_proc_entry(osst_proc_dirname, NULL);
+	osst_proc_dir = NULL;
+}
+#endif
+
 /*
  * osst startup / cleanup code
  */
@@ -5514,6 +5630,9 @@
 	}
 	drive->number = devfs_register_tape(SDp->devfs_name);
 
+#ifdef CONFIG_SCSI_PROC_FS
+	osst_proc_create(tpnt, tape_name(tpnt));
+#endif
 	printk(KERN_INFO
 		"osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as %s\n",
 		SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, tape_name(tpnt));
@@ -5527,37 +5646,40 @@
 
 static int osst_remove(struct device *dev)
 {
-  Scsi_Device * SDp = to_scsi_device(dev);
-  OS_Scsi_Tape * tpnt;
-  int i, mode;
-
-  if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
-	  return 0;
-
-  write_lock(&os_scsi_tapes_lock);
-  for(i=0; i < osst_max_dev; i++) {
-	if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
-		tpnt->device = NULL;
-		for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-			devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
-			devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
-		}
-		devfs_unregister_tape(tpnt->drive->number);
-		put_disk(tpnt->drive);
-		os_scsi_tapes[i] = NULL;
-		osst_nr_dev--;
-		write_unlock(&os_scsi_tapes_lock);
-		if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
-		if (tpnt->buffer) {
-			normalize_buffer(tpnt->buffer);
-			kfree(tpnt->buffer);
-		}
-		kfree(tpnt);
+	Scsi_Device  * SDp = to_scsi_device(dev);
+	OS_Scsi_Tape * tpnt;
+	int i, mode;
+
+	if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
 		return 0;
+
+	write_lock(&os_scsi_tapes_lock);
+	for(i=0; i < osst_max_dev; i++) {
+		if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
+#ifdef CONFIG_SCSI_PROC_FS
+			osst_proc_destroy(tape_name(tpnt));
+#endif
+			tpnt->device = NULL;
+			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+				devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
+				devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
+			}
+			devfs_unregister_tape(tpnt->drive->number);
+			put_disk(tpnt->drive);
+			os_scsi_tapes[i] = NULL;
+			osst_nr_dev--;
+			write_unlock(&os_scsi_tapes_lock);
+			if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
+			if (tpnt->buffer) {
+				normalize_buffer(tpnt->buffer);
+				kfree(tpnt->buffer);
+			}
+			kfree(tpnt);
+			return 0;
+		}
 	}
-  }
-  write_unlock(&os_scsi_tapes_lock);
-  return 0;
+	write_unlock(&os_scsi_tapes_lock);
+	return 0;
 }
 
 static int __init init_osst(void) 
@@ -5565,7 +5687,10 @@
 	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
 	validate_options();
-	
+
+#ifdef CONFIG_SCSI_PROC_FS
+	osst_proc_init();
+#endif
 	if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
 		printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
 		return 1;
@@ -5582,6 +5707,9 @@
 	scsi_unregister_driver(&osst_template.gendrv);
 	unregister_chrdev(OSST_MAJOR, "osst");
 
+#ifdef CONFIG_SCSI_PROC_FS
+	osst_proc_cleanup();
+#endif
 	if (os_scsi_tapes) {
 		for (i=0; i < osst_max_dev; ++i) {
 			if (!(STp = os_scsi_tapes[i])) continue;
--- drivers/scsi/osst.h.orig	2003-12-17 21:59:05.000000000 -0500
+++ drivers/scsi/osst.h	2003-12-14 14:34:38.000000000 -0500
@@ -1,12 +1,11 @@
 /*
- *	$Header: /home/cvsroot/Driver/osst.h,v 1.12 2001/10/11 00:30:15 riede Exp $
+ *	$Header: /cvsroot/osst/Driver/osst.h,v 1.14 2003/12/14 14:34:38 wriede Exp $
  */
 
 #include <asm/byteorder.h>
 #include <linux/config.h>
 #include <linux/completion.h>
 
-
 /*	FIXME - rename and use the following two types or delete them!
  *              and the types really should go to st.h anyway...
  *	INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C)
--- drivers/scsi/osst_options.h.orig	2003-12-17 22:00:00.000000000 -0500
+++ drivers/scsi/osst_options.h	2003-12-23 09:31:57.708132856 -0500
@@ -8,7 +8,7 @@
    Changed (and renamed) for OnStream SCSI drives garloff@suse.de
    2000-06-21
 
-   $Header: /home/cvsroot/Driver/osst_options.h,v 1.5 2001/01/07 22:19:15 riede Exp $
+   $Header: /cvsroot/osst/Driver/osst_options.h,v 1.6 2003/12/23 14:22:12 wriede Exp $
 */
 
 #ifndef _OSST_OPTIONS_H
----------  end patch  ---------


Comments? Thanks, Willem Riede,
osst maintaner.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Updated osst driver for 2.6.x
  2003-12-23 17:43 [PATCH] Updated osst driver for 2.6.x Willem Riede
@ 2003-12-23 19:26 ` Christoph Hellwig
  2003-12-23 21:29   ` Willem Riede
  0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2003-12-23 19:26 UTC (permalink / raw)
  To: Willem Riede; +Cc: linux-scsi

On Tue, Dec 23, 2003 at 12:43:20PM -0500, Willem Riede wrote:
> - Supports a proc file for each drive (/proc/scsi/osst/osstX) which provides
>   ADRversion_major.minor linux_media_version first_data_ppos eod_frame_ppos filemrk_cnt

Please don't.  This is exactly what sysfs is for.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Updated osst driver for 2.6.x
  2003-12-23 19:26 ` Christoph Hellwig
@ 2003-12-23 21:29   ` Willem Riede
  2003-12-28 13:25     ` Christoph Hellwig
  0 siblings, 1 reply; 4+ messages in thread
From: Willem Riede @ 2003-12-23 21:29 UTC (permalink / raw)
  To: linux-scsi

On 2003.12.23 14:26, Christoph Hellwig wrote:
> On Tue, Dec 23, 2003 at 12:43:20PM -0500, Willem Riede wrote:
> > - Supports a proc file for each drive (/proc/scsi/osst/osstX) which provides
> >   ADRversion_major.minor linux_media_version first_data_ppos eod_frame_ppos filemrk_cnt
> 
> Please don't.  This is exactly what sysfs is for.
> 
I was afraid you were going to say that :-)

The 2.4 version I have on the osst web site has had this /proc file for some time,
and I simply copied the logic over.

But if you don't want me to go there, I won't. I'll come back later with a sysfs
version that provides that info. One question: should each parameter be in its
own little file, or can I create them all on one line as I do now?

In the mean time, here is the patch without the offending pieces.

Is this OK? Thanks, Willem Riede.

--------  start patch  --------
--- drivers/scsi/osst.c.orig	2003-12-17 21:58:49.000000000 -0500
+++ drivers/scsi/osst.c	2003-12-23 09:31:52.086888871 -0500
@@ -16,15 +16,15 @@
   Copyright 1992 - 2002 Kai Makisara / Willem Riede
 	 email Kai.Makisara@metla.fi / osst@riede.org
 
-  $Header: /home/cvsroot/Driver/osst.c,v 1.68 2002/12/23 16:33:36 riede Exp $
+  $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
   Some small formal changes - aeb, 950809
 */
 
-static const char * cvsid = "$Id: osst.c,v 1.68 2002/12/23 16:33:36 riede Exp $";
-const char * osst_version = "0.99.0";
+static const char * cvsid = "$Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $";
+const char * osst_version = "0.99.1";
 
 /* The "failure to reconnect" firmware bug */
 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
@@ -846,9 +847,6 @@
 	/* TODO: Error handling */
 	if (STp->poll)
 		retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);
-#if 0// DEBUG
-	printk ("osst_read: wait for frame returned %i\n", retval);
-#endif
 	
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = READ_6;
@@ -1279,14 +1277,14 @@
 	Scsi_Request  * SRpnt = * aSRpnt;
 	unsigned char * buffer, * p;
 	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int             flag, new_frame, i;
-	int             nframes          = STp->cur_frames;
-	int             blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
-	int             frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
+	int		flag, new_frame, i;
+	int		nframes          = STp->cur_frames;
+	int		blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+	int		frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
 						- (nframes + pending - 1);
-	int             logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
+	int		logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
 						- (nframes + pending - 1) * blks_per_frame;
-	char          * name             = tape_name(STp);
+	char	      * name             = tape_name(STp);
 	unsigned long	startwait        = jiffies;
 #if DEBUG
 	int		dbg              = debugging;
@@ -1472,7 +1470,7 @@
 {
 	unsigned char	cmd[MAX_COMMAND_SIZE];
 	Scsi_Request  * SRpnt;
-	char          * name      = tape_name(STp);
+	char	      * name      = tape_name(STp);
 	int		expected  = 0;
 	int		attempts  = 1000 / skip;
 	int		flag      = 1;
@@ -2189,6 +2187,7 @@
 	if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
 		if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
 			printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
+		osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
 		if (osst_initiate_read (STp, aSRpnt)) {
 			printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
 			return 0;
@@ -2817,7 +2816,29 @@
 	return result;
 }
 
+static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT)
+{
+	ST_partstat * STps = &(STp->ps[STp->partition]);
+	int result = 0;
+
+	if (STp->write_type != OS_WRITE_NEW_MARK) {
+		/* true unless the user wrote the filemark for us */
+		result = osst_flush_drive_buffer(STp, aSRpnt);
+		if (result < 0) goto out;
+		result = osst_write_filemark(STp, aSRpnt);
+		if (result < 0) goto out;
+
+		if (STps->drv_file >= 0)
+			STps->drv_file++ ;
+		STps->drv_block = 0;
+	}
+	result = osst_write_eod(STp, aSRpnt);
+	osst_write_header(STp, aSRpnt, leave_at_EOT);
 
+	STps->eof = ST_FM;
+out:
+	return result;
+}
 \f

 /* osst versions of st functions - augmented and stripped to suit OnStream only */
 
@@ -2935,7 +2956,7 @@
 					result = (-EIO);
 				}
 			}
-			STps->drv_block = (-1);
+			STps->drv_block = (-1);		/* FIXME - even if write recovery succeeds? */
 		}
 		else {
 			STp->first_frame_position++;
@@ -3628,7 +3649,7 @@
 	/* Change the eof state if no data from tape or buffer */
 	if (total == 0) {
 		if (STps->eof == ST_FM_HIT) {
-			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
+			STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
 			STps->drv_block = 0;
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
@@ -4037,8 +4058,8 @@
 		if (debugging)
 		   printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
 #endif
-		osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
-	if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) {
+		if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
+			    (osst_get_logical_frame(STp, &SRpnt, -1, 0)               < 0)) {
 		   ioctl_result = -EIO;
 		   goto os_bypass;
 		}
@@ -4076,6 +4097,23 @@
 		break;
 
 	 case MTSETBLK:           /* Set block length */
+		 if ((STps->drv_block == 0 )			  &&
+		     !STp->dirty				  &&
+		     ((STp->buffer)->buffer_bytes == 0)		  &&
+		     ((arg & MT_ST_BLKSIZE_MASK) >= 512 )	  && 
+		     ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
+		     !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))  ) {
+			 /*
+			  * Only allowed to change the block size if you opened the
+			  * device at the beginning of a file before writing anything.
+			  * Note, that when reading, changing block_size is futile,
+			  * as the size used when writing overrides it.
+			  */
+			 STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
+			 printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
+					   name, STp->block_size);
+			 return 0;
+		 }
 	 case MTSETDENSITY:       /* Set tape density */
 	 case MTSETDRVBUFFER:     /* Set drive buffering */
 	 case SET_DENS_AND_BLK:   /* Set density and block size */
@@ -4083,11 +4121,11 @@
 		 if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
 			 return (-EIO);       /* Not allowed if data in buffer */
 		 if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
-		   (arg & MT_ST_BLKSIZE_MASK) != 0 &&
-		   ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
-		    (arg & MT_ST_BLKSIZE_MASK) > STp->max_block ||
-		    (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) {
-			 printk(KERN_WARNING "%s:W: Illegal block size.\n", name);
+		     (arg & MT_ST_BLKSIZE_MASK) != 0                    &&
+		     (arg & MT_ST_BLKSIZE_MASK) != STp->block_size       ) {
+			 printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
+						name, (int)(arg & MT_ST_BLKSIZE_MASK),
+						(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
 			 return (-EINVAL);
 		 }
 		 return 0;  /* FIXME silently ignore if block size didn't change */
@@ -4592,22 +4630,7 @@
 					       name, STp->nbr_waits, STp->nbr_finished);
 		}
 #endif
-		if (STp->write_type != OS_WRITE_NEW_MARK) {
-			/* true unless the user wrote the filemark for us */
-			result = osst_flush_drive_buffer(STp, &SRpnt);
-			if (result < 0) goto out;
-			result = osst_write_filemark(STp, &SRpnt);
-			if (result < 0) goto out;
-
-			if (STps->drv_file >= 0)
-				STps->drv_file++ ;
-			STps->drv_block = 0;
-		}
-		result = osst_write_eod(STp, &SRpnt);
-		osst_write_header(STp, &SRpnt, !(STp->rew_at_close));
-
-		STps->eof = ST_FM;
-
+		result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
 #if DEBUG
 		if (debugging)
 			printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
@@ -4618,7 +4641,7 @@
 		STps = &(STp->ps[STp->partition]);
 		if (!STm->sysv || STps->rw != ST_READING) {
 			if (STp->can_bsr)
-		result = osst_flush_buffer(STp, &SRpnt, 0);	/* this is the default path */
+				result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
 			else if (STps->eof == ST_FM_HIT) {
 				result = cross_eof(STp, &SRpnt, FALSE);
 					if (result) {
@@ -4633,7 +4656,7 @@
 		}
 		else if ((STps->eof == ST_NOEOF &&
 			  !(result = cross_eof(STp, &SRpnt, TRUE))) ||
-			  STps->eof == ST_FM_HIT) {
+			 STps->eof == ST_FM_HIT) {
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
 			STps->drv_block = 0;
@@ -4736,6 +4759,7 @@
 #endif
 	if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
 		struct mtop mtc;
+		int    auto_weof = 0;
 
 		if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
 			retval = (-EINVAL);
@@ -4812,10 +4836,41 @@
 			STp->device->was_reset = 0;
 		}
 
-		if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM &&
-		    mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETBLK &&
-		    mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
-			STps->rw = ST_IDLE;  /* Prevent automatic WEOF and fsf */
+		if (mtc.mt_op != MTCOMPRESSION  && mtc.mt_op != MTLOCK         &&
+		    mtc.mt_op != MTNOP          && mtc.mt_op != MTSETBLK       &&
+		    mtc.mt_op != MTSETDENSITY   && mtc.mt_op != MTSETDRVBUFFER && 
+		    mtc.mt_op != MTMKPART       && mtc.mt_op != MTSETPART      &&
+		    mtc.mt_op != MTWEOF         && mtc.mt_op != MTWSM           ) {
+
+			/*
+			 * The user tells us to move to another position on the tape.
+			 * If we were appending to the tape content, that would leave
+			 * the tape without proper end, in that case write EOD and
+			 * update the header to reflect its position.
+			 */
+#if DEBUG
+			printk(KERN_WARNING "%s:D: auto_weod %s at ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n", name,
+					STps->rw >= ST_WRITING ? "write" : STps->rw == ST_READING ? "read" : "idle",
+					STp->first_frame_position, STp->eod_frame_ppos, STp->frame_seq_number,
+					STp->logical_blk_num, STps->drv_file, STps->drv_block );
+#endif
+			if (STps->rw >= ST_WRITING && STp->first_frame_position >= STp->eod_frame_ppos) {
+				auto_weof = ((STp->write_type != OS_WRITE_NEW_MARK) &&
+							!(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
+				i = osst_write_trailer(STp, &SRpnt,
+							!(mtc.mt_op == MTREW || mtc.mt_op == MTOFFL));
+#if DEBUG
+				printk(KERN_WARNING "%s:D: post trailer xeof=%d,ffp=%d,efp=%d,fsn=%d,lbn=%d,fn=%d,bn=%d\n",
+						name, auto_weof, STp->first_frame_position, STp->eod_frame_ppos,
+						STp->frame_seq_number, STp->logical_blk_num, STps->drv_file, STps->drv_block );
+#endif
+				if (i < 0) {
+					retval = i;
+					goto out;
+				}
+			}
+			STps->rw = ST_IDLE;
+		}
 
 		if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
 			do_door_lock(STp, 0);  /* Ignore result! */
@@ -4873,11 +4928,15 @@
 			retval = do_door_lock(STp, (mtc.mt_op == MTLOCK));
 			goto out;
 		}
-			
+
+		if (auto_weof)
+			cross_eof(STp, &SRpnt, FALSE);
+
 		if (mtc.mt_op == MTCOMPRESSION)
-			retval = -EINVAL /*osst_compression(STp, (mtc.mt_count & 1))*/;
+			retval = -EINVAL;       /* OnStream drives don't have compression hardware */
 		else
-
+			/* MTBSF MTBSFM MTBSR MTBSS MTEOM MTERASE MTFSF MTFSFB MTFSR MTFSS
+			 * MTLOAD MTOFFL MTRESET MTRETEN MTREW MTUNLOAD MTWEOF MTWSM */
 			retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
 		goto out;
 	}
@@ -5527,37 +5646,37 @@
 
 static int osst_remove(struct device *dev)
 {
-  Scsi_Device * SDp = to_scsi_device(dev);
-  OS_Scsi_Tape * tpnt;
-  int i, mode;
-
-  if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
-	  return 0;
-
-  write_lock(&os_scsi_tapes_lock);
-  for(i=0; i < osst_max_dev; i++) {
-	if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
-		tpnt->device = NULL;
-		for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-			devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
-			devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
-		}
-		devfs_unregister_tape(tpnt->drive->number);
-		put_disk(tpnt->drive);
-		os_scsi_tapes[i] = NULL;
-		osst_nr_dev--;
-		write_unlock(&os_scsi_tapes_lock);
-		if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
-		if (tpnt->buffer) {
-			normalize_buffer(tpnt->buffer);
-			kfree(tpnt->buffer);
-		}
-		kfree(tpnt);
+	Scsi_Device  * SDp = to_scsi_device(dev);
+	OS_Scsi_Tape * tpnt;
+	int i, mode;
+
+	if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
 		return 0;
+
+	write_lock(&os_scsi_tapes_lock);
+	for(i=0; i < osst_max_dev; i++) {
+		if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
+			tpnt->device = NULL;
+			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+				devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
+				devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
+			}
+			devfs_unregister_tape(tpnt->drive->number);
+			put_disk(tpnt->drive);
+			os_scsi_tapes[i] = NULL;
+			osst_nr_dev--;
+			write_unlock(&os_scsi_tapes_lock);
+			if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
+			if (tpnt->buffer) {
+				normalize_buffer(tpnt->buffer);
+				kfree(tpnt->buffer);
+			}
+			kfree(tpnt);
+			return 0;
+		}
 	}
-  }
-  write_unlock(&os_scsi_tapes_lock);
-  return 0;
+	write_unlock(&os_scsi_tapes_lock);
+	return 0;
 }
 
 static int __init init_osst(void) 
--- drivers/scsi/osst.h.orig	2003-12-17 21:59:05.000000000 -0500
+++ drivers/scsi/osst.h	2003-12-14 14:34:38.000000000 -0500
@@ -1,12 +1,11 @@
 /*
- *	$Header: /home/cvsroot/Driver/osst.h,v 1.12 2001/10/11 00:30:15 riede Exp $
+ *	$Header: /cvsroot/osst/Driver/osst.h,v 1.14 2003/12/14 14:34:38 wriede Exp $
  */
 
 #include <asm/byteorder.h>
 #include <linux/config.h>
 #include <linux/completion.h>
 
-
 /*	FIXME - rename and use the following two types or delete them!
  *              and the types really should go to st.h anyway...
  *	INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C)
--- drivers/scsi/osst_options.h.orig	2003-12-17 22:00:00.000000000 -0500
+++ drivers/scsi/osst_options.h	2003-12-23 09:31:57.708132856 -0500
@@ -8,7 +8,7 @@
    Changed (and renamed) for OnStream SCSI drives garloff@suse.de
    2000-06-21
 
-   $Header: /home/cvsroot/Driver/osst_options.h,v 1.5 2001/01/07 22:19:15 riede Exp $
+   $Header: /cvsroot/osst/Driver/osst_options.h,v 1.6 2003/12/23 14:22:12 wriede Exp $
 */
 
 #ifndef _OSST_OPTIONS_H
--------   end patch  ---------

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Updated osst driver for 2.6.x
  2003-12-23 21:29   ` Willem Riede
@ 2003-12-28 13:25     ` Christoph Hellwig
  0 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2003-12-28 13:25 UTC (permalink / raw)
  To: Willem Riede; +Cc: linux-scsi

On Tue, Dec 23, 2003 at 04:29:50PM -0500, Willem Riede wrote:
> > Please don't.  This is exactly what sysfs is for.
> > 
> I was afraid you were going to say that :-)
> 
> The 2.4 version I have on the osst web site has had this /proc file for some time,
> and I simply copied the logic over.
> 
> But if you don't want me to go there, I won't. I'll come back later with a sysfs
> version that provides that info. One question: should each parameter be in its
> own little file, or can I create them all on one line as I do now?

Yes, please do one value per file.

> In the mean time, here is the patch without the offending pieces.
> 
> Is this OK? Thanks, Willem Riede.

The patch looks okay to me.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-12-28 13:25 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-12-23 17:43 [PATCH] Updated osst driver for 2.6.x Willem Riede
2003-12-23 19:26 ` Christoph Hellwig
2003-12-23 21:29   ` Willem Riede
2003-12-28 13:25     ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox