Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.13 992 lines 27 kB view raw
1/* 2 * Copyright (C) 1993-1996 Bas Laarhoven, 3 * (C) 1996 Kai Harrekilde-Petersen, 4 * (C) 1997 Claus-Justus Heine. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; see the file COPYING. If not, write to 18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 20 * 21 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-io.c,v $ 22 * $Revision: 1.4 $ 23 * $Date: 1997/11/11 14:02:36 $ 24 * 25 * This file contains the general control functions for the 26 * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. 27 */ 28 29#include <linux/errno.h> 30#include <linux/sched.h> 31#include <linux/mm.h> 32#include <asm/system.h> 33#include <linux/ioctl.h> 34#include <linux/mtio.h> 35#include <linux/delay.h> 36 37#include <linux/ftape.h> 38#include <linux/qic117.h> 39#include "../lowlevel/ftape-tracing.h" 40#include "../lowlevel/fdc-io.h" 41#include "../lowlevel/ftape-io.h" 42#include "../lowlevel/ftape-ctl.h" 43#include "../lowlevel/ftape-rw.h" 44#include "../lowlevel/ftape-write.h" 45#include "../lowlevel/ftape-read.h" 46#include "../lowlevel/ftape-init.h" 47#include "../lowlevel/ftape-calibr.h" 48 49/* Global vars. 50 */ 51/* NOTE: sectors start numbering at 1, all others at 0 ! */ 52ft_timeout_table ftape_timeout; 53unsigned int ftape_tape_len; 54volatile qic117_cmd_t ftape_current_command; 55const struct qic117_command_table qic117_cmds[] = QIC117_COMMANDS; 56int ftape_might_be_off_track; 57 58/* Local vars. 59 */ 60static int diagnostic_mode; 61static unsigned int ftape_udelay_count; 62static unsigned int ftape_udelay_time; 63 64void ftape_udelay(unsigned int usecs) 65{ 66 volatile int count = (ftape_udelay_count * usecs + 67 ftape_udelay_count - 1) / ftape_udelay_time; 68 volatile int i; 69 70 while (count-- > 0) { 71 for (i = 0; i < 20; ++i); 72 } 73} 74 75void ftape_udelay_calibrate(void) 76{ 77 ftape_calibrate("ftape_udelay", 78 ftape_udelay, &ftape_udelay_count, &ftape_udelay_time); 79} 80 81/* Delay (msec) routine. 82 */ 83void ftape_sleep(unsigned int time) 84{ 85 TRACE_FUN(ft_t_any); 86 87 time *= 1000; /* msecs -> usecs */ 88 if (time < FT_USPT) { 89 /* Time too small for scheduler, do a busy wait ! */ 90 ftape_udelay(time); 91 } else { 92 long timeout; 93 unsigned long flags; 94 unsigned int ticks = (time + FT_USPT - 1) / FT_USPT; 95 96 TRACE(ft_t_any, "%d msec, %d ticks", time/1000, ticks); 97 timeout = ticks; 98 save_flags(flags); 99 sti(); 100 msleep_interruptible(jiffies_to_msecs(timeout)); 101 /* Mmm. Isn't current->blocked == 0xffffffff ? 102 */ 103 if (signal_pending(current)) { 104 TRACE(ft_t_err, "awoken by non-blocked signal :-("); 105 } 106 restore_flags(flags); 107 } 108 TRACE_EXIT; 109} 110 111/* send a command or parameter to the drive 112 * Generates # of step pulses. 113 */ 114static inline int ft_send_to_drive(int arg) 115{ 116 /* Always wait for a command_timeout period to separate 117 * individuals commands and/or parameters. 118 */ 119 ftape_sleep(3 * FT_MILLISECOND); 120 /* Keep cylinder nr within range, step towards home if possible. 121 */ 122 if (ftape_current_cylinder >= arg) { 123 return fdc_seek(ftape_current_cylinder - arg); 124 } else { 125 return fdc_seek(ftape_current_cylinder + arg); 126 } 127} 128 129/* forward */ int ftape_report_raw_drive_status(int *status); 130 131static int ft_check_cmd_restrictions(qic117_cmd_t command) 132{ 133 int status = -1; 134 TRACE_FUN(ft_t_any); 135 136 TRACE(ft_t_flow, "%s", qic117_cmds[command].name); 137 /* A new motion command during an uninterruptible (motion) 138 * command requires a ready status before the new command can 139 * be issued. Otherwise a new motion command needs to be 140 * checked against required status. 141 */ 142 if (qic117_cmds[command].cmd_type == motion && 143 qic117_cmds[ftape_current_command].non_intr) { 144 ftape_report_raw_drive_status(&status); 145 if ((status & QIC_STATUS_READY) == 0) { 146 TRACE(ft_t_noise, 147 "motion cmd (%d) during non-intr cmd (%d)", 148 command, ftape_current_command); 149 TRACE(ft_t_noise, "waiting until drive gets ready"); 150 ftape_ready_wait(ftape_timeout.seek, 151 &status); 152 } 153 } 154 if (qic117_cmds[command].mask != 0) { 155 __u8 difference; 156 /* Some commands do require a certain status: 157 */ 158 if (status == -1) { /* not yet set */ 159 ftape_report_raw_drive_status(&status); 160 } 161 difference = ((status ^ qic117_cmds[command].state) & 162 qic117_cmds[command].mask); 163 /* Wait until the drive gets 164 * ready. This may last forever if 165 * the drive never gets ready... 166 */ 167 while ((difference & QIC_STATUS_READY) != 0) { 168 TRACE(ft_t_noise, "command %d issued while not ready", 169 command); 170 TRACE(ft_t_noise, "waiting until drive gets ready"); 171 if (ftape_ready_wait(ftape_timeout.seek, 172 &status) == -EINTR) { 173 /* Bail out on signal ! 174 */ 175 TRACE_ABORT(-EINTR, ft_t_warn, 176 "interrupted by non-blockable signal"); 177 } 178 difference = ((status ^ qic117_cmds[command].state) & 179 qic117_cmds[command].mask); 180 } 181 while ((difference & QIC_STATUS_ERROR) != 0) { 182 int err; 183 qic117_cmd_t cmd; 184 185 TRACE(ft_t_noise, 186 "command %d issued while error pending", 187 command); 188 TRACE(ft_t_noise, "clearing error status"); 189 ftape_report_error(&err, &cmd, 1); 190 ftape_report_raw_drive_status(&status); 191 difference = ((status ^ qic117_cmds[command].state) & 192 qic117_cmds[command].mask); 193 if ((difference & QIC_STATUS_ERROR) != 0) { 194 /* Bail out on fatal signal ! 195 */ 196 FT_SIGNAL_EXIT(_NEVER_BLOCK); 197 } 198 } 199 if (difference) { 200 /* Any remaining difference can't be solved 201 * here. 202 */ 203 if (difference & (QIC_STATUS_CARTRIDGE_PRESENT | 204 QIC_STATUS_NEW_CARTRIDGE | 205 QIC_STATUS_REFERENCED)) { 206 TRACE(ft_t_warn, 207 "Fatal: tape removed or reinserted !"); 208 ft_failure = 1; 209 } else { 210 TRACE(ft_t_err, "wrong state: 0x%02x should be: 0x%02x", 211 status & qic117_cmds[command].mask, 212 qic117_cmds[command].state); 213 } 214 TRACE_EXIT -EIO; 215 } 216 if (~status & QIC_STATUS_READY & qic117_cmds[command].mask) { 217 TRACE_ABORT(-EBUSY, ft_t_err, "Bad: still busy!"); 218 } 219 } 220 TRACE_EXIT 0; 221} 222 223/* Issue a tape command: 224 */ 225int ftape_command(qic117_cmd_t command) 226{ 227 int result = 0; 228 static int level; 229 TRACE_FUN(ft_t_any); 230 231 if ((unsigned int)command > NR_ITEMS(qic117_cmds)) { 232 /* This is a bug we'll want to know about too. 233 */ 234 TRACE_ABORT(-EIO, ft_t_bug, "bug - bad command: %d", command); 235 } 236 if (++level > 5) { /* This is a bug we'll want to know about. */ 237 --level; 238 TRACE_ABORT(-EIO, ft_t_bug, "bug - recursion for command: %d", 239 command); 240 } 241 /* disable logging and restriction check for some commands, 242 * check all other commands that have a prescribed starting 243 * status. 244 */ 245 if (diagnostic_mode) { 246 TRACE(ft_t_flow, "diagnostic command %d", command); 247 } else if (command == QIC_REPORT_DRIVE_STATUS || 248 command == QIC_REPORT_NEXT_BIT) { 249 TRACE(ft_t_any, "%s", qic117_cmds[command].name); 250 } else { 251 TRACE_CATCH(ft_check_cmd_restrictions(command), --level); 252 } 253 /* Now all conditions are met or result was < 0. 254 */ 255 result = ft_send_to_drive((unsigned int)command); 256 if (qic117_cmds[command].cmd_type == motion && 257 command != QIC_LOGICAL_FORWARD && command != QIC_STOP_TAPE) { 258 ft_location.known = 0; 259 } 260 ftape_current_command = command; 261 --level; 262 TRACE_EXIT result; 263} 264 265/* Send a tape command parameter: 266 * Generates command # of step pulses. 267 * Skips tape-status call ! 268 */ 269int ftape_parameter(unsigned int parameter) 270{ 271 TRACE_FUN(ft_t_any); 272 273 TRACE(ft_t_flow, "called with parameter = %d", parameter); 274 TRACE_EXIT ft_send_to_drive(parameter + 2); 275} 276 277/* Wait for the drive to get ready. 278 * timeout time in milli-seconds 279 * Returned status is valid if result != -EIO 280 * 281 * Should we allow to be killed by SIGINT? (^C) 282 * Would be nice at least for large timeouts. 283 */ 284int ftape_ready_wait(unsigned int timeout, int *status) 285{ 286 unsigned long t0; 287 unsigned int poll_delay; 288 int signal_retries; 289 TRACE_FUN(ft_t_any); 290 291 /* the following ** REALLY ** reduces the system load when 292 * e.g. one simply rewinds or retensions. The tape is slow 293 * anyway. It is really not necessary to detect error 294 * conditions with 1/10 seconds granularity 295 * 296 * On my AMD 133MHZ 486: 100 ms: 23% system load 297 * 1 sec: 5% 298 * 5 sec: 0.6%, yeah 299 */ 300 if (timeout <= FT_SECOND) { 301 poll_delay = 100 * FT_MILLISECOND; 302 signal_retries = 20; /* two seconds */ 303 } else if (timeout < 20 * FT_SECOND) { 304 TRACE(ft_t_flow, "setting poll delay to 1 second"); 305 poll_delay = FT_SECOND; 306 signal_retries = 2; /* two seconds */ 307 } else { 308 TRACE(ft_t_flow, "setting poll delay to 5 seconds"); 309 poll_delay = 5 * FT_SECOND; 310 signal_retries = 1; /* five seconds */ 311 } 312 for (;;) { 313 t0 = jiffies; 314 TRACE_CATCH(ftape_report_raw_drive_status(status),); 315 if (*status & QIC_STATUS_READY) { 316 TRACE_EXIT 0; 317 } 318 if (!signal_retries--) { 319 FT_SIGNAL_EXIT(_NEVER_BLOCK); 320 } 321 if ((int)timeout >= 0) { 322 /* this will fail when jiffies wraps around about 323 * once every year :-) 324 */ 325 timeout -= ((jiffies - t0) * FT_SECOND) / HZ; 326 if (timeout <= 0) { 327 TRACE_ABORT(-ETIME, ft_t_err, "timeout"); 328 } 329 ftape_sleep(poll_delay); 330 timeout -= poll_delay; 331 } else { 332 ftape_sleep(poll_delay); 333 } 334 } 335 TRACE_EXIT -ETIME; 336} 337 338/* Issue command and wait up to timeout milli seconds for drive ready 339 */ 340int ftape_command_wait(qic117_cmd_t command, unsigned int timeout, int *status) 341{ 342 int result; 343 344 /* Drive should be ready, issue command 345 */ 346 result = ftape_command(command); 347 if (result >= 0) { 348 result = ftape_ready_wait(timeout, status); 349 } 350 return result; 351} 352 353static int ftape_parameter_wait(unsigned int parm, unsigned int timeout, int *status) 354{ 355 int result; 356 357 /* Drive should be ready, issue command 358 */ 359 result = ftape_parameter(parm); 360 if (result >= 0) { 361 result = ftape_ready_wait(timeout, status); 362 } 363 return result; 364} 365 366/*-------------------------------------------------------------------------- 367 * Report operations 368 */ 369 370/* Query the drive about its status. The command is sent and 371 result_length bits of status are returned (2 extra bits are read 372 for start and stop). */ 373 374int ftape_report_operation(int *status, 375 qic117_cmd_t command, 376 int result_length) 377{ 378 int i, st3; 379 unsigned int t0; 380 unsigned int dt; 381 TRACE_FUN(ft_t_any); 382 383 TRACE_CATCH(ftape_command(command),); 384 t0 = ftape_timestamp(); 385 i = 0; 386 do { 387 ++i; 388 ftape_sleep(3 * FT_MILLISECOND); /* see remark below */ 389 TRACE_CATCH(fdc_sense_drive_status(&st3),); 390 dt = ftape_timediff(t0, ftape_timestamp()); 391 /* Ack should be asserted within Ttimout + Tack = 6 msec. 392 * Looks like some drives fail to do this so extend this 393 * period to 300 msec. 394 */ 395 } while (!(st3 & ST3_TRACK_0) && dt < 300000); 396 if (!(st3 & ST3_TRACK_0)) { 397 TRACE(ft_t_err, 398 "No acknowledge after %u msec. (%i iter)", dt / 1000, i); 399 TRACE_ABORT(-EIO, ft_t_err, "timeout on Acknowledge"); 400 } 401 /* dt may be larger than expected because of other tasks 402 * scheduled while we were sleeping. 403 */ 404 if (i > 1 && dt > 6000) { 405 TRACE(ft_t_err, "Acknowledge after %u msec. (%i iter)", 406 dt / 1000, i); 407 } 408 *status = 0; 409 for (i = 0; i < result_length + 1; i++) { 410 TRACE_CATCH(ftape_command(QIC_REPORT_NEXT_BIT),); 411 TRACE_CATCH(fdc_sense_drive_status(&st3),); 412 if (i < result_length) { 413 *status |= ((st3 & ST3_TRACK_0) ? 1 : 0) << i; 414 } else if ((st3 & ST3_TRACK_0) == 0) { 415 TRACE_ABORT(-EIO, ft_t_err, "missing status stop bit"); 416 } 417 } 418 /* this command will put track zero and index back into normal state */ 419 (void)ftape_command(QIC_REPORT_NEXT_BIT); 420 TRACE_EXIT 0; 421} 422 423/* Report the current drive status. */ 424 425int ftape_report_raw_drive_status(int *status) 426{ 427 int result; 428 int count = 0; 429 TRACE_FUN(ft_t_any); 430 431 do { 432 result = ftape_report_operation(status, 433 QIC_REPORT_DRIVE_STATUS, 8); 434 } while (result < 0 && ++count <= 3); 435 if (result < 0) { 436 TRACE_ABORT(-EIO, ft_t_err, 437 "report_operation failed after %d trials", count); 438 } 439 if ((*status & 0xff) == 0xff) { 440 TRACE_ABORT(-EIO, ft_t_err, 441 "impossible drive status 0xff"); 442 } 443 if (*status & QIC_STATUS_READY) { 444 ftape_current_command = QIC_NO_COMMAND; /* completed */ 445 } 446 ft_last_status.status.drive_status = (__u8)(*status & 0xff); 447 TRACE_EXIT 0; 448} 449 450int ftape_report_drive_status(int *status) 451{ 452 TRACE_FUN(ft_t_any); 453 454 TRACE_CATCH(ftape_report_raw_drive_status(status),); 455 if (*status & QIC_STATUS_NEW_CARTRIDGE || 456 !(*status & QIC_STATUS_CARTRIDGE_PRESENT)) { 457 ft_failure = 1; /* will inhibit further operations */ 458 TRACE_EXIT -EIO; 459 } 460 if (*status & QIC_STATUS_READY && *status & QIC_STATUS_ERROR) { 461 /* Let caller handle all errors */ 462 TRACE_ABORT(1, ft_t_warn, "warning: error status set!"); 463 } 464 TRACE_EXIT 0; 465} 466 467int ftape_report_error(unsigned int *error, 468 qic117_cmd_t *command, int report) 469{ 470 static const ftape_error ftape_errors[] = QIC117_ERRORS; 471 int code; 472 TRACE_FUN(ft_t_any); 473 474 TRACE_CATCH(ftape_report_operation(&code, QIC_REPORT_ERROR_CODE, 16),); 475 *error = (unsigned int)(code & 0xff); 476 *command = (qic117_cmd_t)((code>>8)&0xff); 477 /* remember hardware status, maybe useful for status ioctls 478 */ 479 ft_last_error.error.command = (__u8)*command; 480 ft_last_error.error.error = (__u8)*error; 481 if (!report) { 482 TRACE_EXIT 0; 483 } 484 if (*error == 0) { 485 TRACE_ABORT(0, ft_t_info, "No error"); 486 } 487 TRACE(ft_t_info, "errorcode: %d", *error); 488 if (*error < NR_ITEMS(ftape_errors)) { 489 TRACE(ft_t_noise, "%sFatal ERROR:", 490 (ftape_errors[*error].fatal ? "" : "Non-")); 491 TRACE(ft_t_noise, "%s ...", ftape_errors[*error].message); 492 } else { 493 TRACE(ft_t_noise, "Unknown ERROR !"); 494 } 495 if ((unsigned int)*command < NR_ITEMS(qic117_cmds) && 496 qic117_cmds[*command].name != NULL) { 497 TRACE(ft_t_noise, "... caused by command \'%s\'", 498 qic117_cmds[*command].name); 499 } else { 500 TRACE(ft_t_noise, "... caused by unknown command %d", 501 *command); 502 } 503 TRACE_EXIT 0; 504} 505 506int ftape_report_configuration(qic_model *model, 507 unsigned int *rate, 508 int *qic_std, 509 int *tape_len) 510{ 511 int result; 512 int config; 513 int status; 514 static const unsigned int qic_rates[ 4] = { 250, 2000, 500, 1000 }; 515 TRACE_FUN(ft_t_any); 516 517 result = ftape_report_operation(&config, 518 QIC_REPORT_DRIVE_CONFIGURATION, 8); 519 if (result < 0) { 520 ft_last_status.status.drive_config = (__u8)0x00; 521 *model = prehistoric; 522 *rate = 500; 523 *qic_std = QIC_TAPE_QIC40; 524 *tape_len = 205; 525 TRACE_EXIT 0; 526 } else { 527 ft_last_status.status.drive_config = (__u8)(config & 0xff); 528 } 529 *rate = qic_rates[(config & QIC_CONFIG_RATE_MASK) >> QIC_CONFIG_RATE_SHIFT]; 530 result = ftape_report_operation(&status, QIC_REPORT_TAPE_STATUS, 8); 531 if (result < 0) { 532 ft_last_status.status.tape_status = (__u8)0x00; 533 /* pre- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is valid. 534 */ 535 *qic_std = (config & QIC_CONFIG_80) ? 536 QIC_TAPE_QIC80 : QIC_TAPE_QIC40; 537 /* ?? how's about 425ft tapes? */ 538 *tape_len = (config & QIC_CONFIG_LONG) ? 307 : 0; 539 *model = pre_qic117c; 540 result = 0; 541 } else { 542 ft_last_status.status.tape_status = (__u8)(status & 0xff); 543 *model = post_qic117b; 544 TRACE(ft_t_any, "report tape status result = %02x", status); 545 /* post- QIC117 rev C spec. drive, QIC_CONFIG_80 bit is 546 * invalid. 547 */ 548 switch (status & QIC_TAPE_STD_MASK) { 549 case QIC_TAPE_QIC40: 550 case QIC_TAPE_QIC80: 551 case QIC_TAPE_QIC3020: 552 case QIC_TAPE_QIC3010: 553 *qic_std = status & QIC_TAPE_STD_MASK; 554 break; 555 default: 556 *qic_std = -1; 557 break; 558 } 559 switch (status & QIC_TAPE_LEN_MASK) { 560 case QIC_TAPE_205FT: 561 /* 205 or 425+ ft 550 Oe tape */ 562 *tape_len = 0; 563 break; 564 case QIC_TAPE_307FT: 565 /* 307.5 ft 550 Oe Extended Length (XL) tape */ 566 *tape_len = 307; 567 break; 568 case QIC_TAPE_VARIABLE: 569 /* Variable length 550 Oe tape */ 570 *tape_len = 0; 571 break; 572 case QIC_TAPE_1100FT: 573 /* 1100 ft 550 Oe tape */ 574 *tape_len = 1100; 575 break; 576 case QIC_TAPE_FLEX: 577 /* Variable length 900 Oe tape */ 578 *tape_len = 0; 579 break; 580 default: 581 *tape_len = -1; 582 break; 583 } 584 if (*qic_std == -1 || *tape_len == -1) { 585 TRACE(ft_t_any, 586 "post qic-117b spec drive with unknown tape"); 587 } 588 result = *tape_len == -1 ? -EIO : 0; 589 if (status & QIC_TAPE_WIDE) { 590 switch (*qic_std) { 591 case QIC_TAPE_QIC80: 592 TRACE(ft_t_info, "TR-1 tape detected"); 593 break; 594 case QIC_TAPE_QIC3010: 595 TRACE(ft_t_info, "TR-2 tape detected"); 596 break; 597 case QIC_TAPE_QIC3020: 598 TRACE(ft_t_info, "TR-3 tape detected"); 599 break; 600 default: 601 TRACE(ft_t_warn, 602 "Unknown Travan tape type detected"); 603 break; 604 } 605 } 606 } 607 TRACE_EXIT (result < 0) ? -EIO : 0; 608} 609 610static int ftape_report_rom_version(int *version) 611{ 612 613 if (ftape_report_operation(version, QIC_REPORT_ROM_VERSION, 8) < 0) { 614 return -EIO; 615 } else { 616 return 0; 617 } 618} 619 620void ftape_report_vendor_id(unsigned int *id) 621{ 622 int result; 623 TRACE_FUN(ft_t_any); 624 625 /* We'll try to get a vendor id from the drive. First 626 * according to the QIC-117 spec, a 16-bit id is requested. 627 * If that fails we'll try an 8-bit version, otherwise we'll 628 * try an undocumented query. 629 */ 630 result = ftape_report_operation((int *) id, QIC_REPORT_VENDOR_ID, 16); 631 if (result < 0) { 632 result = ftape_report_operation((int *) id, 633 QIC_REPORT_VENDOR_ID, 8); 634 if (result < 0) { 635 /* The following is an undocumented call found 636 * in the CMS code. 637 */ 638 result = ftape_report_operation((int *) id, 24, 8); 639 if (result < 0) { 640 *id = UNKNOWN_VENDOR; 641 } else { 642 TRACE(ft_t_noise, "got old 8 bit id: %04x", 643 *id); 644 *id |= 0x20000; 645 } 646 } else { 647 TRACE(ft_t_noise, "got 8 bit id: %04x", *id); 648 *id |= 0x10000; 649 } 650 } else { 651 TRACE(ft_t_noise, "got 16 bit id: %04x", *id); 652 } 653 if (*id == 0x0047) { 654 int version; 655 int sign; 656 657 if (ftape_report_rom_version(&version) < 0) { 658 TRACE(ft_t_bug, "report rom version failed"); 659 TRACE_EXIT; 660 } 661 TRACE(ft_t_noise, "CMS rom version: %d", version); 662 ftape_command(QIC_ENTER_DIAGNOSTIC_1); 663 ftape_command(QIC_ENTER_DIAGNOSTIC_1); 664 diagnostic_mode = 1; 665 if (ftape_report_operation(&sign, 9, 8) < 0) { 666 unsigned int error; 667 qic117_cmd_t command; 668 669 ftape_report_error(&error, &command, 1); 670 ftape_command(QIC_ENTER_PRIMARY_MODE); 671 diagnostic_mode = 0; 672 TRACE_EXIT; /* failure ! */ 673 } else { 674 TRACE(ft_t_noise, "CMS signature: %02x", sign); 675 } 676 if (sign == 0xa5) { 677 result = ftape_report_operation(&sign, 37, 8); 678 if (result < 0) { 679 if (version >= 63) { 680 *id = 0x8880; 681 TRACE(ft_t_noise, 682 "This is an Iomega drive !"); 683 } else { 684 *id = 0x0047; 685 TRACE(ft_t_noise, 686 "This is a real CMS drive !"); 687 } 688 } else { 689 *id = 0x0047; 690 TRACE(ft_t_noise, "CMS status: %d", sign); 691 } 692 } else { 693 *id = UNKNOWN_VENDOR; 694 } 695 ftape_command(QIC_ENTER_PRIMARY_MODE); 696 diagnostic_mode = 0; 697 } 698 TRACE_EXIT; 699} 700 701static int qic_rate_code(unsigned int rate) 702{ 703 switch (rate) { 704 case 250: 705 return QIC_CONFIG_RATE_250; 706 case 500: 707 return QIC_CONFIG_RATE_500; 708 case 1000: 709 return QIC_CONFIG_RATE_1000; 710 case 2000: 711 return QIC_CONFIG_RATE_2000; 712 default: 713 return QIC_CONFIG_RATE_500; 714 } 715} 716 717static int ftape_set_rate_test(unsigned int *max_rate) 718{ 719 unsigned int error; 720 qic117_cmd_t command; 721 int status; 722 int supported = 0; 723 TRACE_FUN(ft_t_any); 724 725 /* Check if the drive does support the select rate command 726 * by testing all different settings. If any one is accepted 727 * we assume the command is supported, else not. 728 */ 729 for (*max_rate = 2000; *max_rate >= 250; *max_rate /= 2) { 730 if (ftape_command(QIC_SELECT_RATE) < 0) { 731 continue; 732 } 733 if (ftape_parameter_wait(qic_rate_code(*max_rate), 734 1 * FT_SECOND, &status) < 0) { 735 continue; 736 } 737 if (status & QIC_STATUS_ERROR) { 738 ftape_report_error(&error, &command, 0); 739 continue; 740 } 741 supported = 1; /* did accept a request */ 742 break; 743 } 744 TRACE(ft_t_noise, "Select Rate command is%s supported", 745 supported ? "" : " not"); 746 TRACE_EXIT supported; 747} 748 749int ftape_set_data_rate(unsigned int new_rate /* Kbps */, unsigned int qic_std) 750{ 751 int status; 752 int result = 0; 753 unsigned int data_rate = new_rate; 754 static int supported; 755 int rate_changed = 0; 756 qic_model dummy_model; 757 unsigned int dummy_qic_std, dummy_tape_len; 758 TRACE_FUN(ft_t_any); 759 760 if (ft_drive_max_rate == 0) { /* first time */ 761 supported = ftape_set_rate_test(&ft_drive_max_rate); 762 } 763 if (supported) { 764 ftape_command(QIC_SELECT_RATE); 765 result = ftape_parameter_wait(qic_rate_code(new_rate), 766 1 * FT_SECOND, &status); 767 if (result >= 0 && !(status & QIC_STATUS_ERROR)) { 768 rate_changed = 1; 769 } 770 } 771 TRACE_CATCH(result = ftape_report_configuration(&dummy_model, 772 &data_rate, 773 &dummy_qic_std, 774 &dummy_tape_len),); 775 if (data_rate != new_rate) { 776 if (!supported) { 777 TRACE(ft_t_warn, "Rate change not supported!"); 778 } else if (rate_changed) { 779 TRACE(ft_t_warn, "Requested: %d, got %d", 780 new_rate, data_rate); 781 } else { 782 TRACE(ft_t_warn, "Rate change failed!"); 783 } 784 result = -EINVAL; 785 } 786 /* 787 * Set data rate and write precompensation as specified: 788 * 789 * | QIC-40/80 | QIC-3010/3020 790 * rate | precomp | precomp 791 * ----------+-------------+-------------- 792 * 250 Kbps. | 250 ns. | 0 ns. 793 * 500 Kbps. | 125 ns. | 0 ns. 794 * 1 Mbps. | 42 ns. | 0 ns. 795 * 2 Mbps | N/A | 0 ns. 796 */ 797 if ((qic_std == QIC_TAPE_QIC40 && data_rate > 500) || 798 (qic_std == QIC_TAPE_QIC80 && data_rate > 1000)) { 799 TRACE_ABORT(-EINVAL, 800 ft_t_warn, "Datarate too high for QIC-mode"); 801 } 802 TRACE_CATCH(fdc_set_data_rate(data_rate),_res = -EINVAL); 803 ft_data_rate = data_rate; 804 if (qic_std == QIC_TAPE_QIC40 || qic_std == QIC_TAPE_QIC80) { 805 switch (data_rate) { 806 case 250: 807 fdc_set_write_precomp(250); 808 break; 809 default: 810 case 500: 811 fdc_set_write_precomp(125); 812 break; 813 case 1000: 814 fdc_set_write_precomp(42); 815 break; 816 } 817 } else { 818 fdc_set_write_precomp(0); 819 } 820 TRACE_EXIT result; 821} 822 823/* The next two functions are used to cope with excessive overrun errors 824 */ 825int ftape_increase_threshold(void) 826{ 827 TRACE_FUN(ft_t_flow); 828 829 if (fdc.type < i82077 || ft_fdc_threshold >= 12) { 830 TRACE_ABORT(-EIO, ft_t_err, "cannot increase fifo threshold"); 831 } 832 if (fdc_fifo_threshold(++ft_fdc_threshold, NULL, NULL, NULL) < 0) { 833 TRACE(ft_t_err, "cannot increase fifo threshold"); 834 ft_fdc_threshold --; 835 fdc_reset(); 836 } 837 TRACE(ft_t_info, "New FIFO threshold: %d", ft_fdc_threshold); 838 TRACE_EXIT 0; 839} 840 841int ftape_half_data_rate(void) 842{ 843 if (ft_data_rate < 500) { 844 return -1; 845 } 846 if (ftape_set_data_rate(ft_data_rate / 2, ft_qic_std) < 0) { 847 return -EIO; 848 } 849 ftape_calc_timeouts(ft_qic_std, ft_data_rate, ftape_tape_len); 850 return 0; 851} 852 853/* Seek the head to the specified track. 854 */ 855int ftape_seek_head_to_track(unsigned int track) 856{ 857 int status; 858 TRACE_FUN(ft_t_any); 859 860 ft_location.track = -1; /* remains set in case of error */ 861 if (track >= ft_tracks_per_tape) { 862 TRACE_ABORT(-EINVAL, ft_t_bug, "track out of bounds"); 863 } 864 TRACE(ft_t_flow, "seeking track %d", track); 865 TRACE_CATCH(ftape_command(QIC_SEEK_HEAD_TO_TRACK),); 866 TRACE_CATCH(ftape_parameter_wait(track, ftape_timeout.head_seek, 867 &status),); 868 ft_location.track = track; 869 ftape_might_be_off_track = 0; 870 TRACE_EXIT 0; 871} 872 873int ftape_wakeup_drive(wake_up_types method) 874{ 875 int status; 876 int motor_on = 0; 877 TRACE_FUN(ft_t_any); 878 879 switch (method) { 880 case wake_up_colorado: 881 TRACE_CATCH(ftape_command(QIC_PHANTOM_SELECT),); 882 TRACE_CATCH(ftape_parameter(0 /* ft_drive_sel ?? */),); 883 break; 884 case wake_up_mountain: 885 TRACE_CATCH(ftape_command(QIC_SOFT_SELECT),); 886 ftape_sleep(FT_MILLISECOND); /* NEEDED */ 887 TRACE_CATCH(ftape_parameter(18),); 888 break; 889 case wake_up_insight: 890 ftape_sleep(100 * FT_MILLISECOND); 891 motor_on = 1; 892 fdc_motor(motor_on); /* enable is done by motor-on */ 893 case no_wake_up: 894 break; 895 default: 896 TRACE_EXIT -ENODEV; /* unknown wakeup method */ 897 break; 898 } 899 /* If wakeup succeeded we shouldn't get an error here.. 900 */ 901 TRACE_CATCH(ftape_report_raw_drive_status(&status), 902 if (motor_on) { 903 fdc_motor(0); 904 }); 905 TRACE_EXIT 0; 906} 907 908int ftape_put_drive_to_sleep(wake_up_types method) 909{ 910 TRACE_FUN(ft_t_any); 911 912 switch (method) { 913 case wake_up_colorado: 914 TRACE_CATCH(ftape_command(QIC_PHANTOM_DESELECT),); 915 break; 916 case wake_up_mountain: 917 TRACE_CATCH(ftape_command(QIC_SOFT_DESELECT),); 918 break; 919 case wake_up_insight: 920 fdc_motor(0); /* enable is done by motor-on */ 921 case no_wake_up: /* no wakeup / no sleep ! */ 922 break; 923 default: 924 TRACE_EXIT -ENODEV; /* unknown wakeup method */ 925 } 926 TRACE_EXIT 0; 927} 928 929int ftape_reset_drive(void) 930{ 931 int result = 0; 932 int status; 933 unsigned int err_code; 934 qic117_cmd_t err_command; 935 int i; 936 TRACE_FUN(ft_t_any); 937 938 /* We want to re-establish contact with our drive. Fire a 939 * number of reset commands (single step pulses) and pray for 940 * success. 941 */ 942 for (i = 0; i < 2; ++i) { 943 TRACE(ft_t_flow, "Resetting fdc"); 944 fdc_reset(); 945 ftape_sleep(10 * FT_MILLISECOND); 946 TRACE(ft_t_flow, "Reset command to drive"); 947 result = ftape_command(QIC_RESET); 948 if (result == 0) { 949 ftape_sleep(1 * FT_SECOND); /* drive not 950 * accessible 951 * during 1 second 952 */ 953 TRACE(ft_t_flow, "Re-selecting drive"); 954 955 /* Strange, the QIC-117 specs don't mention 956 * this but the drive gets deselected after a 957 * soft reset ! So we need to enable it 958 * again. 959 */ 960 if (ftape_wakeup_drive(ft_drive_type.wake_up) < 0) { 961 TRACE(ft_t_err, "Wakeup failed !"); 962 } 963 TRACE(ft_t_flow, "Waiting until drive gets ready"); 964 result= ftape_ready_wait(ftape_timeout.reset, &status); 965 if (result == 0 && (status & QIC_STATUS_ERROR)) { 966 result = ftape_report_error(&err_code, 967 &err_command, 1); 968 if (result == 0 && err_code == 27) { 969 /* Okay, drive saw reset 970 * command and responded as it 971 * should 972 */ 973 break; 974 } else { 975 result = -EIO; 976 } 977 } else { 978 result = -EIO; 979 } 980 } 981 FT_SIGNAL_EXIT(_DONT_BLOCK); 982 } 983 if (result != 0) { 984 TRACE(ft_t_err, "General failure to reset tape drive"); 985 } else { 986 /* Restore correct settings: keep original rate 987 */ 988 ftape_set_data_rate(ft_data_rate, ft_qic_std); 989 } 990 ftape_init_drive_needed = 1; 991 TRACE_EXIT result; 992}