tape34xx.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:69k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /***************************************************************************
  2.  *
  3.  *  drivers/s390/char/tape34xx.c
  4.  *    common tape device discipline for 34xx tapes.
  5.  *
  6.  *  S390 and zSeries version
  7.  *    Copyright (C) 2001 IBM Corporation
  8.  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  9.  *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
  10.  *
  11.  ****************************************************************************
  12.  */
  13. #include "tapedefs.h"
  14. #include <linux/config.h>
  15. #include <linux/version.h>
  16. #include <linux/stddef.h>
  17. #include <linux/kernel.h>
  18. #include <asm/types.h>
  19. #include <asm/uaccess.h>
  20. #include <linux/stat.h>
  21. #include <linux/proc_fs.h>
  22. #include <asm/ccwcache.h> 
  23. #include <asm/idals.h>  
  24. #ifdef CONFIG_S390_TAPE_DYNAMIC
  25. #include <asm/s390dyn.h>
  26. #endif
  27. #include <asm/debug.h>
  28. #include <linux/compatmac.h>
  29. #include "tape.h"
  30. #include "tape34xx.h"
  31. #define PRINTK_HEADER "T34xx:"
  32. tape_event_handler_t tape34xx_event_handler_table[TS_SIZE][TE_SIZE] =
  33. {
  34.     /* {START , DONE, FAILED, ERROR, OTHER } */
  35. {NULL, tape34xx_unused_done, NULL, NULL, NULL}, /* TS_UNUSED */
  36. {NULL, tape34xx_idle_done, NULL, NULL, NULL}, /* TS_IDLE */
  37. {NULL, NULL, NULL, NULL, NULL}, /* TS_DONE */
  38. {NULL, NULL, NULL, NULL, NULL}, /* TS_FAILED */
  39. {NULL, tape34xx_block_done, NULL, NULL, NULL}, /* TS_BLOCK_INIT */
  40. {NULL, tape34xx_bsb_init_done, NULL, NULL, NULL}, /* TS_BSB_INIT */
  41. {NULL, tape34xx_bsf_init_done, NULL, NULL, NULL}, /* TS_BSF_INIT */
  42. {NULL, tape34xx_dse_init_done, NULL, NULL, NULL}, /* TS_DSE_INIT */
  43. {NULL, NULL, NULL, NULL, NULL}, /* TS_EGA_INIT */
  44. {NULL, tape34xx_fsb_init_done, NULL, NULL, NULL}, /* TS_FSB_INIT */
  45. {NULL, tape34xx_fsf_init_done, NULL, NULL, NULL}, /* TS_FSF_INIT */
  46. {NULL, NULL, NULL, NULL, NULL}, /* TS_LDI_INIT */
  47. {NULL, tape34xx_lbl_init_done, NULL, NULL, NULL}, /* TS_LBL_INIT */
  48. {NULL, NULL, NULL, NULL, NULL}, /* TS_MSE_INIT */
  49. {NULL, tape34xx_nop_init_done, NULL, NULL, NULL}, /* TS_NOP_INIT */
  50. {NULL, NULL, NULL, NULL, NULL}, /* TS_RBA_INIT */
  51. {NULL, tape34xx_rbi_init_done, NULL, NULL, NULL}, /* TS_RBI_INIT */
  52. {NULL, NULL, NULL, NULL, NULL}, /* TS_RBU_INIT */
  53. {NULL, NULL, NULL, NULL, NULL}, /* TS_RBL_INIT */
  54. {NULL, NULL, NULL, NULL, NULL}, /* TS_RDC_INIT */
  55. {NULL, tape34xx_rfo_init_done, NULL, NULL, NULL}, /* TS_RFO_INIT */
  56. {NULL, NULL, NULL, NULL, NULL}, /* TS_RSD_INIT */
  57. {NULL, tape34xx_rew_init_done, NULL, NULL, NULL}, /* TS_REW_INIT */
  58. {NULL, tape34xx_rew_release_init_done, NULL, NULL, NULL}, /* TS_REW_RELEASE_IMIT */
  59. {NULL, tape34xx_run_init_done, NULL, NULL, NULL}, /* TS_RUN_INIT */
  60. {NULL, NULL, NULL, NULL, NULL}, /* TS_SEN_INIT */
  61. {NULL, NULL, NULL, NULL, NULL}, /* TS_SID_INIT */
  62. {NULL, NULL, NULL, NULL, NULL}, /* TS_SNP_INIT */
  63. {NULL, NULL, NULL, NULL, NULL}, /* TS_SPG_INIT */
  64. {NULL, NULL, NULL, NULL, NULL}, /* TS_SWI_INIT */
  65. {NULL, NULL, NULL, NULL, NULL}, /* TS_SMR_INIT */
  66. {NULL, NULL, NULL, NULL, NULL}, /* TS_SYN_INIT */
  67. {NULL, NULL, NULL, NULL, NULL}, /* TS_TIO_INIT */
  68. {NULL, NULL, NULL, NULL, NULL}, /* TS_UNA_INIT */
  69. {NULL, tape34xx_wri_init_done, NULL, NULL, NULL}, /* TS_WRI_INIT */
  70. {NULL, tape34xx_wtm_init_done, NULL, NULL, NULL}, /* TS_WTM_INIT */
  71. {NULL, NULL, NULL, NULL, NULL}};        /* TS_NOT_OPER */
  72. int
  73. tape34xx_ioctl_overload (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
  74. {
  75. return -EINVAL; // no additional ioctls
  76. }
  77. ccw_req_t *
  78. tape34xx_write_block (const char *data, size_t count, tape_info_t * ti)
  79. {
  80. long lockflags;
  81. ccw_req_t *cqr;
  82. ccw1_t *ccw;
  83. void *mem;
  84. cqr = tape_alloc_ccw_req (ti, 2, 0);
  85. if (!cqr) {
  86. #ifdef TAPE_DEBUG
  87.         debug_text_exception (tape_debug_area,6,"xwbl nomem");
  88. #endif /* TAPE_DEBUG */
  89. return NULL;
  90. }
  91. mem = kmalloc (count, GFP_KERNEL);
  92. if (!mem) {
  93. tape_free_request (cqr);
  94. #ifdef TAPE_DEBUG
  95.         debug_text_exception (tape_debug_area,6,"xwbl nomem");
  96. #endif /* TAPE_DEBUG */
  97. return NULL;
  98. }
  99. if (copy_from_user (mem, data, count)) {
  100. kfree (mem);
  101. tape_free_request (cqr);
  102. #ifdef TAPE_DEBUG
  103.         debug_text_exception (tape_debug_area,6,"xwbl segf.");
  104. #endif /* TAPE_DEBUG */
  105. return NULL;
  106. }
  107. ccw = cqr->cpaddr;
  108. ccw->cmd_code = MODE_SET_DB;
  109. ccw->flags = CCW_FLAG_CC;
  110. ccw->count = 1;
  111. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  112. ccw++;
  113. ccw->cmd_code = WRITE_CMD;
  114. ccw->flags = 0;
  115. ccw->count = count;
  116. set_normalized_cda (ccw, (unsigned long) mem);
  117. if ((ccw->cda) == 0) {
  118. kfree (mem);
  119. tape_free_request (cqr);
  120. return NULL;
  121. }
  122. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  123. ti->kernbuf = mem;
  124. ti->userbuf = (void *) data;
  125. tapestate_set (ti, TS_WRI_INIT);
  126. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  127. #ifdef TAPE_DEBUG
  128. debug_text_event (tape_debug_area,6,"xwbl ccwg");
  129. #endif /* TAPE_DEBUG */
  130. return cqr;
  131. }
  132. void 
  133. tape34xx_free_write_block (ccw_req_t * cqr, tape_info_t * ti)
  134. {
  135. unsigned long lockflags;
  136. ccw1_t *ccw;
  137. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  138. ccw = cqr->cpaddr;
  139. ccw++;
  140. clear_normalized_cda (ccw);
  141. kfree (ti->kernbuf);
  142. tape_free_request (cqr);
  143. ti->kernbuf = ti->userbuf = NULL;
  144. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  145. #ifdef TAPE_DEBUG
  146. debug_text_event (tape_debug_area,6,"xfwb free");
  147. #endif /* TAPE_DEBUG */
  148. }
  149. ccw_req_t *
  150. tape34xx_read_block (const char *data, size_t count, tape_info_t * ti)
  151. {
  152. long lockflags;
  153. ccw_req_t *cqr;
  154. ccw1_t *ccw;
  155. void *mem;
  156. cqr = tape_alloc_ccw_req (ti, 2, 0);
  157. if (!cqr) {
  158. #ifdef TAPE_DEBUG
  159.         debug_text_exception (tape_debug_area,6,"xrbl nomem");
  160. #endif /* TAPE_DEBUG */
  161. return NULL;
  162. }
  163. mem = kmalloc (count, GFP_KERNEL);
  164. if (!mem) {
  165. tape_free_request (cqr);
  166. #ifdef TAPE_DEBUG
  167.         debug_text_exception (tape_debug_area,6,"xrbl nomem");
  168. #endif /* TAPE_DEBUG */
  169. return NULL;
  170. }
  171. ccw = cqr->cpaddr;
  172. ccw->cmd_code = MODE_SET_DB;
  173. ccw->flags = CCW_FLAG_CC;
  174. ccw->count = 1;
  175. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  176. ccw++;
  177. ccw->cmd_code = READ_FORWARD;
  178. ccw->flags = 0;
  179. ccw->count = count;
  180. set_normalized_cda (ccw, (unsigned long) mem);
  181. if ((ccw->cda) == 0) {
  182. kfree (mem);
  183. tape_free_request (cqr);
  184. return NULL;
  185. }
  186. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  187. ti->kernbuf = mem;
  188. ti->userbuf = (void *) data;
  189. tapestate_set (ti, TS_RFO_INIT);
  190. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  191. #ifdef TAPE_DEBUG
  192. debug_text_event (tape_debug_area,6,"xrbl ccwg");
  193. #endif /* TAPE_DEBUG */
  194. return cqr;
  195. }
  196. ccw_req_t *
  197. tape34xx_read_opposite (tape_info_t * ti,int novalue)
  198. {
  199. ccw_req_t *cqr;
  200. ccw1_t *ccw;
  201. size_t count;
  202. // first, retrieve the count from the old cqr.
  203. cqr = ti->cqr;
  204. ccw = cqr->cpaddr;
  205. ccw++;
  206. count=ccw->count;
  207. // free old cqr.
  208. clear_normalized_cda (ccw);
  209. tape_free_request (cqr);
  210. // build new cqr
  211. cqr = tape_alloc_ccw_req (ti, 3, 0);
  212. if (!cqr) {
  213. #ifdef TAPE_DEBUG
  214.         debug_text_exception (tape_debug_area,6,"xrop nomem");
  215. #endif /* TAPE_DEBUG */
  216. return NULL;
  217. }
  218. ccw = cqr->cpaddr;
  219. ccw->cmd_code = MODE_SET_DB;
  220. ccw->flags = CCW_FLAG_CC;
  221. ccw->count = 1;
  222. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  223. ccw++;
  224. ccw->cmd_code = READ_BACKWARD;
  225. ccw->flags = CCW_FLAG_CC;
  226. ccw->count = count;
  227. set_normalized_cda (ccw, (unsigned long) ti->kernbuf);
  228. if ((ccw->cda) == 0) {
  229. tape_free_request (cqr);
  230. return NULL;
  231. }
  232. ccw++;
  233. ccw->cmd_code = FORSPACEBLOCK;
  234. ccw->flags = CCW_FLAG_CC;
  235. ccw->count = 1;
  236. ccw->cda = (unsigned long)ccw;
  237. ccw++;
  238. ccw->cmd_code = NOP;
  239. ccw->flags = 0;
  240. ccw->count = 1;
  241. ccw->cda = (unsigned long)ccw;
  242. tapestate_set (ti, TS_RBA_INIT);
  243. #ifdef TAPE_DEBUG
  244. debug_text_event (tape_debug_area,6,"xrop ccwg");
  245. #endif /* TAPE_DEBUG */
  246. return cqr;
  247. }
  248. void 
  249. tape34xx_free_read_block (ccw_req_t * cqr, tape_info_t * ti)
  250. {
  251. unsigned long lockflags;
  252. size_t cpysize;
  253. ccw1_t *ccw;
  254. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  255. ccw = cqr->cpaddr;
  256. ccw++;
  257. cpysize = ccw->count - ti->devstat.rescnt;
  258. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  259. if (copy_to_user (ti->userbuf, ti->kernbuf, cpysize)) {
  260. #ifdef TAPE_DEBUG
  261.     debug_text_exception (tape_debug_area,6,"xfrb segf.");
  262. #endif /* TAPE_DEBUG */
  263. }
  264. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  265. clear_normalized_cda (ccw);
  266. kfree (ti->kernbuf);
  267. tape_free_request (cqr);
  268. ti->kernbuf = ti->userbuf = NULL;
  269. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  270. #ifdef TAPE_DEBUG
  271. debug_text_event (tape_debug_area,6,"xfrb free");
  272. #endif /* TAPE_DEBUG */
  273. }
  274. /*
  275.  * The IOCTL interface is implemented in the following section,
  276.  * excepted the MTRESET, MTSETBLK which are handled by tapechar.c
  277.  */
  278. /*
  279.  * MTFSF: Forward space over 'count' file marks. The tape is positioned
  280.  * at the EOT (End of Tape) side of the file mark.
  281.  */
  282. ccw_req_t *
  283. tape34xx_mtfsf (tape_info_t * ti, int count)
  284. {
  285. long lockflags;
  286. int i;
  287. ccw_req_t *cqr;
  288. ccw1_t *ccw;
  289. if ((count == 0) || (count > 510)) {
  290. #ifdef TAPE_DEBUG
  291.         debug_text_exception (tape_debug_area,6,"xfsf parm");
  292. #endif /* TAPE_DEBUG */
  293. return NULL;
  294. }
  295. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  296. if (!cqr) {
  297. #ifdef TAPE_DEBUG
  298.         debug_text_exception (tape_debug_area,6,"xfsf nomem");
  299. #endif /* TAPE_DEBUG */
  300. return NULL;
  301. }
  302. ccw = cqr->cpaddr;
  303. ccw->cmd_code = MODE_SET_DB;
  304. ccw->flags = CCW_FLAG_CC;
  305. ccw->count = 1;
  306. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  307. ccw++;
  308. for (i = 0; i < count; i++) {
  309. ccw->cmd_code = FORSPACEFILE;
  310. ccw->flags = CCW_FLAG_CC;
  311. ccw->count = 0;
  312. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  313. ccw++;
  314. }
  315. ccw->cmd_code = NOP;
  316. ccw->flags = 0;
  317. ccw->count = 0;
  318. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  319. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  320. ti->kernbuf = NULL;
  321. ti->userbuf = NULL;
  322. tapestate_set (ti, TS_FSF_INIT);
  323. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  324. #ifdef TAPE_DEBUG
  325. debug_text_event (tape_debug_area,6,"xfsf ccwg");
  326. #endif /* TAPE_DEBUG */
  327. return cqr;
  328. }
  329. /*
  330.  * MTBSF: Backward space over 'count' file marks. The tape is positioned at
  331.  * the EOT (End of Tape) side of the last skipped file mark.
  332.  */
  333. ccw_req_t *
  334. tape34xx_mtbsf (tape_info_t * ti, int count)
  335. {
  336. long lockflags;
  337. int i;
  338. ccw_req_t *cqr;
  339. ccw1_t *ccw;
  340. if ((count == 0) || (count > 510)) {
  341. #ifdef TAPE_DEBUG
  342.         debug_text_exception (tape_debug_area,6,"xbsf parm");
  343. #endif /* TAPE_DEBUG */
  344.         return NULL;
  345. }
  346. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  347. if (!cqr) {
  348. #ifdef TAPE_DEBUG
  349.         debug_text_exception (tape_debug_area,6,"xbsf nomem");
  350. #endif /* TAPE_DEBUG */
  351. return NULL;
  352. }
  353. ccw = cqr->cpaddr;
  354. ccw->cmd_code = MODE_SET_DB;
  355. ccw->flags = CCW_FLAG_CC;
  356. ccw->count = 1;
  357. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  358. ccw++;
  359. for (i = 0; i < count; i++) {
  360. ccw->cmd_code = BACKSPACEFILE;
  361. ccw->flags = CCW_FLAG_CC;
  362. ccw->count = 0;
  363. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  364. ccw++;
  365. }
  366. ccw->cmd_code = NOP;
  367. ccw->flags = 0;
  368. ccw->count = 0;
  369. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  370. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  371. ti->kernbuf = NULL;
  372. ti->userbuf = NULL;
  373. tapestate_set (ti, TS_BSF_INIT);
  374. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  375. #ifdef TAPE_DEBUG
  376. debug_text_event (tape_debug_area,6,"xbsf ccwg");
  377. #endif /* TAPE_DEBUG */
  378. return cqr;
  379. }
  380. /*
  381.  * MTFSR: Forward space over 'count' tape blocks (blocksize is set
  382.  * via MTSETBLK.
  383.  */
  384. ccw_req_t *
  385. tape34xx_mtfsr (tape_info_t * ti, int count)
  386. {
  387. long lockflags;
  388. int i;
  389. ccw_req_t *cqr;
  390. ccw1_t *ccw;
  391. if ((count == 0) || (count > 510)) {
  392. #ifdef TAPE_DEBUG
  393.         debug_text_exception (tape_debug_area,6,"xfsr parm");
  394. #endif /* TAPE_DEBUG */
  395. return NULL;
  396. }
  397. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  398. if (!cqr) {
  399. #ifdef TAPE_DEBUG
  400.         debug_text_exception (tape_debug_area,6,"xfsr nomem");
  401. #endif /* TAPE_DEBUG */
  402. return NULL;
  403. }
  404. ccw = cqr->cpaddr;
  405. ccw->cmd_code = MODE_SET_DB;
  406. ccw->flags = CCW_FLAG_CC;
  407. ccw->count = 1;
  408. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  409. ccw++;
  410. for (i = 0; i < count; i++) {
  411. ccw->cmd_code = FORSPACEBLOCK;
  412. ccw->flags = CCW_FLAG_CC;
  413. ccw->count = 0;
  414. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  415. ccw++;
  416. }
  417. ccw->cmd_code = NOP;
  418. ccw->flags = 0;
  419. ccw->count = 0;
  420. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  421. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  422. ti->kernbuf = NULL;
  423. ti->userbuf = NULL;
  424. tapestate_set (ti, TS_FSB_INIT);
  425. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  426. #ifdef TAPE_DEBUG
  427. debug_text_event (tape_debug_area,6,"xfsr ccwgen");
  428. #endif /* TAPE_DEBUG */
  429. return cqr;
  430. }
  431. /*
  432.  * MTBSR: Backward space over 'count' tape blocks.
  433.  * (blocksize is set via MTSETBLK.
  434.  */
  435. ccw_req_t *
  436. tape34xx_mtbsr (tape_info_t * ti, int count)
  437. {
  438. long lockflags;
  439. int i;
  440. ccw_req_t *cqr;
  441. ccw1_t *ccw;
  442. if ((count == 0) || (count > 510)) {
  443. #ifdef TAPE_DEBUG
  444.         debug_text_exception (tape_debug_area,6,"xbsr parm");
  445. #endif /* TAPE_DEBUG */   
  446.         return NULL;
  447. }
  448. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  449. if (!cqr) {
  450. #ifdef TAPE_DEBUG
  451.         debug_text_exception (tape_debug_area,6,"xbsr nomem");
  452. #endif /* TAPE_DEBUG */
  453. return NULL;
  454. }
  455. ccw = cqr->cpaddr;
  456. ccw->cmd_code = MODE_SET_DB;
  457. ccw->flags = CCW_FLAG_CC;
  458. ccw->count = 1;
  459. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  460. ccw++;
  461. for (i = 0; i < count; i++) {
  462. ccw->cmd_code = BACKSPACEBLOCK;
  463. ccw->flags = CCW_FLAG_CC;
  464. ccw->count = 0;
  465. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  466. ccw++;
  467. }
  468. ccw->cmd_code = NOP;
  469. ccw->flags = 0;
  470. ccw->count = 0;
  471. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  472. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  473. ti->kernbuf = NULL;
  474. ti->userbuf = NULL;
  475. tapestate_set (ti, TS_BSB_INIT);
  476. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  477. #ifdef TAPE_DEBUG
  478. debug_text_event (tape_debug_area,6,"xbsr ccwg");
  479. #endif /* TAPE_DEBUG */
  480. return cqr;
  481. }
  482. /*
  483.  * MTWEOF: Write 'count' file marks at the current position.
  484.  */
  485. ccw_req_t *
  486. tape34xx_mtweof (tape_info_t * ti, int count)
  487. {
  488. long lockflags;
  489. int i;
  490. ccw_req_t *cqr;
  491. ccw1_t *ccw;
  492. if ((count == 0) || (count > 510)) {
  493. #ifdef TAPE_DEBUG
  494.         debug_text_exception (tape_debug_area,6,"xweo parm");
  495. #endif /* TAPE_DEBUG */
  496. return NULL;
  497. }
  498. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  499. if (!cqr) {
  500. #ifdef TAPE_DEBUG
  501.         debug_text_exception (tape_debug_area,6,"xweo nomem");
  502. #endif /* TAPE_DEBUG */
  503. return NULL;
  504. }
  505. ccw = cqr->cpaddr;
  506. ccw->cmd_code = MODE_SET_DB;
  507. ccw->flags = CCW_FLAG_CC;
  508. ccw->count = 1;
  509. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  510. ccw++;
  511. for (i = 0; i < count; i++) {
  512. ccw->cmd_code = WRITETAPEMARK;
  513. ccw->flags = CCW_FLAG_CC;
  514. ccw->count = 1;
  515. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  516. ccw++;
  517. }
  518. ccw->cmd_code = NOP;
  519. ccw->flags = 0;
  520. ccw->count = 0;
  521. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  522. ccw++;
  523. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  524. ti->kernbuf = NULL;
  525. ti->userbuf = NULL;
  526. tapestate_set (ti, TS_WTM_INIT);
  527. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  528. #ifdef TAPE_DEBUG
  529. debug_text_event (tape_debug_area,6,"xweo ccwg");
  530. #endif /* TAPE_DEBUG */
  531. return cqr;
  532. }
  533. /*
  534.  * MTREW: Rewind the tape.
  535.  */
  536. ccw_req_t *
  537. tape34xx_mtrew (tape_info_t * ti, int count)
  538. {
  539. long lockflags;
  540. ccw_req_t *cqr;
  541. ccw1_t *ccw;
  542. cqr = tape_alloc_ccw_req (ti, 3, 0);
  543. if (!cqr) {
  544. #ifdef TAPE_DEBUG
  545.         debug_text_exception (tape_debug_area,6,"xrew nomem");
  546. #endif /* TAPE_DEBUG */
  547. return NULL;
  548. }
  549. ccw = cqr->cpaddr;
  550. ccw->cmd_code = MODE_SET_DB;
  551. ccw->flags = CCW_FLAG_CC;
  552. ccw->count = 1;
  553. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  554. ccw++;
  555. ccw->cmd_code = REWIND;
  556. ccw->flags = CCW_FLAG_CC;
  557. ccw->count = 0;
  558. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  559. ccw++;
  560. ccw->cmd_code = NOP;
  561. ccw->flags = 0;
  562. ccw->count = 0;
  563. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  564. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  565. ti->kernbuf = NULL;
  566. ti->userbuf = NULL;
  567. tapestate_set (ti, TS_REW_INIT);
  568. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  569. #ifdef TAPE_DEBUG
  570. debug_text_event (tape_debug_area,6,"xrew ccwg");
  571. #endif /* TAPE_DEBUG */
  572. return cqr;
  573. }
  574. /*
  575.  * MTOFFL: Rewind the tape and put the drive off-line.
  576.  * Implement 'rewind unload'
  577.  */
  578. ccw_req_t *
  579. tape34xx_mtoffl (tape_info_t * ti, int count)
  580. {
  581. long lockflags;
  582. ccw_req_t *cqr;
  583. ccw1_t *ccw;
  584. cqr = tape_alloc_ccw_req (ti, 3, 32);
  585. if (!cqr) {
  586. #ifdef TAPE_DEBUG
  587.         debug_text_exception (tape_debug_area,6,"xoff nomem");
  588. #endif /* TAPE_DEBUG */
  589. return NULL;
  590. }
  591. ccw = cqr->cpaddr;
  592. ccw->cmd_code = MODE_SET_DB;
  593. ccw->flags = CCW_FLAG_CC;
  594. ccw->count = 1;
  595. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  596. ccw++;
  597. ccw->cmd_code = REWIND_UNLOAD;
  598. ccw->flags = CCW_FLAG_CC;
  599. ccw->count = 1;
  600. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  601. ccw++;
  602. ccw->cmd_code = SENSE;
  603. ccw->flags = 0;
  604. ccw->count = 32;
  605. ccw->cda = (unsigned long) cqr->cpaddr;
  606. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  607. ti->kernbuf = NULL;
  608. ti->userbuf = NULL;
  609. tapestate_set (ti, TS_RUN_INIT);
  610. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  611. #ifdef TAPE_DEBUG
  612. debug_text_event (tape_debug_area,6,"xoff ccwg");
  613. #endif /* TAPE_DEBUG */
  614. return cqr;
  615. }
  616. /*
  617.  * MTNOP: 'No operation'.
  618.  */
  619. ccw_req_t *
  620. tape34xx_mtnop (tape_info_t * ti, int count)
  621. {
  622. long lockflags;
  623. ccw_req_t *cqr;
  624. ccw1_t *ccw;
  625. cqr = tape_alloc_ccw_req (ti, 1, 0);
  626. if (!cqr) {
  627. #ifdef TAPE_DEBUG
  628.         debug_text_exception (tape_debug_area,6,"xnop nomem");
  629. #endif /* TAPE_DEBUG */
  630. return NULL;
  631. }
  632. ccw = cqr->cpaddr;
  633. ccw->cmd_code = NOP;
  634. ccw->flags = 0;
  635. ccw->count = 0;
  636. ccw->cda = (unsigned long) ccw->cmd_code;
  637. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  638. ti->kernbuf = NULL;
  639. ti->userbuf = NULL;
  640. tapestate_set (ti, TS_NOP_INIT);
  641. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  642. #ifdef TAPE_DEBUG
  643. debug_text_event (tape_debug_area,6,"xnop ccwg");
  644. #endif /* TAPE_DEBUG */
  645. return cqr;
  646. }
  647. /*
  648.  * MTBSFM: Backward space over 'count' file marks.
  649.  * The tape is positioned at the BOT (Begin Of Tape) side of the
  650.  * last skipped file mark.
  651.  */
  652. ccw_req_t *
  653. tape34xx_mtbsfm (tape_info_t * ti, int count)
  654. {
  655. long lockflags;
  656. int i;
  657. ccw_req_t *cqr;
  658. ccw1_t *ccw;
  659. if ((count == 0) || (count > 510)) {
  660. #ifdef TAPE_DEBUG
  661.         debug_text_exception (tape_debug_area,6,"xbsm parm");
  662. #endif /* TAPE_DEBUG */
  663. return NULL;
  664. }
  665. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  666. if (!cqr) {
  667. #ifdef TAPE_DEBUG
  668.         debug_text_exception (tape_debug_area,6,"xbsm nomem");
  669. #endif /* TAPE_DEBUG */
  670. return NULL;
  671. }
  672. ccw = cqr->cpaddr;
  673. ccw->cmd_code = MODE_SET_DB;
  674. ccw->flags = CCW_FLAG_CC;
  675. ccw->count = 1;
  676. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  677. ccw++;
  678. for (i = 0; i < count; i++) {
  679. ccw->cmd_code = BACKSPACEFILE;
  680. ccw->flags = CCW_FLAG_CC;
  681. ccw->count = 0;
  682. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  683. ccw++;
  684. }
  685. ccw->cmd_code = NOP;
  686. ccw->flags = 0;
  687. ccw->count = 0;
  688. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  689. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  690. ti->kernbuf = NULL;
  691. ti->userbuf = NULL;
  692. tapestate_set (ti, TS_BSF_INIT);
  693. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  694. #ifdef TAPE_DEBUG
  695. debug_text_event (tape_debug_area,6,"xbsm ccwg");
  696. #endif /* TAPE_DEBUG */
  697. return cqr;
  698. }
  699. /*
  700.  * MTFSFM: Forward space over 'count' file marks.
  701.  * The tape is positioned at the BOT (Begin Of Tape) side
  702.  * of the last skipped file mark.
  703.  */
  704. ccw_req_t *
  705. tape34xx_mtfsfm (tape_info_t * ti, int count)
  706. {
  707. long lockflags;
  708. int i;
  709. ccw_req_t *cqr;
  710. ccw1_t *ccw;
  711. if ((count == 0) || (count > 510)) {
  712. #ifdef TAPE_DEBUG
  713.         debug_text_exception (tape_debug_area,6,"xfsm parm");
  714. #endif /* TAPE_DEBUG */
  715. return NULL;
  716. }
  717. cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
  718. if (!cqr) {
  719. #ifdef TAPE_DEBUG
  720.         debug_text_exception (tape_debug_area,6,"xfsm nomem");
  721. #endif /* TAPE_DEBUG */     
  722. return NULL;
  723. }
  724. ccw = cqr->cpaddr;
  725. ccw->cmd_code = MODE_SET_DB;
  726. ccw->flags = CCW_FLAG_CC;
  727. ccw->count = 1;
  728. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  729. ccw++;
  730. for (i = 0; i < count; i++) {
  731. ccw->cmd_code = FORSPACEFILE;
  732. ccw->flags = CCW_FLAG_CC;
  733. ccw->count = 0;
  734. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  735. ccw++;
  736. }
  737. ccw->cmd_code = NOP;
  738. ccw->flags = 0;
  739. ccw->count = 0;
  740. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  741. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  742. ti->kernbuf = NULL;
  743. ti->userbuf = NULL;
  744. tapestate_set (ti, TS_FSF_INIT);
  745. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  746. #ifdef TAPE_DEBUG
  747. debug_text_event (tape_debug_area,6,"xfsm ccwg");
  748. #endif /* TAPE_DEBUG */
  749. return cqr;
  750. }
  751. /*
  752.  * MTEOM: positions at the end of the portion of the tape already used
  753.  * for recordind data. MTEOM positions after the last file mark, ready for
  754.  * appending another file.
  755.  * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
  756.  */
  757. ccw_req_t *
  758. tape34xx_mteom (tape_info_t * ti, int count)
  759. {
  760. long lockflags;
  761. ccw_req_t *cqr;
  762. ccw1_t *ccw;
  763. cqr = tape_alloc_ccw_req (ti, 4, 0);
  764. if (!cqr) {
  765. #ifdef TAPE_DEBUG
  766.         debug_text_exception (tape_debug_area,6,"xeom nomem");
  767. #endif /* TAPE_DEBUG */
  768. return NULL;
  769. }
  770. ccw = cqr->cpaddr;
  771. ccw->cmd_code = MODE_SET_DB;
  772. ccw->flags = CCW_FLAG_CC;
  773. ccw->count = 1;
  774. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  775. ccw++;
  776. ccw->cmd_code = FORSPACEFILE;
  777. ccw->flags = CCW_FLAG_CC;
  778. ccw->count = 0;
  779. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  780. ccw++;
  781. ccw->cmd_code = NOP;
  782. ccw->flags = CCW_FLAG_CC;
  783. ccw->count = 0;
  784. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  785. ccw++;
  786. ccw->cmd_code = CCW_CMD_TIC;
  787. ccw->flags = 0;
  788. ccw->count = 0;
  789. ccw->cda = (unsigned long) (cqr->cpaddr);
  790. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  791. ti->kernbuf = NULL;
  792. ti->userbuf = NULL;
  793. tapestate_set (ti, TS_FSF_INIT);
  794. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  795. #ifdef TAPE_DEBUG
  796. debug_text_event (tape_debug_area,6,"xeom ccwg");
  797. #endif /* TAPE_DEBUG */
  798. return cqr;
  799. }
  800. /*
  801.  * MTERASE: erases the tape.
  802.  */
  803. ccw_req_t *
  804. tape34xx_mterase (tape_info_t * ti, int count)
  805. {
  806. long lockflags;
  807. ccw_req_t *cqr;
  808. ccw1_t *ccw;
  809. cqr = tape_alloc_ccw_req (ti, 5, 0);
  810. if (!cqr) {
  811. #ifdef TAPE_DEBUG
  812.         debug_text_exception (tape_debug_area,6,"xera nomem");
  813. #endif /* TAPE_DEBUG */
  814. return NULL;
  815. }
  816. ccw = cqr->cpaddr;
  817. ccw->cmd_code = MODE_SET_DB;
  818. ccw->flags = CCW_FLAG_CC;
  819. ccw->count = 1;
  820. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  821. ccw++;
  822. ccw->cmd_code = REWIND;
  823. ccw->flags = CCW_FLAG_CC;
  824. ccw->count = 0;
  825. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  826. ccw++;
  827. ccw->cmd_code = ERASE_GAP;
  828. ccw->flags = CCW_FLAG_CC;
  829. ccw->count = 0;
  830. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  831. ccw++;
  832. ccw->cmd_code = DATA_SEC_ERASE;
  833. ccw->flags = CCW_FLAG_CC;
  834. ccw->count = 0;
  835. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  836. ccw++;
  837. ccw->cmd_code = NOP;
  838. ccw->flags = 0;
  839. ccw->count = 0;
  840. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  841. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  842. ti->kernbuf = NULL;
  843. ti->userbuf = NULL;
  844. tapestate_set (ti, TS_DSE_INIT);
  845. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  846. #ifdef TAPE_DEBUG
  847. debug_text_event (tape_debug_area,6,"xera ccwg");
  848. #endif /* TAPE_DEBUG */
  849. return cqr;
  850. }
  851. /*
  852.  * MTSETDENSITY: set tape density.
  853.  */
  854. ccw_req_t *
  855. tape34xx_mtsetdensity (tape_info_t * ti, int count)
  856. {
  857. long lockflags;
  858. ccw_req_t *cqr;
  859. ccw1_t *ccw;
  860. cqr = tape_alloc_ccw_req (ti, 2, 0);
  861. if (!cqr) {
  862. #ifdef TAPE_DEBUG
  863.         debug_text_exception (tape_debug_area,6,"xden nomem");
  864. #endif /* TAPE_DEBUG */
  865. return NULL;
  866. }
  867. ccw = cqr->cpaddr;
  868. ccw->cmd_code = MODE_SET_DB;
  869. ccw->flags = CCW_FLAG_CC;
  870. ccw->count = 1;
  871. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  872. ccw++;
  873. ccw->cmd_code = NOP;
  874. ccw->flags = 0;
  875. ccw->count = 0;
  876. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  877. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  878. ti->kernbuf = NULL;
  879. ti->userbuf = NULL;
  880. tapestate_set (ti, TS_NOP_INIT);
  881. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  882. #ifdef TAPE_DEBUG
  883. debug_text_event (tape_debug_area,6,"xden ccwg");
  884. #endif /* TAPE_DEBUG */
  885. return cqr;
  886. }
  887. /*
  888.  * MTSEEK: seek to the specified block.
  889.  */
  890. ccw_req_t *
  891. tape34xx_mtseek (tape_info_t * ti, int count)
  892. {
  893. long lockflags;
  894. __u8 *data;
  895. ccw_req_t *cqr;
  896. ccw1_t *ccw;
  897. if ((data = kmalloc (4 * sizeof (__u8), GFP_KERNEL)) == NULL) {
  898. #ifdef TAPE_DEBUG
  899.         debug_text_exception (tape_debug_area,6,"xsee nomem");
  900. #endif /* TAPE_DEBUG */
  901. return NULL;
  902. }
  903. data[0] = 0x01;
  904. data[1] = data[2] = data[3] = 0x00;
  905. if (count >= 4194304) {
  906. #ifdef TAPE_DEBUG
  907.         debug_text_exception (tape_debug_area,6,"xsee parm");
  908. #endif /* TAPE_DEBUG */
  909. kfree(data);
  910. return NULL;
  911. }
  912. if (((tape34xx_disc_data_t *) ti->discdata)->modeset_byte & 0x08) // IDRC on
  913. data[1] = data[1] | 0x80;
  914. data[3] += count % 256;
  915. data[2] += (count / 256) % 256;
  916. data[1] += (count / 65536);
  917. #ifdef TAPE_DEBUG
  918. debug_text_event (tape_debug_area,6,"xsee id:");
  919. debug_int_event (tape_debug_area,6,count);
  920. #endif /* TAPE_DEBUG */
  921. cqr = tape_alloc_ccw_req (ti, 3, 0);
  922. if (!cqr) {
  923. #ifdef TAPE_DEBUG
  924.         debug_text_exception (tape_debug_area,6,"xsee nomem");
  925. #endif /* TAPE_DEBUG */
  926. kfree (data);
  927. return NULL;
  928. }
  929. ccw = cqr->cpaddr;
  930. ccw->cmd_code = MODE_SET_DB;
  931. ccw->flags = CCW_FLAG_CC;
  932. ccw->count = 1;
  933. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  934. ccw++;
  935. ccw->cmd_code = LOCATE;
  936. ccw->flags = CCW_FLAG_CC;
  937. ccw->count = 4;
  938. set_normalized_cda (ccw, (unsigned long) data);
  939. ccw++;
  940. ccw->cmd_code = NOP;
  941. ccw->flags = 0;
  942. ccw->count = 0;
  943. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  944. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  945. ti->kernbuf = data;
  946. ti->userbuf = NULL;
  947. tapestate_set (ti, TS_LBL_INIT);
  948. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  949. #ifdef TAPE_DEBUG
  950. debug_text_event (tape_debug_area,6,"xsee ccwg");
  951. #endif /* TAPE_DEBUG */
  952. return cqr;
  953. }
  954. /*
  955.  * MTTELL: Tell block. Return the number of block relative to current file.
  956.  */
  957. ccw_req_t *
  958. tape34xx_mttell (tape_info_t * ti, int count)
  959. {
  960. long lockflags;
  961. ccw_req_t *cqr;
  962. ccw1_t *ccw;
  963. void *mem;
  964. cqr = tape_alloc_ccw_req (ti, 2, 0);
  965. if (!cqr) {
  966. #ifdef TAPE_DEBUG
  967.         debug_text_exception (tape_debug_area,6,"xtel nomem");
  968. #endif /* TAPE_DEBUG */
  969. return NULL;
  970. }
  971. mem = kmalloc (8, GFP_KERNEL);
  972. if (!mem) {
  973. tape_free_request (cqr);
  974. #ifdef TAPE_DEBUG
  975.         debug_text_exception (tape_debug_area,6,"xtel nomem");
  976. #endif /* TAPE_DEBUG */
  977. return NULL;
  978. }
  979. ccw = cqr->cpaddr;
  980. ccw->cmd_code = MODE_SET_DB;
  981. ccw->flags = CCW_FLAG_CC;
  982. ccw->count = 1;
  983. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  984. ccw++;
  985. ccw->cmd_code = READ_BLOCK_ID;
  986. ccw->flags = 0;
  987. ccw->count = 8;
  988. set_normalized_cda (ccw, (unsigned long) mem);
  989. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  990. ti->kernbuf = mem;
  991. ti->userbuf = NULL;
  992. tapestate_set (ti, TS_RBI_INIT);
  993. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  994. #ifdef TAPE_DEBUG
  995. debug_text_event (tape_debug_area,6,"xtel ccwg");
  996. #endif /* TAPE_DEBUG */
  997. return cqr;
  998. }
  999. /*
  1000.  * MTSETDRVBUFFER: Set the tape drive buffer code to number.
  1001.  * Implement NOP.
  1002.  */
  1003. ccw_req_t *
  1004. tape34xx_mtsetdrvbuffer (tape_info_t * ti, int count)
  1005. {
  1006. long lockflags;
  1007. ccw_req_t *cqr;
  1008. ccw1_t *ccw;
  1009. cqr = tape_alloc_ccw_req (ti, 2, 0);
  1010. if (!cqr) {
  1011. #ifdef TAPE_DEBUG
  1012.         debug_text_exception (tape_debug_area,6,"xbuf nomem");
  1013. #endif /* TAPE_DEBUG */
  1014. return NULL;
  1015. }
  1016. ccw = cqr->cpaddr;
  1017. ccw->cmd_code = MODE_SET_DB;
  1018. ccw->flags = CCW_FLAG_CC;
  1019. ccw->count = 1;
  1020. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1021. ccw++;
  1022. ccw->cmd_code = NOP;
  1023. ccw->flags = 0;
  1024. ccw->count = 0;
  1025. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1026. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1027. ti->kernbuf = NULL;
  1028. ti->userbuf = NULL;
  1029. tapestate_set (ti, TS_NOP_INIT);
  1030. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1031. #ifdef TAPE_DEBUG
  1032. debug_text_event (tape_debug_area,6,"xbuf ccwg");
  1033. #endif /* TAPE_DEBUG */
  1034. return cqr;
  1035. }
  1036. /*
  1037.  * MTLOCK: Locks the tape drive door.
  1038.  * Implement NOP CCW command.
  1039.  */
  1040. ccw_req_t *
  1041. tape34xx_mtlock (tape_info_t * ti, int count)
  1042. {
  1043. long lockflags;
  1044. ccw_req_t *cqr;
  1045. ccw1_t *ccw;
  1046. cqr = tape_alloc_ccw_req (ti, 2, 0);
  1047. if (!cqr) {
  1048. #ifdef TAPE_DEBUG
  1049.         debug_text_exception (tape_debug_area,6,"xloc nomem");
  1050. #endif /* TAPE_DEBUG */
  1051. return NULL;
  1052. }
  1053. ccw = cqr->cpaddr;
  1054. ccw->cmd_code = MODE_SET_DB;
  1055. ccw->flags = CCW_FLAG_CC;
  1056. ccw->count = 1;
  1057. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1058. ccw++;
  1059. ccw->cmd_code = NOP;
  1060. ccw->flags = 0;
  1061. ccw->count = 0;
  1062. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1063. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1064. ti->kernbuf = NULL;
  1065. ti->userbuf = NULL;
  1066. tapestate_set (ti, TS_NOP_INIT);
  1067. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1068. #ifdef TAPE_DEBUG
  1069. debug_text_event (tape_debug_area,6,"xloc ccwg");
  1070. #endif /* TAPE_DEBUG */
  1071. return cqr;
  1072. }
  1073. /*
  1074.  * MTUNLOCK: Unlocks the tape drive door.
  1075.  * Implement the NOP CCW command.
  1076.  */
  1077. ccw_req_t *
  1078. tape34xx_mtunlock (tape_info_t * ti, int count)
  1079. {
  1080. long lockflags;
  1081. ccw_req_t *cqr;
  1082. ccw1_t *ccw;
  1083. cqr = tape_alloc_ccw_req (ti, 2, 0);
  1084. if (!cqr) {
  1085. #ifdef TAPE_DEBUG
  1086.         debug_text_exception (tape_debug_area,6,"xulk nomem");
  1087. #endif /* TAPE_DEBUG */
  1088. return NULL;
  1089. }
  1090. ccw = cqr->cpaddr;
  1091. ccw->cmd_code = MODE_SET_DB;
  1092. ccw->flags = CCW_FLAG_CC;
  1093. ccw->count = 1;
  1094. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1095. ccw++;
  1096. ccw->cmd_code = NOP;
  1097. ccw->flags = 0;
  1098. ccw->count = 0;
  1099. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1100. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1101. ti->kernbuf = NULL;
  1102. ti->userbuf = NULL;
  1103. tapestate_set (ti, TS_NOP_INIT);
  1104. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1105. #ifdef TAPE_DEBUG
  1106. debug_text_event (tape_debug_area,6,"xulk ccwg");
  1107. #endif /* TAPE_DEBUG */
  1108. return cqr;
  1109. }
  1110. /*
  1111.  * MTLOAD: Loads the tape.
  1112.  * This function is not implemented and returns NULL, which causes the Frontend to wait for a medium being loaded.
  1113.  *  The 3480/3490 type Tapes do not support a load command
  1114.  */
  1115. ccw_req_t *
  1116. tape34xx_mtload (tape_info_t * ti, int count)
  1117. {
  1118.          return NULL;
  1119. }
  1120. /*
  1121.  * MTUNLOAD: Rewind the tape and unload it.
  1122.  */
  1123. ccw_req_t *
  1124. tape34xx_mtunload (tape_info_t * ti, int count)
  1125. {
  1126. long lockflags;
  1127. ccw_req_t *cqr;
  1128. ccw1_t *ccw;
  1129. cqr = tape_alloc_ccw_req (ti, 3, 32);
  1130. if (!cqr) {
  1131. #ifdef TAPE_DEBUG
  1132.         debug_text_exception (tape_debug_area,6,"xunl nomem");
  1133. #endif /* TAPE_DEBUG */
  1134. return NULL;
  1135. }
  1136. ccw = cqr->cpaddr;
  1137. ccw->cmd_code = MODE_SET_DB;
  1138. ccw->flags = CCW_FLAG_CC;
  1139. ccw->count = 1;
  1140. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1141. ccw++;
  1142. ccw->cmd_code = REWIND_UNLOAD;
  1143. ccw->flags = CCW_FLAG_CC;
  1144. ccw->count = 1;
  1145. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1146. ccw++;
  1147. ccw->cmd_code = SENSE;
  1148. ccw->flags = 0;
  1149. ccw->count = 32;
  1150. ccw->cda = (unsigned long) cqr->cpaddr;
  1151. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1152. ti->kernbuf = NULL;
  1153. ti->userbuf = NULL;
  1154. tapestate_set (ti, TS_RUN_INIT);
  1155. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1156. #ifdef TAPE_DEBUG
  1157. debug_text_event (tape_debug_area,6,"xunl ccwg");
  1158. #endif /* TAPE_DEBUG */
  1159. return cqr;
  1160. }
  1161. /*
  1162.  * MTCOMPRESSION: used to enable compression.
  1163.  * Sets the IDRC on/off.
  1164.  */
  1165. ccw_req_t *
  1166. tape34xx_mtcompression (tape_info_t * ti, int count)
  1167. {
  1168. long lockflags;
  1169. ccw_req_t *cqr;
  1170. ccw1_t *ccw;
  1171. if ((count < 0) || (count > 1)) {
  1172. #ifdef TAPE_DEBUG
  1173.         debug_text_exception (tape_debug_area,6,"xcom parm");
  1174. #endif /* TAPE_DEBUG */
  1175. return NULL;
  1176. }
  1177. if (count == 0)
  1178. ((tape34xx_disc_data_t *) ti->discdata)->modeset_byte = 0x00; // IDRC off
  1179. else
  1180. ((tape34xx_disc_data_t *) ti->discdata)->modeset_byte = 0x08; // IDRC on
  1181. cqr = tape_alloc_ccw_req (ti, 2, 0);
  1182. if (!cqr) {
  1183. #ifdef TAPE_DEBUG
  1184.         debug_text_exception (tape_debug_area,6,"xcom nomem");
  1185. #endif /* TAPE_DEBUG */
  1186. return NULL;
  1187. }
  1188. ccw = cqr->cpaddr;
  1189. ccw->cmd_code = MODE_SET_DB;
  1190. ccw->flags = CCW_FLAG_CC;
  1191. ccw->count = 1;
  1192. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1193. ccw++;
  1194. ccw->cmd_code = NOP;
  1195. ccw->flags = 0;
  1196. ccw->count = 0;
  1197. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1198. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1199. ti->kernbuf = NULL;
  1200. ti->userbuf = NULL;
  1201. tapestate_set (ti, TS_NOP_INIT);
  1202. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1203. #ifdef TAPE_DEBUG
  1204. debug_text_event (tape_debug_area,6,"xcom ccwg");
  1205. #endif /* TAPE_DEBUG */
  1206. return cqr;
  1207. }
  1208. /*
  1209.  * MTSTPART: Move the tape head at the partition with the number 'count'.
  1210.  * Implement the NOP CCW command.
  1211.  */
  1212. ccw_req_t *
  1213. tape34xx_mtsetpart (tape_info_t * ti, int count)
  1214. {
  1215. long lockflags;
  1216. ccw_req_t *cqr;
  1217. ccw1_t *ccw;
  1218. cqr = tape_alloc_ccw_req (ti, 2, 0);
  1219. if (!cqr) {
  1220. #ifdef TAPE_DEBUG
  1221.         debug_text_exception (tape_debug_area,6,"xspa nomem");
  1222. #endif /* TAPE_DEBUG */     
  1223. return NULL;
  1224. }
  1225. ccw = cqr->cpaddr;
  1226. ccw->cmd_code = MODE_SET_DB;
  1227. ccw->flags = CCW_FLAG_CC;
  1228. ccw->count = 1;
  1229. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1230. ccw++;
  1231. ccw->cmd_code = NOP;
  1232. ccw->flags = 0;
  1233. ccw->count = 0;
  1234. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1235. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1236. ti->kernbuf = NULL;
  1237. ti->userbuf = NULL;
  1238. tapestate_set (ti, TS_NOP_INIT);
  1239. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1240. #ifdef TAPE_DEBUG
  1241. debug_text_event (tape_debug_area,6,"xspa ccwg");
  1242. #endif /* TAPE_DEBUG */
  1243. return cqr;
  1244. }
  1245. /*
  1246.  * MTMKPART: .... dummy .
  1247.  * Implement the NOP CCW command.
  1248.  */
  1249. ccw_req_t *
  1250. tape34xx_mtmkpart (tape_info_t * ti, int count)
  1251. {
  1252. long lockflags;
  1253. ccw_req_t *cqr;
  1254. ccw1_t *ccw;
  1255. cqr = tape_alloc_ccw_req (ti, 2, 0);
  1256. if (!cqr) {
  1257. #ifdef TAPE_DEBUG
  1258.         debug_text_exception (tape_debug_area,6,"xnpa nomem");
  1259. #endif /* TAPE_DEBUG */
  1260. return NULL;
  1261. }
  1262. ccw = cqr->cpaddr;
  1263. ccw->cmd_code = MODE_SET_DB;
  1264. ccw->flags = CCW_FLAG_CC;
  1265. ccw->count = 1;
  1266. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1267. ccw++;
  1268. ccw->cmd_code = NOP;
  1269. ccw->flags = 0;
  1270. ccw->count = 0;
  1271. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1272. s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
  1273. ti->kernbuf = NULL;
  1274. ti->userbuf = NULL;
  1275. tapestate_set (ti, TS_NOP_INIT);
  1276. s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
  1277. #ifdef TAPE_DEBUG
  1278. debug_text_event (tape_debug_area,6,"xnpa ccwg");
  1279. #endif /* TAPE_DEBUG */
  1280. return cqr;
  1281. }
  1282. /*
  1283.  * MTIOCGET: query the tape drive status.
  1284.  */
  1285. ccw_req_t *
  1286. tape34xx_mtiocget (tape_info_t * ti, int count)
  1287. {
  1288. return NULL;
  1289. }
  1290. /*
  1291.  * MTIOCPOS: query the tape position.
  1292.  */
  1293. ccw_req_t *
  1294. tape34xx_mtiocpos (tape_info_t * ti, int count)
  1295. {
  1296. return NULL;
  1297. }
  1298. ccw_req_t * tape34xx_bread (struct request *req,tape_info_t* ti,int tapeblock_major) {
  1299. ccw_req_t *cqr;
  1300. ccw1_t *ccw;
  1301. __u8 *data;
  1302. int s2b = blksize_size[tapeblock_major][ti->blk_minor]/hardsect_size[tapeblock_major][ti->blk_minor];
  1303. int realcount;
  1304. int size,bhct = 0;
  1305. struct buffer_head* bh;
  1306. for (bh = req->bh; bh; bh = bh->b_reqnext) {
  1307. if (bh->b_size > blksize_size[tapeblock_major][ti->blk_minor])
  1308. for (size = 0; size < bh->b_size; size += blksize_size[tapeblock_major][ti->blk_minor])
  1309. bhct++;
  1310. else
  1311. bhct++;
  1312. }
  1313. if ((data = kmalloc (4 * sizeof (__u8), GFP_ATOMIC)) == NULL) {
  1314. #ifdef TAPE_DEBUG
  1315.         debug_text_exception (tape_debug_area,3,"xBREDnomem");
  1316. #endif /* TAPE_DEBUG */
  1317. return NULL;
  1318. }
  1319. data[0] = 0x01;
  1320. data[1] = data[2] = data[3] = 0x00;
  1321. realcount=req->sector/s2b;
  1322. if (((tape34xx_disc_data_t *) ti->discdata)->modeset_byte & 0x08) // IDRC on
  1323. data[1] = data[1] | 0x80;
  1324. data[3] += realcount % 256;
  1325. data[2] += (realcount / 256) % 256;
  1326. data[1] += (realcount / 65536);
  1327. #ifdef TAPE_DEBUG
  1328. debug_text_event (tape_debug_area,6,"xBREDid:");
  1329. debug_int_event (tape_debug_area,6,realcount);
  1330. #endif /* TAPE_DEBUG */
  1331. cqr = tape_alloc_ccw_req (ti, 2+bhct+1, 0);
  1332. if (!cqr) {
  1333. #ifdef TAPE_DEBUG
  1334.         debug_text_exception (tape_debug_area,6,"xBREDnomem");
  1335. #endif /* TAPE_DEBUG */
  1336. kfree(data);
  1337. return NULL;
  1338. }
  1339. ccw = cqr->cpaddr;
  1340. ccw->cmd_code = MODE_SET_DB;
  1341. ccw->flags = CCW_FLAG_CC;
  1342. ccw->count = 1;
  1343. set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
  1344. if (realcount!=ti->position) {
  1345.     ccw++;
  1346.     ccw->cmd_code = LOCATE;
  1347.     ccw->flags = CCW_FLAG_CC;
  1348.     ccw->count = 4;
  1349.     set_normalized_cda (ccw, (unsigned long) data);
  1350. }
  1351. ti->position=realcount+req->nr_sectors/s2b;
  1352. for (bh=req->bh;bh!=NULL;) {
  1353.         ccw->flags = CCW_FLAG_CC;
  1354. if (bh->b_size >= blksize_size[tapeblock_major][ti->blk_minor]) {
  1355. for (size = 0; size < bh->b_size; size += blksize_size[tapeblock_major][ti->blk_minor]) {
  1356.         ccw++;
  1357. ccw->flags = CCW_FLAG_CC;
  1358. ccw->cmd_code = READ_FORWARD;
  1359. ccw->count = blksize_size[tapeblock_major][ti->blk_minor];
  1360. set_normalized_cda (ccw, __pa (bh->b_data + size));
  1361. }
  1362. bh = bh->b_reqnext;
  1363. } else { /* group N bhs to fit into byt_per_blk */
  1364. for (size = 0; bh != NULL && size < blksize_size[tapeblock_major][ti->blk_minor];) {
  1365. ccw++;
  1366. ccw->flags = CCW_FLAG_DC;
  1367. ccw->cmd_code = READ_FORWARD;
  1368. ccw->count = bh->b_size;
  1369. set_normalized_cda (ccw, __pa (bh->b_data));
  1370. size += bh->b_size;
  1371. bh = bh->b_reqnext;
  1372. }
  1373. if (size != blksize_size[tapeblock_major][ti->blk_minor]) {
  1374. PRINT_WARN ("Cannot fulfill small request %d vs. %d (%ld sects)n",
  1375.     size,
  1376.     blksize_size[tapeblock_major][ti->blk_minor],
  1377.     req->nr_sectors);
  1378. kfree(data);
  1379. tape_free_request (cqr);
  1380. return NULL;
  1381. }
  1382. }
  1383. }
  1384. ccw -> flags &= ~(CCW_FLAG_DC);
  1385. ccw -> flags |= (CCW_FLAG_CC);
  1386. ccw++;
  1387. ccw->cmd_code = NOP;
  1388. ccw->flags = 0;
  1389. ccw->count = 0;
  1390. ccw->cda = (unsigned long) (&(ccw->cmd_code));
  1391. ti->kernbuf = data;
  1392. ti->userbuf = NULL;
  1393. tapestate_set (ti, TS_BLOCK_INIT);
  1394. #ifdef TAPE_DEBUG
  1395. debug_text_event (tape_debug_area,6,"xBREDccwg");
  1396. #endif /* TAPE_DEBUG */
  1397. return cqr;
  1398. }
  1399. void tape34xx_free_bread (ccw_req_t* cqr,struct _tape_info_t* ti) {
  1400.     ccw1_t* ccw;
  1401.     for (ccw=(ccw1_t*)cqr->cpaddr;(ccw->flags & CCW_FLAG_CC)||(ccw->flags & CCW_FLAG_DC);ccw++) 
  1402. if ((ccw->cmd_code == MODE_SET_DB) ||
  1403.     (ccw->cmd_code == LOCATE) ||
  1404.     (ccw->cmd_code == READ_FORWARD))
  1405.     clear_normalized_cda(ccw);
  1406.     tape_free_request(cqr);
  1407.     kfree(ti->kernbuf);
  1408.     ti->kernbuf=NULL;
  1409. }
  1410. /* event handlers */
  1411. void
  1412. tape34xx_default_handler (tape_info_t * ti)
  1413. {
  1414. #ifdef TAPE_DEBUG
  1415.     debug_text_event (tape_debug_area,6,"xdefhandle");
  1416. #endif /* TAPE_DEBUG */
  1417. PRINT_ERR ("TAPE34XX: An unexpected Unit Check occurred.n");
  1418. PRINT_ERR ("TAPE34XX: Please read Documentation/s390/TAPE and report it!n");
  1419. PRINT_ERR ("TAPE34XX: Current state is: %s",
  1420.    (((tapestate_get (ti) < TS_SIZE) && (tapestate_get (ti) >= 0)) ?
  1421.     state_verbose[tapestate_get (ti)] : "->UNKNOWN STATE<-"));
  1422. tape_dump_sense (&ti->devstat);
  1423. ti->rc = -EIO;
  1424. ti->wanna_wakeup=1;
  1425.         switch (tapestate_get(ti)) {
  1426.         case TS_REW_RELEASE_INIT:
  1427.             tapestate_set(ti,TS_FAILED);
  1428.             wake_up (&ti->wq);
  1429.             break;
  1430.         case TS_BLOCK_INIT:
  1431.             tapestate_set(ti,TS_FAILED);
  1432.             schedule_tapeblock_exec_IO(ti);
  1433.             break;
  1434.         default:
  1435.             tapestate_set(ti,TS_FAILED);
  1436.             wake_up_interruptible (&ti->wq);
  1437.         }      
  1438. }
  1439. void
  1440. tape34xx_unexpect_uchk_handler (tape_info_t * ti)
  1441. {
  1442. if ((ti->devstat.ii.sense.data[0] == 0x40) &&
  1443.     (ti->devstat.ii.sense.data[1] == 0x40) &&
  1444.     (ti->devstat.ii.sense.data[3] == 0x43)) {
  1445. // no tape in the drive
  1446.         PRINT_INFO ("Drive %d not ready. No volume loaded.n", ti->rew_minor / 2);
  1447. #ifdef TAPE_DEBUG
  1448.         debug_text_event (tape_debug_area,3,"xuuh nomed");
  1449. #endif /* TAPE_DEBUG */
  1450. tapestate_set (ti, TS_FAILED);
  1451. ti->rc = -ENOMEDIUM;
  1452. ti->wanna_wakeup=1;
  1453. wake_up_interruptible (&ti->wq);
  1454. } else if ((ti->devstat.ii.sense.data[0] == 0x42) &&
  1455.    (ti->devstat.ii.sense.data[1] == 0x44) &&
  1456.    (ti->devstat.ii.sense.data[3] == 0x3b)) {
  1457.                 PRINT_INFO ("Media in drive %d was changed!n",
  1458.     ti->rew_minor / 2);
  1459. #ifdef TAPE_DEBUG
  1460. debug_text_event (tape_debug_area,3,"xuuh medchg");
  1461. #endif
  1462. /* nothing to do. chan end & dev end will be reported when io is finished */
  1463. } else {
  1464. #ifdef TAPE_DEBUG
  1465.         debug_text_event (tape_debug_area,3,"xuuh unexp");
  1466.         debug_text_event (tape_debug_area,3,"state:");
  1467.         debug_text_event (tape_debug_area,3,((tapestate_get (ti) < TS_SIZE) && 
  1468.      (tapestate_get (ti) >= 0)) ?
  1469.   state_verbose[tapestate_get (ti)] : 
  1470.   "TS UNKNOWN");
  1471. #endif /* TAPE_DEBUG */
  1472. tape34xx_default_handler (ti);
  1473. }
  1474. }
  1475. void
  1476. tape34xx_unused_done (tape_info_t * ti)
  1477. {
  1478.     if (ti->medium_is_unloaded) {
  1479. // A medium was inserted in the drive!
  1480. #ifdef TAPE_DEBUG
  1481. debug_text_event (tape_debug_area,6,"xuui med");
  1482. #endif /* TAPE_DEBUG */
  1483. PRINT_WARN ("A medium was inserted into the tape.n");
  1484. ti->medium_is_unloaded=0;
  1485.     } else {
  1486. #ifdef TAPE_DEBUG
  1487.         debug_text_event (tape_debug_area,3,"unsol.irq!");
  1488.         debug_text_event (tape_debug_area,3,"dev end");
  1489.         debug_int_exception (tape_debug_area,3,ti->devinfo.irq);
  1490. #endif /* TAPE_DEBUG */
  1491. PRINT_WARN ("Unsolicited IRQ (Device End) caught in unused state.n");
  1492. tape_dump_sense (&ti->devstat);
  1493.     }
  1494. }
  1495. void
  1496. tape34xx_idle_done (tape_info_t * ti)
  1497. {
  1498.     if (ti->medium_is_unloaded) {
  1499. // A medium was inserted in the drive!
  1500. #ifdef TAPE_DEBUG
  1501. debug_text_event (tape_debug_area,6,"xuud med");
  1502. #endif /* TAPE_DEBUG */
  1503. PRINT_WARN ("A medium was inserted into the tape.n");
  1504. ti->medium_is_unloaded=0;
  1505. wake_up_interruptible (&ti->wq);
  1506.     } else {
  1507. #ifdef TAPE_DEBUG
  1508.         debug_text_event (tape_debug_area,3,"unsol.irq!");
  1509.         debug_text_event (tape_debug_area,3,"dev end");
  1510.         debug_int_exception (tape_debug_area,3,ti->devinfo.irq);
  1511. #endif /* TAPE_DEBUG */
  1512. PRINT_WARN ("Unsolicited IRQ (Device End) caught in idle state.n");
  1513. tape_dump_sense (&ti->devstat);
  1514.     }
  1515. }
  1516. void
  1517. tape34xx_block_done (tape_info_t * ti)
  1518. {
  1519. #ifdef TAPE_DEBUG
  1520.         debug_text_event (tape_debug_area,6,"x:bREQdone");
  1521. #endif /* TAPE_DEBUG */
  1522. tapestate_set(ti,TS_DONE);
  1523. schedule_tapeblock_exec_IO(ti);
  1524. }
  1525. void
  1526. tape34xx_bsf_init_done (tape_info_t * ti)
  1527. {
  1528. #ifdef TAPE_DEBUG
  1529.         debug_text_event (tape_debug_area,6,"bsf done");
  1530. #endif
  1531. tapestate_set (ti, TS_DONE);
  1532. ti->rc = 0;
  1533. ti->wanna_wakeup=1;
  1534. wake_up_interruptible (&ti->wq);
  1535. }
  1536. void
  1537. tape34xx_dse_init_done (tape_info_t * ti)
  1538. {
  1539. #ifdef TAPE_DEBUG
  1540.         debug_text_event (tape_debug_area,6,"dse done");
  1541. #endif
  1542. tapestate_set (ti, TS_DONE);
  1543. ti->rc = 0;
  1544. ti->wanna_wakeup=1;
  1545. wake_up_interruptible (&ti->wq);
  1546. }
  1547. void
  1548. tape34xx_fsf_init_done (tape_info_t * ti)
  1549. {
  1550. #ifdef TAPE_DEBUG
  1551.         debug_text_event (tape_debug_area,6,"fsf done");
  1552. #endif
  1553. tapestate_set (ti, TS_DONE);
  1554. ti->rc = 0;
  1555. ti->wanna_wakeup=1;
  1556. wake_up_interruptible (&ti->wq);
  1557. }
  1558. void
  1559. tape34xx_fsb_init_done (tape_info_t * ti)
  1560. {
  1561. #ifdef TAPE_DEBUG
  1562.         debug_text_event (tape_debug_area,6,"fsb done");
  1563. #endif
  1564. tapestate_set (ti, TS_DONE);
  1565. ti->rc = 0;
  1566. ti->wanna_wakeup=1;
  1567. wake_up_interruptible (&ti->wq);
  1568. }
  1569. void
  1570. tape34xx_bsb_init_done (tape_info_t * ti)
  1571. {
  1572. #ifdef TAPE_DEBUG
  1573.         debug_text_event (tape_debug_area,6,"bsb done");
  1574. #endif
  1575. tapestate_set (ti, TS_DONE);
  1576. ti->rc = 0;
  1577. ti->wanna_wakeup=1;
  1578. wake_up (&ti->wq);
  1579. }
  1580. void
  1581. tape34xx_lbl_init_done (tape_info_t * ti)
  1582. {
  1583. #ifdef TAPE_DEBUG
  1584.         debug_text_event (tape_debug_area,6,"lbl done");
  1585. #endif
  1586. tapestate_set (ti, TS_DONE);
  1587. ti->rc = 0;
  1588. //s390irq_spin_unlock(tape->devinfo.irq);
  1589. ti->wanna_wakeup=1;
  1590. wake_up (&ti->wq);
  1591. }
  1592. void
  1593. tape34xx_nop_init_done (tape_info_t * ti)
  1594. {
  1595. #ifdef TAPE_DEBUG
  1596.         debug_text_event (tape_debug_area,6,"nop done..");
  1597.         debug_text_exception (tape_debug_area,6,"or rew/rel");
  1598. #endif
  1599. tapestate_set (ti, TS_DONE);
  1600. ti->rc = 0;
  1601. //s390irq_spin_unlock(tape->devinfo.irq);
  1602. ti->wanna_wakeup=1;
  1603. wake_up (&ti->wq);
  1604. }
  1605. void
  1606. tape34xx_rfo_init_done (tape_info_t * ti)
  1607. {
  1608. #ifdef TAPE_DEBUG
  1609.         debug_text_event (tape_debug_area,6,"rfo done");
  1610. #endif
  1611. tapestate_set (ti, TS_DONE);
  1612. ti->rc = 0;
  1613. ti->wanna_wakeup=1;
  1614. wake_up (&ti->wq);
  1615. }
  1616. void
  1617. tape34xx_rbi_init_done (tape_info_t * ti)
  1618. {
  1619. __u8 *data;
  1620. #ifdef TAPE_DEBUG
  1621. int i;
  1622. #endif
  1623. tapestate_set (ti, TS_FAILED);
  1624. data = ti->kernbuf;
  1625. ti->rc = data[3];
  1626. ti->rc += 256 * data[2];
  1627. ti->rc += 65536 * (data[1] & 0x3F);
  1628. #ifdef TAPE_DEBUG
  1629.         debug_text_event (tape_debug_area,6,"rbi done");
  1630.         debug_text_event (tape_debug_area,6,"data:");
  1631. for (i=0;i<8;i++)
  1632.     debug_int_event (tape_debug_area,6,data[i]);
  1633. #endif
  1634. ti->wanna_wakeup=1;
  1635. wake_up_interruptible (&ti->wq);
  1636. }
  1637. void
  1638. tape34xx_rew_init_done (tape_info_t * ti)
  1639. {
  1640. #ifdef TAPE_DEBUG
  1641.         debug_text_event (tape_debug_area,6,"rew done");
  1642. #endif
  1643. //BH: use irqsave
  1644. //s390irq_spin_lock(tape->devinfo.irq);
  1645. tapestate_set (ti, TS_DONE);
  1646. ti->rc = 0;
  1647. //s390irq_spin_unlock(tape->devinfo.irq);
  1648. ti->wanna_wakeup=1;
  1649. wake_up_interruptible (&ti->wq);
  1650. }
  1651. void
  1652. tape34xx_rew_release_init_done (tape_info_t * ti)
  1653. {
  1654. #ifdef TAPE_DEBUG
  1655.         debug_text_event (tape_debug_area,6,"rewR done");
  1656. #endif
  1657. tapestate_set (ti, TS_DONE);
  1658. ti->rc = 0;
  1659. //s390irq_spin_unlock(tape->devinfo.irq);
  1660. ti->wanna_wakeup=1;
  1661. wake_up (&ti->wq);
  1662. }
  1663. void
  1664. tape34xx_run_init_done (tape_info_t * ti)
  1665. {
  1666. #ifdef TAPE_DEBUG
  1667.         debug_text_event (tape_debug_area,6,"rew done");
  1668. #endif
  1669. tapestate_set (ti, TS_DONE);
  1670. ti->rc = 0;
  1671. ti->wanna_wakeup=1;
  1672. wake_up_interruptible (&ti->wq);
  1673. }
  1674. void
  1675. tape34xx_wri_init_done (tape_info_t * ti)
  1676. {
  1677. #ifdef TAPE_DEBUG
  1678.         debug_text_event (tape_debug_area,6,"wri done");
  1679. #endif
  1680. //BH: use irqsave
  1681. //s390irq_spin_lock(ti->devinfo.irq);
  1682. tapestate_set (ti, TS_DONE);
  1683. ti->rc = 0;
  1684. //s390irq_spin_unlock(ti->devinfo.irq);
  1685. ti->wanna_wakeup=1;
  1686. wake_up_interruptible (&ti->wq);
  1687. }
  1688. void
  1689. tape34xx_wtm_init_done (tape_info_t * ti)
  1690. {
  1691. #ifdef TAPE_DEBUG
  1692.         debug_text_event (tape_debug_area,3,"wtm done");
  1693. #endif
  1694. tapestate_set (ti, TS_DONE);
  1695. ti->rc = 0;
  1696. ti->wanna_wakeup=1;
  1697. wake_up_interruptible (&ti->wq);
  1698. }
  1699. /* This function analyses the tape's sense-data in case of a unit-check. If possible,
  1700.    it tries to recover from the error. Else the user is informed about the problem. */
  1701. void
  1702. tape34xx_error_recovery (tape_info_t* ti)
  1703. {
  1704.     __u8* sense=ti->devstat.ii.sense.data;
  1705.     int inhibit_cu_recovery=0;
  1706.     int cu_type=ti->discipline->cu_type;
  1707.     if ((((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)&0x80) inhibit_cu_recovery=1;
  1708.     if (tapestate_get(ti)==TS_BLOCK_INIT) {
  1709. // no recovery for block device, bottom half will retry...
  1710. tape34xx_error_recovery_has_failed(ti,EIO);
  1711. return;
  1712.     }
  1713.     if (sense[0]&SENSE_COMMAND_REJECT)
  1714. switch (tapestate_get(ti)) {
  1715. case TS_BLOCK_INIT:
  1716. case TS_DSE_INIT:
  1717. case TS_EGA_INIT:
  1718. case TS_WRI_INIT:
  1719. case TS_WTM_INIT:
  1720.     if (sense[1]&SENSE_WRITE_PROTECT) {
  1721. // trying to write, but medium is write protected
  1722. tape34xx_error_recovery_has_failed(ti,EACCES);
  1723. return;
  1724.     }
  1725. default:
  1726.     tape34xx_error_recovery_HWBUG(ti,1);
  1727.     return;
  1728. }
  1729.     // special cases for various tape-states when reaching end of recorded area
  1730.     if (((sense[0]==0x08) || (sense[0]==0x10) || (sense[0]==0x12)) &&
  1731. ((sense[1]==0x40) || (sense[1]==0x0c)))
  1732. switch (tapestate_get(ti)) {
  1733. case TS_FSF_INIT:
  1734.     // Trying to seek beyond end of recorded area
  1735.     tape34xx_error_recovery_has_failed(ti,EIO);
  1736.     return;
  1737. case TS_LBL_INIT:
  1738.     // Block could not be located.
  1739.     tape34xx_error_recovery_has_failed(ti,EIO);
  1740.     return;
  1741. case TS_RFO_INIT:
  1742.     // Try to read beyond end of recorded area -> 0 bytes read
  1743.     tape34xx_error_recovery_has_failed(ti,0);
  1744.     return;
  1745. }
  1746.     // Sensing special bits
  1747.     if (sense[0]&SENSE_BUS_OUT_CHECK) {
  1748. tape34xx_error_recovery_do_retry(ti);
  1749. return;
  1750.     }
  1751.     if (sense[0]&SENSE_DATA_CHECK) {
  1752. // hardware failure, damaged tape or improper operating conditions
  1753. switch (sense[3]) {
  1754. case 0x23:
  1755.     // a read data check occurred
  1756.     if ((sense[2]&SENSE_TAPE_SYNC_MODE) ||
  1757. (inhibit_cu_recovery)) {
  1758. // data check is not permanent, may be recovered. 
  1759. // We always use async-mode with cu-recovery, so this should *never* happen.
  1760. tape34xx_error_recovery_HWBUG(ti,2);
  1761. return;
  1762.     } else {
  1763. // data check is permanent, CU recovery has failed
  1764. PRINT_WARN("Permanent read error, recovery failed!n");
  1765. tape34xx_error_recovery_has_failed(ti,EIO);
  1766. return;
  1767.     }
  1768. case 0x25:
  1769.     // a write data check occurred
  1770.     if ((sense[2]&SENSE_TAPE_SYNC_MODE) ||
  1771. (inhibit_cu_recovery)) {
  1772. // data check is not permanent, may be recovered.
  1773. // We always use async-mode with cu-recovery, so this should *never* happen.
  1774. tape34xx_error_recovery_HWBUG(ti,3);
  1775. return;
  1776.     } else {
  1777. // data check is permanent, cu-recovery has failed
  1778. PRINT_WARN("Permanent write error, recovery failed!n");
  1779. tape34xx_error_recovery_has_failed(ti,EIO);
  1780. return;
  1781.     }
  1782. case 0x26:
  1783.     // Data Check (read opposite) occurred. We'll recover this.
  1784.     tape34xx_error_recovery_read_opposite(ti);
  1785.     return;
  1786. case 0x28:
  1787.     // The ID-Mark at the beginning of the tape could not be written. This is fatal, we'll report and exit.
  1788.     PRINT_WARN("ID-Mark could not be written. Check your hardware!n");
  1789.     tape34xx_error_recovery_has_failed(ti,EIO);
  1790.     return;
  1791. case 0x31:
  1792.     // Tape void. Tried to read beyond end of device. We'll report and exit.
  1793.     PRINT_WARN("Try to read beyond end of recorded area!n");
  1794.     tape34xx_error_recovery_has_failed(ti,ENOSPC);
  1795.     return;
  1796. case 0x41:
  1797.     // Record sequence error. cu detected incorrect block-id sequence on tape. We'll report and exit.
  1798.     PRINT_WARN("Illegal block-id sequence found!n");
  1799.     tape34xx_error_recovery_has_failed(ti,EIO);
  1800.     return;
  1801.     default:
  1802.     // well, all data checks for 3480 should result in one of the above erpa-codes. if not -> bug
  1803.     // On 3490, other data-check conditions do exist.
  1804. if (cu_type==0x3480) {
  1805.     tape34xx_error_recovery_HWBUG(ti,4);
  1806.     return;
  1807. }
  1808. }
  1809.     }
  1810.     if (sense[0]&SENSE_OVERRUN) {
  1811. // A data overrun between cu and drive occurred. The channel speed is to slow! We'll report this and exit!
  1812. switch (sense[3]) {
  1813. case 0x40: // overrun error
  1814.     PRINT_WARN ("Data overrun error between control-unit and drive. Use a faster channel connection, if possible! n");
  1815.     tape34xx_error_recovery_has_failed(ti,EIO);
  1816.     return;
  1817. default:
  1818.     // Overrun bit is set, but erpa does not show overrun error. This is a bug.
  1819.     tape34xx_error_recovery_HWBUG(ti,5);
  1820.     return;
  1821. }
  1822.     }
  1823.     if (sense[1]&SENSE_RECORD_SEQUENCE_ERR) {
  1824. switch (sense[3]) {
  1825. case 0x41:
  1826.     // Record sequence error. cu detected incorrect block-id sequence on tape. We'll report and exit.
  1827.     PRINT_WARN("Illegal block-id sequence found!n");
  1828.     tape34xx_error_recovery_has_failed(ti,EIO);
  1829.     return;
  1830. default:
  1831.     // Record sequence error bit is set, but erpa does not show record sequence error. This is a bug.
  1832.     tape34xx_error_recovery_HWBUG(ti,6);
  1833.     return;
  1834. }
  1835.     }
  1836.     // Sensing erpa codes
  1837.     switch (sense[3]) {
  1838.     case 0x00:
  1839. // Everything is fine, but we got a unit check. Report and ignore!
  1840. PRINT_WARN ("Non-error sense was found. Unit-check will be ignored, expect errors...n");
  1841. return;
  1842.     case 0x21:
  1843. // Data streaming not operational. Cu switches to interlock mode, we reissue the command.
  1844. PRINT_WARN ("Data streaming not operational. Switching to interlock-mode! n");
  1845. tape34xx_error_recovery_do_retry(ti);
  1846. return;
  1847.     case 0x22:
  1848. // Path equipment check. Might be drive adapter error, buffer error on the lower interface, internal path not useable, or error during cartridge load.
  1849. // All of the above are not recoverable
  1850. PRINT_WARN ("A path equipment check occurred. One of the following conditions occurred:n");
  1851. PRINT_WARN ("drive adapter error,buffer error on the lower interface, internal path not useable, error during cartridge load.n");
  1852. tape34xx_error_recovery_has_failed(ti,EIO);
  1853. return;
  1854.     case 0x23:
  1855. // Read data check. Should have been be covered earlier -> Bug!
  1856. tape34xx_error_recovery_HWBUG(ti,7);
  1857. return;
  1858.     case 0x24:
  1859. // Load display check. Load display was command was issued, but the drive is displaying a drive check message. Can be threated as "device end".
  1860. tape34xx_error_recovery_succeded(ti);
  1861. return;
  1862.     case 0x25:
  1863. // Write data check. Should have been covered earlier -> Bug!
  1864. tape34xx_error_recovery_HWBUG(ti,8);
  1865. return;
  1866.     case 0x26:
  1867. // Data check (read opposite). Should have been covered earlier -> Bug!
  1868. tape34xx_error_recovery_HWBUG(ti,9);
  1869. return;
  1870.     case 0x27:
  1871. // Command reject. May indicate illegal channel program or buffer over/underrun. 
  1872. // Since all channel programms are issued by this driver and ought be correct,
  1873. // we assume a over/underrun situaltion and retry the channel program.
  1874. tape34xx_error_recovery_do_retry(ti);
  1875. return;
  1876.     case 0x28:
  1877. // Write id mark check. Should have beed covered earlier -> bug!
  1878. tape34xx_error_recovery_HWBUG(ti,10);
  1879. return;
  1880.     case 0x29:
  1881. // Function incompatible. Either idrc is on but hardware not capable doing idrc 
  1882. // or a perform subsystem func is issued and the cu is not online. Anyway, this 
  1883. // cannot be recovered and is an I/O error.
  1884. PRINT_WARN ("Function incompatible. Try to switch off idrc! n");
  1885. tape34xx_error_recovery_has_failed(ti,EIO);
  1886. return;
  1887.     case 0x2a:
  1888. // Unsolicited environmental data. An internal counter overflows, we can ignore
  1889. // this and reissue the cmd.
  1890. tape34xx_error_recovery_do_retry(ti);
  1891. return;
  1892.     case 0x2b:
  1893. // Environmental data present. Indicates either unload completed ok or read buffered 
  1894. // log command completed ok. 
  1895. if (tapestate_get(ti)==TS_RUN_INIT) {
  1896.     // Rewind unload completed ok.
  1897.     tape34xx_error_recovery_succeded(ti);
  1898.     return;
  1899. }
  1900. // Since we do not issue read buffered log commands, this should never occur -> bug.
  1901. tape34xx_error_recovery_HWBUG(ti,11);
  1902. return;
  1903.     case 0x2c:
  1904. // Permanent equipment check. cu has tried recovery, but did not succeed. This is an
  1905. // I/O error.
  1906. tape34xx_error_recovery_has_failed(ti,EIO);
  1907. return;
  1908.     case 0x2d:
  1909. // Data security erase failure.
  1910. if (tapestate_get(ti)==TS_DSE_INIT) {
  1911.     // report an I/O error
  1912.     tape34xx_error_recovery_has_failed(ti,EIO);
  1913.     return;
  1914. }
  1915. // Data security erase failure, but no such command issued. This is a bug.
  1916. tape34xx_error_recovery_HWBUG(ti,12);
  1917. return;
  1918.     case 0x2e:
  1919. // Not capable. This indicates either that the drive fails reading the format id mark
  1920. // or that that format specified is not supported by the drive. We write a message and
  1921. // return an I/O error.
  1922. PRINT_WARN("Drive not capable processing the tape format!");
  1923. tape34xx_error_recovery_has_failed(ti,EMEDIUMTYPE);
  1924. return;
  1925.     case 0x2f:
  1926. // This erpa is reserved. This is a bug.
  1927. tape34xx_error_recovery_HWBUG(ti,13);
  1928. return;
  1929.     case 0x30:
  1930. // The medium is write protected, while trying to write on it. We'll report this.
  1931. PRINT_WARN("Medium is write protected!n");
  1932. tape34xx_error_recovery_has_failed(ti,EACCES);
  1933. return;
  1934.     case 0x31:
  1935. // Tape void. Should have beed covered ealier -> bug
  1936. tape34xx_error_recovery_HWBUG(ti,14);
  1937. return;
  1938.     case 0x32:
  1939. // Tension loss. We cannot recover this, it's an I/O error.
  1940. PRINT_WARN("The drive lost tape tension.n");
  1941. tape34xx_error_recovery_has_failed(ti,EIO);
  1942. return;
  1943.     case 0x33:
  1944. // Load Failure. The catridge was not inserted correctly or the tape is not threaded
  1945. // correctly. We cannot recover this, the user has to reload the catridge.
  1946. PRINT_WARN("Cartridge load failure. Reload the cartridge and try again.n");
  1947. tape34xx_error_recovery_has_failed(ti,EIO);
  1948. return;
  1949.     case 0x34:
  1950. // Unload failure. The drive cannot maintain tape tension and control tape movement 
  1951. // during an unload operation. 
  1952. PRINT_WARN("Failure during cartridge unload. Please try manually.n");
  1953. if (tapestate_get(ti)!=TS_RUN_INIT) {
  1954.     tape34xx_error_recovery_HWBUG(ti,15);
  1955.     return;
  1956. }
  1957. tape34xx_error_recovery_has_failed(ti,EIO);
  1958. return;
  1959.     case 0x35:
  1960. // Drive equipment check. One of the following:
  1961. // - cu cannot recover from a drive detected error
  1962. // - a check code message is displayed on drive message/load displays
  1963. // - the cartridge loader does not respond correctly
  1964. // - a failure occurs during an index, load, or unload cycle
  1965. PRINT_WARN("Equipment check! Please check the drive and the cartridge loader.n");
  1966. tape34xx_error_recovery_has_failed(ti,EIO);
  1967. return;
  1968.     case 0x36:
  1969. switch (cu_type) {
  1970. case 0x3480:
  1971.     // This erpa is reserved for 3480 -> BUG
  1972.     tape34xx_error_recovery_HWBUG(ti,16);
  1973.     return;
  1974. case 0x3490:
  1975.     // End of data. This is a permanent I/O error, which cannot be recovered.
  1976.     // A read-type command has reached the end-of-data mark.
  1977.     tape34xx_error_recovery_has_failed(ti,EIO);
  1978.     return;
  1979. }
  1980.     case 0x37:
  1981. // Tape length error. The tape is shorter than reported in the beginning-of-tape data.
  1982. PRINT_WARN("Tape length error.n");
  1983. tape34xx_error_recovery_has_failed(ti,EIO);
  1984. return;
  1985.     case 0x38:
  1986. // Physical end of tape. A read/write operation reached the physical end of tape.
  1987. if (tapestate_get(ti)==TS_WRI_INIT ||
  1988.     tapestate_get(ti)==TS_DSE_INIT ||
  1989.     tapestate_get(ti)==TS_EGA_INIT ||
  1990.     tapestate_get(ti)==TS_WTM_INIT){
  1991.       tape34xx_error_recovery_has_failed(ti,ENOSPC);
  1992. } else {
  1993.     tape34xx_error_recovery_has_failed(ti,EIO);
  1994. }
  1995. return;
  1996.     case 0x39:
  1997. // Backward at BOT. The drive is at BOT and is requestet to move backward.
  1998. tape34xx_error_recovery_has_failed(ti,EIO);
  1999. return;
  2000.     case 0x3a:
  2001. // Drive switched not ready, but the command needs the drive to be ready.
  2002. PRINT_WARN("Drive not ready. Turn the ready/not ready switch to ready position and try again.n");
  2003. tape34xx_error_recovery_has_failed(ti,EIO);
  2004. return;
  2005.     case 0x3b:
  2006. // Manual rewind or unload. This causes an I/O error.
  2007. PRINT_WARN("Medium was rewound or unloaded manually. Expect errors! Please do only use the mtoffl and mtrew ioctl to unload tapes or rewind tapes.n");
  2008. tape34xx_error_recovery_has_failed(ti,EIO);
  2009. return;
  2010.     case 0x3c:
  2011.     case 0x3d:
  2012.     case 0x3e:
  2013.     case 0x3f:
  2014. // These erpas are reserved -> BUG
  2015. tape34xx_error_recovery_HWBUG(ti,17);
  2016. return;
  2017.     case 0x40:
  2018. // Overrun error. This should have been covered earlier -> bug.
  2019. tape34xx_error_recovery_HWBUG(ti,18);
  2020. return;
  2021.     case 0x41:
  2022. // Record sequence error. This should have been covered earlier -> bug.
  2023. tape34xx_error_recovery_HWBUG(ti,19);
  2024. return;
  2025.     case 0x42:
  2026. // Degraded mode. A condition that can cause degraded performace is detected.
  2027. PRINT_WARN("Subsystem is running in degraded mode. This may compromise your performace.n");
  2028. tape34xx_error_recovery_do_retry(ti);
  2029. return;
  2030.     case 0x43:
  2031. // Drive not ready. Probably swith the ready/not ready switch to ready?
  2032. PRINT_WARN("The drive is not ready. Maybe no medium in?n");
  2033. tape34xx_error_recovery_has_failed(ti,ENOMEDIUM);
  2034. return;
  2035.     case 0x44:
  2036. // Locate Block unsuccessfull. We'll report this.
  2037. if ((tapestate_get(ti)!=TS_BLOCK_INIT) &&
  2038.     (tapestate_get(ti)!=TS_LBL_INIT)) {
  2039.     tape34xx_error_recovery_HWBUG(ti,20); // No locate block was issued...
  2040.     return;
  2041. }
  2042. tape34xx_error_recovery_has_failed(ti,EIO);
  2043. return;
  2044.     case 0x45:
  2045. // The drive is assigned elsewhere [to a different channel path/computer].
  2046. PRINT_WARN("The drive is assigned elsewhere.n");
  2047. tape34xx_error_recovery_has_failed(ti,EIO);
  2048. return;
  2049.     case 0x46:
  2050. // Drive not online. Drive may be switched offline, the power supply may be switched off 
  2051. // or the drive address may not be set correctly.
  2052. PRINT_WARN("The drive is not online.");
  2053. tape34xx_error_recovery_has_failed(ti,EIO);
  2054. return;
  2055.     case 0x47:
  2056. // Volume fenced. cu reports volume integrity is lost! 
  2057. PRINT_WARN("Volume fenced. The volume integrity is lost! n");
  2058. tape34xx_error_recovery_has_failed(ti,EIO);
  2059. return;
  2060.     case 0x48:
  2061. // Log sense data and retry request. We'll do so...
  2062. tape34xx_error_recovery_do_retry(ti);
  2063. return;
  2064.     case 0x49:
  2065. // Bus out check. A parity check error on the bus was found. PRINT_WARN("Bus out check. A data transfer over the bus was corrupted.n");
  2066. tape34xx_error_recovery_has_failed(ti,EIO);
  2067. return;
  2068.     case 0x4a:
  2069. // Control unit erp failed. We'll report this.
  2070. PRINT_WARN("The control unit failed recovering an I/O error.n");
  2071. tape34xx_error_recovery_has_failed(ti,EIO);
  2072. return;
  2073.     case 0x4b:
  2074. // Cu and drive incompatible. The drive requests micro-program patches, which are not available on the cu.
  2075. PRINT_WARN("The drive needs microprogram patches from the control unit, which are not available.n");
  2076. tape34xx_error_recovery_has_failed(ti,EIO);
  2077. return;
  2078.     case 0x4c:
  2079. // Recovered Check-One failure. Cu develops a hardware error, but is able to recover. We'll reissue the command.
  2080. tape34xx_error_recovery_do_retry(ti);
  2081. return;
  2082.     case 0x4d:
  2083. switch (cu_type) {
  2084. case 0x3480:
  2085.     // This erpa is reserved for 3480 -> bug
  2086.            tape34xx_error_recovery_HWBUG(ti,21);
  2087.     return;
  2088. case 0x3490:
  2089.     // Resetting event recieved. Since the driver does not support resetting event recovery
  2090.     // (which has to be handled by the I/O Layer), we'll report and retry our command.
  2091.     tape34xx_error_recovery_do_retry(ti);
  2092.     return;
  2093. }
  2094.     case 0x4e:
  2095. switch (cu_type) {
  2096. case 0x3480:
  2097.     // This erpa is reserved for 3480 -> bug.
  2098.     tape34xx_error_recovery_HWBUG(ti,22);
  2099.     return;
  2100. case 0x3490:
  2101.     // Maximum block size exeeded. This indicates, that the block to be written is larger
  2102.     // than allowed for buffered mode. We'll report this...
  2103.     PRINT_WARN("Maximum block size for buffered mode exceeded.n");
  2104.     tape34xx_error_recovery_has_failed(ti,ENOBUFS);
  2105.     return;
  2106. }
  2107.     case 0x4f:
  2108. // These erpas are reserved -> bug
  2109. tape34xx_error_recovery_HWBUG(ti,23);
  2110. return;
  2111.     case 0x50:
  2112. // Read buffered log (Overflow). Cu is running in extended beffered log mode, and a counter overflows.
  2113. // This should never happen, since we're never running in extended buffered log mode -> bug.
  2114. tape34xx_error_recovery_do_retry(ti);
  2115. return;
  2116.     case 0x51:
  2117. // Read buffered log (EOV). EOF processing occurs while the cu is in extended buffered log mode.
  2118. // This should never happen, since we're never running in extended buffered log mode -> bug.
  2119. tape34xx_error_recovery_do_retry(ti);
  2120. return;
  2121.     case 0x52:
  2122. // End of Volume complete. Rewind unload completed ok. We'll report to the user...
  2123. if (tapestate_get(ti)!=TS_RUN_INIT) {
  2124.     tape34xx_error_recovery_HWBUG(ti,24);
  2125.     return;
  2126. }
  2127. tape34xx_error_recovery_succeded(ti);
  2128. return;
  2129.     case 0x53:
  2130. // Global command intercept. We'll have to reissue our command.
  2131. tape34xx_error_recovery_do_retry(ti);
  2132. return;
  2133.     case 0x54:
  2134. // Channel interface recovery (temporary). This can be recovered by reissuing the command.
  2135. tape34xx_error_recovery_do_retry(ti);
  2136. return;
  2137.     case 0x55:
  2138. // Channel interface recovery (permanent). This cannot be recovered, we'll inform the user.
  2139. PRINT_WARN("A permanent channel interface error occurred.n");
  2140. tape34xx_error_recovery_has_failed(ti,EIO);
  2141. return;
  2142.     case 0x56:
  2143. // Channel protocol error. This cannot be recovered.
  2144. PRINT_WARN("A channel protocol error occurred.n");
  2145. tape34xx_error_recovery_has_failed(ti,EIO);
  2146. return;
  2147.     case 0x57:
  2148. switch (cu_type) {
  2149. case 0x3480:
  2150.     // Attention intercept. We have to reissue the command.
  2151.     PRINT_WARN("An attention intercept occurred, which will be recovered.n");
  2152.     tape34xx_error_recovery_do_retry(ti);
  2153.     return;
  2154. case 0x3490:
  2155.     // Global status intercept. We have to reissue the command.
  2156.     PRINT_WARN("An global status intercept was recieved, which will be recovered.n");
  2157.     tape34xx_error_recovery_do_retry(ti);
  2158.     return;
  2159. }
  2160.     case 0x58:
  2161.     case 0x59:
  2162. // These erpas are reserved -> bug.
  2163. tape34xx_error_recovery_HWBUG(ti,25);
  2164. return;
  2165.     case 0x5a:
  2166. // Tape length incompatible. The tape inserted is too long, 
  2167. // which could cause damage to the tape or the drive.
  2168. PRINT_WARN("Tape length incompatible [should be IBM Cartridge System Tape]. May cause damage to drive or tape.n");
  2169. tape34xx_error_recovery_has_failed(ti,EIO);
  2170. return;
  2171.     case 0x5b:
  2172. // Format 3480 XF incompatible
  2173. if (sense[1]&SENSE_BEGINNING_OF_TAPE) {
  2174.     // Everything is fine. The tape will be overwritten in a different format.
  2175.     tape34xx_error_recovery_do_retry(ti);
  2176.     return;
  2177. }
  2178. PRINT_WARN("Tape format is incompatible to the drive, which writes 3480-2 XF.n");
  2179. tape34xx_error_recovery_has_failed(ti,EIO);
  2180. return;
  2181.     case 0x5c:
  2182. // Format 3480-2 XF incompatible
  2183. PRINT_WARN("Tape format is incompatible to the drive. The drive cannot access 3480-2 XF volumes.n");
  2184. tape34xx_error_recovery_has_failed(ti,EIO);
  2185. return;
  2186.     case 0x5d:
  2187. // Tape length violation. 
  2188. PRINT_WARN("Tape length violation [should be IBM Enhanced Capacity Cartridge System Tape]. May cause damage to drive or tape.n");
  2189. tape34xx_error_recovery_has_failed(ti,EMEDIUMTYPE);
  2190. return;
  2191.     case 0x5e:
  2192. // Compaction algorithm incompatible.
  2193. PRINT_WARN("The volume is recorded using an incompatible compaction algorith, which is not supported by the control unit.n");
  2194. tape34xx_error_recovery_has_failed(ti,EMEDIUMTYPE);
  2195. return;
  2196.     default:
  2197. // Reserved erpas -> bug
  2198. tape34xx_error_recovery_HWBUG(ti,26);
  2199. return;
  2200.     }
  2201. }
  2202. void tape34xx_error_recovery_has_failed (tape_info_t* ti,int error_id) {
  2203. #ifdef TAPE_DEBUG
  2204.     debug_text_event (tape_debug_area,3,"xerp fail");
  2205.     debug_text_event (tape_debug_area,3,(((tapestate_get (ti) < TS_SIZE) && 
  2206.       (tapestate_get (ti) >= 0)) ?
  2207. state_verbose[tapestate_get (ti)] : "UNKNOWN"));
  2208. #endif
  2209.     if ((tapestate_get(ti)!=TS_UNUSED) && (tapestate_get(ti)!=TS_IDLE)) {
  2210. tape_dump_sense(&ti->devstat);
  2211. ti->rc = -error_id;
  2212. ti->wanna_wakeup=1;
  2213. switch (tapestate_get(ti)) {
  2214. case TS_REW_RELEASE_INIT:
  2215. case TS_RFO_INIT:
  2216. case TS_RBA_INIT:
  2217.     tapestate_set(ti,TS_FAILED);
  2218.     wake_up (&ti->wq);
  2219.     break;
  2220. case TS_BLOCK_INIT:
  2221.     tapestate_set(ti,TS_FAILED);
  2222.     schedule_tapeblock_exec_IO(ti);
  2223.     break;
  2224. default:
  2225.     tapestate_set(ti,TS_FAILED);
  2226.     wake_up_interruptible (&ti->wq);
  2227. }
  2228.     } else {
  2229. PRINT_WARN("Recieved an unsolicited IRQ.n");
  2230. tape_dump_sense(&ti->devstat);
  2231.     }
  2232. }    
  2233. void tape34xx_error_recovery_succeded(tape_info_t* ti) {
  2234. #ifdef TAPE_DEBUG
  2235.     debug_text_event (tape_debug_area,3,"xerp done");
  2236.     debug_text_event (tape_debug_area,3,(((tapestate_get (ti) < TS_SIZE) && 
  2237.       (tapestate_get (ti) >= 0)) ?
  2238. state_verbose[tapestate_get (ti)] : "UNKNOWN"));
  2239. #endif
  2240.     if ((tapestate_get(ti)!=TS_UNUSED) && (tapestate_get(ti)!=TS_DONE)) {
  2241. tapestate_event (ti, TE_DONE);
  2242.     } else {
  2243. PRINT_WARN("Recieved an unsolicited IRQ.n");
  2244. tape_dump_sense(&ti->devstat);
  2245.     }
  2246. }
  2247. void tape34xx_error_recovery_do_retry(tape_info_t* ti) {
  2248. #ifdef TAPE_DEBUG
  2249.     debug_text_event (tape_debug_area,3,"xerp retr");
  2250.     debug_text_event (tape_debug_area,3,(((tapestate_get (ti) < TS_SIZE) && 
  2251.   (tapestate_get (ti) >= 0)) ?
  2252.  state_verbose[tapestate_get (ti)] : "UNKNOWN"));
  2253. #endif
  2254.     if ((tapestate_get(ti)!=TS_UNUSED) && (tapestate_get(ti)!=TS_IDLE)) {
  2255. tape_dump_sense(&ti->devstat);
  2256. while (do_IO (ti->devinfo.irq, ti->cqr->cpaddr, (unsigned long) ti->cqr, 0x00, ti->cqr->options));
  2257.     } else {
  2258. PRINT_WARN("Recieved an unsolicited IRQ.n");
  2259. tape_dump_sense(&ti->devstat);
  2260.     }
  2261. }
  2262.     
  2263. void 
  2264. tape34xx_error_recovery_read_opposite (tape_info_t* ti) {
  2265.     switch (tapestate_get(ti)) {
  2266.     case TS_RFO_INIT:
  2267. // We did read forward, but the data could not be read *correctly*.
  2268. // We will read backward and then skip forward again.
  2269. ti->cqr=tape34xx_read_opposite(ti,0);
  2270. if (ti->cqr==NULL)
  2271.     tape34xx_error_recovery_has_failed(ti,EIO);
  2272. else
  2273.     tape34xx_error_recovery_do_retry(ti);
  2274. break;
  2275.     case TS_RBA_INIT:
  2276. // We tried to read forward and backward, but hat no success -> failed.
  2277. tape34xx_error_recovery_has_failed(ti,EIO);
  2278. break;
  2279.     case TS_BLOCK_INIT:
  2280. tape34xx_error_recovery_do_retry(ti);
  2281. break;
  2282.     default:
  2283. PRINT_WARN("read_opposite_recovery_called_with_state:%sn",
  2284.    (((tapestate_get (ti) < TS_SIZE) && 
  2285.      (tapestate_get (ti) >= 0)) ?
  2286.     state_verbose[tapestate_get (ti)] : "UNKNOWN"));
  2287.     }
  2288. }
  2289. void 
  2290. tape34xx_error_recovery_HWBUG (tape_info_t* ti,int condno) {
  2291.     devstat_t* stat=&ti->devstat;
  2292.     PRINT_WARN("An unexpected condition #%d was caught in tape error recovery.n",condno);
  2293.     PRINT_WARN("Please report this incident.n");
  2294.     PRINT_WARN("State of the tape:%sn",
  2295.        (((tapestate_get (ti) < TS_SIZE) && 
  2296.  (tapestate_get (ti) >= 0)) ?
  2297. state_verbose[tapestate_get (ti)] : "UNKNOWN"));
  2298.     PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
  2299. " %02X%02X%02X%02X %02X%02X%02X%02X n",
  2300. stat->ii.sense.data[0], stat->ii.sense.data[1],
  2301. stat->ii.sense.data[2], stat->ii.sense.data[3],
  2302. stat->ii.sense.data[4], stat->ii.sense.data[5],
  2303. stat->ii.sense.data[6], stat->ii.sense.data[7],
  2304. stat->ii.sense.data[8], stat->ii.sense.data[9],
  2305. stat->ii.sense.data[10], stat->ii.sense.data[11],
  2306. stat->ii.sense.data[12], stat->ii.sense.data[13],
  2307. stat->ii.sense.data[14], stat->ii.sense.data[15]);
  2308.     PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
  2309. " %02X%02X%02X%02X %02X%02X%02X%02X n",
  2310. stat->ii.sense.data[16], stat->ii.sense.data[17],
  2311. stat->ii.sense.data[18], stat->ii.sense.data[19],
  2312. stat->ii.sense.data[20], stat->ii.sense.data[21],
  2313. stat->ii.sense.data[22], stat->ii.sense.data[23],
  2314. stat->ii.sense.data[24], stat->ii.sense.data[25],
  2315. stat->ii.sense.data[26], stat->ii.sense.data[27],
  2316. stat->ii.sense.data[28], stat->ii.sense.data[29],
  2317. stat->ii.sense.data[30], stat->ii.sense.data[31]);
  2318.     tape34xx_error_recovery_has_failed(ti,EIO);
  2319. }