osst.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:172k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.   SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
  3.   file README.st for more information.
  4.   History:
  5.   OnStream SCSI Tape support (osst) cloned from st.c by
  6.   Willem Riede (osst@riede.org) Feb 2000
  7.   Fixes ... Kurt Garloff <garloff@suse.de> Mar 2000
  8.   Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
  9.   Contribution and ideas from several people including (in alphabetical
  10.   order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
  11.   Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
  12.   Copyright 1992 - 2000 Kai Makisara
  13.  email Kai.Makisara@metla.fi
  14.   $Header: /home/cvsroot/Driver/osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $
  15.   Microscopic alterations - Rik Ling, 2000/12/21
  16.   Last modified: Wed Feb  2 22:04:05 2000 by makisara@kai.makisara.local
  17.   Some small formal changes - aeb, 950809
  18. */
  19. static const char * cvsid = "$Id: osst.c,v 1.65 2001/11/11 20:38:56 riede Exp $";
  20. const char * osst_version = "0.9.10";
  21. /* The "failure to reconnect" firmware bug */
  22. #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
  23. #define OSST_FW_NEED_POLL_MAX 10704 /*(108D)*/
  24. #define OSST_FW_NEED_POLL(x,d) ((x) >= OSST_FW_NEED_POLL_MIN && (x) <= OSST_FW_NEED_POLL_MAX && d->host->this_id != 7)
  25. #include <linux/module.h>
  26. #include <linux/fs.h>
  27. #include <linux/kernel.h>
  28. #include <linux/sched.h>
  29. #include <linux/mm.h>
  30. #include <linux/init.h>
  31. #include <linux/string.h>
  32. #include <linux/errno.h>
  33. #include <linux/mtio.h>
  34. #include <linux/ioctl.h>
  35. #include <linux/fcntl.h>
  36. #include <linux/spinlock.h>
  37. #include <linux/vmalloc.h>
  38. #include <linux/version.h>
  39. #include <asm/uaccess.h>
  40. #include <asm/dma.h>
  41. #include <asm/system.h>
  42. /* The driver prints some debugging information on the console if DEBUG
  43.    is defined and non-zero. */
  44. #define DEBUG 0
  45. /* The message level for the debug messages is currently set to KERN_NOTICE
  46.    so that people can easily see the messages. Later when the debugging messages
  47.    in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
  48. #define OSST_DEB_MSG  KERN_NOTICE
  49. #define MAJOR_NR OSST_MAJOR
  50. #include <linux/blk.h>
  51. #include "scsi.h"
  52. #include "hosts.h"
  53. #include <scsi/scsi_ioctl.h>
  54. #define ST_KILOBYTE 1024
  55. #include "st.h"
  56. #include "osst.h"
  57. #include "osst_options.h"
  58. #include "osst_detect.h"
  59. #include "constants.h"
  60. static int buffer_kbs = 0;
  61. static int write_threshold_kbs = 0;
  62. static int max_buffers = 0;
  63. static int max_sg_segs = 0;
  64. #ifdef MODULE
  65. MODULE_AUTHOR("Willem Riede");
  66. MODULE_DESCRIPTION("OnStream SCSI Tape Driver");
  67. MODULE_LICENSE("GPL");
  68. MODULE_PARM(buffer_kbs, "i");
  69. MODULE_PARM(write_threshold_kbs, "i");
  70. MODULE_PARM(max_buffers, "i");
  71. MODULE_PARM(max_sg_segs, "i");
  72. #else
  73. static struct osst_dev_parm {
  74.        char   *name;
  75.        int    *val;
  76. } parms[] __initdata = {
  77.        { "buffer_kbs",          &buffer_kbs          },
  78.        { "write_threshold_kbs", &write_threshold_kbs },
  79.        { "max_buffers",         &max_buffers         },
  80.        { "max_sg_segs",         &max_sg_segs         }
  81.        };
  82. #endif
  83. /* Some default definitions have been moved to osst_options.h */
  84. #define OSST_BUFFER_SIZE (OSST_BUFFER_BLOCKS * ST_KILOBYTE)
  85. #define OSST_WRITE_THRESHOLD (OSST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE)
  86. /* The buffer size should fit into the 24 bits for length in the
  87.    6-byte SCSI read and write commands. */
  88. #if OSST_BUFFER_SIZE >= (2 << 24 - 1)
  89. #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
  90. #endif
  91. #if DEBUG
  92. static int debugging = 1;
  93. /* uncomment define below to test error recovery */
  94. // #define OSST_INJECT_ERRORS 1 
  95. #endif
  96. #define MAX_RETRIES 0
  97. #define MAX_WRITE_RETRIES 0
  98. #define MAX_READY_RETRIES 5
  99. #define NO_TAPE  NOT_READY
  100. #define OSST_TIMEOUT (200 * HZ)
  101. #define OSST_LONG_TIMEOUT (1800 * HZ)
  102. #define TAPE_NR(x) (MINOR(x) & ~(128 | ST_MODE_MASK))
  103. #define TAPE_MODE(x) ((MINOR(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
  104. /* Internal ioctl to set both density (uppermost 8 bits) and blocksize (lower
  105.    24 bits) */
  106. #define SET_DENS_AND_BLK 0x10001
  107. static int osst_nbr_buffers;
  108. static int osst_buffer_size       = OSST_BUFFER_SIZE;
  109. static int osst_write_threshold   = OSST_WRITE_THRESHOLD;
  110. static int osst_max_buffers       = OSST_MAX_BUFFERS;
  111. static int osst_max_sg_segs       = OSST_MAX_SG;
  112. static OS_Scsi_Tape **os_scsi_tapes = NULL;
  113. static OSST_buffer  **osst_buffers  = NULL;
  114. static int modes_defined = FALSE;
  115. static OSST_buffer *new_tape_buffer(int, int);
  116. static int enlarge_buffer(OSST_buffer *, int, int);
  117. static void normalize_buffer(OSST_buffer *);
  118. static int append_to_buffer(const char *, OSST_buffer *, int);
  119. static int from_buffer(OSST_buffer *, char *, int);
  120. static int osst_zero_buffer_tail(OSST_buffer *);
  121. static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
  122. static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
  123. static int osst_init(void);
  124. static int osst_attach(Scsi_Device *);
  125. static int osst_detect(Scsi_Device *);
  126. static void osst_detach(Scsi_Device *);
  127. struct Scsi_Device_Template osst_template =
  128. {
  129.        name: "OnStream tape",
  130.        tag: "osst",
  131.        scsi_type: TYPE_TAPE,
  132.        major: OSST_MAJOR,
  133.        detect: osst_detect,
  134.        init: osst_init,
  135.        attach: osst_attach,
  136.        detach: osst_detach
  137. };
  138. static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg);
  139. static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int frame, int skip);
  140. static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
  141. static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
  142. static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending);
  143. /* Routines that handle the interaction with mid-layer SCSI routines */
  144. /* Convert the result to success code */
  145. static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
  146. {
  147. int dev = TAPE_NR(STp->devt);
  148. int result = SRpnt->sr_result;
  149. unsigned char * sense = SRpnt->sr_sense_buffer, scode;
  150. #if DEBUG
  151. const char *stp;
  152. #endif
  153. if (!result) {
  154. sense[0] = 0;    /* We don't have sense data if this byte is zero */
  155. return 0;
  156. }
  157. if (driver_byte(result) & DRIVER_SENSE)
  158. scode = sense[2] & 0x0f;
  159. else {
  160. sense[0] = 0;    /* We don't have sense data if this byte is zero */
  161. scode = 0;
  162. }
  163. #if DEBUG
  164. if (debugging) {
  165. printk(OSST_DEB_MSG "osst%d:D: Error: %x, cmd: %x %x %x %x %x %x Len: %dn",
  166.    dev, result,
  167.    SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
  168.    SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
  169.    SRpnt->sr_bufflen);
  170. if (driver_byte(result) & DRIVER_SENSE)
  171. print_req_sense("osst", SRpnt);
  172. }
  173. else
  174. #endif
  175. if (!(driver_byte(result) & DRIVER_SENSE) ||
  176. ((sense[0] & 0x70) == 0x70 &&
  177.  scode != NO_SENSE &&
  178.  scode != RECOVERED_ERROR &&
  179. /*        scode != UNIT_ATTENTION && */
  180.  scode != BLANK_CHECK &&
  181.  scode != VOLUME_OVERFLOW &&
  182.  SRpnt->sr_cmnd[0] != MODE_SENSE &&
  183.  SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
  184. if (driver_byte(result) & DRIVER_SENSE) {
  185. printk(KERN_WARNING "osst%d:W: Command with sense data: ", dev);
  186. print_req_sense("osst:", SRpnt);
  187. }
  188. else {
  189. static int notyetprinted = 1;
  190. printk(KERN_WARNING
  191.      "osst%d:W: Warning %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).n",
  192.      dev, result, suggestion(result), driver_byte(result) & DRIVER_MASK,
  193.      host_byte(result));
  194. if (notyetprinted) {
  195. notyetprinted = 0;
  196. printk(KERN_INFO
  197. "osst%d:I: This warning may be caused by your scsi controller,n", dev);
  198. printk(KERN_INFO
  199. "osst%d:I: it has been reported with some Buslogic cards.n", dev);
  200. }
  201. }
  202. }
  203. if ((sense[0] & 0x70) == 0x70 &&
  204.      scode == RECOVERED_ERROR) {
  205. STp->recover_count++;
  206. STp->recover_erreg++;
  207. #if DEBUG
  208. if (debugging) {
  209. if (SRpnt->sr_cmnd[0] == READ_6)
  210. stp = "read";
  211. else if (SRpnt->sr_cmnd[0] == WRITE_6)
  212. stp = "write";
  213. else
  214. stp = "ioctl";
  215. printk(OSST_DEB_MSG "osst%d:D: Recovered %s error (%d).n", dev, stp,
  216.      os_scsi_tapes[dev]->recover_count);
  217. }
  218. #endif
  219. if ((sense[2] & 0xe0) == 0)
  220. return 0;
  221. }
  222. return (-EIO);
  223. }
  224. /* Wakeup from interrupt */
  225. static void osst_sleep_done (Scsi_Cmnd * SCpnt)
  226. {
  227. unsigned int dev = TAPE_NR(SCpnt->request.rq_dev);
  228. OS_Scsi_Tape * STp;
  229. if (os_scsi_tapes && (STp = os_scsi_tapes[dev])) {
  230. if ((STp->buffer)->writing &&
  231.     (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
  232.     (SCpnt->sense_buffer[2] & 0x40)) {
  233. /* EOM at write-behind, has all been written? */
  234. if ((SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
  235. (STp->buffer)->midlevel_result = SCpnt->result; /* Error */
  236. else
  237. (STp->buffer)->midlevel_result = INT_MAX;       /* OK */
  238. }
  239. else
  240. (STp->buffer)->midlevel_result = SCpnt->result;
  241. SCpnt->request.rq_status = RQ_SCSI_DONE;
  242. (STp->buffer)->last_SRpnt = SCpnt->sc_request;
  243. #if DEBUG
  244. STp->write_pending = 0;
  245. #endif
  246. complete(SCpnt->request.waiting);
  247. }
  248. #if DEBUG
  249. else if (debugging)
  250. printk(OSST_DEB_MSG "osst?:D: Illegal interrupt device %xn", dev);
  251. #endif
  252. }
  253. /* Do the scsi command. Waits until command performed if do_wait is true.
  254.    Otherwise osst_write_behind_check() is used to check that the command
  255.    has finished. */
  256. static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, 
  257. unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
  258. {
  259. unsigned char *bp;
  260. #ifdef OSST_INJECT_ERRORS
  261. static   int   inject = 0;
  262. static   int   repeat = 0;
  263. #endif
  264. if (SRpnt == NULL) {
  265. if ((SRpnt = scsi_allocate_request(STp->device)) == NULL) {
  266. printk(KERN_ERR "osst%d:E: Can't get SCSI request.n", TAPE_NR(STp->devt));
  267. if (signal_pending(current))
  268. (STp->buffer)->syscall_result = (-EINTR);
  269. else
  270. (STp->buffer)->syscall_result = (-EBUSY);
  271. return NULL;
  272. }
  273. }
  274.         if (SRpnt->sr_device->scsi_level <= SCSI_2)
  275.                 cmd[1] |= (SRpnt->sr_device->lun << 5) & 0xe0;
  276.         init_completion(&STp->wait);
  277. SRpnt->sr_use_sg = (bytes > (STp->buffer)->sg[0].length) ?
  278.     (STp->buffer)->use_sg : 0;
  279. if (SRpnt->sr_use_sg) {
  280. bp = (char *)&(STp->buffer->sg[0]);
  281. if (STp->buffer->sg_segs < SRpnt->sr_use_sg)
  282. SRpnt->sr_use_sg = STp->buffer->sg_segs;
  283. }
  284. else
  285. bp = (STp->buffer)->b_data;
  286. SRpnt->sr_data_direction = direction;
  287. SRpnt->sr_cmd_len = 0;
  288. SRpnt->sr_request.waiting = &(STp->wait);
  289. SRpnt->sr_request.rq_status = RQ_SCSI_BUSY;
  290. SRpnt->sr_request.rq_dev = STp->devt;
  291. scsi_do_req(SRpnt, (void *)cmd, bp, bytes, osst_sleep_done, timeout, retries);
  292. if (do_wait) {
  293. wait_for_completion(SRpnt->sr_request.waiting);
  294. SRpnt->sr_request.waiting = NULL;
  295. STp->buffer->syscall_result = osst_chk_result(STp, SRpnt);
  296. #ifdef OSST_INJECT_ERRORS
  297. if (STp->buffer->syscall_result == 0 &&
  298.     cmd[0] == READ_6 &&
  299.     cmd[4] && 
  300.     ( (++ inject % 83) == 29  ||
  301.       (STp->first_frame_position == 240 
  302.          /* or STp->read_error_frame to fail again on the block calculated above */ &&
  303.  ++repeat < 3))) {
  304. printk(OSST_DEB_MSG "osst%d:D: Injecting read errorn", TAPE_NR(STp->devt));
  305. STp->buffer->last_result_fatal = 1;
  306. }
  307. #endif
  308. }
  309. return SRpnt;
  310. }
  311. /* Handle the write-behind checking (downs the semaphore) */
  312. static void osst_write_behind_check(OS_Scsi_Tape *STp)
  313. {
  314. OSST_buffer * STbuffer;
  315. STbuffer = STp->buffer;
  316. #if DEBUG
  317. if (STp->write_pending)
  318. STp->nbr_waits++;
  319. else
  320. STp->nbr_finished++;
  321. #endif
  322. wait_for_completion(&(STp->wait));
  323. (STp->buffer)->last_SRpnt->sr_request.waiting = NULL;
  324. STp->buffer->syscall_result = osst_chk_result(STp, STp->buffer->last_SRpnt);
  325. if ((STp->buffer)->syscall_result)
  326. (STp->buffer)->syscall_result =
  327. osst_write_error_recovery(STp, &((STp->buffer)->last_SRpnt), 1);
  328. else
  329. STp->first_frame_position++;
  330. scsi_release_request((STp->buffer)->last_SRpnt);
  331. if (STbuffer->writing < STbuffer->buffer_bytes)
  332. printk(KERN_WARNING "osst:A: write_behind_check: something left in buffer!n");
  333. STbuffer->buffer_bytes -= STbuffer->writing;
  334. STbuffer->writing = 0;
  335. return;
  336. }
  337. /* Onstream specific Routines */
  338. /*
  339.  * Initialize the OnStream AUX
  340.  */
  341. static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number,
  342.  int logical_blk_num, int blk_sz, int blk_cnt)
  343. {
  344. os_aux_t       *aux = STp->buffer->aux;
  345. os_partition_t *par = &aux->partition;
  346. os_dat_t       *dat = &aux->dat;
  347. if (STp->raw) return;
  348. memset(aux, 0, sizeof(*aux));
  349. aux->format_id = htonl(0);
  350. memcpy(aux->application_sig, "LIN4", 4);
  351. aux->hdwr = htonl(0);
  352. aux->frame_type = frame_type;
  353. switch (frame_type) {
  354.   case OS_FRAME_TYPE_HEADER:
  355. aux->update_frame_cntr    = htonl(STp->update_frame_cntr);
  356. par->partition_num        = OS_CONFIG_PARTITION;
  357. par->par_desc_ver         = OS_PARTITION_VERSION;
  358. par->wrt_pass_cntr        = htons(0xffff);
  359. /* 0-4 = reserved, 5-9 = header, 2990-2994 = header, 2995-2999 = reserved */
  360. par->first_frame_ppos     = htonl(0);
  361. par->last_frame_ppos      = htonl(0xbb7);
  362. aux->frame_seq_num        = htonl(0);
  363. aux->logical_blk_num_high = htonl(0);
  364. aux->logical_blk_num      = htonl(0);
  365. aux->next_mark_ppos       = htonl(STp->first_mark_ppos);
  366. break;
  367.   case OS_FRAME_TYPE_DATA:
  368.   case OS_FRAME_TYPE_MARKER:
  369. dat->dat_sz = 8;
  370. dat->reserved1 = 0;
  371. dat->entry_cnt = 1;
  372. dat->reserved3 = 0;
  373. dat->dat_list[0].blk_sz   = htonl(blk_sz);
  374. dat->dat_list[0].blk_cnt  = htons(blk_cnt);
  375. dat->dat_list[0].flags    = frame_type==OS_FRAME_TYPE_MARKER?
  376. OS_DAT_FLAGS_MARK:OS_DAT_FLAGS_DATA;
  377. dat->dat_list[0].reserved = 0;
  378.   case OS_FRAME_TYPE_EOD:
  379. aux->update_frame_cntr    = htonl(0);
  380. par->partition_num        = OS_DATA_PARTITION;
  381. par->par_desc_ver         = OS_PARTITION_VERSION;
  382. par->wrt_pass_cntr        = htons(STp->wrt_pass_cntr);
  383. par->first_frame_ppos     = htonl(STp->first_data_ppos);
  384. par->last_frame_ppos      = htonl(STp->capacity);
  385. aux->frame_seq_num        = htonl(frame_seq_number);
  386. aux->logical_blk_num_high = htonl(0);
  387. aux->logical_blk_num      = htonl(logical_blk_num);
  388. break;
  389.   default: ; /* probably FILL */
  390. }
  391. aux->filemark_cnt = ntohl(STp->filemark_cnt);
  392. aux->phys_fm = ntohl(0xffffffff);
  393. aux->last_mark_ppos = ntohl(STp->last_mark_ppos);
  394. aux->last_mark_lbn  = ntohl(STp->last_mark_lbn);
  395. }
  396. /*
  397.  * Verify that we have the correct tape frame
  398.  */
  399. static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet)
  400. {
  401. os_aux_t       * aux  = STp->buffer->aux;
  402. os_partition_t * par  = &(aux->partition);
  403. ST_partstat    * STps = &(STp->ps[STp->partition]);
  404. int  dev  = TAPE_NR(STp->devt);
  405. int  blk_cnt, blk_sz, i;
  406. if (STp->raw) {
  407. if (STp->buffer->syscall_result) {
  408. for (i=0; i < STp->buffer->sg_segs; i++)
  409. memset(STp->buffer->sg[i].address, 0, STp->buffer->sg[i].length);
  410. strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
  411.                 } else
  412. STp->buffer->buffer_bytes = OS_FRAME_SIZE;
  413. return 1;
  414. }
  415. if (STp->buffer->syscall_result) {
  416. #if DEBUG
  417. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, read errorn", dev);
  418. #endif
  419. return 0;
  420. }
  421. if (ntohl(aux->format_id) != 0) {
  422. #if DEBUG
  423. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, format_id %un", dev, ntohl(aux->format_id));
  424. #endif
  425. goto err_out;
  426. }
  427. if (memcmp(aux->application_sig, STp->application_sig, 4) != 0 &&
  428.     (memcmp(aux->application_sig, "LIN3", 4) != 0 || STp->linux_media_version != 4)) {
  429. #if DEBUG
  430. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, incorrect application signaturen", dev);
  431. #endif
  432. goto err_out;
  433. }
  434. if (par->partition_num != OS_DATA_PARTITION) {
  435. if (!STp->linux_media || STp->linux_media_version != 2) {
  436. #if DEBUG
  437. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition num %dn",
  438.     dev, par->partition_num);
  439. #endif
  440. goto err_out;
  441. }
  442. }
  443. if (par->par_desc_ver != OS_PARTITION_VERSION) {
  444. #if DEBUG
  445. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, partition version %dn", dev, par->par_desc_ver);
  446. #endif
  447. goto err_out;
  448. }
  449. if (ntohs(par->wrt_pass_cntr) != STp->wrt_pass_cntr) {
  450. #if DEBUG
  451. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, wrt_pass_cntr %d (expected %d)n", 
  452.     dev, ntohs(par->wrt_pass_cntr), STp->wrt_pass_cntr);
  453. #endif
  454. goto err_out;
  455. }
  456. if (aux->frame_type != OS_FRAME_TYPE_DATA &&
  457.     aux->frame_type != OS_FRAME_TYPE_EOD &&
  458.     aux->frame_type != OS_FRAME_TYPE_MARKER) {
  459. if (!quiet)
  460. #if DEBUG
  461. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, frame type %xn", dev, aux->frame_type);
  462. #endif
  463. goto err_out;
  464. }
  465. if (aux->frame_type == OS_FRAME_TYPE_EOD &&
  466.     STp->first_frame_position < STp->eod_frame_ppos) {
  467. printk(KERN_INFO "osst%d:I: Skipping premature EOD frame %dn", dev,
  468.  STp->first_frame_position);
  469. goto err_out;
  470. }
  471. STp->frame_in_buffer = 1;
  472.         if (frame_seq_number != -1 && ntohl(aux->frame_seq_num) != frame_seq_number) {
  473. if (!quiet)
  474. #if DEBUG
  475. printk(OSST_DEB_MSG "osst%d:D: Skipping frame, sequence number %u (expected %d)n", 
  476.     dev, ntohl(aux->frame_seq_num), frame_seq_number);
  477. #endif
  478. goto err_out;
  479. }
  480. if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
  481. STps->eof = ST_FM_HIT;
  482. i = ntohl(aux->filemark_cnt);
  483. if (STp->header_cache != NULL && i < OS_FM_TAB_MAX && (i > STp->filemark_cnt ||
  484.     STp->first_frame_position - 1 != ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i]))) {
  485. #if DEBUG
  486. printk(OSST_DEB_MSG "osst%d:D: %s filemark %d at frame pos %dn", dev,
  487.   STp->header_cache->dat_fm_tab.fm_tab_ent[i] == 0?"Learned":"Corrected",
  488.   i, STp->first_frame_position - 1);
  489. #endif
  490. STp->header_cache->dat_fm_tab.fm_tab_ent[i] = htonl(STp->first_frame_position - 1);
  491. if (i >= STp->filemark_cnt)
  492.  STp->filemark_cnt = i+1;
  493. }
  494. }
  495. if (aux->frame_type == OS_FRAME_TYPE_EOD) {
  496. STps->eof = ST_EOD_1;
  497. }
  498. if (aux->frame_type == OS_FRAME_TYPE_DATA) {
  499.                 blk_cnt = ntohs(aux->dat.dat_list[0].blk_cnt);
  500. blk_sz  = ntohl(aux->dat.dat_list[0].blk_sz);
  501. STp->buffer->buffer_bytes = blk_cnt * blk_sz;
  502. STp->buffer->read_pointer = 0;
  503. /* See what block size was used to write file */
  504. if (STp->block_size != blk_sz && blk_sz > 0) {
  505. printk(KERN_INFO
  506.      "osst%d:I: File was written with block size %d%c, currently %d%c, adjusted to match.n",
  507.         dev, blk_sz<1024?blk_sz:blk_sz/1024,blk_sz<1024?'b':'k',
  508. STp->block_size<1024?STp->block_size:STp->block_size/1024,
  509. STp->block_size<1024?'b':'k');
  510. STp->block_size            = blk_sz;
  511. STp->buffer->buffer_blocks = OS_DATA_SIZE / blk_sz;
  512. }
  513. STps->eof = ST_NOEOF;
  514. }
  515.         STp->frame_seq_number = ntohl(aux->frame_seq_num);
  516. STp->logical_blk_num  = ntohl(aux->logical_blk_num);
  517. return 1;
  518. err_out:
  519. if (STp->read_error_frame == 0)
  520. STp->read_error_frame = STp->first_frame_position - 1;
  521. return 0;
  522. }
  523. /*
  524.  * Wait for the unit to become Ready
  525.  */
  526. static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
  527. {
  528. unsigned char cmd[MAX_COMMAND_SIZE];
  529. Scsi_Request  * SRpnt;
  530. long startwait = jiffies;
  531. #if DEBUG
  532. int dbg = debugging;
  533. int dev  = TAPE_NR(STp->devt);
  534. printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait readyn", dev);
  535. #endif
  536. memset(cmd, 0, MAX_COMMAND_SIZE);
  537. cmd[0] = TEST_UNIT_READY;
  538. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
  539. *aSRpnt = SRpnt;
  540. if (!SRpnt) return (-EBUSY);
  541. while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
  542.        (( SRpnt->sr_sense_buffer[2]  == 2 && SRpnt->sr_sense_buffer[12] == 4    &&
  543.  (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)    ) ||
  544. ( SRpnt->sr_sense_buffer[2]  == 6 && SRpnt->sr_sense_buffer[12] == 0x28 &&
  545.   SRpnt->sr_sense_buffer[13] == 0                                        )  )) {
  546. #if DEBUG
  547.     if (debugging) {
  548. printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait readyn", dev);
  549. printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a whilen", dev);
  550. debugging = 0;
  551.     }
  552. #endif
  553.     set_current_state(TASK_INTERRUPTIBLE);
  554.     schedule_timeout(HZ / 10);
  555.     memset(cmd, 0, MAX_COMMAND_SIZE);
  556.     cmd[0] = TEST_UNIT_READY;
  557.     SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
  558. }
  559. *aSRpnt = SRpnt;
  560. #if DEBUG
  561. debugging = dbg;
  562. #endif
  563. if ( STp->buffer->syscall_result &&
  564.      osst_write_error_recovery(STp, aSRpnt, 0) ) {
  565. #if DEBUG
  566.     printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait readyn", dev);
  567.     printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02xn", dev,
  568. STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
  569. SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
  570. #endif
  571.     return (-EIO);
  572. }
  573. #if DEBUG
  574. printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait readyn", dev);
  575. #endif
  576. return 0;
  577. }
  578. /*
  579.  * Wait for a tape to be inserted in the unit
  580.  */
  581. static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
  582. {
  583. unsigned char cmd[MAX_COMMAND_SIZE];
  584. Scsi_Request  * SRpnt;
  585. long startwait = jiffies;
  586. #if DEBUG
  587. int dbg = debugging;
  588. int dev  = TAPE_NR(STp->devt);
  589. printk(OSST_DEB_MSG "osst%d:D: Reached onstream wait for mediumn", dev);
  590. #endif
  591. memset(cmd, 0, MAX_COMMAND_SIZE);
  592. cmd[0] = TEST_UNIT_READY;
  593. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
  594. *aSRpnt = SRpnt;
  595. if (!SRpnt) return (-EBUSY);
  596. while ( STp->buffer->syscall_result && time_before(jiffies, startwait + timeout*HZ) &&
  597. SRpnt->sr_sense_buffer[2]  == 2 && SRpnt->sr_sense_buffer[12] == 0x3a       &&
  598.         SRpnt->sr_sense_buffer[13] == 0                                             ) {
  599. #if DEBUG
  600.     if (debugging) {
  601. printk(OSST_DEB_MSG "osst%d:D: Sleeping in onstream wait mediumn", dev);
  602. printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a whilen", dev);
  603. debugging = 0;
  604.     }
  605. #endif
  606.     set_current_state(TASK_INTERRUPTIBLE);
  607.     schedule_timeout(HZ / 10);
  608.     memset(cmd, 0, MAX_COMMAND_SIZE);
  609.     cmd[0] = TEST_UNIT_READY;
  610.     SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
  611. }
  612. *aSRpnt = SRpnt;
  613. #if DEBUG
  614. debugging = dbg;
  615. #endif
  616. if ( STp->buffer->syscall_result     && SRpnt->sr_sense_buffer[2]  != 2 &&
  617.      SRpnt->sr_sense_buffer[12] != 4 && SRpnt->sr_sense_buffer[13] == 1) {
  618. #if DEBUG
  619.     printk(OSST_DEB_MSG "osst%d:D: Abnormal exit from onstream wait mediumn", dev);
  620.     printk(OSST_DEB_MSG "osst%d:D: Result = %d, Sense: 0=%02x, 2=%02x, 12=%02x, 13=%02xn", dev,
  621. STp->buffer->syscall_result, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
  622. SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
  623. #endif
  624.     return 0;
  625. }
  626. #if DEBUG
  627. printk(OSST_DEB_MSG "osst%d:D: Normal exit from onstream wait mediumn", dev);
  628. #endif
  629. return 1;
  630. }
  631. static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame)
  632. {
  633. int retval;
  634. osst_wait_ready(STp, aSRpnt, 15 * 60); /* TODO - can this catch a write error? */
  635. retval = osst_set_frame_position(STp, aSRpnt, frame, 0);
  636. if (retval) return (retval);
  637. osst_wait_ready(STp, aSRpnt, 15 * 60);
  638. return (osst_get_frame_position(STp, aSRpnt));
  639. }
  640. /*
  641.  * Wait for write(s) to complete
  642.  */
  643. static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  644. {
  645. unsigned char cmd[MAX_COMMAND_SIZE];
  646. Scsi_Request  * SRpnt;
  647. int             result = 0;
  648. #if DEBUG
  649. int dev  = TAPE_NR(STp->devt);
  650. printk(OSST_DEB_MSG "osst%d:D: Reached onstream flush drive buffer (write filemark)n", dev);
  651. #endif
  652. memset(cmd, 0, MAX_COMMAND_SIZE);
  653. cmd[0] = WRITE_FILEMARKS;
  654. cmd[1] = 1;
  655. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE);
  656. *aSRpnt = SRpnt;
  657. if (!SRpnt) return (-EBUSY);
  658. if ((STp->buffer)->syscall_result)
  659. result = osst_write_error_recovery(STp, aSRpnt, 0);
  660. result |= osst_wait_ready(STp, aSRpnt, 5 * 60);
  661. STp->ps[STp->partition].rw = OS_WRITING_COMPLETE;
  662. return (result);
  663. }
  664. #define OSST_POLL_PER_SEC 10
  665. static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to)
  666. {
  667. long startwait     = jiffies;
  668. int dev       = TAPE_NR(STp->devt);
  669. #if DEBUG
  670. char notyetprinted = 1;
  671. #endif
  672. if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
  673. printk(KERN_ERR "osst%i:A: Waiting for frame without having initialized read!n", dev);
  674. while (time_before (jiffies, startwait + to*HZ))
  675. int result;
  676. result = osst_get_frame_position (STp, aSRpnt);
  677. if (result == -EIO)
  678. if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
  679. return 0; /* successful recovery leaves drive ready for frame */
  680. if (result < 0) break;
  681. if (STp->first_frame_position == curr &&
  682.     ((minlast < 0 &&
  683.       (signed)STp->last_frame_position > (signed)curr + minlast) ||
  684.      (minlast >= 0 && STp->cur_frames > minlast)
  685.     ) && result >= 0)
  686. {
  687. #if DEBUG
  688. if (debugging || jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC)
  689. printk (OSST_DEB_MSG
  690. "osst%d:D: Succ wait f fr %i (>%i): %i-%i %i (%i): %3li.%li sn",
  691. dev, curr, curr+minlast, STp->first_frame_position,
  692. STp->last_frame_position, STp->cur_frames,
  693. result, (jiffies-startwait)/HZ, 
  694. (((jiffies-startwait)%HZ)*10)/HZ);
  695. #endif
  696. return 0;
  697. }
  698. #if DEBUG
  699. if (jiffies - startwait >= 2*HZ/OSST_POLL_PER_SEC && notyetprinted)
  700. {
  701. printk (OSST_DEB_MSG "osst%d:D: Wait for frame %i (>%i): %i-%i %i (%i)n",
  702. dev, curr, curr+minlast, STp->first_frame_position,
  703. STp->last_frame_position, STp->cur_frames, result);
  704. notyetprinted--;
  705. }
  706. #endif
  707. set_current_state(TASK_INTERRUPTIBLE);
  708. schedule_timeout (HZ / OSST_POLL_PER_SEC);
  709. }
  710. #if DEBUG
  711. printk (OSST_DEB_MSG "osst%d:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li sn",
  712. dev, curr, curr+minlast, STp->first_frame_position,
  713. STp->last_frame_position, STp->cur_frames,
  714. (jiffies-startwait)/HZ, (((jiffies-startwait)%HZ)*10)/HZ);
  715. #endif
  716. return -EBUSY;
  717. }
  718. /*
  719.  * Read the next OnStream tape frame at the current location
  720.  */
  721. static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout)
  722. {
  723. unsigned char cmd[MAX_COMMAND_SIZE];
  724. Scsi_Request  * SRpnt;
  725. int retval = 0;
  726. #if DEBUG
  727. os_aux_t      * aux    = STp->buffer->aux;
  728. int dev    = TAPE_NR(STp->devt);
  729. #endif
  730. /* TODO: Error handling */
  731. if (STp->poll)
  732. retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);
  733. #if 0// DEBUG
  734. printk ("osst_read: wait for frame returned %in", retval);
  735. #endif
  736. memset(cmd, 0, MAX_COMMAND_SIZE);
  737. cmd[0] = READ_6;
  738. cmd[1] = 1;
  739. cmd[4] = 1;
  740. #if DEBUG
  741. if (debugging)
  742.     printk(OSST_DEB_MSG "osst%d:D: Reading frame from OnStream tapen", dev);
  743. #endif
  744. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
  745.       STp->timeout, MAX_RETRIES, TRUE);
  746. *aSRpnt = SRpnt;
  747. if (!SRpnt)
  748.     return (-EBUSY);
  749. if ((STp->buffer)->syscall_result) {
  750.     retval = 1;
  751.     if (STp->read_error_frame == 0) {
  752. STp->read_error_frame = STp->first_frame_position;
  753. #if DEBUG
  754. printk(OSST_DEB_MSG "osst%d:D: Recording read error at %dn", dev, STp->read_error_frame);
  755. #endif
  756.     }
  757. #if DEBUG
  758.     if (debugging)
  759. printk(OSST_DEB_MSG "osst%d:D: Sense: %2x %2x %2x %2x %2x %2x %2x %2xn",
  760.    dev,
  761.    SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
  762.    SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
  763.    SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
  764.    SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]);
  765. #endif
  766. }
  767. else
  768.     STp->first_frame_position++;
  769. #if DEBUG
  770. if (debugging) {
  771.    printk(OSST_DEB_MSG 
  772. "osst%d:D: AUX: %c%c%c%c UpdFrCt#%d Wpass#%d %s FrSeq#%d LogBlk#%d Qty=%d Sz=%dn", dev,
  773. aux->application_sig[0], aux->application_sig[1],
  774. aux->application_sig[2], aux->application_sig[3], 
  775. ntohl(aux->update_frame_cntr), ntohs(aux->partition.wrt_pass_cntr),
  776. aux->frame_type==1?"EOD":aux->frame_type==2?"MARK":
  777. aux->frame_type==8?"HEADR":aux->frame_type==0x80?"DATA":"FILL", 
  778. ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
  779. ntohs(aux->dat.dat_list[0].blk_cnt), ntohl(aux->dat.dat_list[0].blk_sz) );
  780.    if (aux->frame_type==2)
  781. printk(OSST_DEB_MSG "osst%d:D: mark_cnt=%d, last_mark_ppos=%d, last_mark_lbn=%dn", dev,
  782. ntohl(aux->filemark_cnt), ntohl(aux->last_mark_ppos), ntohl(aux->last_mark_lbn));
  783.    printk(OSST_DEB_MSG "osst%d:D: Exit read frame from OnStream tape with code %dn", dev, retval);
  784. }
  785. #endif
  786. return (retval);
  787. }
  788. static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  789. {
  790. ST_partstat   * STps   = &(STp->ps[STp->partition]);
  791. Scsi_Request  * SRpnt  ;
  792. unsigned char cmd[MAX_COMMAND_SIZE];
  793. int retval = 0;
  794. #if DEBUG
  795. int dev    = TAPE_NR(STp->devt);
  796. #endif
  797. if (STps->rw != ST_READING) {         /* Initialize read operation */
  798. if (STps->rw == ST_WRITING) {
  799.                         osst_flush_write_buffer(STp, aSRpnt);
  800. osst_flush_drive_buffer(STp, aSRpnt);
  801. }
  802. STps->rw = ST_READING;
  803. STp->frame_in_buffer = 0;
  804. /*
  805.  *      Issue a read 0 command to get the OnStream drive
  806.                  *      read frames into its buffer.
  807.  */
  808. memset(cmd, 0, MAX_COMMAND_SIZE);
  809. cmd[0] = READ_6;
  810. cmd[1] = 1;
  811. #if DEBUG
  812. printk(OSST_DEB_MSG "osst%d:D: Start Read Ahead on OnStream tapen", dev);
  813. #endif
  814. SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
  815. *aSRpnt = SRpnt;
  816. retval  = STp->buffer->syscall_result;
  817. }
  818. return retval;
  819. }
  820. static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet)
  821. {
  822. ST_partstat * STps  = &(STp->ps[STp->partition]);
  823. int           dev   = TAPE_NR(STp->devt);
  824. int           cnt   = 0,
  825.       bad   = 0,
  826.       past  = 0,
  827.       x,
  828.       position;
  829. /*
  830.          * Search and wait for the next logical tape frame
  831.  */
  832. while (1) {
  833. if (cnt++ > 400) {
  834.                         printk(KERN_ERR "osst%d:E: Couldn't find logical frame %d, abortingn",
  835.     dev, frame_seq_number);
  836. if (STp->read_error_frame) {
  837. osst_set_frame_position(STp, aSRpnt, STp->read_error_frame, 0);
  838. #if DEBUG
  839.                          printk(OSST_DEB_MSG "osst%d:D: Repositioning tape to bad frame %dn",
  840.     dev, STp->read_error_frame);
  841. #endif
  842. STp->read_error_frame = 0;
  843. }
  844. return (-EIO);
  845. }
  846. #if DEBUG
  847. if (debugging)
  848. printk(OSST_DEB_MSG "osst%d:D: Looking for frame %d, attempt %dn",
  849.   dev, frame_seq_number, cnt);
  850. #endif
  851. if ( osst_initiate_read(STp, aSRpnt)
  852.                 || ( (!STp->frame_in_buffer) && osst_read_frame(STp, aSRpnt, 30) ) ) {
  853. if (STp->raw)
  854. return (-EIO);
  855. position = osst_get_frame_position(STp, aSRpnt);
  856. if (position >= 0xbae && position < 0xbb8)
  857. position = 0xbb8;
  858. else if (position > STp->eod_frame_ppos || ++bad == 10) {
  859. position = STp->read_error_frame - 1;
  860. }
  861. else {
  862. position += 39;
  863. cnt += 20;
  864. }
  865. #if DEBUG
  866. printk(OSST_DEB_MSG "osst%d:D: Bad frame detected, positioning tape to block %dn",
  867.  dev, position);
  868. #endif
  869. osst_set_frame_position(STp, aSRpnt, position, 0);
  870. continue;
  871. }
  872. if (osst_verify_frame(STp, frame_seq_number, quiet))
  873. break;
  874. if (osst_verify_frame(STp, -1, quiet)) {
  875. x = ntohl(STp->buffer->aux->frame_seq_num);
  876. if (STp->fast_open) {
  877. printk(KERN_WARNING
  878.        "osst%d:W: Found logical frame %d instead of %d after fast openn",
  879.        dev, x, frame_seq_number);
  880. STp->header_ok = 0;
  881. STp->read_error_frame = 0;
  882. return (-EIO);
  883. }
  884. if (x > frame_seq_number) {
  885. if (++past > 3) {
  886. /* positioning backwards did not bring us to the desired frame */
  887. position = STp->read_error_frame - 1;
  888. }
  889. else {
  890.          position = osst_get_frame_position(STp, aSRpnt)
  891.          + frame_seq_number - x - 1;
  892. if (STp->first_frame_position >= 3000 && position < 3000)
  893. position -= 10;
  894. }
  895. #if DEBUG
  896.                                 printk(OSST_DEB_MSG
  897.        "osst%d:D: Found logical frame %d while looking for %d: back up %dn",
  898. dev, x, frame_seq_number,
  899.         STp->first_frame_position - position);
  900. #endif
  901.                          osst_set_frame_position(STp, aSRpnt, position, 0);
  902. cnt += 10;
  903. }
  904. else
  905. past = 0;
  906. }
  907. if (osst_get_frame_position(STp, aSRpnt) == 0xbaf) {
  908. #if DEBUG
  909. printk(OSST_DEB_MSG "osst%d:D: Skipping config partitionn", dev);
  910. #endif
  911. osst_set_frame_position(STp, aSRpnt, 0xbb8, 0);
  912. cnt--;
  913. }
  914. STp->frame_in_buffer = 0;
  915. }
  916. if (cnt > 1) {
  917. STp->recover_count++;
  918. STp->recover_erreg++;
  919. printk(KERN_WARNING "osst%d:I: Don't worry, Read error at position %d recoveredn", 
  920. dev, STp->read_error_frame);
  921.   }
  922. STp->read_count++;
  923. #if DEBUG
  924. if (debugging || STps->eof)
  925. printk(OSST_DEB_MSG
  926. "osst%d:D: Exit get logical frame (%d=>%d) from OnStream tape with code %dn",
  927. dev, frame_seq_number, STp->frame_seq_number, STps->eof);
  928. #endif
  929. STp->fast_open = FALSE;
  930. STp->read_error_frame = 0;
  931. return (STps->eof);
  932. }
  933. static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num)
  934. {
  935.         ST_partstat * STps = &(STp->ps[STp->partition]);
  936. int dev        = TAPE_NR(STp->devt);
  937. int retries    = 0;
  938. int frame_seq_estimate, ppos_estimate, move;
  939. if (logical_blk_num < 0) logical_blk_num = 0;
  940. #if DEBUG
  941. printk(OSST_DEB_MSG "osst%d:D: Seeking logical block %d (now at %d, size %d%c)n",
  942. dev, logical_blk_num, STp->logical_blk_num, 
  943. STp->block_size<1024?STp->block_size:STp->block_size/1024,
  944. STp->block_size<1024?'b':'k');
  945. #endif
  946. /* Do we know where we are? */
  947. if (STps->drv_block >= 0) {
  948. move                = logical_blk_num - STp->logical_blk_num;
  949. if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
  950. move               /= (OS_DATA_SIZE / STp->block_size);
  951. frame_seq_estimate  = STp->frame_seq_number + move;
  952. } else
  953. frame_seq_estimate  = logical_blk_num * STp->block_size / OS_DATA_SIZE;
  954. if (frame_seq_estimate < 2980) ppos_estimate = frame_seq_estimate + 10;
  955. else        ppos_estimate = frame_seq_estimate + 20;
  956. while (++retries < 10) {
  957.    if (ppos_estimate > STp->eod_frame_ppos-2) {
  958.        frame_seq_estimate += STp->eod_frame_ppos - 2 - ppos_estimate;
  959.        ppos_estimate       = STp->eod_frame_ppos - 2;
  960.    }
  961.    if (frame_seq_estimate < 0) {
  962.        frame_seq_estimate = 0;
  963.        ppos_estimate      = 10;
  964.    }
  965.    osst_set_frame_position(STp, aSRpnt, ppos_estimate, 0);
  966.    if (osst_get_logical_frame(STp, aSRpnt, frame_seq_estimate, 1) >= 0) {
  967.       /* we've located the estimated frame, now does it have our block? */
  968.       if (logical_blk_num <  STp->logical_blk_num ||
  969.           logical_blk_num >= STp->logical_blk_num + ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt)) {
  970.  if (STps->eof == ST_FM_HIT)
  971.     move = logical_blk_num < STp->logical_blk_num? -2 : 1;
  972.  else {
  973.     move                = logical_blk_num - STp->logical_blk_num;
  974.     if (move < 0) move -= (OS_DATA_SIZE / STp->block_size) - 1;
  975.     move               /= (OS_DATA_SIZE / STp->block_size);
  976.  }
  977. #if DEBUG
  978.  printk(OSST_DEB_MSG
  979. "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d) move %dn",
  980. dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
  981. STp->logical_blk_num, logical_blk_num, move);
  982. #endif
  983.  frame_seq_estimate += move;
  984.  ppos_estimate      += move;
  985.  continue;
  986.       } else {
  987.  STp->buffer->read_pointer  = (logical_blk_num - STp->logical_blk_num) * STp->block_size;
  988.  STp->buffer->buffer_bytes -= STp->buffer->read_pointer;
  989.  STp->logical_blk_num       =  logical_blk_num;
  990. #if DEBUG
  991.  printk(OSST_DEB_MSG 
  992. "osst%d:D: Seek success at ppos %d fsq %d in_buf %d, bytes %d, ptr %d*%dn",
  993. dev, ppos_estimate, STp->frame_seq_number, STp->frame_in_buffer, 
  994. STp->buffer->buffer_bytes, STp->buffer->read_pointer / STp->block_size, 
  995. STp->block_size);
  996. #endif
  997.  STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
  998.  if (STps->eof == ST_FM_HIT) {
  999.      STps->drv_file++;
  1000.      STps->drv_block = 0;
  1001.  } else {
  1002.      STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
  1003.   STp->logical_blk_num -
  1004.      (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
  1005. -1;
  1006.  }
  1007.  STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
  1008.  return 0;
  1009.       }
  1010.    }
  1011.    if (osst_get_logical_frame(STp, aSRpnt, -1, 1) < 0)
  1012.       goto error;
  1013.    /* we are not yet at the estimated frame, adjust our estimate of its physical position */
  1014. #if DEBUG
  1015.    printk(OSST_DEB_MSG "osst%d:D: Seek retry %d at ppos %d fsq %d (est %d) lbn %d (need %d)n", 
  1016.    dev, retries, ppos_estimate, STp->frame_seq_number, frame_seq_estimate, 
  1017.    STp->logical_blk_num, logical_blk_num);
  1018. #endif
  1019.    if (frame_seq_estimate != STp->frame_seq_number)
  1020.       ppos_estimate += frame_seq_estimate - STp->frame_seq_number;
  1021.    else
  1022.       break;
  1023. }
  1024. error:
  1025. printk(KERN_ERR "osst%d:E: Couldn't seek to logical block %d (at %d), %d retriesn", 
  1026.     dev, logical_blk_num, STp->logical_blk_num, retries);
  1027. return (-EIO);
  1028. }
  1029. /* The values below are based on the OnStream frame payload size of 32K == 2**15,
  1030.  * that is, OSST_FRAME_SHIFT + OSST_SECTOR_SHIFT must be 15. With a minimum block
  1031.  * size of 512 bytes, we need to be able to resolve 32K/512 == 64 == 2**6 positions
  1032.  * inside each frame. Finaly, OSST_SECTOR_MASK == 2**OSST_FRAME_SHIFT - 1.
  1033.  */
  1034. #define OSST_FRAME_SHIFT  6
  1035. #define OSST_SECTOR_SHIFT 9
  1036. #define OSST_SECTOR_MASK  0x03F
  1037. static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  1038. {
  1039. int sector;
  1040. #if DEBUG
  1041. int dev = TAPE_NR(STp->devt);
  1042. printk(OSST_DEB_MSG 
  1043. "osst%d:D: Positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, %cptr %d, eof %dn",
  1044. dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
  1045. STp->ps[STp->partition].drv_file, STp->ps[STp->partition].drv_block, 
  1046. STp->ps[STp->partition].rw == ST_WRITING?'w':'r',
  1047. STp->ps[STp->partition].rw == ST_WRITING?STp->buffer->buffer_bytes:
  1048. STp->buffer->read_pointer, STp->ps[STp->partition].eof);
  1049. #endif
  1050. /* do we know where we are inside a file? */
  1051. if (STp->ps[STp->partition].drv_block >= 0) {
  1052. sector = (STp->frame_in_buffer ? STp->first_frame_position-1 :
  1053. STp->first_frame_position) << OSST_FRAME_SHIFT;
  1054. if (STp->ps[STp->partition].rw == ST_WRITING)
  1055.         sector |= (STp->buffer->buffer_bytes >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
  1056. else
  1057.         sector |= (STp->buffer->read_pointer >> OSST_SECTOR_SHIFT) & OSST_SECTOR_MASK;
  1058. } else {
  1059. sector = osst_get_frame_position(STp, aSRpnt);
  1060. if (sector > 0)
  1061. sector <<= OSST_FRAME_SHIFT;
  1062. }
  1063. return sector;
  1064. }
  1065. static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector)
  1066. {
  1067.         ST_partstat   * STps   = &(STp->ps[STp->partition]);
  1068. int frame  = sector >> OSST_FRAME_SHIFT,
  1069. offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
  1070. r;
  1071. #if DEBUG
  1072. int dev    = TAPE_NR(STp->devt);
  1073. printk(OSST_DEB_MSG "osst%d:D: Seeking sector %d in frame %d at offset %dn",
  1074. dev, sector, frame, offset);
  1075. #endif
  1076. if (frame < 0 || frame >= STp->capacity) return (-ENXIO);
  1077. if (frame <= STp->first_data_ppos) {
  1078. STp->frame_seq_number = STp->logical_blk_num = STps->drv_file = STps->drv_block = 0;
  1079. return (osst_set_frame_position(STp, aSRpnt, frame, 0));
  1080. }
  1081. r = osst_set_frame_position(STp, aSRpnt, offset?frame:frame-1, 0);
  1082. if (r < 0) return r;
  1083. r = osst_get_logical_frame(STp, aSRpnt, -1, 1);
  1084. if (r < 0) return r;
  1085. if (osst_get_frame_position(STp, aSRpnt) != (offset?frame+1:frame)) return (-EIO);
  1086. if (offset) {
  1087. STp->logical_blk_num      += offset / STp->block_size;
  1088. STp->buffer->read_pointer  = offset;
  1089. STp->buffer->buffer_bytes -= offset;
  1090. } else {
  1091. STp->frame_seq_number++;
  1092. STp->frame_in_buffer       = 0;
  1093. STp->logical_blk_num      += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
  1094. STp->buffer->buffer_bytes  = STp->buffer->read_pointer = 0;
  1095. }
  1096. STps->drv_file = ntohl(STp->buffer->aux->filemark_cnt);
  1097. if (STps->eof == ST_FM_HIT) {
  1098. STps->drv_file++;
  1099. STps->drv_block = 0;
  1100. } else {
  1101. STps->drv_block = ntohl(STp->buffer->aux->last_mark_lbn)?
  1102.     STp->logical_blk_num -
  1103. (STps->drv_file ? ntohl(STp->buffer->aux->last_mark_lbn) + 1 : 0):
  1104.   -1;
  1105. }
  1106. STps->eof       = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_NOEOF;
  1107. #if DEBUG
  1108. printk(OSST_DEB_MSG 
  1109. "osst%d:D: Now positioned at ppos %d, frame %d, lbn %d, file %d, blk %d, rptr %d, eof %dn",
  1110. dev, STp->first_frame_position, STp->frame_seq_number, STp->logical_blk_num,
  1111. STps->drv_file, STps->drv_block, STp->buffer->read_pointer, STps->eof);
  1112. #endif
  1113. return 0;
  1114. }
  1115. /*
  1116.  * Read back the drive's internal buffer contents, as a part
  1117.  * of the write error recovery mechanism for old OnStream
  1118.  * firmware revisions.
  1119.  * Precondition for this function to work: all frames in the
  1120.  * drive's buffer must be of one type (DATA, MARK or EOD)!
  1121.  */
  1122. static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
  1123. unsigned int frame, unsigned int skip, int pending)
  1124. {
  1125. Scsi_Request  * SRpnt = * aSRpnt;
  1126. unsigned char * buffer, * p;
  1127. unsigned char cmd[MAX_COMMAND_SIZE];
  1128. int             flag, new_frame, i;
  1129. int             nframes          = STp->cur_frames;
  1130. int             blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
  1131. int             frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
  1132. - (nframes + pending - 1);
  1133. int             logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
  1134. - (nframes + pending - 1) * blks_per_frame;
  1135. int dev              = TAPE_NR(STp->devt);
  1136. long startwait        = jiffies;
  1137. #if DEBUG
  1138. int dbg              = debugging;
  1139. #endif
  1140. if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
  1141. return (-EIO);
  1142. printk(KERN_INFO "osst%d:I: Reading back %d frames from drive buffer%sn",
  1143.  dev, nframes, pending?" and one that was pending":"");
  1144. osst_copy_from_buffer(STp->buffer, (p = &buffer[nframes * OS_DATA_SIZE]));
  1145. #if DEBUG
  1146. if (pending && debugging)
  1147. printk(OSST_DEB_MSG "osst%d:D: Pending frame %d (lblk %d), data %02x %02x %02x %02xn",
  1148. dev, frame_seq_number + nframes,
  1149.         logical_blk_num + nframes * blks_per_frame,
  1150.         p[0], p[1], p[2], p[3]);
  1151. #endif
  1152. for (i = 0, p = buffer; i < nframes; i++, p += OS_DATA_SIZE) {
  1153. memset(cmd, 0, MAX_COMMAND_SIZE);
  1154. cmd[0] = 0x3C; /* Buffer Read           */
  1155. cmd[1] = 6; /* Retrieve Faulty Block */
  1156. cmd[7] = 32768 >> 8;
  1157. cmd[8] = 32768 & 0xff;
  1158. SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
  1159.     STp->timeout, MAX_RETRIES, TRUE);
  1160. if ((STp->buffer)->syscall_result || !SRpnt) {
  1161. printk(KERN_ERR "osst%d:E: Failed to read frame back from OnStream buffern", dev);
  1162. vfree((void *)buffer);
  1163. *aSRpnt = SRpnt;
  1164. return (-EIO);
  1165. }
  1166. osst_copy_from_buffer(STp->buffer, p);
  1167. #if DEBUG
  1168. if (debugging)
  1169. printk(OSST_DEB_MSG "osst%d:D: Read back logical frame %d, data %02x %02x %02x %02xn",
  1170.   dev, frame_seq_number + i, p[0], p[1], p[2], p[3]);
  1171. #endif
  1172. }
  1173. *aSRpnt = SRpnt;
  1174. osst_get_frame_position(STp, aSRpnt);
  1175. #if DEBUG
  1176. printk(OSST_DEB_MSG "osst%d:D: Frames left in buffer: %dn", dev, STp->cur_frames);
  1177. #endif
  1178. /* Write synchronously so we can be sure we're OK again and don't have to recover recursively */
  1179. /* In the header we don't actually re-write the frames that fail, just the ones after them */
  1180. for (flag=1, new_frame=frame, p=buffer, i=0; i < nframes + pending; ) {
  1181. if (flag) {
  1182. if (STp->write_type == OS_WRITE_HEADER) {
  1183. i += skip;
  1184. p += skip * OS_DATA_SIZE;
  1185. }
  1186. else if (new_frame < 2990 && new_frame+skip+nframes+pending >= 2990)
  1187. new_frame = 3000-i;
  1188. else
  1189. new_frame += skip;
  1190. #if DEBUG
  1191. printk(OSST_DEB_MSG "osst%d:D: Position to frame %d, write fseq %dn",
  1192. dev, new_frame+i, frame_seq_number+i);
  1193. #endif
  1194. osst_set_frame_position(STp, aSRpnt, new_frame + i, 0);
  1195. osst_wait_ready(STp, aSRpnt, 60);
  1196. osst_get_frame_position(STp, aSRpnt);
  1197. SRpnt = * aSRpnt;
  1198. if (new_frame > frame + 1000) {
  1199. printk(KERN_ERR "osst%d:E: Failed to find writable tape median", dev);
  1200. vfree((void *)buffer);
  1201. return (-EIO);
  1202. }
  1203. flag = 0;
  1204. if ( i >= nframes + pending ) break;
  1205. }
  1206. osst_copy_to_buffer(STp->buffer, p);
  1207. /*
  1208.  * IMPORTANT: for error recovery to work, _never_ queue frames with mixed frame type!
  1209.  */
  1210. osst_init_aux(STp, STp->buffer->aux->frame_type, frame_seq_number+i,
  1211.         logical_blk_num + i*blks_per_frame,
  1212.         ntohl(STp->buffer->aux->dat.dat_list[0].blk_sz), blks_per_frame);
  1213. memset(cmd, 0, MAX_COMMAND_SIZE);
  1214. cmd[0] = WRITE_6;
  1215. cmd[1] = 1;
  1216. cmd[4] = 1;
  1217. #if DEBUG
  1218. if (debugging)
  1219. printk(OSST_DEB_MSG
  1220. "osst%d:D: About to write frame %d, seq %d, lbn %d, data %02x %02x %02x %02xn",
  1221. dev, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame,
  1222. p[0], p[1], p[2], p[3]);
  1223. #endif
  1224. SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
  1225.     STp->timeout, MAX_WRITE_RETRIES, TRUE);
  1226. if (STp->buffer->syscall_result)
  1227. flag = 1;
  1228. else {
  1229. p += OS_DATA_SIZE; i++;
  1230. /* if we just sent the last frame, wait till all successfully written */
  1231. if ( i == nframes + pending ) {
  1232. #if DEBUG
  1233. printk(OSST_DEB_MSG "osst%d:D: Check re-write successfuln", dev);
  1234. #endif
  1235. memset(cmd, 0, MAX_COMMAND_SIZE);
  1236. cmd[0] = WRITE_FILEMARKS;
  1237. cmd[1] = 1;
  1238. SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
  1239.     STp->timeout, MAX_WRITE_RETRIES, TRUE);
  1240. #if DEBUG
  1241. if (debugging) {
  1242. printk(OSST_DEB_MSG "osst%d:D: Sleeping in re-write wait readyn", dev);
  1243. printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a whilen", dev);
  1244. debugging = 0;
  1245. }
  1246. #endif
  1247. flag = STp->buffer->syscall_result;
  1248. while ( !flag && time_before(jiffies, startwait + 60*HZ) ) {
  1249. memset(cmd, 0, MAX_COMMAND_SIZE);
  1250. cmd[0] = TEST_UNIT_READY;
  1251. SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout,
  1252.  MAX_READY_RETRIES, TRUE);
  1253. if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
  1254.     (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
  1255. /* in the process of becoming ready */
  1256. schedule_timeout(HZ / 10);
  1257. continue;
  1258. }
  1259. if (STp->buffer->syscall_result)
  1260. flag = 1;
  1261. break;
  1262. }
  1263. #if DEBUG
  1264. debugging = dbg;
  1265. printk(OSST_DEB_MSG "osst%d:D: Wait re-write finishedn", dev);
  1266. #endif
  1267. }
  1268. }
  1269. *aSRpnt = SRpnt;
  1270. if (flag) {
  1271. if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
  1272.      SRpnt->sr_sense_buffer[12]         ==  0 &&
  1273.      SRpnt->sr_sense_buffer[13]         ==  2) {
  1274. printk(KERN_ERR "osst%d:E: Volume overflow in write error recoveryn", dev);
  1275. vfree((void *)buffer);
  1276. return (-EIO); /* hit end of tape = fail */
  1277. }
  1278. i = ((SRpnt->sr_sense_buffer[3] << 24) |
  1279.      (SRpnt->sr_sense_buffer[4] << 16) |
  1280.      (SRpnt->sr_sense_buffer[5] <<  8) |
  1281.       SRpnt->sr_sense_buffer[6]        ) - new_frame;
  1282. p = &buffer[i * OS_DATA_SIZE];
  1283. #if DEBUG
  1284. printk(OSST_DEB_MSG "osst%d:D: Additional write error at %dn", dev, new_frame+i);
  1285. #endif
  1286. osst_get_frame_position(STp, aSRpnt);
  1287. #if DEBUG
  1288. printk(OSST_DEB_MSG "osst%d:D: reported frame positions: host = %d, tape = %dn",
  1289.   dev, STp->first_frame_position, STp->last_frame_position);
  1290. #endif
  1291. }
  1292. }    
  1293. if (!pending)
  1294. osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */
  1295. vfree((void *)buffer);
  1296. return 0;
  1297. }
  1298. static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
  1299. unsigned int frame, unsigned int skip, int pending)
  1300. {
  1301. unsigned char cmd[MAX_COMMAND_SIZE];
  1302. Scsi_Request  * SRpnt;
  1303. int dev       = TAPE_NR(STp->devt);
  1304. int expected  = 0;
  1305. int attempts  = 1000 / skip;
  1306. int flag      = 1;
  1307. long startwait = jiffies;
  1308. #if DEBUG
  1309. int dbg       = debugging;
  1310. #endif
  1311. while (attempts && time_before(jiffies, startwait + 60*HZ)) {
  1312. if (flag) {
  1313. #if DEBUG
  1314. debugging = dbg;
  1315. #endif
  1316. if (frame < 2990 && frame+skip+STp->cur_frames+pending >= 2990)
  1317. frame = 3000-skip;
  1318. expected = frame+skip+STp->cur_frames+pending;
  1319. #if DEBUG
  1320. printk(OSST_DEB_MSG "osst%d:D: Position to fppos %d, re-write from fseq %dn",
  1321.   dev, frame+skip, STp->frame_seq_number-STp->cur_frames-pending);
  1322. #endif
  1323. osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
  1324. flag = 0;
  1325. attempts--;
  1326. }
  1327. if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
  1328. #if DEBUG
  1329. printk(OSST_DEB_MSG "osst%d:D: Addl error, host %d, tape %d, buffer %dn",
  1330.   dev, STp->first_frame_position,
  1331.   STp->last_frame_position, STp->cur_frames);
  1332. #endif
  1333. frame = STp->last_frame_position;
  1334. flag = 1;
  1335. continue;
  1336. }
  1337. if (pending && STp->cur_frames < 50) {
  1338. memset(cmd, 0, MAX_COMMAND_SIZE);
  1339. cmd[0] = WRITE_6;
  1340. cmd[1] = 1;
  1341. cmd[4] = 1;
  1342. #if DEBUG
  1343. printk(OSST_DEB_MSG "osst%d:D: About to write pending fseq %d at fppos %dn",
  1344.   dev, STp->frame_seq_number-1, STp->first_frame_position);
  1345. #endif
  1346. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
  1347.       STp->timeout, MAX_WRITE_RETRIES, TRUE);
  1348. *aSRpnt = SRpnt;
  1349. if (STp->buffer->syscall_result) { /* additional write error */
  1350. if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) == 13 &&
  1351.      SRpnt->sr_sense_buffer[12]         ==  0 &&
  1352.      SRpnt->sr_sense_buffer[13]         ==  2) {
  1353. printk(KERN_ERR
  1354.        "osst%d:E: Volume overflow in write error recoveryn",
  1355.        dev);
  1356. break; /* hit end of tape = fail */
  1357. }
  1358. flag = 1;
  1359. }
  1360. else
  1361. pending = 0;
  1362. continue;
  1363. }
  1364. if (STp->cur_frames == 0) {
  1365. #if DEBUG
  1366. debugging = dbg;
  1367. printk(OSST_DEB_MSG "osst%d:D: Wait re-write finishedn", dev);
  1368. #endif
  1369. if (STp->first_frame_position != expected) {
  1370. printk(KERN_ERR "osst%d:A: Actual position %d - expected %dn", 
  1371. dev, STp->first_frame_position, expected);
  1372. return (-EIO);
  1373. }
  1374. return 0;
  1375. }
  1376. #if DEBUG
  1377. if (debugging) {
  1378. printk(OSST_DEB_MSG "osst%d:D: Sleeping in re-write wait readyn", dev);
  1379. printk(OSST_DEB_MSG "osst%d:D: Turning off debugging for a whilen", dev);
  1380. debugging = 0;
  1381. }
  1382. #endif
  1383. schedule_timeout(HZ / 10);
  1384. }
  1385. printk(KERN_ERR "osst%d:E: Failed to find valid tape median", dev);
  1386. #if DEBUG
  1387. debugging = dbg;
  1388. #endif
  1389. return (-EIO);
  1390. }
  1391. /*
  1392.  * Error recovery algorithm for the OnStream tape.
  1393.  */
  1394. static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending)
  1395. {
  1396. Scsi_Request * SRpnt  = * aSRpnt;
  1397. ST_partstat  * STps   = & STp->ps[STp->partition];
  1398. int            dev    = TAPE_NR(STp->devt);
  1399. int            retval = 0;
  1400. int            rw_state;
  1401. unsigned int  frame, skip;
  1402. rw_state = STps->rw;
  1403. if ((SRpnt->sr_sense_buffer[ 2] & 0x0f) != 3
  1404.   || SRpnt->sr_sense_buffer[12]         != 12
  1405.   || SRpnt->sr_sense_buffer[13]         != 0) {
  1406. #if DEBUG
  1407. printk(OSST_DEB_MSG "osst%d:D: Write error recovery cannot handle %02x:%02x:%02xn", dev,
  1408. SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
  1409. #endif
  1410. return (-EIO);
  1411. }
  1412. frame = (SRpnt->sr_sense_buffer[3] << 24) |
  1413. (SRpnt->sr_sense_buffer[4] << 16) |
  1414. (SRpnt->sr_sense_buffer[5] <<  8) |
  1415.  SRpnt->sr_sense_buffer[6];
  1416. skip  =  SRpnt->sr_sense_buffer[9];
  1417.  
  1418. #if DEBUG
  1419. printk(OSST_DEB_MSG "osst%d:D: Detected physical bad frame at %u, advised to skip %dn", dev, frame, skip);
  1420. #endif
  1421. osst_get_frame_position(STp, aSRpnt);
  1422. #if DEBUG
  1423. printk(OSST_DEB_MSG "osst%d:D: reported frame positions: host = %d, tape = %dn",
  1424. dev, STp->first_frame_position, STp->last_frame_position);
  1425. #endif
  1426. switch (STp->write_type) {
  1427.    case OS_WRITE_DATA:
  1428.    case OS_WRITE_EOD:
  1429.    case OS_WRITE_NEW_MARK:
  1430. printk(KERN_WARNING 
  1431. "osst%d:I: Relocating %d buffered logical frames from position %u to %un",
  1432. dev, STp->cur_frames, frame, (frame + skip > 3000 && frame < 3000)?3000:frame + skip);
  1433. if (STp->os_fw_rev >= 10600)
  1434. retval = osst_reposition_and_retry(STp, aSRpnt, frame, skip, pending);
  1435. else
  1436. retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, skip, pending);
  1437. printk(KERN_WARNING "osst%d:%s: %sWrite error%srecoveredn", dev,
  1438.         retval?"E"    :"I",
  1439.         retval?""     :"Don't worry, ",
  1440.         retval?" not ":" ");
  1441. break;
  1442.    case OS_WRITE_LAST_MARK:
  1443. printk(KERN_ERR "osst%d:E: Bad frame in update last marker, fataln", dev);
  1444. osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
  1445. retval = -EIO;
  1446. break;
  1447.    case OS_WRITE_HEADER:
  1448. printk(KERN_WARNING "osst%d:I: Bad frame in header partition, skippedn", dev);
  1449. retval = osst_read_back_buffer_and_rewrite(STp, aSRpnt, frame, 1, pending);
  1450. break;
  1451.    default:
  1452. printk(KERN_INFO "osst%d:I: Bad frame in filler, ignoredn", dev);
  1453. osst_set_frame_position(STp, aSRpnt, frame + STp->cur_frames + pending, 0);
  1454. }
  1455. osst_get_frame_position(STp, aSRpnt);
  1456. #if DEBUG
  1457. printk(OSST_DEB_MSG "osst%d:D: Positioning complete, cur_frames %d, pos %d, tape pos %dn", 
  1458. dev, STp->cur_frames, STp->first_frame_position, STp->last_frame_position);
  1459. printk(OSST_DEB_MSG "osst%d:D: next logical frame to write: %dn", dev, STp->logical_blk_num);
  1460. #endif
  1461. if (retval == 0) {
  1462. STp->recover_count++;
  1463. STp->recover_erreg++;
  1464. }
  1465. STps->rw = rw_state;
  1466. return retval;
  1467. }
  1468. static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
  1469.  int mt_op, int mt_count)
  1470. {
  1471. int     dev = TAPE_NR(STp->devt);
  1472. int     cnt;
  1473. int     last_mark_ppos = -1;
  1474. #if DEBUG
  1475. printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_backwards %d %dn", dev, mt_op, mt_count);
  1476. #endif
  1477. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1478. #if DEBUG
  1479. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_bwdn", dev);
  1480. #endif
  1481. return -EIO;
  1482. }
  1483. if (STp->linux_media_version >= 4) {
  1484. /*
  1485.  * direct lookup in header filemark list
  1486.  */
  1487. cnt = ntohl(STp->buffer->aux->filemark_cnt);
  1488. if (STp->header_ok                         && 
  1489.     STp->header_cache != NULL              &&
  1490.     (cnt - mt_count)  >= 0                 &&
  1491.     (cnt - mt_count)   < OS_FM_TAB_MAX     &&
  1492.     (cnt - mt_count)   < STp->filemark_cnt &&
  1493.     STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] == STp->buffer->aux->last_mark_ppos)
  1494. last_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt - mt_count]);
  1495. #if DEBUG
  1496. if (STp->header_cache == NULL || (cnt - mt_count) < 0 || (cnt - mt_count) >= OS_FM_TAB_MAX)
  1497. printk(OSST_DEB_MSG "osst%d:D: Filemark lookup fail due to %sn", dev,
  1498.        STp->header_cache == NULL?"lack of header cache":"count out of range");
  1499. else
  1500. printk(OSST_DEB_MSG "osst%d:D: Filemark lookup: prev mark %d (%s), skip %d to %dn",
  1501. dev, cnt,
  1502. ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
  1503.  (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt-1] ==
  1504.  STp->buffer->aux->last_mark_ppos))?"match":"error",
  1505.        mt_count, last_mark_ppos);
  1506. #endif
  1507. if (last_mark_ppos > 10 && last_mark_ppos < STp->eod_frame_ppos) {
  1508. osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
  1509. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1510. #if DEBUG
  1511. printk(OSST_DEB_MSG 
  1512. "osst%d:D: Couldn't get logical blk num in space_filemarksn", dev);
  1513. #endif
  1514. return (-EIO);
  1515. }
  1516. if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
  1517. printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not foundn",
  1518.  dev, last_mark_ppos);
  1519. return (-EIO);
  1520. }
  1521. if (mt_op == MTBSFM) {
  1522. STp->frame_seq_number++;
  1523. STp->frame_in_buffer  = 0;
  1524. STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
  1525. }
  1526. return 0;
  1527. }
  1528. #if DEBUG
  1529. printk(OSST_DEB_MSG "osst%d:D: Reverting to scan filemark backwardsn", dev);
  1530. #endif
  1531. }
  1532. cnt = 0;
  1533. while (cnt != mt_count) {
  1534. last_mark_ppos = ntohl(STp->buffer->aux->last_mark_ppos);
  1535. if (last_mark_ppos == -1)
  1536. return (-EIO);
  1537. #if DEBUG
  1538. printk(OSST_DEB_MSG "osst%d:D: Positioning to last mark at %dn", dev, last_mark_ppos);
  1539. #endif
  1540. osst_position_tape_and_confirm(STp, aSRpnt, last_mark_ppos);
  1541. cnt++;
  1542. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1543. #if DEBUG
  1544. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarksn", dev);
  1545. #endif
  1546. return (-EIO);
  1547. }
  1548. if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
  1549. printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not foundn",
  1550.  dev, last_mark_ppos);
  1551. return (-EIO);
  1552. }
  1553. }
  1554. if (mt_op == MTBSFM) {
  1555. STp->frame_seq_number++;
  1556. STp->frame_in_buffer  = 0;
  1557. STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
  1558. }
  1559. return 0;
  1560. }
  1561. /*
  1562.  * ADRL 1.1 compatible "slow" space filemarks fwd version
  1563.  *
  1564.  * Just scans for the filemark sequentially.
  1565.  */
  1566. static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
  1567.      int mt_op, int mt_count)
  1568. {
  1569. int cnt = 0;
  1570. #if DEBUG
  1571. int dev = TAPE_NR(STp->devt);
  1572. printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_forward_slow %d %dn", dev, mt_op, mt_count);
  1573. #endif
  1574. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1575. #if DEBUG
  1576. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_fwdn", dev);
  1577. #endif
  1578. return (-EIO);
  1579. }
  1580. while (1) {
  1581. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1582. #if DEBUG
  1583. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarksn", dev);
  1584. #endif
  1585. return (-EIO);
  1586. }
  1587. if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
  1588. cnt++;
  1589. if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
  1590. #if DEBUG
  1591. printk(OSST_DEB_MSG "osst%d:D: space_fwd: EOD reachedn", dev);
  1592. #endif
  1593. if (STp->first_frame_position > STp->eod_frame_ppos+1) {
  1594. #if DEBUG
  1595. printk(OSST_DEB_MSG "osst%d:D: EOD position corrected (%d=>%d)n",
  1596.         dev, STp->eod_frame_ppos, STp->first_frame_position-1);
  1597. #endif
  1598. STp->eod_frame_ppos = STp->first_frame_position-1;
  1599. }
  1600. return (-EIO);
  1601. }
  1602. if (cnt == mt_count)
  1603. break;
  1604. STp->frame_in_buffer = 0;
  1605. }
  1606. if (mt_op == MTFSF) {
  1607. STp->frame_seq_number++;
  1608. STp->frame_in_buffer  = 0;
  1609. STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
  1610. }
  1611. return 0;
  1612. }
  1613. /*
  1614.  * Fast linux specific version of OnStream FSF
  1615.  */
  1616. static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
  1617.      int mt_op, int mt_count)
  1618. {
  1619. int dev = TAPE_NR(STp->devt);
  1620. int cnt = 0,
  1621. next_mark_ppos = -1;
  1622. #if DEBUG
  1623. printk(OSST_DEB_MSG "osst%d:D: Reached space_over_filemarks_forward_fast %d %dn", dev, mt_op, mt_count);
  1624. #endif
  1625. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1626. #if DEBUG
  1627. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarks_fwdn", dev);
  1628. #endif
  1629. return (-EIO);
  1630. }
  1631. if (STp->linux_media_version >= 4) {
  1632. /*
  1633.  * direct lookup in header filemark list
  1634.  */
  1635. cnt = ntohl(STp->buffer->aux->filemark_cnt) - 1;
  1636. if (STp->header_ok                         && 
  1637.     STp->header_cache != NULL              &&
  1638.     (cnt + mt_count)   < OS_FM_TAB_MAX     &&
  1639.     (cnt + mt_count)   < STp->filemark_cnt &&
  1640.     ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
  1641.      (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] == STp->buffer->aux->last_mark_ppos)))
  1642. next_mark_ppos = ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[cnt + mt_count]);
  1643. #if DEBUG
  1644. if (STp->header_cache == NULL || (cnt + mt_count) >= OS_FM_TAB_MAX)
  1645. printk(OSST_DEB_MSG "osst%d:D: Filemark lookup fail due to %sn", dev,
  1646.        STp->header_cache == NULL?"lack of header cache":"count out of range");
  1647. else
  1648. printk(OSST_DEB_MSG "osst%d:D: Filemark lookup: prev mark %d (%s), skip %d to %dn",
  1649.        dev, cnt,
  1650.        ((cnt == -1 && ntohl(STp->buffer->aux->last_mark_ppos) == -1) ||
  1651. (STp->header_cache->dat_fm_tab.fm_tab_ent[cnt] ==
  1652.  STp->buffer->aux->last_mark_ppos))?"match":"error",
  1653.        mt_count, next_mark_ppos);
  1654. #endif
  1655. if (next_mark_ppos <= 10 || next_mark_ppos > STp->eod_frame_ppos) {
  1656. #if DEBUG
  1657. printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark spacen", dev);
  1658. #endif
  1659. return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
  1660. } else {
  1661. osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
  1662. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1663. #if DEBUG
  1664. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarksn",
  1665.  dev);
  1666. #endif
  1667. return (-EIO);
  1668. }
  1669. if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
  1670. printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not foundn",
  1671.  dev, next_mark_ppos);
  1672. return (-EIO);
  1673. }
  1674. if (ntohl(STp->buffer->aux->filemark_cnt) != cnt + mt_count) {
  1675. printk(KERN_WARNING "osst%d:W: Expected to find marker %d at ppos %d, not %dn",
  1676.  dev, cnt+mt_count, next_mark_ppos,
  1677.  ntohl(STp->buffer->aux->filemark_cnt));
  1678.         return (-EIO);
  1679. }
  1680. }
  1681. } else {
  1682. /*
  1683.  * Find nearest (usually previous) marker, then jump from marker to marker
  1684.  */
  1685. while (1) {
  1686. if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER)
  1687. break;
  1688. if (STp->buffer->aux->frame_type == OS_FRAME_TYPE_EOD) {
  1689. #if DEBUG
  1690. printk(OSST_DEB_MSG "osst%d:D: space_fwd: EOD reachedn", dev);
  1691. #endif
  1692. return (-EIO);
  1693. }
  1694. if (ntohl(STp->buffer->aux->filemark_cnt) == 0) {
  1695. if (STp->first_mark_ppos == -1) {
  1696. #if DEBUG
  1697. printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark spacen", dev);
  1698. #endif
  1699. return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count);
  1700. }
  1701. osst_position_tape_and_confirm(STp, aSRpnt, STp->first_mark_ppos);
  1702. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1703. #if DEBUG
  1704. printk(OSST_DEB_MSG
  1705.        "osst%d:D: Couldn't get logical blk num in space_filemarks_fwd_fastn",
  1706.        dev);
  1707. #endif
  1708. return (-EIO);
  1709. }
  1710. if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
  1711. printk(KERN_WARNING "osst%d:W: Expected to find filemark at %dn",
  1712.  dev, STp->first_mark_ppos);
  1713. return (-EIO);
  1714. }
  1715. } else {
  1716. if (osst_space_over_filemarks_backward(STp, aSRpnt, MTBSF, 1) < 0)
  1717. return (-EIO);
  1718. mt_count++;
  1719. }
  1720. }
  1721. cnt++;
  1722. while (cnt != mt_count) {
  1723. next_mark_ppos = ntohl(STp->buffer->aux->next_mark_ppos);
  1724. if (!next_mark_ppos || next_mark_ppos > STp->eod_frame_ppos) {
  1725. #if DEBUG
  1726. printk(OSST_DEB_MSG "osst%d:D: Reverting to slow filemark spacen", dev);
  1727. #endif
  1728. return osst_space_over_filemarks_forward_slow(STp, aSRpnt, mt_op, mt_count - cnt);
  1729. }
  1730. #if DEBUG
  1731. else printk(OSST_DEB_MSG "osst%d:D: Positioning to next mark at %dn", dev, next_mark_ppos);
  1732. #endif
  1733. osst_position_tape_and_confirm(STp, aSRpnt, next_mark_ppos);
  1734. cnt++;
  1735. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  1736. #if DEBUG
  1737. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in space_filemarksn",
  1738.  dev);
  1739. #endif
  1740. return (-EIO);
  1741. }
  1742. if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_MARKER) {
  1743. printk(KERN_WARNING "osst%d:W: Expected to find marker at ppos %d, not foundn",
  1744.  dev, next_mark_ppos);
  1745. return (-EIO);
  1746. }
  1747. }
  1748. }
  1749. if (mt_op == MTFSF) {
  1750. STp->frame_seq_number++;
  1751. STp->frame_in_buffer  = 0;
  1752. STp->logical_blk_num += ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
  1753. }
  1754. return 0;
  1755. }
  1756. /*
  1757.  * In debug mode, we want to see as many errors as possible
  1758.  * to test the error recovery mechanism.
  1759.  */
  1760. #if DEBUG
  1761. static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries)
  1762. {
  1763. unsigned char cmd[MAX_COMMAND_SIZE];
  1764. Scsi_Request     * SRpnt  = * aSRpnt;
  1765. int dev  = TAPE_NR(STp->devt);
  1766. memset(cmd, 0, MAX_COMMAND_SIZE);
  1767. cmd[0] = MODE_SELECT;
  1768. cmd[1] = 0x10;
  1769. cmd[4] = NUMBER_RETRIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
  1770. (STp->buffer)->b_data[0] = cmd[4] - 1;
  1771. (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
  1772. (STp->buffer)->b_data[2] = 0; /* Reserved */
  1773. (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
  1774. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = NUMBER_RETRIES_PAGE | (1 << 7);
  1775. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 2;
  1776. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 4;
  1777. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = retries;
  1778. if (debugging)
  1779.     printk(OSST_DEB_MSG "osst%d:D: Setting number of retries on OnStream tape to %dn", dev, retries);
  1780. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
  1781. *aSRpnt = SRpnt;
  1782. if ((STp->buffer)->syscall_result)
  1783.     printk (KERN_ERR "osst%d:D: Couldn't set retries to %dn", dev, retries);
  1784. }
  1785. #endif
  1786. static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  1787. {
  1788. int result;
  1789. int this_mark_ppos = STp->first_frame_position;
  1790. int this_mark_lbn  = STp->logical_blk_num;
  1791. #if DEBUG
  1792. int dev = TAPE_NR(STp->devt);
  1793. #endif
  1794. if (STp->raw) return 0;
  1795. STp->write_type = OS_WRITE_NEW_MARK;
  1796. #if DEBUG
  1797. printk(OSST_DEB_MSG "osst%d:D: Writing Filemark %i at fppos %d (fseq %d, lblk %d)n", 
  1798.        dev, STp->filemark_cnt, this_mark_ppos, STp->frame_seq_number, this_mark_lbn);
  1799. #endif
  1800. STp->dirty = 1;
  1801. result  = osst_flush_write_buffer(STp, aSRpnt);
  1802. result |= osst_flush_drive_buffer(STp, aSRpnt);
  1803. STp->last_mark_ppos = this_mark_ppos;
  1804. STp->last_mark_lbn  = this_mark_lbn;
  1805. if (STp->header_cache != NULL && STp->filemark_cnt < OS_FM_TAB_MAX)
  1806. STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt] = htonl(this_mark_ppos);
  1807. if (STp->filemark_cnt++ == 0)
  1808. STp->first_mark_ppos = this_mark_ppos;
  1809. return result;
  1810. }
  1811. static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  1812. {
  1813. int result;
  1814. #if DEBUG
  1815. int dev = TAPE_NR(STp->devt);
  1816. #endif
  1817. if (STp->raw) return 0;
  1818. STp->write_type = OS_WRITE_EOD;
  1819. STp->eod_frame_ppos = STp->first_frame_position;
  1820. #if DEBUG
  1821. printk(OSST_DEB_MSG "osst%d:D: Writing EOD at fppos %d (fseq %d, lblk %d)n", dev,
  1822. STp->eod_frame_ppos, STp->frame_seq_number, STp->logical_blk_num);
  1823. #endif
  1824. STp->dirty = 1;
  1825. result  = osst_flush_write_buffer(STp, aSRpnt);
  1826. result |= osst_flush_drive_buffer(STp, aSRpnt);
  1827. STp->eod_frame_lfa = --(STp->frame_seq_number);
  1828. return result;
  1829. }
  1830. static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
  1831. {
  1832. int dev = TAPE_NR(STp->devt);
  1833. #if DEBUG
  1834. printk(OSST_DEB_MSG "osst%d:D: Reached onstream write filler group %dn", dev, where);
  1835. #endif
  1836. osst_wait_ready(STp, aSRpnt, 60 * 5);
  1837. osst_set_frame_position(STp, aSRpnt, where, 0);
  1838. STp->write_type = OS_WRITE_FILLER;
  1839. while (count--) {
  1840. memcpy(STp->buffer->b_data, "Filler", 6);
  1841. STp->buffer->buffer_bytes = 6;
  1842. STp->dirty = 1;
  1843. if (osst_flush_write_buffer(STp, aSRpnt)) {
  1844. printk(KERN_INFO "osst%i:I: Couldn't write filler framen", dev);
  1845. return (-EIO);
  1846. }
  1847. }
  1848. #if DEBUG
  1849. printk(OSST_DEB_MSG "osst%d:D: Exiting onstream write filler groupn", dev);
  1850. #endif
  1851. return osst_flush_drive_buffer(STp, aSRpnt);
  1852. }
  1853. static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
  1854. {
  1855. int dev   = TAPE_NR(STp->devt);
  1856. int     result;
  1857. #if DEBUG
  1858. printk(OSST_DEB_MSG "osst%d:D: Reached onstream write header group %dn", dev, where);
  1859. #endif
  1860. osst_wait_ready(STp, aSRpnt, 60 * 5);
  1861. osst_set_frame_position(STp, aSRpnt, where, 0);
  1862. STp->write_type = OS_WRITE_HEADER;
  1863. while (count--) {
  1864. osst_copy_to_buffer(STp->buffer, (unsigned char *)STp->header_cache);
  1865. STp->buffer->buffer_bytes = sizeof(os_header_t);
  1866. STp->dirty = 1;
  1867. if (osst_flush_write_buffer(STp, aSRpnt)) {
  1868. printk(KERN_INFO "osst%i:I: Couldn't write header framen", dev);
  1869. return (-EIO);
  1870. }
  1871. }
  1872. result = osst_flush_drive_buffer(STp, aSRpnt);
  1873. #if DEBUG
  1874. printk(OSST_DEB_MSG "osst%d:D: Write onstream header group %sn", dev, result?"failed":"done");
  1875. #endif
  1876. return result;
  1877. }
  1878. static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod)
  1879. {
  1880. os_header_t * header;
  1881. int       result;
  1882. int       dev   = TAPE_NR(STp->devt);
  1883. #if DEBUG
  1884. printk(OSST_DEB_MSG "osst%d:D: Writing tape headern", dev);
  1885. #endif
  1886. if (STp->raw) return 0;
  1887. if (STp->header_cache == NULL) {
  1888. if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
  1889. printk(KERN_ERR "osst%i:E: Failed to allocate header cachen", dev);
  1890. return (-ENOMEM);
  1891. }
  1892. memset(STp->header_cache, 0, sizeof(os_header_t));
  1893. #if DEBUG
  1894. printk(OSST_DEB_MSG "osst%d:D: Allocated and cleared memory for header cachen", dev);
  1895. #endif
  1896. }
  1897. if (STp->header_ok) STp->update_frame_cntr++;
  1898. else                STp->update_frame_cntr = 0;
  1899. header = STp->header_cache;
  1900. strcpy(header->ident_str, "ADR_SEQ");
  1901. header->major_rev      = 1;
  1902. header->minor_rev      = 4;
  1903. header->ext_trk_tb_off = htons(17192);
  1904. header->pt_par_num     = 1;
  1905. header->partition[0].partition_num              = OS_DATA_PARTITION;
  1906. header->partition[0].par_desc_ver               = OS_PARTITION_VERSION;
  1907. header->partition[0].wrt_pass_cntr              = htons(STp->wrt_pass_cntr);
  1908. header->partition[0].first_frame_ppos           = htonl(STp->first_data_ppos);
  1909. header->partition[0].last_frame_ppos            = htonl(STp->capacity);
  1910. header->partition[0].eod_frame_ppos             = htonl(STp->eod_frame_ppos);
  1911. header->cfg_col_width                           = htonl(20);
  1912. header->dat_col_width                           = htonl(1500);
  1913. header->qfa_col_width                           = htonl(0);
  1914. header->ext_track_tb.nr_stream_part             = 1;
  1915. header->ext_track_tb.et_ent_sz                  = 32;
  1916. header->ext_track_tb.dat_ext_trk_ey.et_part_num = 0;
  1917. header->ext_track_tb.dat_ext_trk_ey.fmt         = 1;
  1918. header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  = htons(17736);
  1919. header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi = 0;
  1920. header->ext_track_tb.dat_ext_trk_ey.last_hlb    = htonl(STp->eod_frame_lfa);
  1921. header->ext_track_tb.dat_ext_trk_ey.last_pp = htonl(STp->eod_frame_ppos);
  1922. header->dat_fm_tab.fm_part_num                  = 0;
  1923. header->dat_fm_tab.fm_tab_ent_sz                = 4;
  1924. header->dat_fm_tab.fm_tab_ent_cnt               = htons(STp->filemark_cnt<OS_FM_TAB_MAX?
  1925. STp->filemark_cnt:OS_FM_TAB_MAX);
  1926. result  = __osst_write_header(STp, aSRpnt, 0xbae, 5);
  1927. if (STp->update_frame_cntr == 0)
  1928.     osst_write_filler(STp, aSRpnt, 0xbb3, 5);
  1929. result &= __osst_write_header(STp, aSRpnt,     5, 5);
  1930. if (locate_eod) {
  1931. #if DEBUG
  1932. printk(OSST_DEB_MSG "osst%d:D: Locating back to eod frame addr %dn", dev, STp->eod_frame_ppos);
  1933. #endif
  1934. osst_set_frame_position(STp, aSRpnt, STp->eod_frame_ppos, 0);
  1935. }
  1936. if (result)
  1937. printk(KERN_ERR "osst%i:E: Write header failedn", dev);
  1938. else {
  1939. memcpy(STp->application_sig, "LIN4", 4);
  1940. STp->linux_media         = 1;
  1941. STp->linux_media_version = 4;
  1942. STp->header_ok           = 1;
  1943. }
  1944. return result;
  1945. }
  1946. static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  1947. {
  1948. if (STp->header_cache != NULL)
  1949. memset(STp->header_cache, 0, sizeof(os_header_t));
  1950. STp->logical_blk_num = STp->frame_seq_number = 0;
  1951. STp->frame_in_buffer = 0;
  1952. STp->eod_frame_ppos = STp->first_data_ppos = 0x0000000A;
  1953. STp->filemark_cnt = 0;
  1954. STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
  1955. return osst_write_header(STp, aSRpnt, 1);
  1956. }
  1957. static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos)
  1958. {
  1959. int           dev = TAPE_NR(STp->devt);
  1960. os_header_t * header;
  1961. os_aux_t    * aux;
  1962. char          id_string[8];
  1963. int       linux_media_version,
  1964.       update_frame_cntr;
  1965. if (STp->raw)
  1966. return 1;
  1967. if (ppos == 5 || ppos == 0xbae || STp->buffer->syscall_result) {
  1968. if (osst_set_frame_position(STp, aSRpnt, ppos, 0))
  1969. printk(KERN_WARNING "osst%i:W: Couldn't position tapen", dev);
  1970. if (osst_initiate_read (STp, aSRpnt)) {
  1971. printk(KERN_WARNING "osst%i:W: Couldn't initiate readn", dev);
  1972. return 0;
  1973. }
  1974. }
  1975. if (osst_read_frame(STp, aSRpnt, 180)) {
  1976. #if DEBUG
  1977. printk(OSST_DEB_MSG "osst%d:D: Couldn't read header framen", dev);
  1978. #endif
  1979. return 0;
  1980. }
  1981. header = (os_header_t *) STp->buffer->b_data; /* warning: only first segment addressable */
  1982. aux = STp->buffer->aux;
  1983. if (aux->frame_type != OS_FRAME_TYPE_HEADER) {
  1984. #if DEBUG
  1985. printk(OSST_DEB_MSG "osst%d:D: Skipping non-header frame (%d)n", dev, ppos);
  1986. #endif
  1987. return 0;
  1988. }
  1989. if (ntohl(aux->frame_seq_num)              != 0                   ||
  1990.     ntohl(aux->logical_blk_num)            != 0                   ||
  1991.           aux->partition.partition_num     != OS_CONFIG_PARTITION ||
  1992.     ntohl(aux->partition.first_frame_ppos) != 0                   ||
  1993.     ntohl(aux->partition.last_frame_ppos)  != 0xbb7               ) {
  1994. #if DEBUG
  1995. printk(OSST_DEB_MSG "osst%d:D: Invalid header frame (%d,%d,%d,%d,%d)n", dev,
  1996. ntohl(aux->frame_seq_num), ntohl(aux->logical_blk_num),
  1997.         aux->partition.partition_num, ntohl(aux->partition.first_frame_ppos),
  1998.         ntohl(aux->partition.last_frame_ppos));
  1999. #endif
  2000. return 0;
  2001. }
  2002. if (strncmp(header->ident_str, "ADR_SEQ", 7) != 0 &&
  2003.     strncmp(header->ident_str, "ADR-SEQ", 7) != 0) {
  2004. strncpy(id_string, header->ident_str, 7);
  2005. id_string[7] = 0;
  2006. #if DEBUG
  2007. printk(OSST_DEB_MSG "osst%d:D: Invalid header identification string %sn", dev, id_string);
  2008. #endif
  2009. return 0;
  2010. }
  2011. update_frame_cntr = ntohl(aux->update_frame_cntr);
  2012. if (update_frame_cntr < STp->update_frame_cntr) {
  2013. #if DEBUG
  2014. printk(OSST_DEB_MSG "osst%d:D: Skipping frame %d with update_frame_counter %d<%dn",
  2015.    dev, ppos, update_frame_cntr, STp->update_frame_cntr);
  2016. #endif
  2017. return 0;
  2018. }
  2019. if (header->major_rev != 1 || header->minor_rev != 4 ) {
  2020. #if DEBUG
  2021. printk(OSST_DEB_MSG "osst%d:D: %s revision %d.%d detected (1.4 supported)n", 
  2022.  dev, (header->major_rev != 1 || header->minor_rev < 2 || 
  2023.        header->minor_rev  > 4 )? "Invalid" : "Warning:",
  2024.  header->major_rev, header->minor_rev);
  2025. #endif
  2026. if (header->major_rev != 1 || header->minor_rev < 2 || header->minor_rev > 4)
  2027. return 0;
  2028. }
  2029. #if DEBUG
  2030. if (header->pt_par_num != 1)
  2031. printk(KERN_INFO "osst%i:W: %d partitions defined, only one supportedn", 
  2032.  dev, header->pt_par_num);
  2033. #endif
  2034. memcpy(id_string, aux->application_sig, 4);
  2035. id_string[4] = 0;
  2036. if (memcmp(id_string, "LIN", 3) == 0) {
  2037. STp->linux_media = 1;
  2038. linux_media_version = id_string[3] - '0';
  2039. if (linux_media_version != 4)
  2040. printk(KERN_INFO "osst%i:I: Linux media version %d detected (current 4)n",
  2041.  dev, linux_media_version);
  2042. } else {
  2043. printk(KERN_WARNING "osst%i:W: Non Linux media detected (%s)n", dev, id_string);
  2044. return 0;
  2045. }
  2046. if (linux_media_version < STp->linux_media_version) {
  2047. #if DEBUG
  2048. printk(OSST_DEB_MSG "osst%d:D: Skipping frame %d with linux_media_version %dn",
  2049.   dev, ppos, linux_media_version);
  2050. #endif
  2051. return 0;
  2052. }
  2053. if (linux_media_version > STp->linux_media_version) {
  2054. #if DEBUG
  2055. printk(OSST_DEB_MSG "osst%d:D: Frame %d sets linux_media_version to %dn",
  2056.    dev, ppos, linux_media_version);
  2057. #endif
  2058. memcpy(STp->application_sig, id_string, 5);
  2059. STp->linux_media_version = linux_media_version;
  2060. STp->update_frame_cntr = -1;
  2061. }
  2062. if (update_frame_cntr > STp->update_frame_cntr) {
  2063. #if DEBUG
  2064. printk(OSST_DEB_MSG "osst%d:D: Frame %d sets update_frame_counter to %dn",
  2065.    dev, ppos, update_frame_cntr);
  2066. #endif
  2067. if (STp->header_cache == NULL) {
  2068. if ((STp->header_cache = (os_header_t *)vmalloc(sizeof(os_header_t))) == NULL) {
  2069. printk(KERN_ERR "osst%i:E: Failed to allocate header cachen", dev);
  2070. return 0;
  2071. }
  2072. #if DEBUG
  2073. printk(OSST_DEB_MSG "osst%d:D: Allocated memory for header cachen", dev);
  2074. #endif
  2075. }
  2076. osst_copy_from_buffer(STp->buffer, (unsigned char *)STp->header_cache);
  2077. header = STp->header_cache; /* further accesses from cached (full) copy */
  2078. STp->wrt_pass_cntr     = ntohs(header->partition[0].wrt_pass_cntr);
  2079. STp->first_data_ppos   = ntohl(header->partition[0].first_frame_ppos);
  2080. STp->eod_frame_ppos    = ntohl(header->partition[0].eod_frame_ppos);
  2081. STp->eod_frame_lfa     = ntohl(header->ext_track_tb.dat_ext_trk_ey.last_hlb);
  2082. STp->filemark_cnt      = ntohl(aux->filemark_cnt);
  2083. STp->first_mark_ppos   = ntohl(aux->next_mark_ppos);
  2084. STp->last_mark_ppos    = ntohl(aux->last_mark_ppos);
  2085. STp->last_mark_lbn     = ntohl(aux->last_mark_lbn);
  2086. STp->update_frame_cntr = update_frame_cntr;
  2087. #if DEBUG
  2088. printk(OSST_DEB_MSG "osst%d:D: Detected write pass %d, update frame counter %d, filemark counter %dn",
  2089.   dev, STp->wrt_pass_cntr, STp->update_frame_cntr, STp->filemark_cnt);
  2090. printk(OSST_DEB_MSG "osst%d:D: first data frame on tape = %d, last = %d, eod frame = %dn", dev,
  2091.   STp->first_data_ppos,
  2092.   ntohl(header->partition[0].last_frame_ppos),
  2093.   ntohl(header->partition[0].eod_frame_ppos));
  2094. printk(OSST_DEB_MSG "osst%d:D: first mark on tape = %d, last = %d, eod frame = %dn", 
  2095.   dev, STp->first_mark_ppos, STp->last_mark_ppos, STp->eod_frame_ppos);
  2096. #endif
  2097. if (header->minor_rev < 4 && STp->linux_media_version == 4) {
  2098. #if DEBUG
  2099. printk(OSST_DEB_MSG "osst%i:D: Moving filemark list to ADR 1.4 locationn", dev);
  2100. #endif
  2101. memcpy((void *)header->dat_fm_tab.fm_tab_ent, 
  2102.        (void *)header->old_filemark_list, sizeof(header->dat_fm_tab.fm_tab_ent));
  2103. memset((void *)header->old_filemark_list, 0, sizeof(header->old_filemark_list));
  2104. }
  2105. if (header->minor_rev == 4   &&
  2106.     (header->ext_trk_tb_off                          != htons(17192)               ||
  2107.      header->partition[0].partition_num              != OS_DATA_PARTITION          ||
  2108.      header->partition[0].par_desc_ver               != OS_PARTITION_VERSION       ||
  2109.      header->partition[0].last_frame_ppos            != htonl(STp->capacity)       ||
  2110.      header->cfg_col_width                           != htonl(20)                  ||
  2111.      header->dat_col_width                           != htonl(1500)                ||
  2112.      header->qfa_col_width                           != htonl(0)                   ||
  2113.      header->ext_track_tb.nr_stream_part             != 1                          ||
  2114.      header->ext_track_tb.et_ent_sz                  != 32                         ||
  2115.      header->ext_track_tb.dat_ext_trk_ey.et_part_num != OS_DATA_PARTITION          ||
  2116.      header->ext_track_tb.dat_ext_trk_ey.fmt         != 1                          ||
  2117.      header->ext_track_tb.dat_ext_trk_ey.fm_tab_off  != htons(17736)               ||
  2118.      header->ext_track_tb.dat_ext_trk_ey.last_hlb_hi != 0                          ||
  2119.      header->ext_track_tb.dat_ext_trk_ey.last_pp     != htonl(STp->eod_frame_ppos) ||
  2120.      header->dat_fm_tab.fm_part_num                  != OS_DATA_PARTITION          ||
  2121.      header->dat_fm_tab.fm_tab_ent_sz                != 4                          ||
  2122.      header->dat_fm_tab.fm_tab_ent_cnt               !=
  2123.      htons(STp->filemark_cnt<OS_FM_TAB_MAX?STp->filemark_cnt:OS_FM_TAB_MAX)))
  2124. printk(KERN_WARNING "osst%i:W: Failed consistency check ADR 1.4 formatn", dev);
  2125. }
  2126. return 1;
  2127. }
  2128. static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  2129. {
  2130. int position, ppos;
  2131. int first, last;
  2132. int valid = 0;
  2133. int dev = TAPE_NR(STp->devt);
  2134. position = osst_get_frame_position(STp, aSRpnt);
  2135. if (STp->raw) {
  2136. STp->header_ok = STp->linux_media = 1;
  2137. STp->linux_media_version = 0;
  2138. return 1;
  2139. }
  2140. STp->header_ok = STp->linux_media = STp->linux_media_version = 0;
  2141. STp->wrt_pass_cntr = STp->update_frame_cntr = -1;
  2142. STp->eod_frame_ppos = STp->first_data_ppos = -1;
  2143. STp->first_mark_ppos = STp->last_mark_ppos = STp->last_mark_lbn = -1;
  2144. #if DEBUG
  2145. printk(OSST_DEB_MSG "osst%d:D: Reading headern", dev);
  2146. #endif
  2147. /* optimization for speed - if we are positioned at ppos 10, read second group first  */
  2148. /* TODO try the ADR 1.1 locations for the second group if we have no valid one yet... */
  2149. first = position==10?0xbae: 5;
  2150. last  = position==10?0xbb3:10;
  2151. for (ppos = first; ppos < last; ppos++)
  2152. if (__osst_analyze_headers(STp, aSRpnt, ppos))
  2153. valid = 1;
  2154. first = position==10? 5:0xbae;
  2155. last  = position==10?10:0xbb3;
  2156. for (ppos = first; ppos < last; ppos++)
  2157. if (__osst_analyze_headers(STp, aSRpnt, ppos))
  2158. valid = 1;
  2159. if (!valid) {
  2160. printk(KERN_ERR "osst%i:E: Failed to find valid ADRL header, new media?n", dev);
  2161. STp->eod_frame_ppos = STp->first_data_ppos = 0;
  2162. osst_set_frame_position(STp, aSRpnt, 10, 0);
  2163. return 0;
  2164. }
  2165. if (position <= STp->first_data_ppos) {
  2166. position = STp->first_data_ppos;
  2167. STp->ps[0].drv_file = STp->ps[0].drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
  2168. }
  2169. osst_set_frame_position(STp, aSRpnt, position, 0);
  2170. STp->header_ok = 1;
  2171. return 1;
  2172. }
  2173. static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
  2174. {
  2175. int frame_position  = STp->first_frame_position;
  2176. int frame_seq_numbr = STp->frame_seq_number;
  2177. int logical_blk_num = STp->logical_blk_num;
  2178.         int halfway_frame   = STp->frame_in_buffer;
  2179. int read_pointer    = STp->buffer->read_pointer;
  2180. int prev_mark_ppos  = -1;
  2181. int actual_mark_ppos, i, n;
  2182. #if DEBUG
  2183. int dev = TAPE_NR(STp->devt);
  2184. printk(OSST_DEB_MSG "osst%d:D: Verify that the tape is really the one we think before writingn", dev);
  2185. #endif
  2186. osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
  2187. if (osst_get_logical_frame(STp, aSRpnt, -1, 0) < 0) {
  2188. #if DEBUG
  2189. printk(OSST_DEB_MSG "osst%d:D: Couldn't get logical blk num in verify_positionn", dev);
  2190. #endif
  2191. return (-EIO);
  2192. }
  2193. if (STp->linux_media_version >= 4) {
  2194. for (i=0; i<STp->filemark_cnt; i++)
  2195. if ((n=ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[i])) < frame_position)
  2196. prev_mark_ppos = n;
  2197. } else
  2198. prev_mark_ppos = frame_position - 1;  /* usually - we don't really know */
  2199. actual_mark_ppos = STp->buffer->aux->frame_type == OS_FRAME_TYPE_MARKER ?
  2200. frame_position - 1 : ntohl(STp->buffer->aux->last_mark_ppos);
  2201. if (frame_position  != STp->first_frame_position                   ||
  2202.     frame_seq_numbr != STp->frame_seq_number + (halfway_frame?0:1) ||
  2203.     prev_mark_ppos  != actual_mark_ppos                            ) {
  2204. #if DEBUG
  2205. printk(OSST_DEB_MSG "osst%d:D: Block mismatch: fppos %d-%d, fseq %d-%d, mark %d-%dn", dev,
  2206.   STp->first_frame_position, frame_position, 
  2207.   STp->frame_seq_number + (halfway_frame?0:1),
  2208.   frame_seq_numbr, actual_mark_ppos, prev_mark_ppos);
  2209. #endif
  2210. return (-EIO);
  2211. }
  2212. if (halfway_frame) {
  2213. /* prepare buffer for append and rewrite on top of original */
  2214. osst_set_frame_position(STp, aSRpnt, frame_position - 1, 0);
  2215. STp->buffer->buffer_bytes  = read_pointer;
  2216. STp->ps[STp->partition].rw = ST_WRITING;
  2217. STp->dirty                 = 1;
  2218. }
  2219. STp->frame_in_buffer  = halfway_frame;
  2220. STp->frame_seq_number = frame_seq_numbr;
  2221. STp->logical_blk_num  = logical_blk_num;
  2222. return 0;
  2223. }
  2224. /* Acc. to OnStream, the vers. numbering is the following:
  2225.  * X.XX for released versions (X=digit), 
  2226.  * XXXY for unreleased versions (Y=letter)
  2227.  * Ordering 1.05 < 106A < 106B < ...  < 106a < ... < 1.06
  2228.  * This fn makes monoton numbers out of this scheme ...
  2229.  */
  2230. static unsigned int osst_parse_firmware_rev (const char * str)
  2231. {
  2232. if (str[1] == '.') {
  2233. return (str[0]-'0')*10000
  2234. +(str[2]-'0')*1000
  2235. +(str[3]-'0')*100;
  2236. } else {
  2237. return (str[0]-'0')*10000
  2238. +(str[1]-'0')*1000
  2239. +(str[2]-'0')*100 - 100
  2240. +(str[3]-'@');
  2241. }
  2242. }
  2243. /*
  2244.  * Configure the OnStream SCII tape drive for default operation
  2245.  */
  2246. static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
  2247. {
  2248. unsigned char                  cmd[MAX_COMMAND_SIZE];
  2249. int                            dev   = TAPE_NR(STp->devt);
  2250. Scsi_Request                    * SRpnt = * aSRpnt;
  2251. osst_mode_parameter_header_t * header;
  2252. osst_block_size_page_t       * bs;
  2253. osst_capabilities_page_t     * cp;
  2254. osst_tape_paramtr_page_t     * prm;
  2255. int                            drive_buffer_size;
  2256. if (STp->ready != ST_READY) {
  2257. #if DEBUG
  2258.     printk(OSST_DEB_MSG "osst%d:D: Not Readyn", dev);
  2259. #endif
  2260.     return (-EIO);
  2261. }
  2262. if (STp->os_fw_rev < 10600) {
  2263.     printk(KERN_INFO "osst%i:I: Old OnStream firmware revision detected (%s),n", dev, STp->device->rev);
  2264.     printk(KERN_INFO "osst%d:I: an upgrade to version 1.06 or above is recommendedn", dev);
  2265. }
  2266. /*
  2267.  * Configure 32.5KB (data+aux) frame size.
  2268.          * Get the current frame size from the block size mode page
  2269.  */
  2270. memset(cmd, 0, MAX_COMMAND_SIZE);
  2271. cmd[0] = MODE_SENSE;
  2272. cmd[1] = 8;
  2273. cmd[2] = BLOCK_SIZE_PAGE;
  2274. cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
  2275. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
  2276. if (SRpnt == NULL) {
  2277. #if DEBUG
  2278.       printk(OSST_DEB_MSG "osst :D: Busyn");
  2279. #endif
  2280.     return (-EBUSY);
  2281. }
  2282. *aSRpnt = SRpnt;
  2283. if ((STp->buffer)->syscall_result != 0) {
  2284.     printk (KERN_ERR "osst%i:E: Can't get tape block size mode pagen", dev);
  2285.     return (-EIO);
  2286. }
  2287. header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
  2288. bs = (osst_block_size_page_t *) ((STp->buffer)->b_data + sizeof(osst_mode_parameter_header_t) + header->bdl);
  2289. #if DEBUG
  2290. printk(OSST_DEB_MSG "osst%d:D: 32KB play back: %sn",   dev, bs->play32     ? "Yes" : "No");
  2291. printk(OSST_DEB_MSG "osst%d:D: 32.5KB play back: %sn", dev, bs->play32_5   ? "Yes" : "No");
  2292. printk(OSST_DEB_MSG "osst%d:D: 32KB record: %sn",      dev, bs->record32   ? "Yes" : "No");
  2293. printk(OSST_DEB_MSG "osst%d:D: 32.5KB record: %sn",    dev, bs->record32_5 ? "Yes" : "No");
  2294. #endif
  2295. /*
  2296.  * Configure default auto columns mode, 32.5KB transfer mode
  2297.  */ 
  2298. bs->one = 1;
  2299. bs->play32 = 0;
  2300. bs->play32_5 = 1;
  2301. bs->record32 = 0;
  2302. bs->record32_5 = 1;
  2303. memset(cmd, 0, MAX_COMMAND_SIZE);
  2304. cmd[0] = MODE_SELECT;
  2305. cmd[1] = 0x10;
  2306. cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
  2307. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
  2308. *aSRpnt = SRpnt;
  2309. if ((STp->buffer)->syscall_result != 0) {
  2310.     printk (KERN_ERR "osst%i:E: Couldn't set tape block size mode pagen", dev);
  2311.     return (-EIO);
  2312. }
  2313. #if DEBUG
  2314. printk(KERN_INFO "osst%d:D: Drive Block Size changed to 32.5Kn", dev);
  2315.  /*
  2316.  * In debug mode, we want to see as many errors as possible
  2317.  * to test the error recovery mechanism.
  2318.  */
  2319. osst_set_retries(STp, aSRpnt, 0);
  2320. SRpnt = * aSRpnt;
  2321. #endif
  2322. /*
  2323.  * Set vendor name to 'LIN4' for "Linux support version 4".
  2324.  */
  2325. memset(cmd, 0, MAX_COMMAND_SIZE);
  2326. cmd[0] = MODE_SELECT;
  2327. cmd[1] = 0x10;
  2328. cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
  2329. header->mode_data_length = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH - 1;
  2330. header->medium_type      = 0; /* Medium Type - ignoring */
  2331. header->dsp              = 0; /* Reserved */
  2332. header->bdl              = 0; /* Block Descriptor Length */
  2333. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = VENDOR_IDENT_PAGE | (1 << 7);
  2334. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 6;
  2335. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 'L';
  2336. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 'I';
  2337. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 4] = 'N';
  2338. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 5] = '4';
  2339. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
  2340. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
  2341. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
  2342. *aSRpnt = SRpnt;
  2343. if ((STp->buffer)->syscall_result != 0) {
  2344.     printk (KERN_ERR "osst%i:E: Couldn't set vendor name to %sn", dev, 
  2345. (char *) ((STp->buffer)->b_data + MODE_HEADER_LENGTH + 2));
  2346.     return (-EIO);
  2347. }
  2348. memset(cmd, 0, MAX_COMMAND_SIZE);
  2349. cmd[0] = MODE_SENSE;
  2350. cmd[1] = 8;
  2351. cmd[2] = CAPABILITIES_PAGE;
  2352. cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
  2353. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
  2354. *aSRpnt = SRpnt;
  2355. if ((STp->buffer)->syscall_result != 0) {
  2356.     printk (KERN_ERR "osst%i:E: Can't get capabilities pagen", dev);
  2357.     return (-EIO);
  2358. }
  2359. header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
  2360. cp     = (osst_capabilities_page_t    *) ((STp->buffer)->b_data +
  2361.  sizeof(osst_mode_parameter_header_t) + header->bdl);
  2362. drive_buffer_size = ntohs(cp->buffer_size) / 2;
  2363. memset(cmd, 0, MAX_COMMAND_SIZE);
  2364. cmd[0] = MODE_SENSE;
  2365. cmd[1] = 8;
  2366. cmd[2] = TAPE_PARAMTR_PAGE;
  2367. cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
  2368. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
  2369. *aSRpnt = SRpnt;
  2370. if ((STp->buffer)->syscall_result != 0) {
  2371.     printk (KERN_ERR "osst%i:E: Can't get tape parameter pagen", dev);
  2372.     return (-EIO);
  2373. }
  2374. header = (osst_mode_parameter_header_t *) (STp->buffer)->b_data;
  2375. prm    = (osst_tape_paramtr_page_t    *) ((STp->buffer)->b_data +
  2376.  sizeof(osst_mode_parameter_header_t) + header->bdl);
  2377. STp->density  = prm->density;
  2378. STp->capacity = ntohs(prm->segtrk) * ntohs(prm->trks);
  2379. #if DEBUG
  2380. printk(OSST_DEB_MSG "osst%d:D: Density %d, tape length: %dMB, drive buffer size: %dKBn",
  2381.   dev, STp->density, STp->capacity / 32, drive_buffer_size);
  2382. #endif
  2383. return 0;
  2384. }
  2385. /* Step over EOF if it has been inadvertently crossed (ioctl not used because
  2386.    it messes up the block number). */
  2387. static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward)
  2388. {
  2389. int result;
  2390. int dev   = TAPE_NR(STp->devt);
  2391. #if DEBUG
  2392. if (debugging)
  2393. printk(OSST_DEB_MSG "osst%d:D: Stepping over filemark %s.n",
  2394.       dev, forward ? "forward" : "backward");
  2395. #endif
  2396. if (forward) {
  2397.    /* assumes that the filemark is already read by the drive, so this is low cost */
  2398.    result = osst_space_over_filemarks_forward_slow(STp, aSRpnt, MTFSF, 1);
  2399. }
  2400. else
  2401.    /* assumes this is only called if we just read the filemark! */
  2402.    result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - 1);
  2403. if (result < 0)
  2404.    printk(KERN_WARNING "osst%d:W: Stepping over filemark %s failed.n",
  2405. dev, forward ? "forward" : "backward");
  2406. return result;
  2407. }
  2408. /* Get the tape position. */
  2409. static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
  2410. {
  2411. unsigned char scmd[MAX_COMMAND_SIZE];
  2412. Scsi_Request  * SRpnt;
  2413. int result = 0;
  2414. /* KG: We want to be able to use it for checking Write Buffer availability
  2415.  *  and thus don't want to risk to overwrite anything. Exchange buffers ... */
  2416. char mybuf[24];
  2417. char       * olddata = STp->buffer->b_data;
  2418. int oldsize = STp->buffer->buffer_size;
  2419. int dev     = TAPE_NR(STp->devt);
  2420. if (STp->ready != ST_READY) return (-EIO);
  2421. memset (scmd, 0, MAX_COMMAND_SIZE);
  2422. scmd[0] = READ_POSITION;
  2423. STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
  2424. SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ,
  2425.       STp->timeout, MAX_READY_RETRIES, TRUE);
  2426. if (!SRpnt) {
  2427. STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
  2428. return (-EBUSY);
  2429. }
  2430. *aSRpnt = SRpnt;
  2431. if (STp->buffer->syscall_result)
  2432. result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;
  2433. if (result == -EINVAL)
  2434. printk(KERN_ERR "osst%d:E: Can't read tape position.n", dev);
  2435. else {
  2436. if (result == -EIO) { /* re-read position */
  2437. unsigned char mysense[16];
  2438. memcpy (mysense, SRpnt->sr_sense_buffer, 16);
  2439. memset (scmd, 0, MAX_COMMAND_SIZE);
  2440. scmd[0] = READ_POSITION;
  2441. STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
  2442. SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ,
  2443.     STp->timeout, MAX_READY_RETRIES, TRUE);
  2444. if (!STp->buffer->syscall_result)
  2445. memcpy (SRpnt->sr_sense_buffer, mysense, 16);
  2446. }
  2447. STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
  2448.   + ((STp->buffer)->b_data[5] << 16)
  2449.   + ((STp->buffer)->b_data[6] << 8)
  2450.   +  (STp->buffer)->b_data[7];
  2451. STp->last_frame_position  = ((STp->buffer)->b_data[ 8] << 24)
  2452.   + ((STp->buffer)->b_data[ 9] << 16)
  2453.   + ((STp->buffer)->b_data[10] <<  8)
  2454.   +  (STp->buffer)->b_data[11];
  2455. STp->cur_frames           =  (STp->buffer)->b_data[15];
  2456. #if DEBUG
  2457. if (debugging) {
  2458. printk(OSST_DEB_MSG "osst%d:D: Drive Positions: host %d, tape %d%s, buffer %dn", dev,
  2459.     STp->first_frame_position, STp->last_frame_position,
  2460.     ((STp->buffer)->b_data[0]&0x80)?" (BOP)":
  2461.     ((STp->buffer)->b_data[0]&0x40)?" (EOP)":"",
  2462.     STp->cur_frames);
  2463. }
  2464. #endif
  2465. if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
  2466. #if DEBUG
  2467. printk(KERN_WARNING "osst%d:D: Correcting read position %d, %d, %dn", dev,
  2468. STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
  2469. #endif
  2470. STp->first_frame_position = STp->last_frame_position;
  2471. }
  2472. }
  2473. STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
  2474. return (result == 0 ? STp->first_frame_position : result);
  2475. }
  2476. /* Set the tape block */
  2477. static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip)
  2478. {
  2479. unsigned char scmd[MAX_COMMAND_SIZE];
  2480. Scsi_Request  * SRpnt;
  2481. ST_partstat   * STps;
  2482. int result = 0;
  2483. int pp  = (ppos == 3000 && !skip)? 0 : ppos;
  2484. int dev = TAPE_NR(STp->devt);
  2485. if (STp->ready != ST_READY) return (-EIO);
  2486. STps = &(STp->ps[STp->partition]);
  2487. if (ppos < 0 || ppos > STp->capacity) {
  2488. printk(KERN_WARNING "osst%d:W: Reposition request %d out of rangen", dev, ppos);
  2489. pp = ppos = ppos < 0 ? 0 : (STp->capacity - 1);
  2490. result = (-EINVAL);
  2491. }
  2492. do {
  2493. #if DEBUG
  2494. if (debugging)
  2495. printk(OSST_DEB_MSG "osst%d:D: Setting ppos to %d.n", dev, pp);
  2496. #endif
  2497. memset (scmd, 0, MAX_COMMAND_SIZE);
  2498. scmd[0] = SEEK_10;
  2499. scmd[1] = 1;
  2500. scmd[3] = (pp >> 24);
  2501. scmd[4] = (pp >> 16);
  2502. scmd[5] = (pp >> 8);
  2503. scmd[6] =  pp;
  2504. if (skip)
  2505. scmd[9] = 0x80;
  2506. SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout,
  2507. MAX_READY_RETRIES, TRUE);
  2508. if (!SRpnt)
  2509. return (-EBUSY);
  2510. *aSRpnt  = SRpnt;
  2511. if ((STp->buffer)->syscall_result != 0) {
  2512. #if DEBUG
  2513. printk(OSST_DEB_MSG "osst%d:D: SEEK command from %d to %d failed.n",
  2514. dev, STp->first_frame_position, pp);
  2515. #endif
  2516. result = (-EIO);
  2517. }
  2518. if (pp != ppos)
  2519. osst_wait_ready(STp, aSRpnt, 5 * 60);
  2520. } while ((pp != ppos) && (pp = ppos));
  2521. STp->first_frame_position = STp->last_frame_position = ppos;
  2522. STps->eof = ST_NOEOF;
  2523. STps->at_sm = 0;
  2524. STps->rw = ST_IDLE;
  2525. STp->frame_in_buffer = 0;
  2526. return result;
  2527. }
  2528. /* osst versions of st functions - augmented and stripped to suit OnStream only */
  2529. /* Flush the write buffer (never need to write if variable blocksize). */
  2530. static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
  2531. {
  2532. int offset, transfer, blks = 0;
  2533. int result = 0;
  2534. unsigned char cmd[MAX_COMMAND_SIZE];
  2535. Scsi_Request * SRpnt = *aSRpnt;
  2536. ST_partstat * STps;
  2537. int dev = TAPE_NR(STp->devt);
  2538. if ((STp->buffer)->writing) {
  2539. if (SRpnt == (STp->buffer)->last_SRpnt)
  2540. #if DEBUG
  2541. { printk(OSST_DEB_MSG
  2542.  "osst%d:D: aSRpnt points to Scsi_Request that write_behind_check will release -- clearedn", dev);
  2543. #endif
  2544. *aSRpnt = SRpnt = NULL;
  2545. #if DEBUG
  2546. } else if (SRpnt)
  2547. printk(OSST_DEB_MSG
  2548.  "osst%d:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strangen", dev);
  2549. #endif
  2550. osst_write_behind_check(STp);
  2551. if ((STp->buffer)->syscall_result) {
  2552. #if DEBUG
  2553. if (debugging)
  2554. printk(OSST_DEB_MSG "osst%d:D: Async write error (flush) %x.n",
  2555.        dev, (STp->buffer)->midlevel_result);
  2556. #endif
  2557. if ((STp->buffer)->midlevel_result == INT_MAX)
  2558. return (-ENOSPC);
  2559. return (-EIO);
  2560. }
  2561. }
  2562. result = 0;
  2563. if (STp->dirty == 1) {
  2564. STp->write_count++;
  2565. STps     = &(STp->ps[STp->partition]);
  2566. STps->rw = ST_WRITING;
  2567. offset   = STp->buffer->buffer_bytes;
  2568. blks     = (offset + STp->block_size - 1) / STp->block_size;
  2569. transfer = OS_FRAME_SIZE;
  2570. if (offset < OS_DATA_SIZE)
  2571. osst_zero_buffer_tail(STp->buffer);
  2572. /* TODO: Error handling! */
  2573. if (STp->poll)
  2574. result = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120);
  2575. memset(cmd, 0, MAX_COMMAND_SIZE);
  2576. cmd[0] = WRITE_6;
  2577. cmd[1] = 1;
  2578. cmd[4] = 1;
  2579. switch (STp->write_type) {
  2580.    case OS_WRITE_DATA:
  2581. #if DEBUG
  2582.     if (debugging)
  2583. printk(OSST_DEB_MSG "osst%d:D: Writing %d blocks to frame %d, lblks %d-%dn",
  2584. dev, blks, STp->frame_seq_number, 
  2585. STp->logical_blk_num - blks, STp->logical_blk_num - 1);
  2586. #endif
  2587. osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
  2588.       STp->logical_blk_num - blks, STp->block_size, blks);