patrice peretti wrote:

Bonjour a tous

Slt



J ai installer un seveur de fichier samba sous debian qui 'ailleur fonctionne a merveille pour remplacer une station NT . Je desirerai maintenant y ajoindre un lecteru onstream di 30 pour effectuer les sauvegardes. Le lecteur est reconnu par le systeme mais il est impossible d'y acceder ( celui ci se trouve sur hdb)

Il faut utiliser utiliser ce lecteur avec le module ide-scsi et non pas avec le module ide-tape. Il faut que tu patches le noyau : t�l�charge la version officielle du driver (http://www.linux1onstream.nl/test/onstream-20021231.tar.gz) ou utilises le patch joint Ensuite il faudra que tu cr�es les nodes dans /dev (tu trouveras un script dans les pages ci-dessous)
Utilises /dev/nosst0 et /dev/osst0 pour acc�der au lecteur.
Je l'utilise avec amanda et il marche tr�s bien


Si quelqu'un savait ou je peut trouver un howto pour installer un onstream sous debian, je lui serais infiniment reconnaissant ??

Site interessant : http://www.netaxs.com/~vossenjp/linux/linux.html

Site tr�s interessant : http://www.linux1onstream.nl/test/ide-tape.html

Site tr�s interessant : http://www.linux1onstream.nl/test/README.osst

Site tr�s interessant : http://www.e-smith.org/docs/howto/contrib/onstreamdi30-howto.htm

Document utile : http://www.linuxtapecert.org/di30_install.html


Merci encore de l'aide que vous pourriez m'apporter

Patrice

diff -Naur linux-2.4.20/drivers/scsi/osst.c linux-2.4.20-neo/drivers/scsi/osst.c
--- linux-2.4.20/drivers/scsi/osst.c    2001-12-21 18:41:55.000000000 +0100
+++ linux-2.4.20-neo/drivers/scsi/osst.c        2002-12-13 01:54:43.000000000 
+0100
@@ -16,15 +16,15 @@
   Copyright 1992 - 2000 Kai Makisara
                 email [EMAIL PROTECTED]
 
-  $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.67 2002/12/13 00:54:43 riede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last modified: Wed Feb  2 22:04:05 2000 by [EMAIL PROTECTED]
   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.67 2002/12/13 00:54:43 riede Exp 
$";
+const char * osst_version = "0.9.12";
 
 /* 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>
@@ -75,28 +76,27 @@
 
 #include "constants.h"
 
-static int buffer_kbs = 0;
+static int max_dev = 0;
 static int write_threshold_kbs = 0;
-static int max_buffers = 0;
 static int max_sg_segs = 0;
 
 #ifdef MODULE
 MODULE_AUTHOR("Willem Riede");
 MODULE_DESCRIPTION("OnStream SCSI Tape Driver");
+#ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
+#endif
 
-MODULE_PARM(buffer_kbs, "i");
+MODULE_PARM(max_dev, "i");
 MODULE_PARM(write_threshold_kbs, "i");
-MODULE_PARM(max_buffers, "i");
 MODULE_PARM(max_sg_segs, "i");
 #else
 static struct osst_dev_parm {
        char   *name;
        int    *val;
 } parms[] __initdata = {
-       { "buffer_kbs",          &buffer_kbs          },
+       { "max_dev",             &max_dev             },
        { "write_threshold_kbs", &write_threshold_kbs },
-       { "max_buffers",         &max_buffers         },
        { "max_sg_segs",         &max_sg_segs         }
        };
 #endif
@@ -117,11 +117,16 @@
 // #define OSST_INJECT_ERRORS 1 
 #endif
 
-#define MAX_RETRIES 0
+#define MAX_RETRIES 2
+#define MAX_READ_RETRIES 0
 #define MAX_WRITE_RETRIES 0
-#define MAX_READY_RETRIES 5
+#define MAX_READY_RETRIES 0
 #define NO_TAPE  NOT_READY
 
+#define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
+#define OSST_WAIT_WRITE_COMPLETE      (HZ / 12)
+#define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
+
 #define OSST_TIMEOUT (200 * HZ)
 #define OSST_LONG_TIMEOUT (1800 * HZ)
 
@@ -137,6 +142,7 @@
 static int osst_write_threshold   = OSST_WRITE_THRESHOLD;
 static int osst_max_buffers       = OSST_MAX_BUFFERS;
 static int osst_max_sg_segs       = OSST_MAX_SG;
+static int osst_max_dev           = OSST_MAX_TAPES;
 
 static OS_Scsi_Tape **os_scsi_tapes = NULL;
 static OSST_buffer  **osst_buffers  = NULL;
@@ -539,8 +545,6 @@
                                 STp->first_frame_position);
                goto err_out;
        }
-       STp->frame_in_buffer = 1;
-
         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != 
frame_seq_number) {
                if (!quiet)
 #if DEBUG
@@ -567,12 +571,14 @@
        }
        if (aux->frame_type == OS_FRAME_TYPE_EOD) {
                STps->eof = ST_EOD_1;
+               STp->frame_in_buffer = 1;
        }
        if (aux->frame_type == OS_FRAME_TYPE_DATA) {
                 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
                blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
                STp->buffer->buffer_bytes = blk_cnt * blk_sz;
                STp->buffer->read_pointer = 0;
+               STp->frame_in_buffer = 1;
 
                /* See what block size was used to write file */
                if (STp->block_size != blk_sz && blk_sz > 0) {
@@ -599,18 +605,23 @@
 /*
  * Wait for the unit to become Ready
  */
-static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, 
unsigned timeout)
+static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, 
unsigned timeout, int initial_delay)
 {
        unsigned char   cmd[MAX_COMMAND_SIZE];
        Scsi_Request  * SRpnt;
        long            startwait = jiffies;
 #if DEBUG
        int             dbg = debugging;
-       int             dev  = TAPE_NR(STp->devt);
+       int             dev = TAPE_NR(STp->devt);
 
        printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait ready\n", dev);
 #endif
 
+       if (initial_delay > 0) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(initial_delay);
+       }
+
        memset(cmd, 0, MAX_COMMAND_SIZE);
        cmd[0] = TEST_UNIT_READY;
 
@@ -722,10 +733,10 @@
 {
        int     retval;
 
-       osst_wait_ready(STp, aSRpnt, 15 * 60);                  /* TODO - can 
this catch a write error? */
+       osst_wait_ready(STp, aSRpnt, 15 * 60, 0);                       /* TODO 
- can this catch a write error? */
        retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
        if (retval) return (retval);
-       osst_wait_ready(STp, aSRpnt, 15 * 60);
+       osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
        return (osst_get_frame_position(STp, aSRpnt));
 }
 
@@ -738,6 +749,7 @@
        Scsi_Request  * SRpnt;
 
        int             result = 0;
+       int             delay  = OSST_WAIT_WRITE_COMPLETE;
 #if DEBUG
        int             dev  = TAPE_NR(STp->devt);
 
@@ -751,12 +763,17 @@
        SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, 
STp->timeout, MAX_WRITE_RETRIES, TRUE);
        *aSRpnt = SRpnt;
        if (!SRpnt) return (-EBUSY);
-
-       if ((STp->buffer)->syscall_result)
-               result = osst_write_error_recovery(STp, aSRpnt, 0);
-
-       result |= osst_wait_ready(STp, aSRpnt, 5 * 60);
+       if (STp->buffer->syscall_result) {
+               if ((SRpnt->sr_sense_buffer[2] & 0x0f) == 2 && 
SRpnt->sr_sense_buffer[12] == 4) {
+                       if (SRpnt->sr_sense_buffer[13] == 8) {
+                               delay = OSST_WAIT_LONG_WRITE_COMPLETE;
+                       }
+               } else
+                       result = osst_write_error_recovery(STp, aSRpnt, 0);
+       }
+       result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
        STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
+
        return (result);
 }
 
@@ -847,7 +864,7 @@
            printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tape\n", 
dev);
 #endif
        SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-                                     STp->timeout, MAX_RETRIES, TRUE);
+                                     STp->timeout, MAX_READ_RETRIES, TRUE);
        *aSRpnt = SRpnt;
        if (!SRpnt)
            return (-EBUSY);
@@ -903,7 +920,8 @@
 #endif
 
        if (STps->rw != ST_READING) {         /* Initialize read operation */
-               if (STps->rw == ST_WRITING) {
+               if (STps->rw == ST_WRITING || STp->dirty) {
+                       STp->write_type = OS_WRITE_DATA;
                         osst_flush_write_buffer(STp, aSRpnt);
                        osst_flush_drive_buffer(STp, aSRpnt);
                }
@@ -921,7 +939,7 @@
 #if DEBUG
                printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream 
tape\n", dev);
 #endif
-               SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, 
STp->timeout, MAX_RETRIES, TRUE);
+               SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, 
STp->timeout, MAX_READ_RETRIES, TRUE);
                *aSRpnt = SRpnt;
                retval  = STp->buffer->syscall_result;
        }
@@ -940,6 +958,15 @@
                      position;
 
        /*
+        * If we want just any frame (-1) and there is a frame in the buffer, 
return it
+        */
+       if (frame_seq_number == -1 && STp->frame_in_buffer) {
+#if DEBUG
+               printk(OSST_DEB_MSG "osst%d:D: Frame %d still in buffer\n", 
dev, STp->frame_seq_number);
+#endif
+               return (STps->eof);
+       }
+       /*
          * Search and wait for the next logical tape frame
         */
        while (1) {
@@ -1092,6 +1119,7 @@
                    if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
                    move               /= (OS_DATA_SIZE / STp->block_size);
                 }
+                if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : 
-1;
 #if DEBUG
                 printk(OSST_DEB_MSG
                        "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn 
%d (need %d) move %d\n",
@@ -1289,7 +1317,7 @@
                cmd[8] = 32768 & 0xff;
 
                SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, 
SCSI_DATA_READ,
-                                           STp->timeout, MAX_RETRIES, TRUE);
+                                           STp->timeout, MAX_READ_RETRIES, 
TRUE);
        
                if ((STp->buffer)->syscall_result || !SRpnt) {
                        printk(KERN_ERR "osst%d:E: Failed to read frame back 
from OnStream buffer\n", dev);
@@ -1329,7 +1357,7 @@
                                                dev, new_frame+i, 
frame_seq_number+i);
 #endif
                        osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
-                       osst_wait_ready(STp, aSRpnt, 60);
+                       osst_wait_ready(STp, aSRpnt, 60, 
OSST_WAIT_POSITION_COMPLETE);
                        osst_get_frame_position(STp, aSRpnt);
                        SRpnt = * aSRpnt;
 
@@ -1397,6 +1425,7 @@
                                        if (SRpnt->sr_sense_buffer[2] == 2 && 
SRpnt->sr_sense_buffer[12] == 4 &&
                                            (SRpnt->sr_sense_buffer[13] == 1 || 
SRpnt->sr_sense_buffer[13] == 8)) {
                                                /* in the process of becoming 
ready */
+                                               
set_current_state(TASK_INTERRUPTIBLE);
                                                schedule_timeout(HZ / 10);
                                                continue;
                                        }
@@ -1469,6 +1498,8 @@
                        osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
                        flag = 0;
                        attempts--;
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(HZ / 10);
                }
                if (osst_get_frame_position(STp, aSRpnt) < 0) {         /* 
additional write error */
 #if DEBUG
@@ -1529,6 +1560,7 @@
                        debugging = 0;
                }
 #endif
+               set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(HZ / 10);
        }
        printk(KERN_ERR "osst%d:E: Failed to find valid tape media\n", dev);
@@ -1674,12 +1706,7 @@
                                                 dev, last_mark_ppos);
                                return (-EIO);
                        }
-                       if (mt_op == MTBSFM) {
-                               STp->frame_seq_number++;
-                               STp->frame_in_buffer  = 0;
-                               STp->logical_blk_num += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
-                       }
-                       return 0;
+                       goto found;
                }
 #if DEBUG
                printk(OSST_DEB_MSG "osst%d:D: Reverting to scan filemark 
backwards\n", dev);
@@ -1707,10 +1734,13 @@
                        return (-EIO);
                }
        }
+found:
        if (mt_op == MTBSFM) {
                STp->frame_seq_number++;
-               STp->frame_in_buffer  = 0;
-               STp->logical_blk_num += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+               STp->frame_in_buffer      = 0;
+               STp->buffer->buffer_bytes = 0;
+               STp->buffer->read_pointer = 0;
+               STp->logical_blk_num     += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
        }
        return 0;
 }
@@ -1763,8 +1793,10 @@
        }
        if (mt_op == MTFSF) {
                STp->frame_seq_number++;
-               STp->frame_in_buffer  = 0;
-               STp->logical_blk_num += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+               STp->frame_in_buffer      = 0;
+               STp->buffer->buffer_bytes = 0;
+               STp->buffer->read_pointer = 0;
+               STp->logical_blk_num     += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
        }
        return 0;
 }
@@ -1910,8 +1942,10 @@
        }
        if (mt_op == MTFSF) {
                STp->frame_seq_number++;
-               STp->frame_in_buffer  = 0;
-               STp->logical_blk_num += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+               STp->frame_in_buffer      = 0;
+               STp->buffer->buffer_bytes = 0;
+               STp->buffer->read_pointer = 0;
+               STp->logical_blk_num     += 
ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
        }
        return 0;
 }
@@ -2011,7 +2045,7 @@
 #if DEBUG
        printk(OSST_DEB_MSG "osst%d:D: Reached onstream write filler group 
%d\n", dev, where);
 #endif
-       osst_wait_ready(STp, aSRpnt, 60 * 5);
+       osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
        osst_set_frame_position(STp, aSRpnt, where, 0);
        STp->write_type = OS_WRITE_FILLER;
        while (count--) {
@@ -2037,7 +2071,7 @@
 #if DEBUG
        printk(OSST_DEB_MSG "osst%d:D: Reached onstream write header group 
%d\n", dev, where);
 #endif
-       osst_wait_ready(STp, aSRpnt, 60 * 5);
+       osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
        osst_set_frame_position(STp, aSRpnt, where, 0);
        STp->write_type = OS_WRITE_HEADER;
        while (count--) {
@@ -2377,11 +2411,12 @@
 
 static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
 {
+       int     write_pass      = STp->wrt_pass_cntr;
        int     frame_position  = STp->first_frame_position;
-       int frame_seq_numbr = STp->frame_seq_number;
+       int     frame_seq_numbr = STp->frame_seq_number;
        int     logical_blk_num = STp->logical_blk_num;
-               int halfway_frame   = STp->frame_in_buffer;
-       int read_pointer    = STp->buffer->read_pointer;
+       int     halfway_frame   = STp->frame_in_buffer;
+       int     read_pointer    = STp->buffer->read_pointer;
        int     prev_mark_ppos  = -1;
        int     actual_mark_ppos, i, n;
 #if DEBUG
@@ -2389,12 +2424,24 @@
 
        printk(OSST_DEB_MSG "osst%d:D: Verify that the tape is really the one 
we think before writing\n", dev);
 #endif
-       osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
-       if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
+       if (frame_position <= STp->first_data_ppos) {
+               /* check header match */
+               if (!osst_analyze_headers(STp, aSRpnt) ||
+                   (write_pass != STp->wrt_pass_cntr)) {
 #if DEBUG
-               printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in 
verify_position\n", dev);
+                        printk(OSST_DEB_MSG "osst%d:D: Couldn't match header 
in verify_position\n", dev);
 #endif
-               return (-EIO);
+                        return (-EIO);
+               }
+       } else {
+               /* find preceding data frame of current write pass */
+               osst_set_frame_position(STp, aSRpnt, frame_position - 1, 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 verify_position\n", dev);
+#endif
+                       return (-EIO);
+               }
        }
        if (STp->linux_media_version >= 4) {
                for (i=0; i<STp->filemark_cnt; i++)
@@ -2671,7 +2718,7 @@
 
        STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
        SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ,
-                                     STp->timeout, MAX_READY_RETRIES, TRUE);
+                                     STp->timeout, MAX_RETRIES, TRUE);
        if (!SRpnt) {
                STp->buffer->b_data = olddata; STp->buffer->buffer_size = 
oldsize;
                return (-EBUSY);
@@ -2692,7 +2739,7 @@
                        scmd[0] = READ_POSITION;
                        STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 
24;
                        SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, 
SCSI_DATA_READ,
-                                                   STp->timeout, 
MAX_READY_RETRIES, TRUE);
+                                                   STp->timeout, MAX_RETRIES, 
TRUE);
                        if (!STp->buffer->syscall_result)
                                memcpy (SRpnt->sr_sense_buffer, mysense, 16);
                }
@@ -2764,7 +2811,7 @@
                        scmd[9] = 0x80;
 
                SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, 
STp->long_timeout,
-                                                               
MAX_READY_RETRIES, TRUE);
+                                                               MAX_RETRIES, 
TRUE);
                if (!SRpnt)
                        return (-EBUSY);
                *aSRpnt  = SRpnt;
@@ -2777,7 +2824,7 @@
                        result = (-EIO);
                }
                if (pp != ppos)
-                       osst_wait_ready(STp, aSRpnt, 5 * 60);
+                       osst_wait_ready(STp, aSRpnt, 5 * 60, 
OSST_WAIT_POSITION_COMPLETE);
        } while ((pp != ppos) && (pp = ppos));
        STp->first_frame_position = STp->last_frame_position = ppos;
        STps->eof = ST_NOEOF;
@@ -2941,9 +2988,10 @@
                return 0;
 
        STps = &(STp->ps[STp->partition]);
-       if (STps->rw == ST_WRITING)  /* Writing */
+       if (STps->rw == ST_WRITING || STp->dirty) {     /* Writing */
+               STp->write_type = OS_WRITE_DATA;
                return osst_flush_write_buffer(STp, aSRpnt);
-
+       }
        if (STp->block_size == 0)
                return 0;
 
@@ -3166,12 +3214,16 @@
 
 
        if (STps->rw == ST_READING) {
+#if DEBUG
+               printk(OSST_DEB_MSG "osst%d:D: Switching from read to write at 
file %d, block %d\n", dev, 
+                                       STps->drv_file, STps->drv_block);
+#endif
                retval = osst_flush_buffer(STp, &SRpnt, 0);
                if (retval)
                        goto out;
                STps->rw = ST_IDLE;
        }
-       else if (STps->rw != ST_WRITING) {
+       if (STps->rw != ST_WRITING) {
                /* Are we totally rewriting this tape? */
                if (!STp->header_ok ||
                    (STp->first_frame_position == STp->first_data_ppos && 
STps->drv_block < 0) ||
@@ -3524,9 +3576,19 @@
                            printk(OSST_DEB_MSG "osst%d:D: EOF up (%d). Left 
%d, needed %d.\n", dev,
                                                 STps->eof, 
(STp->buffer)->buffer_bytes, count - total);
 #endif
+                       /* force multiple of block size, note block_size may 
have been adjusted */
                        transfer = (((STp->buffer)->buffer_bytes < count - 
total ?
                                     (STp->buffer)->buffer_bytes : count - 
total)/
-                                       STp->block_size) * STp->block_size; /* 
force multiple of block size */
+                                       STp->block_size) * STp->block_size;
+
+                       if (transfer == 0) {
+                               printk(KERN_WARNING
+                           "osst%d:W: Nothing can be transfered, requested %d, 
tape block size (%d%c).\n",
+                                       dev, count, STp->block_size < 1024?
+                                       STp->block_size:STp->block_size/1024,
+                                       STp->block_size<1024?'b':'k');
+                               break;
+                       }
                        i = from_buffer(STp->buffer, buf, transfer);
                        if (i)  {
                                retval = i;
@@ -3876,9 +3938,10 @@
                 }
                 break;
         case MTWEOF:
-                if ( STps->rw == ST_WRITING && !(STp->device)->was_reset)
+                if ((STps->rw == ST_WRITING || STp->dirty) && 
!(STp->device)->was_reset) {
+                       STp->write_type = OS_WRITE_DATA;
                        ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
-                else
+                } else
                        ioctl_result = 0;
 #if DEBUG
                 if (debugging) 
@@ -4083,6 +4146,14 @@
 
                if (cmd_in == MTEOM)
                        STps->eof = ST_EOD;
+               else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == 
ST_FM_HIT) {
+                       ioctl_result = osst_seek_logical_blk(STp, &SRpnt, 
STp->logical_blk_num-1);
+                       STps->drv_block++;
+                       STp->logical_blk_num++;
+                       STp->frame_seq_number++;
+                       STp->frame_in_buffer = 0;
+                       STp->buffer->read_pointer = 0;
+               }
                else if (cmd_in == MTFSF)
                        STps->eof = (STp->first_frame_position >= 
STp->eod_frame_ppos)?ST_EOD:ST_FM;
                else if (chg_eof)
@@ -4091,7 +4162,6 @@
                if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
                        STp->rew_at_close = 0;
                else if (cmd_in == MTLOAD) {
-/*                     STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0; 
 FIXME */
                        for (i=0; i < ST_NBR_PARTITIONS; i++) {
                            STp->ps[i].rw = ST_IDLE;
                            STp->ps[i].last_block_valid = FALSE;/* FIXME - 
where else is this field maintained? */
@@ -4140,10 +4210,15 @@
                        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);
+                       ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, 
OSST_WAIT_POSITION_COMPLETE);
        }
        *aSRpnt = SRpnt;
 
+#if DEBUG
+       printk(OSST_DEB_MSG "osst%d:D: Ioctl %s, ppos %d fseq %d lblk %d bytes 
%d file %d blk %d\n", dev,
+                       ioctl_result?"fail":"success", 
STp->first_frame_position, STp->frame_seq_number,
+                       STp->logical_blk_num, STp->buffer->buffer_bytes, 
STps->drv_file, STps->drv_block);
+#endif
        return ioctl_result;
 }
 
@@ -4263,7 +4338,7 @@
                        SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
                                             STp->timeout, MAX_READY_RETRIES, 
TRUE);
                }
-               osst_wait_ready(STp, &SRpnt, 
(SRpnt->sr_sense_buffer[13]==1?15:3) * 60);
+               osst_wait_ready(STp, &SRpnt, 
(SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
        }
        if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
            (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New 
media? */
@@ -4410,7 +4485,7 @@
                }
        }
 
-       if (osst_wait_ready(STp, &SRpnt, 15 * 60))              /* FIXME - not 
allowed with NOBLOCK */
+       if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0))           /* FIXME - not 
allowed with NOBLOCK */
                 printk(KERN_INFO "osst%i:I: Device did not become Ready in 
open\n",dev);
 
        if ((STp->buffer)->syscall_result != 0) {
@@ -4551,7 +4626,8 @@
        STm = &(STp->modes[STp->current_mode]);
        STps = &(STp->ps[STp->partition]);
 
-       if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
+       if ((STps->rw == ST_WRITING || STp->dirty) && 
!(STp->device)->was_reset) {
+               STp->write_type = OS_WRITE_DATA;
                result = osst_flush_write_buffer(STp, &SRpnt);
                if (result != 0 && result != (-ENOSPC))
                        goto out;
@@ -4816,12 +4892,6 @@
                }
 
                if (mtc.mt_op == MTSETPART) {
-/*     if (!STp->can_partitions ||
-          mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS)
-        return (-EINVAL);
-                if (mtc.mt_count >= STp->nbr_partitions &&
-          (STp->nbr_partitions = nbr_partitions(inode)) < 0)
-        return (-EIO);*/
                        if (mtc.mt_count >= STp->nbr_partitions)
                                retval = -EINVAL;
                        else {
@@ -4886,10 +4956,6 @@
                goto out;
        }
 
-/* if (STp->can_partitions &&
-                (i = update_partition(inode)) < 0)
-        {retval=i;goto out;}*/
-
        if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
                struct mtget mt_status;
 
@@ -5024,7 +5090,11 @@
                        tb->sg[0].address =
                            (unsigned char *)__get_free_pages(priority, order);
                        if (tb->sg[0].address != NULL) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
                            tb->sg[0].page = NULL;
+#else
+                           tb->sg[0].alt_address = NULL;
+#endif
                            tb->sg[0].length = b_size;
                            break;
                        }
@@ -5060,7 +5130,11 @@
                                tb = NULL;
                                break;
                            }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
                             tb->sg[segs].page = NULL;
+#else
+                           tb->sg[segs].alt_address = NULL;
+#endif
                            tb->sg[segs].length = b_size;
                            got += b_size;
                            segs++;
@@ -5119,9 +5193,10 @@
        for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size;
             segs < max_segs && got < new_size; ) {
                STbuffer->sg[segs].address =
-                         (unsigned char *)__get_free_pages(priority, order);
+                         (unsigned char *)__get_free_pages(priority,
+                               (new_size - got <= PAGE_SIZE) ? 0 : order);
                if (STbuffer->sg[segs].address == NULL) {
-                       if (new_size - got <= (max_segs - segs) * b_size / 2) {
+                       if (new_size - got <= (max_segs - segs) * b_size / 2 && 
order) {
                                b_size /= 2;  /* Large enough for the rest of 
the buffers */
                                order--;
                                continue;
@@ -5134,10 +5209,14 @@
                        normalize_buffer(STbuffer);
                        return FALSE;
                }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
                STbuffer->sg[segs].page = NULL;
-               STbuffer->sg[segs].length = b_size;
+#else
+               STbuffer->sg[segs].alt_address = NULL;
+#endif
+               STbuffer->sg[segs].length = (new_size - got <= PAGE_SIZE / 2) ? 
(new_size - got) : b_size;
                STbuffer->sg_segs += 1;
-               got += b_size;
+               got += STbuffer->sg[segs].length;
                STbuffer->buffer_size = got;
                segs++;
        }
@@ -5320,28 +5399,26 @@
 
 static void validate_options (void)
 {
-  if (buffer_kbs > 0)
-               osst_buffer_size = buffer_kbs * ST_KILOBYTE;
+  if (max_dev > 0)
+               osst_max_dev = osst_max_buffers = max_dev;
   if (write_threshold_kbs > 0)
                osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
   if (osst_write_threshold > osst_buffer_size)
                osst_write_threshold = osst_buffer_size;
-  if (max_buffers > 0)
-               osst_max_buffers = max_buffers;
   if (max_sg_segs >= OSST_FIRST_SG)
                osst_max_sg_segs = max_sg_segs;
 #if DEBUG
-  printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs 
%d.\n",
+  printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max devices %d, s/g segs 
%d.\n",
         osst_buffer_size, osst_write_threshold, osst_max_buffers, 
osst_max_sg_segs);
-//printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)\n",
-//             
sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error");
 #endif
 }
        
 #ifndef MODULE
-/* Set the boot options. Syntax: osst=xxx,yyy,...
-   where xxx is buffer size in 1024 byte blocks and yyy is write threshold
-   in 1024 byte blocks. */
+/* Set the boot options. Syntax: osst=xxx,yyy,zzz
+ * where xxx is maximum nr of devices to attach,
+ * yyy is write threshold in 1024 byte blocks
+ * and zzz the maximum nr of s/g segments to handle.
+ */
 static int __init osst_setup (char *str)
 {
   int i, ints[5];
@@ -5417,6 +5494,72 @@
        return 0;
 }
 
+/*
+ * /proc support for accessing ADR header information
+ */
+static struct proc_dir_entry * osst_proc_dir = NULL;
+static char   osst_proc_dirname[] = "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)
+{
+       if (!proc_scsi) return;
+
+       osst_proc_dir = proc_mkdir(osst_proc_dirname, proc_scsi);
+       osst_proc_dir->owner = THIS_MODULE;
+}
+
+static void osst_proc_create(OS_Scsi_Tape * STp, int dev)
+{
+       char s[16];
+       struct proc_dir_entry * p_entry;
+
+       if (!osst_proc_dir) return;
+
+       sprintf(s, "osst%d", dev);
+       p_entry = create_proc_read_entry(s, 0444, osst_proc_dir, 
osst_proc_read, (void *) STp);
+       p_entry->owner = THIS_MODULE;
+}
+
+static void osst_proc_destroy(int dev)
+{
+       char s[16];
+
+       if (!osst_proc_dir) return; 
+
+       sprintf(s, "osst%d", dev);
+       remove_proc_entry(s, osst_proc_dir);
+}
+
+static void osst_proc_cleanup(void)
+{
+       if ((! proc_scsi) || (!osst_proc_dir)) return;
+
+       remove_proc_entry(osst_proc_dirname, proc_scsi);
+       osst_proc_dir = NULL;
+}
+
+/*
+ * osst startup / cleanup code
+ */
+
 static int osst_attach(Scsi_Device * SDp)
 {
        OS_Scsi_Tape * tpnt;
@@ -5522,7 +5665,8 @@
        tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
        tpnt->omit_blklims = 1;
 
-       tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 
OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
+       tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || 
+                    (strncmp(SDp->model, "FW-", 3) == 0) || 
OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
        tpnt->frame_in_buffer = 0;
        tpnt->header_ok = 0;
        tpnt->linux_media = 0;
@@ -5559,6 +5703,8 @@
 
        osst_template.nr_dev++;
 
+       osst_proc_create(tpnt, dev);
+
        printk(KERN_INFO
                "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id 
%d, lun %d as osst%d\n",
                SDp->model, SDp->host->host_no, SDp->channel, SDp->id, 
SDp->lun, dev);
@@ -5597,7 +5743,7 @@
   }
   
   if (os_scsi_tapes) return 0;
-  osst_template.dev_max = OSST_MAX_TAPES;
+  osst_template.dev_max = osst_max_dev;
   if (osst_template.dev_max > 128 / ST_NBR_MODES)
        printk(KERN_INFO "osst :I: Only %d tapes accessible.\n", 128 / 
ST_NBR_MODES);
   os_scsi_tapes =
@@ -5637,39 +5783,42 @@
   printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d 
bytes.\n",
         osst_buffer_size, osst_write_threshold);
 #endif
+  osst_proc_init();
   return 0;
 }
 
 
 static void osst_detach(Scsi_Device * SDp)
 {
-  OS_Scsi_Tape * tpnt;
-  int i;
+       OS_Scsi_Tape * tpnt;
+       int i;
 #ifdef CONFIG_DEVFS_FS
-  int mode;
+       int mode;
 #endif
-
-  for(i=0; i<osst_template.dev_max; i++) {
-       tpnt = os_scsi_tapes[i];
-       if(tpnt != NULL && tpnt->device == SDp) {
-               tpnt->device = NULL;
+       for(i=0; i<osst_template.dev_max; i++) {
+               tpnt = os_scsi_tapes[i];
+               if(tpnt != NULL && tpnt->device == SDp) {
+                       osst_proc_destroy(i);
+                       tpnt->device = NULL;
 #ifdef CONFIG_DEVFS_FS
-               for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-         devfs_unregister (tpnt->de_r[mode]);
-         tpnt->de_r[mode] = NULL;
-         devfs_unregister (tpnt->de_n[mode]);
-         tpnt->de_n[mode] = NULL;
+                       for (mode = 0; mode < ST_NBR_MODES; ++mode) {
+                               devfs_unregister (tpnt->de_r[mode]);
+                               tpnt->de_r[mode] = NULL;
+                               devfs_unregister (tpnt->de_n[mode]);
+                               tpnt->de_n[mode] = NULL;
+                       }
+#endif
+                       if (tpnt->header_cache != NULL) {
+                               vfree(tpnt->header_cache);
+                       }
+                       kfree(tpnt);
+                       os_scsi_tapes[i] = NULL;
+                       SDp->attached--;
+                       osst_template.nr_dev--;
+                       osst_template.dev_noticed--;
+                       return;
                }
-#endif
-               kfree(tpnt);
-               os_scsi_tapes[i] = NULL;
-               SDp->attached--;
-               osst_template.nr_dev--;
-               osst_template.dev_noticed--;
-               return;
        }
-  }
-  return;
 }
 
 static int __init init_osst(void) 
@@ -5681,38 +5830,32 @@
 
 static void __exit exit_osst (void)
 {
-  int i;
-  OS_Scsi_Tape * STp;
+       int i;
 
-  scsi_unregister_module(MODULE_SCSI_DEV, &osst_template);
+       scsi_unregister_module(MODULE_SCSI_DEV, &osst_template);
 #ifdef CONFIG_DEVFS_FS
-  devfs_unregister_chrdev(MAJOR_NR, "osst");
+       devfs_unregister_chrdev(MAJOR_NR, "osst");
 #else
-  unregister_chrdev(MAJOR_NR, "osst");
+       unregister_chrdev(MAJOR_NR, "osst");
 #endif
-  osst_registered--;
-  if(os_scsi_tapes != NULL) {
-       for (i=0; i < osst_template.dev_max; ++i) {
-               if ((STp = os_scsi_tapes[i])) {
-       if (STp->header_cache != NULL) vfree(STp->header_cache);
-       kfree(STp);
-               }
-       }
-       kfree(os_scsi_tapes);
+       osst_registered--;
 
+       osst_proc_cleanup();
+
+       if(os_scsi_tapes != NULL) {
+               kfree(os_scsi_tapes);
+       }
        if (osst_buffers != NULL) {
                for (i=0; i < osst_nbr_buffers; i++)
-       if (osst_buffers[i] != NULL) {
-         osst_buffers[i]->orig_sg_segs = 0;
-         normalize_buffer(osst_buffers[i]);
-         kfree(osst_buffers[i]);
-       }
-
+                       if (osst_buffers[i] != NULL) {
+                               osst_buffers[i]->orig_sg_segs = 0;
+                               normalize_buffer(osst_buffers[i]);
+                               kfree(osst_buffers[i]);
+                       }
                kfree(osst_buffers);
        }
-  }
-  osst_template.dev_max = 0;
-  printk(KERN_INFO "osst :I: Unloaded.\n");
+       osst_template.dev_max = 0;
+       printk(KERN_INFO "osst :I: Unloaded.\n");
 }
 
 module_init(init_osst);

Répondre à