aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavem <davem>2002-01-15 18:04:30 +0000
committerdavem <davem>2002-01-15 18:04:30 +0000
commit826db16337e3fe95ee644e8021f03dad7b68197f (patch)
tree46f424fed6a581f4ffeb8515b3e6b93ff7345d8c
parentea0b7d568ac44bb6967505042b91fd8ab3f7d4a5 (diff)
downloadnetdev-vger-cvs-826db16337e3fe95ee644e8021f03dad7b68197f.tar.gz
Revert 2.4.x changes.
-rw-r--r--drivers/scsi/osst.c208
-rw-r--r--drivers/scsi/osst.h4
-rw-r--r--drivers/scsi/sg.c307
-rw-r--r--include/scsi/sg.h91
4 files changed, 161 insertions, 449 deletions
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 36b57bfbd..4c8d0a95e 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -16,15 +16,15 @@
Copyright 1992 - 2000 Kai Makisara
email Kai.Makisara@metla.fi
- $Header: /home/cvsroot/Driver/osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $
+ $Header: /home/cvsroot/Driver/osst.c,v 1.61 2001/06/03 21:55:12 riede Exp $
Microscopic alterations - Rik Ling, 2000/12/21
Last modified: Wed Feb 2 22:04:05 2000 by makisara@kai.makisara.local
Some small formal changes - aeb, 950809
*/
-static const char * cvsid = "$Id: osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $";
-const char * osst_version = "0.9.10";
+static const char * cvsid = "$Id: osst.c,v 1.61 2001/06/03 21:55:12 riede Exp $";
+const char * osst_version = "0.9.8";
/* The "failure to reconnect" firmware bug */
#define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
@@ -226,20 +226,20 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
SRpnt->sr_cmnd[0] != MODE_SENSE &&
SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
if (driver_byte(result) & DRIVER_SENSE) {
- printk(KERN_WARNING "osst%d:W: Command with sense data: ", dev);
- print_req_sense("osst:", SRpnt);
+ printk(KERN_WARNING "osst%d:W: Error with sense data: ", dev);
+ print_req_sense("osst", SRpnt);
}
else {
static int notyetprinted = 1;
printk(KERN_WARNING
- "osst%d:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
+ "osst%d:W: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n",
dev, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
host_byte(result));
if (notyetprinted) {
notyetprinted = 0;
printk(KERN_INFO
- "osst%d:I: This warning may be caused by your scsi controller,\n", dev);
+ "osst%d:I: This error may be caused by your scsi controller,\n", dev);
printk(KERN_INFO
"osst%d:I: it has been reported with some Buslogic cards.\n", dev);
}
@@ -271,10 +271,11 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
/* Wakeup from interrupt */
static void osst_sleep_done (Scsi_Cmnd * SCpnt)
{
- unsigned int dev = TAPE_NR(SCpnt->request.rq_dev);
+ unsigned int dev;
OS_Scsi_Tape * STp;
- if (os_scsi_tapes && (STp = os_scsi_tapes[dev])) {
+ if ((dev = TAPE_NR(SCpnt->request.rq_dev)) < osst_template.nr_dev) {
+ STp = os_scsi_tapes[dev];
if ((STp->buffer)->writing &&
(SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
(SCpnt->sense_buffer[2] & 0x40)) {
@@ -481,8 +482,7 @@ static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet
memset(page_address(STp->buffer->sg[i].page),
0, STp->buffer->sg[i].length);
strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
- } else
- STp->buffer->buffer_bytes = OS_FRAME_SIZE;
+ }
return 1;
}
if (STp->buffer->syscall_result) {
@@ -621,10 +621,8 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned
if (!SRpnt) return (-EBUSY);
while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
- (( SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
- (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) ||
- ( SRpnt->sr_sense_buffer[2] == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&
- SRpnt->sr_sense_buffer[13] == 0 ) )) {
+ SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
+ (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8) ) {
#if DEBUG
if (debugging) {
printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait ready\n", dev);
@@ -632,7 +630,7 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned
debugging = 0;
}
#endif
- set_current_state(TASK_INTERRUPTIBLE);
+ current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ / 10);
memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -660,66 +658,6 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned
return 0;
}
-/*
- * Wait for a tape to be inserted in the unit
- */
-static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
-{
- unsigned char cmd[MAX_COMMAND_SIZE];
- Scsi_Request * SRpnt;
- long startwait = jiffies;
-#if DEBUG
- int dbg = debugging;
- int dev = TAPE_NR(STp->devt);
-
- printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait for medium\n", dev);
-#endif
-
- memset(cmd, 0, MAX_COMMAND_SIZE);
- cmd[0] = TEST_UNIT_READY;
-
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
- *aSRpnt = SRpnt;
- if (!SRpnt) return (-EBUSY);
-
- while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
- SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 0x3a &&
- SRpnt->sr_sense_buffer[13] == 0 ) {
-#if DEBUG
- if (debugging) {
- printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait medium\n", dev);
- printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a while\n", dev);
- debugging = 0;
- }
-#endif
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 10);
-
- memset(cmd, 0, MAX_COMMAND_SIZE);
- cmd[0] = TEST_UNIT_READY;
-
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
- }
- *aSRpnt = SRpnt;
-#if DEBUG
- debugging = dbg;
-#endif
- if ( STp->buffer->syscall_result && SRpnt->sr_sense_buffer[2] != 2 &&
- SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
-#if DEBUG
- printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait medium\n", dev);
- printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", dev,
- STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
- SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
-#endif
- return 0;
- }
-#if DEBUG
- printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait medium\n", dev);
-#endif
- return 1;
-}
-
static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame)
{
int retval;
@@ -758,7 +696,7 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
result = osst_write_error_recovery(STp, aSRpnt, 0);
result |= osst_wait_ready(STp, aSRpnt, 5 * 60);
- STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
+ STp->ps[STp->partition].rw = ST_IDLE;
return (result);
}
@@ -807,7 +745,7 @@ static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr,
notyetprinted--;
}
#endif
- set_current_state(TASK_INTERRUPTIBLE);
+ current->state = TASK_INTERRUPTIBLE;
schedule_timeout (HZ / OSST_POLL_PER_SEC);
}
#if DEBUG
@@ -965,8 +903,6 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in
#endif
if ( osst_initiate_read(STp, aSRpnt)
|| ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
- if (STp->raw)
- return (-EIO);
position = osst_get_frame_position(STp, aSRpnt);
if (position >= 0xbae && position < 0xbb8)
position = 0xbb8;
@@ -1032,7 +968,7 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in
if (cnt > 1) {
STp->recover_count++;
STp->recover_erreg++;
- printk(KERN_WARNING "osst%d:I: Don't worry, Read error at position %d recovered\n",
+ printk(KERN_WARNING "osst%d:I: Read error at position %d recovered\n",
dev, STp->read_error_frame);
}
STp->read_count++;
@@ -1589,10 +1525,7 @@ static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
else
retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
- printk(KERN_WARNING "osst%d:%s: %sWrite error%srecovered\n", dev,
- retval?"E" :"I",
- retval?"" :"Don't worry, ",
- retval?" not ":" ");
+ printk(KERN_WARNING "osst%d:I: Write error%srecovered\n", dev, retval?" not ":" ");
break;
case OS_WRITE_LAST_MARK:
printk(KERN_ERR "osst%d:E: Bad frame in update last marker, fatal\n", dev);
@@ -1663,7 +1596,7 @@ static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request *
mt_count, last_mark_ppos);
#endif
if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
- osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
+ osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0);
if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
#if DEBUG
printk(OSST_DEB_MSG
@@ -1695,7 +1628,7 @@ static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request *
#if DEBUG
printk(OSST_DEB_MSG "osst%d:D: Positioning to last mark at %d\n", dev, last_mark_ppos);
#endif
- osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
+ osst_set_frame_position(STp, aSRpnt, last_mark_ppos, 0);
cnt++;
if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
#if DEBUG
@@ -1822,7 +1755,7 @@ static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Reque
#endif
return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
} else {
- osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
+ osst_set_frame_position(STp, aSRpnt, next_mark_ppos, 0);
if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
#if DEBUG
printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks\n",
@@ -1862,7 +1795,7 @@ static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Reque
#endif
return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
}
- osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
+ osst_set_frame_position(STp, aSRpnt, STp->first_mark_ppos, 0);
if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
#if DEBUG
printk(OSST_DEB_MSG
@@ -1894,7 +1827,7 @@ static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Reque
#if DEBUG
else printk(OSST_DEB_MSG "osst%d:D: Positioning to next mark at %d\n", dev, next_mark_ppos);
#endif
- osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
+ osst_set_frame_position(STp, aSRpnt, next_mark_ppos, 0);
cnt++;
if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
#if DEBUG
@@ -2531,7 +2464,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
}
#if DEBUG
- printk(KERN_INFO "osst%d:D: Drive Block Size changed to 32.5K\n", dev);
+ printk(KERN_INFO "osst%d:D: Block Size changed to 32.5K\n", dev);
/*
* In debug mode, we want to see as many errors as possible
* to test the error recovery mechanism.
@@ -3469,7 +3402,6 @@ static ssize_t osst_read(struct file * filp, char * buf, size_t count, loff_t *p
if (retval)
goto out;
STps->rw = ST_IDLE;
- /* FIXME -- this may leave the tape without EOD and up2date headers */
}
if ((count % STp->block_size) != 0) {
@@ -3882,10 +3814,6 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i
ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
else
ioctl_result = 0;
-#if DEBUG
- if (debugging)
- printk(OSST_DEB_MSG "osst%d:D: Writing %ld filemark(s).\n", dev, arg);
-#endif
for (i=0; i<arg; i++)
ioctl_result |= osst_write_filemark(STp, &SRpnt);
if (fileno >= 0) fileno += arg;
@@ -3905,9 +3833,14 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i
cmd[4] = arg;
timeout = STp->timeout;
#if DEBUG
- if (debugging)
- printk(OSST_DEB_MSG "osst%d:D: Writing %d setmark(s).\n", dev,
+ if (debugging) {
+ if (cmd_in == MTWEOF)
+ printk(OSST_DEB_MSG "osst%d:D: Writing %d filemarks.\n", dev,
+ cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
+ else
+ printk(OSST_DEB_MSG "osst%d:D: Writing %d setmarks.\n", dev,
cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
+ }
#endif
if (fileno >= 0)
fileno += arg;
@@ -3920,12 +3853,8 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i
case MTRETEN:
cmd[0] = START_STOP;
cmd[1] = 1; /* Don't wait for completion */
- if (cmd_in == MTLOAD) {
- if (STp->ready == ST_NO_TAPE)
- cmd[4] = 4; /* open tray */
- else
+ if (cmd_in == MTLOAD)
cmd[4] = 1; /* load */
- }
if (cmd_in == MTRETEN)
cmd[4] = 3; /* retension then mount */
if (cmd_in == MTOFFL)
@@ -4064,7 +3993,7 @@ os_bypass:
printk(OSST_DEB_MSG "osst%d:D: IOCTL (%d) Result=%d\n", dev, cmd_in, ioctl_result);
#endif
- if (!ioctl_result) { /* success */
+ if (!ioctl_result) {
if (cmd_in == MTFSFM) {
fileno--;
@@ -4141,8 +4070,6 @@ os_bypass:
if (cmd_in == MTLOCK)
STp->door_locked = ST_LOCK_FAILS;
- if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
- ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60);
}
*aSRpnt = SRpnt;
@@ -4183,7 +4110,6 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
__MOD_INC_USE_COUNT(STp->device->host->hostt->module);
if (osst_template.module)
__MOD_INC_USE_COUNT(osst_template.module);
- STp->device->access_count++;
if (mode != STp->current_mode) {
#if DEBUG
@@ -4200,8 +4126,6 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
STp->raw = (minor(inode->i_rdev) & 0x40) != 0;
- if (STp->raw)
- STp->header_ok = 0;
/* Allocate a buffer for this user */
need_dma_buffer = STp->restr_dma;
@@ -4292,7 +4216,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
for (i=0; i < ST_NBR_PARTITIONS; i++) {
STps = &(STp->ps[i]);
- STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
+ STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
STps->eof = ST_NOEOF;
STps->at_sm = 0;
STps->last_block_valid = FALSE;
@@ -4340,8 +4264,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
STp->door_locked = ST_LOCKED_AUTO;
}
if (!STp->frame_in_buffer) {
- STp->block_size = (STm->default_blksize > 0) ?
- STm->default_blksize : OS_DATA_SIZE;
+ STp->block_size = (STp->raw) ? OS_FRAME_SIZE : (
+ (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
}
STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
@@ -4434,6 +4358,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
return 0;
}
+ STp->min_block = STp->max_block = (-1);
+
osst_configure_onstream(STp, &SRpnt);
/* STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; FIXME */
@@ -4460,9 +4386,11 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
} else
STp->buffer->aux = NULL; /* this had better never happen! */
- STp->block_size = STp->raw ? OS_FRAME_SIZE : (
+ STp->block_size = (STp->raw) ? OS_FRAME_SIZE : (
(STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
- STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
+ STp->min_block = 512;
+ STp->max_block = OS_DATA_SIZE;
+ STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
STp->buffer->buffer_bytes =
STp->buffer->read_pointer =
STp->frame_in_buffer = 0;
@@ -4520,8 +4448,6 @@ err_out:
STp->buffer = NULL;
}
STp->in_use = 0;
- STp->header_ok = 0;
- STp->device->access_count--;
if (STp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
@@ -4558,7 +4484,7 @@ static int os_scsi_tape_flush(struct file * filp)
if (result != 0 && result != (-ENOSPC))
goto out;
}
- if ( STps->rw >= ST_WRITING && !(STp->device)->was_reset) {
+ if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
#if DEBUG
if (debugging) {
@@ -4568,17 +4494,16 @@ static int os_scsi_tape_flush(struct file * filp)
dev, 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_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));
@@ -4662,12 +4587,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp)
if (STp->buffer != NULL)
STp->buffer->in_use = 0;
- if (STp->raw)
- STp->header_ok = 0;
-
STp->in_use = 0;
- STp->device->access_count--;
-
if (STp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
if(osst_template.module)
@@ -4717,10 +4637,7 @@ static int osst_ioctl(struct inode * inode,struct file * file,
cmd_type = _IOC_TYPE(cmd_in);
cmd_nr = _IOC_NR(cmd_in);
-#if DEBUG
- printk(OSST_DEB_MSG "osst%d:D: Ioctl %d,%d in %s mode\n", dev,
- cmd_type, cmd_nr, STp->raw?"raw":"normal");
-#endif
+
if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
struct mtop mtc;
@@ -4803,8 +4720,8 @@ static int osst_ioctl(struct inode * inode,struct file * file,
}
}
- if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM &&
- mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETBLK &&
+ if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
+ mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
STps->rw = ST_IDLE; /* Prevent automatic WEOF and fsf */
@@ -4856,10 +4773,7 @@ static int osst_ioctl(struct inode * inode,struct file * file,
}
if (mtc.mt_op == MTSEEK) {
- if (STp->raw)
- i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
- else
- i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
+ i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
if (!STp->can_partitions)
STp->ps[0].rw = ST_IDLE;
retval = i;
@@ -4964,10 +4878,7 @@ static int osst_ioctl(struct inode * inode,struct file * file,
retval = (-EINVAL);
goto out;
}
- if (STp->raw)
- blk = osst_get_frame_position(STp, &SRpnt);
- else
- blk = osst_get_sector(STp, &SRpnt);
+ blk = osst_get_sector(STp, &SRpnt);
if (blk < 0) {
retval = blk;
goto out;
@@ -5061,7 +4972,7 @@ static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma )
tb = NULL;
break;
}
- tb->sg[segs].page = NULL;
+ tb->sg[segs].page = NULL;
tb->sg[segs].length = b_size;
got += b_size;
segs++;
@@ -5513,8 +5424,6 @@ static int osst_attach(Scsi_Device * SDp)
tpnt->partition = 0;
tpnt->new_partition = 0;
tpnt->nbr_partitions = 0;
- tpnt->min_block = 512;
- tpnt->max_block = OS_DATA_SIZE;
tpnt->timeout = OSST_TIMEOUT;
tpnt->long_timeout = OSST_LONG_TIMEOUT;
@@ -5554,7 +5463,6 @@ static int osst_attach(Scsi_Device * SDp)
tpnt->current_mode = 0;
tpnt->modes[0].defined = TRUE;
- tpnt->modes[2].defined = TRUE;
tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE;
init_MUTEX(&tpnt->lock);
diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h
index 089433262..f3ecb546e 100644
--- a/drivers/scsi/osst.h
+++ b/drivers/scsi/osst.h
@@ -1,5 +1,5 @@
/*
- * $Header: /home/cvsroot/Driver/osst.h,v 1.12 2001/10/11 00:30:15 riede Exp $
+ * $Header: /home/cvsroot/Driver/osst.h,v 1.11 2001/01/26 01:54:49 riede Exp $
*/
#include <asm/byteorder.h>
@@ -638,5 +638,3 @@ typedef struct {
#define OS_WRITE_HEADER 4
#define OS_WRITE_FILLER 5
-/* Additional rw state */
-#define OS_WRITING_COMPLETE 3
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 05b5dae41..909b8c6cb 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -19,9 +19,9 @@
*/
#include <linux/config.h>
#ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.22 (20011128)";
+ static char sg_version_str[] = "Version: 3.1.20 (20010814)";
#endif
- static int sg_version_num = 30122; /* 2 digits for each component */
+ static int sg_version_num = 30120; /* 2 digits for each component */
/*
* D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
* - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -82,8 +82,6 @@ static void sg_proc_cleanup(void);
#include <linux/iobuf.h>
#endif
-#define SG_NEW_KIOVEC 0 /* use alloc_kiovec(), not alloc_kiovec_sz() */
-
int sg_big_buff = SG_DEF_RESERVED_SIZE;
/* N.B. This variable is readable and writeable via
/proc/scsi/sg/def_reserved_size . Each time sg_open() is called a buffer
@@ -138,10 +136,10 @@ static struct Scsi_Device_Template sg_template =
typedef struct sg_scatter_hold /* holding area for scsi scatter gather info */
{
unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
- unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
+ unsigned short sglist_len; /* size of malloc'd scatter-gather list */
unsigned bufflen; /* Size of (aggregate) data buffer */
unsigned b_malloc_len; /* actual len malloc'ed in buffer */
- void * buffer; /* Data buffer or scatter list + mem_src_arr */
+ void * buffer; /* Data buffer or scatter list,12 bytes each*/
struct kiobuf * kiobp; /* for direct IO information */
char mapped; /* indicates kiobp has locked pages */
char buffer_mem_src; /* heap whereabouts of 'buffer' */
@@ -184,7 +182,6 @@ typedef struct sg_fd /* holds the state of a file descriptor */
char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
- char mmap_called; /* 0 -> mmap() never called on this fd */
} Sg_fd; /* 2760 bytes long on i386 */
typedef struct sg_device /* holds the state of each scsi generic device */
@@ -206,8 +203,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt);
static int sg_start_req(Sg_request * srp);
static void sg_finish_rem_req(Sg_request * srp);
static int sg_build_indi(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
-static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
- int tablesize);
+static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp);
static ssize_t sg_new_read(Sg_fd * sfp, char * buf, size_t count,
Sg_request * srp);
static ssize_t sg_new_write(Sg_fd * sfp, const char * buf, size_t count,
@@ -237,14 +233,13 @@ static Sg_request * sg_get_rq_mark(Sg_fd * sfp, int pack_id);
static Sg_request * sg_add_request(Sg_fd * sfp);
static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
static int sg_res_in_use(Sg_fd * sfp);
+static void sg_clr_srpnt(Scsi_Request * SRpnt);
static int sg_ms_to_jif(unsigned int msecs);
-static inline unsigned sg_jif_to_ms(int jifs);
+static unsigned sg_jif_to_ms(int jifs);
static int sg_allow_access(unsigned char opcode, char dev_type);
static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
static void sg_unmap_and(Sg_scatter_hold * schp, int free_also);
static Sg_device * sg_get_dev(int dev);
-static inline int sg_alloc_kiovec(int nr, struct kiobuf **bufp, int *szp);
-static inline void sg_free_kiovec(int nr, struct kiobuf **bufp, int *szp);
#ifdef CONFIG_PROC_FS
static int sg_last_dev(void);
#endif
@@ -620,20 +615,6 @@ static ssize_t sg_new_write(Sg_fd * sfp, const char * buf, size_t count,
sg_remove_request(sfp, srp);
return -ENOSYS;
}
- if (hp->flags & SG_FLAG_MMAP_IO) {
- if (hp->dxfer_len > sfp->reserve.bufflen) {
- sg_remove_request(sfp, srp);
- return -ENOMEM; /* MMAP_IO size must fit in reserve buffer */
- }
- if (hp->flags & SG_FLAG_DIRECT_IO) {
- sg_remove_request(sfp, srp);
- return -EINVAL; /* either MMAP_IO or DIRECT_IO (not both) */
- }
- if (sg_res_in_use(sfp)) {
- sg_remove_request(sfp, srp);
- return -EBUSY; /* reserve buffer already being used */
- }
- }
timeout = sg_ms_to_jif(srp->header.timeout);
if ((! hp->cmdp) || (hp->cmd_len < 6) || (hp->cmd_len > sizeof(cmnd))) {
sg_remove_request(sfp, srp);
@@ -734,9 +715,7 @@ static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
(void *)SRpnt->sr_buffer, hp->dxfer_len,
sg_cmd_done_bh, timeout, SG_DEFAULT_RETRIES);
/* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,1)
generic_unplug_device(q);
-#endif
return 0;
}
@@ -870,7 +849,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
result = get_user(val, (int *)arg);
if (result) return result;
if (val != sfp->reserve.bufflen) {
- if (sg_res_in_use(sfp) || sfp->mmap_called)
+ if (sg_res_in_use(sfp))
return -EBUSY;
sg_remove_scat(&sfp->reserve);
sg_build_reserve(sfp, val);
@@ -1051,136 +1030,6 @@ static int sg_fasync(int fd, struct file * filp, int mode)
return (retval < 0) ? retval : 0;
}
-static void sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
-{
- void * page_ptr;
- struct page * page;
- int k, m;
-
- SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, "
- "scatg=%d\n", startFinish, rsv_schp->k_use_sg));
- /* N.B. correction _not_ applied to base page of aech allocation */
- if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
- struct scatterlist * sclp = rsv_schp->buffer;
-
- for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
- for (m = PAGE_SIZE; m < sclp->length; m += PAGE_SIZE) {
- page = sclp->page;
- if (startFinish)
- get_page(page); /* increment page count */
- else {
- if (page_count(page) > 0)
- put_page_testzero(page); /* decrement page count */
- }
- }
- }
- }
- else { /* reserve buffer is just a single allocation */
- for (m = PAGE_SIZE; m < rsv_schp->bufflen; m += PAGE_SIZE) {
- page_ptr = (unsigned char *)rsv_schp->buffer + m;
- page = virt_to_page(page_ptr);
- if (startFinish)
- get_page(page); /* increment page count */
- else {
- if (page_count(page) > 0)
- put_page_testzero(page); /* decrement page count */
- }
- }
- }
-}
-
-static struct page * sg_vma_nopage(struct vm_area_struct *vma,
- unsigned long addr, int unused)
-{
- Sg_fd * sfp;
- struct page * page = NOPAGE_SIGBUS;
- void * page_ptr = NULL;
- unsigned long offset;
- Sg_scatter_hold * rsv_schp;
-
- if ((NULL == vma) || (! (sfp = (Sg_fd *)vma->vm_private_data)))
- return page;
- rsv_schp = &sfp->reserve;
- offset = addr - vma->vm_start;
- if (offset >= rsv_schp->bufflen)
- return page;
- SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n",
- offset, rsv_schp->k_use_sg));
- if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
- int k;
- unsigned long sa = vma->vm_start;
- unsigned long len;
- struct scatterlist * sclp = rsv_schp->buffer;
-
- for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
- ++k, ++sclp) {
- len = vma->vm_end - sa;
- len = (len < sclp->length) ? len : sclp->length;
- if (offset < len) {
- get_page(sclp->page); /* increment page count */
- break;
- }
- sa += len;
- offset -= len;
- }
- }
- else { /* reserve buffer is just a single allocation */
- page_ptr = (unsigned char *)rsv_schp->buffer + offset;
- page = virt_to_page(page_ptr);
- get_page(page); /* increment page count */
- }
- return page;
-}
-
-static struct vm_operations_struct sg_mmap_vm_ops = {
- nopage : sg_vma_nopage,
-};
-
-static int sg_mmap(struct file * filp, struct vm_area_struct *vma)
-{
- Sg_fd * sfp;
- unsigned long req_sz = vma->vm_end - vma->vm_start;
- Sg_scatter_hold * rsv_schp;
-
- if ((! filp) || (! vma) || (! (sfp = (Sg_fd *)filp->private_data)))
- return -ENXIO;
- SCSI_LOG_TIMEOUT(3, printk("sg_mmap starting, vm_start=%p, len=%d\n",
- (void *)vma->vm_start, (int)req_sz));
- if (vma->vm_pgoff)
- return -EINVAL; /* want no offset */
- rsv_schp = &sfp->reserve;
- if (req_sz > rsv_schp->bufflen)
- return -ENOMEM; /* cannot map more than reserved buffer */
-
- if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
- int k;
- unsigned long sa = vma->vm_start;
- unsigned long len;
- struct scatterlist * sclp = rsv_schp->buffer;
-
- for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
- ++k, ++sclp) {
- if ((unsigned long)sclp->offset & (PAGE_SIZE - 1))
- return -EFAULT; /* non page aligned memory ?? */
- len = vma->vm_end - sa;
- len = (len < sclp->length) ? len : sclp->length;
- sa += len;
- }
- }
- else { /* reserve buffer is just a single allocation */
- if ((unsigned long)rsv_schp->buffer & (PAGE_SIZE - 1))
- return -EFAULT; /* non page aligned memory ?? */
- }
- if (0 == sfp->mmap_called) {
- sg_rb_correct4mmap(rsv_schp, 1); /* do only once per fd lifetime */
- sfp->mmap_called = 1;
- }
- vma->vm_flags |= (VM_RESERVED | VM_IO);
- vma->vm_private_data = sfp;
- vma->vm_ops = &sg_mmap_vm_ops;
- return 0;
-}
-
/* This function is a "bottom half" handler that is called by the
* mid level when a command is completed (or has failed). */
static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
@@ -1227,14 +1076,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
srp->data.sglist_len = SRpnt->sr_sglist_len;
srp->data.bufflen = SRpnt->sr_bufflen;
srp->data.buffer = SRpnt->sr_buffer;
- /* now clear out request structure */
- SRpnt->sr_use_sg = 0;
- SRpnt->sr_sglist_len = 0;
- SRpnt->sr_bufflen = 0;
- SRpnt->sr_buffer = NULL;
- SRpnt->sr_underflow = 0;
- SRpnt->sr_request.rq_dev = mk_kdev(0, 0); /* "sg" _disowns_ command blk */
-
+ sg_clr_srpnt(SRpnt);
srp->my_cmdp = NULL;
srp->done = 1;
read_unlock(&sg_dev_arr_lock);
@@ -1310,7 +1152,6 @@ static struct file_operations sg_fops = {
poll: sg_poll,
ioctl: sg_ioctl,
open: sg_open,
- mmap: sg_mmap,
release: sg_release,
fasync: sg_fasync,
};
@@ -1335,7 +1176,7 @@ static int sg_init()
if(!sg_registered) {
if (devfs_register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
{
- printk(KERN_ERR "Unable to get major %d for generic SCSI device\n",
+ printk("Unable to get major %d for generic SCSI device\n",
SCSI_GENERIC_MAJOR);
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
return 1;
@@ -1348,7 +1189,7 @@ static int sg_init()
sg_dev_arr = (Sg_device **)kmalloc(sg_template.dev_max *
sizeof(Sg_device *), GFP_ATOMIC);
if (NULL == sg_dev_arr) {
- printk(KERN_ERR "sg_init: no space for sg_dev_arr\n");
+ printk("sg_init: no space for sg_dev_arr\n");
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
return 1;
}
@@ -1371,8 +1212,8 @@ static int __init sg_def_reserved_size_setup(char *str)
sg_big_buff = tmp;
return 1;
} else {
- printk(KERN_WARNING "sg_def_reserved_size : usage "
- "sg_def_reserved_size=n (n could be 65536, 131072 or 262144)\n");
+ printk("sg_def_reserved_size : usage sg_def_reserved_size=n "
+ "(n could be 65536, 131072 or 262144)\n");
return 0;
}
}
@@ -1397,7 +1238,7 @@ static int sg_attach(Scsi_Device * scsidp)
if (NULL == tmp_da) {
scsidp->attached--;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- printk(KERN_ERR "sg_attach: device array cannot be resized\n");
+ printk("sg_attach: device array cannot be resized\n");
return 1;
}
memset(tmp_da, 0, tmp_dev_max * sizeof(Sg_device *));
@@ -1412,7 +1253,7 @@ static int sg_attach(Scsi_Device * scsidp)
if (k > MINORMASK) {
scsidp->attached--;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- printk(KERN_WARNING "Unable to attach sg device <%d, %d, %d, %d>"
+ printk("Unable to attach sg device <%d, %d, %d, %d>"
" type=%d, minor number exceed %d\n", scsidp->host->host_no,
scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,
MINORMASK);
@@ -1425,7 +1266,7 @@ static int sg_attach(Scsi_Device * scsidp)
if (NULL == sdp) {
scsidp->attached--;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- printk(KERN_ERR "sg_attach: Sg_device cannot be allocated\n");
+ printk("sg_attach: Sg_device cannot be allocated\n");
return 1;
}
@@ -1452,8 +1293,8 @@ static int sg_attach(Scsi_Device * scsidp)
case TYPE_WORM:
case TYPE_TAPE: break;
default:
- printk(KERN_NOTICE "Attached scsi generic sg%d at scsi%d, channel"
- " %d, id %d, lun %d, type %d\n", k, scsidp->host->host_no,
+ printk("Attached scsi generic sg%d at scsi%d, channel %d, id %d,"
+ " lun %d, type %d\n", k, scsidp->host->host_no,
scsidp->channel, scsidp->id, scsidp->lun, scsidp->type);
}
return 0;
@@ -1530,10 +1371,7 @@ static void sg_detach(Scsi_Device * scsidp)
MODULE_AUTHOR("Douglas Gilbert");
MODULE_DESCRIPTION("SCSI generic (sg) driver");
-
-#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
-#endif
MODULE_PARM(def_reserved_size, "i");
MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
@@ -1579,8 +1417,9 @@ static int sg_start_req(Sg_request * srp)
if (res <= 0) /* -ve -> error, 0 -> done, 1 -> try indirect */
return res;
}
- if ((! sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen))
+ if ((! sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen)) {
sg_link_reserve(sfp, srp, dxfer_len);
+ }
else {
res = sg_build_indi(req_schp, sfp, dxfer_len);
if (res) {
@@ -1606,24 +1445,23 @@ static void sg_finish_rem_req(Sg_request * srp)
sg_remove_request(sfp, srp);
}
-static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
- int tablesize)
+static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp)
{
int mem_src, ret_sz;
+ int sg_bufflen = PAGE_SIZE;
int elem_sz = sizeof(struct scatterlist) + sizeof(char);
- /* scatter gather array, followed by mem_src_arr (array of chars) */
- int sg_bufflen = tablesize * elem_sz;
- int mx_sc_elems = tablesize;
+ int mx_sc_elems = (sg_bufflen / elem_sz) - 1;
mem_src = SG_HEAP_KMAL;
- schp->buffer = sg_malloc(sfp, sg_bufflen, &ret_sz, &mem_src);
+ schp->buffer = (struct scatterlist *)sg_malloc(sfp, sg_bufflen,
+ &ret_sz, &mem_src);
+ schp->buffer_mem_src = (char)mem_src;
if (! schp->buffer)
return -ENOMEM;
else if (ret_sz != sg_bufflen) {
sg_bufflen = ret_sz;
- mx_sc_elems = sg_bufflen / elem_sz;
+ mx_sc_elems = (sg_bufflen / elem_sz) - 1;
}
- schp->buffer_mem_src = (char)mem_src;
schp->sglist_len = sg_bufflen;
memset(schp->buffer, 0, sg_bufflen);
return mx_sc_elems; /* number of scat_gath elements allocated */
@@ -1632,15 +1470,13 @@ static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
static void sg_unmap_and(Sg_scatter_hold * schp, int free_also)
{
#ifdef SG_ALLOW_DIO_CODE
- int nbhs = 0;
-
if (schp && schp->kiobp) {
if (schp->mapped) {
unmap_kiobuf(schp->kiobp);
schp->mapped = 0;
}
if (free_also) {
- sg_free_kiovec(1, &schp->kiobp, &nbhs);
+ free_kiovec(1, &schp->kiobp);
schp->kiobp = NULL;
}
}
@@ -1658,12 +1494,10 @@ static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
sg_io_hdr_t * hp = &srp->header;
Sg_scatter_hold * schp = &srp->data;
int sg_tablesize = sfp->parentdp->sg_tablesize;
- int nbhs = 0;
- res = sg_alloc_kiovec(1, &schp->kiobp, &nbhs);
+ res = alloc_kiovec(1, &schp->kiobp);
if (0 != res) {
- SCSI_LOG_TIMEOUT(5, printk("sg_build_dir: sg_alloc_kiovec res=%d\n",
- res));
+ SCSI_LOG_TIMEOUT(5, printk("sg_build_dir: alloc_kiovec res=%d\n", res));
return 1;
}
res = map_user_kiobuf((SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0,
@@ -1693,7 +1527,7 @@ static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
hp->info |= SG_INFO_DIRECT_IO;
return 0;
}
- mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
+ mx_sc_elems = sg_build_sgat(schp, sfp);
if (mx_sc_elems <= 1) {
sg_unmap_and(schp, 1);
sg_remove_scat(schp);
@@ -1701,7 +1535,7 @@ static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
}
mem_src_arr = schp->buffer + (mx_sc_elems * sizeof(struct scatterlist));
for (k = 0, sclp = schp->buffer, rem_sz = dxfer_len;
- (rem_sz > 0) && (k < mx_sc_elems);
+ (k < sg_tablesize) && (rem_sz > 0) && (k < mx_sc_elems);
++k, ++sclp) {
offset = (0 == k) ? kp->offset : 0;
num = (rem_sz > (PAGE_SIZE - offset)) ? (PAGE_SIZE - offset) :
@@ -1712,8 +1546,8 @@ static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
mem_src_arr[k] = SG_USER_MEM;
rem_sz -= num;
SCSI_LOG_TIMEOUT(5,
- printk("sg_build_dir: k=%d, a=0x%p, off=%d, len=%d, ms=%d\n",
- k, page_address(sclp->page), sclp->offset, num, mem_src_arr[k]));
+ printk("sg_build_dir: k=%d, a=0x%p, len=%d, ms=%d\n",
+ k, page_address(sclp->page) + sclp->offset, num, mem_src_arr[k]));
}
schp->k_use_sg = k;
SCSI_LOG_TIMEOUT(5,
@@ -1775,14 +1609,14 @@ static int sg_build_indi(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
char * mem_src_arr;
/* N.B. ret_sz and mem_src carried into this block ... */
- mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
+ mx_sc_elems = sg_build_sgat(schp, sfp);
if (mx_sc_elems < 0)
return mx_sc_elems; /* most likely -ENOMEM */
mem_src_arr = schp->buffer +
(mx_sc_elems * sizeof(struct scatterlist));
for (k = 0, sclp = schp->buffer, rem_sz = blk_size;
- (rem_sz > 0) && (k < mx_sc_elems);
+ (k < sg_tablesize) && (rem_sz > 0) && (k < mx_sc_elems);
++k, rem_sz -= ret_sz, ++sclp) {
if (first)
first = 0;
@@ -1793,14 +1627,14 @@ static int sg_build_indi(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
if (! p)
break;
}
- sclp->page = virt_to_page(p);
+ sclp->page = virt_to_page(p);
sclp->offset = ((unsigned long)p & ~PAGE_MASK);
sclp->length = ret_sz;
mem_src_arr[k] = mem_src;
SCSI_LOG_TIMEOUT(5,
printk("sg_build_build: k=%d, a=0x%p, len=%d, ms=%d\n",
- k, page_address(sclp->page), ret_sz, mem_src));
+ k, page_address(sclp->page) + sclp->offset, ret_sz, mem_src));
} /* end of for loop */
schp->k_use_sg = k;
SCSI_LOG_TIMEOUT(5,
@@ -1830,8 +1664,7 @@ static int sg_write_xfer(Sg_request * srp)
if (schp->bufflen < num_xfer)
num_xfer = schp->bufflen;
}
- if ((num_xfer <= 0) ||
- (new_interface && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
+ if ((num_xfer <= 0) || (new_interface && (SG_FLAG_NO_DXFER & hp->flags)))
return 0;
SCSI_LOG_TIMEOUT(4,
@@ -1873,7 +1706,7 @@ static int sg_write_xfer(Sg_request * srp)
for (; (k < schp->k_use_sg) && p;
++k, ++sclp, ksglen = (int)sclp->length,
- p = page_address(sclp->page) + sclp->offset) {
+ p = page_address(sclp->page) + sclp->offset) {
ok = (SG_USER_MEM != mem_src_arr[k]);
if (usglen <= 0)
break;
@@ -1934,7 +1767,7 @@ static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
static char * sg_get_sgat_msa(Sg_scatter_hold * schp)
{
int elem_sz = sizeof(struct scatterlist) + sizeof(char);
- int mx_sc_elems = schp->sglist_len / elem_sz;
+ int mx_sc_elems = (schp->sglist_len / elem_sz) - 1;
return schp->buffer + (sizeof(struct scatterlist) * mx_sc_elems);
}
@@ -1951,9 +1784,9 @@ static void sg_remove_scat(Sg_scatter_hold * schp)
mem_src = mem_src_arr[k];
SCSI_LOG_TIMEOUT(5,
printk("sg_remove_scat: k=%d, a=0x%p, len=%d, ms=%d\n",
- k, page_address(sclp->page), sclp->length, mem_src));
+ k, page_address(sclp->page) + sclp->offset, sclp->length, mem_src));
sg_free(page_address(sclp->page) + sclp->offset, sclp->length, mem_src);
- sclp->page = NULL;
+ sclp->page = NULL;
sclp->length = 0;
}
sg_free(schp->buffer, schp->sglist_len, schp->buffer_mem_src);
@@ -1981,8 +1814,7 @@ static int sg_read_xfer(Sg_request * srp)
if (schp->bufflen < num_xfer)
num_xfer = schp->bufflen;
}
- if ((num_xfer <= 0) ||
- (new_interface && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
+ if ((num_xfer <= 0) || (new_interface && (SG_FLAG_NO_DXFER & hp->flags)))
return 0;
SCSI_LOG_TIMEOUT(4,
@@ -2024,7 +1856,7 @@ static int sg_read_xfer(Sg_request * srp)
for (; (k < schp->k_use_sg) && p;
++k, ++sclp, ksglen = (int)sclp->length,
- p = page_address(sclp->page) + sclp->offset) {
+ p = page_address(sclp->page) + sclp->offset) {
ok = (SG_USER_MEM != mem_src_arr[k]);
if (usglen <= 0)
break;
@@ -2358,8 +2190,6 @@ static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
if (sfp->reserve.bufflen > 0) {
SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp: bufflen=%d, k_use_sg=%d\n",
(int)sfp->reserve.bufflen, (int)sfp->reserve.k_use_sg));
- if (sfp->mmap_called)
- sg_rb_correct4mmap(&sfp->reserve, 0); /* undo correction */
sg_remove_scat(&sfp->reserve);
}
sfp->parentdp = NULL;
@@ -2408,7 +2238,7 @@ static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
/* MOD_INC's to inhibit unloading sg and associated adapter driver */
if (sg_template.module)
__MOD_INC_USE_COUNT(sg_template.module);
- if (sdp->device->host->hostt->module)
+ if (sdp->device->host->hostt->module)
__MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
SCSI_LOG_TIMEOUT(1, printk(
"sg_remove_sfp: worrisome, %d writes pending\n", dirty));
@@ -2482,8 +2312,7 @@ static char * sg_low_malloc(int rqSz, int lowDma, int mem_src, int * retSzp)
if (retSzp) *retSzp = resSz;
}
else
- printk(KERN_ERR "sg_low_malloc: bad mem_src=%d, rqSz=%df\n",
- mem_src, rqSz);
+ printk("sg_low_malloc: bad mem_src=%d, rqSz=%df\n", mem_src, rqSz);
return resp;
}
@@ -2518,7 +2347,7 @@ static char * sg_malloc(const Sg_fd * sfp, int size, int * retSzp,
if (resp && retSzp) *retSzp = size;
break;
case SG_HEAP_KMAL:
- l_ms = SG_HEAP_KMAL; /* was SG_HEAP_PAGE */
+ l_ms = SG_HEAP_PAGE;
resp = sg_low_malloc(size, low_dma, l_ms, 0);
if (resp)
break;
@@ -2537,15 +2366,6 @@ static char * sg_malloc(const Sg_fd * sfp, int size, int * retSzp,
return resp;
}
-static inline int sg_alloc_kiovec(int nr, struct kiobuf **bufp, int *szp)
-{
-#if SG_NEW_KIOVEC
- return alloc_kiovec_sz(nr, bufp, szp);
-#else
- return alloc_kiovec(nr, bufp);
-#endif
-}
-
static void sg_low_free(char * buff, int size, int mem_src)
{
if (! buff) return;
@@ -2573,7 +2393,7 @@ static void sg_low_free(char * buff, int size, int mem_src)
case SG_USER_MEM:
break; /* nothing to do */
default:
- printk(KERN_ERR "sg_low_free: bad mem_src=%d, buff=0x%p, rqSz=%d\n",
+ printk("sg_low_free: bad mem_src=%d, buff=0x%p, rqSz=%d\n",
mem_src, buff, size);
break;
}
@@ -2589,13 +2409,14 @@ static void sg_free(char * buff, int size, int mem_src)
sg_low_free(buff, size, mem_src);
}
-static inline void sg_free_kiovec(int nr, struct kiobuf **bufp, int *szp)
+static void sg_clr_srpnt(Scsi_Request * SRpnt)
{
-#if SG_NEW_KIOVEC
- free_kiovec_sz(nr, bufp, szp);
-#else
- free_kiovec(nr, bufp);
-#endif
+ SRpnt->sr_use_sg = 0;
+ SRpnt->sr_sglist_len = 0;
+ SRpnt->sr_bufflen = 0;
+ SRpnt->sr_buffer = NULL;
+ SRpnt->sr_underflow = 0;
+ SRpnt->sr_request.rq_dev = mk_kdev(0, 0); /* "sg" _disowns_ command blk */
}
static int sg_ms_to_jif(unsigned int msecs)
@@ -2607,7 +2428,7 @@ static int sg_ms_to_jif(unsigned int msecs)
: (((int)msecs / 1000) * HZ);
}
-static inline unsigned sg_jif_to_ms(int jifs)
+static unsigned sg_jif_to_ms(int jifs)
{
if (jifs <= 0)
return 0U;
@@ -2657,8 +2478,8 @@ static Sg_device * sg_get_dev(int dev)
if (sg_dev_arr && (dev >= 0))
{
read_lock_irqsave(&sg_dev_arr_lock, iflags);
- if (dev < sg_template.dev_max)
- sdp = sg_dev_arr[dev];
+ if (dev < sg_template.dev_max)
+ sdp = sg_dev_arr[dev];
read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
}
return sdp;
@@ -2851,7 +2672,7 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin,
{
Sg_device * sdp;
const sg_io_hdr_t * hp;
- int j, max_dev, new_interface;
+ int j, max_dev;
if (NULL == sg_dev_arr) {
PRINT_PROC("sg_dev_arr NULL, driver not initialized\n");
@@ -2897,10 +2718,8 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin,
(int)fp->keep_orphan, (int)fp->closed);
for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) {
hp = &srp->header;
- new_interface = (hp->interface_id == '\0') ? 0 : 1;
/* stop indenting so far ... */
- PRINT_PROC(srp->res_used ? ((new_interface &&
- (SG_FLAG_MMAP_IO & hp->flags)) ? " mmap>> " : " rb>> ") :
+ PRINT_PROC(srp->res_used ? " rb>> " :
((SG_INFO_DIRECT_IO_MASK & hp->info) ? " dio>> " : " "));
blen = srp->my_cmdp ? srp->my_cmdp->sr_bufflen : srp->data.bufflen;
usg = srp->my_cmdp ? srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
@@ -2910,8 +2729,8 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin,
if (srp->done)
PRINT_PROC(" dur=%d", hp->duration);
else
- PRINT_PROC(" t_o/elap=%d/%d", new_interface ? hp->timeout :
- sg_jif_to_ms(fp->timeout),
+ PRINT_PROC(" t_o/elap=%d/%d", ((hp->interface_id == '\0') ?
+ sg_jif_to_ms(fp->timeout) : hp->timeout),
sg_jif_to_ms(hp->duration ? (jiffies - hp->duration) : 0));
PRINT_PROC("ms sgat=%d op=0x%02x\n", usg, (int)srp->data.cmd_opcode);
/* reset indenting */
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index 863b89120..26ee7fea2 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -11,20 +11,9 @@ Original driver (sg.h):
Version 2 and 3 extensions to driver:
* Copyright (C) 1998 - 2001 Douglas Gilbert
- Version: 3.1.22 (20011128)
+ Version: 3.1.20 (20010814)
This version is for 2.4 series kernels.
- Changes since 3.1.21 (20011029)
- - add support for SG_FLAG_MMAP_IO [permit mmap() on sg devices]
- - update documentation pointers in this header
- - put KERNEL_VERSION macros around code that breaks early 2.4 series
- - switch back to alloc_kiovec()
- Changes since 3.1.20 (20010814)
- - use alloc_kiovec_sz() to speed dio [set num_buffer_heads==0]
- - changes to cope with larger scatter gather element sizes
- - clean up some printk()s
- - add MODULE_LICENSE("GPL") [in a 3.1.20 subversion]
- - fix race around generic_unplug_device() [in a 3.1.20 subversion]
Changes since 3.1.19 (20010623)
- add SG_GET_ACCESS_COUNT ioctl
- make open() increment and close() decrement access_count
@@ -44,57 +33,56 @@ Version 2 and 3 extensions to driver:
Map of SG verions to the Linux kernels in which they appear:
---------- ----------------------------------
original all kernels < 2.2.6
- 2.1.40 2.2.20
+ 2.1.38 2.2.16
+ 2.1.39 2.2.17 - 2.2.19
3.0.x optional version 3 sg driver for 2.2 series
- 3.1.17++ 2.4.0++
+ 3.1.17 2.4.0 ++
Major new features in SG 3.x driver (cf SG 2.x drivers)
- SG_IO ioctl() combines function if write() and read()
- new interface (sg_io_hdr_t) but still supports old interface
- - scatter/gather in user space, direct IO, and mmap supported
-
- The normal action of this driver is to use the adapter (HBA) driver to DMA
- data into kernel buffers and then use the CPU to copy the data into the
- user space (vice versa for writes). That is called "indirect" IO due to
- the double handling of data. There are two methods offered to remove the
- redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and
- 2) using the mmap() system call to map the reserve buffer (this driver has
- one reserve buffer per fd) into the user space. Both have their advantages.
- In terms of absolute speed mmap() is faster. If speed is not a concern,
- indirect IO should be fine. Read the documentation for more information.
+ - scatter/gather in user space and direct IO supported
+
+ The term "indirect IO" refers a method by which data is DMAed into kernel
+ buffers from the hardware and afterwards is transferred into the user
+ space (or vice versa if you are writing). Transfer speeds of up to 20 to
+ 30MBytes/sec have been measured using indirect IO. For faster throughputs
+ "direct IO" which cuts out the double handling of data is required.
+ Direct IO is supported by the SG 3.x drivers on 2.4 series Linux kernels
+ and requires the use of the new interface.
+
+ Requests for direct IO with the new interface will automatically fall back
+ to indirect IO mode if they cannot be fulfilled. An example of such a case
+ is an ISA SCSI adapter which is only capable of DMAing to the lower 16MB of
+ memory due to the architecture of ISA. The 'info' field in the new
+ interface indicates whether a direct or indirect data transfer took place.
+
+ Obtaining memory for the kernel buffers used in indirect IO is done by
+ first checking if the "reserved buffer" for the current file descriptor
+ is available and large enough. If these conditions are _not_ met then
+ kernel memory is obtained on a per SCSI command basis. This corresponds
+ to a write(), read() sequence or a SG_IO ioctl() call. Further, the
+ kernel memory that is suitable for DMA may be constrained by the
+ architecture of the SCSI adapter (e.g. ISA adapters).
** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be
needed. That pseudo file's content is defaulted to 0. **
-
- Historical note: this SCSI pass-through driver has been known as "sg" for
- a decade. In broader kernel discussions "sg" is used to refer to scatter
- gather techniques. The context should clarify which "sg" is referred to.
Documentation
=============
- A web site for the SG device driver can be found at:
+ A web site for SG device drivers can be found at:
http://www.torque.net/sg [alternatively check the MAINTAINERS file]
- The documentation for the sg version 3 driver can be found at:
- http://www.torque.net/sg/p/sg_v3_ho.html
- This is a rendering from DocBook source [change the extension to "sgml"
- or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
-
- The older, version 2 documents discuss the original sg interface in detail:
+ The main documents are still based on 2.x versions:
http://www.torque.net/sg/p/scsi-generic.txt
http://www.torque.net/sg/p/scsi-generic_long.txt
+ Documentation on the changes and additions in 3.x version of the sg driver
+ can be found at: http://www.torque.net/sg/p/scsi-generic_v3.txt
A version of this document (potentially out of date) may also be found in
the kernel source tree, probably at:
/usr/src/linux/Documentation/scsi-generic.txt .
-
- Utility and test programs are available at the sg web site. They are
- bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the
- lk 2.4 series).
-
- There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at:
- http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO
+ Utility and test programs are available at the sg web site.
*/
-
/* New interface introduced in the 3.x SG drivers follows */
typedef struct sg_iovec /* same structure as used by readv() Linux system */
@@ -132,20 +120,19 @@ typedef struct sg_io_hdr
} sg_io_hdr_t; /* 64 bytes long (on i386) */
/* Use negative values to flag difference from original sg_header structure */
-#define SG_DXFER_NONE (-1) /* e.g. a SCSI Test Unit Ready command */
-#define SG_DXFER_TO_DEV (-2) /* e.g. a SCSI WRITE command */
-#define SG_DXFER_FROM_DEV (-3) /* e.g. a SCSI READ command */
-#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the
+#define SG_DXFER_NONE -1 /* e.g. a SCSI Test Unit Ready command */
+#define SG_DXFER_TO_DEV -2 /* e.g. a SCSI WRITE command */
+#define SG_DXFER_FROM_DEV -3 /* e.g. a SCSI READ command */
+#define SG_DXFER_TO_FROM_DEV -4 /* treated like SG_DXFER_FROM_DEV with the
additional property than during indirect
IO the user buffer is copied into the
kernel buffers before the transfer */
-#define SG_DXFER_UNKNOWN (-5) /* Unknown data direction */
+#define SG_DXFER_UNKNOWN -5 /* Unknown data direction */
/* following flag values can be "or"-ed together */
#define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */
-#define SG_FLAG_LUN_INHIBIT 2 /* default is overwrite lun in SCSI */
- /* command block (when <= SCSI_2) */
-#define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */
+#define SG_FLAG_LUN_INHIBIT 2 /* default is to put device's lun into */
+ /* the 2nd byte of SCSI command */
#define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */
/* user space (debug indirect IO) */