2  *      Copyright (C) 1994-1996 Bas Laarhoven,
 
   3  *                (C) 1996-1997 Claus-Justus Heine.
 
   5  This program is free software; you can redistribute it and/or modify
 
   6  it under the terms of the GNU General Public License as published by
 
   7  the Free Software Foundation; either version 2, or (at your option)
 
  10  This program is distributed in the hope that it will be useful,
 
  11  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  13  GNU General Public License for more details.
 
  15  You should have received a copy of the GNU General Public License
 
  16  along with this program; see the file COPYING.  If not, write to
 
  17  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
  20  * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fdc-isr.c,v $
 
  22  * $Date: 1997/10/17 23:01:53 $
 
  24  *      This file contains the interrupt service routine and
 
  25  *      associated code for the QIC-40/80/3010/3020 floppy-tape driver
 
  32 #define volatile                /* */
 
  34 #include <linux/ftape.h>
 
  35 #include <linux/qic117.h>
 
  36 #include "../lowlevel/ftape-tracing.h"
 
  37 #include "../lowlevel/fdc-isr.h"
 
  38 #include "../lowlevel/fdc-io.h"
 
  39 #include "../lowlevel/ftape-ctl.h"
 
  40 #include "../lowlevel/ftape-rw.h"
 
  41 #include "../lowlevel/ftape-io.h"
 
  42 #include "../lowlevel/ftape-calibr.h"
 
  43 #include "../lowlevel/ftape-bsm.h"
 
  47 volatile int ft_expected_stray_interrupts;
 
  48 volatile int ft_interrupt_seen;
 
  49 volatile int ft_seek_completed;
 
  50 volatile int ft_hide_interrupt;
 
  54         no_error = 0, id_am_error = 0x01, id_crc_error = 0x02,
 
  55         data_am_error = 0x04, data_crc_error = 0x08,
 
  56         no_data_error = 0x10, overrun_error = 0x20,
 
  58 static int stop_read_ahead;
 
  61 static void print_error_cause(int cause)
 
  67                 TRACE(ft_t_noise, "no data error");
 
  70                 TRACE(ft_t_noise, "id am error");
 
  73                 TRACE(ft_t_noise, "id crc error");
 
  76                 TRACE(ft_t_noise, "data am error");
 
  79                 TRACE(ft_t_noise, "data crc error");
 
  82                 TRACE(ft_t_noise, "overrun error");
 
  89 static char *fdc_mode_txt(fdc_mode_enum mode)
 
  94         case fdc_reading_data:
 
  95                 return "fdc_reading_data";
 
  98         case fdc_writing_data:
 
  99                 return "fdc_writing_data";
 
 101                 return "fdc_reading_id";
 
 102         case fdc_recalibrating:
 
 103                 return "fdc_recalibrating";
 
 105                 return "fdc_formatting";
 
 107                 return "fdc_verifying";
 
 113 static inline error_cause decode_irq_cause(fdc_mode_enum mode, __u8 st[])
 
 115         error_cause cause = no_error;
 
 118         /*  Valid st[], decode cause of interrupt.
 
 120         switch (st[0] & ST0_INT_MASK) {
 
 122                 TRACE(ft_t_fdc_dma,"normal completion: %s",fdc_mode_txt(mode));
 
 124         case FDC_INT_ABNORMAL:
 
 125                 TRACE(ft_t_flow, "abnormal completion %s", fdc_mode_txt(mode));
 
 126                 TRACE(ft_t_fdc_dma, "ST0: 0x%02x, ST1: 0x%02x, ST2: 0x%02x",
 
 127                       st[0], st[1], st[2]);
 
 129                       "C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x",
 
 130                       st[3], st[4], st[5], st[6]);
 
 133                                 cause = data_am_error;
 
 137                 } else if (st[1] & 0x20) {
 
 139                                 cause = data_crc_error;
 
 141                                 cause = id_crc_error;
 
 143                 } else if (st[1] & 0x04) {
 
 144                         cause = no_data_error;
 
 145                 } else if (st[1] & 0x10) {
 
 146                         cause = overrun_error;
 
 148                 print_error_cause(cause);
 
 150         case FDC_INT_INVALID:
 
 151                 TRACE(ft_t_flow, "invalid completion %s", fdc_mode_txt(mode));
 
 153         case FDC_INT_READYCH:
 
 154                 if (st[0] & ST0_SEEK_END) {
 
 155                         TRACE(ft_t_flow, "drive poll completed");
 
 157                         TRACE(ft_t_flow, "ready change %s",fdc_mode_txt(mode));
 
 166 static void update_history(error_cause cause)
 
 170                 ft_history.id_am_errors++;
 
 173                 ft_history.id_crc_errors++;
 
 176                 ft_history.data_am_errors++;
 
 179                 ft_history.data_crc_errors++;
 
 182                 ft_history.overrun_errors++;
 
 185                 ft_history.no_data_errors++;
 
 191 static void skip_bad_sector(buffer_struct * buff)
 
 195         /*  Mark sector as soft error and skip it
 
 197         if (buff->remaining > 0) {
 
 198                 ++buff->sector_offset;
 
 201                 buff->ptr += FT_SECTOR_SIZE;
 
 202                 buff->bad_sector_map >>= 1;
 
 204                 /*  Hey, what is this????????????? C code: if we shift 
 
 205                  *  more than 31 bits, we get no shift. That's bad!!!!!!
 
 207                 ++buff->sector_offset;  /* hack for error maps */
 
 208                 TRACE(ft_t_warn, "skipping last sector in segment");
 
 213 static void update_error_maps(buffer_struct * buff, unsigned int error_offset)
 
 218         if (buff->retry < FT_SOFT_RETRIES) {
 
 219                 buff->soft_error_map |= (1 << error_offset);
 
 221                 buff->hard_error_map |= (1 << error_offset);
 
 222                 buff->soft_error_map &= ~buff->hard_error_map;
 
 223                 buff->retry = -1;  /* will be set to 0 in setup_segment */
 
 226         TRACE(ft_t_noise, "sector %d : %s error\n"
 
 227               KERN_INFO "hard map: 0x%08lx\n"
 
 228               KERN_INFO "soft map: 0x%08lx",
 
 229               FT_SECTOR(error_offset), hard ? "hard" : "soft",
 
 230               (long) buff->hard_error_map, (long) buff->soft_error_map);
 
 234 static void print_progress(buffer_struct *buff, error_cause cause)
 
 240                 TRACE(ft_t_flow,"%d Sector(s) transferred", buff->sector_count);
 
 243                 TRACE(ft_t_flow, "Sector %d not found",
 
 244                       FT_SECTOR(buff->sector_offset));
 
 247                 /*  got an overrun error on the first byte, must be a
 
 251                       "Unexpected error: failing DMA or FDC controller ?");
 
 254                 TRACE(ft_t_flow, "Error in sector %d",
 
 255                       FT_SECTOR(buff->sector_offset - 1));
 
 260                 TRACE(ft_t_flow, "Error in sector %d",
 
 261                       FT_SECTOR(buff->sector_offset));
 
 264                 TRACE(ft_t_flow, "Unexpected error at sector %d",
 
 265                       FT_SECTOR(buff->sector_offset));
 
 272  *  Error cause:   Amount xferred:  Action:
 
 274  *  id_am_error         0           mark bad and skip
 
 275  *  id_crc_error        0           mark bad and skip
 
 276  *  data_am_error       0           mark bad and skip
 
 277  *  data_crc_error    % 1024        mark bad and skip
 
 278  *  no_data_error       0           retry on write
 
 279  *                                  mark bad and skip on read
 
 280  *  overrun_error  [ 0..all-1 ]     mark bad and skip
 
 281  *  no_error           all          continue
 
 284 /*  the arg `sector' is returned by the fdc and tells us at which sector we
 
 285  *  are positioned at (relative to starting sector of segment)
 
 287 static void determine_verify_progress(buffer_struct *buff,
 
 293         if (cause == no_error && sector == 1) {
 
 294                 buff->sector_offset = FT_SECTORS_PER_SEGMENT;
 
 296                 if (TRACE_LEVEL >= ft_t_flow) {
 
 297                         print_progress(buff, cause);
 
 300                 buff->sector_offset = sector - buff->sect;
 
 301                 buff->remaining = FT_SECTORS_PER_SEGMENT - buff->sector_offset;
 
 302                 TRACE(ft_t_noise, "%ssector offset: 0x%04x", 
 
 303                       (cause == no_error) ? "unexpected " : "",
 
 304                       buff->sector_offset);
 
 310                         buff->retry = FT_SOFT_RETRIES;
 
 311                         if (buff->hard_error_map    &&
 
 312                             buff->sector_offset > 1 &&
 
 313                             (buff->hard_error_map & 
 
 314                              (1 << (buff->sector_offset-2)))) {
 
 320                         buff->retry = FT_SOFT_RETRIES;
 
 323                 if (TRACE_LEVEL >= ft_t_flow) {
 
 324                         print_progress(buff, cause);
 
 326                 /*  Sector_offset points to the problem area Now adjust
 
 327                  *  sector_offset so it always points one past he failing
 
 328                  *  sector. I.e. skip the bad sector.
 
 330                 ++buff->sector_offset;
 
 332                 update_error_maps(buff, buff->sector_offset - 1);
 
 337 static void determine_progress(buffer_struct *buff,
 
 341         unsigned int dma_residue;
 
 344         /*  Using less preferred order of disable_dma and
 
 345          *  get_dma_residue because this seems to fail on at least one
 
 346          *  system if reversed!
 
 348         dma_residue = get_dma_residue(fdc.dma);
 
 349         disable_dma(fdc.dma);
 
 350         if (cause != no_error || dma_residue != 0) {
 
 351                 TRACE(ft_t_noise, "%sDMA residue: 0x%04x", 
 
 352                       (cause == no_error) ? "unexpected " : "",
 
 354                 /* adjust to actual value: */
 
 355                 if (dma_residue == 0) {
 
 356                         /* this happens sometimes with overrun errors.
 
 357                          * I don't know whether we could ignore the
 
 358                          * overrun error. Play save.
 
 360                         buff->sector_count --;
 
 362                         buff->sector_count -= ((dma_residue + 
 
 363                                                 (FT_SECTOR_SIZE - 1)) /
 
 367         /*  Update var's influenced by the DMA operation.
 
 369         if (buff->sector_count > 0) {
 
 370                 buff->sector_offset   += buff->sector_count;
 
 371                 buff->data_offset     += buff->sector_count;
 
 372                 buff->ptr             += (buff->sector_count *
 
 374                 buff->remaining       -= buff->sector_count;
 
 375                 buff->bad_sector_map >>= buff->sector_count;
 
 377         if (TRACE_LEVEL >= ft_t_flow) {
 
 378                 print_progress(buff, cause);
 
 380         if (cause != no_error) {
 
 381                 if (buff->remaining == 0) {
 
 382                         TRACE(ft_t_warn, "foo?\n"
 
 383                               KERN_INFO "count : %d\n"
 
 384                               KERN_INFO "offset: %d\n"
 
 385                               KERN_INFO "soft  : %08x\n"
 
 386                               KERN_INFO "hard  : %08x",
 
 389                               buff->soft_error_map,
 
 390                               buff->hard_error_map);
 
 392                 /*  Sector_offset points to the problem area, except if we got
 
 393                  *  a data_crc_error. In that case it points one past the
 
 396                  *  Now adjust sector_offset so it always points one past he
 
 397                  *  failing sector. I.e. skip the bad sector.  
 
 399                 if (cause != data_crc_error) {
 
 400                         skip_bad_sector(buff);
 
 402                 update_error_maps(buff, buff->sector_offset - 1);
 
 407 static int calc_steps(int cmd)
 
 409         if (ftape_current_cylinder > cmd) {
 
 410                 return ftape_current_cylinder - cmd;
 
 412                 return ftape_current_cylinder + cmd;
 
 416 static void pause_tape(int retry, int mode)
 
 419         __u8 out[3] = {FDC_SEEK, ft_drive_sel, 0};
 
 422         /*  We'll use a raw seek command to get the tape to rewind and
 
 425         ++ft_history.rewinds;
 
 426         if (qic117_cmds[ftape_current_command].non_intr) {
 
 427                 TRACE(ft_t_warn, "motion command may be issued too soon");
 
 429         if (retry && (mode == fdc_reading_data ||
 
 430                       mode == fdc_reading_id   ||
 
 431                       mode == fdc_verifying)) {
 
 432                 ftape_current_command = QIC_MICRO_STEP_PAUSE;
 
 433                 ftape_might_be_off_track = 1;
 
 435                 ftape_current_command = QIC_PAUSE;
 
 437         out[2] = calc_steps(ftape_current_command);
 
 438         result = fdc_command(out, 3); /* issue QIC_117 command */
 
 439         ftape_current_cylinder = out[ 2];
 
 441                 TRACE(ft_t_noise, "qic-pause failed, status = %d", result);
 
 443                 ft_location.known  = 0;
 
 444                 ft_runner_status   = idle;
 
 445                 ft_hide_interrupt     = 1;
 
 446                 ftape_tape_running = 0;
 
 451 static void continue_xfer(buffer_struct *buff,
 
 458         if (mode == fdc_writing_data || mode == fdc_deleting) {
 
 461         /*  This part can be removed if it never happens
 
 464             (ft_runner_status != running ||
 
 465              (write && (buff->status != writing)) ||
 
 466              (!write && (buff->status != reading && 
 
 467                          buff->status != verifying)))) {
 
 468                 TRACE(ft_t_err, "unexpected runner/buffer state %d/%d",
 
 469                       ft_runner_status, buff->status);
 
 470                 buff->status = error;
 
 471                 /* finish this buffer: */
 
 472                 (void)ftape_next_buffer(ft_queue_head);
 
 473                 ft_runner_status = aborting;
 
 475         } else if (buff->remaining > 0 && ftape_calc_next_cluster(buff) > 0) {
 
 476                 /*  still sectors left in current segment, continue
 
 479                 if (fdc_setup_read_write(buff, mode) < 0) {
 
 480                         /* failed, abort operation
 
 482                         buff->bytes = buff->ptr - buff->address;
 
 483                         buff->status = error;
 
 484                         /* finish this buffer: */
 
 485                         (void)ftape_next_buffer(ft_queue_head);
 
 486                         ft_runner_status = aborting;
 
 490                 /* current segment completed
 
 492                 unsigned int last_segment = buff->segment_id;
 
 493                 int eot = ((last_segment + 1) % ft_segments_per_track) == 0;
 
 494                 unsigned int next = buff->next_segment; /* 0 means stop ! */
 
 496                 buff->bytes = buff->ptr - buff->address;
 
 498                 buff = ftape_next_buffer(ft_queue_head);
 
 500                         /*  finished last segment on current track,
 
 503                         ft_runner_status = logical_eot;
 
 508                         /*  don't continue with next segment
 
 510                         TRACE(ft_t_noise, "no %s allowed, stopping tape",
 
 511                               (write) ? "write next" : "read ahead");
 
 513                         ft_runner_status = idle;  /*  not quite true until
 
 518                 /*  continue with next segment
 
 520                 if (buff->status != waiting) {
 
 521                         TRACE(ft_t_noise, "all input buffers %s, pausing tape",
 
 522                               (write) ? "empty" : "full");
 
 524                         ft_runner_status = idle;  /*  not quite true until
 
 529                 if (write && next != buff->segment_id) {
 
 531                               "segments out of order, aborting write");
 
 532                         ft_runner_status = do_abort;
 
 536                 ftape_setup_new_segment(buff, next, 0);
 
 537                 if (stop_read_ahead) {
 
 538                         buff->next_segment = 0;
 
 541                 if (ftape_calc_next_cluster(buff) == 0 ||
 
 542                     fdc_setup_read_write(buff, mode) != 0) {
 
 543                         TRACE(ft_t_err, "couldn't start %s-ahead",
 
 544                               write ? "write" : "read");
 
 545                         ft_runner_status = do_abort;
 
 549                         switch (ft_driver_state) {
 
 550                         case   reading: buff->status = reading;   break;
 
 551                         case verifying: buff->status = verifying; break;
 
 552                         case   writing: buff->status = writing;   break;
 
 553                         case  deleting: buff->status = deleting;  break;
 
 556                       "BUG: ft_driver_state %d should be one out of "
 
 557                       "{reading, writing, verifying, deleting}",
 
 559                                 buff->status = write ? writing : reading;
 
 567 static void retry_sector(buffer_struct *buff, 
 
 573         TRACE(ft_t_noise, "%s error, will retry",
 
 574               (mode == fdc_writing_data || mode == fdc_deleting) ? "write" : "read");
 
 576         ft_runner_status = aborting;
 
 577         buff->status     = error;
 
 582 static unsigned int find_resume_point(buffer_struct *buff)
 
 589         /*  This function is to be called after all variables have been
 
 590          *  updated to point past the failing sector.
 
 591          *  If there are any soft errors before the failing sector,
 
 592          *  find the first soft error and return the sector offset.
 
 593          *  Otherwise find the last hard error.
 
 594          *  Note: there should always be at least one hard or soft error !
 
 596         if (buff->sector_offset < 1 || buff->sector_offset > 32) {
 
 597                 TRACE(ft_t_bug, "BUG: sector_offset = %d",
 
 598                       buff->sector_offset);
 
 601         if (buff->sector_offset >= 32) { /* C-limitation on shift ! */
 
 604                 mask = (1 << buff->sector_offset) - 1;
 
 606         map = buff->soft_error_map & mask;
 
 608                 while ((map & (1 << i)) == 0) {
 
 611                 TRACE(ft_t_noise, "at sector %d", FT_SECTOR(i));
 
 613                 map = buff->hard_error_map & mask;
 
 614                 i = buff->sector_offset - 1;
 
 616                         while ((map & (1 << i)) == 0) {
 
 619                         TRACE(ft_t_noise, "after sector %d", FT_SECTOR(i));
 
 620                         ++i; /* first sector after last hard error */
 
 622                         TRACE(ft_t_bug, "BUG: no soft or hard errors");
 
 628 /*  check possible dma residue when formatting, update position record in
 
 629  *  buffer struct. This is, of course, modelled after determine_progress(), but
 
 630  *  we don't need to set up for retries because the format process cannot be
 
 631  *  interrupted (except at the end of the tape track).
 
 633 static int determine_fmt_progress(buffer_struct *buff, error_cause cause)
 
 635         unsigned int dma_residue;
 
 638         /*  Using less preferred order of disable_dma and
 
 639          *  get_dma_residue because this seems to fail on at least one
 
 640          *  system if reversed!
 
 642         dma_residue = get_dma_residue(fdc.dma);
 
 643         disable_dma(fdc.dma);
 
 644         if (cause != no_error || dma_residue != 0) {
 
 645                 TRACE(ft_t_info, "DMA residue = 0x%04x", dma_residue);
 
 649                         ft_runner_status = aborting;
 
 653                         /*  got an overrun error on the first byte, must be a
 
 657                               "Unexpected error: failing DMA controller ?");
 
 658                         ft_runner_status = do_abort;
 
 659                         buff->status = error;
 
 662                         TRACE(ft_t_noise, "Unexpected error at segment %d",
 
 664                         ft_runner_status = do_abort;
 
 665                         buff->status = error;
 
 668                 TRACE_EXIT -EIO; /* can only retry entire track in format mode
 
 671         /*  Update var's influenced by the DMA operation.
 
 673         buff->ptr             += FT_SECTORS_PER_SEGMENT * 4;
 
 674         buff->bytes           -= FT_SECTORS_PER_SEGMENT * 4;
 
 675         buff->remaining       -= FT_SECTORS_PER_SEGMENT;
 
 676         buff->segment_id ++; /* done with segment */
 
 681  *  Continue formatting, switch buffers if there is no data left in
 
 682  *  current buffer. This is, of course, modelled after
 
 683  *  continue_xfer(), but we don't need to set up for retries because
 
 684  *  the format process cannot be interrupted (except at the end of the
 
 687 static void continue_formatting(buffer_struct *buff)
 
 691         if (buff->remaining <= 0) { /*  no space left in dma buffer */
 
 692                 unsigned int next = buff->next_segment; 
 
 694                 if (next == 0) { /* end of tape track */
 
 696                         ft_runner_status = logical_eot;
 
 698                         TRACE(ft_t_noise, "Done formatting track %d",
 
 703                  *  switch to next buffer!
 
 706                 buff = ftape_next_buffer(ft_queue_head);
 
 708                 if (buff->status != waiting  || next != buff->segment_id) {
 
 709                         goto format_setup_error;
 
 712         if (fdc_setup_formatting(buff) < 0) {
 
 713                 goto format_setup_error;
 
 715         buff->status = formatting;
 
 716         TRACE(ft_t_fdc_dma, "Formatting segment %d on track %d",
 
 717               buff->segment_id, ft_location.track);
 
 720         ft_runner_status = do_abort;
 
 722         buff->status     = error;
 
 723         TRACE(ft_t_err, "Error setting up for segment %d on track %d",
 
 724               buff->segment_id, ft_location.track);
 
 729 /*  this handles writing, read id, reading and formatting
 
 731 static void handle_fdc_busy(buffer_struct *buff)
 
 733         static int no_data_error_count;
 
 738         fdc_mode_enum fmode = fdc_mode;
 
 741         if (fdc_result(in, 7) < 0) { /* better get it fast ! */
 
 743                       "Probably fatal error during FDC Result Phase\n"
 
 745                       "drive may hang until (power on) reset :-(");
 
 746                 /*  what to do next ????
 
 750         cause = decode_irq_cause(fdc_mode, in);
 
 753         for (i = 0; i < (int)ft_nr_buffers; ++i)
 
 754                 TRACE(ft_t_any, "buffer[%d] status: %d, segment_id: %d",
 
 755                       i, ft_buffer[i]->status, ft_buffer[i]->segment_id);
 
 758         if (fmode == fdc_reading_data && ft_driver_state == verifying) {
 
 759                 fmode = fdc_verifying;
 
 763                 if (ft_runner_status == aborting ||
 
 764                     ft_runner_status == do_abort) {
 
 765                         TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
 
 768                 if (buff->retry > 0) {
 
 769                         TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
 
 773                         no_data_error_count = 0;
 
 774                         determine_verify_progress(buff, cause, in[5]);
 
 776                                 /*  This should not happen when verifying
 
 779                                       "deleted data in segment %d/%d",
 
 781                                       FT_SECTOR(buff->sector_offset - 1));
 
 782                                 buff->remaining = 0; /* abort transfer */
 
 783                                 buff->hard_error_map = EMPTY_SEGMENT;
 
 788                         continue_xfer(buff, fdc_mode, skip);
 
 791                         no_data_error_count ++;
 
 798                         determine_verify_progress(buff, cause, in[5]); 
 
 799                         if (cause == no_data_error) {
 
 800                                 if (no_data_error_count >= 2) {
 
 802                                               "retrying because of successive "
 
 804                                         no_data_error_count = 0;
 
 809                                 no_data_error_count = 0;
 
 812                                 skip = find_resume_point(buff);
 
 814                                 skip = buff->sector_offset;
 
 816                         if (retry && skip < 32) {
 
 817                                 retry_sector(buff, fdc_mode, skip);
 
 819                                 continue_xfer(buff, fdc_mode, skip);
 
 821                         update_history(cause);
 
 824                         /*  Don't know why this could happen 
 
 827                         determine_verify_progress(buff, cause, in[5]);
 
 828                         retry_sector(buff, fdc_mode, 0);
 
 829                         TRACE(ft_t_err, "Error: unexpected error");
 
 833         case fdc_reading_data:
 
 835                 /* I'm sorry, but: NOBODY ever used this trace
 
 836                  * messages for ages. I guess that Bas was the last person
 
 837                  * that ever really used this (thank you, between the lines)
 
 839                 if (cause == no_error) {
 
 840                         TRACE(ft_t_flow,"reading segment %d",buff->segment_id);
 
 842                         TRACE(ft_t_noise, "error reading segment %d",
 
 844                         TRACE(ft_t_noise, "\n"
 
 846                              "IRQ:C: 0x%02x, H: 0x%02x, R: 0x%02x, N: 0x%02x\n"
 
 848                               "BUF:C: 0x%02x, H: 0x%02x, R: 0x%02x",
 
 849                               in[3], in[4], in[5], in[6],
 
 850                               buff->cyl, buff->head, buff->sect);
 
 853                 if (ft_runner_status == aborting ||
 
 854                     ft_runner_status == do_abort) {
 
 855                         TRACE(ft_t_noise,"aborting %s",fdc_mode_txt(fdc_mode));
 
 858                 if (buff->bad_sector_map == FAKE_SEGMENT) {
 
 859                         /* This condition occurs when reading a `fake'
 
 860                          * sector that's not accessible. Doesn't
 
 861                          * really matter as we would have ignored it
 
 864                          * Chance is that we're past the next segment
 
 865                          * now, so the next operation may fail and
 
 868                         buff->remaining = 0;    /* skip failing sector */
 
 869                         /* buff->ptr       = buff->address; */
 
 871                         continue_xfer(buff, fdc_mode, 1);
 
 872                         /*  trace calls are expensive: place them AFTER
 
 873                          *  the real stuff has been done.
 
 876                         TRACE(ft_t_noise, "skipping empty segment %d (read), size? %d",
 
 877                               buff->segment_id, buff->ptr - buff->address);
 
 880                 if (buff->retry > 0) {
 
 881                         TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
 
 885                         determine_progress(buff, cause, in[5]);
 
 887                                 /*  Handle deleted data in header segments.
 
 888                                  *  Skip segment and force read-ahead.
 
 891                                       "deleted data in segment %d/%d",
 
 893                                       FT_SECTOR(buff->sector_offset - 1));
 
 895                                 buff->remaining = 0;/*abort transfer */
 
 896                                 buff->soft_error_map |=
 
 897                                                 (-1L << buff->sector_offset);
 
 898                                 if (buff->segment_id == 0) {
 
 899                                         /* stop on next segment */
 
 902                                 /* force read-ahead: */
 
 904                                         buff->segment_id + 1;
 
 905                                 skip = (FT_SECTORS_PER_SEGMENT - 
 
 906                                         buff->sector_offset);
 
 910                         continue_xfer(buff, fdc_mode, skip);
 
 913                         /* Tape started too far ahead of or behind the
 
 914                          * right sector.  This may also happen in the
 
 915                          * middle of a segment !
 
 917                          * Handle no-data as soft error. If next
 
 918                          * sector fails too, a retry (with needed
 
 919                          * reposition) will follow.
 
 927                         retry += (buff->soft_error_map != 0 ||
 
 928                                   buff->hard_error_map != 0);
 
 929                         determine_progress(buff, cause, in[5]); 
 
 930 #if 1 || defined(TESTING)
 
 931                         if (cause == overrun_error) retry ++;
 
 934                                 skip = find_resume_point(buff);
 
 936                                 skip = buff->sector_offset;
 
 938                         /*  Try to resume with next sector on single
 
 939                          *  errors (let ecc correct it), but retry on
 
 940                          *  no_data (we'll be past the target when we
 
 941                          *  get here so we cannot retry) or on
 
 942                          *  multiple errors (reduce chance on ecc
 
 945                         /*  cH: 23/02/97: if the last sector in the 
 
 946                          *  segment was a hard error, then there is 
 
 947                          *  no sense in a retry. This occasion seldom
 
 948                          *  occurs but ... @:³²¸`@%&§$
 
 950                         if (retry && skip < 32) {
 
 951                                 retry_sector(buff, fdc_mode, skip);
 
 953                                 continue_xfer(buff, fdc_mode, skip);
 
 955                         update_history(cause);
 
 958                         /*  Don't know why this could happen 
 
 961                         determine_progress(buff, cause, in[5]);
 
 962                         retry_sector(buff, fdc_mode, 0);
 
 963                         TRACE(ft_t_err, "Error: unexpected error");
 
 968                 if (cause == no_error) {
 
 973                               "id read: C: 0x%02x, H: 0x%02x, R: 0x%02x",
 
 974                               fdc_cyl, fdc_head, fdc_sect);
 
 975                 } else {        /* no valid information, use invalid sector */
 
 976                         fdc_cyl = fdc_head = fdc_sect = 0;
 
 977                         TRACE(ft_t_flow, "Didn't find valid sector Id");
 
 982         case fdc_writing_data:
 
 984                 if (cause == no_error) {
 
 985                         TRACE(ft_t_flow, "writing segment %d", buff->segment_id);
 
 987                         TRACE(ft_t_noise, "error writing segment %d",
 
 991                 if (ft_runner_status == aborting ||
 
 992                     ft_runner_status == do_abort) {
 
 993                         TRACE(ft_t_flow, "aborting %s",fdc_mode_txt(fdc_mode));
 
 996                 if (buff->retry > 0) {
 
 997                         TRACE(ft_t_flow, "this is retry nr %d", buff->retry);
 
 999                 if (buff->bad_sector_map == FAKE_SEGMENT) {
 
1000                         /* This condition occurs when trying to write to a
 
1001                          * `fake' sector that's not accessible. Doesn't really
 
1002                          * matter as it isn't used anyway ! Might be located
 
1003                          * at wrong segment, then we'll fail on the next
 
1006                         TRACE(ft_t_noise, "skipping empty segment (write)");
 
1007                         buff->remaining = 0;    /* skip failing sector */
 
1009                         continue_xfer(buff, fdc_mode, 1);
 
1014                         determine_progress(buff, cause, in[5]);
 
1015                         continue_xfer(buff, fdc_mode, 0);
 
1022                         update_history(cause);
 
1023                         determine_progress(buff, cause, in[5]);
 
1024                         skip = find_resume_point(buff);
 
1025                         retry_sector(buff, fdc_mode, skip);
 
1029                                 TRACE(ft_t_err, "media not writable");
 
1031                                 TRACE(ft_t_bug, "unforeseen write error");
 
1033                         fdc_mode = fdc_idle;
 
1036                 break; /* fdc_deleting || fdc_writing_data */
 
1037         case fdc_formatting:
 
1038                 /*  The interrupt comes after formatting a segment. We then
 
1039                  *  have to set up QUICKLY for the next segment. But
 
1040                  *  afterwards, there is plenty of time.
 
1044                         /*  would like to keep most of the formatting stuff
 
1045                          *  outside the isr code, but timing is too critical
 
1047                         if (determine_fmt_progress(buff, cause) >= 0) {
 
1048                                 continue_formatting(buff);
 
1057                         determine_fmt_progress(buff, cause);
 
1058                         update_history(cause);
 
1060                                 TRACE(ft_t_err, "media not writable");
 
1062                                 TRACE(ft_t_bug, "unforeseen write error");
 
1068                 TRACE(ft_t_warn, "Warning: unexpected irq during: %s",
 
1069                       fdc_mode_txt(fdc_mode));
 
1070                 fdc_mode = fdc_idle;
 
1076 /*      FDC interrupt service routine.
 
1080         static int isr_active;
 
1082         unsigned int t0 = ftape_timestamp();
 
1084         TRACE_FUN(ft_t_any);
 
1088                 TRACE(ft_t_bug, "BUG: nested interrupt, not good !");
 
1089                 *fdc.hook = fdc_isr; /*  hook our handler into the fdc
 
1095         if (inb_p(fdc.msr) & FDC_BUSY) {        /*  Entering Result Phase */
 
1096                 ft_hide_interrupt = 0;
 
1097                 handle_fdc_busy(ftape_get_buffer(ft_queue_head));
 
1098                 if (ft_runner_status == do_abort) {
 
1099                         /*      cease operation, remember tape position
 
1101                         TRACE(ft_t_flow, "runner aborting");
 
1102                         ft_runner_status = aborting;
 
1103                         ++ft_expected_stray_interrupts;
 
1105         } else { /* !FDC_BUSY */
 
1106                 /*  clear interrupt, cause should be gotten by issuing
 
1107                  *  a Sense Interrupt Status command.
 
1109                 if (fdc_mode == fdc_recalibrating || fdc_mode == fdc_seeking) {
 
1110                         if (ft_hide_interrupt) {
 
1114                                 if (fdc_sense_interrupt_status(&st0, &pcn) < 0)
 
1116                                               "sense interrupt status failed");
 
1117                                 ftape_current_cylinder = pcn;
 
1118                                 TRACE(ft_t_flow, "handled hidden interrupt");
 
1120                         ft_seek_completed = 1;
 
1121                         fdc_mode = fdc_idle;
 
1122                 } else if (!waitqueue_active(&ftape_wait_intr)) {
 
1123                         if (ft_expected_stray_interrupts == 0) {
 
1124                                 TRACE(ft_t_warn, "unexpected stray interrupt");
 
1126                                 TRACE(ft_t_flow, "expected stray interrupt");
 
1127                                 --ft_expected_stray_interrupts;
 
1130                         if (fdc_mode == fdc_reading_data ||
 
1131                             fdc_mode == fdc_verifying    ||
 
1132                             fdc_mode == fdc_writing_data ||
 
1133                             fdc_mode == fdc_deleting     ||
 
1134                             fdc_mode == fdc_formatting   ||
 
1135                             fdc_mode == fdc_reading_id) {
 
1136                                 if (inb_p(fdc.msr) & FDC_BUSY) {
 
1138                                         "***** FDC failure, busy too late");
 
1141                                               "***** FDC failure, no busy");
 
1144                                 TRACE(ft_t_fdc_dma, "awaited stray interrupt");
 
1147                 ft_hide_interrupt = 0;
 
1149         /*    Handle sleep code.
 
1151         if (!ft_hide_interrupt) {
 
1152                 ft_interrupt_seen ++;
 
1153                 if (waitqueue_active(&ftape_wait_intr)) {
 
1154                         wake_up_interruptible(&ftape_wait_intr);
 
1157                 TRACE(ft_t_flow, "hiding interrupt while %s", 
 
1158                       waitqueue_active(&ftape_wait_intr) ? "waiting":"active");
 
1161         t0 = ftape_timediff(t0, ftape_timestamp());
 
1163                 /* only tell us about long calls */
 
1164                 TRACE(ft_t_noise, "isr() duration: %5d usec", t0);
 
1167         *fdc.hook = fdc_isr;    /* hook our handler into the fdc code again */