patch-2.4.9 linux/drivers/scsi/st.c
Next file: linux/drivers/scsi/st.h
Previous file: linux/drivers/scsi/sr_ioctl.c
Back to the patch index
Back to the overall index
- Lines: 211
- Date:
Sun Aug 12 11:21:47 2001
- Orig file:
v2.4.8/linux/drivers/scsi/st.c
- Orig date:
Wed Jul 25 17:10:23 2001
diff -u --recursive --new-file v2.4.8/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
@@ -5,14 +5,14 @@
History:
Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
Contribution and ideas from several people including (in alphabetical
- order) Klaus Ehrenfried, Eric Lee Green, Wolfgang Denk, Steve Hirsch,
- Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, Michael Schaefer,
- J"org Weule, and Eric Youngdale.
+ order) Klaus Ehrenfried, Eugene Exarevsky, Eric Lee Green, Wolfgang Denk,
+ Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
+ Michael Schaefer, J"org Weule, and Eric Youngdale.
- Copyright 1992 - 2000 Kai Makisara
+ Copyright 1992 - 2001 Kai Makisara
email Kai.Makisara@metla.fi
- Last modified: Mon Nov 13 21:01:09 2000 by makisara@kai.makisara.local
+ Last modified: Sun Aug 12 12:34:28 2001 by makisara@kai.makisara.local
Some small formal changes - aeb, 950809
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
@@ -21,6 +21,8 @@
error handling will be discarded.
*/
+static char *verstr = "20010812";
+
#include <linux/module.h>
#include <linux/fs.h>
@@ -77,9 +79,13 @@
MODULE_AUTHOR("Kai Makisara");
MODULE_DESCRIPTION("SCSI Tape Driver");
MODULE_PARM(buffer_kbs, "i");
+MODULE_PARM_DESC(buffer_kbs, "Default driver buffer size (KB; 32)");
MODULE_PARM(write_threshold_kbs, "i");
+MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 30)");
MODULE_PARM(max_buffers, "i");
+MODULE_PARM_DESC(max_buffers, "Maximum number of buffer allocated at initialisation (4)");
MODULE_PARM(max_sg_segs, "i");
+MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (32)");
#ifndef MODULE
static struct st_dev_parm {
@@ -302,38 +308,33 @@
int remainder;
Scsi_Tape *STp;
- if ((st_nbr = TAPE_NR(SCpnt->request.rq_dev)) < st_template.nr_dev) {
- read_lock(&st_dev_arr_lock);
- STp = scsi_tapes[st_nbr];
- read_unlock(&st_dev_arr_lock);
- if ((STp->buffer)->writing &&
- (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
- (SCpnt->sense_buffer[2] & 0x40)) {
- /* EOM at write-behind, has all been written? */
- if ((SCpnt->sense_buffer[0] & 0x80) != 0)
- remainder = (SCpnt->sense_buffer[3] << 24) |
- (SCpnt->sense_buffer[4] << 16) |
- (SCpnt->sense_buffer[5] << 8) |
- SCpnt->sense_buffer[6];
- else
- remainder = 0;
- if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW ||
- remainder > 0)
- (STp->buffer)->midlevel_result = SCpnt->result; /* Error */
- else
- (STp->buffer)->midlevel_result = INT_MAX; /* OK */
- } else
- (STp->buffer)->midlevel_result = SCpnt->result;
- SCpnt->request.rq_status = RQ_SCSI_DONE;
- (STp->buffer)->last_SRpnt = SCpnt->sc_request;
- DEB( STp->write_pending = 0; )
+ st_nbr = TAPE_NR(SCpnt->request.rq_dev);
+ read_lock(&st_dev_arr_lock);
+ STp = scsi_tapes[st_nbr];
+ read_unlock(&st_dev_arr_lock);
+ if ((STp->buffer)->writing &&
+ (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
+ (SCpnt->sense_buffer[2] & 0x40)) {
+ /* EOM at write-behind, has all been written? */
+ if ((SCpnt->sense_buffer[0] & 0x80) != 0)
+ remainder = (SCpnt->sense_buffer[3] << 24) |
+ (SCpnt->sense_buffer[4] << 16) |
+ (SCpnt->sense_buffer[5] << 8) |
+ SCpnt->sense_buffer[6];
+ else
+ remainder = 0;
+ if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW ||
+ remainder > 0)
+ (STp->buffer)->midlevel_result = SCpnt->result; /* Error */
+ else
+ (STp->buffer)->midlevel_result = INT_MAX; /* OK */
+ } else
+ (STp->buffer)->midlevel_result = SCpnt->result;
+ SCpnt->request.rq_status = RQ_SCSI_DONE;
+ (STp->buffer)->last_SRpnt = SCpnt->sc_request;
+ DEB( STp->write_pending = 0; )
- complete(SCpnt->request.waiting);
- }
- DEB(
- else if (debugging)
- printk(KERN_ERR "st?: Illegal interrupt device %x\n", st_nbr);
- ) /* end DEB */
+ complete(SCpnt->request.waiting);
}
@@ -1302,8 +1303,7 @@
DEBC(printk(ST_DEB_MSG "st%d: Error on write:\n", dev));
if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
(SRpnt->sr_sense_buffer[2] & 0x40)) {
- if (STp->block_size != 0 &&
- (SRpnt->sr_sense_buffer[0] & 0x80) != 0)
+ if ((SRpnt->sr_sense_buffer[0] & 0x80) != 0)
transfer = (SRpnt->sr_sense_buffer[3] << 24) |
(SRpnt->sr_sense_buffer[4] << 16) |
(SRpnt->sr_sense_buffer[5] << 8) |
@@ -2302,7 +2302,7 @@
case MTEOM:
if (!STp->fast_mteom) {
/* space to the end of tape */
- ioctl_result = st_int_ioctl(STp, MTFSF, 0x3fff);
+ ioctl_result = st_int_ioctl(STp, MTFSF, 0x7fffff);
fileno = STps->drv_file;
if (STps->eof >= ST_EOD_1)
return 0;
@@ -2361,6 +2361,8 @@
return (-EINVAL);
}
cmd[0] = MODE_SELECT;
+ if ((STp->use_pf & USE_PF))
+ cmd[1] = MODE_SELECT_PAGE_FORMAT;
cmd[4] = datalen = 12;
direction = SCSI_DATA_WRITE;
@@ -2474,11 +2476,11 @@
STps->drv_block = 0;
}
- undone = (
- (SRpnt->sr_sense_buffer[3] << 24) +
- (SRpnt->sr_sense_buffer[4] << 16) +
- (SRpnt->sr_sense_buffer[5] << 8) +
- SRpnt->sr_sense_buffer[6]);
+ undone = ((SRpnt->sr_sense_buffer[3] << 24) +
+ (SRpnt->sr_sense_buffer[4] << 16) +
+ (SRpnt->sr_sense_buffer[5] << 8) +
+ SRpnt->sr_sense_buffer[6]);
+
if (cmd_in == MTWEOF &&
(SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
(SRpnt->sr_sense_buffer[2] & 0x4f) == 0x40 &&
@@ -2496,6 +2498,8 @@
STps->drv_block = 0;
STps->eof = ST_NOEOF;
} else if ((cmd_in == MTBSF) || (cmd_in == MTBSFM)) {
+ if (arg > 0 && undone < 0) /* Some drives get this wrong */
+ undone = (-undone);
if (STps->drv_file >= 0)
STps->drv_file = fileno + undone;
STps->drv_block = 0;
@@ -2518,6 +2522,8 @@
STps->drv_file--;
STps->drv_block = (-1);
} else {
+ if (arg > 0 && undone < 0) /* Some drives get this wrong */
+ undone = (-undone);
if (STps->drv_block >= 0)
STps->drv_block = blkno + undone;
}
@@ -2526,6 +2532,19 @@
STps->drv_file = (-1);
STps->drv_block = (-1);
STps->eof = ST_EOD;
+ } else if (cmd_in == MTSETBLK ||
+ cmd_in == MTSETDENSITY ||
+ cmd_in == MTSETDRVBUFFER ||
+ cmd_in == SET_DENS_AND_BLK) {
+ if ((SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST &&
+ !(STp->use_pf & PF_TESTED)) {
+ /* Try the other possible state of Page Format if not
+ already tried */
+ STp->use_pf = !STp->use_pf | PF_TESTED;
+ scsi_release_request(SRpnt);
+ SRpnt = NULL;
+ return st_int_ioctl(STp, cmd_in, arg);
+ }
} else if (chg_eof)
STps->eof = ST_NOEOF;
@@ -3608,6 +3627,7 @@
tpnt->in_use = 0;
tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
+ tpnt->use_pf = (SDp->scsi_level >= SCSI_2);
tpnt->density = 0;
tpnt->do_auto_lock = ST_AUTO_LOCK;
tpnt->can_bsr = ST_IN_FILE_POS;
@@ -3692,8 +3712,9 @@
if (st_template.dev_noticed == 0 || st_registered)
return 0;
- printk(KERN_INFO "st: bufsize %d, wrt %d, max init. buffers %d, s/g segs %d.\n",
- st_buffer_size, st_write_threshold, st_max_buffers, st_max_sg_segs);
+ printk(KERN_INFO
+ "st: Version %s, bufsize %d, wrt %d, max init. bufs %d, s/g segs %d\n",
+ verstr, st_buffer_size, st_write_threshold, st_max_buffers, st_max_sg_segs);
write_lock_irqsave(&st_dev_arr_lock, flags);
if (!st_registered) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)