patch-2.3.44 linux/drivers/scsi/st.c

Next file: linux/drivers/usb/acm.c
Previous file: linux/drivers/scsi/sd.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.43/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
@@ -11,7 +11,7 @@
    Copyright 1992 - 2000 Kai Makisara
    email Kai.Makisara@metla.fi
 
-   Last modified: Tue Jan  4 21:43:17 2000 by makisara@kai.makisara.local
+   Last modified: Fri Feb 11 19:43:57 2000 by makisara@kai.makisara.local
    Some small formal changes - aeb, 950809
  */
 
@@ -66,15 +66,15 @@
 static int write_threshold_kbs = 0;
 static int max_buffers = (-1);
 static int max_sg_segs = 0;
-#ifdef MODULE
+
 MODULE_AUTHOR("Kai Makisara");
 MODULE_DESCRIPTION("SCSI Tape Driver");
 MODULE_PARM(buffer_kbs, "i");
 MODULE_PARM(write_threshold_kbs, "i");
 MODULE_PARM(max_buffers, "i");
 MODULE_PARM(max_sg_segs, "i");
-#else
 
+#ifndef MODULE
 static struct st_dev_parm {
 	char *name;
 	int *val;
@@ -92,7 +92,6 @@
 		"max_sg_segs", &max_sg_segs
 	}
 };
-
 #endif
 
 
@@ -380,7 +379,7 @@
 static int cross_eof(Scsi_Tape * STp, int forward)
 {
 	Scsi_Cmnd *SCpnt;
-	unsigned char cmd[10];
+	unsigned char cmd[MAX_COMMAND_SIZE];
 
 	cmd[0] = SPACE;
 	cmd[1] = 0x01;		/* Space FileMarks */
@@ -414,7 +413,7 @@
 {
 	int offset, transfer, blks;
 	int result;
-	unsigned char cmd[10];
+	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 	ST_partstat *STps;
 
@@ -443,7 +442,7 @@
 
 		memset((STp->buffer)->b_data + offset, 0, transfer - offset);
 
-		memset(cmd, 0, 10);
+		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = WRITE_6;
 		cmd[1] = 1;
 		blks = transfer / STp->block_size;
@@ -582,7 +581,8 @@
 {
 	unsigned short flags;
 	int i, need_dma_buffer, new_session = FALSE;
-	unsigned char cmd[10];
+	int retval;
+	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 	Scsi_Tape *STp;
 	ST_mode *STm;
@@ -601,8 +601,14 @@
 		DEB( printk(ST_DEB_MSG "st%d: Device already in use.\n", dev); )
 		return (-EBUSY);
 	}
+	STp->in_use = 1;
 	STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0;
 
+	if (scsi_tapes[dev].device->host->hostt->module)
+		__MOD_INC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
+	if (st_template.module)
+		__MOD_INC_USE_COUNT(st_template.module);
+
 	if (mode != STp->current_mode) {
                 DEBC(printk(ST_DEB_MSG "st%d: Mode change from %d to %d.\n",
 			       dev, STp->current_mode, mode));
@@ -621,7 +627,8 @@
 		STp->buffer = new_tape_buffer(FALSE, need_dma_buffer);
 		if (STp->buffer == NULL) {
 			printk(KERN_WARNING "st%d: Can't allocate tape buffer.\n", dev);
-			return (-EBUSY);
+			retval = (-EBUSY);
+			goto err_out;
 		}
 	} else
 		STp->buffer = st_buffers[i];
@@ -651,22 +658,14 @@
 	STp->recover_count = 0;
 	DEB( STp->nbr_waits = STp->nbr_finished = 0; )
 
-	if (scsi_tapes[dev].device->host->hostt->module)
-		__MOD_INC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
-	if (st_template.module)
-		__MOD_INC_USE_COUNT(st_template.module);
-
-	memset((void *) &cmd[0], 0, 10);
+	memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
 	SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->long_timeout, MAX_READY_RETRIES,
 			   TRUE);
 	if (!SCpnt) {
-		if (scsi_tapes[dev].device->host->hostt->module)
-			__MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
-		if (st_template.module)
-			__MOD_DEC_USE_COUNT(st_template.module);
-		return (STp->buffer)->last_result_fatal;
+		retval = (STp->buffer)->last_result_fatal;
+		goto err_out;
 	}
 
 	if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
@@ -674,7 +673,7 @@
 
 		/* Flush the queued UNIT ATTENTION sense data */
 		for (i=0; i < 10; i++) {
-                        memset((void *) &cmd[0], 0, 10);
+                        memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
                         cmd[0] = TEST_UNIT_READY;
                         SCpnt = st_do_scsi(SCpnt, STp, cmd, 0, STp->long_timeout,
                                            MAX_READY_RETRIES, TRUE);
@@ -716,14 +715,13 @@
 		STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
 		STp->partition = STp->new_partition = 0;
 		STp->door_locked = ST_UNLOCKED;
-		STp->in_use = 1;
 		return 0;
 	}
 
 	if (STp->omit_blklims)
 		STp->min_block = STp->max_block = (-1);
 	else {
-		memset((void *) &cmd[0], 0, 10);
+		memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
 		cmd[0] = READ_BLOCK_LIMITS;
 
 		SCpnt = st_do_scsi(SCpnt, STp, cmd, 6, STp->timeout, MAX_READY_RETRIES,
@@ -745,7 +743,7 @@
 		}
 	}
 
-	memset((void *) &cmd[0], 0, 10);
+	memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SENSE;
 	cmd[4] = 12;
 
@@ -780,13 +778,8 @@
 			printk(KERN_NOTICE "st%d: Blocksize %d too large for buffer.\n",
                                dev, STp->block_size);
 			scsi_release_command(SCpnt);
-			(STp->buffer)->in_use = 0;
-			STp->buffer = NULL;
-			if (scsi_tapes[dev].device->host->hostt->module)
-				__MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
-			if (st_template.module)
-				__MOD_DEC_USE_COUNT(st_template.module);
-			return (-EIO);
+			retval = (-EIO);
+			goto err_out;
 		}
 		STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
 	}
@@ -812,13 +805,8 @@
                 DEBC(printk(ST_DEB_MSG "st%d: Write protected\n", dev));
 
 		if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
-			(STp->buffer)->in_use = 0;
-			STp->buffer = NULL;
-			if (scsi_tapes[dev].device->host->hostt->module)
-				__MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
-			if (st_template.module)
-				__MOD_DEC_USE_COUNT(st_template.module);
-			return (-EROFS);
+			retval = (-EROFS);
+			goto err_out;
 		}
 	}
 
@@ -829,13 +817,8 @@
                 DEBC(printk(ST_DEB_MSG
                             "st%d: Updating partition number in status.\n", dev));
 		if ((STp->partition = find_partition(inode)) < 0) {
-			(STp->buffer)->in_use = 0;
-			STp->buffer = NULL;
-			if (scsi_tapes[dev].device->host->hostt->module)
-				__MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
-			if (st_template.module)
-				__MOD_DEC_USE_COUNT(st_template.module);
-			return STp->partition;
+			retval = STp->partition;
+			goto err_out;
 		}
 		STp->new_partition = STp->partition;
 		STp->nbr_partitions = 1; /* This guess will be updated when necessary */
@@ -845,15 +828,8 @@
 		STp->density_changed = STp->blksize_changed = FALSE;
 		STp->compression_changed = FALSE;
 		if (!(STm->defaults_for_writes) &&
-		    (i = set_mode_densblk(inode, STp, STm)) < 0) {
-			(STp->buffer)->in_use = 0;
-			STp->buffer = NULL;
-			if (scsi_tapes[dev].device->host->hostt->module)
-				__MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
-			if (st_template.module)
-				__MOD_DEC_USE_COUNT(st_template.module);
-			return i;
-		}
+		    (retval = set_mode_densblk(inode, STp, STm)) < 0)
+		    goto err_out;
 
 		if (STp->default_drvbuffer != 0xff) {
 			if (st_int_ioctl(inode, MTSETDRVBUFFER, STp->default_drvbuffer))
@@ -862,9 +838,21 @@
 				       dev, STp->default_drvbuffer);
 		}
 	}
-	STp->in_use = 1;
 
 	return 0;
+
+ err_out:
+	if (STp->buffer != NULL) {
+		(STp->buffer)->in_use = 0;
+		STp->buffer = NULL;
+	}
+	STp->in_use = 0;
+	if (scsi_tapes[dev].device->host->hostt->module)
+	    __MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module);
+	if (st_template.module)
+	    __MOD_DEC_USE_COUNT(st_template.module);
+	return retval;
+
 }
 
 
@@ -872,7 +860,7 @@
 static int scsi_tape_flush(struct file *filp)
 {
 	int result = 0, result2;
-	static unsigned char cmd[10];
+	static unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 	Scsi_Tape *STp;
 	ST_mode *STm;
@@ -890,59 +878,62 @@
 	STm = &(STp->modes[STp->current_mode]);
 	STps = &(STp->ps[STp->partition]);
 
+	if (STps->rw == ST_WRITING && !(STp->device)->was_reset) {
+		result = flush_write_buffer(STp);
+		if (result != 0 && result != (-ENOSPC))
+			goto out;
+	}
+
 	if (STp->can_partitions &&
-	    (result = update_partition(inode)) < 0) {
+	    (result2 = update_partition(inode)) < 0) {
                 DEBC(printk(ST_DEB_MSG
                                "st%d: update_partition at close failed.\n", dev));
+		if (result == 0)
+			result = result2;
 		goto out;
 	}
 
 	if (STps->rw == ST_WRITING && !(STp->device)->was_reset) {
 
-		result = flush_write_buffer(STp);
-
                 DEBC(printk(ST_DEB_MSG "st%d: File length %ld bytes.\n",
                             dev, (long) (filp->f_pos));
                      printk(ST_DEB_MSG "st%d: Async write waits %d, finished %d.\n",
                             dev, STp->nbr_waits, STp->nbr_finished);
 		)
 
-		if (result == 0 || result == (-ENOSPC)) {
+		memset(cmd, 0, MAX_COMMAND_SIZE);
+		cmd[0] = WRITE_FILEMARKS;
+		cmd[4] = 1 + STp->two_fm;
 
-			memset(cmd, 0, 10);
-			cmd[0] = WRITE_FILEMARKS;
-			cmd[4] = 1 + STp->two_fm;
-
-			SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->timeout,
-                                           MAX_WRITE_RETRIES, TRUE);
-			if (!SCpnt) {
-				result = (STp->buffer)->last_result_fatal;
-				goto out;
-			}
+		SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->timeout,
+				   MAX_WRITE_RETRIES, TRUE);
+		if (!SCpnt) {
+			result = (STp->buffer)->last_result_fatal;
+			goto out;
+		}
 
-			if ((STp->buffer)->last_result_fatal != 0 &&
-			    ((SCpnt->sense_buffer[0] & 0x70) != 0x70 ||
-			     (SCpnt->sense_buffer[2] & 0x4f) != 0x40 ||
-			     ((SCpnt->sense_buffer[0] & 0x80) != 0 &&
-			(SCpnt->sense_buffer[3] | SCpnt->sense_buffer[4] |
-			 SCpnt->sense_buffer[5] |
-			 SCpnt->sense_buffer[6]) == 0))) {
-				/* Filter out successful write at EOM */
-				scsi_release_command(SCpnt);
-				SCpnt = NULL;
-				printk(KERN_ERR "st%d: Error on write filemark.\n", dev);
-				if (result == 0)
-					result = (-EIO);
-			} else {
-				scsi_release_command(SCpnt);
-				SCpnt = NULL;
-				if (STps->drv_file >= 0)
-					STps->drv_file++;
-				STps->drv_block = 0;
-				if (STp->two_fm)
-					cross_eof(STp, FALSE);
-				STps->eof = ST_FM;
-			}
+		if ((STp->buffer)->last_result_fatal != 0 &&
+		    ((SCpnt->sense_buffer[0] & 0x70) != 0x70 ||
+		     (SCpnt->sense_buffer[2] & 0x4f) != 0x40 ||
+		     ((SCpnt->sense_buffer[0] & 0x80) != 0 &&
+		      (SCpnt->sense_buffer[3] | SCpnt->sense_buffer[4] |
+		       SCpnt->sense_buffer[5] |
+		       SCpnt->sense_buffer[6]) == 0))) {
+			/* Filter out successful write at EOM */
+			scsi_release_command(SCpnt);
+			SCpnt = NULL;
+			printk(KERN_ERR "st%d: Error on write filemark.\n", dev);
+			if (result == 0)
+				result = (-EIO);
+		} else {
+			scsi_release_command(SCpnt);
+			SCpnt = NULL;
+			if (STps->drv_file >= 0)
+				STps->drv_file++;
+			STps->drv_block = 0;
+			if (STp->two_fm)
+				cross_eof(STp, FALSE);
+			STps->eof = ST_FM;
 		}
 
                 DEBC(printk(ST_DEB_MSG "st%d: Buffer flushed, %d EOF(s) written\n",
@@ -1021,7 +1012,7 @@
 	ssize_t i, do_count, blks, retval, transfer;
 	int write_threshold;
 	int doing_write = 0;
-	static unsigned char cmd[10];
+	static unsigned char cmd[MAX_COMMAND_SIZE];
 	const char *b_point;
 	Scsi_Cmnd *SCpnt = NULL;
 	Scsi_Tape *STp;
@@ -1153,7 +1144,7 @@
 
 	total = count;
 
-	memset(cmd, 0, 10);
+	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = WRITE_6;
 	cmd[1] = (STp->block_size != 0);
 
@@ -1331,7 +1322,7 @@
 static long read_tape(struct inode *inode, long count, Scsi_Cmnd ** aSCpnt)
 {
 	int transfer, blks, bytes;
-	static unsigned char cmd[10];
+	static unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 	Scsi_Tape *STp;
 	ST_mode *STm;
@@ -1348,7 +1339,7 @@
 	if (STps->eof == ST_FM_HIT)
 		return 1;
 
-	memset(cmd, 0, 10);
+	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = READ_6;
 	cmd[1] = (STp->block_size != 0);
 	if (STp->block_size == 0)
@@ -1836,14 +1827,14 @@
 static int st_compression(Scsi_Tape * STp, int state)
 {
 	int dev;
-	unsigned char cmd[10];
+	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt = NULL;
 
 	if (STp->ready != ST_READY)
 		return (-EIO);
 
 	/* Read the current page contents */
-	memset(cmd, 0, 10);
+	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SENSE;
 	cmd[1] = 8;
 	cmd[2] = COMPRESSION_PAGE;
@@ -1879,7 +1870,7 @@
 	else
 		(STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] &= ~DCE_MASK;
 
-	memset(cmd, 0, 10);
+	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
 	cmd[1] = 0x10;
 	cmd[4] = COMPRESSION_PAGE_LENGTH + MODE_HEADER_LENGTH;
@@ -1913,7 +1904,7 @@
 	long ltmp;
 	int i, ioctl_result;
 	int chg_eof = TRUE;
-	unsigned char cmd[10];
+	unsigned char cmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 	Scsi_Tape *STp;
 	ST_partstat *STps;
@@ -1933,7 +1924,7 @@
 	blkno = STps->drv_block;
 	at_sm = STps->at_sm;
 
-	memset(cmd, 0, 10);
+	memset(cmd, 0, MAX_COMMAND_SIZE);
 	datalen = 0;
 	switch (cmd_in) {
 	case MTFSFM:
@@ -2368,14 +2359,14 @@
 	Scsi_Tape *STp;
 	int dev = TAPE_NR(inode->i_rdev);
 	int result;
-	unsigned char scmd[10];
+	unsigned char scmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 
 	STp = &(scsi_tapes[dev]);
 	if (STp->ready != ST_READY)
 		return (-EIO);
 
-	memset(scmd, 0, 10);
+	memset(scmd, 0, MAX_COMMAND_SIZE);
 	if ((STp->device)->scsi_level < SCSI_2) {
 		scmd[0] = QFA_REQUEST_BLOCK;
 		scmd[4] = 3;
@@ -2432,7 +2423,7 @@
 	int result, p;
 	unsigned int blk;
 	int timeout;
-	unsigned char scmd[10];
+	unsigned char scmd[MAX_COMMAND_SIZE];
 	Scsi_Cmnd *SCpnt;
 
 	STp = &(scsi_tapes[dev]);
@@ -2462,7 +2453,7 @@
 		}
 	}
 
-	memset(scmd, 0, 10);
+	memset(scmd, 0, MAX_COMMAND_SIZE);
 	if ((STp->device)->scsi_level < SCSI_2) {
 		scmd[0] = QFA_SEEK_BLOCK;
 		scmd[2] = (block >> 16);
@@ -2569,13 +2560,13 @@
 	int dev = TAPE_NR(inode->i_rdev), result;
 	Scsi_Tape *STp;
 	Scsi_Cmnd *SCpnt = NULL;
-	unsigned char cmd[10];
+	unsigned char cmd[MAX_COMMAND_SIZE];
 
 	STp = &(scsi_tapes[dev]);
 	if (STp->ready != ST_READY)
 		return (-EIO);
 
-	memset((void *) &cmd[0], 0, 10);
+	memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SENSE;
 	cmd[1] = 8;		/* Page format */
 	cmd[2] = PART_PAGE;
@@ -2609,7 +2600,7 @@
 	int length;
 	Scsi_Tape *STp;
 	Scsi_Cmnd *SCpnt = NULL;
-	unsigned char cmd[10], *bp;
+	unsigned char cmd[MAX_COMMAND_SIZE], *bp;
 
 	if ((result = nbr_partitions(inode)) < 0)
 		return result;
@@ -2640,7 +2631,7 @@
 	bp[MODE_HEADER_LENGTH] &= 0x3f;
 	bp[MODE_HEADER_LENGTH + 1] = length - 2;
 
-	memset(cmd, 0, 10);
+	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
 	cmd[1] = 0x10;
 	cmd[4] = length + MODE_HEADER_LENGTH;

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