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