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

Linux/Unix编程

开发平台:

Unix_Linux

  1. break;
  2.    case OS_WRITE_EOD:
  3. osst_init_aux(STp, OS_FRAME_TYPE_EOD, STp->frame_seq_number++,
  4.       STp->logical_blk_num, 0, 0);
  5. break;
  6.    case OS_WRITE_NEW_MARK:
  7. osst_init_aux(STp, OS_FRAME_TYPE_MARKER, STp->frame_seq_number++,
  8.       STp->logical_blk_num++, 0, blks=1);
  9. break;
  10.    case OS_WRITE_HEADER:
  11. osst_init_aux(STp, OS_FRAME_TYPE_HEADER, 0, 0, 0, blks=0);
  12. break;
  13. default: /* probably FILLER */
  14. osst_init_aux(STp, OS_FRAME_TYPE_FILL, 0, 0, 0, 0);
  15. }
  16. #if DEBUG
  17. if (debugging)
  18. printk(OSST_DEB_MSG "osst%d:D: Flushing %d bytes, Transfering %d bytes in %d lblocks.n",
  19.     dev, offset, transfer, blks);
  20. #endif
  21. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
  22.   STp->timeout, MAX_WRITE_RETRIES, TRUE);
  23. *aSRpnt = SRpnt;
  24. if (!SRpnt)
  25. return (-EBUSY);
  26. if ((STp->buffer)->syscall_result != 0) {
  27. #if DEBUG
  28. printk(OSST_DEB_MSG
  29. "osst%d:D: write sense [0]=0x%02x [2]=%02x [12]=%02x [13]=%02xn",
  30. dev, SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[2],
  31. SRpnt->sr_sense_buffer[12], SRpnt->sr_sense_buffer[13]);
  32. #endif
  33. if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
  34.     (SRpnt->sr_sense_buffer[2] & 0x40) && /* FIXME - SC-30 drive doesn't assert EOM bit */
  35.     (SRpnt->sr_sense_buffer[2] & 0x0f) == NO_SENSE) {
  36. STp->dirty = 0;
  37. (STp->buffer)->buffer_bytes = 0;
  38. result = (-ENOSPC);
  39. }
  40. else {
  41. if (osst_write_error_recovery(STp, aSRpnt, 1)) {
  42. printk(KERN_ERR "osst%d:E: Error on flush write.n", dev);
  43. result = (-EIO);
  44. }
  45. }
  46. STps->drv_block = (-1);
  47. }
  48. else {
  49. STp->first_frame_position++;
  50. STp->dirty = 0;
  51. (STp->buffer)->buffer_bytes = 0;
  52. }
  53. }
  54. #if DEBUG
  55. printk(OSST_DEB_MSG "osst%d:D: Exit flush write buffer with code %dn", dev, result);
  56. #endif
  57. return result;
  58. }
  59. /* Flush the tape buffer. The tape will be positioned correctly unless
  60.    seek_next is true. */
  61. static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next)
  62. {
  63. ST_partstat   * STps;
  64. int backspace = 0, result = 0;
  65. #if DEBUG
  66. int dev = TAPE_NR(STp->devt);
  67. #endif
  68. /*
  69.  * If there was a bus reset, block further access
  70.  * to this device.
  71.  */
  72. if( STp->device->was_reset )
  73. return (-EIO);
  74. if (STp->ready != ST_READY)
  75. return 0;
  76. STps = &(STp->ps[STp->partition]);
  77. if (STps->rw == ST_WRITING)  /* Writing */
  78. return osst_flush_write_buffer(STp, aSRpnt);
  79. if (STp->block_size == 0)
  80. return 0;
  81. #if DEBUG
  82. printk(OSST_DEB_MSG "osst%d:D: Reached flush (read) buffern", dev);
  83. #endif
  84. if (!STp->can_bsr) {
  85. backspace = ((STp->buffer)->buffer_bytes + (STp->buffer)->read_pointer) / STp->block_size -
  86.     ((STp->buffer)->read_pointer + STp->block_size - 1        ) / STp->block_size ;
  87. (STp->buffer)->buffer_bytes = 0;
  88. (STp->buffer)->read_pointer = 0;
  89. STp->frame_in_buffer = 0; /* FIXME is this relevant w. OSST? */
  90. }
  91. if (!seek_next) {
  92. if (STps->eof == ST_FM_HIT) {
  93. result = cross_eof(STp, aSRpnt, FALSE); /* Back over the EOF hit */
  94. if (!result)
  95. STps->eof = ST_NOEOF;
  96. else {
  97. if (STps->drv_file >= 0)
  98. STps->drv_file++;
  99. STps->drv_block = 0;
  100. }
  101. }
  102. if (!result && backspace > 0) /* TODO -- design and run a test case for this */
  103. result = osst_seek_logical_blk(STp, aSRpnt, STp->logical_blk_num - backspace);
  104. }
  105. else if (STps->eof == ST_FM_HIT) {
  106. if (STps->drv_file >= 0)
  107. STps->drv_file++;
  108. STps->drv_block = 0;
  109. STps->eof = ST_NOEOF;
  110. }
  111. return result;
  112. }
  113. static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous)
  114. {
  115. unsigned char cmd[MAX_COMMAND_SIZE];
  116. Scsi_Request     * SRpnt;
  117. int blks;
  118. #if DEBUG
  119. int dev = TAPE_NR(STp->devt);
  120. #endif
  121. if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
  122. #if DEBUG
  123. printk(OSST_DEB_MSG "osst%d:D: Reaching config partition.n", dev);
  124. #endif
  125. if (osst_flush_drive_buffer(STp, aSRpnt) < 0) {
  126. return (-EIO);
  127. }
  128. /* error recovery may have bumped us past the header partition */
  129. if (osst_get_frame_position(STp, aSRpnt) < 0xbb8) {
  130. #if DEBUG
  131. printk(OSST_DEB_MSG "osst%d:D: Skipping over config partition.n", dev);
  132. #endif
  133. osst_position_tape_and_confirm(STp, aSRpnt, 0xbb8);
  134. }
  135. }
  136. if (STp->poll)
  137. osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60);
  138. /* TODO: Check for an error ! */
  139. // osst_build_stats(STp, &SRpnt);
  140. STp->ps[STp->partition].rw = ST_WRITING;
  141. STp->write_type            = OS_WRITE_DATA;
  142. memset(cmd, 0, MAX_COMMAND_SIZE);
  143. cmd[0]   = WRITE_6;
  144. cmd[1]   = 1;
  145. cmd[4]   = 1; /* one frame at a time... */
  146. blks     = STp->buffer->buffer_bytes / STp->block_size;
  147. #if DEBUG
  148. if (debugging)
  149. printk(OSST_DEB_MSG "osst%d:D: Writing %d blocks to frame %d, lblks %d-%dn", dev, blks, 
  150. STp->frame_seq_number, STp->logical_blk_num - blks, STp->logical_blk_num - 1);
  151. #endif
  152. osst_init_aux(STp, OS_FRAME_TYPE_DATA, STp->frame_seq_number++,
  153.       STp->logical_blk_num - blks, STp->block_size, blks);
  154. #if DEBUG
  155. if (!synchronous)
  156. STp->write_pending = 1;
  157. #endif
  158. SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout,
  159. MAX_WRITE_RETRIES, synchronous);
  160. if (!SRpnt)
  161. return (-EBUSY);
  162. *aSRpnt = SRpnt;
  163. if (synchronous) {
  164. if (STp->buffer->syscall_result != 0) {
  165. #if DEBUG
  166. if (debugging)
  167. printk(OSST_DEB_MSG "osst%d:D: Error on write:n", dev);
  168. #endif
  169. if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
  170.     (SRpnt->sr_sense_buffer[2] & 0x40)) {
  171. if ((SRpnt->sr_sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)
  172. return (-ENOSPC);
  173. }
  174. else {
  175. if (osst_write_error_recovery(STp, aSRpnt, 1))
  176. return (-EIO);
  177. }
  178. }
  179. else
  180. STp->first_frame_position++;
  181. }
  182. STp->write_count++;
  183. return 0;
  184. }
  185. /* Entry points to osst */
  186. /* Write command */
  187. static ssize_t osst_write(struct file * filp, const char * buf, size_t count, loff_t *ppos)
  188. {
  189. struct inode *inode = filp->f_dentry->d_inode;
  190. ssize_t total, retval = 0;
  191. ssize_t i, do_count, blks, transfer;
  192. int write_threshold;
  193. int doing_write = 0;
  194. const char *b_point;
  195. Scsi_Request * SRpnt = NULL;
  196. OS_Scsi_Tape * STp;
  197. ST_mode * STm;
  198. ST_partstat * STps;
  199. int dev = TAPE_NR(inode->i_rdev);
  200. STp = os_scsi_tapes[dev];
  201. if (down_interruptible(&STp->lock))
  202. return (-ERESTARTSYS);
  203. /*
  204.  * If we are in the middle of error recovery, don't let anyone
  205.  * else try and use this device.  Also, if error recovery fails, it
  206.  * may try and take the device offline, in which case all further
  207.  * access to the device is prohibited.
  208.  */
  209. if( !scsi_block_when_processing_errors(STp->device) ) {
  210. retval = (-ENXIO);
  211. goto out;
  212. }
  213. if (ppos != &filp->f_pos) {
  214.   /* "A request was outside the capabilities of the device." */
  215. retval = (-ENXIO);
  216. goto out;
  217. }
  218. if (STp->ready != ST_READY) {
  219. if (STp->ready == ST_NO_TAPE)
  220. retval = (-ENOMEDIUM);
  221. else
  222. retval = (-EIO);
  223. goto out;
  224. }
  225. STm = &(STp->modes[STp->current_mode]);
  226. if (!STm->defined) {
  227. retval = (-ENXIO);
  228. goto out;
  229. }
  230. if (count == 0)
  231. goto out;
  232. /*
  233.  * If there was a bus reset, block further access
  234.  * to this device.
  235.  */
  236. if (STp->device->was_reset) {
  237. retval = (-EIO);
  238. goto out;
  239. }
  240. #if DEBUG
  241. if (!STp->in_use) {
  242. printk(OSST_DEB_MSG "osst%d:D: Incorrect device.n", dev);
  243. retval = (-EIO);
  244. goto out;
  245. }
  246. #endif
  247. if (STp->write_prot) {
  248. retval = (-EACCES);
  249. goto out;
  250. }
  251. /* Write must be integral number of blocks */
  252. if (STp->block_size != 0 && (count % STp->block_size) != 0) {
  253. printk(KERN_ERR "osst%d:E: Write (%ld bytes) not multiple of tape block size (%d%c).n",
  254.        dev, (unsigned long)count, STp->block_size<1024?
  255.        STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
  256. retval = (-EINVAL);
  257. goto out;
  258. }
  259. if (STp->first_frame_position >= STp->capacity - OSST_EOM_RESERVE) {
  260. printk(KERN_ERR "osst%d:E: Write truncated at EOM early warning (frame %d).n",
  261.        dev, STp->first_frame_position);
  262. retval = (-ENOSPC);
  263. goto out;
  264. }
  265. STps = &(STp->ps[STp->partition]);
  266. if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
  267.     !osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
  268. STp->door_locked = ST_LOCKED_AUTO;
  269. if (STps->rw == ST_READING) {
  270. retval = osst_flush_buffer(STp, &SRpnt, 0);
  271. if (retval)
  272. goto out;
  273. STps->rw = ST_IDLE;
  274. }
  275. else if (STps->rw != ST_WRITING) {
  276. /* Are we totally rewriting this tape? */
  277. if (!STp->header_ok ||
  278.     (STp->first_frame_position == STp->first_data_ppos && STps->drv_block < 0) ||
  279.     (STps->drv_file == 0 && STps->drv_block == 0)) {
  280. STp->wrt_pass_cntr++;
  281. #if DEBUG
  282. printk(OSST_DEB_MSG "osst%d:D: Allocating next write pass counter: %dn",
  283.   dev, STp->wrt_pass_cntr);
  284. #endif
  285. osst_reset_header(STp, &SRpnt);
  286. STps->drv_file = STps->drv_block = 0;
  287. }
  288. /* Do we know where we'll be writing on the tape? */
  289. else {
  290. if ((STp->fast_open && osst_verify_position(STp, &SRpnt)) ||
  291.    STps->drv_file < 0 || STps->drv_block < 0) {
  292. if (STp->first_frame_position == STp->eod_frame_ppos) { /* at EOD */
  293.    STps->drv_file = STp->filemark_cnt;
  294.    STps->drv_block = 0;
  295. }
  296. else {
  297. /* We have no idea where the tape is positioned - give up */
  298. #if DEBUG
  299. printk(OSST_DEB_MSG
  300. "osst%d:D: Cannot write at indeterminate position.n", dev);
  301. #endif
  302. retval = (-EIO);
  303. goto out;
  304. }
  305.        }   
  306. if ((STps->drv_file + STps->drv_block) > 0 && STps->drv_file < STp->filemark_cnt) {
  307. STp->filemark_cnt = STps->drv_file;
  308. STp->last_mark_ppos =
  309.         ntohl(STp->header_cache->dat_fm_tab.fm_tab_ent[STp->filemark_cnt-1]);
  310. printk(KERN_WARNING
  311. "osst%d:W: Overwriting file %d with old write pass counter %dn",
  312. dev, STps->drv_file, STp->wrt_pass_cntr);
  313. printk(KERN_WARNING
  314. "osst%d:W: may lead to stale data being accepted on reading back!n",
  315. dev);
  316. #if DEBUG
  317. printk(OSST_DEB_MSG
  318.   "osst%d:D: resetting filemark count to %d and last mark ppos,lbn to %d,%dn",
  319. dev, STp->filemark_cnt, STp->last_mark_ppos, STp->last_mark_lbn);
  320. #endif
  321. }
  322. }
  323. STp->fast_open = FALSE;
  324. }
  325. if (!STp->header_ok) {
  326. #if DEBUG
  327. printk(OSST_DEB_MSG "osst%d:D: Write cannot proceed without valid headersn", dev);
  328. #endif
  329. retval = (-EIO);
  330. goto out;
  331. }
  332. if ((STp->buffer)->writing) {
  333. if (SRpnt) printk(KERN_ERR "osst%d:A: Not supposed to have SRpnt at line %dn", dev, __LINE__);
  334. osst_write_behind_check(STp);
  335. if ((STp->buffer)->syscall_result) {
  336. #if DEBUG
  337. if (debugging)
  338. printk(OSST_DEB_MSG "osst%d:D: Async write error (write) %x.n", dev,
  339.  (STp->buffer)->midlevel_result);
  340. #endif
  341. if ((STp->buffer)->midlevel_result == INT_MAX)
  342. STps->eof = ST_EOM_OK;
  343. else
  344. STps->eof = ST_EOM_ERROR;
  345. }
  346. }
  347. if (STps->eof == ST_EOM_OK) {
  348. retval = (-ENOSPC);
  349. goto out;
  350. }
  351. else if (STps->eof == ST_EOM_ERROR) {
  352. retval = (-EIO);
  353. goto out;
  354. }
  355. /* Check the buffer readability in cases where copy_user might catch
  356.  the problems after some tape movement. */
  357. if ((copy_from_user(&i, buf, 1) != 0 ||
  358.      copy_from_user(&i, buf + count - 1, 1) != 0)) {
  359. retval = (-EFAULT);
  360. goto out;
  361. }
  362. if (!STm->do_buffer_writes) {
  363. write_threshold = 1;
  364. }
  365. else
  366. write_threshold = (STp->buffer)->buffer_blocks * STp->block_size;
  367. if (!STm->do_async_writes)
  368. write_threshold--;
  369. total = count;
  370. #if DEBUG
  371. if (debugging)
  372. printk(OSST_DEB_MSG "osst%d:D: Writing %d bytes to file %d block %d lblk %d fseq %d fppos %dn",
  373. dev, count, STps->drv_file, STps->drv_block,
  374. STp->logical_blk_num, STp->frame_seq_number, STp->first_frame_position);
  375. #endif
  376. b_point = buf;
  377. while ((STp->buffer)->buffer_bytes + count > write_threshold)
  378. {
  379. doing_write = 1;
  380. do_count = (STp->buffer)->buffer_blocks * STp->block_size -
  381.    (STp->buffer)->buffer_bytes;
  382. if (do_count > count)
  383. do_count = count;
  384. i = append_to_buffer(b_point, STp->buffer, do_count);
  385. if (i) {
  386. retval = i;
  387. goto out;
  388. }
  389. blks = do_count / STp->block_size;
  390. STp->logical_blk_num += blks;  /* logical_blk_num is incremented as data is moved from user */
  391.   
  392. i = osst_write_frame(STp, &SRpnt, TRUE);
  393. if (i == (-ENOSPC)) {
  394. transfer = STp->buffer->writing; /* FIXME -- check this logic */
  395. if (transfer <= do_count) {
  396. filp->f_pos += do_count - transfer;
  397. count -= do_count - transfer;
  398. if (STps->drv_block >= 0) {
  399. STps->drv_block += (do_count - transfer) / STp->block_size;
  400. }
  401. STps->eof = ST_EOM_OK;
  402. retval = (-ENOSPC); /* EOM within current request */
  403. #if DEBUG
  404. if (debugging)
  405.       printk(OSST_DEB_MSG "osst%d:D: EOM with %d bytes unwritten.n",
  406.      dev, transfer);
  407. #endif
  408. }
  409. else {
  410. STps->eof = ST_EOM_ERROR;
  411. STps->drv_block = (-1); /* Too cautious? */
  412. retval = (-EIO); /* EOM for old data */
  413. #if DEBUG
  414. if (debugging)
  415.       printk(OSST_DEB_MSG "osst%d:D: EOM with lost data.n", dev);
  416. #endif
  417. }
  418. }
  419. else
  420. retval = i;
  421. if (retval < 0) {
  422. if (SRpnt != NULL) {
  423. scsi_release_request(SRpnt);
  424. SRpnt = NULL;
  425. }
  426. STp->buffer->buffer_bytes = 0;
  427. STp->dirty = 0;
  428. if (count < total)
  429. retval = total - count;
  430. goto out;
  431. }
  432. filp->f_pos += do_count;
  433. b_point += do_count;
  434. count -= do_count;
  435. if (STps->drv_block >= 0) {
  436. STps->drv_block += blks;
  437. }
  438. STp->buffer->buffer_bytes = 0;
  439. STp->dirty = 0;
  440. }  /* end while write threshold exceeded */
  441. if (count != 0) {
  442. STp->dirty = 1;
  443. i = append_to_buffer(b_point, STp->buffer, count);
  444. if (i) {
  445. retval = i;
  446. goto out;
  447. }
  448. blks = count / STp->block_size;
  449. STp->logical_blk_num += blks;
  450. if (STps->drv_block >= 0) {
  451. STps->drv_block += blks;
  452. }
  453. filp->f_pos += count;
  454. count = 0;
  455. }
  456. if (doing_write && (STp->buffer)->syscall_result != 0) {
  457. retval = (STp->buffer)->syscall_result;
  458. goto out;
  459. }
  460. if (STm->do_async_writes && ((STp->buffer)->buffer_bytes >= STp->write_threshold)) { 
  461. /* Schedule an asynchronous write */
  462. (STp->buffer)->writing = ((STp->buffer)->buffer_bytes /
  463.    STp->block_size) * STp->block_size;
  464. STp->dirty = !((STp->buffer)->writing ==
  465.           (STp->buffer)->buffer_bytes);
  466. i = osst_write_frame(STp, &SRpnt, FALSE);
  467. if (i < 0) {
  468. retval = (-EIO);
  469. goto out;
  470. }
  471. SRpnt = NULL; /* Prevent releasing this request! */
  472. }
  473. STps->at_sm &= (total == 0);
  474. if (total > 0)
  475. STps->eof = ST_NOEOF;
  476. retval = total;
  477. out:
  478. if (SRpnt != NULL) scsi_release_request(SRpnt);
  479. up(&STp->lock);
  480. return retval;
  481. }
  482. /* Read command */
  483. static ssize_t osst_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
  484. {
  485. struct inode * inode = filp->f_dentry->d_inode;
  486. ssize_t total, retval = 0;
  487. ssize_t i, transfer;
  488. int special;
  489. OS_Scsi_Tape * STp;
  490. ST_mode * STm;
  491. ST_partstat * STps;
  492. Scsi_Request *SRpnt = NULL;
  493. int dev = TAPE_NR(inode->i_rdev);
  494. STp = os_scsi_tapes[dev];
  495. if (down_interruptible(&STp->lock))
  496. return (-ERESTARTSYS);
  497. /*
  498.  * If we are in the middle of error recovery, don't let anyone
  499.  * else try and use this device.  Also, if error recovery fails, it
  500.  * may try and take the device offline, in which case all further
  501.  * access to the device is prohibited.
  502.  */
  503. if( !scsi_block_when_processing_errors(STp->device) ) {
  504. retval = (-ENXIO);
  505. goto out;
  506. }
  507. if (ppos != &filp->f_pos) {
  508. /* "A request was outside the capabilities of the device." */
  509. retval = (-ENXIO);
  510. goto out;
  511. }
  512. if (STp->ready != ST_READY) {
  513. if (STp->ready == ST_NO_TAPE)
  514. retval = (-ENOMEDIUM);
  515. else
  516. retval = (-EIO);
  517. goto out;
  518. }
  519. STm = &(STp->modes[STp->current_mode]);
  520. if (!STm->defined) {
  521. retval = (-ENXIO);
  522. goto out;
  523. }
  524. #if DEBUG
  525. if (!STp->in_use) {
  526. printk(OSST_DEB_MSG "osst%d:D: Incorrect device.n", dev);
  527. retval = (-EIO);
  528. goto out;
  529. }
  530. #endif
  531. /* Must have initialized medium */
  532. if (!STp->header_ok) {
  533. retval = (-EIO);
  534. goto out;
  535. }
  536. if (STp->do_auto_lock && STp->door_locked == ST_UNLOCKED &&
  537. !osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
  538. STp->door_locked = ST_LOCKED_AUTO;
  539. STps = &(STp->ps[STp->partition]);
  540. if (STps->rw == ST_WRITING) {
  541. retval = osst_flush_buffer(STp, &SRpnt, 0);
  542. if (retval)
  543. goto out;
  544. STps->rw = ST_IDLE;
  545. /* FIXME -- this may leave the tape without EOD and up2date headers */
  546. }
  547. if ((count % STp->block_size) != 0) {
  548. printk(KERN_WARNING
  549.     "osst%d:W: Read (%Zd bytes) not multiple of tape block size (%d%c).n", dev, count,
  550.     STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k');
  551. }
  552. #if DEBUG
  553. if (debugging && STps->eof != ST_NOEOF)
  554. printk(OSST_DEB_MSG "osst%d:D: EOF/EOM flag up (%d). Bytes %dn", dev,
  555.      STps->eof, (STp->buffer)->buffer_bytes);
  556. #endif
  557. if ((STp->buffer)->buffer_bytes == 0 &&
  558.      STps->eof >= ST_EOD_1) {
  559. if (STps->eof < ST_EOD) {
  560. STps->eof += 1;
  561. retval = 0;
  562. goto out;
  563. }
  564. retval = (-EIO);  /* EOM or Blank Check */
  565. goto out;
  566. }
  567. /* Check the buffer writability before any tape movement. Don't alter
  568.  buffer data. */
  569. if (copy_from_user(&i, buf, 1)             != 0 ||
  570.     copy_to_user  (buf, &i, 1)             != 0 ||
  571.     copy_from_user(&i, buf + count - 1, 1) != 0 ||
  572.     copy_to_user  (buf + count - 1, &i, 1) != 0) {
  573. retval = (-EFAULT);
  574. goto out;
  575. }
  576. /* Loop until enough data in buffer or a special condition found */
  577. for (total = 0, special = 0; total < count - STp->block_size + 1 && !special; ) {
  578. /* Get new data if the buffer is empty */
  579. if ((STp->buffer)->buffer_bytes == 0) {
  580. if (STps->eof == ST_FM_HIT)
  581. break;
  582. special = osst_get_logical_frame(STp, &SRpnt, STp->frame_seq_number, 0);
  583. if (special < 0) {  /* No need to continue read */
  584. STp->frame_in_buffer = 0;
  585. retval = special;
  586. goto out;
  587. }
  588. }
  589. /* Move the data from driver buffer to user buffer */
  590. if ((STp->buffer)->buffer_bytes > 0) {
  591. #if DEBUG
  592. if (debugging && STps->eof != ST_NOEOF)
  593.     printk(OSST_DEB_MSG "osst%d:D: EOF up (%d). Left %d, needed %d.n", dev,
  594.  STps->eof, (STp->buffer)->buffer_bytes, count - total);
  595. #endif
  596. transfer = (((STp->buffer)->buffer_bytes < count - total ?
  597.      (STp->buffer)->buffer_bytes : count - total)/
  598. STp->block_size) * STp->block_size; /* force multiple of block size */
  599. i = from_buffer(STp->buffer, buf, transfer);
  600. if (i)  {
  601. retval = i;
  602. goto out;
  603. }
  604. STp->logical_blk_num += transfer / STp->block_size;
  605. STps->drv_block      += transfer / STp->block_size;
  606. filp->f_pos          += transfer;
  607. buf                  += transfer;
  608. total                += transfer;
  609. }
  610.  
  611. if ((STp->buffer)->buffer_bytes == 0) {
  612. #if DEBUG
  613. if (debugging)
  614. printk(OSST_DEB_MSG "osst%d:D: Finished with frame %dn",
  615.         dev, STp->frame_seq_number);
  616. #endif
  617. STp->frame_in_buffer = 0;
  618. STp->frame_seq_number++;              /* frame to look for next time */
  619. }
  620. } /* for (total = 0, special = 0; total < count && !special; ) */
  621. /* Change the eof state if no data from tape or buffer */
  622. if (total == 0) {
  623. if (STps->eof == ST_FM_HIT) {
  624. STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
  625. STps->drv_block = 0;
  626. if (STps->drv_file >= 0)
  627. STps->drv_file++;
  628. }
  629. else if (STps->eof == ST_EOD_1) {
  630. STps->eof = ST_EOD_2;
  631. if (STps->drv_block > 0 && STps->drv_file >= 0)
  632. STps->drv_file++;
  633. STps->drv_block = 0;
  634. }
  635. else if (STps->eof == ST_EOD_2)
  636. STps->eof = ST_EOD;
  637. }
  638. else if (STps->eof == ST_FM)
  639. STps->eof = ST_NOEOF;
  640. retval = total;
  641. out:
  642. if (SRpnt != NULL) scsi_release_request(SRpnt);
  643. up(&STp->lock);
  644. return retval;
  645. }
  646. /* Set the driver options */
  647. static void osst_log_options(OS_Scsi_Tape *STp, ST_mode *STm, int dev)
  648. {
  649.   printk(KERN_INFO
  650. "osst%d:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %dn",
  651.  dev, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
  652.  STm->do_read_ahead);
  653.   printk(KERN_INFO
  654. "osst%d:I:    can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,n",
  655.  dev, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
  656.   printk(KERN_INFO
  657. "osst%d:I:    defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %dn",
  658.  dev, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
  659.  STp->scsi2_logical);
  660.   printk(KERN_INFO
  661. "osst%d:I:    sysv: %dn", dev, STm->sysv);
  662. #if DEBUG
  663.   printk(KERN_INFO
  664.  "osst%d:D:    debugging: %dn",
  665.  dev, debugging);
  666. #endif
  667. }
  668. static int osst_set_options(OS_Scsi_Tape *STp, long options)
  669. {
  670. int value;
  671. long code;
  672. ST_mode *STm;
  673. int dev = TAPE_NR(STp->devt);
  674. STm = &(STp->modes[STp->current_mode]);
  675. if (!STm->defined) {
  676. memcpy(STm, &(STp->modes[0]), sizeof(ST_mode));
  677. modes_defined = TRUE;
  678. #if DEBUG
  679. if (debugging)
  680. printk(OSST_DEB_MSG "osst%d:D: Initialized mode %d definition from mode 0n",
  681.      dev, STp->current_mode);
  682. #endif
  683. }
  684. code = options & MT_ST_OPTIONS;
  685. if (code == MT_ST_BOOLEANS) {
  686. STm->do_buffer_writes = (options & MT_ST_BUFFER_WRITES) != 0;
  687. STm->do_async_writes  = (options & MT_ST_ASYNC_WRITES) != 0;
  688. STm->defaults_for_writes = (options & MT_ST_DEF_WRITES) != 0;
  689. STm->do_read_ahead    = (options & MT_ST_READ_AHEAD) != 0;
  690. STp->two_fm       = (options & MT_ST_TWO_FM) != 0;
  691. STp->fast_mteom       = (options & MT_ST_FAST_MTEOM) != 0;
  692. STp->do_auto_lock     = (options & MT_ST_AUTO_LOCK) != 0;
  693. STp->can_bsr          = (options & MT_ST_CAN_BSR) != 0;
  694. STp->omit_blklims     = (options & MT_ST_NO_BLKLIMS) != 0;
  695. if ((STp->device)->scsi_level >= SCSI_2)
  696. STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
  697. STp->scsi2_logical    = (options & MT_ST_SCSI2LOGICAL) != 0;
  698. STm->sysv       = (options & MT_ST_SYSV) != 0;
  699. #if DEBUG
  700. debugging = (options & MT_ST_DEBUGGING) != 0;
  701. #endif
  702. osst_log_options(STp, STm, dev);
  703. }
  704. else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
  705. value = (code == MT_ST_SETBOOLEANS);
  706. if ((options & MT_ST_BUFFER_WRITES) != 0)
  707. STm->do_buffer_writes = value;
  708. if ((options & MT_ST_ASYNC_WRITES) != 0)
  709. STm->do_async_writes = value;
  710. if ((options & MT_ST_DEF_WRITES) != 0)
  711. STm->defaults_for_writes = value;
  712. if ((options & MT_ST_READ_AHEAD) != 0)
  713. STm->do_read_ahead = value;
  714. if ((options & MT_ST_TWO_FM) != 0)
  715. STp->two_fm = value;
  716. if ((options & MT_ST_FAST_MTEOM) != 0)
  717. STp->fast_mteom = value;
  718. if ((options & MT_ST_AUTO_LOCK) != 0)
  719. STp->do_auto_lock = value;
  720. if ((options & MT_ST_CAN_BSR) != 0)
  721. STp->can_bsr = value;
  722. if ((options & MT_ST_NO_BLKLIMS) != 0)
  723. STp->omit_blklims = value;
  724. if ((STp->device)->scsi_level >= SCSI_2 &&
  725.     (options & MT_ST_CAN_PARTITIONS) != 0)
  726. STp->can_partitions = value;
  727. if ((options & MT_ST_SCSI2LOGICAL) != 0)
  728. STp->scsi2_logical = value;
  729. if ((options & MT_ST_SYSV) != 0)
  730. STm->sysv = value;
  731. #if DEBUG
  732. if ((options & MT_ST_DEBUGGING) != 0)
  733. debugging = value;
  734. #endif
  735. osst_log_options(STp, STm, dev);
  736. }
  737. else if (code == MT_ST_WRITE_THRESHOLD) {
  738. value = (options & ~MT_ST_OPTIONS) * ST_KILOBYTE;
  739. if (value < 1 || value > osst_buffer_size) {
  740. printk(KERN_WARNING "osst%d:W: Write threshold %d too small or too large.n",
  741.      dev, value);
  742. return (-EIO);
  743. }
  744. STp->write_threshold = value;
  745. printk(KERN_INFO "osst%d:I: Write threshold set to %d bytes.n",
  746.   dev, value);
  747. }
  748. else if (code == MT_ST_DEF_BLKSIZE) {
  749. value = (options & ~MT_ST_OPTIONS);
  750. if (value == ~MT_ST_OPTIONS) {
  751. STm->default_blksize = (-1);
  752. printk(KERN_INFO "osst%d:I: Default block size disabled.n", dev);
  753. }
  754. else {
  755. if (value < 512 || value > OS_DATA_SIZE || OS_DATA_SIZE % value) {
  756. printk(KERN_WARNING "osst%d:W: Default block size cannot be set to %d.n",
  757.  dev, value);
  758. return (-EINVAL);
  759. }
  760. STm->default_blksize = value;
  761. printk(KERN_INFO "osst%d:I: Default block size set to %d bytes.n",
  762.   dev, STm->default_blksize);
  763. }
  764. }
  765. else if (code == MT_ST_TIMEOUTS) {
  766. value = (options & ~MT_ST_OPTIONS);
  767. if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
  768. STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
  769. printk(KERN_INFO "osst%d:I: Long timeout set to %d seconds.n", dev,
  770.      (value & ~MT_ST_SET_LONG_TIMEOUT));
  771. }
  772. else {
  773. STp->timeout = value * HZ;
  774. printk(KERN_INFO "osst%d:I: Normal timeout set to %d seconds.n", dev, value);
  775. }
  776. }
  777. else if (code == MT_ST_DEF_OPTIONS) {
  778. code = (options & ~MT_ST_CLEAR_DEFAULT);
  779. value = (options & MT_ST_CLEAR_DEFAULT);
  780. if (code == MT_ST_DEF_DENSITY) {
  781. if (value == MT_ST_CLEAR_DEFAULT) {
  782. STm->default_density = (-1);
  783. printk(KERN_INFO "osst%d:I: Density default disabled.n", dev);
  784. }
  785. else {
  786. STm->default_density = value & 0xff;
  787. printk(KERN_INFO "osst%d:I: Density default set to %xn",
  788.   dev, STm->default_density);
  789. }
  790. }
  791. else if (code == MT_ST_DEF_DRVBUFFER) {
  792. if (value == MT_ST_CLEAR_DEFAULT) {
  793. STp->default_drvbuffer = 0xff;
  794. printk(KERN_INFO "osst%d:I: Drive buffer default disabled.n", dev);
  795. }
  796. else {
  797. STp->default_drvbuffer = value & 7;
  798. printk(KERN_INFO "osst%d:I: Drive buffer default set to %xn",
  799.   dev, STp->default_drvbuffer);
  800. }
  801. }
  802. else if (code == MT_ST_DEF_COMPRESSION) {
  803. if (value == MT_ST_CLEAR_DEFAULT) {
  804. STm->default_compression = ST_DONT_TOUCH;
  805. printk(KERN_INFO "osst%d:I: Compression default disabled.n", dev);
  806. }
  807. else {
  808. STm->default_compression = (value & 1 ? ST_YES : ST_NO);
  809. printk(KERN_INFO "osst%d:I: Compression default set to %xn",
  810.   dev, (value & 1));
  811. }
  812. }
  813. }
  814. else
  815. return (-EIO);
  816. return 0;
  817. }
  818. /* Internal ioctl function */
  819. static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned int cmd_in, unsigned long arg)
  820. {
  821. int timeout;
  822. long ltmp;
  823. int i, ioctl_result;
  824. int chg_eof = TRUE;
  825. unsigned char cmd[MAX_COMMAND_SIZE];
  826. Scsi_Request * SRpnt = * aSRpnt;
  827. ST_partstat * STps;
  828. int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
  829. int datalen = 0, direction = SCSI_DATA_NONE;
  830. int dev = TAPE_NR(STp->devt);
  831. if (STp->ready != ST_READY && cmd_in != MTLOAD) {
  832. if (STp->ready == ST_NO_TAPE)
  833. return (-ENOMEDIUM);
  834. else
  835. return (-EIO);
  836. }
  837. timeout = STp->long_timeout;
  838. STps = &(STp->ps[STp->partition]);
  839. fileno = STps->drv_file;
  840. blkno = STps->drv_block;
  841. at_sm = STps->at_sm;
  842. frame_seq_numbr = STp->frame_seq_number;
  843. logical_blk_num = STp->logical_blk_num;
  844. memset(cmd, 0, MAX_COMMAND_SIZE);
  845. switch (cmd_in) {
  846.  case MTFSFM:
  847. chg_eof = FALSE; /* Changed from the FSF after this */
  848.  case MTFSF:
  849. if (STp->raw)
  850.    return (-EIO);
  851. if (STp->linux_media)
  852.    ioctl_result = osst_space_over_filemarks_forward_fast(STp, &SRpnt, cmd_in, arg);
  853. else
  854.    ioctl_result = osst_space_over_filemarks_forward_slow(STp, &SRpnt, cmd_in, arg);
  855. if (fileno >= 0)
  856.    fileno += arg;
  857. blkno = 0;
  858. at_sm &= (arg == 0);
  859. goto os_bypass;
  860.  case MTBSF:
  861. chg_eof = FALSE; /* Changed from the FSF after this */
  862.  case MTBSFM:
  863. if (STp->raw)
  864.    return (-EIO);
  865. ioctl_result = osst_space_over_filemarks_backward(STp, &SRpnt, cmd_in, arg);
  866. if (fileno >= 0)
  867.    fileno -= arg;
  868. blkno = (-1);  /* We can't know the block number */
  869. at_sm &= (arg == 0);
  870. goto os_bypass;
  871.  case MTFSR:
  872.  case MTBSR:
  873. #if DEBUG
  874. if (debugging)
  875.    printk(OSST_DEB_MSG "osst%d:D: Skipping %lu blocks %s from logical block %dn",
  876. dev, arg, cmd_in==MTFSR?"forward":"backward", logical_blk_num);
  877. #endif
  878. if (cmd_in == MTFSR) {
  879.    logical_blk_num += arg;
  880.    if (blkno >= 0) blkno += arg;
  881. }
  882. else {
  883.    logical_blk_num -= arg;
  884.    if (blkno >= 0) blkno -= arg;
  885. }
  886. ioctl_result = osst_seek_logical_blk(STp, &SRpnt, logical_blk_num);
  887. fileno = STps->drv_file;
  888. blkno  = STps->drv_block;
  889. at_sm &= (arg == 0);
  890. goto os_bypass;
  891.  case MTFSS:
  892. cmd[0] = SPACE;
  893. cmd[1] = 0x04; /* Space Setmarks */   /* FIXME -- OS can't do this? */
  894. cmd[2] = (arg >> 16);
  895. cmd[3] = (arg >> 8);
  896. cmd[4] = arg;
  897. #if DEBUG
  898. if (debugging)
  899. printk(OSST_DEB_MSG "osst%d:D: Spacing tape forward %d setmarks.n", dev,
  900. cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
  901. #endif
  902. if (arg != 0) {
  903. blkno = fileno = (-1);
  904. at_sm = 1;
  905. }
  906. break;
  907.  case MTBSS:
  908. cmd[0] = SPACE;
  909. cmd[1] = 0x04; /* Space Setmarks */   /* FIXME -- OS can't do this? */
  910. ltmp = (-arg);
  911. cmd[2] = (ltmp >> 16);
  912. cmd[3] = (ltmp >> 8);
  913. cmd[4] = ltmp;
  914. #if DEBUG
  915. if (debugging) {
  916. if (cmd[2] & 0x80)
  917.    ltmp = 0xff000000;
  918. ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
  919. printk(OSST_DEB_MSG "osst%d:D: Spacing tape backward %ld setmarks.n",
  920. dev, (-ltmp));
  921.  }
  922. #endif
  923.  if (arg != 0) {
  924. blkno = fileno = (-1);
  925. at_sm = 1;
  926.  }
  927.  break;
  928.  case MTWEOF:
  929.  if ( STps->rw == ST_WRITING && !(STp->device)->was_reset)
  930. ioctl_result = osst_flush_write_buffer(STp, &SRpnt);
  931.  else
  932. ioctl_result = 0;
  933. #if DEBUG
  934.  if (debugging) 
  935.    printk(OSST_DEB_MSG "osst%d:D: Writing %ld filemark(s).n", dev, arg);
  936. #endif
  937.  for (i=0; i<arg; i++)
  938. ioctl_result |= osst_write_filemark(STp, &SRpnt);
  939.  if (fileno >= 0) fileno += arg;
  940.  if (blkno  >= 0) blkno   = 0;
  941.  goto os_bypass;
  942.  case MTWSM:
  943.  if (STp->write_prot)
  944. return (-EACCES);
  945.  if (!STp->raw)
  946. return 0;
  947.  cmd[0] = WRITE_FILEMARKS;   /* FIXME -- need OS version */
  948.  if (cmd_in == MTWSM)
  949.  cmd[1] = 2;
  950.  cmd[2] = (arg >> 16);
  951.  cmd[3] = (arg >> 8);
  952.  cmd[4] = arg;
  953.  timeout = STp->timeout;
  954. #if DEBUG
  955.  if (debugging) 
  956.    printk(OSST_DEB_MSG "osst%d:D: Writing %d setmark(s).n", dev,
  957.   cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
  958. #endif
  959.  if (fileno >= 0)
  960. fileno += arg;
  961.  blkno = 0;
  962.  at_sm = (cmd_in == MTWSM);
  963.  break;
  964.  case MTOFFL:
  965.  case MTLOAD:
  966.  case MTUNLOAD:
  967.  case MTRETEN:
  968.  cmd[0] = START_STOP;
  969.  cmd[1] = 1; /* Don't wait for completion */
  970.  if (cmd_in == MTLOAD) {
  971.      if (STp->ready == ST_NO_TAPE)
  972.  cmd[4] = 4; /* open tray */
  973.       else
  974.  cmd[4] = 1; /* load */
  975.  }
  976.  if (cmd_in == MTRETEN)
  977.  cmd[4] = 3; /* retension then mount */
  978.  if (cmd_in == MTOFFL)
  979.  cmd[4] = 4; /* rewind then eject */
  980.  timeout = STp->timeout;
  981. #if DEBUG
  982.  if (debugging) {
  983.  switch (cmd_in) {
  984.  case MTUNLOAD:
  985.  printk(OSST_DEB_MSG "osst%d:D: Unloading tape.n", dev);
  986.  break;
  987.  case MTLOAD:
  988.  printk(OSST_DEB_MSG "osst%d:D: Loading tape.n", dev);
  989.  break;
  990.  case MTRETEN:
  991.  printk(OSST_DEB_MSG "osst%d:D: Retensioning tape.n", dev);
  992.  break;
  993.  case MTOFFL:
  994.  printk(OSST_DEB_MSG "osst%d:D: Ejecting tape.n", dev);
  995.  break;
  996.  }
  997.  }
  998. #endif
  999.        fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
  1000.  break;
  1001.  case MTNOP:
  1002. #if DEBUG
  1003.  if (debugging)
  1004.  printk(OSST_DEB_MSG "osst%d:D: No-op on tape.n", dev);
  1005. #endif
  1006.  return 0;  /* Should do something ? */
  1007.  break;
  1008.  case MTEOM:
  1009. #if DEBUG
  1010. if (debugging)
  1011.    printk(OSST_DEB_MSG "osst%d:D: Spacing to end of recorded medium.n", dev);
  1012. #endif
  1013. osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
  1014. if (osst_get_logical_frame(STp, &SRpnt, -1, 0) < 0) {
  1015.    ioctl_result = -EIO;
  1016.    goto os_bypass;
  1017. }
  1018. if (STp->buffer->aux->frame_type != OS_FRAME_TYPE_EOD) {
  1019. #if DEBUG
  1020.    printk(OSST_DEB_MSG "osst%d:D: No EOD frame found where expected.n", dev);
  1021. #endif
  1022.    ioctl_result = -EIO;
  1023.    goto os_bypass;
  1024. }
  1025. ioctl_result = osst_set_frame_position(STp, &SRpnt, STp->eod_frame_ppos, 0);
  1026. fileno = STp->filemark_cnt;
  1027. blkno  = at_sm = 0;
  1028. goto os_bypass;
  1029.  case MTERASE:
  1030. if (STp->write_prot)
  1031.    return (-EACCES);
  1032. ioctl_result = osst_reset_header(STp, &SRpnt);
  1033. i = osst_write_eod(STp, &SRpnt);
  1034. if (i < ioctl_result) ioctl_result = i;
  1035. i = osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos);
  1036. if (i < ioctl_result) ioctl_result = i;
  1037. fileno = blkno = at_sm = 0 ;
  1038. goto os_bypass;
  1039.  case MTREW:
  1040. cmd[0] = REZERO_UNIT; /* rewind */
  1041. cmd[1] = 1;
  1042. #if DEBUG
  1043. if (debugging)
  1044.    printk(OSST_DEB_MSG "osst%d:D: Rewinding tape, Immed=%d.n", dev, cmd[1]);
  1045. #endif
  1046. fileno = blkno = at_sm = frame_seq_numbr = logical_blk_num = 0 ;
  1047. break;
  1048.  case MTLOCK:
  1049. chg_eof = FALSE;
  1050. cmd[0] = ALLOW_MEDIUM_REMOVAL;
  1051. cmd[4] = SCSI_REMOVAL_PREVENT;
  1052. #if DEBUG
  1053. if (debugging)
  1054.     printk(OSST_DEB_MSG "osst%d:D: Locking drive door.n", dev);
  1055. #endif
  1056. break;
  1057.  case MTUNLOCK:
  1058. chg_eof = FALSE;
  1059. cmd[0] = ALLOW_MEDIUM_REMOVAL;
  1060. cmd[4] = SCSI_REMOVAL_ALLOW;
  1061. #if DEBUG
  1062. if (debugging)
  1063.    printk(OSST_DEB_MSG "osst%d:D: Unlocking drive door.n", dev);
  1064. #endif
  1065. break;
  1066.  case MTSETBLK:           /* Set block length */
  1067.  case MTSETDENSITY:       /* Set tape density */
  1068.  case MTSETDRVBUFFER:     /* Set drive buffering */
  1069.  case SET_DENS_AND_BLK:   /* Set density and block size */
  1070.  chg_eof = FALSE;
  1071.  if (STp->dirty || (STp->buffer)->buffer_bytes != 0)
  1072.  return (-EIO);       /* Not allowed if data in buffer */
  1073.  if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) &&
  1074.    (arg & MT_ST_BLKSIZE_MASK) != 0 &&
  1075.    ((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
  1076.     (arg & MT_ST_BLKSIZE_MASK) > STp->max_block ||
  1077.     (arg & MT_ST_BLKSIZE_MASK) > osst_buffer_size)) {
  1078.  printk(KERN_WARNING "osst%d:W: Illegal block size.n", dev);
  1079.  return (-EINVAL);
  1080.  }
  1081.  return 0;  /* FIXME silently ignore if block size didn't change */
  1082.  default:
  1083. return (-ENOSYS);
  1084. }
  1085. SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, TRUE);
  1086. ioctl_result = (STp->buffer)->syscall_result;
  1087. if (!SRpnt) {
  1088. #if DEBUG
  1089. printk(OSST_DEB_MSG "osst%d:D: Couldn't exec scsi cmd for IOCTLn", dev);
  1090. #endif
  1091. return ioctl_result;
  1092. }
  1093. if (!ioctl_result) {  /* SCSI command successful */
  1094. STp->frame_seq_number = frame_seq_numbr;
  1095. STp->logical_blk_num  = logical_blk_num;
  1096. }
  1097. os_bypass:
  1098. #if DEBUG
  1099. if (debugging)
  1100. printk(OSST_DEB_MSG "osst%d:D: IOCTL (%d) Result=%dn", dev, cmd_in, ioctl_result);
  1101. #endif
  1102. if (!ioctl_result) { /* success */
  1103. if (cmd_in == MTFSFM) {
  1104.  fileno--;
  1105.  blkno--;
  1106. }
  1107. if (cmd_in == MTBSFM) {
  1108.  fileno++;
  1109.  blkno++;
  1110. }
  1111. STps->drv_block = blkno;
  1112. STps->drv_file = fileno;
  1113. STps->at_sm = at_sm;
  1114. if (cmd_in == MTLOCK)
  1115.  STp->door_locked = ST_LOCKED_EXPLICIT;
  1116. else if (cmd_in == MTUNLOCK)
  1117. STp->door_locked = ST_UNLOCKED;
  1118. if (cmd_in == MTEOM)
  1119. STps->eof = ST_EOD;
  1120. else if (cmd_in == MTFSF)
  1121. STps->eof = (STp->first_frame_position >= STp->eod_frame_ppos)?ST_EOD:ST_FM;
  1122. else if (chg_eof)
  1123. STps->eof = ST_NOEOF;
  1124. if (cmd_in == MTOFFL || cmd_in == MTUNLOAD)
  1125. STp->rew_at_close = 0;
  1126. else if (cmd_in == MTLOAD) {
  1127. /*       STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0;  FIXME */
  1128. for (i=0; i < ST_NBR_PARTITIONS; i++) {
  1129.     STp->ps[i].rw = ST_IDLE;
  1130.     STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */
  1131. }
  1132. STp->partition = 0;
  1133. }
  1134. if (cmd_in == MTREW) {
  1135. ioctl_result = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos); 
  1136. if (ioctl_result > 0)
  1137. ioctl_result = 0;
  1138. }
  1139. } else if (cmd_in == MTBSF || cmd_in == MTBSFM ) {
  1140. if (osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos) < 0)
  1141. STps->drv_file = STps->drv_block = -1;
  1142. else
  1143. STps->drv_file = STps->drv_block = 0;
  1144. STps->eof = ST_NOEOF;
  1145. } else if (cmd_in == MTFSF || cmd_in == MTFSFM) {
  1146. if (osst_position_tape_and_confirm(STp, &SRpnt, STp->eod_frame_ppos) < 0)
  1147. STps->drv_file = STps->drv_block = -1;
  1148. else {
  1149. STps->drv_file  = STp->filemark_cnt;
  1150. STps->drv_block = 0;
  1151. }
  1152. STps->eof = ST_EOD;
  1153. } else if (cmd_in == MTBSR || cmd_in == MTFSR || cmd_in == MTWEOF || cmd_in == MTEOM) {
  1154. STps->drv_file = STps->drv_block = (-1);
  1155. STps->eof = ST_NOEOF;
  1156. STp->header_ok = 0;
  1157. } else if (cmd_in == MTERASE) {
  1158. STp->header_ok = 0;
  1159. } else if (SRpnt) {  /* SCSI command was not completely successful. */
  1160. if (SRpnt->sr_sense_buffer[2] & 0x40) {
  1161. STps->eof = ST_EOM_OK;
  1162. STps->drv_block = 0;
  1163. }
  1164. if (chg_eof)
  1165. STps->eof = ST_NOEOF;
  1166. if ((SRpnt->sr_sense_buffer[2] & 0x0f) == BLANK_CHECK)
  1167. STps->eof = ST_EOD;
  1168. if (cmd_in == MTLOCK)
  1169. STp->door_locked = ST_LOCK_FAILS;
  1170. if (cmd_in == MTLOAD && osst_wait_for_medium(STp, &SRpnt, 60))
  1171. ioctl_result = osst_wait_ready(STp, &SRpnt, 5 * 60);
  1172. }
  1173. *aSRpnt = SRpnt;
  1174. return ioctl_result;
  1175. }
  1176. /* Open the device */
  1177. static int os_scsi_tape_open(struct inode * inode, struct file * filp)
  1178. {
  1179. unsigned short flags;
  1180. int i, b_size, need_dma_buffer, new_session = FALSE, retval = 0;
  1181. unsigned char cmd[MAX_COMMAND_SIZE];
  1182. Scsi_Request * SRpnt;
  1183. OS_Scsi_Tape * STp;
  1184. ST_mode * STm;
  1185. ST_partstat * STps;
  1186. int dev = TAPE_NR(inode->i_rdev);
  1187. int mode = TAPE_MODE(inode->i_rdev);
  1188. if (dev >= osst_template.dev_max || (STp = os_scsi_tapes[dev]) == NULL || !STp->device)
  1189. return (-ENXIO);
  1190. if( !scsi_block_when_processing_errors(STp->device) ) {
  1191. return -ENXIO;
  1192. }
  1193. if (STp->in_use) {
  1194. #if DEBUG
  1195. printk(OSST_DEB_MSG "osst%d:D: Device already in use.n", dev);
  1196. #endif
  1197. return (-EBUSY);
  1198. }
  1199. STp->in_use       = 1;
  1200. STp->rew_at_close = (MINOR(inode->i_rdev) & 0x80) == 0;
  1201. if (STp->device->host->hostt->module)
  1202.  __MOD_INC_USE_COUNT(STp->device->host->hostt->module);
  1203. if (osst_template.module)
  1204.  __MOD_INC_USE_COUNT(osst_template.module);
  1205. STp->device->access_count++;
  1206. if (mode != STp->current_mode) {
  1207. #if DEBUG
  1208. if (debugging)
  1209. printk(OSST_DEB_MSG "osst%d:D: Mode change from %d to %d.n",
  1210.        dev, STp->current_mode, mode);
  1211. #endif
  1212. new_session = TRUE;
  1213. STp->current_mode = mode;
  1214. }
  1215. STm = &(STp->modes[STp->current_mode]);
  1216. flags = filp->f_flags;
  1217. STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY);
  1218. STp->raw = (MINOR(inode->i_rdev) & 0x40) != 0;
  1219. if (STp->raw)
  1220. STp->header_ok = 0;
  1221. /* Allocate a buffer for this user */
  1222. need_dma_buffer = STp->restr_dma;
  1223. for (i=0; i < osst_nbr_buffers; i++)
  1224. if (!osst_buffers[i]->in_use &&
  1225.    (!need_dma_buffer || osst_buffers[i]->dma))
  1226. break;
  1227. if (i >= osst_nbr_buffers) {
  1228. STp->buffer = new_tape_buffer(FALSE, need_dma_buffer);
  1229. if (STp->buffer == NULL) {
  1230. printk(KERN_WARNING "osst%d:W: Can't allocate tape buffer.n", dev);
  1231. retval = (-EBUSY);
  1232. goto err_out;
  1233. }
  1234. }
  1235. else
  1236. STp->buffer = osst_buffers[i];
  1237. (STp->buffer)->in_use = 1;
  1238. (STp->buffer)->writing = 0;
  1239. (STp->buffer)->syscall_result = 0;
  1240. (STp->buffer)->use_sg = STp->device->host->sg_tablesize;
  1241. /* Compute the usable buffer size for this SCSI adapter */
  1242. if (!(STp->buffer)->use_sg)
  1243. (STp->buffer)->buffer_size = (STp->buffer)->sg[0].length;
  1244. else {
  1245. for (i=0, (STp->buffer)->buffer_size = 0; i < (STp->buffer)->use_sg &&
  1246.      i < (STp->buffer)->sg_segs; i++)
  1247. (STp->buffer)->buffer_size += (STp->buffer)->sg[i].length;
  1248. }
  1249. STp->dirty = 0;
  1250. for (i=0; i < ST_NBR_PARTITIONS; i++) {
  1251. STps = &(STp->ps[i]);
  1252. STps->rw = ST_IDLE;
  1253. }
  1254. STp->ready = ST_READY;
  1255. #if DEBUG
  1256. STp->nbr_waits = STp->nbr_finished = 0;
  1257. #endif
  1258. memset (cmd, 0, MAX_COMMAND_SIZE);
  1259. cmd[0] = TEST_UNIT_READY;
  1260. SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
  1261. if (!SRpnt) {
  1262. retval = (STp->buffer)->syscall_result;
  1263. goto err_out;
  1264. }
  1265. if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70      &&
  1266.     (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
  1267.      SRpnt->sr_sense_buffer[12]        == 4         ) {
  1268. #if DEBUG
  1269. printk(OSST_DEB_MSG "osst%d:D: Unit not ready, cause %xn", dev, SRpnt->sr_sense_buffer[13]);
  1270. #endif
  1271. if (SRpnt->sr_sense_buffer[13] == 2) { /* initialize command required (LOAD) */
  1272. memset (cmd, 0, MAX_COMMAND_SIZE);
  1273.          cmd[0] = START_STOP;
  1274. cmd[1] = 1;
  1275. cmd[4] = 1;
  1276. SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
  1277.      STp->timeout, MAX_READY_RETRIES, TRUE);
  1278. }
  1279. osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60);
  1280. }
  1281. if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
  1282.     (SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
  1283. #if DEBUG
  1284. printk(OSST_DEB_MSG "osst%d:D: Unit wants attentionn", dev);
  1285. #endif
  1286. STp->header_ok = 0;
  1287. for (i=0; i < 10; i++) {
  1288. memset (cmd, 0, MAX_COMMAND_SIZE);
  1289. cmd[0] = TEST_UNIT_READY;
  1290. SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
  1291.      STp->timeout, MAX_READY_RETRIES, TRUE);
  1292. if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
  1293.     (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
  1294. break;
  1295. }
  1296. STp->device->was_reset = 0;
  1297. STp->partition = STp->new_partition = 0;
  1298. if (STp->can_partitions)
  1299. STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
  1300. for (i=0; i < ST_NBR_PARTITIONS; i++) {
  1301. STps = &(STp->ps[i]);
  1302. STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */
  1303. STps->eof = ST_NOEOF;
  1304. STps->at_sm = 0;
  1305. STps->last_block_valid = FALSE;
  1306. STps->drv_block = 0;
  1307. STps->drv_file = 0 ;
  1308. }
  1309. new_session = TRUE;
  1310. STp->recover_count = 0;
  1311. }
  1312. /*
  1313.  * if we have valid headers from before, and the drive/tape seem untouched,
  1314.  * open without reconfiguring and re-reading the headers
  1315.  */
  1316. if (!STp->buffer->syscall_result && STp->header_ok &&
  1317.     !SRpnt->sr_result && SRpnt->sr_sense_buffer[0] == 0) {
  1318. memset(cmd, 0, MAX_COMMAND_SIZE);
  1319. cmd[0] = MODE_SENSE;
  1320. cmd[1] = 8;
  1321. cmd[2] = VENDOR_IDENT_PAGE;
  1322. cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
  1323. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE);
  1324. if (STp->buffer->syscall_result                     ||
  1325.     STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
  1326.     STp->buffer->b_data[MODE_HEADER_LENGTH + 3] != 'I' ||
  1327.     STp->buffer->b_data[MODE_HEADER_LENGTH + 4] != 'N' ||
  1328.     STp->buffer->b_data[MODE_HEADER_LENGTH + 5] != '4'  ) {
  1329. #if DEBUG
  1330. printk(OSST_DEB_MSG "osst%d:D: Signature was changed to %c%c%c%cn", dev,
  1331.   STp->buffer->b_data[MODE_HEADER_LENGTH + 2],
  1332.   STp->buffer->b_data[MODE_HEADER_LENGTH + 3],
  1333.   STp->buffer->b_data[MODE_HEADER_LENGTH + 4],
  1334.   STp->buffer->b_data[MODE_HEADER_LENGTH + 5]);
  1335. #endif
  1336. STp->header_ok = 0;
  1337. }
  1338. i = STp->first_frame_position;
  1339. if (STp->header_ok && i == osst_get_frame_position(STp, &SRpnt)) {
  1340. if (STp->door_locked == ST_UNLOCKED) {
  1341. if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
  1342. printk(KERN_INFO "osst%d:I: Can't lock drive doorn", dev);
  1343. else
  1344. STp->door_locked = ST_LOCKED_AUTO;
  1345. }
  1346. if (!STp->frame_in_buffer) {
  1347. STp->block_size = (STm->default_blksize > 0) ?
  1348. STm->default_blksize : OS_DATA_SIZE;
  1349. STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0;
  1350. }
  1351. STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size;
  1352. STp->fast_open = TRUE;
  1353. scsi_release_request(SRpnt);
  1354. return 0;
  1355. }
  1356. #if DEBUG
  1357. if (i != STp->first_frame_position)
  1358. printk(OSST_DEB_MSG "osst%d:D: Tape position changed from %d to %dn",
  1359. dev, i, STp->first_frame_position);
  1360. #endif
  1361. STp->header_ok = 0;
  1362. }
  1363. STp->fast_open = FALSE;
  1364. if ((STp->buffer)->syscall_result != 0 &&   /* in all error conditions except no medium */ 
  1365.     (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) {
  1366. memset(cmd, 0, MAX_COMMAND_SIZE);
  1367. cmd[0] = MODE_SELECT;
  1368. cmd[1] = 0x10;
  1369. cmd[4] = 4 + MODE_HEADER_LENGTH;
  1370. (STp->buffer)->b_data[0] = cmd[4] - 1;
  1371. (STp->buffer)->b_data[1] = 0; /* Medium Type - ignoring */
  1372. (STp->buffer)->b_data[2] = 0; /* Reserved */
  1373. (STp->buffer)->b_data[3] = 0; /* Block Descriptor Length */
  1374. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 0] = 0x3f;
  1375. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 1] = 1;
  1376. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 2] = 2;
  1377. (STp->buffer)->b_data[MODE_HEADER_LENGTH + 3] = 3;
  1378. #if DEBUG
  1379. printk(OSST_DEB_MSG "osst%d:D: Applying soft resetn", dev);
  1380. #endif
  1381. SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE);
  1382. STp->header_ok = 0;
  1383. for (i=0; i < 10; i++) {
  1384. memset (cmd, 0, MAX_COMMAND_SIZE);
  1385. cmd[0] = TEST_UNIT_READY;
  1386. SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
  1387.      STp->timeout, MAX_READY_RETRIES, TRUE);
  1388. if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
  1389.     (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
  1390. break;
  1391. if ((SRpnt->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION) {
  1392. STp->device->was_reset = 0;
  1393. STp->partition = STp->new_partition = 0;
  1394. if (STp->can_partitions)
  1395. STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
  1396. for (i=0; i < ST_NBR_PARTITIONS; i++) {
  1397. STps = &(STp->ps[i]);
  1398. STps->rw = ST_IDLE;
  1399. STps->eof = ST_NOEOF;
  1400. STps->at_sm = 0;
  1401. STps->last_block_valid = FALSE;
  1402. STps->drv_block = 0;
  1403. STps->drv_file = 0 ;
  1404. }
  1405. new_session = TRUE;
  1406. }
  1407. }
  1408. }
  1409. if (osst_wait_ready(STp, &SRpnt, 15 * 60)) /* FIXME - not allowed with NOBLOCK */
  1410.  printk(KERN_INFO "osst%i:I: Device did not become Ready in openn",dev);
  1411. if ((STp->buffer)->syscall_result != 0) {
  1412. if ((STp->device)->scsi_level >= SCSI_2 &&
  1413.     (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 &&
  1414.     (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY &&
  1415.      SRpnt->sr_sense_buffer[12] == 0x3a) { /* Check ASC */
  1416. STp->ready = ST_NO_TAPE;
  1417. } else
  1418. STp->ready = ST_NOT_READY;
  1419. scsi_release_request(SRpnt);
  1420. SRpnt = NULL;
  1421. STp->density = 0;    /* Clear the erroneous "residue" */
  1422. STp->write_prot = 0;
  1423. STp->block_size = 0;
  1424. STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
  1425. STp->partition = STp->new_partition = 0;
  1426. STp->door_locked = ST_UNLOCKED;
  1427. return 0;
  1428. }
  1429. osst_configure_onstream(STp, &SRpnt);
  1430. /* STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; FIXME */
  1431. if (OS_FRAME_SIZE > (STp->buffer)->buffer_size &&
  1432.     !enlarge_buffer(STp->buffer, OS_FRAME_SIZE, STp->restr_dma)) {
  1433. printk(KERN_NOTICE "osst%d:A: Framesize %d too large for buffer.n", dev,
  1434.      OS_FRAME_SIZE);
  1435. retval = (-EIO);
  1436. goto err_out;
  1437. }
  1438. if ((STp->buffer)->buffer_size >= OS_FRAME_SIZE) {
  1439. for (i = 0, b_size = 0; 
  1440.      i < STp->buffer->sg_segs && (b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE; 
  1441.      b_size += STp->buffer->sg[i++].length);
  1442. STp->buffer->aux = (os_aux_t *) (STp->buffer->sg[i].address + OS_DATA_SIZE - b_size);
  1443. #if DEBUG
  1444. printk(OSST_DEB_MSG "osst%d:D: b_data points to %p in segment 0 at %pn", dev,
  1445. STp->buffer->b_data, STp->buffer->sg[0].address);
  1446. printk(OSST_DEB_MSG "osst%d:D: AUX points to %p in segment %d at %pn", dev,
  1447.  STp->buffer->aux, i, STp->buffer->sg[i].address);
  1448. #endif
  1449. } else
  1450. STp->buffer->aux = NULL; /* this had better never happen! */
  1451. STp->block_size = STp->raw ? OS_FRAME_SIZE : (
  1452.      (STm->default_blksize > 0) ? STm->default_blksize : OS_DATA_SIZE);
  1453. STp->buffer->buffer_blocks = STp->raw ? 1 : OS_DATA_SIZE / STp->block_size;
  1454. STp->buffer->buffer_bytes  =
  1455. STp->buffer->read_pointer  =
  1456. STp->frame_in_buffer       = 0;
  1457. #if DEBUG
  1458. if (debugging)
  1459. printk(OSST_DEB_MSG "osst%d:D: Block size: %d, frame size: %d, buffer size: %d (%d blocks).n",
  1460.      dev, STp->block_size, OS_FRAME_SIZE, (STp->buffer)->buffer_size,
  1461.      (STp->buffer)->buffer_blocks);
  1462. #endif
  1463. if (STp->drv_write_prot) {
  1464. STp->write_prot = 1;
  1465. #if DEBUG
  1466. if (debugging)
  1467. printk(OSST_DEB_MSG "osst%d:D: Write protectedn", dev);
  1468. #endif
  1469. if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
  1470. retval = (-EROFS);
  1471. goto err_out;
  1472. }
  1473. }
  1474. if (new_session) {  /* Change the drive parameters for the new mode */
  1475. #if DEBUG
  1476. if (debugging)
  1477. printk(OSST_DEB_MSG "osst%d:D: New Sessionn", dev);
  1478. #endif
  1479. STp->density_changed = STp->blksize_changed = FALSE;
  1480. STp->compression_changed = FALSE;
  1481. }
  1482. /*
  1483.  * properly position the tape and check the ADR headers
  1484.  */
  1485. if (STp->door_locked == ST_UNLOCKED) {
  1486.  if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0))
  1487. printk(KERN_INFO "osst%d:I: Can't lock drive doorn", dev);
  1488.  else
  1489. STp->door_locked = ST_LOCKED_AUTO;
  1490. }
  1491. osst_analyze_headers(STp, &SRpnt);
  1492. scsi_release_request(SRpnt);
  1493. SRpnt = NULL;
  1494. return 0;
  1495. err_out:
  1496. if (SRpnt != NULL)
  1497. scsi_release_request(SRpnt);
  1498. if (STp->buffer != NULL) {
  1499. STp->buffer->in_use = 0;
  1500. STp->buffer = NULL;
  1501. }
  1502. STp->in_use = 0;
  1503. STp->header_ok = 0;
  1504. STp->device->access_count--;
  1505. if (STp->device->host->hostt->module)
  1506.     __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
  1507. if (osst_template.module)
  1508.     __MOD_DEC_USE_COUNT(osst_template.module);
  1509. return retval;
  1510. }
  1511. /* Flush the tape buffer before close */
  1512. static int os_scsi_tape_flush(struct file * filp)
  1513. {
  1514. int result = 0, result2;
  1515. OS_Scsi_Tape * STp;
  1516. ST_mode * STm;
  1517. ST_partstat * STps;
  1518. Scsi_Request *SRpnt = NULL;
  1519. struct inode *inode = filp->f_dentry->d_inode;
  1520. kdev_t devt = inode->i_rdev;
  1521. int dev;
  1522. if (file_count(filp) > 1)
  1523. return 0;
  1524. dev = TAPE_NR(devt);
  1525. STp = os_scsi_tapes[dev];
  1526. STm = &(STp->modes[STp->current_mode]);
  1527. STps = &(STp->ps[STp->partition]);
  1528. if ( STps->rw == ST_WRITING && !(STp->device)->was_reset) {
  1529. result = osst_flush_write_buffer(STp, &SRpnt);
  1530. if (result != 0 && result != (-ENOSPC))
  1531. goto out;
  1532. }
  1533. if ( STps->rw >= ST_WRITING && !(STp->device)->was_reset) {
  1534. #if DEBUG
  1535. if (debugging) {
  1536. printk(OSST_DEB_MSG "osst%d:D: File length %ld bytes.n",
  1537.        dev, (long)(filp->f_pos));
  1538. printk(OSST_DEB_MSG "osst%d:D: Async write waits %d, finished %d.n",
  1539.        dev, STp->nbr_waits, STp->nbr_finished);
  1540. }
  1541. #endif
  1542. if (STp->write_type != OS_WRITE_NEW_MARK) {
  1543. /* true unless the user wrote the filemark for us */
  1544. result = osst_flush_drive_buffer(STp, &SRpnt);
  1545. if (result < 0) goto out;
  1546. result = osst_write_filemark(STp, &SRpnt);
  1547. if (result < 0) goto out;
  1548. if (STps->drv_file >= 0)
  1549. STps->drv_file++ ;
  1550. STps->drv_block = 0;
  1551. }
  1552. result = osst_write_eod(STp, &SRpnt);
  1553. osst_write_header(STp, &SRpnt, !(STp->rew_at_close));
  1554. STps->eof = ST_FM;
  1555. #if DEBUG
  1556. if (debugging)
  1557. printk(OSST_DEB_MSG "osst%d:D: Buffer flushed, %d EOF(s) writtenn",
  1558.        dev, 1+STp->two_fm);
  1559. #endif
  1560. }
  1561. else if (!STp->rew_at_close) {
  1562. STps = &(STp->ps[STp->partition]);
  1563. if (!STm->sysv || STps->rw != ST_READING) {
  1564. if (STp->can_bsr)
  1565. result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */
  1566. else if (STps->eof == ST_FM_HIT) {
  1567. result = cross_eof(STp, &SRpnt, FALSE);
  1568. if (result) {
  1569. if (STps->drv_file >= 0)
  1570. STps->drv_file++;
  1571. STps->drv_block = 0;
  1572. STps->eof = ST_FM;
  1573. }
  1574. else
  1575. STps->eof = ST_NOEOF;
  1576. }
  1577. }
  1578. else if ((STps->eof == ST_NOEOF &&
  1579.   !(result = cross_eof(STp, &SRpnt, TRUE))) ||
  1580.   STps->eof == ST_FM_HIT) {
  1581. if (STps->drv_file >= 0)
  1582. STps->drv_file++;
  1583. STps->drv_block = 0;
  1584. STps->eof = ST_FM;
  1585. }
  1586. }
  1587. out:
  1588. if (STp->rew_at_close) {
  1589. result2 = osst_position_tape_and_confirm(STp, &SRpnt, STp->first_data_ppos);
  1590. STps->drv_file = STps->drv_block = STp->frame_seq_number = STp->logical_blk_num = 0;
  1591. if (result == 0 && result2 < 0)
  1592. result = result2;
  1593. }
  1594. if (SRpnt) scsi_release_request(SRpnt);
  1595. if (STp->recover_count) {
  1596. printk(KERN_INFO "osst%d:I: %d recovered errors in", dev, STp->recover_count);
  1597. if (STp->write_count)
  1598. printk(" %d frames written", STp->write_count);
  1599. if (STp->read_count)
  1600. printk(" %d frames read", STp->read_count);
  1601. printk("n");
  1602. STp->recover_count = 0;
  1603. }
  1604. STp->write_count = 0;
  1605. STp->read_count  = 0;
  1606. return result;
  1607. }
  1608. /* Close the device and release it */
  1609. static int os_scsi_tape_close(struct inode * inode, struct file * filp)
  1610. {
  1611. int result = 0;
  1612. OS_Scsi_Tape * STp;
  1613. Scsi_Request * SRpnt = NULL;
  1614. kdev_t devt = inode->i_rdev;
  1615. int dev;
  1616. dev = TAPE_NR(devt);
  1617. STp = os_scsi_tapes[dev];
  1618. if (STp->door_locked == ST_LOCKED_AUTO)
  1619. osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0);
  1620. if (SRpnt) scsi_release_request(SRpnt);
  1621. if (STp->buffer != NULL)
  1622. STp->buffer->in_use = 0;
  1623. if (STp->raw)
  1624. STp->header_ok = 0;
  1625. STp->in_use = 0;
  1626. STp->device->access_count--;
  1627. if (STp->device->host->hostt->module)
  1628. __MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
  1629. if(osst_template.module)
  1630. __MOD_DEC_USE_COUNT(osst_template.module);
  1631. return result;
  1632. }
  1633. /* The ioctl command */
  1634. static int osst_ioctl(struct inode * inode,struct file * file,
  1635.  unsigned int cmd_in, unsigned long arg)
  1636. {
  1637. int i, cmd_nr, cmd_type, retval = 0;
  1638. unsigned int blk;
  1639. OS_Scsi_Tape *STp;
  1640. ST_mode *STm;
  1641. ST_partstat *STps;
  1642. Scsi_Request *SRpnt = NULL;
  1643. int dev = TAPE_NR(inode->i_rdev);
  1644. STp = os_scsi_tapes[dev];
  1645. if (down_interruptible(&STp->lock))
  1646. return -ERESTARTSYS;
  1647. #if DEBUG
  1648. if (debugging && !STp->in_use) {
  1649. printk(OSST_DEB_MSG "osst%d:D: Incorrect device.n", dev);
  1650. retval = (-EIO);
  1651. goto out;
  1652. }
  1653. #endif
  1654. STm = &(STp->modes[STp->current_mode]);
  1655. STps = &(STp->ps[STp->partition]);
  1656. /*
  1657.  * If we are in the middle of error recovery, don't let anyone
  1658.  * else try and use this device.  Also, if error recovery fails, it
  1659.  * may try and take the device offline, in which case all further
  1660.  * access to the device is prohibited.
  1661.  */
  1662. if( !scsi_block_when_processing_errors(STp->device) ) {
  1663. retval = (-ENXIO);
  1664. goto out;
  1665. }
  1666. cmd_type = _IOC_TYPE(cmd_in);
  1667. cmd_nr   = _IOC_NR(cmd_in);
  1668. #if DEBUG
  1669. printk(OSST_DEB_MSG "osst%d:D: Ioctl %d,%d in %s moden", dev,
  1670.     cmd_type, cmd_nr, STp->raw?"raw":"normal");
  1671. #endif
  1672. if (cmd_type == _IOC_TYPE(MTIOCTOP) && cmd_nr == _IOC_NR(MTIOCTOP)) {
  1673. struct mtop mtc;
  1674. if (_IOC_SIZE(cmd_in) != sizeof(mtc)) {
  1675. retval = (-EINVAL);
  1676. goto out;
  1677. }
  1678. i = copy_from_user((char *) &mtc, (char *)arg, sizeof(struct mtop));
  1679. if (i) {
  1680. retval = (-EFAULT);
  1681. goto out;
  1682. }
  1683. if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
  1684. printk(KERN_WARNING "osst%d:W: MTSETDRVBUFFER only allowed for root.n", dev);
  1685. retval = (-EPERM);
  1686. goto out;
  1687. }
  1688. if (!STm->defined && (mtc.mt_op != MTSETDRVBUFFER && (mtc.mt_count & MT_ST_OPTIONS) == 0)) {
  1689. retval = (-ENXIO);
  1690. goto out;
  1691. }
  1692. if (!(STp->device)->was_reset) {
  1693. if (STps->eof == ST_FM_HIT) {
  1694. if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) {
  1695. mtc.mt_count -= 1;
  1696. if (STps->drv_file >= 0)
  1697. STps->drv_file += 1;
  1698. }
  1699. else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) {
  1700. mtc.mt_count += 1;
  1701. if (STps->drv_file >= 0)
  1702. STps->drv_file += 1;
  1703. }
  1704. }
  1705. if (mtc.mt_op == MTSEEK) {
  1706. /* Old position must be restored if partition will be changed */
  1707. i = !STp->can_partitions || (STp->new_partition != STp->partition);
  1708. }
  1709. else {
  1710. i = mtc.mt_op == MTREW   || mtc.mt_op == MTOFFL ||
  1711.     mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM  ||
  1712.     mtc.mt_op == MTLOCK  || mtc.mt_op == MTLOAD ||
  1713.     mtc.mt_op == MTCOMPRESSION;
  1714. }
  1715. i = osst_flush_buffer(STp, &SRpnt, i);
  1716. if (i < 0) {
  1717. retval = i;
  1718. goto out;
  1719. }
  1720. }
  1721. else {
  1722. /*
  1723.  * If there was a bus reset, block further access
  1724.  * to this device.  If the user wants to rewind the tape,
  1725.  * then reset the flag and allow access again.
  1726.  */
  1727. if(mtc.mt_op != MTREW   &&
  1728.    mtc.mt_op != MTOFFL  &&
  1729.    mtc.mt_op != MTRETEN &&
  1730.    mtc.mt_op != MTERASE &&
  1731.    mtc.mt_op != MTSEEK  &&
  1732.    mtc.mt_op != MTEOM)   {
  1733. retval = (-EIO);
  1734. goto out;
  1735. }
  1736. STp->device->was_reset = 0;
  1737. if (STp->door_locked != ST_UNLOCKED &&
  1738.     STp->door_locked != ST_LOCK_FAILS) {
  1739. if (osst_int_ioctl(STp, &SRpnt, MTLOCK, 0)) {
  1740. printk(KERN_NOTICE "osst%d:I: Could not relock door after bus reset.n",
  1741.   dev);
  1742. STp->door_locked = ST_UNLOCKED;
  1743. }
  1744. }
  1745. }
  1746. if (mtc.mt_op != MTNOP && mtc.mt_op != MTWEOF && mtc.mt_op != MTWSM &&
  1747.     mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTSETBLK &&
  1748.     mtc.mt_op != MTSETDRVBUFFER && mtc.mt_op != MTSETPART)
  1749. STps->rw = ST_IDLE;  /* Prevent automatic WEOF and fsf */
  1750. if (mtc.mt_op == MTOFFL && STp->door_locked != ST_UNLOCKED)
  1751. osst_int_ioctl(STp, &SRpnt, MTUNLOCK, 0);  /* Ignore result! */
  1752. if (mtc.mt_op == MTSETDRVBUFFER &&
  1753.    (mtc.mt_count & MT_ST_OPTIONS) != 0) {
  1754. retval = osst_set_options(STp, mtc.mt_count);
  1755. goto out;
  1756. }
  1757. if (mtc.mt_op == MTSETPART) {
  1758. /*     if (!STp->can_partitions ||
  1759.    mtc.mt_count < 0 || mtc.mt_count >= ST_NBR_PARTITIONS)
  1760.  return (-EINVAL);
  1761.  if (mtc.mt_count >= STp->nbr_partitions &&
  1762.    (STp->nbr_partitions = nbr_partitions(inode)) < 0)
  1763.  return (-EIO);*/
  1764. if (mtc.mt_count >= STp->nbr_partitions)
  1765. retval = -EINVAL;
  1766. else {
  1767. STp->new_partition = mtc.mt_count;
  1768. retval = 0;
  1769. }
  1770. goto out;
  1771. }
  1772. if (mtc.mt_op == MTMKPART) {
  1773. if (!STp->can_partitions) {
  1774. retval = (-EINVAL);
  1775. goto out;
  1776. }
  1777. if ((i = osst_int_ioctl(STp, &SRpnt, MTREW, 0)) < 0 /*||
  1778.     (i = partition_tape(inode, mtc.mt_count)) < 0*/) {
  1779. retval = i;
  1780. goto out;
  1781. }
  1782. for (i=0; i < ST_NBR_PARTITIONS; i++) {
  1783. STp->ps[i].rw = ST_IDLE;
  1784. STp->ps[i].at_sm = 0;
  1785. STp->ps[i].last_block_valid = FALSE;
  1786. }
  1787. STp->partition = STp->new_partition = 0;
  1788. STp->nbr_partitions = 1;  /* Bad guess ?-) */
  1789. STps->drv_block = STps->drv_file = 0;
  1790. retval = 0;
  1791. goto out;
  1792.   }
  1793. if (mtc.mt_op == MTSEEK) {
  1794. if (STp->raw)
  1795. i = osst_set_frame_position(STp, &SRpnt, mtc.mt_count, 0);
  1796. else
  1797. i = osst_seek_sector(STp, &SRpnt, mtc.mt_count);
  1798. if (!STp->can_partitions)
  1799. STp->ps[0].rw = ST_IDLE;
  1800. retval = i;
  1801. goto out;
  1802. }
  1803. /*   if (STp->can_partitions && STp->ready == ST_READY &&
  1804.  (i = update_partition(inode)) < 0)
  1805.  {retval=i;goto out;}*/
  1806. if (mtc.mt_op == MTCOMPRESSION)
  1807. retval = -EINVAL /*osst_compression(STp, (mtc.mt_count & 1))*/;
  1808. else
  1809. retval = osst_int_ioctl(STp, &SRpnt, mtc.mt_op, mtc.mt_count);
  1810. goto out;
  1811. }
  1812. if (!STm->defined) {
  1813. retval = (-ENXIO);
  1814. goto out;
  1815. }
  1816. if ((i = osst_flush_buffer(STp, &SRpnt, FALSE)) < 0) {
  1817. retval = i;
  1818. goto out;
  1819. }
  1820. /* if (STp->can_partitions &&
  1821.  (i = update_partition(inode)) < 0)
  1822.  {retval=i;goto out;}*/
  1823. if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) {
  1824. struct mtget mt_status;
  1825. if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) {
  1826.  retval = (-EINVAL);
  1827.  goto out;
  1828. }
  1829. mt_status.mt_type = MT_ISONSTREAM_SC;
  1830. mt_status.mt_erreg = STp->recover_erreg << MT_ST_SOFTERR_SHIFT;
  1831. mt_status.mt_dsreg =
  1832. ((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
  1833. ((STp->density    << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
  1834. mt_status.mt_blkno = STps->drv_block;
  1835. mt_status.mt_fileno = STps->drv_file;
  1836. if (STp->block_size != 0) {
  1837. if (STps->rw == ST_WRITING)
  1838. mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size;
  1839. else if (STps->rw == ST_READING)
  1840. mt_status.mt_blkno -= ((STp->buffer)->buffer_bytes +
  1841. STp->block_size - 1) / STp->block_size;
  1842. }
  1843. mt_status.mt_gstat = 0;
  1844. if (STp->drv_write_prot)
  1845. mt_status.mt_gstat |= GMT_WR_PROT(0xffffffff);
  1846. if (mt_status.mt_blkno == 0) {
  1847. if (mt_status.mt_fileno == 0)
  1848. mt_status.mt_gstat |= GMT_BOT(0xffffffff);
  1849. else
  1850. mt_status.mt_gstat |= GMT_EOF(0xffffffff);
  1851. }
  1852. mt_status.mt_resid = STp->partition;
  1853. if (STps->eof == ST_EOM_OK || STps->eof == ST_EOM_ERROR)
  1854. mt_status.mt_gstat |= GMT_EOT(0xffffffff);
  1855. else if (STps->eof >= ST_EOM_OK)
  1856. mt_status.mt_gstat |= GMT_EOD(0xffffffff);
  1857. if (STp->density == 1)
  1858. mt_status.mt_gstat |= GMT_D_800(0xffffffff);
  1859. else if (STp->density == 2)
  1860. mt_status.mt_gstat |= GMT_D_1600(0xffffffff);
  1861. else if (STp->density == 3)
  1862. mt_status.mt_gstat |= GMT_D_6250(0xffffffff);
  1863. if (STp->ready == ST_READY)
  1864. mt_status.mt_gstat |= GMT_ONLINE(0xffffffff);
  1865. if (STp->ready == ST_NO_TAPE)
  1866. mt_status.mt_gstat |= GMT_DR_OPEN(0xffffffff);
  1867. if (STps->at_sm)
  1868. mt_status.mt_gstat |= GMT_SM(0xffffffff);
  1869. if (STm->do_async_writes || (STm->do_buffer_writes && STp->block_size != 0) ||
  1870.     STp->drv_buffer != 0)
  1871. mt_status.mt_gstat |= GMT_IM_REP_EN(0xffffffff);
  1872. i = copy_to_user((char *)arg, (char *)&mt_status,
  1873.       sizeof(struct mtget));
  1874. if (i) {
  1875. retval = (-EFAULT);
  1876. goto out;
  1877. }
  1878. STp->recover_erreg = 0;  /* Clear after read */
  1879. retval = 0;
  1880. goto out;
  1881. } /* End of MTIOCGET */
  1882. if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
  1883. struct mtpos mt_pos;
  1884. if (_IOC_SIZE(cmd_in) != sizeof(struct mtpos)) {
  1885. retval = (-EINVAL);
  1886. goto out;
  1887. }
  1888. if (STp->raw)
  1889. blk = osst_get_frame_position(STp, &SRpnt);
  1890. else
  1891. blk = osst_get_sector(STp, &SRpnt);
  1892. if (blk < 0) {
  1893. retval = blk;
  1894. goto out;
  1895. }
  1896. mt_pos.mt_blkno = blk;
  1897. i = copy_to_user((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
  1898. if (i)
  1899. retval = -EFAULT;
  1900. goto out;
  1901. }
  1902. if (SRpnt) scsi_release_request(SRpnt);
  1903. up(&STp->lock);
  1904. return scsi_ioctl(STp->device, cmd_in, (void *) arg);
  1905. out:
  1906. if (SRpnt) scsi_release_request(SRpnt);
  1907. up(&STp->lock);
  1908. return retval;
  1909. }
  1910. /* Memory handling routines */
  1911. /* Try to allocate a new tape buffer */
  1912. static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma )
  1913. {
  1914. int i, priority, b_size, order, got = 0, segs = 0;
  1915. OSST_buffer *tb;
  1916. if (osst_nbr_buffers >= osst_template.dev_max)
  1917. return NULL;  /* Should never happen */
  1918. if (from_initialization)
  1919. priority = GFP_ATOMIC;
  1920. else
  1921. priority = GFP_KERNEL;
  1922. i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
  1923. tb = (OSST_buffer *)kmalloc(i, priority);
  1924. if (tb) {
  1925. //    tb->this_size = i;
  1926. if (need_dma)
  1927. priority |= GFP_DMA;
  1928. /* Try to allocate the first segment up to OSST_FIRST_ORDER and the
  1929.  others big enough to reach the goal */
  1930. for (b_size = PAGE_SIZE,          order = 0;
  1931.      b_size < osst_buffer_size && order < OSST_FIRST_ORDER;
  1932.      b_size *= 2,                 order++ );
  1933. for ( ; b_size >= PAGE_SIZE; order--, b_size /= 2) {
  1934. tb->sg[0].address =
  1935.     (unsigned char *)__get_free_pages(priority, order);
  1936. if (tb->sg[0].address != NULL) {
  1937.     tb->sg[0].page = NULL;
  1938.     tb->sg[0].length = b_size;
  1939.     break;
  1940. }
  1941. }
  1942. if (tb->sg[segs].address == NULL) {
  1943. kfree(tb);
  1944. tb = NULL;
  1945. }
  1946. else {  /* Got something, continue */
  1947. for (b_size = PAGE_SIZE, order = 0;
  1948.      osst_buffer_size > tb->sg[0].length + (OSST_FIRST_SG - 1) * b_size;
  1949.      b_size *= 2, order++ );
  1950. for (segs=1, got=tb->sg[0].length;
  1951.      got < osst_buffer_size && segs < OSST_FIRST_SG; ) {
  1952.     tb->sg[segs].address =
  1953. (unsigned char *)__get_free_pages(priority, order);
  1954.     if (tb->sg[segs].address == NULL) {
  1955. if (osst_buffer_size - got <=
  1956.     (OSST_FIRST_SG - segs) * b_size / 2) {
  1957.     b_size /= 2; /* Large enough for the rest of the buffers */
  1958.     order--;
  1959.     continue;
  1960. }
  1961. tb->sg_segs = segs;
  1962. tb->orig_sg_segs = 0;
  1963. #if DEBUG
  1964. tb->buffer_size = got;
  1965. #endif
  1966. normalize_buffer(tb);
  1967. kfree(tb);
  1968. tb = NULL;
  1969. break;
  1970.     }
  1971.                             tb->sg[segs].page = NULL;
  1972.     tb->sg[segs].length = b_size;
  1973.     got += b_size;
  1974.     segs++;
  1975. }
  1976. }
  1977. }
  1978. if (!tb) {
  1979. printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer (nbr %d).n",
  1980.    osst_nbr_buffers);
  1981. return NULL;
  1982. }
  1983. tb->sg_segs = tb->orig_sg_segs = segs;
  1984. tb->b_data = tb->sg[0].address;
  1985. #if DEBUG
  1986. if (debugging) {
  1987. printk(OSST_DEB_MSG
  1988. "osst :D: Allocated tape buffer %d (%d bytes, %d segments, dma: %d, a: %p).n",
  1989.    osst_nbr_buffers, got, tb->sg_segs, need_dma, tb->b_data);
  1990. printk(OSST_DEB_MSG
  1991. "osst :D: segment sizes: first %d, last %d bytes.n",
  1992.    tb->sg[0].length, tb->sg[segs-1].length);
  1993. }
  1994. #endif
  1995. tb->in_use = 0;
  1996. tb->dma = need_dma;
  1997. tb->buffer_size = got;
  1998. tb->writing = 0;
  1999. osst_buffers[osst_nbr_buffers++] = tb;
  2000. return tb;
  2001. }
  2002. /* Try to allocate a temporary enlarged tape buffer */
  2003. static int enlarge_buffer(OSST_buffer *STbuffer, int new_size, int need_dma)
  2004. {
  2005. int segs, nbr, max_segs, b_size, priority, order, got;
  2006. normalize_buffer(STbuffer);
  2007. max_segs = STbuffer->use_sg;
  2008. if (max_segs > osst_max_sg_segs)
  2009. max_segs = osst_max_sg_segs;
  2010. nbr = max_segs - STbuffer->sg_segs;
  2011. if (nbr <= 0)
  2012. return FALSE;
  2013. priority = GFP_KERNEL;
  2014. if (need_dma)
  2015. priority |= GFP_DMA;
  2016. for (b_size = PAGE_SIZE, order = 0;
  2017.  b_size * nbr < new_size - STbuffer->buffer_size;
  2018.  b_size *= 2, order++);
  2019. for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size;
  2020.      segs < max_segs && got < new_size; ) {
  2021. STbuffer->sg[segs].address =
  2022.   (unsigned char *)__get_free_pages(priority, order);
  2023. if (STbuffer->sg[segs].address == NULL) {
  2024. if (new_size - got <= (max_segs - segs) * b_size / 2) {
  2025. b_size /= 2;  /* Large enough for the rest of the buffers */
  2026. order--;
  2027. continue;
  2028. }
  2029. printk(KERN_WARNING "osst :W: Failed to enlarge buffer to %d bytes.n",
  2030. new_size);
  2031. #if DEBUG
  2032. STbuffer->buffer_size = got;
  2033. #endif
  2034. normalize_buffer(STbuffer);
  2035. return FALSE;
  2036. }
  2037. STbuffer->sg[segs].page = NULL;
  2038. STbuffer->sg[segs].length = b_size;
  2039. STbuffer->sg_segs += 1;
  2040. got += b_size;
  2041. STbuffer->buffer_size = got;
  2042. segs++;
  2043. }
  2044. #if DEBUG
  2045. if (debugging) {
  2046. for (nbr=0; osst_buffers[nbr] != STbuffer && nbr < osst_nbr_buffers; nbr++);
  2047. printk(OSST_DEB_MSG
  2048.    "osst :D: Expanded tape buffer %d (%d bytes, %d->%d segments, dma: %d, a: %p).n",
  2049.    nbr, got, STbuffer->orig_sg_segs, STbuffer->sg_segs, need_dma, STbuffer->b_data);
  2050. printk(OSST_DEB_MSG
  2051.    "osst :D: segment sizes: first %d, last %d bytes.n",
  2052.    STbuffer->sg[0].length, STbuffer->sg[segs-1].length);
  2053. }
  2054. #endif
  2055. return TRUE;
  2056. }
  2057. /* Release the extra buffer */
  2058. static void normalize_buffer(OSST_buffer *STbuffer)
  2059. {
  2060.   int i, order, b_size;
  2061. for (i=STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) {
  2062. for (b_size = PAGE_SIZE, order = 0;
  2063.      b_size < STbuffer->sg[i].length;
  2064.      b_size *= 2, order++);
  2065. free_pages((unsigned long)STbuffer->sg[i].address, order);
  2066. STbuffer->buffer_size -= STbuffer->sg[i].length;
  2067. }
  2068. #if DEBUG
  2069. if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
  2070. printk(OSST_DEB_MSG "osst :D: Buffer at %p normalized to %d bytes (segs %d).n",
  2071.      STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
  2072. #endif
  2073. STbuffer->sg_segs = STbuffer->orig_sg_segs;
  2074. }
  2075. /* Move data from the user buffer to the tape buffer. Returns zero (success) or
  2076.    negative error code. */
  2077. static int append_to_buffer(const char *ubp, OSST_buffer *st_bp, int do_count)
  2078. {
  2079. int i, cnt, res, offset;
  2080. for (i=0, offset=st_bp->buffer_bytes;
  2081.      i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
  2082. offset -= st_bp->sg[i].length;
  2083. if (i == st_bp->sg_segs) {  /* Should never happen */
  2084. printk(KERN_WARNING "osst :A: Append_to_buffer offset overflow.n");
  2085. return (-EIO);
  2086. }
  2087. for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
  2088. cnt = st_bp->sg[i].length - offset < do_count ?
  2089.       st_bp->sg[i].length - offset : do_count;
  2090. res = copy_from_user(st_bp->sg[i].address + offset, ubp, cnt);
  2091. if (res)
  2092. return (-EFAULT);
  2093. do_count -= cnt;
  2094. st_bp->buffer_bytes += cnt;
  2095. ubp += cnt;
  2096. offset = 0;
  2097. }
  2098. if (do_count) {  /* Should never happen */
  2099. printk(KERN_WARNING "osst :A: Append_to_buffer overflow (left %d).n",
  2100.        do_count);
  2101. return (-EIO);
  2102. }
  2103. return 0;
  2104. }
  2105. /* Move data from the tape buffer to the user buffer. Returns zero (success) or
  2106.    negative error code. */
  2107. static int from_buffer(OSST_buffer *st_bp, char *ubp, int do_count)
  2108. {
  2109. int i, cnt, res, offset;
  2110. for (i=0, offset=st_bp->read_pointer;
  2111.      i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
  2112. offset -= st_bp->sg[i].length;
  2113. if (i == st_bp->sg_segs) {  /* Should never happen */
  2114. printk(KERN_WARNING "osst :A: From_buffer offset overflow.n");
  2115. return (-EIO);
  2116. }
  2117. for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
  2118. cnt = st_bp->sg[i].length - offset < do_count ?
  2119.       st_bp->sg[i].length - offset : do_count;
  2120. res = copy_to_user(ubp, st_bp->sg[i].address + offset, cnt);
  2121. if (res)
  2122. return (-EFAULT);
  2123. do_count -= cnt;
  2124. st_bp->buffer_bytes -= cnt;
  2125. st_bp->read_pointer += cnt;
  2126. ubp += cnt;
  2127. offset = 0;
  2128. }
  2129. if (do_count) {  /* Should never happen */
  2130. printk(KERN_WARNING "osst :A: From_buffer overflow (left %d).n", do_count);
  2131. return (-EIO);
  2132. }
  2133. return 0;
  2134. }
  2135. /* Sets the tail of the buffer after fill point to zero.
  2136.    Returns zero (success) or negative error code.        */
  2137. static int osst_zero_buffer_tail(OSST_buffer *st_bp)
  2138. {
  2139. int i, offset, do_count, cnt;
  2140. for (i = 0, offset = st_bp->buffer_bytes;
  2141.      i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++)
  2142. offset -= st_bp->sg[i].length;
  2143. if (i == st_bp->sg_segs) {  /* Should never happen */
  2144. printk(KERN_WARNING "osst :A: Zero_buffer offset overflow.n");
  2145. return (-EIO);
  2146. }
  2147. for (do_count = OS_DATA_SIZE - st_bp->buffer_bytes;
  2148.      i < st_bp->sg_segs && do_count > 0; i++) {
  2149. cnt = st_bp->sg[i].length - offset < do_count ?
  2150.       st_bp->sg[i].length - offset : do_count ;
  2151. memset(st_bp->sg[i].address + offset, 0, cnt);
  2152. do_count -= cnt;
  2153. offset = 0;
  2154. }
  2155. if (do_count) {  /* Should never happen */
  2156. printk(KERN_WARNING "osst :A: Zero_buffer overflow (left %d).n", do_count);
  2157. return (-EIO);
  2158. }
  2159. return 0;
  2160. }
  2161. /* Copy a osst 32K chunk of memory into the buffer.
  2162.    Returns zero (success) or negative error code.  */
  2163. static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr)
  2164. {
  2165. int i, cnt, do_count = OS_DATA_SIZE;
  2166. for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
  2167. cnt = st_bp->sg[i].length < do_count ?
  2168.       st_bp->sg[i].length : do_count ;
  2169. memcpy(st_bp->sg[i].address, ptr, cnt);
  2170. do_count -= cnt;
  2171. ptr      += cnt;
  2172. }
  2173. if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
  2174. printk(KERN_WARNING "osst :A: Copy_to_buffer overflow (left %d at sg %d).n",
  2175.  do_count, i);
  2176. return (-EIO);
  2177. }
  2178. return 0;
  2179. }
  2180. /* Copy a osst 32K chunk of memory from the buffer.
  2181.    Returns zero (success) or negative error code.  */
  2182. static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr)
  2183. {
  2184. int i, cnt, do_count = OS_DATA_SIZE;
  2185. for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
  2186. cnt = st_bp->sg[i].length < do_count ?
  2187.       st_bp->sg[i].length : do_count ;
  2188. memcpy(ptr, st_bp->sg[i].address, cnt);
  2189. do_count -= cnt;
  2190. ptr      += cnt;
  2191. }
  2192. if (do_count || i != st_bp->sg_segs-1) {  /* Should never happen */
  2193. printk(KERN_WARNING "osst :A: Copy_from_buffer overflow (left %d at sg %d).n",
  2194.  do_count, i);
  2195. return (-EIO);
  2196. }
  2197. return 0;
  2198. }
  2199. /* Module housekeeping */
  2200. static void validate_options (void)
  2201. {
  2202.   if (buffer_kbs > 0)
  2203. osst_buffer_size = buffer_kbs * ST_KILOBYTE;
  2204.   if (write_threshold_kbs > 0)
  2205. osst_write_threshold = write_threshold_kbs * ST_KILOBYTE;
  2206.   if (osst_write_threshold > osst_buffer_size)
  2207. osst_write_threshold = osst_buffer_size;
  2208.   if (max_buffers > 0)
  2209. osst_max_buffers = max_buffers;
  2210.   if (max_sg_segs >= OSST_FIRST_SG)
  2211. osst_max_sg_segs = max_sg_segs;
  2212. #if DEBUG
  2213.   printk(OSST_DEB_MSG "osst :D: bufsize %d, wrt %d, max buffers %d, s/g segs %d.n",
  2214.  osst_buffer_size, osst_write_threshold, osst_max_buffers, osst_max_sg_segs);
  2215. //printk(OSST_DEB_MSG "osst :D: sizeof(header) = %d (%s)n",
  2216. // sizeof(os_header_t),sizeof(os_header_t)==OS_DATA_SIZE?"ok":"error");
  2217. #endif
  2218. }
  2219. #ifndef MODULE
  2220. /* Set the boot options. Syntax: osst=xxx,yyy,...
  2221.    where xxx is buffer size in 1024 byte blocks and yyy is write threshold
  2222.    in 1024 byte blocks. */
  2223. static int __init osst_setup (char *str)
  2224. {
  2225.   int i, ints[5];
  2226.   char *stp;
  2227.   stp = get_options(str, ARRAY_SIZE(ints), ints);
  2228.   if (ints[0] > 0) {
  2229. for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
  2230.   *parms[i].val = ints[i + 1];
  2231.   } else {
  2232. while (stp != NULL) {
  2233. for (i = 0; i < ARRAY_SIZE(parms); i++) {
  2234. int len = strlen(parms[i].name);
  2235. if (!strncmp(stp, parms[i].name, len) &&
  2236.     (*(stp + len) == ':' || *(stp + len) == '=')) {
  2237. *parms[i].val =
  2238. simple_strtoul(stp + len + 1, NULL, 0);
  2239. break;
  2240. }
  2241. }
  2242. if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
  2243. printk(KERN_INFO "osst :I: Illegal parameter in '%s'n",
  2244.        stp);
  2245. stp = strchr(stp, ',');
  2246. if (stp)
  2247. stp++;
  2248. }
  2249.   }
  2250.   return 1;
  2251. }
  2252. __setup("osst=", osst_setup);
  2253. #endif
  2254. static struct file_operations osst_fops = {
  2255. read: osst_read,
  2256. write: osst_write,
  2257. ioctl: osst_ioctl,
  2258. open: os_scsi_tape_open,
  2259. flush: os_scsi_tape_flush,
  2260. release: os_scsi_tape_close,
  2261. };
  2262. static int osst_supports(Scsi_Device * SDp)
  2263. {
  2264. struct osst_support_data {
  2265. char *vendor;
  2266. char *model;
  2267. char *rev;
  2268. char *driver_hint; /* Name of the correct driver, NULL if unknown */
  2269. };
  2270. static struct osst_support_data support_list[] = {
  2271. /* {"XXX", "Yy-", "", NULL},  example */
  2272. SIGS_FROM_OSST,
  2273. {NULL, }};
  2274. struct osst_support_data *rp;
  2275. /* We are willing to drive OnStream SC-x0 as well as the
  2276.  *   * IDE, ParPort, FireWire, USB variants, if accessible by
  2277.  *     * emulation layer (ide-scsi, usb-storage, ...) */
  2278. for (rp=&(support_list[0]); rp->vendor != NULL; rp++)
  2279. if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
  2280.     !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
  2281.     !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) 
  2282. return 1;
  2283. return 0;
  2284. }
  2285. static int osst_attach(Scsi_Device * SDp)
  2286. {
  2287. OS_Scsi_Tape * tpnt;
  2288. ST_mode * STm;
  2289. ST_partstat * STps;
  2290. int i, dev;
  2291. #ifdef CONFIG_DEVFS_FS
  2292. int mode;
  2293. #endif
  2294. if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
  2295.  return 1;
  2296. if (osst_template.nr_dev >= osst_template.dev_max) {
  2297.  SDp->attached--;
  2298.  return 1;
  2299. }
  2300. /* find a free minor number */
  2301. for (i=0; os_scsi_tapes[i] && i<osst_template.dev_max; i++);
  2302. if(i >= osst_template.dev_max) panic ("Scsi_devices corrupt (osst)");
  2303. /* allocate a OS_Scsi_Tape for this device */
  2304. tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
  2305. if (tpnt == NULL) {
  2306.  SDp->attached--;
  2307.  printk(KERN_WARNING "osst :W: Can't allocate device descriptor.n");
  2308.  return 1;
  2309. }
  2310. memset(tpnt, 0, sizeof(OS_Scsi_Tape));
  2311. os_scsi_tapes[i] = tpnt;
  2312. dev = i;
  2313. tpnt->capacity = 0xfffff;
  2314. /* allocate a buffer for this device */
  2315. if (!new_tape_buffer(TRUE, TRUE)) 
  2316.  printk(KERN_ERR "osst :W: Unable to allocate a tape buffer.n");
  2317. #ifdef CONFIG_DEVFS_FS
  2318. for (mode = 0; mode < ST_NBR_MODES; ++mode) {
  2319.  char name[8];
  2320.  static char *formats[ST_NBR_MODES] ={"", "l", "m", "a"};
  2321.  /*  Rewind entry  */
  2322.  sprintf (name, "mt%s", formats[mode]);
  2323. # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
  2324.  tpnt->de_r[mode] =
  2325. devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
  2326.    MAJOR_NR, i + (mode << 5),
  2327.    S_IFCHR | S_IRUGO | S_IWUGO,
  2328.    &osst_fops, NULL);
  2329. # else
  2330.  tpnt->de_r[mode] =
  2331. devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT,
  2332.    MAJOR_NR, i + (mode << 5),
  2333.    S_IFCHR | S_IRUGO | S_IWUGO,
  2334.    0, 0, &osst_fops, NULL);
  2335. # endif
  2336.  /*  No-rewind entry  */
  2337.  sprintf (name, "mt%sn", formats[mode]);
  2338. # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
  2339.  tpnt->de_n[mode] =
  2340. devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
  2341.    MAJOR_NR, i + (mode << 5) + 128,
  2342.    S_IFCHR | S_IRUGO | S_IWUGO,
  2343.    &osst_fops, NULL);
  2344. # else
  2345.  tpnt->de_n[mode] =
  2346. devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT,
  2347.    MAJOR_NR, i + (mode << 5) + 128,
  2348.    S_IFCHR | S_IRUGO | S_IWUGO,
  2349.    0, 0, &osst_fops, NULL);
  2350. # endif
  2351. }
  2352. devfs_register_tape (tpnt->de_r[0]);
  2353. #endif
  2354. tpnt->device = SDp;
  2355. tpnt->devt = MKDEV(MAJOR_NR, i);
  2356. tpnt->dirty = 0;
  2357. tpnt->in_use = 0;
  2358. tpnt->drv_buffer = 1;  /* Try buffering if no mode sense */
  2359. tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
  2360. tpnt->density = 0;
  2361. tpnt->do_auto_lock = OSST_AUTO_LOCK;
  2362. tpnt->can_bsr = OSST_IN_FILE_POS;
  2363. tpnt->can_partitions = 0;
  2364. tpnt->two_fm = OSST_TWO_FM;
  2365. tpnt->fast_mteom = OSST_FAST_MTEOM;
  2366. tpnt->scsi2_logical = OSST_SCSI2LOGICAL; /* FIXME */
  2367. tpnt->write_threshold = osst_write_threshold;
  2368. tpnt->default_drvbuffer = 0xff; /* No forced buffering */
  2369. tpnt->partition = 0;
  2370. tpnt->new_partition = 0;
  2371. tpnt->nbr_partitions = 0;
  2372. tpnt->min_block = 512;
  2373. tpnt->max_block = OS_DATA_SIZE;
  2374. tpnt->timeout = OSST_TIMEOUT;
  2375. tpnt->long_timeout = OSST_LONG_TIMEOUT;
  2376. /* Recognize OnStream tapes */
  2377. /* We don't need to test for OnStream, as this has been done in detect () */
  2378. tpnt->os_fw_rev = osst_parse_firmware_rev (SDp->rev);
  2379. tpnt->omit_blklims = 1;
  2380. tpnt->poll = (strncmp(SDp->model, "DI-", 3) == 0) || OSST_FW_NEED_POLL(tpnt->os_fw_rev,SDp);
  2381. tpnt->frame_in_buffer = 0;
  2382. tpnt->header_ok = 0;
  2383. tpnt->linux_media = 0;
  2384. tpnt->header_cache = NULL;
  2385. for (i=0; i < ST_NBR_MODES; i++) {
  2386. STm = &(tpnt->modes[i]);
  2387. STm->defined = FALSE;
  2388. STm->sysv = OSST_SYSV;
  2389. STm->defaults_for_writes = 0;
  2390. STm->do_async_writes = OSST_ASYNC_WRITES;
  2391. STm->do_buffer_writes = OSST_BUFFER_WRITES;
  2392. STm->do_read_ahead = OSST_READ_AHEAD;
  2393. STm->default_compression = ST_DONT_TOUCH;
  2394. STm->default_blksize = 512;
  2395. STm->default_density = (-1);  /* No forced density */
  2396. }
  2397. for (i=0; i < ST_NBR_PARTITIONS; i++) {
  2398. STps = &(tpnt->ps[i]);
  2399. STps->rw = ST_IDLE;
  2400. STps->eof = ST_NOEOF;
  2401. STps->at_sm = 0;
  2402. STps->last_block_valid = FALSE;
  2403. STps->drv_block = (-1);
  2404. STps->drv_file = (-1);
  2405. }
  2406. tpnt->current_mode = 0;
  2407. tpnt->modes[0].defined = TRUE;
  2408. tpnt->modes[2].defined = TRUE;
  2409. tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE;
  2410. init_MUTEX(&tpnt->lock);
  2411. osst_template.nr_dev++;
  2412. printk(KERN_INFO
  2413. "osst :I: Attached OnStream %.5s tape at scsi%d, channel %d, id %d, lun %d as osst%dn",
  2414. SDp->model, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun, dev);
  2415. return 0;
  2416. };
  2417. static int osst_detect(Scsi_Device * SDp)
  2418. {
  2419. if (SDp->type != TYPE_TAPE) return 0;
  2420. if ( ! osst_supports(SDp) ) return 0;
  2421. osst_template.dev_noticed++;
  2422. return 1;
  2423. }
  2424. static int osst_registered = 0;
  2425. /* Driver initialization (not __initfunc because may be called later) */
  2426. static int osst_init()
  2427. {
  2428.   int i;
  2429.   if (osst_template.dev_noticed == 0) return 0;
  2430.   if(!osst_registered) {
  2431. #ifdef CONFIG_DEVFS_FS
  2432. if (devfs_register_chrdev(MAJOR_NR,"osst",&osst_fops)) {
  2433. #else
  2434. if (register_chrdev(MAJOR_NR,"osst",&osst_fops)) {
  2435. #endif
  2436. printk(KERN_ERR "osst :W: Unable to get major %d for OnStream tapesn",MAJOR_NR);
  2437. return 1;
  2438. }
  2439. osst_registered++;
  2440.   }
  2441.   
  2442.   if (os_scsi_tapes) return 0;
  2443.   osst_template.dev_max = OSST_MAX_TAPES;
  2444.   if (osst_template.dev_max > 128 / ST_NBR_MODES)
  2445. printk(KERN_INFO "osst :I: Only %d tapes accessible.n", 128 / ST_NBR_MODES);
  2446.   os_scsi_tapes =
  2447. (OS_Scsi_Tape **)kmalloc(osst_template.dev_max * sizeof(OS_Scsi_Tape *),
  2448.    GFP_ATOMIC);
  2449.   if (os_scsi_tapes == NULL) {
  2450. printk(KERN_ERR "osst :W: Unable to allocate array for OnStream SCSI tapes.n");
  2451. #ifdef CONFIG_DEVFS_FS
  2452. devfs_unregister_chrdev(MAJOR_NR, "osst");
  2453. #else
  2454. unregister_chrdev(MAJOR_NR, "osst");
  2455. #endif
  2456. return 1;
  2457.   }
  2458.   for (i=0; i < osst_template.dev_max; ++i) os_scsi_tapes[i] = NULL;
  2459.   /* Allocate the buffer pointers */
  2460.   osst_buffers =
  2461. (OSST_buffer **)kmalloc(osst_template.dev_max * sizeof(OSST_buffer *),
  2462.     GFP_ATOMIC);
  2463.   if (osst_buffers == NULL) {
  2464. printk(KERN_ERR "osst :W: Unable to allocate tape buffer pointers.n");
  2465. #ifdef CONFIG_DEVFS_FS
  2466. devfs_unregister_chrdev(MAJOR_NR, "osst");
  2467. #else
  2468. unregister_chrdev(MAJOR_NR, "osst");
  2469. #endif
  2470. kfree(os_scsi_tapes);
  2471. return 1;
  2472.   }
  2473.   osst_nbr_buffers = 0;
  2474.   printk(KERN_INFO "osst :I: Tape driver with OnStream support version %snosst :I: %sn", osst_version, cvsid);
  2475. #if DEBUG
  2476.   printk(OSST_DEB_MSG "osst :D: Buffer size %d bytes, write threshold %d bytes.n",
  2477.  osst_buffer_size, osst_write_threshold);
  2478. #endif
  2479.   return 0;
  2480. }
  2481. static void osst_detach(Scsi_Device * SDp)
  2482. {
  2483.   OS_Scsi_Tape * tpnt;
  2484.   int i;
  2485. #ifdef CONFIG_DEVFS_FS
  2486.   int mode;
  2487. #endif
  2488.   for(i=0; i<osst_template.dev_max; i++) {
  2489. tpnt = os_scsi_tapes[i];
  2490. if(tpnt != NULL && tpnt->device == SDp) {
  2491. tpnt->device = NULL;
  2492. #ifdef CONFIG_DEVFS_FS
  2493. for (mode = 0; mode < ST_NBR_MODES; ++mode) {
  2494.   devfs_unregister (tpnt->de_r[mode]);
  2495.   tpnt->de_r[mode] = NULL;
  2496.   devfs_unregister (tpnt->de_n[mode]);
  2497.   tpnt->de_n[mode] = NULL;
  2498. }
  2499. #endif
  2500. kfree(tpnt);
  2501. os_scsi_tapes[i] = NULL;
  2502. SDp->attached--;
  2503. osst_template.nr_dev--;
  2504. osst_template.dev_noticed--;
  2505. return;
  2506. }
  2507.   }
  2508.   return;
  2509. }
  2510. static int __init init_osst(void) 
  2511. {
  2512. validate_options();
  2513. osst_template.module = THIS_MODULE;
  2514. return scsi_register_module(MODULE_SCSI_DEV, &osst_template);
  2515. }
  2516. static void __exit exit_osst (void)
  2517. {
  2518.   int i;
  2519.   OS_Scsi_Tape * STp;
  2520.   scsi_unregister_module(MODULE_SCSI_DEV, &osst_template);
  2521. #ifdef CONFIG_DEVFS_FS
  2522.   devfs_unregister_chrdev(MAJOR_NR, "osst");
  2523. #else
  2524.   unregister_chrdev(MAJOR_NR, "osst");
  2525. #endif
  2526.   osst_registered--;
  2527.   if(os_scsi_tapes != NULL) {
  2528. for (i=0; i < osst_template.dev_max; ++i) {
  2529. if ((STp = os_scsi_tapes[i])) {
  2530. if (STp->header_cache != NULL) vfree(STp->header_cache);
  2531. kfree(STp);
  2532. }
  2533. }
  2534. kfree(os_scsi_tapes);
  2535. if (osst_buffers != NULL) {
  2536. for (i=0; i < osst_nbr_buffers; i++)
  2537. if (osst_buffers[i] != NULL) {
  2538.   osst_buffers[i]->orig_sg_segs = 0;
  2539.   normalize_buffer(osst_buffers[i]);
  2540.   kfree(osst_buffers[i]);
  2541. }
  2542. kfree(osst_buffers);
  2543. }
  2544.   }
  2545.   osst_template.dev_max = 0;
  2546.   printk(KERN_INFO "osst :I: Unloaded.n");
  2547. }
  2548. module_init(init_osst);
  2549. module_exit(exit_osst);