Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
osst.c
Go to the documentation of this file.
1 /*
2  SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
3  file Documentation/scsi/st.txt for more information.
4 
5  History:
6 
7  OnStream SCSI Tape support (osst) cloned from st.c by
8  Willem Riede ([email protected]) Feb 2000
9  Fixes ... Kurt Garloff <[email protected]> Mar 2000
10 
11  Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
12  Contribution and ideas from several people including (in alphabetical
13  order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
14  Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
15 
16  Copyright 1992 - 2002 Kai Makisara / 2000 - 2006 Willem Riede
17  email [email protected]
18 
19  $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
20 
21  Microscopic alterations - Rik Ling, 2000/12/21
22  Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
23  Some small formal changes - aeb, 950809
24 */
25 
26 static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
27 static const char * osst_version = "0.99.4";
28 
29 /* The "failure to reconnect" firmware bug */
30 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
31 #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
32 #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
33 
34 #include <linux/module.h>
35 
36 #include <linux/fs.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/proc_fs.h>
40 #include <linux/mm.h>
41 #include <linux/slab.h>
42 #include <linux/init.h>
43 #include <linux/string.h>
44 #include <linux/errno.h>
45 #include <linux/mtio.h>
46 #include <linux/ioctl.h>
47 #include <linux/fcntl.h>
48 #include <linux/spinlock.h>
49 #include <linux/vmalloc.h>
50 #include <linux/blkdev.h>
51 #include <linux/moduleparam.h>
52 #include <linux/delay.h>
53 #include <linux/jiffies.h>
54 #include <linux/mutex.h>
55 #include <asm/uaccess.h>
56 #include <asm/dma.h>
57 
58 /* The driver prints some debugging information on the console if DEBUG
59  is defined and non-zero. */
60 #define DEBUG 0
61 
62 /* The message level for the debug messages is currently set to KERN_NOTICE
63  so that people can easily see the messages. Later when the debugging messages
64  in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
65 #define OSST_DEB_MSG KERN_NOTICE
66 
67 #include <scsi/scsi.h>
68 #include <scsi/scsi_dbg.h>
69 #include <scsi/scsi_device.h>
70 #include <scsi/scsi_driver.h>
71 #include <scsi/scsi_eh.h>
72 #include <scsi/scsi_host.h>
73 #include <scsi/scsi_ioctl.h>
74 
75 #define ST_KILOBYTE 1024
76 
77 #include "st.h"
78 #include "osst.h"
79 #include "osst_options.h"
80 #include "osst_detect.h"
81 
82 static DEFINE_MUTEX(osst_int_mutex);
83 static int max_dev = 0;
84 static int write_threshold_kbs = 0;
85 static int max_sg_segs = 0;
86 
87 #ifdef MODULE
88 MODULE_AUTHOR("Willem Riede");
89 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
90 MODULE_LICENSE("GPL");
93 
94 module_param(max_dev, int, 0444);
95 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
96 
97 module_param(write_threshold_kbs, int, 0644);
98 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
99 
100 module_param(max_sg_segs, int, 0644);
101 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
102 #else
103 static struct osst_dev_parm {
104  char *name;
105  int *val;
106 } parms[] __initdata = {
107  { "max_dev", &max_dev },
108  { "write_threshold_kbs", &write_threshold_kbs },
109  { "max_sg_segs", &max_sg_segs }
110 };
111 #endif
112 
113 /* Some default definitions have been moved to osst_options.h */
114 #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
115 #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
116 
117 /* The buffer size should fit into the 24 bits for length in the
118  6-byte SCSI read and write commands. */
119 #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
120 #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
121 #endif
122 
123 #if DEBUG
124 static int debugging = 1;
125 /* uncomment define below to test error recovery */
126 // #define OSST_INJECT_ERRORS 1
127 #endif
128 
129 /* Do not retry! The drive firmware already retries when appropriate,
130  and when it tries to tell us something, we had better listen... */
131 #define MAX_RETRIES 0
132 
133 #define NO_TAPE NOT_READY
134 
135 #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1)
136 #define OSST_WAIT_WRITE_COMPLETE (HZ / 12)
137 #define OSST_WAIT_LONG_WRITE_COMPLETE (HZ / 2)
138 
139 #define OSST_TIMEOUT (200 * HZ)
140 #define OSST_LONG_TIMEOUT (1800 * HZ)
141 
142 #define TAPE_NR(x) (iminor(x) & ~(-1 << ST_MODE_SHIFT))
143 #define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
144 #define TAPE_REWIND(x) ((iminor(x) & 0x80) == 0)
145 #define TAPE_IS_RAW(x) (TAPE_MODE(x) & (ST_NBR_MODES >> 1))
146 
147 /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
148  24 bits) */
149 #define SET_DENS_AND_BLK 0x10001
150 
151 static int osst_buffer_size = OSST_BUFFER_SIZE;
152 static int osst_write_threshold = OSST_WRITE_THRESHOLD;
153 static int osst_max_sg_segs = OSST_MAX_SG;
154 static int osst_max_dev = OSST_MAX_TAPES;
155 static int osst_nr_dev;
156 
157 static struct osst_tape **os_scsi_tapes = NULL;
158 static DEFINE_RWLOCK(os_scsi_tapes_lock);
159 
160 static int modes_defined = 0;
161 
162 static struct osst_buffer *new_tape_buffer(int, int, int);
163 static int enlarge_buffer(struct osst_buffer *, int);
164 static void normalize_buffer(struct osst_buffer *);
165 static int append_to_buffer(const char __user *, struct osst_buffer *, int);
166 static int from_buffer(struct osst_buffer *, char __user *, int);
167 static int osst_zero_buffer_tail(struct osst_buffer *);
168 static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
169 static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
170 
171 static int osst_probe(struct device *);
172 static int osst_remove(struct device *);
173 
174 static struct scsi_driver osst_template = {
175  .owner = THIS_MODULE,
176  .gendrv = {
177  .name = "osst",
178  .probe = osst_probe,
179  .remove = osst_remove,
180  }
181 };
182 
183 static int osst_int_ioctl(struct osst_tape *STp, struct osst_request ** aSRpnt,
184  unsigned int cmd_in, unsigned long arg);
185 
186 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int frame, int skip);
187 
188 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt);
189 
190 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt);
191 
192 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending);
193 
194 static inline char *tape_name(struct osst_tape *tape)
195 {
196  return tape->drive->disk_name;
197 }
198 
199 /* Routines that handle the interaction with mid-layer SCSI routines */
200 
201 
202 /* Normalize Sense */
203 static void osst_analyze_sense(struct osst_request *SRpnt, struct st_cmdstatus *s)
204 {
205  const u8 *ucp;
206  const u8 *sense = SRpnt->sense;
207 
210  s->flags = 0;
211 
212  if (s->have_sense) {
213  s->deferred = 0;
214  s->remainder_valid =
216  switch (sense[0] & 0x7f) {
217  case 0x71:
218  s->deferred = 1;
219  case 0x70:
220  s->fixed_format = 1;
221  s->flags = sense[2] & 0xe0;
222  break;
223  case 0x73:
224  s->deferred = 1;
225  case 0x72:
226  s->fixed_format = 0;
228  s->flags = ucp ? (ucp[3] & 0xe0) : 0;
229  break;
230  }
231  }
232 }
233 
234 /* Convert the result to success code */
235 static int osst_chk_result(struct osst_tape * STp, struct osst_request * SRpnt)
236 {
237  char *name = tape_name(STp);
238  int result = SRpnt->result;
239  u8 * sense = SRpnt->sense, scode;
240 #if DEBUG
241  const char *stp;
242 #endif
243  struct st_cmdstatus *cmdstatp;
244 
245  if (!result)
246  return 0;
247 
248  cmdstatp = &STp->buffer->cmdstat;
249  osst_analyze_sense(SRpnt, cmdstatp);
250 
251  if (cmdstatp->have_sense)
252  scode = STp->buffer->cmdstat.sense_hdr.sense_key;
253  else
254  scode = 0;
255 #if DEBUG
256  if (debugging) {
257  printk(OSST_DEB_MSG "%s:D: Error: %x, cmd: %x %x %x %x %x %x\n",
258  name, result,
259  SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
260  SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
261  if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n",
262  name, scode, sense[12], sense[13]);
263  if (cmdstatp->have_sense)
265  }
266  else
267 #endif
268  if (cmdstatp->have_sense && (
269  scode != NO_SENSE &&
270  scode != RECOVERED_ERROR &&
271 /* scode != UNIT_ATTENTION && */
272  scode != BLANK_CHECK &&
273  scode != VOLUME_OVERFLOW &&
274  SRpnt->cmd[0] != MODE_SENSE &&
275  SRpnt->cmd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
276  if (cmdstatp->have_sense) {
277  printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
279  }
280  else {
281  static int notyetprinted = 1;
282 
284  "%s:W: Warning %x (driver bt 0x%x, host bt 0x%x).\n",
285  name, result, driver_byte(result),
286  host_byte(result));
287  if (notyetprinted) {
288  notyetprinted = 0;
290  "%s:I: This warning may be caused by your scsi controller,\n", name);
292  "%s:I: it has been reported with some Buslogic cards.\n", name);
293  }
294  }
295  }
296  STp->pos_unknown |= STp->device->was_reset;
297 
298  if (cmdstatp->have_sense && scode == RECOVERED_ERROR) {
299  STp->recover_count++;
300  STp->recover_erreg++;
301 #if DEBUG
302  if (debugging) {
303  if (SRpnt->cmd[0] == READ_6)
304  stp = "read";
305  else if (SRpnt->cmd[0] == WRITE_6)
306  stp = "write";
307  else
308  stp = "ioctl";
309  printk(OSST_DEB_MSG "%s:D: Recovered %s error (%d).\n", name, stp,
310  STp->recover_count);
311  }
312 #endif
313  if ((sense[2] & 0xe0) == 0)
314  return 0;
315  }
316  return (-EIO);
317 }
318 
319 
320 /* Wakeup from interrupt */
321 static void osst_end_async(struct request *req, int update)
322 {
323  struct osst_request *SRpnt = req->end_io_data;
324  struct osst_tape *STp = SRpnt->stp;
325  struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
326 
327  STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
328 #if DEBUG
329  STp->write_pending = 0;
330 #endif
331  if (SRpnt->waiting)
332  complete(SRpnt->waiting);
333 
334  if (SRpnt->bio) {
335  kfree(mdata->pages);
336  blk_rq_unmap_user(SRpnt->bio);
337  }
338 
339  __blk_put_request(req->q, req);
340 }
341 
342 /* osst_request memory management */
343 static struct osst_request *osst_allocate_request(void)
344 {
345  return kzalloc(sizeof(struct osst_request), GFP_KERNEL);
346 }
347 
348 static void osst_release_request(struct osst_request *streq)
349 {
350  kfree(streq);
351 }
352 
353 static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
354  int cmd_len, int data_direction, void *buffer, unsigned bufflen,
355  int use_sg, int timeout, int retries)
356 {
357  struct request *req;
358  struct page **pages = NULL;
359  struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
360 
361  int err = 0;
362  int write = (data_direction == DMA_TO_DEVICE);
363 
364  req = blk_get_request(SRpnt->stp->device->request_queue, write, GFP_KERNEL);
365  if (!req)
366  return DRIVER_ERROR << 24;
367 
368  req->cmd_type = REQ_TYPE_BLOCK_PC;
369  req->cmd_flags |= REQ_QUIET;
370 
371  SRpnt->bio = NULL;
372 
373  if (use_sg) {
374  struct scatterlist *sg, *sgl = (struct scatterlist *)buffer;
375  int i;
376 
377  pages = kzalloc(use_sg * sizeof(struct page *), GFP_KERNEL);
378  if (!pages)
379  goto free_req;
380 
381  for_each_sg(sgl, sg, use_sg, i)
382  pages[i] = sg_page(sg);
383 
384  mdata->null_mapped = 1;
385 
386  mdata->page_order = get_order(sgl[0].length);
387  mdata->nr_entries =
388  DIV_ROUND_UP(bufflen, PAGE_SIZE << mdata->page_order);
389  mdata->offset = 0;
390 
391  err = blk_rq_map_user(req->q, req, mdata, NULL, bufflen, GFP_KERNEL);
392  if (err) {
393  kfree(pages);
394  goto free_req;
395  }
396  SRpnt->bio = req->bio;
397  mdata->pages = pages;
398 
399  } else if (bufflen) {
400  err = blk_rq_map_kern(req->q, req, buffer, bufflen, GFP_KERNEL);
401  if (err)
402  goto free_req;
403  }
404 
405  req->cmd_len = cmd_len;
406  memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
407  memcpy(req->cmd, cmd, req->cmd_len);
408  req->sense = SRpnt->sense;
409  req->sense_len = 0;
410  req->timeout = timeout;
411  req->retries = retries;
412  req->end_io_data = SRpnt;
413 
414  blk_execute_rq_nowait(req->q, NULL, req, 1, osst_end_async);
415  return 0;
416 free_req:
417  blk_put_request(req);
418  return DRIVER_ERROR << 24;
419 }
420 
421 /* Do the scsi command. Waits until command performed if do_wait is true.
422  Otherwise osst_write_behind_check() is used to check that the command
423  has finished. */
424 static struct osst_request * osst_do_scsi(struct osst_request *SRpnt, struct osst_tape *STp,
425  unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
426 {
427  unsigned char *bp;
428  unsigned short use_sg;
429 #ifdef OSST_INJECT_ERRORS
430  static int inject = 0;
431  static int repeat = 0;
432 #endif
433  struct completion *waiting;
434 
435  /* if async, make sure there's no command outstanding */
436  if (!do_wait && ((STp->buffer)->last_SRpnt)) {
437  printk(KERN_ERR "%s: Async command already active.\n",
438  tape_name(STp));
439  if (signal_pending(current))
440  (STp->buffer)->syscall_result = (-EINTR);
441  else
442  (STp->buffer)->syscall_result = (-EBUSY);
443  return NULL;
444  }
445 
446  if (SRpnt == NULL) {
447  SRpnt = osst_allocate_request();
448  if (SRpnt == NULL) {
449  printk(KERN_ERR "%s: Can't allocate SCSI request.\n",
450  tape_name(STp));
451  if (signal_pending(current))
452  (STp->buffer)->syscall_result = (-EINTR);
453  else
454  (STp->buffer)->syscall_result = (-EBUSY);
455  return NULL;
456  }
457  SRpnt->stp = STp;
458  }
459 
460  /* If async IO, set last_SRpnt. This ptr tells write_behind_check
461  which IO is outstanding. It's nulled out when the IO completes. */
462  if (!do_wait)
463  (STp->buffer)->last_SRpnt = SRpnt;
464 
465  waiting = &STp->wait;
466  init_completion(waiting);
467  SRpnt->waiting = waiting;
468 
469  use_sg = (bytes > STp->buffer->sg[0].length) ? STp->buffer->use_sg : 0;
470  if (use_sg) {
471  bp = (char *)&(STp->buffer->sg[0]);
472  if (STp->buffer->sg_segs < use_sg)
473  use_sg = STp->buffer->sg_segs;
474  }
475  else
476  bp = (STp->buffer)->b_data;
477 
478  memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
479  STp->buffer->cmdstat.have_sense = 0;
480  STp->buffer->syscall_result = 0;
481 
482  if (osst_execute(SRpnt, cmd, COMMAND_SIZE(cmd[0]), direction, bp, bytes,
483  use_sg, timeout, retries))
484  /* could not allocate the buffer or request was too large */
485  (STp->buffer)->syscall_result = (-EBUSY);
486  else if (do_wait) {
487  wait_for_completion(waiting);
488  SRpnt->waiting = NULL;
489  STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
490 #ifdef OSST_INJECT_ERRORS
491  if (STp->buffer->syscall_result == 0 &&
492  cmd[0] == READ_6 &&
493  cmd[4] &&
494  ( (++ inject % 83) == 29 ||
495  (STp->first_frame_position == 240
496  /* or STp->read_error_frame to fail again on the block calculated above */ &&
497  ++repeat < 3))) {
498  printk(OSST_DEB_MSG "%s:D: Injecting read error\n", tape_name(STp));
499  STp->buffer->last_result_fatal = 1;
500  }
501 #endif
502  }
503  return SRpnt;
504 }
505 
506 
507 /* Handle the write-behind checking (downs the semaphore) */
508 static void osst_write_behind_check(struct osst_tape *STp)
509 {
510  struct osst_buffer * STbuffer;
511 
512  STbuffer = STp->buffer;
513 
514 #if DEBUG
515  if (STp->write_pending)
516  STp->nbr_waits++;
517  else
518  STp->nbr_finished++;
519 #endif
520  wait_for_completion(&(STp->wait));
521  STp->buffer->last_SRpnt->waiting = NULL;
522 
523  STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
524 
525  if (STp->buffer->syscall_result)
526  STp->buffer->syscall_result =
527  osst_write_error_recovery(STp, &(STp->buffer->last_SRpnt), 1);
528  else
529  STp->first_frame_position++;
530 
531  osst_release_request(STp->buffer->last_SRpnt);
532 
533  if (STbuffer->writing < STbuffer->buffer_bytes)
534  printk(KERN_WARNING "osst :A: write_behind_check: something left in buffer!\n");
535 
536  STbuffer->last_SRpnt = NULL;
537  STbuffer->buffer_bytes -= STbuffer->writing;
538  STbuffer->writing = 0;
539 
540  return;
541 }
542 
543 
544 
545 /* Onstream specific Routines */
546 /*
547  * Initialize the OnStream AUX
548  */
549 static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
550  int logical_blk_num, int blk_sz, int blk_cnt)
551 {
552  os_aux_t *aux = STp->buffer->aux;
553  os_partition_t *par = &aux->partition;
554  os_dat_t *dat = &aux->dat;
555 
556  if (STp->raw) return;
557 
558  memset(aux, 0, sizeof(*aux));
559  aux->format_id = htonl(0);
560  memcpy(aux->application_sig, "LIN4", 4);
561  aux->hdwr = htonl(0);
562  aux->frame_type = frame_type;
563 
564  switch (frame_type) {
569  par->wrt_pass_cntr = htons(0xffff);
570  /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
571  par->first_frame_ppos = htonl(0);
572  par->last_frame_ppos = htonl(0xbb7);
573  aux->frame_seq_num = htonl(0);
574  aux->logical_blk_num_high = htonl(0);
575  aux->logical_blk_num = htonl(0);
576  aux->next_mark_ppos = htonl(STp->first_mark_ppos);
577  break;
578  case OS_FRAME_TYPE_DATA:
580  dat->dat_sz = 8;
581  dat->reserved1 = 0;
582  dat->entry_cnt = 1;
583  dat->reserved3 = 0;
584  dat->dat_list[0].blk_sz = htonl(blk_sz);
585  dat->dat_list[0].blk_cnt = htons(blk_cnt);
586  dat->dat_list[0].flags = frame_type==OS_FRAME_TYPE_MARKER?
588  dat->dat_list[0].reserved = 0;
589  case OS_FRAME_TYPE_EOD:
590  aux->update_frame_cntr = htonl(0);
593  par->wrt_pass_cntr = htons(STp->wrt_pass_cntr);
595  par->last_frame_ppos = htonl(STp->capacity);
596  aux->frame_seq_num = htonl(frame_seq_number);
597  aux->logical_blk_num_high = htonl(0);
598  aux->logical_blk_num = htonl(logical_blk_num);
599  break;
600  default: ; /* probably FILL */
601  }
602  aux->filemark_cnt = htonl(STp->filemark_cnt);
603  aux->phys_fm = htonl(0xffffffff);
604  aux->last_mark_ppos = htonl(STp->last_mark_ppos);
605  aux->last_mark_lbn = htonl(STp->last_mark_lbn);
606 }
607 
608 /*
609  * Verify that we have the correct tape frame
610  */
611 static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
612 {
613  char * name = tape_name(STp);
614  os_aux_t * aux = STp->buffer->aux;
615  os_partition_t * par = &(aux->partition);
616  struct st_partstat * STps = &(STp->ps[STp->partition]);
617  int blk_cnt, blk_sz, i;
618 
619  if (STp->raw) {
620  if (STp->buffer->syscall_result) {
621  for (i=0; i < STp->buffer->sg_segs; i++)
622  memset(page_address(sg_page(&STp->buffer->sg[i])),
623  0, STp->buffer->sg[i].length);
624  strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
625  } else
626  STp->buffer->buffer_bytes = OS_FRAME_SIZE;
627  return 1;
628  }
629  if (STp->buffer->syscall_result) {
630 #if DEBUG
631  printk(OSST_DEB_MSG "%s:D: Skipping frame, read error\n", name);
632 #endif
633  return 0;
634  }
635  if (ntohl(aux->format_id) != 0) {
636 #if DEBUG
637  printk(OSST_DEB_MSG "%s:D: Skipping frame, format_id %u\n", name, ntohl(aux->format_id));
638 #endif
639  goto err_out;
640  }
641  if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
642  (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
643 #if DEBUG
644  printk(OSST_DEB_MSG "%s:D: Skipping frame, incorrect application signature\n", name);
645 #endif
646  goto err_out;
647  }
648  if (par->partition_num != OS_DATA_PARTITION) {
649  if (!STp->linux_media || STp->linux_media_version != 2) {
650 #if DEBUG
651  printk(OSST_DEB_MSG "%s:D: Skipping frame, partition num %d\n",
652  name, par->partition_num);
653 #endif
654  goto err_out;
655  }
656  }
657  if (par->par_desc_ver != OS_PARTITION_VERSION) {
658 #if DEBUG
659  printk(OSST_DEB_MSG "%s:D: Skipping frame, partition version %d\n", name, par->par_desc_ver);
660 #endif
661  goto err_out;
662  }
663  if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
664 #if DEBUG
665  printk(OSST_DEB_MSG "%s:D: Skipping frame, wrt_pass_cntr %d (expected %d)\n",
666  name, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
667 #endif
668  goto err_out;
669  }
670  if (aux->frame_type != OS_FRAME_TYPE_DATA &&
671  aux->frame_type != OS_FRAME_TYPE_EOD &&
673  if (!quiet) {
674 #if DEBUG
675  printk(OSST_DEB_MSG "%s:D: Skipping frame, frame type %x\n", name, aux->frame_type);
676 #endif
677  }
678  goto err_out;
679  }
680  if (aux->frame_type == OS_FRAME_TYPE_EOD &&
681  STp->first_frame_position < STp->eod_frame_ppos) {
682  printk(KERN_INFO "%s:I: Skipping premature EOD frame %d\n", name,
683  STp->first_frame_position);
684  goto err_out;
685  }
686  if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
687  if (!quiet) {
688 #if DEBUG
689  printk(OSST_DEB_MSG "%s:D: Skipping frame, sequence number %u (expected %d)\n",
690  name, ntohl(aux->frame_seq_num), frame_seq_number);
691 #endif
692  }
693  goto err_out;
694  }
695  if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
696  STps->eof = ST_FM_HIT;
697 
698  i = ntohl(aux->filemark_cnt);
699  if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
701 #if DEBUG
702  printk(OSST_DEB_MSG "%s:D: %s filemark %d at frame pos %d\n", name,
703  STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
704  i, STp->first_frame_position - 1);
705 #endif
707  if (i >= STp->filemark_cnt)
708  STp->filemark_cnt = i+1;
709  }
710  }
711  if (aux->frame_type == OS_FRAME_TYPE_EOD) {
712  STps->eof = ST_EOD_1;
713  STp->frame_in_buffer = 1;
714  }
715  if (aux->frame_type == OS_FRAME_TYPE_DATA) {
716  blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
717  blk_sz = ntohl(aux->dat.dat_list[0].blk_sz);
718  STp->buffer->buffer_bytes = blk_cnt * blk_sz;
719  STp->buffer->read_pointer = 0;
720  STp->frame_in_buffer = 1;
721 
722  /* See what block size was used to write file */
723  if (STp->block_size != blk_sz && blk_sz > 0) {
725  "%s:I: File was written with block size %d%c, currently %d%c, adjusted to match.\n",
726  name, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
727  STp->block_size<1024?STp->block_size:STp->block_size/1024,
728  STp->block_size<1024?'b':'k');
729  STp->block_size = blk_sz;
730  STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
731  }
732  STps->eof = ST_NOEOF;
733  }
734  STp->frame_seq_number = ntohl(aux->frame_seq_num);
736  return 1;
737 
738 err_out:
739  if (STp->read_error_frame == 0)
740  STp->read_error_frame = STp->first_frame_position - 1;
741  return 0;
742 }
743 
744 /*
745  * Wait for the unit to become Ready
746  */
747 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
748  unsigned timeout, int initial_delay)
749 {
750  unsigned char cmd[MAX_COMMAND_SIZE];
751  struct osst_request * SRpnt;
752  unsigned long startwait = jiffies;
753 #if DEBUG
754  int dbg = debugging;
755  char * name = tape_name(STp);
756 
757  printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
758 #endif
759 
760  if (initial_delay > 0)
761  msleep(jiffies_to_msecs(initial_delay));
762 
763  memset(cmd, 0, MAX_COMMAND_SIZE);
764  cmd[0] = TEST_UNIT_READY;
765 
766  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
767  *aSRpnt = SRpnt;
768  if (!SRpnt) return (-EBUSY);
769 
770  while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
771  (( SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
772  (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8) ) ||
773  ( SRpnt->sense[2] == 6 && SRpnt->sense[12] == 0x28 &&
774  SRpnt->sense[13] == 0 ) )) {
775 #if DEBUG
776  if (debugging) {
777  printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait ready\n", name);
778  printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
779  debugging = 0;
780  }
781 #endif
782  msleep(100);
783 
784  memset(cmd, 0, MAX_COMMAND_SIZE);
785  cmd[0] = TEST_UNIT_READY;
786 
787  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
788  }
789  *aSRpnt = SRpnt;
790 #if DEBUG
791  debugging = dbg;
792 #endif
793  if ( STp->buffer->syscall_result &&
794  osst_write_error_recovery(STp, aSRpnt, 0) ) {
795 #if DEBUG
796  printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait ready\n", name);
797  printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
798  STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
799  SRpnt->sense[12], SRpnt->sense[13]);
800 #endif
801  return (-EIO);
802  }
803 #if DEBUG
804  printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait ready\n", name);
805 #endif
806  return 0;
807 }
808 
809 /*
810  * Wait for a tape to be inserted in the unit
811  */
812 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
813 {
814  unsigned char cmd[MAX_COMMAND_SIZE];
815  struct osst_request * SRpnt;
816  unsigned long startwait = jiffies;
817 #if DEBUG
818  int dbg = debugging;
819  char * name = tape_name(STp);
820 
821  printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
822 #endif
823 
824  memset(cmd, 0, MAX_COMMAND_SIZE);
825  cmd[0] = TEST_UNIT_READY;
826 
827  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
828  *aSRpnt = SRpnt;
829  if (!SRpnt) return (-EBUSY);
830 
831  while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
832  SRpnt->sense[2] == 2 && SRpnt->sense[12] == 0x3a && SRpnt->sense[13] == 0 ) {
833 #if DEBUG
834  if (debugging) {
835  printk(OSST_DEB_MSG "%s:D: Sleeping in onstream wait medium\n", name);
836  printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
837  debugging = 0;
838  }
839 #endif
840  msleep(100);
841 
842  memset(cmd, 0, MAX_COMMAND_SIZE);
843  cmd[0] = TEST_UNIT_READY;
844 
845  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
846  }
847  *aSRpnt = SRpnt;
848 #if DEBUG
849  debugging = dbg;
850 #endif
851  if ( STp->buffer->syscall_result && SRpnt->sense[2] != 2 &&
852  SRpnt->sense[12] != 4 && SRpnt->sense[13] == 1) {
853 #if DEBUG
854  printk(OSST_DEB_MSG "%s:D: Abnormal exit from onstream wait medium\n", name);
855  printk(OSST_DEB_MSG "%s:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02x\n", name,
856  STp->buffer->syscall_result, SRpnt->sense[0], SRpnt->sense[2],
857  SRpnt->sense[12], SRpnt->sense[13]);
858 #endif
859  return 0;
860  }
861 #if DEBUG
862  printk(OSST_DEB_MSG "%s:D: Normal exit from onstream wait medium\n", name);
863 #endif
864  return 1;
865 }
866 
867 static int osst_position_tape_and_confirm(struct osst_tape * STp, struct osst_request ** aSRpnt, int frame)
868 {
869  int retval;
870 
871  osst_wait_ready(STp, aSRpnt, 15 * 60, 0); /* TODO - can this catch a write error? */
872  retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
873  if (retval) return (retval);
874  osst_wait_ready(STp, aSRpnt, 15 * 60, OSST_WAIT_POSITION_COMPLETE);
875  return (osst_get_frame_position(STp, aSRpnt));
876 }
877 
878 /*
879  * Wait for write(s) to complete
880  */
881 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
882 {
883  unsigned char cmd[MAX_COMMAND_SIZE];
884  struct osst_request * SRpnt;
885  int result = 0;
887 #if DEBUG
888  char * name = tape_name(STp);
889 
890  printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
891 #endif
892 
893  memset(cmd, 0, MAX_COMMAND_SIZE);
894  cmd[0] = WRITE_FILEMARKS;
895  cmd[1] = 1;
896 
897  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
898  *aSRpnt = SRpnt;
899  if (!SRpnt) return (-EBUSY);
900  if (STp->buffer->syscall_result) {
901  if ((SRpnt->sense[2] & 0x0f) == 2 && SRpnt->sense[12] == 4) {
902  if (SRpnt->sense[13] == 8) {
904  }
905  } else
906  result = osst_write_error_recovery(STp, aSRpnt, 0);
907  }
908  result |= osst_wait_ready(STp, aSRpnt, 5 * 60, delay);
909  STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
910 
911  return (result);
912 }
913 
914 #define OSST_POLL_PER_SEC 10
915 static int osst_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int curr, int minlast, int to)
916 {
917  unsigned long startwait = jiffies;
918  char * name = tape_name(STp);
919 #if DEBUG
920  char notyetprinted = 1;
921 #endif
922  if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
923  printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
924 
925  while (time_before (jiffies, startwait + to*HZ))
926  {
927  int result;
928  result = osst_get_frame_position(STp, aSRpnt);
929  if (result == -EIO)
930  if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
931  return 0; /* successful recovery leaves drive ready for frame */
932  if (result < 0) break;
933  if (STp->first_frame_position == curr &&
934  ((minlast < 0 &&
935  (signed)STp->last_frame_position > (signed)curr + minlast) ||
936  (minlast >= 0 && STp->cur_frames > minlast)
937  ) && result >= 0)
938  {
939 #if DEBUG
940  if (debugging || time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC))
942  "%s:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li s\n",
943  name, curr, curr+minlast, STp->first_frame_position,
944  STp->last_frame_position, STp->cur_frames,
945  result, (jiffies-startwait)/HZ,
946  (((jiffies-startwait)%HZ)*10)/HZ);
947 #endif
948  return 0;
949  }
950 #if DEBUG
951  if (time_after_eq(jiffies, startwait + 2*HZ/OSST_POLL_PER_SEC) && notyetprinted)
952  {
953  printk (OSST_DEB_MSG "%s:D: Wait for frame %i (>%i): %i-%i %i (%i)\n",
954  name, curr, curr+minlast, STp->first_frame_position,
955  STp->last_frame_position, STp->cur_frames, result);
956  notyetprinted--;
957  }
958 #endif
959  msleep(1000 / OSST_POLL_PER_SEC);
960  }
961 #if DEBUG
962  printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n",
963  name, curr, curr+minlast, STp->first_frame_position,
964  STp->last_frame_position, STp->cur_frames,
965  (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
966 #endif
967  return -EBUSY;
968 }
969 
970 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
971 {
972  struct osst_request * SRpnt;
973  unsigned char cmd[MAX_COMMAND_SIZE];
974  unsigned long startwait = jiffies;
975  int retval = 1;
976  char * name = tape_name(STp);
977 
978  if (writing) {
979  char mybuf[24];
980  char * olddata = STp->buffer->b_data;
981  int oldsize = STp->buffer->buffer_size;
982 
983  /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
984 
985  memset(cmd, 0, MAX_COMMAND_SIZE);
986  cmd[0] = WRITE_FILEMARKS;
987  cmd[1] = 1;
988  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
989  MAX_RETRIES, 1);
990 
991  while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
992 
993  if (STp->buffer->syscall_result && (SRpnt->sense[2] & 0x0f) != 2) {
994 
995  /* some failure - not just not-ready */
996  retval = osst_write_error_recovery(STp, aSRpnt, 0);
997  break;
998  }
1000 
1001  STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
1002  memset(cmd, 0, MAX_COMMAND_SIZE);
1003  cmd[0] = READ_POSITION;
1004 
1005  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
1006  MAX_RETRIES, 1);
1007 
1008  retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
1009  STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
1010  }
1011  if (retval)
1012  printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
1013  } else
1014  /* TODO - figure out which error conditions can be handled */
1015  if (STp->buffer->syscall_result)
1017  "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
1018  (*aSRpnt)->sense[ 2] & 0x0f,
1019  (*aSRpnt)->sense[12],
1020  (*aSRpnt)->sense[13]);
1021 
1022  return retval;
1023 }
1024 
1025 /*
1026  * Read the next OnStream tape frame at the current location
1027  */
1028 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
1029 {
1030  unsigned char cmd[MAX_COMMAND_SIZE];
1031  struct osst_request * SRpnt;
1032  int retval = 0;
1033 #if DEBUG
1034  os_aux_t * aux = STp->buffer->aux;
1035  char * name = tape_name(STp);
1036 #endif
1037 
1038  if (STp->poll)
1039  if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
1040  retval = osst_recover_wait_frame(STp, aSRpnt, 0);
1041 
1042  memset(cmd, 0, MAX_COMMAND_SIZE);
1043  cmd[0] = READ_6;
1044  cmd[1] = 1;
1045  cmd[4] = 1;
1046 
1047 #if DEBUG
1048  if (debugging)
1049  printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
1050 #endif
1051  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1052  STp->timeout, MAX_RETRIES, 1);
1053  *aSRpnt = SRpnt;
1054  if (!SRpnt)
1055  return (-EBUSY);
1056 
1057  if ((STp->buffer)->syscall_result) {
1058  retval = 1;
1059  if (STp->read_error_frame == 0) {
1061 #if DEBUG
1062  printk(OSST_DEB_MSG "%s:D: Recording read error at %d\n", name, STp->read_error_frame);
1063 #endif
1064  }
1065 #if DEBUG
1066  if (debugging)
1067  printk(OSST_DEB_MSG "%s:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
1068  name,
1069  SRpnt->sense[0], SRpnt->sense[1],
1070  SRpnt->sense[2], SRpnt->sense[3],
1071  SRpnt->sense[4], SRpnt->sense[5],
1072  SRpnt->sense[6], SRpnt->sense[7]);
1073 #endif
1074  }
1075  else
1076  STp->first_frame_position++;
1077 #if DEBUG
1078  if (debugging) {
1079  char sig[8]; int i;
1080  for (i=0;i<4;i++)
1081  sig[i] = aux->application_sig[i]<32?'^':aux->application_sig[i];
1082  sig[4] = '\0';
1084  "%s:D: AUX: %s UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%d\n", name, sig,
1086  aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
1087  aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL",
1089  ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
1090  if (aux->frame_type==2)
1091  printk(OSST_DEB_MSG "%s:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%d\n", name,
1093  printk(OSST_DEB_MSG "%s:D: Exit read frame from OnStream tape with code %d\n", name, retval);
1094  }
1095 #endif
1096  return (retval);
1097 }
1098 
1099 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
1100 {
1101  struct st_partstat * STps = &(STp->ps[STp->partition]);
1102  struct osst_request * SRpnt ;
1103  unsigned char cmd[MAX_COMMAND_SIZE];
1104  int retval = 0;
1105  char * name = tape_name(STp);
1106 
1107  if (STps->rw != ST_READING) { /* Initialize read operation */
1108  if (STps->rw == ST_WRITING || STp->dirty) {
1109  STp->write_type = OS_WRITE_DATA;
1110  osst_flush_write_buffer(STp, aSRpnt);
1111  osst_flush_drive_buffer(STp, aSRpnt);
1112  }
1113  STps->rw = ST_READING;
1114  STp->frame_in_buffer = 0;
1115 
1116  /*
1117  * Issue a read 0 command to get the OnStream drive
1118  * read frames into its buffer.
1119  */
1120  memset(cmd, 0, MAX_COMMAND_SIZE);
1121  cmd[0] = READ_6;
1122  cmd[1] = 1;
1123 
1124 #if DEBUG
1125  printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
1126 #endif
1127  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
1128  *aSRpnt = SRpnt;
1129  if ((retval = STp->buffer->syscall_result))
1130  printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
1131  }
1132 
1133  return retval;
1134 }
1135 
1136 static int osst_get_logical_frame(struct osst_tape * STp, struct osst_request ** aSRpnt,
1137  int frame_seq_number, int quiet)
1138 {
1139  struct st_partstat * STps = &(STp->ps[STp->partition]);
1140  char * name = tape_name(STp);
1141  int cnt = 0,
1142  bad = 0,
1143  past = 0,
1144  x,
1145  position;
1146 
1147  /*
1148  * If we want just any frame (-1) and there is a frame in the buffer, return it
1149  */
1150  if (frame_seq_number == -1 && STp->frame_in_buffer) {
1151 #if DEBUG
1152  printk(OSST_DEB_MSG "%s:D: Frame %d still in buffer\n", name, STp->frame_seq_number);
1153 #endif
1154  return (STps->eof);
1155  }
1156  /*
1157  * Search and wait for the next logical tape frame
1158  */
1159  while (1) {
1160  if (cnt++ > 400) {
1161  printk(KERN_ERR "%s:E: Couldn't find logical frame %d, aborting\n",
1162  name, frame_seq_number);
1163  if (STp->read_error_frame) {
1164  osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
1165 #if DEBUG
1166  printk(OSST_DEB_MSG "%s:D: Repositioning tape to bad frame %d\n",
1167  name, STp->read_error_frame);
1168 #endif
1169  STp->read_error_frame = 0;
1170  STp->abort_count++;
1171  }
1172  return (-EIO);
1173  }
1174 #if DEBUG
1175  if (debugging)
1176  printk(OSST_DEB_MSG "%s:D: Looking for frame %d, attempt %d\n",
1177  name, frame_seq_number, cnt);
1178 #endif
1179  if ( osst_initiate_read(STp, aSRpnt)
1180  || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
1181  if (STp->raw)
1182  return (-EIO);
1183  position = osst_get_frame_position(STp, aSRpnt);
1184  if (position >= 0xbae && position < 0xbb8)
1185  position = 0xbb8;
1186  else if (position > STp->eod_frame_ppos || ++bad == 10) {
1187  position = STp->read_error_frame - 1;
1188  bad = 0;
1189  }
1190  else {
1191  position += 29;
1192  cnt += 19;
1193  }
1194 #if DEBUG
1195  printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
1196  name, position);
1197 #endif
1198  osst_set_frame_position(STp, aSRpnt, position, 0);
1199  continue;
1200  }
1201  if (osst_verify_frame(STp, frame_seq_number, quiet))
1202  break;
1203  if (osst_verify_frame(STp, -1, quiet)) {
1204  x = ntohl(STp->buffer->aux->frame_seq_num);
1205  if (STp->fast_open) {
1207  "%s:W: Found logical frame %d instead of %d after fast open\n",
1208  name, x, frame_seq_number);
1209  STp->header_ok = 0;
1210  STp->read_error_frame = 0;
1211  return (-EIO);
1212  }
1213  if (x > frame_seq_number) {
1214  if (++past > 3) {
1215  /* positioning backwards did not bring us to the desired frame */
1216  position = STp->read_error_frame - 1;
1217  }
1218  else {
1219  position = osst_get_frame_position(STp, aSRpnt)
1220  + frame_seq_number - x - 1;
1221 
1222  if (STp->first_frame_position >= 3000 && position < 3000)
1223  position -= 10;
1224  }
1225 #if DEBUG
1227  "%s:D: Found logical frame %d while looking for %d: back up %d\n",
1228  name, x, frame_seq_number,
1229  STp->first_frame_position - position);
1230 #endif
1231  osst_set_frame_position(STp, aSRpnt, position, 0);
1232  cnt += 10;
1233  }
1234  else
1235  past = 0;
1236  }
1237  if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
1238 #if DEBUG
1239  printk(OSST_DEB_MSG "%s:D: Skipping config partition\n", name);
1240 #endif
1241  osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
1242  cnt--;
1243  }
1244  STp->frame_in_buffer = 0;
1245  }
1246  if (cnt > 1) {
1247  STp->recover_count++;
1248  STp->recover_erreg++;
1249  printk(KERN_WARNING "%s:I: Don't worry, Read error at position %d recovered\n",
1250  name, STp->read_error_frame);
1251  }
1252  STp->read_count++;
1253 
1254 #if DEBUG
1255  if (debugging || STps->eof)
1257  "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n",
1258  name, frame_seq_number, STp->frame_seq_number, STps->eof);
1259 #endif
1260  STp->fast_open = 0;
1261  STp->read_error_frame = 0;
1262  return (STps->eof);
1263 }
1264 
1265 static int osst_seek_logical_blk(struct osst_tape * STp, struct osst_request ** aSRpnt, int logical_blk_num)
1266 {
1267  struct st_partstat * STps = &(STp->ps[STp->partition]);
1268  char * name = tape_name(STp);
1269  int retries = 0;
1270  int frame_seq_estimate, ppos_estimate, move;
1271 
1272  if (logical_blk_num < 0) logical_blk_num = 0;
1273 #if DEBUG
1274  printk(OSST_DEB_MSG "%s:D: Seeking logical block %d (now at %d, size %d%c)\n",
1275  name, logical_blk_num, STp->logical_blk_num,
1276  STp->block_size<1024?STp->block_size:STp->block_size/1024,
1277  STp->block_size<1024?'b':'k');
1278 #endif
1279  /* Do we know where we are? */
1280  if (STps->drv_block >= 0) {
1281  move = logical_blk_num - STp->logical_blk_num;
1282  if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1283  move /= (OS_DATA_SIZE / STp->block_size);
1284  frame_seq_estimate = STp->frame_seq_number + move;
1285  } else
1286  frame_seq_estimate = logical_blk_num * STp->block_size / OS_DATA_SIZE;
1287 
1288  if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
1289  else ppos_estimate = frame_seq_estimate + 20;
1290  while (++retries < 10) {
1291  if (ppos_estimate > STp->eod_frame_ppos-2) {
1292  frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
1293  ppos_estimate = STp->eod_frame_ppos - 2;
1294  }
1295  if (frame_seq_estimate < 0) {
1296  frame_seq_estimate = 0;
1297  ppos_estimate = 10;
1298  }
1299  osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
1300  if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
1301  /* we've located the estimated frame, now does it have our block? */
1302  if (logical_blk_num < STp->logical_blk_num ||
1303  logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
1304  if (STps->eof == ST_FM_HIT)
1305  move = logical_blk_num < STp->logical_blk_num? -2 : 1;
1306  else {
1307  move = logical_blk_num - STp->logical_blk_num;
1308  if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
1309  move /= (OS_DATA_SIZE / STp->block_size);
1310  }
1311  if (!move) move = logical_blk_num > STp->logical_blk_num ? 1 : -1;
1312 #if DEBUG
1314  "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %d\n",
1315  name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1316  STp->logical_blk_num, logical_blk_num, move);
1317 #endif
1318  frame_seq_estimate += move;
1319  ppos_estimate += move;
1320  continue;
1321  } else {
1322  STp->buffer->read_pointer = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
1323  STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
1324  STp->logical_blk_num = logical_blk_num;
1325 #if DEBUG
1327  "%s:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%d\n",
1328  name, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer,
1329  STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size,
1330  STp->block_size);
1331 #endif
1332  STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1333  if (STps->eof == ST_FM_HIT) {
1334  STps->drv_file++;
1335  STps->drv_block = 0;
1336  } else {
1337  STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1338  STp->logical_blk_num -
1339  (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1340  -1;
1341  }
1342  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1343  return 0;
1344  }
1345  }
1346  if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
1347  goto error;
1348  /* we are not yet at the estimated frame, adjust our estimate of its physical position */
1349 #if DEBUG
1350  printk(OSST_DEB_MSG "%s:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)\n",
1351  name, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate,
1352  STp->logical_blk_num, logical_blk_num);
1353 #endif
1354  if (frame_seq_estimate != STp->frame_seq_number)
1355  ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
1356  else
1357  break;
1358  }
1359 error:
1360  printk(KERN_ERR "%s:E: Couldn't seek to logical block %d (at %d), %d retries\n",
1361  name, logical_blk_num, STp->logical_blk_num, retries);
1362  return (-EIO);
1363 }
1364 
1365 /* The values below are based on the OnStream frame payload size of 32K == 2**15,
1366  * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
1367  * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
1368  * inside each frame. Finally, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
1369  */
1370 #define OSST_FRAME_SHIFT 6
1371 #define OSST_SECTOR_SHIFT 9
1372 #define OSST_SECTOR_MASK 0x03F
1373 
1374 static int osst_get_sector(struct osst_tape * STp, struct osst_request ** aSRpnt)
1375 {
1376  int sector;
1377 #if DEBUG
1378  char * name = tape_name(STp);
1379 
1381  "%s:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %d\n",
1382  name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1383  STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block,
1384  STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
1385  STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
1386  STp->buffer->read_pointer, STp->ps[STp->partition].eof);
1387 #endif
1388  /* do we know where we are inside a file? */
1389  if (STp->ps[STp->partition].drv_block >= 0) {
1390  sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
1392  if (STp->ps[STp->partition].rw == ST_WRITING)
1393  sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1394  else
1395  sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
1396  } else {
1397  sector = osst_get_frame_position(STp, aSRpnt);
1398  if (sector > 0)
1399  sector <<= OSST_FRAME_SHIFT;
1400  }
1401  return sector;
1402 }
1403 
1404 static int osst_seek_sector(struct osst_tape * STp, struct osst_request ** aSRpnt, int sector)
1405 {
1406  struct st_partstat * STps = &(STp->ps[STp->partition]);
1407  int frame = sector >> OSST_FRAME_SHIFT,
1408  offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT,
1409  r;
1410 #if DEBUG
1411  char * name = tape_name(STp);
1412 
1413  printk(OSST_DEB_MSG "%s:D: Seeking sector %d in frame %d at offset %d\n",
1414  name, sector, frame, offset);
1415 #endif
1416  if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
1417 
1418  if (frame <= STp->first_data_ppos) {
1419  STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
1420  return (osst_set_frame_position(STp, aSRpnt, frame, 0));
1421  }
1422  r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
1423  if (r < 0) return r;
1424 
1425  r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
1426  if (r < 0) return r;
1427 
1428  if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
1429 
1430  if (offset) {
1431  STp->logical_blk_num += offset / STp->block_size;
1432  STp->buffer->read_pointer = offset;
1433  STp->buffer->buffer_bytes -= offset;
1434  } else {
1435  STp->frame_seq_number++;
1436  STp->frame_in_buffer = 0;
1437  STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1438  STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
1439  }
1440  STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
1441  if (STps->eof == ST_FM_HIT) {
1442  STps->drv_file++;
1443  STps->drv_block = 0;
1444  } else {
1445  STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
1446  STp->logical_blk_num -
1447  (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
1448  -1;
1449  }
1450  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
1451 #if DEBUG
1453  "%s:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %d\n",
1454  name, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
1455  STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
1456 #endif
1457  return 0;
1458 }
1459 
1460 /*
1461  * Read back the drive's internal buffer contents, as a part
1462  * of the write error recovery mechanism for old OnStream
1463  * firmware revisions.
1464  * Precondition for this function to work: all frames in the
1465  * drive's buffer must be of one type (DATA, MARK or EOD)!
1466  */
1467 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
1468  unsigned int frame, unsigned int skip, int pending)
1469 {
1470  struct osst_request * SRpnt = * aSRpnt;
1471  unsigned char * buffer, * p;
1472  unsigned char cmd[MAX_COMMAND_SIZE];
1473  int flag, new_frame, i;
1474  int nframes = STp->cur_frames;
1475  int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1476  int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
1477  - (nframes + pending - 1);
1478  int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num)
1479  - (nframes + pending - 1) * blks_per_frame;
1480  char * name = tape_name(STp);
1481  unsigned long startwait = jiffies;
1482 #if DEBUG
1483  int dbg = debugging;
1484 #endif
1485 
1486  if ((buffer = vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
1487  return (-EIO);
1488 
1489  printk(KERN_INFO "%s:I: Reading back %d frames from drive buffer%s\n",
1490  name, nframes, pending?" and one that was pending":"");
1491 
1492  osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
1493 #if DEBUG
1494  if (pending && debugging)
1495  printk(OSST_DEB_MSG "%s:D: Pending frame %d (lblk %d), data %02x %02x %02x %02x\n",
1496  name, frame_seq_number + nframes,
1497  logical_blk_num + nframes * blks_per_frame,
1498  p[0], p[1], p[2], p[3]);
1499 #endif
1500  for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
1501 
1502  memset(cmd, 0, MAX_COMMAND_SIZE);
1503  cmd[0] = 0x3C; /* Buffer Read */
1504  cmd[1] = 6; /* Retrieve Faulty Block */
1505  cmd[7] = 32768 >> 8;
1506  cmd[8] = 32768 & 0xff;
1507 
1508  SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
1509  STp->timeout, MAX_RETRIES, 1);
1510 
1511  if ((STp->buffer)->syscall_result || !SRpnt) {
1512  printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
1513  vfree(buffer);
1514  *aSRpnt = SRpnt;
1515  return (-EIO);
1516  }
1517  osst_copy_from_buffer(STp->buffer, p);
1518 #if DEBUG
1519  if (debugging)
1520  printk(OSST_DEB_MSG "%s:D: Read back logical frame %d, data %02x %02x %02x %02x\n",
1521  name, frame_seq_number + i, p[0], p[1], p[2], p[3]);
1522 #endif
1523  }
1524  *aSRpnt = SRpnt;
1525  osst_get_frame_position(STp, aSRpnt);
1526 
1527 #if DEBUG
1528  printk(OSST_DEB_MSG "%s:D: Frames left in buffer: %d\n", name, STp->cur_frames);
1529 #endif
1530  /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
1531  /* In the header we don't actually re-write the frames that fail, just the ones after them */
1532 
1533  for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
1534 
1535  if (flag) {
1536  if (STp->write_type == OS_WRITE_HEADER) {
1537  i += skip;
1538  p += skip * OS_DATA_SIZE;
1539  }
1540  else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
1541  new_frame = 3000-i;
1542  else
1543  new_frame += skip;
1544 #if DEBUG
1545  printk(OSST_DEB_MSG "%s:D: Position to frame %d, write fseq %d\n",
1546  name, new_frame+i, frame_seq_number+i);
1547 #endif
1548  osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
1549  osst_wait_ready(STp, aSRpnt, 60, OSST_WAIT_POSITION_COMPLETE);
1550  osst_get_frame_position(STp, aSRpnt);
1551  SRpnt = * aSRpnt;
1552 
1553  if (new_frame > frame + 1000) {
1554  printk(KERN_ERR "%s:E: Failed to find writable tape media\n", name);
1555  vfree(buffer);
1556  return (-EIO);
1557  }
1558  if ( i >= nframes + pending ) break;
1559  flag = 0;
1560  }
1561  osst_copy_to_buffer(STp->buffer, p);
1562  /*
1563  * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
1564  */
1565  osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
1566  logical_blk_num + i*blks_per_frame,
1567  ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
1568  memset(cmd, 0, MAX_COMMAND_SIZE);
1569  cmd[0] = WRITE_6;
1570  cmd[1] = 1;
1571  cmd[4] = 1;
1572 
1573 #if DEBUG
1574  if (debugging)
1576  "%s:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02x\n",
1577  name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
1578  p[0], p[1], p[2], p[3]);
1579 #endif
1580  SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1581  STp->timeout, MAX_RETRIES, 1);
1582 
1583  if (STp->buffer->syscall_result)
1584  flag = 1;
1585  else {
1586  p += OS_DATA_SIZE; i++;
1587 
1588  /* if we just sent the last frame, wait till all successfully written */
1589  if ( i == nframes + pending ) {
1590 #if DEBUG
1591  printk(OSST_DEB_MSG "%s:D: Check re-write successful\n", name);
1592 #endif
1593  memset(cmd, 0, MAX_COMMAND_SIZE);
1594  cmd[0] = WRITE_FILEMARKS;
1595  cmd[1] = 1;
1596  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
1597  STp->timeout, MAX_RETRIES, 1);
1598 #if DEBUG
1599  if (debugging) {
1600  printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1601  printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1602  debugging = 0;
1603  }
1604 #endif
1605  flag = STp->buffer->syscall_result;
1606  while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
1607 
1608  memset(cmd, 0, MAX_COMMAND_SIZE);
1609  cmd[0] = TEST_UNIT_READY;
1610 
1611  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
1612  MAX_RETRIES, 1);
1613 
1614  if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
1615  (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
1616  /* in the process of becoming ready */
1617  msleep(100);
1618  continue;
1619  }
1620  if (STp->buffer->syscall_result)
1621  flag = 1;
1622  break;
1623  }
1624 #if DEBUG
1625  debugging = dbg;
1626  printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1627 #endif
1628  }
1629  }
1630  *aSRpnt = SRpnt;
1631  if (flag) {
1632  if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1633  SRpnt->sense[12] == 0 &&
1634  SRpnt->sense[13] == 2) {
1635  printk(KERN_ERR "%s:E: Volume overflow in write error recovery\n", name);
1636  vfree(buffer);
1637  return (-EIO); /* hit end of tape = fail */
1638  }
1639  i = ((SRpnt->sense[3] << 24) |
1640  (SRpnt->sense[4] << 16) |
1641  (SRpnt->sense[5] << 8) |
1642  SRpnt->sense[6] ) - new_frame;
1643  p = &buffer[i * OS_DATA_SIZE];
1644 #if DEBUG
1645  printk(OSST_DEB_MSG "%s:D: Additional write error at %d\n", name, new_frame+i);
1646 #endif
1647  osst_get_frame_position(STp, aSRpnt);
1648 #if DEBUG
1649  printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
1650  name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
1651 #endif
1652  }
1653  }
1654  if (flag) {
1655  /* error recovery did not successfully complete */
1656  printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
1657  STp->write_type == OS_WRITE_HEADER?"header":"body");
1658  }
1659  if (!pending)
1660  osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
1661  vfree(buffer);
1662  return 0;
1663 }
1664 
1665 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
1666  unsigned int frame, unsigned int skip, int pending)
1667 {
1668  unsigned char cmd[MAX_COMMAND_SIZE];
1669  struct osst_request * SRpnt;
1670  char * name = tape_name(STp);
1671  int expected = 0;
1672  int attempts = 1000 / skip;
1673  int flag = 1;
1674  unsigned long startwait = jiffies;
1675 #if DEBUG
1676  int dbg = debugging;
1677 #endif
1678 
1679  while (attempts && time_before(jiffies, startwait + 60*HZ)) {
1680  if (flag) {
1681 #if DEBUG
1682  debugging = dbg;
1683 #endif
1684  if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
1685  frame = 3000-skip;
1686  expected = frame+skip+STp->cur_frames+pending;
1687 #if DEBUG
1688  printk(OSST_DEB_MSG "%s:D: Position to fppos %d, re-write from fseq %d\n",
1689  name, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
1690 #endif
1691  osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1692  flag = 0;
1693  attempts--;
1695  }
1696  if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1697 #if DEBUG
1698  printk(OSST_DEB_MSG "%s:D: Addl error, host %d, tape %d, buffer %d\n",
1699  name, STp->first_frame_position,
1700  STp->last_frame_position, STp->cur_frames);
1701 #endif
1702  frame = STp->last_frame_position;
1703  flag = 1;
1704  continue;
1705  }
1706  if (pending && STp->cur_frames < 50) {
1707 
1708  memset(cmd, 0, MAX_COMMAND_SIZE);
1709  cmd[0] = WRITE_6;
1710  cmd[1] = 1;
1711  cmd[4] = 1;
1712 #if DEBUG
1713  printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n",
1714  name, STp->frame_seq_number-1, STp->first_frame_position);
1715 #endif
1716  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
1717  STp->timeout, MAX_RETRIES, 1);
1718  *aSRpnt = SRpnt;
1719 
1720  if (STp->buffer->syscall_result) { /* additional write error */
1721  if ((SRpnt->sense[ 2] & 0x0f) == 13 &&
1722  SRpnt->sense[12] == 0 &&
1723  SRpnt->sense[13] == 2) {
1725  "%s:E: Volume overflow in write error recovery\n",
1726  name);
1727  break; /* hit end of tape = fail */
1728  }
1729  flag = 1;
1730  }
1731  else
1732  pending = 0;
1733 
1734  continue;
1735  }
1736  if (STp->cur_frames == 0) {
1737 #if DEBUG
1738  debugging = dbg;
1739  printk(OSST_DEB_MSG "%s:D: Wait re-write finished\n", name);
1740 #endif
1741  if (STp->first_frame_position != expected) {
1742  printk(KERN_ERR "%s:A: Actual position %d - expected %d\n",
1743  name, STp->first_frame_position, expected);
1744  return (-EIO);
1745  }
1746  return 0;
1747  }
1748 #if DEBUG
1749  if (debugging) {
1750  printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
1751  printk(OSST_DEB_MSG "%s:D: Turning off debugging for a while\n", name);
1752  debugging = 0;
1753  }
1754 #endif
1756  }
1757  printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1758 #if DEBUG
1759  debugging = dbg;
1760 #endif
1761  return (-EIO);
1762 }
1763 
1764 /*
1765  * Error recovery algorithm for the OnStream tape.
1766  */
1767 
1768 static int osst_write_error_recovery(struct osst_tape * STp, struct osst_request ** aSRpnt, int pending)
1769 {
1770  struct osst_request * SRpnt = * aSRpnt;
1771  struct st_partstat * STps = & STp->ps[STp->partition];
1772  char * name = tape_name(STp);
1773  int retval = 0;
1774  int rw_state;
1775  unsigned int frame, skip;
1776 
1777  rw_state = STps->rw;
1778 
1779  if ((SRpnt->sense[ 2] & 0x0f) != 3
1780  || SRpnt->sense[12] != 12
1781  || SRpnt->sense[13] != 0) {
1782 #if DEBUG
1783  printk(OSST_DEB_MSG "%s:D: Write error recovery cannot handle %02x:%02x:%02x\n", name,
1784  SRpnt->sense[2], SRpnt->sense[12], SRpnt->sense[13]);
1785 #endif
1786  return (-EIO);
1787  }
1788  frame = (SRpnt->sense[3] << 24) |
1789  (SRpnt->sense[4] << 16) |
1790  (SRpnt->sense[5] << 8) |
1791  SRpnt->sense[6];
1792  skip = SRpnt->sense[9];
1793 
1794 #if DEBUG
1795  printk(OSST_DEB_MSG "%s:D: Detected physical bad frame at %u, advised to skip %d\n", name, frame, skip);
1796 #endif
1797  osst_get_frame_position(STp, aSRpnt);
1798 #if DEBUG
1799  printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
1800  name, STp->first_frame_position, STp->last_frame_position);
1801 #endif
1802  switch (STp->write_type) {
1803  case OS_WRITE_DATA:
1804  case OS_WRITE_EOD:
1805  case OS_WRITE_NEW_MARK:
1807  "%s:I: Relocating %d buffered logical frames from position %u to %u\n",
1808  name, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
1809  if (STp->os_fw_rev >= 10600)
1810  retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
1811  else
1812  retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
1813  printk(KERN_WARNING "%s:%s: %sWrite error%srecovered\n", name,
1814  retval?"E" :"I",
1815  retval?"" :"Don't worry, ",
1816  retval?" not ":" ");
1817  break;
1818  case OS_WRITE_LAST_MARK:
1819  printk(KERN_ERR "%s:E: Bad frame in update last marker, fatal\n", name);
1820  osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1821  retval = -EIO;
1822  break;
1823  case OS_WRITE_HEADER:
1824  printk(KERN_WARNING "%s:I: Bad frame in header partition, skipped\n", name);
1825  retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
1826  break;
1827  default:
1828  printk(KERN_INFO "%s:I: Bad frame in filler, ignored\n", name);
1829  osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
1830  }
1831  osst_get_frame_position(STp, aSRpnt);
1832 #if DEBUG
1833  printk(OSST_DEB_MSG "%s:D: Positioning complete, cur_frames %d, pos %d, tape pos %d\n",
1834  name, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
1835  printk(OSST_DEB_MSG "%s:D: next logical frame to write: %d\n", name, STp->logical_blk_num);
1836 #endif
1837  if (retval == 0) {
1838  STp->recover_count++;
1839  STp->recover_erreg++;
1840  } else
1841  STp->abort_count++;
1842 
1843  STps->rw = rw_state;
1844  return retval;
1845 }
1846 
1847 static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct osst_request ** aSRpnt,
1848  int mt_op, int mt_count)
1849 {
1850  char * name = tape_name(STp);
1851  int cnt;
1852  int last_mark_ppos = -1;
1853 
1854 #if DEBUG
1855  printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_backwards %d %d\n", name, mt_op, mt_count);
1856 #endif
1857  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1858 #if DEBUG
1859  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_bwd\n", name);
1860 #endif
1861  return -EIO;
1862  }
1863  if (STp->linux_media_version >= 4) {
1864  /*
1865  * direct lookup in header filemark list
1866  */
1867  cnt = ntohl(STp->buffer->aux->filemark_cnt);
1868  if (STp->header_ok &&
1869  STp->header_cache != NULL &&
1870  (cnt - mt_count) >= 0 &&
1871  (cnt - mt_count) < OS_FM_TAB_MAX &&
1872  (cnt - mt_count) < STp->filemark_cnt &&
1873  STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
1874 
1875  last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
1876 #if DEBUG
1877  if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
1878  printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
1879  STp->header_cache == NULL?"lack of header cache":"count out of range");
1880  else
1881  printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
1882  name, cnt,
1883  ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
1884  (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
1885  STp->buffer->aux->last_mark_ppos))?"match":"error",
1886  mt_count, last_mark_ppos);
1887 #endif
1888  if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
1889  osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1890  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1891 #if DEBUG
1893  "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1894 #endif
1895  return (-EIO);
1896  }
1897  if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1898  printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1899  name, last_mark_ppos);
1900  return (-EIO);
1901  }
1902  goto found;
1903  }
1904 #if DEBUG
1905  printk(OSST_DEB_MSG "%s:D: Reverting to scan filemark backwards\n", name);
1906 #endif
1907  }
1908  cnt = 0;
1909  while (cnt != mt_count) {
1910  last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
1911  if (last_mark_ppos == -1)
1912  return (-EIO);
1913 #if DEBUG
1914  printk(OSST_DEB_MSG "%s:D: Positioning to last mark at %d\n", name, last_mark_ppos);
1915 #endif
1916  osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
1917  cnt++;
1918  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1919 #if DEBUG
1920  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1921 #endif
1922  return (-EIO);
1923  }
1924  if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
1925  printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
1926  name, last_mark_ppos);
1927  return (-EIO);
1928  }
1929  }
1930 found:
1931  if (mt_op == MTBSFM) {
1932  STp->frame_seq_number++;
1933  STp->frame_in_buffer = 0;
1934  STp->buffer->buffer_bytes = 0;
1935  STp->buffer->read_pointer = 0;
1936  STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1937  }
1938  return 0;
1939 }
1940 
1941 /*
1942  * ADRL 1.1 compatible "slow" space filemarks fwd version
1943  *
1944  * Just scans for the filemark sequentially.
1945  */
1946 static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct osst_request ** aSRpnt,
1947  int mt_op, int mt_count)
1948 {
1949  int cnt = 0;
1950 #if DEBUG
1951  char * name = tape_name(STp);
1952 
1953  printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_slow %d %d\n", name, mt_op, mt_count);
1954 #endif
1955  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1956 #if DEBUG
1957  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
1958 #endif
1959  return (-EIO);
1960  }
1961  while (1) {
1962  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
1963 #if DEBUG
1964  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n", name);
1965 #endif
1966  return (-EIO);
1967  }
1968  if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
1969  cnt++;
1970  if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
1971 #if DEBUG
1972  printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
1973 #endif
1974  if (STp->first_frame_position > STp->eod_frame_ppos+1) {
1975 #if DEBUG
1976  printk(OSST_DEB_MSG "%s:D: EOD position corrected (%d=>%d)\n",
1977  name, STp->eod_frame_ppos, STp->first_frame_position-1);
1978 #endif
1979  STp->eod_frame_ppos = STp->first_frame_position-1;
1980  }
1981  return (-EIO);
1982  }
1983  if (cnt == mt_count)
1984  break;
1985  STp->frame_in_buffer = 0;
1986  }
1987  if (mt_op == MTFSF) {
1988  STp->frame_seq_number++;
1989  STp->frame_in_buffer = 0;
1990  STp->buffer->buffer_bytes = 0;
1991  STp->buffer->read_pointer = 0;
1992  STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
1993  }
1994  return 0;
1995 }
1996 
1997 /*
1998  * Fast linux specific version of OnStream FSF
1999  */
2000 static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct osst_request ** aSRpnt,
2001  int mt_op, int mt_count)
2002 {
2003  char * name = tape_name(STp);
2004  int cnt = 0,
2005  next_mark_ppos = -1;
2006 
2007 #if DEBUG
2008  printk(OSST_DEB_MSG "%s:D: Reached space_over_filemarks_forward_fast %d %d\n", name, mt_op, mt_count);
2009 #endif
2010  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2011 #if DEBUG
2012  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks_fwd\n", name);
2013 #endif
2014  return (-EIO);
2015  }
2016 
2017  if (STp->linux_media_version >= 4) {
2018  /*
2019  * direct lookup in header filemark list
2020  */
2021  cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
2022  if (STp->header_ok &&
2023  STp->header_cache != NULL &&
2024  (cnt + mt_count) < OS_FM_TAB_MAX &&
2025  (cnt + mt_count) < STp->filemark_cnt &&
2026  ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2027  (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
2028 
2029  next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
2030 #if DEBUG
2031  if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
2032  printk(OSST_DEB_MSG "%s:D: Filemark lookup fail due to %s\n", name,
2033  STp->header_cache == NULL?"lack of header cache":"count out of range");
2034  else
2035  printk(OSST_DEB_MSG "%s:D: Filemark lookup: prev mark %d (%s), skip %d to %d\n",
2036  name, cnt,
2037  ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
2038  (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
2039  STp->buffer->aux->last_mark_ppos))?"match":"error",
2040  mt_count, next_mark_ppos);
2041 #endif
2042  if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
2043 #if DEBUG
2044  printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2045 #endif
2046  return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2047  } else {
2048  osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2049  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2050 #if DEBUG
2051  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2052  name);
2053 #endif
2054  return (-EIO);
2055  }
2056  if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2057  printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2058  name, next_mark_ppos);
2059  return (-EIO);
2060  }
2061  if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
2062  printk(KERN_WARNING "%s:W: Expected to find marker %d at ppos %d, not %d\n",
2063  name, cnt+mt_count, next_mark_ppos,
2064  ntohl(STp->buffer->aux->filemark_cnt));
2065  return (-EIO);
2066  }
2067  }
2068  } else {
2069  /*
2070  * Find nearest (usually previous) marker, then jump from marker to marker
2071  */
2072  while (1) {
2073  if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
2074  break;
2075  if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
2076 #if DEBUG
2077  printk(OSST_DEB_MSG "%s:D: space_fwd: EOD reached\n", name);
2078 #endif
2079  return (-EIO);
2080  }
2081  if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
2082  if (STp->first_mark_ppos == -1) {
2083 #if DEBUG
2084  printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2085 #endif
2086  return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
2087  }
2088  osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
2089  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2090 #if DEBUG
2092  "%s:D: Couldn't get logical blk num in space_filemarks_fwd_fast\n",
2093  name);
2094 #endif
2095  return (-EIO);
2096  }
2097  if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2098  printk(KERN_WARNING "%s:W: Expected to find filemark at %d\n",
2099  name, STp->first_mark_ppos);
2100  return (-EIO);
2101  }
2102  } else {
2103  if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
2104  return (-EIO);
2105  mt_count++;
2106  }
2107  }
2108  cnt++;
2109  while (cnt != mt_count) {
2110  next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
2111  if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
2112 #if DEBUG
2113  printk(OSST_DEB_MSG "%s:D: Reverting to slow filemark space\n", name);
2114 #endif
2115  return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
2116  }
2117 #if DEBUG
2118  else printk(OSST_DEB_MSG "%s:D: Positioning to next mark at %d\n", name, next_mark_ppos);
2119 #endif
2120  osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
2121  cnt++;
2122  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2123 #if DEBUG
2124  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in space_filemarks\n",
2125  name);
2126 #endif
2127  return (-EIO);
2128  }
2129  if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
2130  printk(KERN_WARNING "%s:W: Expected to find marker at ppos %d, not found\n",
2131  name, next_mark_ppos);
2132  return (-EIO);
2133  }
2134  }
2135  }
2136  if (mt_op == MTFSF) {
2137  STp->frame_seq_number++;
2138  STp->frame_in_buffer = 0;
2139  STp->buffer->buffer_bytes = 0;
2140  STp->buffer->read_pointer = 0;
2141  STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
2142  }
2143  return 0;
2144 }
2145 
2146 /*
2147  * In debug mode, we want to see as many errors as possible
2148  * to test the error recovery mechanism.
2149  */
2150 #if DEBUG
2151 static void osst_set_retries(struct osst_tape * STp, struct osst_request ** aSRpnt, int retries)
2152 {
2153  unsigned char cmd[MAX_COMMAND_SIZE];
2154  struct osst_request * SRpnt = * aSRpnt;
2155  char * name = tape_name(STp);
2156 
2157  memset(cmd, 0, MAX_COMMAND_SIZE);
2158  cmd[0] = MODE_SELECT;
2159  cmd[1] = 0x10;
2161 
2162  (STp->buffer)->b_data[0] = cmd[4] - 1;
2163  (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
2164  (STp->buffer)->b_data[2] = 0; /* Reserved */
2165  (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
2166  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
2167  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
2168  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
2169  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
2170 
2171  if (debugging)
2172  printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
2173 
2174  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2175  *aSRpnt = SRpnt;
2176 
2177  if ((STp->buffer)->syscall_result)
2178  printk (KERN_ERR "%s:D: Couldn't set retries to %d\n", name, retries);
2179 }
2180 #endif
2181 
2182 
2183 static int osst_write_filemark(struct osst_tape * STp, struct osst_request ** aSRpnt)
2184 {
2185  int result;
2186  int this_mark_ppos = STp->first_frame_position;
2187  int this_mark_lbn = STp->logical_blk_num;
2188 #if DEBUG
2189  char * name = tape_name(STp);
2190 #endif
2191 
2192  if (STp->raw) return 0;
2193 
2195 #if DEBUG
2196  printk(OSST_DEB_MSG "%s:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)\n",
2197  name, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
2198 #endif
2199  STp->dirty = 1;
2200  result = osst_flush_write_buffer(STp, aSRpnt);
2201  result |= osst_flush_drive_buffer(STp, aSRpnt);
2202  STp->last_mark_ppos = this_mark_ppos;
2203  STp->last_mark_lbn = this_mark_lbn;
2204  if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
2205  STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
2206  if (STp->filemark_cnt++ == 0)
2207  STp->first_mark_ppos = this_mark_ppos;
2208  return result;
2209 }
2210 
2211 static int osst_write_eod(struct osst_tape * STp, struct osst_request ** aSRpnt)
2212 {
2213  int result;
2214 #if DEBUG
2215  char * name = tape_name(STp);
2216 #endif
2217 
2218  if (STp->raw) return 0;
2219 
2220  STp->write_type = OS_WRITE_EOD;
2222 #if DEBUG
2223  printk(OSST_DEB_MSG "%s:D: Writing EOD at fppos %d (fseq %d, lblk %d)\n", name,
2225 #endif
2226  STp->dirty = 1;
2227 
2228  result = osst_flush_write_buffer(STp, aSRpnt);
2229  result |= osst_flush_drive_buffer(STp, aSRpnt);
2230  STp->eod_frame_lfa = --(STp->frame_seq_number);
2231  return result;
2232 }
2233 
2234 static int osst_write_filler(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2235 {
2236  char * name = tape_name(STp);
2237 
2238 #if DEBUG
2239  printk(OSST_DEB_MSG "%s:D: Reached onstream write filler group %d\n", name, where);
2240 #endif
2241  osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2242  osst_set_frame_position(STp, aSRpnt, where, 0);
2243  STp->write_type = OS_WRITE_FILLER;
2244  while (count--) {
2245  memcpy(STp->buffer->b_data, "Filler", 6);
2246  STp->buffer->buffer_bytes = 6;
2247  STp->dirty = 1;
2248  if (osst_flush_write_buffer(STp, aSRpnt)) {
2249  printk(KERN_INFO "%s:I: Couldn't write filler frame\n", name);
2250  return (-EIO);
2251  }
2252  }
2253 #if DEBUG
2254  printk(OSST_DEB_MSG "%s:D: Exiting onstream write filler group\n", name);
2255 #endif
2256  return osst_flush_drive_buffer(STp, aSRpnt);
2257 }
2258 
2259 static int __osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int where, int count)
2260 {
2261  char * name = tape_name(STp);
2262  int result;
2263 
2264 #if DEBUG
2265  printk(OSST_DEB_MSG "%s:D: Reached onstream write header group %d\n", name, where);
2266 #endif
2267  osst_wait_ready(STp, aSRpnt, 60 * 5, 0);
2268  osst_set_frame_position(STp, aSRpnt, where, 0);
2269  STp->write_type = OS_WRITE_HEADER;
2270  while (count--) {
2271  osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2272  STp->buffer->buffer_bytes = sizeof(os_header_t);
2273  STp->dirty = 1;
2274  if (osst_flush_write_buffer(STp, aSRpnt)) {
2275  printk(KERN_INFO "%s:I: Couldn't write header frame\n", name);
2276  return (-EIO);
2277  }
2278  }
2279  result = osst_flush_drive_buffer(STp, aSRpnt);
2280 #if DEBUG
2281  printk(OSST_DEB_MSG "%s:D: Write onstream header group %s\n", name, result?"failed":"done");
2282 #endif
2283  return result;
2284 }
2285 
2286 static int osst_write_header(struct osst_tape * STp, struct osst_request ** aSRpnt, int locate_eod)
2287 {
2288  os_header_t * header;
2289  int result;
2290  char * name = tape_name(STp);
2291 
2292 #if DEBUG
2293  printk(OSST_DEB_MSG "%s:D: Writing tape header\n", name);
2294 #endif
2295  if (STp->raw) return 0;
2296 
2297  if (STp->header_cache == NULL) {
2298  if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2299  printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2300  return (-ENOMEM);
2301  }
2302  memset(STp->header_cache, 0, sizeof(os_header_t));
2303 #if DEBUG
2304  printk(OSST_DEB_MSG "%s:D: Allocated and cleared memory for header cache\n", name);
2305 #endif
2306  }
2307  if (STp->header_ok) STp->update_frame_cntr++;
2308  else STp->update_frame_cntr = 0;
2309 
2310  header = STp->header_cache;
2311  strcpy(header->ident_str, "ADR_SEQ");
2312  header->major_rev = 1;
2313  header->minor_rev = 4;
2314  header->ext_trk_tb_off = htons(17192);
2315  header->pt_par_num = 1;
2318  header->partition[0].wrt_pass_cntr = htons(STp->wrt_pass_cntr);
2319  header->partition[0].first_frame_ppos = htonl(STp->first_data_ppos);
2320  header->partition[0].last_frame_ppos = htonl(STp->capacity);
2321  header->partition[0].eod_frame_ppos = htonl(STp->eod_frame_ppos);
2322  header->cfg_col_width = htonl(20);
2323  header->dat_col_width = htonl(1500);
2324  header->qfa_col_width = htonl(0);
2325  header->ext_track_tb.nr_stream_part = 1;
2326  header->ext_track_tb.et_ent_sz = 32;
2328  header->ext_track_tb.dat_ext_trk_ey.fmt = 1;
2329  header->ext_track_tb.dat_ext_trk_ey.fm_tab_off = htons(17736);
2333  header->dat_fm_tab.fm_part_num = 0;
2334  header->dat_fm_tab.fm_tab_ent_sz = 4;
2337 
2338  result = __osst_write_header(STp, aSRpnt, 0xbae, 5);
2339  if (STp->update_frame_cntr == 0)
2340  osst_write_filler(STp, aSRpnt, 0xbb3, 5);
2341  result &= __osst_write_header(STp, aSRpnt, 5, 5);
2342 
2343  if (locate_eod) {
2344 #if DEBUG
2345  printk(OSST_DEB_MSG "%s:D: Locating back to eod frame addr %d\n", name, STp->eod_frame_ppos);
2346 #endif
2347  osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
2348  }
2349  if (result)
2350  printk(KERN_ERR "%s:E: Write header failed\n", name);
2351  else {
2352  memcpy(STp->application_sig, "LIN4", 4);
2353  STp->linux_media = 1;
2354  STp->linux_media_version = 4;
2355  STp->header_ok = 1;
2356  }
2357  return result;
2358 }
2359 
2360 static int osst_reset_header(struct osst_tape * STp, struct osst_request ** aSRpnt)
2361 {
2362  if (STp->header_cache != NULL)
2363  memset(STp->header_cache, 0, sizeof(os_header_t));
2364 
2365  STp->logical_blk_num = STp->frame_seq_number = 0;
2366  STp->frame_in_buffer = 0;
2367  STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
2368  STp->filemark_cnt = 0;
2369  STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2370  return osst_write_header(STp, aSRpnt, 1);
2371 }
2372 
2373 static int __osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt, int ppos)
2374 {
2375  char * name = tape_name(STp);
2376  os_header_t * header;
2377  os_aux_t * aux;
2378  char id_string[8];
2379  int linux_media_version,
2380  update_frame_cntr;
2381 
2382  if (STp->raw)
2383  return 1;
2384 
2385  if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
2386  if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
2387  printk(KERN_WARNING "%s:W: Couldn't position tape\n", name);
2388  osst_wait_ready(STp, aSRpnt, 60 * 15, 0);
2389  if (osst_initiate_read (STp, aSRpnt)) {
2390  printk(KERN_WARNING "%s:W: Couldn't initiate read\n", name);
2391  return 0;
2392  }
2393  }
2394  if (osst_read_frame(STp, aSRpnt, 180)) {
2395 #if DEBUG
2396  printk(OSST_DEB_MSG "%s:D: Couldn't read header frame\n", name);
2397 #endif
2398  return 0;
2399  }
2400  header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
2401  aux = STp->buffer->aux;
2402  if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
2403 #if DEBUG
2404  printk(OSST_DEB_MSG "%s:D: Skipping non-header frame (%d)\n", name, ppos);
2405 #endif
2406  return 0;
2407  }
2408  if (ntohl(aux->frame_seq_num) != 0 ||
2409  ntohl(aux->logical_blk_num) != 0 ||
2411  ntohl(aux->partition.first_frame_ppos) != 0 ||
2412  ntohl(aux->partition.last_frame_ppos) != 0xbb7 ) {
2413 #if DEBUG
2414  printk(OSST_DEB_MSG "%s:D: Invalid header frame (%d,%d,%d,%d,%d)\n", name,
2418 #endif
2419  return 0;
2420  }
2421  if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
2422  strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
2423  strlcpy(id_string, header->ident_str, 8);
2424 #if DEBUG
2425  printk(OSST_DEB_MSG "%s:D: Invalid header identification string %s\n", name, id_string);
2426 #endif
2427  return 0;
2428  }
2429  update_frame_cntr = ntohl(aux->update_frame_cntr);
2430  if (update_frame_cntr < STp->update_frame_cntr) {
2431 #if DEBUG
2432  printk(OSST_DEB_MSG "%s:D: Skipping frame %d with update_frame_counter %d<%d\n",
2433  name, ppos, update_frame_cntr, STp->update_frame_cntr);
2434 #endif
2435  return 0;
2436  }
2437  if (header->major_rev != 1 || header->minor_rev != 4 ) {
2438 #if DEBUG
2439  printk(OSST_DEB_MSG "%s:D: %s revision %d.%d detected (1.4 supported)\n",
2440  name, (header->major_rev != 1 || header->minor_rev < 2 ||
2441  header->minor_rev > 4 )? "Invalid" : "Warning:",
2442  header->major_rev, header->minor_rev);
2443 #endif
2444  if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
2445  return 0;
2446  }
2447 #if DEBUG
2448  if (header->pt_par_num != 1)
2449  printk(KERN_INFO "%s:W: %d partitions defined, only one supported\n",
2450  name, header->pt_par_num);
2451 #endif
2452  memcpy(id_string, aux->application_sig, 4);
2453  id_string[4] = 0;
2454  if (memcmp(id_string, "LIN", 3) == 0) {
2455  STp->linux_media = 1;
2456  linux_media_version = id_string[3] - '0';
2457  if (linux_media_version != 4)
2458  printk(KERN_INFO "%s:I: Linux media version %d detected (current 4)\n",
2459  name, linux_media_version);
2460  } else {
2461  printk(KERN_WARNING "%s:W: Non Linux media detected (%s)\n", name, id_string);
2462  return 0;
2463  }
2464  if (linux_media_version < STp->linux_media_version) {
2465 #if DEBUG
2466  printk(OSST_DEB_MSG "%s:D: Skipping frame %d with linux_media_version %d\n",
2467  name, ppos, linux_media_version);
2468 #endif
2469  return 0;
2470  }
2471  if (linux_media_version > STp->linux_media_version) {
2472 #if DEBUG
2473  printk(OSST_DEB_MSG "%s:D: Frame %d sets linux_media_version to %d\n",
2474  name, ppos, linux_media_version);
2475 #endif
2476  memcpy(STp->application_sig, id_string, 5);
2477  STp->linux_media_version = linux_media_version;
2478  STp->update_frame_cntr = -1;
2479  }
2480  if (update_frame_cntr > STp->update_frame_cntr) {
2481 #if DEBUG
2482  printk(OSST_DEB_MSG "%s:D: Frame %d sets update_frame_counter to %d\n",
2483  name, ppos, update_frame_cntr);
2484 #endif
2485  if (STp->header_cache == NULL) {
2486  if ((STp->header_cache = vmalloc(sizeof(os_header_t))) == NULL) {
2487  printk(KERN_ERR "%s:E: Failed to allocate header cache\n", name);
2488  return 0;
2489  }
2490 #if DEBUG
2491  printk(OSST_DEB_MSG "%s:D: Allocated memory for header cache\n", name);
2492 #endif
2493  }
2494  osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
2495  header = STp->header_cache; /* further accesses from cached (full) copy */
2496 
2497  STp->wrt_pass_cntr = ntohs(header->partition[0].wrt_pass_cntr);
2498  STp->first_data_ppos = ntohl(header->partition[0].first_frame_ppos);
2499  STp->eod_frame_ppos = ntohl(header->partition[0].eod_frame_ppos);
2501  STp->filemark_cnt = ntohl(aux->filemark_cnt);
2502  STp->first_mark_ppos = ntohl(aux->next_mark_ppos);
2503  STp->last_mark_ppos = ntohl(aux->last_mark_ppos);
2504  STp->last_mark_lbn = ntohl(aux->last_mark_lbn);
2505  STp->update_frame_cntr = update_frame_cntr;
2506 #if DEBUG
2507  printk(OSST_DEB_MSG "%s:D: Detected write pass %d, update frame counter %d, filemark counter %d\n",
2508  name, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
2509  printk(OSST_DEB_MSG "%s:D: first data frame on tape = %d, last = %d, eod frame = %d\n", name,
2510  STp->first_data_ppos,
2511  ntohl(header->partition[0].last_frame_ppos),
2512  ntohl(header->partition[0].eod_frame_ppos));
2513  printk(OSST_DEB_MSG "%s:D: first mark on tape = %d, last = %d, eod frame = %d\n",
2514  name, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
2515 #endif
2516  if (header->minor_rev < 4 && STp->linux_media_version == 4) {
2517 #if DEBUG
2518  printk(OSST_DEB_MSG "%s:D: Moving filemark list to ADR 1.4 location\n", name);
2519 #endif
2520  memcpy((void *)header->dat_fm_tab.fm_tab_ent,
2521  (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
2522  memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
2523  }
2524  if (header->minor_rev == 4 &&
2525  (header->ext_trk_tb_off != htons(17192) ||
2526  header->partition[0].partition_num != OS_DATA_PARTITION ||
2528  header->partition[0].last_frame_ppos != htonl(STp->capacity) ||
2529  header->cfg_col_width != htonl(20) ||
2530  header->dat_col_width != htonl(1500) ||
2531  header->qfa_col_width != htonl(0) ||
2532  header->ext_track_tb.nr_stream_part != 1 ||
2533  header->ext_track_tb.et_ent_sz != 32 ||
2535  header->ext_track_tb.dat_ext_trk_ey.fmt != 1 ||
2536  header->ext_track_tb.dat_ext_trk_ey.fm_tab_off != htons(17736) ||
2537  header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0 ||
2540  header->dat_fm_tab.fm_tab_ent_sz != 4 ||
2541  header->dat_fm_tab.fm_tab_ent_cnt !=
2543  printk(KERN_WARNING "%s:W: Failed consistency check ADR 1.4 format\n", name);
2544 
2545  }
2546 
2547  return 1;
2548 }
2549 
2550 static int osst_analyze_headers(struct osst_tape * STp, struct osst_request ** aSRpnt)
2551 {
2552  int position, ppos;
2553  int first, last;
2554  int valid = 0;
2555  char * name = tape_name(STp);
2556 
2557  position = osst_get_frame_position(STp, aSRpnt);
2558 
2559  if (STp->raw) {
2560  STp->header_ok = STp->linux_media = 1;
2561  STp->linux_media_version = 0;
2562  return 1;
2563  }
2564  STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
2565  STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
2566  STp->eod_frame_ppos = STp->first_data_ppos = -1;
2567  STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
2568 #if DEBUG
2569  printk(OSST_DEB_MSG "%s:D: Reading header\n", name);
2570 #endif
2571 
2572  /* optimization for speed - if we are positioned at ppos 10, read second group first */
2573  /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
2574 
2575  first = position==10?0xbae: 5;
2576  last = position==10?0xbb3:10;
2577 
2578  for (ppos = first; ppos < last; ppos++)
2579  if (__osst_analyze_headers(STp, aSRpnt, ppos))
2580  valid = 1;
2581 
2582  first = position==10? 5:0xbae;
2583  last = position==10?10:0xbb3;
2584 
2585  for (ppos = first; ppos < last; ppos++)
2586  if (__osst_analyze_headers(STp, aSRpnt, ppos))
2587  valid = 1;
2588 
2589  if (!valid) {
2590  printk(KERN_ERR "%s:E: Failed to find valid ADRL header, new media?\n", name);
2591  STp->eod_frame_ppos = STp->first_data_ppos = 0;
2592  osst_set_frame_position(STp, aSRpnt, 10, 0);
2593  return 0;
2594  }
2595  if (position <= STp->first_data_ppos) {
2596  position = STp->first_data_ppos;
2597  STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
2598  }
2599  osst_set_frame_position(STp, aSRpnt, position, 0);
2600  STp->header_ok = 1;
2601 
2602  return 1;
2603 }
2604 
2605 static int osst_verify_position(struct osst_tape * STp, struct osst_request ** aSRpnt)
2606 {
2607  int frame_position = STp->first_frame_position;
2608  int frame_seq_numbr = STp->frame_seq_number;
2609  int logical_blk_num = STp->logical_blk_num;
2610  int halfway_frame = STp->frame_in_buffer;
2611  int read_pointer = STp->buffer->read_pointer;
2612  int prev_mark_ppos = -1;
2613  int actual_mark_ppos, i, n;
2614 #if DEBUG
2615  char * name = tape_name(STp);
2616 
2617  printk(OSST_DEB_MSG "%s:D: Verify that the tape is really the one we think before writing\n", name);
2618 #endif
2619  osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2620  if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
2621 #if DEBUG
2622  printk(OSST_DEB_MSG "%s:D: Couldn't get logical blk num in verify_position\n", name);
2623 #endif
2624  return (-EIO);
2625  }
2626  if (STp->linux_media_version >= 4) {
2627  for (i=0; i<STp->filemark_cnt; i++)
2628  if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
2629  prev_mark_ppos = n;
2630  } else
2631  prev_mark_ppos = frame_position - 1; /* usually - we don't really know */
2632  actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
2633  frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
2634  if (frame_position != STp->first_frame_position ||
2635  frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
2636  prev_mark_ppos != actual_mark_ppos ) {
2637 #if DEBUG
2638  printk(OSST_DEB_MSG "%s:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%d\n", name,
2639  STp->first_frame_position, frame_position,
2640  STp->frame_seq_number + (halfway_frame?0:1),
2641  frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
2642 #endif
2643  return (-EIO);
2644  }
2645  if (halfway_frame) {
2646  /* prepare buffer for append and rewrite on top of original */
2647  osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
2648  STp->buffer->buffer_bytes = read_pointer;
2649  STp->ps[STp->partition].rw = ST_WRITING;
2650  STp->dirty = 1;
2651  }
2652  STp->frame_in_buffer = halfway_frame;
2653  STp->frame_seq_number = frame_seq_numbr;
2654  STp->logical_blk_num = logical_blk_num;
2655  return 0;
2656 }
2657 
2658 /* Acc. to OnStream, the vers. numbering is the following:
2659  * X.XX for released versions (X=digit),
2660  * XXXY for unreleased versions (Y=letter)
2661  * Ordering 1.05 < 106A < 106B < ... < 106a < ... < 1.06
2662  * This fn makes monoton numbers out of this scheme ...
2663  */
2664 static unsigned int osst_parse_firmware_rev (const char * str)
2665 {
2666  if (str[1] == '.') {
2667  return (str[0]-'0')*10000
2668  +(str[2]-'0')*1000
2669  +(str[3]-'0')*100;
2670  } else {
2671  return (str[0]-'0')*10000
2672  +(str[1]-'0')*1000
2673  +(str[2]-'0')*100 - 100
2674  +(str[3]-'@');
2675  }
2676 }
2677 
2678 /*
2679  * Configure the OnStream SCII tape drive for default operation
2680  */
2681 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
2682 {
2683  unsigned char cmd[MAX_COMMAND_SIZE];
2684  char * name = tape_name(STp);
2685  struct osst_request * SRpnt = * aSRpnt;
2690  int drive_buffer_size;
2691 
2692  if (STp->ready != ST_READY) {
2693 #if DEBUG
2694  printk(OSST_DEB_MSG "%s:D: Not Ready\n", name);
2695 #endif
2696  return (-EIO);
2697  }
2698 
2699  if (STp->os_fw_rev < 10600) {
2700  printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
2701  printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
2702  }
2703 
2704  /*
2705  * Configure 32.5KB (data+aux) frame size.
2706  * Get the current frame size from the block size mode page
2707  */
2708  memset(cmd, 0, MAX_COMMAND_SIZE);
2709  cmd[0] = MODE_SENSE;
2710  cmd[1] = 8;
2711  cmd[2] = BLOCK_SIZE_PAGE;
2713 
2714  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2715  if (SRpnt == NULL) {
2716 #if DEBUG
2717  printk(OSST_DEB_MSG "osst :D: Busy\n");
2718 #endif
2719  return (-EBUSY);
2720  }
2721  *aSRpnt = SRpnt;
2722  if ((STp->buffer)->syscall_result != 0) {
2723  printk (KERN_ERR "%s:E: Can't get tape block size mode page\n", name);
2724  return (-EIO);
2725  }
2726 
2727  header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2728  bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
2729 
2730 #if DEBUG
2731  printk(OSST_DEB_MSG "%s:D: 32KB play back: %s\n", name, bs->play32 ? "Yes" : "No");
2732  printk(OSST_DEB_MSG "%s:D: 32.5KB play back: %s\n", name, bs->play32_5 ? "Yes" : "No");
2733  printk(OSST_DEB_MSG "%s:D: 32KB record: %s\n", name, bs->record32 ? "Yes" : "No");
2734  printk(OSST_DEB_MSG "%s:D: 32.5KB record: %s\n", name, bs->record32_5 ? "Yes" : "No");
2735 #endif
2736 
2737  /*
2738  * Configure default auto columns mode, 32.5KB transfer mode
2739  */
2740  bs->one = 1;
2741  bs->play32 = 0;
2742  bs->play32_5 = 1;
2743  bs->record32 = 0;
2744  bs->record32_5 = 1;
2745 
2746  memset(cmd, 0, MAX_COMMAND_SIZE);
2747  cmd[0] = MODE_SELECT;
2748  cmd[1] = 0x10;
2750 
2751  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2752  *aSRpnt = SRpnt;
2753  if ((STp->buffer)->syscall_result != 0) {
2754  printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
2755  return (-EIO);
2756  }
2757 
2758 #if DEBUG
2759  printk(KERN_INFO "%s:D: Drive Block Size changed to 32.5K\n", name);
2760  /*
2761  * In debug mode, we want to see as many errors as possible
2762  * to test the error recovery mechanism.
2763  */
2764  osst_set_retries(STp, aSRpnt, 0);
2765  SRpnt = * aSRpnt;
2766 #endif
2767 
2768  /*
2769  * Set vendor name to 'LIN4' for "Linux support version 4".
2770  */
2771 
2772  memset(cmd, 0, MAX_COMMAND_SIZE);
2773  cmd[0] = MODE_SELECT;
2774  cmd[1] = 0x10;
2776 
2777  header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
2778  header->medium_type = 0; /* Medium Type - ignoring */
2779  header->dsp = 0; /* Reserved */
2780  header->bdl = 0; /* Block Descriptor Length */
2781 
2782  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
2783  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
2784  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
2785  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
2786  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
2787  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
2788  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
2789  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
2790 
2791  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
2792  *aSRpnt = SRpnt;
2793 
2794  if ((STp->buffer)->syscall_result != 0) {
2795  printk (KERN_ERR "%s:E: Couldn't set vendor name to %s\n", name,
2796  (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
2797  return (-EIO);
2798  }
2799 
2800  memset(cmd, 0, MAX_COMMAND_SIZE);
2801  cmd[0] = MODE_SENSE;
2802  cmd[1] = 8;
2803  cmd[2] = CAPABILITIES_PAGE;
2805 
2806  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2807  *aSRpnt = SRpnt;
2808 
2809  if ((STp->buffer)->syscall_result != 0) {
2810  printk (KERN_ERR "%s:E: Can't get capabilities page\n", name);
2811  return (-EIO);
2812  }
2813 
2814  header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2815  cp = (osst_capabilities_page_t *) ((STp->buffer)->b_data +
2816  sizeof(osst_mode_parameter_header_t) + header->bdl);
2817 
2818  drive_buffer_size = ntohs(cp->buffer_size) / 2;
2819 
2820  memset(cmd, 0, MAX_COMMAND_SIZE);
2821  cmd[0] = MODE_SENSE;
2822  cmd[1] = 8;
2823  cmd[2] = TAPE_PARAMTR_PAGE;
2825 
2826  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
2827  *aSRpnt = SRpnt;
2828 
2829  if ((STp->buffer)->syscall_result != 0) {
2830  printk (KERN_ERR "%s:E: Can't get tape parameter page\n", name);
2831  return (-EIO);
2832  }
2833 
2834  header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
2835  prm = (osst_tape_paramtr_page_t *) ((STp->buffer)->b_data +
2836  sizeof(osst_mode_parameter_header_t) + header->bdl);
2837 
2838  STp->density = prm->density;
2839  STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
2840 #if DEBUG
2841  printk(OSST_DEB_MSG "%s:D: Density %d, tape length: %dMB, drive buffer size: %dKB\n",
2842  name, STp->density, STp->capacity / 32, drive_buffer_size);
2843 #endif
2844 
2845  return 0;
2846 
2847 }
2848 
2849 
2850 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
2851  it messes up the block number). */
2852 static int cross_eof(struct osst_tape *STp, struct osst_request ** aSRpnt, int forward)
2853 {
2854  int result;
2855  char * name = tape_name(STp);
2856 
2857 #if DEBUG
2858  if (debugging)
2859  printk(OSST_DEB_MSG "%s:D: Stepping over filemark %s.\n",
2860  name, forward ? "forward" : "backward");
2861 #endif
2862 
2863  if (forward) {
2864  /* assumes that the filemark is already read by the drive, so this is low cost */
2865  result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
2866  }
2867  else
2868  /* assumes this is only called if we just read the filemark! */
2869  result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
2870 
2871  if (result < 0)
2872  printk(KERN_WARNING "%s:W: Stepping over filemark %s failed.\n",
2873  name, forward ? "forward" : "backward");
2874 
2875  return result;
2876 }
2877 
2878 
2879 /* Get the tape position. */
2880 
2881 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
2882 {
2883  unsigned char scmd[MAX_COMMAND_SIZE];
2884  struct osst_request * SRpnt;
2885  int result = 0;
2886  char * name = tape_name(STp);
2887 
2888  /* KG: We want to be able to use it for checking Write Buffer availability
2889  * and thus don't want to risk to overwrite anything. Exchange buffers ... */
2890  char mybuf[24];
2891  char * olddata = STp->buffer->b_data;
2892  int oldsize = STp->buffer->buffer_size;
2893 
2894  if (STp->ready != ST_READY) return (-EIO);
2895 
2896  memset (scmd, 0, MAX_COMMAND_SIZE);
2897  scmd[0] = READ_POSITION;
2898 
2899  STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2900  SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2901  STp->timeout, MAX_RETRIES, 1);
2902  if (!SRpnt) {
2903  STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2904  return (-EBUSY);
2905  }
2906  *aSRpnt = SRpnt;
2907 
2908  if (STp->buffer->syscall_result)
2909  result = ((SRpnt->sense[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */
2910 
2911  if (result == -EINVAL)
2912  printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
2913  else {
2914  if (result == -EIO) { /* re-read position - this needs to preserve media errors */
2915  unsigned char mysense[16];
2916  memcpy (mysense, SRpnt->sense, 16);
2917  memset (scmd, 0, MAX_COMMAND_SIZE);
2918  scmd[0] = READ_POSITION;
2919  STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
2920  SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
2921  STp->timeout, MAX_RETRIES, 1);
2922 #if DEBUG
2923  printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
2924  name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
2925  SRpnt->sense[2],SRpnt->sense[12],SRpnt->sense[13]);
2926 #endif
2927  if (!STp->buffer->syscall_result)
2928  memcpy (SRpnt->sense, mysense, 16);
2929  else
2930  printk(KERN_WARNING "%s:W: Double error in get position\n", name);
2931  }
2932  STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
2933  + ((STp->buffer)->b_data[5] << 16)
2934  + ((STp->buffer)->b_data[6] << 8)
2935  + (STp->buffer)->b_data[7];
2936  STp->last_frame_position = ((STp->buffer)->b_data[ 8] << 24)
2937  + ((STp->buffer)->b_data[ 9] << 16)
2938  + ((STp->buffer)->b_data[10] << 8)
2939  + (STp->buffer)->b_data[11];
2940  STp->cur_frames = (STp->buffer)->b_data[15];
2941 #if DEBUG
2942  if (debugging) {
2943  printk(OSST_DEB_MSG "%s:D: Drive Positions: host %d, tape %d%s, buffer %d\n", name,
2945  ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
2946  ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
2947  STp->cur_frames);
2948  }
2949 #endif
2950  if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
2951 #if DEBUG
2952  printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
2954 #endif
2956  }
2957  }
2958  STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
2959 
2960  return (result == 0 ? STp->first_frame_position : result);
2961 }
2962 
2963 
2964 /* Set the tape block */
2965 static int osst_set_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt, int ppos, int skip)
2966 {
2967  unsigned char scmd[MAX_COMMAND_SIZE];
2968  struct osst_request * SRpnt;
2969  struct st_partstat * STps;
2970  int result = 0;
2971  int pp = (ppos == 3000 && !skip)? 0 : ppos;
2972  char * name = tape_name(STp);
2973 
2974  if (STp->ready != ST_READY) return (-EIO);
2975 
2976  STps = &(STp->ps[STp->partition]);
2977 
2978  if (ppos < 0 || ppos > STp->capacity) {
2979  printk(KERN_WARNING "%s:W: Reposition request %d out of range\n", name, ppos);
2980  pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
2981  result = (-EINVAL);
2982  }
2983 
2984  do {
2985 #if DEBUG
2986  if (debugging)
2987  printk(OSST_DEB_MSG "%s:D: Setting ppos to %d.\n", name, pp);
2988 #endif
2989  memset (scmd, 0, MAX_COMMAND_SIZE);
2990  scmd[0] = SEEK_10;
2991  scmd[1] = 1;
2992  scmd[3] = (pp >> 24);
2993  scmd[4] = (pp >> 16);
2994  scmd[5] = (pp >> 8);
2995  scmd[6] = pp;
2996  if (skip)
2997  scmd[9] = 0x80;
2998 
2999  SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
3000  MAX_RETRIES, 1);
3001  if (!SRpnt)
3002  return (-EBUSY);
3003  *aSRpnt = SRpnt;
3004 
3005  if ((STp->buffer)->syscall_result != 0) {
3006 #if DEBUG
3007  printk(OSST_DEB_MSG "%s:D: SEEK command from %d to %d failed.\n",
3008  name, STp->first_frame_position, pp);
3009 #endif
3010  result = (-EIO);
3011  }
3012  if (pp != ppos)
3013  osst_wait_ready(STp, aSRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
3014  } while ((pp != ppos) && (pp = ppos));
3015  STp->first_frame_position = STp->last_frame_position = ppos;
3016  STps->eof = ST_NOEOF;
3017  STps->at_sm = 0;
3018  STps->rw = ST_IDLE;
3019  STp->frame_in_buffer = 0;
3020  return result;
3021 }
3022 
3023 static int osst_write_trailer(struct osst_tape *STp, struct osst_request ** aSRpnt, int leave_at_EOT)
3024 {
3025  struct st_partstat * STps = &(STp->ps[STp->partition]);
3026  int result = 0;
3027 
3028  if (STp->write_type != OS_WRITE_NEW_MARK) {
3029  /* true unless the user wrote the filemark for us */
3030  result = osst_flush_drive_buffer(STp, aSRpnt);
3031  if (result < 0) goto out;
3032  result = osst_write_filemark(STp, aSRpnt);
3033  if (result < 0) goto out;
3034 
3035  if (STps->drv_file >= 0)
3036  STps->drv_file++ ;
3037  STps->drv_block = 0;
3038  }
3039  result = osst_write_eod(STp, aSRpnt);
3040  osst_write_header(STp, aSRpnt, leave_at_EOT);
3041 
3042  STps->eof = ST_FM;
3043 out:
3044  return result;
3045 }
3046 
3047 /* osst versions of st functions - augmented and stripped to suit OnStream only */
3048 
3049 /* Flush the write buffer (never need to write if variable blocksize). */
3050 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
3051 {
3052  int offset, transfer, blks = 0;
3053  int result = 0;
3054  unsigned char cmd[MAX_COMMAND_SIZE];
3055  struct osst_request * SRpnt = *aSRpnt;
3056  struct st_partstat * STps;
3057  char * name = tape_name(STp);
3058 
3059  if ((STp->buffer)->writing) {
3060  if (SRpnt == (STp->buffer)->last_SRpnt)
3061 #if DEBUG
3063  "%s:D: aSRpnt points to osst_request that write_behind_check will release -- cleared\n", name);
3064 #endif
3065  *aSRpnt = SRpnt = NULL;
3066 #if DEBUG
3067  } else if (SRpnt)
3069  "%s:D: aSRpnt does not point to osst_request that write_behind_check will release -- strange\n", name);
3070 #endif
3071  osst_write_behind_check(STp);
3072  if ((STp->buffer)->syscall_result) {
3073 #if DEBUG
3074  if (debugging)
3075  printk(OSST_DEB_MSG "%s:D: Async write error (flush) %x.\n",
3076  name, (STp->buffer)->midlevel_result);
3077 #endif
3078  if ((STp->buffer)->midlevel_result == INT_MAX)
3079  return (-ENOSPC);
3080  return (-EIO);
3081  }
3082  }
3083 
3084  result = 0;
3085  if (STp->dirty == 1) {
3086 
3087  STp->write_count++;
3088  STps = &(STp->ps[STp->partition]);
3089  STps->rw = ST_WRITING;
3090  offset = STp->buffer->buffer_bytes;
3091  blks = (offset + STp->block_size - 1) / STp->block_size;
3092  transfer = OS_FRAME_SIZE;
3093 
3094  if (offset < OS_DATA_SIZE)
3095  osst_zero_buffer_tail(STp->buffer);
3096 
3097  if (STp->poll)
3098  if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
3099  result = osst_recover_wait_frame(STp, aSRpnt, 1);
3100 
3101  memset(cmd, 0, MAX_COMMAND_SIZE);
3102  cmd[0] = WRITE_6;
3103  cmd[1] = 1;
3104  cmd[4] = 1;
3105 
3106  switch (STp->write_type) {
3107  case OS_WRITE_DATA:
3108 #if DEBUG
3109  if (debugging)
3110  printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n",
3111  name, blks, STp->frame_seq_number,
3112  STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3113 #endif
3114  osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3115  STp->logical_blk_num - blks, STp->block_size, blks);
3116  break;
3117  case OS_WRITE_EOD:
3118  osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
3119  STp->logical_blk_num, 0, 0);
3120  break;
3121  case OS_WRITE_NEW_MARK:
3122  osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
3123  STp->logical_blk_num++, 0, blks=1);
3124  break;
3125  case OS_WRITE_HEADER:
3126  osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
3127  break;
3128  default: /* probably FILLER */
3129  osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
3130  }
3131 #if DEBUG
3132  if (debugging)
3133  printk(OSST_DEB_MSG "%s:D: Flushing %d bytes, Transferring %d bytes in %d lblocks.\n",
3134  name, offset, transfer, blks);
3135 #endif
3136 
3137  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
3138  STp->timeout, MAX_RETRIES, 1);
3139  *aSRpnt = SRpnt;
3140  if (!SRpnt)
3141  return (-EBUSY);
3142 
3143  if ((STp->buffer)->syscall_result != 0) {
3144 #if DEBUG
3146  "%s:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02x\n",
3147  name, SRpnt->sense[0], SRpnt->sense[2],
3148  SRpnt->sense[12], SRpnt->sense[13]);
3149 #endif
3150  if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3151  (SRpnt->sense[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
3152  (SRpnt->sense[2] & 0x0f) == NO_SENSE) {
3153  STp->dirty = 0;
3154  (STp->buffer)->buffer_bytes = 0;
3155  result = (-ENOSPC);
3156  }
3157  else {
3158  if (osst_write_error_recovery(STp, aSRpnt, 1)) {
3159  printk(KERN_ERR "%s:E: Error on flush write.\n", name);
3160  result = (-EIO);
3161  }
3162  }
3163  STps->drv_block = (-1); /* FIXME - even if write recovery succeeds? */
3164  }
3165  else {
3166  STp->first_frame_position++;
3167  STp->dirty = 0;
3168  (STp->buffer)->buffer_bytes = 0;
3169  }
3170  }
3171 #if DEBUG
3172  printk(OSST_DEB_MSG "%s:D: Exit flush write buffer with code %d\n", name, result);
3173 #endif
3174  return result;
3175 }
3176 
3177 
3178 /* Flush the tape buffer. The tape will be positioned correctly unless
3179  seek_next is true. */
3180 static int osst_flush_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt, int seek_next)
3181 {
3182  struct st_partstat * STps;
3183  int backspace = 0, result = 0;
3184 #if DEBUG
3185  char * name = tape_name(STp);
3186 #endif
3187 
3188  /*
3189  * If there was a bus reset, block further access
3190  * to this device.
3191  */
3192  if( STp->pos_unknown)
3193  return (-EIO);
3194 
3195  if (STp->ready != ST_READY)
3196  return 0;
3197 
3198  STps = &(STp->ps[STp->partition]);
3199  if (STps->rw == ST_WRITING || STp->dirty) { /* Writing */
3200  STp->write_type = OS_WRITE_DATA;
3201  return osst_flush_write_buffer(STp, aSRpnt);
3202  }
3203  if (STp->block_size == 0)
3204  return 0;
3205 
3206 #if DEBUG
3207  printk(OSST_DEB_MSG "%s:D: Reached flush (read) buffer\n", name);
3208 #endif
3209 
3210  if (!STp->can_bsr) {
3211  backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
3212  ((STp->buffer)->read_pointer + STp->block_size - 1 ) / STp->block_size ;
3213  (STp->buffer)->buffer_bytes = 0;
3214  (STp->buffer)->read_pointer = 0;
3215  STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
3216  }
3217 
3218  if (!seek_next) {
3219  if (STps->eof == ST_FM_HIT) {
3220  result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */
3221  if (!result)
3222  STps->eof = ST_NOEOF;
3223  else {
3224  if (STps->drv_file >= 0)
3225  STps->drv_file++;
3226  STps->drv_block = 0;
3227  }
3228  }
3229  if (!result && backspace > 0) /* TODO -- design and run a test case for this */
3230  result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
3231  }
3232  else if (STps->eof == ST_FM_HIT) {
3233  if (STps->drv_file >= 0)
3234  STps->drv_file++;
3235  STps->drv_block = 0;
3236  STps->eof = ST_NOEOF;
3237  }
3238 
3239  return result;
3240 }
3241 
3242 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
3243 {
3244  unsigned char cmd[MAX_COMMAND_SIZE];
3245  struct osst_request * SRpnt;
3246  int blks;
3247 #if DEBUG
3248  char * name = tape_name(STp);
3249 #endif
3250 
3251  if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
3252 #if DEBUG
3253  printk(OSST_DEB_MSG "%s:D: Reaching config partition.\n", name);
3254 #endif
3255  if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
3256  return (-EIO);
3257  }
3258  /* error recovery may have bumped us past the header partition */
3259  if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
3260 #if DEBUG
3261  printk(OSST_DEB_MSG "%s:D: Skipping over config partition.\n", name);
3262 #endif
3263  osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
3264  }
3265  }
3266 
3267  if (STp->poll)
3268  if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
3269  if (osst_recover_wait_frame(STp, aSRpnt, 1))
3270  return (-EIO);
3271 
3272 // osst_build_stats(STp, &SRpnt);
3273 
3274  STp->ps[STp->partition].rw = ST_WRITING;
3275  STp->write_type = OS_WRITE_DATA;
3276 
3277  memset(cmd, 0, MAX_COMMAND_SIZE);
3278  cmd[0] = WRITE_6;
3279  cmd[1] = 1;
3280  cmd[4] = 1; /* one frame at a time... */
3281  blks = STp->buffer->buffer_bytes / STp->block_size;
3282 #if DEBUG
3283  if (debugging)
3284  printk(OSST_DEB_MSG "%s:D: Writing %d blocks to frame %d, lblks %d-%d\n", name, blks,
3285  STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
3286 #endif
3287  osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
3288  STp->logical_blk_num - blks, STp->block_size, blks);
3289 
3290 #if DEBUG
3291  if (!synchronous)
3292  STp->write_pending = 1;
3293 #endif
3294  SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
3295  MAX_RETRIES, synchronous);
3296  if (!SRpnt)
3297  return (-EBUSY);
3298  *aSRpnt = SRpnt;
3299 
3300  if (synchronous) {
3301  if (STp->buffer->syscall_result != 0) {
3302 #if DEBUG
3303  if (debugging)
3304  printk(OSST_DEB_MSG "%s:D: Error on write:\n", name);
3305 #endif
3306  if ((SRpnt->sense[0] & 0x70) == 0x70 &&
3307  (SRpnt->sense[2] & 0x40)) {
3308  if ((SRpnt->sense[2] & 0x0f) == VOLUME_OVERFLOW)
3309  return (-ENOSPC);
3310  }
3311  else {
3312  if (osst_write_error_recovery(STp, aSRpnt, 1))
3313  return (-EIO);
3314  }
3315  }
3316  else
3317  STp->first_frame_position++;
3318  }
3319 
3320  STp->write_count++;
3321 
3322  return 0;
3323 }
3324 
3325 /* Lock or unlock the drive door. Don't use when struct osst_request allocated. */
3326 static int do_door_lock(struct osst_tape * STp, int do_lock)
3327 {
3328  int retval, cmd;
3329 
3330  cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
3331 #if DEBUG
3332  printk(OSST_DEB_MSG "%s:D: %socking drive door.\n", tape_name(STp), do_lock ? "L" : "Unl");
3333 #endif
3334  retval = scsi_ioctl(STp->device, cmd, NULL);
3335  if (!retval) {
3336  STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
3337  }
3338  else {
3339  STp->door_locked = ST_LOCK_FAILS;
3340  }
3341  return retval;
3342 }
3343 
3344 /* Set the internal state after reset */
3345 static void reset_state(struct osst_tape *STp)
3346 {
3347  int i;
3348  struct st_partstat *STps;
3349 
3350  STp->pos_unknown = 0;
3351  for (i = 0; i < ST_NBR_PARTITIONS; i++) {
3352  STps = &(STp->ps[i]);
3353  STps->rw = ST_IDLE;
3354  STps->eof = ST_NOEOF;
3355  STps->at_sm = 0;
3356  STps->last_block_valid = 0;
3357  STps->drv_block = -1;
3358  STps->drv_file = -1;
3359  }
3360 }
3361 
3362 
3363 /* Entry points to osst */
3364 
3365 /* Write command */
3366 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
3367 {
3368  ssize_t total, retval = 0;
3369  ssize_t i, do_count, blks, transfer;
3370  int write_threshold;
3371  int doing_write = 0;
3372  const char __user * b_point;
3373  struct osst_request * SRpnt = NULL;
3374  struct st_modedef * STm;
3375  struct st_partstat * STps;
3376  struct osst_tape * STp = filp->private_data;
3377  char * name = tape_name(STp);
3378 
3379 
3380  if (mutex_lock_interruptible(&STp->lock))
3381  return (-ERESTARTSYS);
3382 
3383  /*
3384  * If we are in the middle of error recovery, don't let anyone
3385  * else try and use this device. Also, if error recovery fails, it
3386  * may try and take the device offline, in which case all further
3387  * access to the device is prohibited.
3388  */
3390  retval = (-ENXIO);
3391  goto out;
3392  }
3393 
3394  if (STp->ready != ST_READY) {
3395  if (STp->ready == ST_NO_TAPE)
3396  retval = (-ENOMEDIUM);
3397  else
3398  retval = (-EIO);
3399  goto out;
3400  }
3401  STm = &(STp->modes[STp->current_mode]);
3402  if (!STm->defined) {
3403  retval = (-ENXIO);
3404  goto out;
3405  }
3406  if (count == 0)
3407  goto out;
3408 
3409  /*
3410  * If there was a bus reset, block further access
3411  * to this device.
3412  */
3413  if (STp->pos_unknown) {
3414  retval = (-EIO);
3415  goto out;
3416  }
3417 
3418 #if DEBUG
3419  if (!STp->in_use) {
3420  printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3421  retval = (-EIO);
3422  goto out;
3423  }
3424 #endif
3425 
3426  if (STp->write_prot) {
3427  retval = (-EACCES);
3428  goto out;
3429  }
3430 
3431  /* Write must be integral number of blocks */
3432  if (STp->block_size != 0 && (count % STp->block_size) != 0) {
3433  printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n",
3434  name, count, STp->block_size<1024?
3435  STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3436  retval = (-EINVAL);
3437  goto out;
3438  }
3439 
3440  if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
3441  printk(KERN_ERR "%s:E: Write truncated at EOM early warning (frame %d).\n",
3442  name, STp->first_frame_position);
3443  retval = (-ENOSPC);
3444  goto out;
3445  }
3446 
3447  if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3448  STp->door_locked = ST_LOCKED_AUTO;
3449 
3450  STps = &(STp->ps[STp->partition]);
3451 
3452  if (STps->rw == ST_READING) {
3453 #if DEBUG
3454  printk(OSST_DEB_MSG "%s:D: Switching from read to write at file %d, block %d\n", name,
3455  STps->drv_file, STps->drv_block);
3456 #endif
3457  retval = osst_flush_buffer(STp, &SRpnt, 0);
3458  if (retval)
3459  goto out;
3460  STps->rw = ST_IDLE;
3461  }
3462  if (STps->rw != ST_WRITING) {
3463  /* Are we totally rewriting this tape? */
3464  if (!STp->header_ok ||
3465  (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
3466  (STps->drv_file == 0 && STps->drv_block == 0)) {
3467  STp->wrt_pass_cntr++;
3468 #if DEBUG
3469  printk(OSST_DEB_MSG "%s:D: Allocating next write pass counter: %d\n",
3470  name, STp->wrt_pass_cntr);
3471 #endif
3472  osst_reset_header(STp, &SRpnt);
3473  STps->drv_file = STps->drv_block = 0;
3474  }
3475  /* Do we know where we'll be writing on the tape? */
3476  else {
3477  if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
3478  STps->drv_file < 0 || STps->drv_block < 0) {
3479  if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
3480  STps->drv_file = STp->filemark_cnt;
3481  STps->drv_block = 0;
3482  }
3483  else {
3484  /* We have no idea where the tape is positioned - give up */
3485 #if DEBUG
3487  "%s:D: Cannot write at indeterminate position.\n", name);
3488 #endif
3489  retval = (-EIO);
3490  goto out;
3491  }
3492  }
3493  if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
3494  STp->filemark_cnt = STps->drv_file;
3495  STp->last_mark_ppos =
3498  "%s:W: Overwriting file %d with old write pass counter %d\n",
3499  name, STps->drv_file, STp->wrt_pass_cntr);
3501  "%s:W: may lead to stale data being accepted on reading back!\n",
3502  name);
3503 #if DEBUG
3505  "%s:D: resetting filemark count to %d and last mark ppos,lbn to %d,%d\n",
3506  name, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
3507 #endif
3508  }
3509  }
3510  STp->fast_open = 0;
3511  }
3512  if (!STp->header_ok) {
3513 #if DEBUG
3514  printk(OSST_DEB_MSG "%s:D: Write cannot proceed without valid headers\n", name);
3515 #endif
3516  retval = (-EIO);
3517  goto out;
3518  }
3519 
3520  if ((STp->buffer)->writing) {
3521 if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name, __LINE__);
3522  osst_write_behind_check(STp);
3523  if ((STp->buffer)->syscall_result) {
3524 #if DEBUG
3525  if (debugging)
3526  printk(OSST_DEB_MSG "%s:D: Async write error (write) %x.\n", name,
3527  (STp->buffer)->midlevel_result);
3528 #endif
3529  if ((STp->buffer)->midlevel_result == INT_MAX)
3530  STps->eof = ST_EOM_OK;
3531  else
3532  STps->eof = ST_EOM_ERROR;
3533  }
3534  }
3535  if (STps->eof == ST_EOM_OK) {
3536  retval = (-ENOSPC);
3537  goto out;
3538  }
3539  else if (STps->eof == ST_EOM_ERROR) {
3540  retval = (-EIO);
3541  goto out;
3542  }
3543 
3544  /* Check the buffer readability in cases where copy_user might catch
3545  the problems after some tape movement. */
3546  if ((copy_from_user(&i, buf, 1) != 0 ||
3547  copy_from_user(&i, buf + count - 1, 1) != 0)) {
3548  retval = (-EFAULT);
3549  goto out;
3550  }
3551 
3552  if (!STm->do_buffer_writes) {
3553  write_threshold = 1;
3554  }
3555  else
3556  write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
3557  if (!STm->do_async_writes)
3558  write_threshold--;
3559 
3560  total = count;
3561 #if DEBUG
3562  if (debugging)
3563  printk(OSST_DEB_MSG "%s:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %d\n",
3564  name, (int) count, STps->drv_file, STps->drv_block,
3566 #endif
3567  b_point = buf;
3568  while ((STp->buffer)->buffer_bytes + count > write_threshold)
3569  {
3570  doing_write = 1;
3571  do_count = (STp->buffer)->buffer_blocks * STp->block_size -
3572  (STp->buffer)->buffer_bytes;
3573  if (do_count > count)
3574  do_count = count;
3575 
3576  i = append_to_buffer(b_point, STp->buffer, do_count);
3577  if (i) {
3578  retval = i;
3579  goto out;
3580  }
3581 
3582  blks = do_count / STp->block_size;
3583  STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */
3584 
3585  i = osst_write_frame(STp, &SRpnt, 1);
3586 
3587  if (i == (-ENOSPC)) {
3588  transfer = STp->buffer->writing; /* FIXME -- check this logic */
3589  if (transfer <= do_count) {
3590  *ppos += do_count - transfer;
3591  count -= do_count - transfer;
3592  if (STps->drv_block >= 0) {
3593  STps->drv_block += (do_count - transfer) / STp->block_size;
3594  }
3595  STps->eof = ST_EOM_OK;
3596  retval = (-ENOSPC); /* EOM within current request */
3597 #if DEBUG
3598  if (debugging)
3599  printk(OSST_DEB_MSG "%s:D: EOM with %d bytes unwritten.\n",
3600  name, (int) transfer);
3601 #endif
3602  }
3603  else {
3604  STps->eof = ST_EOM_ERROR;
3605  STps->drv_block = (-1); /* Too cautious? */
3606  retval = (-EIO); /* EOM for old data */
3607 #if DEBUG
3608  if (debugging)
3609  printk(OSST_DEB_MSG "%s:D: EOM with lost data.\n", name);
3610 #endif
3611  }
3612  }
3613  else
3614  retval = i;
3615 
3616  if (retval < 0) {
3617  if (SRpnt != NULL) {
3618  osst_release_request(SRpnt);
3619  SRpnt = NULL;
3620  }
3621  STp->buffer->buffer_bytes = 0;
3622  STp->dirty = 0;
3623  if (count < total)
3624  retval = total - count;
3625  goto out;
3626  }
3627 
3628  *ppos += do_count;
3629  b_point += do_count;
3630  count -= do_count;
3631  if (STps->drv_block >= 0) {
3632  STps->drv_block += blks;
3633  }
3634  STp->buffer->buffer_bytes = 0;
3635  STp->dirty = 0;
3636  } /* end while write threshold exceeded */
3637 
3638  if (count != 0) {
3639  STp->dirty = 1;
3640  i = append_to_buffer(b_point, STp->buffer, count);
3641  if (i) {
3642  retval = i;
3643  goto out;
3644  }
3645  blks = count / STp->block_size;
3646  STp->logical_blk_num += blks;
3647  if (STps->drv_block >= 0) {
3648  STps->drv_block += blks;
3649  }
3650  *ppos += count;
3651  count = 0;
3652  }
3653 
3654  if (doing_write && (STp->buffer)->syscall_result != 0) {
3655  retval = (STp->buffer)->syscall_result;
3656  goto out;
3657  }
3658 
3659  if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) {
3660  /* Schedule an asynchronous write */
3661  (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
3662  STp->block_size) * STp->block_size;
3663  STp->dirty = !((STp->buffer)->writing ==
3664  (STp->buffer)->buffer_bytes);
3665 
3666  i = osst_write_frame(STp, &SRpnt, 0);
3667  if (i < 0) {
3668  retval = (-EIO);
3669  goto out;
3670  }
3671  SRpnt = NULL; /* Prevent releasing this request! */
3672  }
3673  STps->at_sm &= (total == 0);
3674  if (total > 0)
3675  STps->eof = ST_NOEOF;
3676 
3677  retval = total;
3678 
3679 out:
3680  if (SRpnt != NULL) osst_release_request(SRpnt);
3681 
3682  mutex_unlock(&STp->lock);
3683 
3684  return retval;
3685 }
3686 
3687 
3688 /* Read command */
3689 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
3690 {
3691  ssize_t total, retval = 0;
3692  ssize_t i, transfer;
3693  int special;
3694  struct st_modedef * STm;
3695  struct st_partstat * STps;
3696  struct osst_request * SRpnt = NULL;
3697  struct osst_tape * STp = filp->private_data;
3698  char * name = tape_name(STp);
3699 
3700 
3701  if (mutex_lock_interruptible(&STp->lock))
3702  return (-ERESTARTSYS);
3703 
3704  /*
3705  * If we are in the middle of error recovery, don't let anyone
3706  * else try and use this device. Also, if error recovery fails, it
3707  * may try and take the device offline, in which case all further
3708  * access to the device is prohibited.
3709  */
3711  retval = (-ENXIO);
3712  goto out;
3713  }
3714 
3715  if (STp->ready != ST_READY) {
3716  if (STp->ready == ST_NO_TAPE)
3717  retval = (-ENOMEDIUM);
3718  else
3719  retval = (-EIO);
3720  goto out;
3721  }
3722  STm = &(STp->modes[STp->current_mode]);
3723  if (!STm->defined) {
3724  retval = (-ENXIO);
3725  goto out;
3726  }
3727 #if DEBUG
3728  if (!STp->in_use) {
3729  printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
3730  retval = (-EIO);
3731  goto out;
3732  }
3733 #endif
3734  /* Must have initialized medium */
3735  if (!STp->header_ok) {
3736  retval = (-EIO);
3737  goto out;
3738  }
3739 
3740  if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED && !do_door_lock(STp, 1))
3741  STp->door_locked = ST_LOCKED_AUTO;
3742 
3743  STps = &(STp->ps[STp->partition]);
3744  if (STps->rw == ST_WRITING) {
3745  retval = osst_flush_buffer(STp, &SRpnt, 0);
3746  if (retval)
3747  goto out;
3748  STps->rw = ST_IDLE;
3749  /* FIXME -- this may leave the tape without EOD and up2date headers */
3750  }
3751 
3752  if ((count % STp->block_size) != 0) {
3754  "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count,
3755  STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
3756  }
3757 
3758 #if DEBUG
3759  if (debugging && STps->eof != ST_NOEOF)
3760  printk(OSST_DEB_MSG "%s:D: EOF/EOM flag up (%d). Bytes %d\n", name,
3761  STps->eof, (STp->buffer)->buffer_bytes);
3762 #endif
3763  if ((STp->buffer)->buffer_bytes == 0 &&
3764  STps->eof >= ST_EOD_1) {
3765  if (STps->eof < ST_EOD) {
3766  STps->eof += 1;
3767  retval = 0;
3768  goto out;
3769  }
3770  retval = (-EIO); /* EOM or Blank Check */
3771  goto out;
3772  }
3773 
3774  /* Check the buffer writability before any tape movement. Don't alter
3775  buffer data. */
3776  if (copy_from_user(&i, buf, 1) != 0 ||
3777  copy_to_user (buf, &i, 1) != 0 ||
3778  copy_from_user(&i, buf + count - 1, 1) != 0 ||
3779  copy_to_user (buf + count - 1, &i, 1) != 0) {
3780  retval = (-EFAULT);
3781  goto out;
3782  }
3783 
3784  /* Loop until enough data in buffer or a special condition found */
3785  for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
3786 
3787  /* Get new data if the buffer is empty */
3788  if ((STp->buffer)->buffer_bytes == 0) {
3789  if (STps->eof == ST_FM_HIT)
3790  break;
3791  special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
3792  if (special < 0) { /* No need to continue read */
3793  STp->frame_in_buffer = 0;
3794  retval = special;
3795  goto out;
3796  }
3797  }
3798 
3799  /* Move the data from driver buffer to user buffer */
3800  if ((STp->buffer)->buffer_bytes > 0) {
3801 #if DEBUG
3802  if (debugging && STps->eof != ST_NOEOF)
3803  printk(OSST_DEB_MSG "%s:D: EOF up (%d). Left %d, needed %d.\n", name,
3804  STps->eof, (STp->buffer)->buffer_bytes, (int) (count - total));
3805 #endif
3806  /* force multiple of block size, note block_size may have been adjusted */
3807  transfer = (((STp->buffer)->buffer_bytes < count - total ?
3808  (STp->buffer)->buffer_bytes : count - total)/
3809  STp->block_size) * STp->block_size;
3810 
3811  if (transfer == 0) {
3813  "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n",
3814  name, count, STp->block_size < 1024?
3815  STp->block_size:STp->block_size/1024,
3816  STp->block_size<1024?'b':'k');
3817  break;
3818  }
3819  i = from_buffer(STp->buffer, buf, transfer);
3820  if (i) {
3821  retval = i;
3822  goto out;
3823  }
3824  STp->logical_blk_num += transfer / STp->block_size;
3825  STps->drv_block += transfer / STp->block_size;
3826  *ppos += transfer;
3827  buf += transfer;
3828  total += transfer;
3829  }
3830 
3831  if ((STp->buffer)->buffer_bytes == 0) {
3832 #if DEBUG
3833  if (debugging)
3834  printk(OSST_DEB_MSG "%s:D: Finished with frame %d\n",
3835  name, STp->frame_seq_number);
3836 #endif
3837  STp->frame_in_buffer = 0;
3838  STp->frame_seq_number++; /* frame to look for next time */
3839  }
3840  } /* for (total = 0, special = 0; total < count && !special; ) */
3841 
3842  /* Change the eof state if no data from tape or buffer */
3843  if (total == 0) {
3844  if (STps->eof == ST_FM_HIT) {
3845  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD_2:ST_FM;
3846  STps->drv_block = 0;
3847  if (STps->drv_file >= 0)
3848  STps->drv_file++;
3849  }
3850  else if (STps->eof == ST_EOD_1) {
3851  STps->eof = ST_EOD_2;
3852  if (STps->drv_block > 0 && STps->drv_file >= 0)
3853  STps->drv_file++;
3854  STps->drv_block = 0;
3855  }
3856  else if (STps->eof == ST_EOD_2)
3857  STps->eof = ST_EOD;
3858  }
3859  else if (STps->eof == ST_FM)
3860  STps->eof = ST_NOEOF;
3861 
3862  retval = total;
3863 
3864 out:
3865  if (SRpnt != NULL) osst_release_request(SRpnt);
3866 
3867  mutex_unlock(&STp->lock);
3868 
3869  return retval;
3870 }
3871 
3872 
3873 /* Set the driver options */
3874 static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
3875 {
3877 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
3878  name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
3879  STm->do_read_ahead);
3881 "%s:I: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
3882  name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
3884 "%s:I: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
3885  name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
3886  STp->scsi2_logical);
3888 "%s:I: sysv: %d\n", name, STm->sysv);
3889 #if DEBUG
3891  "%s:D: debugging: %d\n",
3892  name, debugging);
3893 #endif
3894 }
3895 
3896 
3897 static int osst_set_options(struct osst_tape *STp, long options)
3898 {
3899  int value;
3900  long code;
3901  struct st_modedef * STm;
3902  char * name = tape_name(STp);
3903 
3904  STm = &(STp->modes[STp->current_mode]);
3905  if (!STm->defined) {
3906  memcpy(STm, &(STp->modes[0]), sizeof(*STm));
3907  modes_defined = 1;
3908 #if DEBUG
3909  if (debugging)
3910  printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n",
3911  name, STp->current_mode);
3912 #endif
3913  }
3914 
3915  code = options & MT_ST_OPTIONS;
3916  if (code == MT_ST_BOOLEANS) {
3917  STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
3918  STm->do_async_writes = (options & MT_ST_ASYNC_WRITES) != 0;
3919  STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
3920  STm->do_read_ahead = (options & MT_ST_READ_AHEAD) != 0;
3921  STp->two_fm = (options & MT_ST_TWO_FM) != 0;
3922  STp->fast_mteom = (options & MT_ST_FAST_MTEOM) != 0;
3923  STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0;
3924  STp->can_bsr = (options & MT_ST_CAN_BSR) != 0;
3925  STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0;
3926  if ((STp->device)->scsi_level >= SCSI_2)
3927  STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
3928  STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0;
3929  STm->sysv = (options & MT_ST_SYSV) != 0;
3930 #if DEBUG
3931  debugging = (options & MT_ST_DEBUGGING) != 0;
3932 #endif
3933  osst_log_options(STp, STm, name);
3934  }
3935  else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
3936  value = (code == MT_ST_SETBOOLEANS);
3937  if ((options & MT_ST_BUFFER_WRITES) != 0)
3938  STm->do_buffer_writes = value;
3939  if ((options & MT_ST_ASYNC_WRITES) != 0)
3940  STm->do_async_writes = value;
3941  if ((options & MT_ST_DEF_WRITES) != 0)
3942  STm->defaults_for_writes = value;
3943  if ((options & MT_ST_READ_AHEAD) != 0)
3944  STm->do_read_ahead = value;
3945  if ((options & MT_ST_TWO_FM) != 0)
3946  STp->two_fm = value;
3947  if ((options & MT_ST_FAST_MTEOM) != 0)
3948  STp->fast_mteom = value;
3949  if ((options & MT_ST_AUTO_LOCK) != 0)
3950  STp->do_auto_lock = value;
3951  if ((options & MT_ST_CAN_BSR) != 0)
3952  STp->can_bsr = value;
3953  if ((options & MT_ST_NO_BLKLIMS) != 0)
3954  STp->omit_blklims = value;
3955  if ((STp->device)->scsi_level >= SCSI_2 &&
3956  (options & MT_ST_CAN_PARTITIONS) != 0)
3957  STp->can_partitions = value;
3958  if ((options & MT_ST_SCSI2LOGICAL) != 0)
3959  STp->scsi2_logical = value;
3960  if ((options & MT_ST_SYSV) != 0)
3961  STm->sysv = value;
3962 #if DEBUG
3963  if ((options & MT_ST_DEBUGGING) != 0)
3964  debugging = value;
3965 #endif
3966  osst_log_options(STp, STm, name);
3967  }
3968  else if (code == MT_ST_WRITE_THRESHOLD) {
3969  value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
3970  if (value < 1 || value > osst_buffer_size) {
3971  printk(KERN_WARNING "%s:W: Write threshold %d too small or too large.\n",
3972  name, value);
3973  return (-EIO);
3974  }
3975  STp->write_threshold = value;
3976  printk(KERN_INFO "%s:I: Write threshold set to %d bytes.\n",
3977  name, value);
3978  }
3979  else if (code == MT_ST_DEF_BLKSIZE) {
3980  value = (options & ~MT_ST_OPTIONS);
3981  if (value == ~MT_ST_OPTIONS) {
3982  STm->default_blksize = (-1);
3983  printk(KERN_INFO "%s:I: Default block size disabled.\n", name);
3984  }
3985  else {
3986  if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
3987  printk(KERN_WARNING "%s:W: Default block size cannot be set to %d.\n",
3988  name, value);
3989  return (-EINVAL);
3990  }
3991  STm->default_blksize = value;
3992  printk(KERN_INFO "%s:I: Default block size set to %d bytes.\n",
3993  name, STm->default_blksize);
3994  }
3995  }
3996  else if (code == MT_ST_TIMEOUTS) {
3997  value = (options & ~MT_ST_OPTIONS);
3998  if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
3999  STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
4000  printk(KERN_INFO "%s:I: Long timeout set to %d seconds.\n", name,
4001  (value & ~MT_ST_SET_LONG_TIMEOUT));
4002  }
4003  else {
4004  STp->timeout = value * HZ;
4005  printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
4006  }
4007  }
4008  else if (code == MT_ST_DEF_OPTIONS) {
4009  code = (options & ~MT_ST_CLEAR_DEFAULT);
4010  value = (options & MT_ST_CLEAR_DEFAULT);
4011  if (code == MT_ST_DEF_DENSITY) {
4012  if (value == MT_ST_CLEAR_DEFAULT) {
4013  STm->default_density = (-1);
4014  printk(KERN_INFO "%s:I: Density default disabled.\n", name);
4015  }
4016  else {
4017  STm->default_density = value & 0xff;
4018  printk(KERN_INFO "%s:I: Density default set to %x\n",
4019  name, STm->default_density);
4020  }
4021  }
4022  else if (code == MT_ST_DEF_DRVBUFFER) {
4023  if (value == MT_ST_CLEAR_DEFAULT) {
4024  STp->default_drvbuffer = 0xff;
4025  printk(KERN_INFO "%s:I: Drive buffer default disabled.\n", name);
4026  }
4027  else {
4028  STp->default_drvbuffer = value & 7;
4029  printk(KERN_INFO "%s:I: Drive buffer default set to %x\n",
4030  name, STp->default_drvbuffer);
4031  }
4032  }
4033  else if (code == MT_ST_DEF_COMPRESSION) {
4034  if (value == MT_ST_CLEAR_DEFAULT) {
4036  printk(KERN_INFO "%s:I: Compression default disabled.\n", name);
4037  }
4038  else {
4039  STm->default_compression = (value & 1 ? ST_YES : ST_NO);
4040  printk(KERN_INFO "%s:I: Compression default set to %x\n",
4041  name, (value & 1));
4042  }
4043  }
4044  }
4045  else
4046  return (-EIO);
4047 
4048  return 0;
4049 }
4050 
4051 
4052 /* Internal ioctl function */
4053 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
4054  unsigned int cmd_in, unsigned long arg)
4055 {
4056  int timeout;
4057  long ltmp;
4058  int i, ioctl_result;
4059  int chg_eof = 1;
4060  unsigned char cmd[MAX_COMMAND_SIZE];
4061  struct osst_request * SRpnt = * aSRpnt;
4062  struct st_partstat * STps;
4063  int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
4064  int datalen = 0, direction = DMA_NONE;
4065  char * name = tape_name(STp);
4066 
4067  if (STp->ready != ST_READY && cmd_in != MTLOAD) {
4068  if (STp->ready == ST_NO_TAPE)
4069  return (-ENOMEDIUM);
4070  else
4071  return (-EIO);
4072  }
4073  timeout = STp->long_timeout;
4074  STps = &(STp->ps[STp->partition]);
4075  fileno = STps->drv_file;
4076  blkno = STps->drv_block;
4077  at_sm = STps->at_sm;
4078  frame_seq_numbr = STp->frame_seq_number;
4079  logical_blk_num = STp->logical_blk_num;
4080 
4081  memset(cmd, 0, MAX_COMMAND_SIZE);
4082  switch (cmd_in) {
4083  case MTFSFM:
4084  chg_eof = 0; /* Changed from the FSF after this */
4085  case MTFSF:
4086  if (STp->raw)
4087  return (-EIO);
4088  if (STp->linux_media)
4089  ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
4090  else
4091  ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
4092  if (fileno >= 0)
4093  fileno += arg;
4094  blkno = 0;
4095  at_sm &= (arg == 0);
4096  goto os_bypass;
4097 
4098  case MTBSF:
4099  chg_eof = 0; /* Changed from the FSF after this */
4100  case MTBSFM:
4101  if (STp->raw)
4102  return (-EIO);
4103  ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
4104  if (fileno >= 0)
4105  fileno -= arg;
4106  blkno = (-1); /* We can't know the block number */
4107  at_sm &= (arg == 0);
4108  goto os_bypass;
4109 
4110  case MTFSR:
4111  case MTBSR:
4112 #if DEBUG
4113  if (debugging)
4114  printk(OSST_DEB_MSG "%s:D: Skipping %lu blocks %s from logical block %d\n",
4115  name, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
4116 #endif
4117  if (cmd_in == MTFSR) {
4118  logical_blk_num += arg;
4119  if (blkno >= 0) blkno += arg;
4120  }
4121  else {
4122  logical_blk_num -= arg;
4123  if (blkno >= 0) blkno -= arg;
4124  }
4125  ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
4126  fileno = STps->drv_file;
4127  blkno = STps->drv_block;
4128  at_sm &= (arg == 0);
4129  goto os_bypass;
4130 
4131  case MTFSS:
4132  cmd[0] = SPACE;
4133  cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4134  cmd[2] = (arg >> 16);
4135  cmd[3] = (arg >> 8);
4136  cmd[4] = arg;
4137 #if DEBUG
4138  if (debugging)
4139  printk(OSST_DEB_MSG "%s:D: Spacing tape forward %d setmarks.\n", name,
4140  cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4141 #endif
4142  if (arg != 0) {
4143  blkno = fileno = (-1);
4144  at_sm = 1;
4145  }
4146  break;
4147  case MTBSS:
4148  cmd[0] = SPACE;
4149  cmd[1] = 0x04; /* Space Setmarks */ /* FIXME -- OS can't do this? */
4150  ltmp = (-arg);
4151  cmd[2] = (ltmp >> 16);
4152  cmd[3] = (ltmp >> 8);
4153  cmd[4] = ltmp;
4154 #if DEBUG
4155  if (debugging) {
4156  if (cmd[2] & 0x80)
4157  ltmp = 0xff000000;
4158  ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
4159  printk(OSST_DEB_MSG "%s:D: Spacing tape backward %ld setmarks.\n",
4160  name, (-ltmp));
4161  }
4162 #endif
4163  if (arg != 0) {
4164  blkno = fileno = (-1);
4165  at_sm = 1;
4166  }
4167  break;
4168  case MTWEOF:
4169  if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4170  STp->write_type = OS_WRITE_DATA;
4171  ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
4172  } else
4173  ioctl_result = 0;
4174 #if DEBUG
4175  if (debugging)
4176  printk(OSST_DEB_MSG "%s:D: Writing %ld filemark(s).\n", name, arg);
4177 #endif
4178  for (i=0; i<arg; i++)
4179  ioctl_result |= osst_write_filemark(STp, &SRpnt);
4180  if (fileno >= 0) fileno += arg;
4181  if (blkno >= 0) blkno = 0;
4182  goto os_bypass;
4183 
4184  case MTWSM:
4185  if (STp->write_prot)
4186  return (-EACCES);
4187  if (!STp->raw)
4188  return 0;
4189  cmd[0] = WRITE_FILEMARKS; /* FIXME -- need OS version */
4190  if (cmd_in == MTWSM)
4191  cmd[1] = 2;
4192  cmd[2] = (arg >> 16);
4193  cmd[3] = (arg >> 8);
4194  cmd[4] = arg;
4195  timeout = STp->timeout;
4196 #if DEBUG
4197  if (debugging)
4198  printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
4199  cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
4200 #endif
4201  if (fileno >= 0)
4202  fileno += arg;
4203  blkno = 0;
4204  at_sm = (cmd_in == MTWSM);
4205  break;
4206  case MTOFFL:
4207  case MTLOAD:
4208  case MTUNLOAD:
4209  case MTRETEN:
4210  cmd[0] = START_STOP;
4211  cmd[1] = 1; /* Don't wait for completion */
4212  if (cmd_in == MTLOAD) {
4213  if (STp->ready == ST_NO_TAPE)
4214  cmd[4] = 4; /* open tray */
4215  else
4216  cmd[4] = 1; /* load */
4217  }
4218  if (cmd_in == MTRETEN)
4219  cmd[4] = 3; /* retension then mount */
4220  if (cmd_in == MTOFFL)
4221  cmd[4] = 4; /* rewind then eject */
4222  timeout = STp->timeout;
4223 #if DEBUG
4224  if (debugging) {
4225  switch (cmd_in) {
4226  case MTUNLOAD:
4227  printk(OSST_DEB_MSG "%s:D: Unloading tape.\n", name);
4228  break;
4229  case MTLOAD:
4230  printk(OSST_DEB_MSG "%s:D: Loading tape.\n", name);
4231  break;
4232  case MTRETEN:
4233  printk(OSST_DEB_MSG "%s:D: Retensioning tape.\n", name);
4234  break;
4235  case MTOFFL:
4236  printk(OSST_DEB_MSG "%s:D: Ejecting tape.\n", name);
4237  break;
4238  }
4239  }
4240 #endif
4241  fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4242  break;
4243  case MTNOP:
4244 #if DEBUG
4245  if (debugging)
4246  printk(OSST_DEB_MSG "%s:D: No-op on tape.\n", name);
4247 #endif
4248  return 0; /* Should do something ? */
4249  break;
4250  case MTEOM:
4251 #if DEBUG
4252  if (debugging)
4253  printk(OSST_DEB_MSG "%s:D: Spacing to end of recorded medium.\n", name);
4254 #endif
4255  if ((osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0) ||
4256  (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0)) {
4257  ioctl_result = -EIO;
4258  goto os_bypass;
4259  }
4260  if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
4261 #if DEBUG
4262  printk(OSST_DEB_MSG "%s:D: No EOD frame found where expected.\n", name);
4263 #endif
4264  ioctl_result = -EIO;
4265  goto os_bypass;
4266  }
4267  ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
4268  fileno = STp->filemark_cnt;
4269  blkno = at_sm = 0;
4270  goto os_bypass;
4271 
4272  case MTERASE:
4273  if (STp->write_prot)
4274  return (-EACCES);
4275  ioctl_result = osst_reset_header(STp, &SRpnt);
4276  i = osst_write_eod(STp, &SRpnt);
4277  if (i < ioctl_result) ioctl_result = i;
4278  i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
4279  if (i < ioctl_result) ioctl_result = i;
4280  fileno = blkno = at_sm = 0 ;
4281  goto os_bypass;
4282 
4283  case MTREW:
4284  cmd[0] = REZERO_UNIT; /* rewind */
4285  cmd[1] = 1;
4286 #if DEBUG
4287  if (debugging)
4288  printk(OSST_DEB_MSG "%s:D: Rewinding tape, Immed=%d.\n", name, cmd[1]);
4289 #endif
4290  fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
4291  break;
4292 
4293  case MTSETBLK: /* Set block length */
4294  if ((STps->drv_block == 0 ) &&
4295  !STp->dirty &&
4296  ((STp->buffer)->buffer_bytes == 0) &&
4297  ((arg & MT_ST_BLKSIZE_MASK) >= 512 ) &&
4298  ((arg & MT_ST_BLKSIZE_MASK) <= OS_DATA_SIZE) &&
4299  !(OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK)) ) {
4300  /*
4301  * Only allowed to change the block size if you opened the
4302  * device at the beginning of a file before writing anything.
4303  * Note, that when reading, changing block_size is futile,
4304  * as the size used when writing overrides it.
4305  */
4306  STp->block_size = (arg & MT_ST_BLKSIZE_MASK);
4307  printk(KERN_INFO "%s:I: Block size set to %d bytes.\n",
4308  name, STp->block_size);
4309  return 0;
4310  }
4311  case MTSETDENSITY: /* Set tape density */
4312  case MTSETDRVBUFFER: /* Set drive buffering */
4313  case SET_DENS_AND_BLK: /* Set density and block size */
4314  chg_eof = 0;
4315  if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
4316  return (-EIO); /* Not allowed if data in buffer */
4317  if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
4318  (arg & MT_ST_BLKSIZE_MASK) != 0 &&
4319  (arg & MT_ST_BLKSIZE_MASK) != STp->block_size ) {
4320  printk(KERN_WARNING "%s:W: Illegal to set block size to %d%s.\n",
4321  name, (int)(arg & MT_ST_BLKSIZE_MASK),
4322  (OS_DATA_SIZE % (arg & MT_ST_BLKSIZE_MASK))?"":" now");
4323  return (-EINVAL);
4324  }
4325  return 0; /* FIXME silently ignore if block size didn't change */
4326 
4327  default:
4328  return (-ENOSYS);
4329  }
4330 
4331  SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
4332 
4333  ioctl_result = (STp->buffer)->syscall_result;
4334 
4335  if (!SRpnt) {
4336 #if DEBUG
4337  printk(OSST_DEB_MSG "%s:D: Couldn't exec scsi cmd for IOCTL\n", name);
4338 #endif
4339  return ioctl_result;
4340  }
4341 
4342  if (!ioctl_result) { /* SCSI command successful */
4343  STp->frame_seq_number = frame_seq_numbr;
4344  STp->logical_blk_num = logical_blk_num;
4345  }
4346 
4347 os_bypass:
4348 #if DEBUG
4349  if (debugging)
4350  printk(OSST_DEB_MSG "%s:D: IOCTL (%d) Result=%d\n", name, cmd_in, ioctl_result);
4351 #endif
4352 
4353  if (!ioctl_result) { /* success */
4354 
4355  if (cmd_in == MTFSFM) {
4356  fileno--;
4357  blkno--;
4358  }
4359  if (cmd_in == MTBSFM) {
4360  fileno++;
4361  blkno++;
4362  }
4363  STps->drv_block = blkno;
4364  STps->drv_file = fileno;
4365  STps->at_sm = at_sm;
4366 
4367  if (cmd_in == MTEOM)
4368  STps->eof = ST_EOD;
4369  else if ((cmd_in == MTFSFM || cmd_in == MTBSF) && STps->eof == ST_FM_HIT) {
4370  ioctl_result = osst_seek_logical_blk(STp, &SRpnt, STp->logical_blk_num-1);
4371  STps->drv_block++;
4372  STp->logical_blk_num++;
4373  STp->frame_seq_number++;
4374  STp->frame_in_buffer = 0;
4375  STp->buffer->read_pointer = 0;
4376  }
4377  else if (cmd_in == MTFSF)
4378  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
4379  else if (chg_eof)
4380  STps->eof = ST_NOEOF;
4381 
4382  if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
4383  STp->rew_at_close = 0;
4384  else if (cmd_in == MTLOAD) {
4385  for (i=0; i < ST_NBR_PARTITIONS; i++) {
4386  STp->ps[i].rw = ST_IDLE;
4387  STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */
4388  }
4389  STp->partition = 0;
4390  }
4391 
4392  if (cmd_in == MTREW) {
4393  ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4394  if (ioctl_result > 0)
4395  ioctl_result = 0;
4396  }
4397 
4398  } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
4399  if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
4400  STps->drv_file = STps->drv_block = -1;
4401  else
4402  STps->drv_file = STps->drv_block = 0;
4403  STps->eof = ST_NOEOF;
4404  } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
4405  if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
4406  STps->drv_file = STps->drv_block = -1;
4407  else {
4408  STps->drv_file = STp->filemark_cnt;
4409  STps->drv_block = 0;
4410  }
4411  STps->eof = ST_EOD;
4412  } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
4413  STps->drv_file = STps->drv_block = (-1);
4414  STps->eof = ST_NOEOF;
4415  STp->header_ok = 0;
4416  } else if (cmd_in == MTERASE) {
4417  STp->header_ok = 0;
4418  } else if (SRpnt) { /* SCSI command was not completely successful. */
4419  if (SRpnt->sense[2] & 0x40) {
4420  STps->eof = ST_EOM_OK;
4421  STps->drv_block = 0;
4422  }
4423  if (chg_eof)
4424  STps->eof = ST_NOEOF;
4425 
4426  if ((SRpnt->sense[2] & 0x0f) == BLANK_CHECK)
4427  STps->eof = ST_EOD;
4428 
4429  if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
4430  ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60, OSST_WAIT_POSITION_COMPLETE);
4431  }
4432  *aSRpnt = SRpnt;
4433 
4434  return ioctl_result;
4435 }
4436 
4437 
4438 /* Open the device */
4439 static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
4440 {
4441  unsigned short flags;
4442  int i, b_size, new_session = 0, retval = 0;
4443  unsigned char cmd[MAX_COMMAND_SIZE];
4444  struct osst_request * SRpnt = NULL;
4445  struct osst_tape * STp;
4446  struct st_modedef * STm;
4447  struct st_partstat * STps;
4448  char * name;
4449  int dev = TAPE_NR(inode);
4450  int mode = TAPE_MODE(inode);
4451 
4452  /*
4453  * We really want to do nonseekable_open(inode, filp); here, but some
4454  * versions of tar incorrectly call lseek on tapes and bail out if that
4455  * fails. So we disallow pread() and pwrite(), but permit lseeks.
4456  */
4457  filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
4458 
4459  write_lock(&os_scsi_tapes_lock);
4460  if (dev >= osst_max_dev || os_scsi_tapes == NULL ||
4461  (STp = os_scsi_tapes[dev]) == NULL || !STp->device) {
4462  write_unlock(&os_scsi_tapes_lock);
4463  return (-ENXIO);
4464  }
4465 
4466  name = tape_name(STp);
4467 
4468  if (STp->in_use) {
4469  write_unlock(&os_scsi_tapes_lock);
4470 #if DEBUG
4471  printk(OSST_DEB_MSG "%s:D: Device already in use.\n", name);
4472 #endif
4473  return (-EBUSY);
4474  }
4475  if (scsi_device_get(STp->device)) {
4476  write_unlock(&os_scsi_tapes_lock);
4477 #if DEBUG
4478  printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
4479 #endif
4480  return (-ENXIO);
4481  }
4482  filp->private_data = STp;
4483  STp->in_use = 1;
4484  write_unlock(&os_scsi_tapes_lock);
4485  STp->rew_at_close = TAPE_REWIND(inode);
4486 
4488  return -ENXIO;
4489  }
4490 
4491  if (mode != STp->current_mode) {
4492 #if DEBUG
4493  if (debugging)
4494  printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n",
4495  name, STp->current_mode, mode);
4496 #endif
4497  new_session = 1;
4498  STp->current_mode = mode;
4499  }
4500  STm = &(STp->modes[STp->current_mode]);
4501 
4502  flags = filp->f_flags;
4503  STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
4504 
4505  STp->raw = TAPE_IS_RAW(inode);
4506  if (STp->raw)
4507  STp->header_ok = 0;
4508 
4509  /* Allocate data segments for this device's tape buffer */
4510  if (!enlarge_buffer(STp->buffer, STp->restr_dma)) {
4511  printk(KERN_ERR "%s:E: Unable to allocate memory segments for tape buffer.\n", name);
4512  retval = (-EOVERFLOW);
4513  goto err_out;
4514  }
4515  if (STp->buffer->buffer_size >= OS_FRAME_SIZE) {
4516  for (i = 0, b_size = 0;
4517  (i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
4518  b_size += STp->buffer->sg[i++].length);
4519  STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
4520 #if DEBUG
4521  printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
4522  STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
4523  printk(OSST_DEB_MSG "%s:D: AUX points to %p in segment %d at %p\n", name,
4524  STp->buffer->aux, i, page_address(STp->buffer->sg[i].page));
4525 #endif
4526  } else {
4527  STp->buffer->aux = NULL; /* this had better never happen! */
4528  printk(KERN_NOTICE "%s:A: Framesize %d too large for buffer.\n", name, OS_FRAME_SIZE);
4529  retval = (-EIO);
4530  goto err_out;
4531  }
4532  STp->buffer->writing = 0;
4533  STp->buffer->syscall_result = 0;
4534  STp->dirty = 0;
4535  for (i=0; i < ST_NBR_PARTITIONS; i++) {
4536  STps = &(STp->ps[i]);
4537  STps->rw = ST_IDLE;
4538  }
4539  STp->ready = ST_READY;
4540 #if DEBUG
4541  STp->nbr_waits = STp->nbr_finished = 0;
4542 #endif
4543 
4544  memset (cmd, 0, MAX_COMMAND_SIZE);
4545  cmd[0] = TEST_UNIT_READY;
4546 
4547  SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
4548  if (!SRpnt) {
4549  retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
4550  goto err_out;
4551  }
4552  if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4553  (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4554  SRpnt->sense[12] == 4 ) {
4555 #if DEBUG
4556  printk(OSST_DEB_MSG "%s:D: Unit not ready, cause %x\n", name, SRpnt->sense[13]);
4557 #endif
4558  if (filp->f_flags & O_NONBLOCK) {
4559  retval = -EAGAIN;
4560  goto err_out;
4561  }
4562  if (SRpnt->sense[13] == 2) { /* initialize command required (LOAD) */
4563  memset (cmd, 0, MAX_COMMAND_SIZE);
4564  cmd[0] = START_STOP;
4565  cmd[1] = 1;
4566  cmd[4] = 1;
4567  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4568  STp->timeout, MAX_RETRIES, 1);
4569  }
4570  osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
4571  }
4572  if ((SRpnt->sense[0] & 0x70) == 0x70 &&
4573  (SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
4574 #if DEBUG
4575  printk(OSST_DEB_MSG "%s:D: Unit wants attention\n", name);
4576 #endif
4577  STp->header_ok = 0;
4578 
4579  for (i=0; i < 10; i++) {
4580 
4581  memset (cmd, 0, MAX_COMMAND_SIZE);
4582  cmd[0] = TEST_UNIT_READY;
4583 
4584  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4585  STp->timeout, MAX_RETRIES, 1);
4586  if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4587  (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
4588  break;
4589  }
4590 
4591  STp->pos_unknown = 0;
4592  STp->partition = STp->new_partition = 0;
4593  if (STp->can_partitions)
4594  STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4595  for (i=0; i < ST_NBR_PARTITIONS; i++) {
4596  STps = &(STp->ps[i]);
4597  STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
4598  STps->eof = ST_NOEOF;
4599  STps->at_sm = 0;
4600  STps->last_block_valid = 0;
4601  STps->drv_block = 0;
4602  STps->drv_file = 0 ;
4603  }
4604  new_session = 1;
4605  STp->recover_count = 0;
4606  STp->abort_count = 0;
4607  }
4608  /*
4609  * if we have valid headers from before, and the drive/tape seem untouched,
4610  * open without reconfiguring and re-reading the headers
4611  */
4612  if (!STp->buffer->syscall_result && STp->header_ok &&
4613  !SRpnt->result && SRpnt->sense[0] == 0) {
4614 
4615  memset(cmd, 0, MAX_COMMAND_SIZE);
4616  cmd[0] = MODE_SENSE;
4617  cmd[1] = 8;
4618  cmd[2] = VENDOR_IDENT_PAGE;
4620 
4621  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
4622 
4623  if (STp->buffer->syscall_result ||
4624  STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
4625  STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
4626  STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
4627  STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4' ) {
4628 #if DEBUG
4629  printk(OSST_DEB_MSG "%s:D: Signature was changed to %c%c%c%c\n", name,
4630  STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
4631  STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
4632  STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
4633  STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
4634 #endif
4635  STp->header_ok = 0;
4636  }
4637  i = STp->first_frame_position;
4638  if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
4639  if (STp->door_locked == ST_UNLOCKED) {
4640  if (do_door_lock(STp, 1))
4641  printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4642  else
4643  STp->door_locked = ST_LOCKED_AUTO;
4644  }
4645  if (!STp->frame_in_buffer) {
4646  STp->block_size = (STm->default_blksize > 0) ?
4648  STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
4649  }
4650  STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
4651  STp->fast_open = 1;
4652  osst_release_request(SRpnt);
4653  return 0;
4654  }
4655 #if DEBUG
4656  if (i != STp->first_frame_position)
4657  printk(OSST_DEB_MSG "%s:D: Tape position changed from %d to %d\n",
4658  name, i, STp->first_frame_position);
4659 #endif
4660  STp->header_ok = 0;
4661  }
4662  STp->fast_open = 0;
4663 
4664  if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */
4665  (SRpnt->sense[2] != 2 || SRpnt->sense[12] != 0x3A) ) {
4666 
4667  memset(cmd, 0, MAX_COMMAND_SIZE);
4668  cmd[0] = MODE_SELECT;
4669  cmd[1] = 0x10;
4670  cmd[4] = 4 + MODE_HEADER_LENGTH;
4671 
4672  (STp->buffer)->b_data[0] = cmd[4] - 1;
4673  (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
4674  (STp->buffer)->b_data[2] = 0; /* Reserved */
4675  (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
4676  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
4677  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
4678  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
4679  (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
4680 
4681 #if DEBUG
4682  printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
4683 #endif
4684  SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
4685 
4686  STp->header_ok = 0;
4687 
4688  for (i=0; i < 10; i++) {
4689 
4690  memset (cmd, 0, MAX_COMMAND_SIZE);
4691  cmd[0] = TEST_UNIT_READY;
4692 
4693  SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
4694  STp->timeout, MAX_RETRIES, 1);
4695  if ((SRpnt->sense[0] & 0x70) != 0x70 ||
4696  (SRpnt->sense[2] & 0x0f) == NOT_READY)
4697  break;
4698 
4699  if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
4700  int j;
4701 
4702  STp->pos_unknown = 0;
4703  STp->partition = STp->new_partition = 0;
4704  if (STp->can_partitions)
4705  STp->nbr_partitions = 1; /* This guess will be updated later if necessary */
4706  for (j = 0; j < ST_NBR_PARTITIONS; j++) {
4707  STps = &(STp->ps[j]);
4708  STps->rw = ST_IDLE;
4709  STps->eof = ST_NOEOF;
4710  STps->at_sm = 0;
4711  STps->last_block_valid = 0;
4712  STps->drv_block = 0;
4713  STps->drv_file = 0 ;
4714  }
4715  new_session = 1;
4716  }
4717  }
4718  }
4719 
4720  if (osst_wait_ready(STp, &SRpnt, 15 * 60, 0)) /* FIXME - not allowed with NOBLOCK */
4721  printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
4722 
4723  if ((STp->buffer)->syscall_result != 0) {
4724  if ((STp->device)->scsi_level >= SCSI_2 &&
4725  (SRpnt->sense[0] & 0x70) == 0x70 &&
4726  (SRpnt->sense[2] & 0x0f) == NOT_READY &&
4727  SRpnt->sense[12] == 0x3a) { /* Check ASC */
4728  STp->ready = ST_NO_TAPE;
4729  } else
4730  STp->ready = ST_NOT_READY;
4731  osst_release_request(SRpnt);
4732  SRpnt = NULL;
4733  STp->density = 0; /* Clear the erroneous "residue" */
4734  STp->write_prot = 0;
4735  STp->block_size = 0;
4736  STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
4737  STp->partition = STp->new_partition = 0;
4738  STp->door_locked = ST_UNLOCKED;
4739  return 0;
4740  }
4741 
4742  osst_configure_onstream(STp, &SRpnt);
4743 
4744  STp->block_size = STp->raw ? OS_FRAME_SIZE : (
4745  (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
4746  STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
4747  STp->buffer->buffer_bytes =
4748  STp->buffer->read_pointer =
4749  STp->frame_in_buffer = 0;
4750 
4751 #if DEBUG
4752  if (debugging)
4753  printk(OSST_DEB_MSG "%s:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).\n",
4754  name, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
4755  (STp->buffer)->buffer_blocks);
4756 #endif
4757 
4758  if (STp->drv_write_prot) {
4759  STp->write_prot = 1;
4760 #if DEBUG
4761  if (debugging)
4762  printk(OSST_DEB_MSG "%s:D: Write protected\n", name);
4763 #endif
4764  if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
4765  retval = (-EROFS);
4766  goto err_out;
4767  }
4768  }
4769 
4770  if (new_session) { /* Change the drive parameters for the new mode */
4771 #if DEBUG
4772  if (debugging)
4773  printk(OSST_DEB_MSG "%s:D: New Session\n", name);
4774 #endif
4775  STp->density_changed = STp->blksize_changed = 0;
4776  STp->compression_changed = 0;
4777  }
4778 
4779  /*
4780  * properly position the tape and check the ADR headers
4781  */
4782  if (STp->door_locked == ST_UNLOCKED) {
4783  if (do_door_lock(STp, 1))
4784  printk(KERN_INFO "%s:I: Can't lock drive door\n", name);
4785  else
4786  STp->door_locked = ST_LOCKED_AUTO;
4787  }
4788 
4789  osst_analyze_headers(STp, &SRpnt);
4790 
4791  osst_release_request(SRpnt);
4792  SRpnt = NULL;
4793 
4794  return 0;
4795 
4796 err_out:
4797  if (SRpnt != NULL)
4798  osst_release_request(SRpnt);
4799  normalize_buffer(STp->buffer);
4800  STp->header_ok = 0;
4801  STp->in_use = 0;
4802  scsi_device_put(STp->device);
4803 
4804  return retval;
4805 }
4806 
4807 /* BKL pushdown: spaghetti avoidance wrapper */
4808 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
4809 {
4810  int ret;
4811 
4812  mutex_lock(&osst_int_mutex);
4813  ret = __os_scsi_tape_open(inode, filp);
4814  mutex_unlock(&osst_int_mutex);
4815  return ret;
4816 }
4817 
4818 
4819 
4820 /* Flush the tape buffer before close */
4821 static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
4822 {
4823  int result = 0, result2;
4824  struct osst_tape * STp = filp->private_data;
4825  struct st_modedef * STm = &(STp->modes[STp->current_mode]);
4826  struct st_partstat * STps = &(STp->ps[STp->partition]);
4827  struct osst_request * SRpnt = NULL;
4828  char * name = tape_name(STp);
4829 
4830  if (file_count(filp) > 1)
4831  return 0;
4832 
4833  if ((STps->rw == ST_WRITING || STp->dirty) && !STp->pos_unknown) {
4834  STp->write_type = OS_WRITE_DATA;
4835  result = osst_flush_write_buffer(STp, &SRpnt);
4836  if (result != 0 && result != (-ENOSPC))
4837  goto out;
4838  }
4839  if ( STps->rw >= ST_WRITING && !STp->pos_unknown) {
4840 
4841 #if DEBUG
4842  if (debugging) {
4843  printk(OSST_DEB_MSG "%s:D: File length %ld bytes.\n",
4844  name, (long)(filp->f_pos));
4845  printk(OSST_DEB_MSG "%s:D: Async write waits %d, finished %d.\n",
4846  name, STp->nbr_waits, STp->nbr_finished);
4847  }
4848 #endif
4849  result = osst_write_trailer(STp, &SRpnt, !(STp->rew_at_close));
4850 #if DEBUG
4851  if (debugging)
4852  printk(OSST_DEB_MSG "%s:D: Buffer flushed, %d EOF(s) written\n",
4853  name, 1+STp->two_fm);
4854 #endif
4855  }
4856  else if (!STp->rew_at_close) {
4857  STps = &(STp->ps[STp->partition]);
4858  if (!STm->sysv || STps->rw != ST_READING) {
4859  if (STp->can_bsr)
4860  result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
4861  else if (STps->eof == ST_FM_HIT) {
4862  result = cross_eof(STp, &SRpnt, 0);
4863  if (result) {
4864  if (STps->drv_file >= 0)
4865  STps->drv_file++;
4866  STps->drv_block = 0;
4867  STps->eof = ST_FM;
4868  }
4869  else
4870  STps->eof = ST_NOEOF;
4871  }
4872  }
4873  else if ((STps->eof == ST_NOEOF &&
4874  !(result = cross_eof(STp, &SRpnt, 1))) ||
4875  STps->eof == ST_FM_HIT) {
4876  if (STps->drv_file >= 0)
4877  STps->drv_file++;
4878  STps->drv_block = 0;
4879  STps->eof = ST_FM;
4880  }
4881  }
4882 
4883 out:
4884  if (STp->rew_at_close) {
4885  result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
4886  STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
4887  if (result == 0 && result2 < 0)
4888  result = result2;
4889  }
4890  if (SRpnt) osst_release_request(SRpnt);
4891 
4892  if (STp->abort_count || STp->recover_count) {
4893  printk(KERN_INFO "%s:I:", name);
4894  if (STp->abort_count)
4895  printk(" %d unrecovered errors", STp->abort_count);
4896  if (STp->recover_count)
4897  printk(" %d recovered errors", STp->recover_count);
4898  if (STp->write_count)
4899  printk(" in %d frames written", STp->write_count);
4900  if (STp->read_count)
4901  printk(" in %d frames read", STp->read_count);
4902  printk("\n");
4903  STp->recover_count = 0;
4904  STp->abort_count = 0;
4905  }
4906  STp->write_count = 0;
4907  STp->read_count = 0;
4908 
4909  return result;
4910 }
4911 
4912 
4913 /* Close the device and release it */
4914 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
4915 {
4916  int result = 0;
4917  struct osst_tape * STp = filp->private_data;
4918 
4919  if (STp->door_locked == ST_LOCKED_AUTO)
4920  do_door_lock(STp, 0);
4921 
4922  if (STp->raw)
4923  STp->header_ok = 0;
4924 
4925  normalize_buffer(STp->buffer);
4926  write_lock(&os_scsi_tapes_lock);
4927  STp->in_use = 0;
4928  write_unlock(&os_scsi_tapes_lock);
4929 
4930  scsi_device_put(STp->device);
4931 
4932  return result;
4933 }
4934 
4935 
4936 /* The ioctl command */
4937 static long osst_ioctl(struct file * file,
4938  unsigned int cmd_in, unsigned long arg)
4939 {
4940  int i, cmd_nr, cmd_type, blk, retval = 0;
4941  struct st_modedef * STm;
4942  struct st_partstat * STps;
4943  struct osst_request * SRpnt = NULL;
4944  struct osst_tape * STp = file->private_data;
4945  char * name = tape_name(STp);
4946  void __user * p = (void __user *)arg;
4947 
4948  mutex_lock(&osst_int_mutex);
4949  if (mutex_lock_interruptible(&STp->lock)) {
4950  mutex_unlock(&osst_int_mutex);
4951  return -ERESTARTSYS;
4952  }
4953 
4954 #if DEBUG
4955  if (debugging && !STp->in_use) {
4956  printk(OSST_DEB_MSG "%s:D: Incorrect device.\n", name);
4957  retval = (-EIO);
4958  goto out;
4959  }
4960 #endif
4961  STm = &(STp->modes[STp->current_mode]);
4962  STps = &(STp->ps[STp->partition]);
4963 
4964  /*
4965  * If we are in the middle of error recovery, don't let anyone
4966  * else try and use this device. Also, if error recovery fails, it
4967  * may try and take the device offline, in which case all further
4968  * access to the device is prohibited.
4969  */
4971  retval = (-ENXIO);
4972  goto out;
4973  }
4974 
4975  cmd_type = _IOC_TYPE(cmd_in);
4976  cmd_nr = _IOC_NR(cmd_in);
4977 #if DEBUG
4978  printk(OSST_DEB_MSG "%s:D: Ioctl %d,%d in %s mode\n", name,
4979  cmd_type, cmd_nr, STp->raw?"raw":"normal");
4980 #endif
4981  if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
4982  struct mtop mtc;
4983  int auto_weof = 0;
4984 
4985  if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
4986  retval = (-EINVAL);
4987  goto out;
4988